uboot/arch/powerpc/lib/interrupts.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2000-2002
   3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   4 *
   5 * (C) Copyright 2003
   6 * Gleb Natapov <gnatapov@mrv.com>
   7 *
   8 * SPDX-License-Identifier:     GPL-2.0+
   9 */
  10
  11#include <common.h>
  12#include <asm/processor.h>
  13#include <watchdog.h>
  14#ifdef CONFIG_STATUS_LED
  15#include <status_led.h>
  16#endif
  17
  18#ifdef CONFIG_SHOW_ACTIVITY
  19void board_show_activity (ulong) __attribute__((weak, alias("__board_show_activity")));
  20
  21void __board_show_activity (ulong dummy)
  22{
  23        return;
  24}
  25#endif /* CONFIG_SHOW_ACTIVITY */
  26
  27#ifndef CONFIG_SYS_WATCHDOG_FREQ
  28#define CONFIG_SYS_WATCHDOG_FREQ (CONFIG_SYS_HZ / 2)
  29#endif
  30
  31extern int interrupt_init_cpu (unsigned *);
  32extern void timer_interrupt_cpu (struct pt_regs *);
  33
  34static unsigned decrementer_count; /* count value for 1e6/HZ microseconds */
  35
  36static __inline__ unsigned long get_msr (void)
  37{
  38        unsigned long msr;
  39
  40        asm volatile ("mfmsr %0":"=r" (msr):);
  41
  42        return msr;
  43}
  44
  45static __inline__ void set_msr (unsigned long msr)
  46{
  47        asm volatile ("mtmsr %0"::"r" (msr));
  48}
  49
  50static __inline__ unsigned long get_dec (void)
  51{
  52        unsigned long val;
  53
  54        asm volatile ("mfdec %0":"=r" (val):);
  55
  56        return val;
  57}
  58
  59
  60static __inline__ void set_dec (unsigned long val)
  61{
  62        if (val)
  63                asm volatile ("mtdec %0"::"r" (val));
  64}
  65
  66
  67void enable_interrupts (void)
  68{
  69        set_msr (get_msr () | MSR_EE);
  70}
  71
  72/* returns flag if MSR_EE was set before */
  73int disable_interrupts (void)
  74{
  75        ulong msr = get_msr ();
  76
  77        set_msr (msr & ~MSR_EE);
  78        return ((msr & MSR_EE) != 0);
  79}
  80
  81int interrupt_init (void)
  82{
  83        int ret;
  84
  85        /* call cpu specific function from $(CPU)/interrupts.c */
  86        ret = interrupt_init_cpu (&decrementer_count);
  87
  88        if (ret)
  89                return ret;
  90
  91        set_dec (decrementer_count);
  92
  93        set_msr (get_msr () | MSR_EE);
  94
  95        return (0);
  96}
  97
  98static volatile ulong timestamp = 0;
  99
 100void timer_interrupt (struct pt_regs *regs)
 101{
 102        /* call cpu specific function from $(CPU)/interrupts.c */
 103        timer_interrupt_cpu (regs);
 104
 105        /* Restore Decrementer Count */
 106        set_dec (decrementer_count);
 107
 108        timestamp++;
 109
 110#if defined(CONFIG_WATCHDOG) || defined (CONFIG_HW_WATCHDOG)
 111        if ((timestamp % (CONFIG_SYS_WATCHDOG_FREQ)) == 0)
 112                WATCHDOG_RESET ();
 113#endif    /* CONFIG_WATCHDOG || CONFIG_HW_WATCHDOG */
 114
 115#ifdef CONFIG_STATUS_LED
 116        status_led_tick (timestamp);
 117#endif /* CONFIG_STATUS_LED */
 118
 119#ifdef CONFIG_SHOW_ACTIVITY
 120        board_show_activity (timestamp);
 121#endif /* CONFIG_SHOW_ACTIVITY */
 122}
 123
 124ulong get_timer (ulong base)
 125{
 126        return (timestamp - base);
 127}
 128