#include #include #include #include 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) { 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; msr = get_msr(); set_msr (msr & ~MSR_EE); return ((msr & MSR_EE) != 0); } u8 in8(u32 port) { return in_byte(port); } void out8(u32 port, u8 val) { out_byte(port, val); } unsigned long in32(u32 port) { return in_long(port); } static inline void soft_restart(unsigned long addr) { /* SRR0 has system reset vector, SRR1 has default MSR value */ /* rfi restores MSR from SRR1 and sets the PC to the SRR0 value */ __asm__ __volatile__ ("mtspr 26, %0" :: "r" (addr)); __asm__ __volatile__ ("li 4, (1 << 6)" ::: "r4"); __asm__ __volatile__ ("mtspr 27, 4"); __asm__ __volatile__ ("rfi"); while(1); /* not reached */ } /* void do_reset (void) { ulong addr; // flush and disable I/D cache __asm__ __volatile__ ("mfspr 3, 1008" ::: "r3"); __asm__ __volatile__ ("ori 5, 5, 0xcc00" ::: "r5"); __asm__ __volatile__ ("ori 4, 3, 0xc00" ::: "r4"); __asm__ __volatile__ ("andc 5, 3, 5" ::: "r5"); __asm__ __volatile__ ("sync"); __asm__ __volatile__ ("mtspr 1008, 4"); __asm__ __volatile__ ("isync"); __asm__ __volatile__ ("sync"); __asm__ __volatile__ ("mtspr 1008, 5"); __asm__ __volatile__ ("isync"); __asm__ __volatile__ ("sync"); #ifdef CFG_RESET_ADDRESS addr = CFG_RESET_ADDRESS; #else // // note: when CFG_MONITOR_BASE points to a RAM address, // CFG_MONITOR_BASE - sizeof (ulong) is usually a valid // address. Better pick an address known to be invalid on your // system and assign it to CFG_RESET_ADDRESS. /// addr = CFG_MONITOR_BASE - sizeof (ulong); #endif soft_restart(addr); while(1); // not reached } */