X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;ds=sidebyside;f=qemu%2Froms%2Fu-boot%2Farch%2Fpowerpc%2Flib%2Finterrupts.c;fp=qemu%2Froms%2Fu-boot%2Farch%2Fpowerpc%2Flib%2Finterrupts.c;h=f7cf915759de29bdc5731561417eaf185a74f1bc;hb=e44e3482bdb4d0ebde2d8b41830ac2cdb07948fb;hp=0000000000000000000000000000000000000000;hpb=9ca8dbcc65cfc63d6f5ef3312a33184e1d726e00;p=kvmfornfv.git diff --git a/qemu/roms/u-boot/arch/powerpc/lib/interrupts.c b/qemu/roms/u-boot/arch/powerpc/lib/interrupts.c new file mode 100644 index 000000000..f7cf91575 --- /dev/null +++ b/qemu/roms/u-boot/arch/powerpc/lib/interrupts.c @@ -0,0 +1,127 @@ +/* + * (C) Copyright 2000-2002 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2003 + * Gleb Natapov + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#ifdef CONFIG_STATUS_LED +#include +#endif + +#ifdef CONFIG_SHOW_ACTIVITY +void board_show_activity (ulong) __attribute__((weak, alias("__board_show_activity"))); + +void __board_show_activity (ulong dummy) +{ + return; +} +#endif /* CONFIG_SHOW_ACTIVITY */ + +#ifndef CONFIG_SYS_WATCHDOG_FREQ +#define CONFIG_SYS_WATCHDOG_FREQ (CONFIG_SYS_HZ / 2) +#endif + +extern int interrupt_init_cpu (unsigned *); +extern void timer_interrupt_cpu (struct pt_regs *); + +static unsigned decrementer_count; /* count value for 1e6/HZ microseconds */ + +static __inline__ unsigned long get_msr (void) +{ + unsigned long msr; + + asm volatile ("mfmsr %0":"=r" (msr):); + + return msr; +} + +static __inline__ void set_msr (unsigned long msr) +{ + asm volatile ("mtmsr %0"::"r" (msr)); +} + +static __inline__ unsigned long get_dec (void) +{ + unsigned long val; + + asm volatile ("mfdec %0":"=r" (val):); + + return val; +} + + +static __inline__ void set_dec (unsigned long val) +{ + if (val) + asm volatile ("mtdec %0"::"r" (val)); +} + + +void enable_interrupts (void) +{ + set_msr (get_msr () | MSR_EE); +} + +/* returns flag if MSR_EE was set before */ +int disable_interrupts (void) +{ + ulong msr = get_msr (); + + set_msr (msr & ~MSR_EE); + return ((msr & MSR_EE) != 0); +} + +int interrupt_init (void) +{ + int ret; + + /* call cpu specific function from $(CPU)/interrupts.c */ + ret = interrupt_init_cpu (&decrementer_count); + + if (ret) + return ret; + + set_dec (decrementer_count); + + set_msr (get_msr () | MSR_EE); + + return (0); +} + +static volatile ulong timestamp = 0; + +void timer_interrupt (struct pt_regs *regs) +{ + /* call cpu specific function from $(CPU)/interrupts.c */ + timer_interrupt_cpu (regs); + + /* Restore Decrementer Count */ + set_dec (decrementer_count); + + timestamp++; + +#if defined(CONFIG_WATCHDOG) || defined (CONFIG_HW_WATCHDOG) + if ((timestamp % (CONFIG_SYS_WATCHDOG_FREQ)) == 0) + WATCHDOG_RESET (); +#endif /* CONFIG_WATCHDOG || CONFIG_HW_WATCHDOG */ + +#ifdef CONFIG_STATUS_LED + status_led_tick (timestamp); +#endif /* CONFIG_STATUS_LED */ + +#ifdef CONFIG_SHOW_ACTIVITY + board_show_activity (timestamp); +#endif /* CONFIG_SHOW_ACTIVITY */ +} + +ulong get_timer (ulong base) +{ + return (timestamp - base); +}