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