static void ip32_unknown_interrupt (struct pt_regs *regs) { u64 crime; u32 mace; printk ("Unknown interrupt occurred!\n"); printk ("cp0_status: %08x\tcp0_cause: %08x\n", read_32bit_cp0_register (CP0_STATUS), read_32bit_cp0_register (CP0_CAUSE)); crime = crime_read_64 (CRIME_INT_MASK); printk ("CRIME interrupt mask: %016lx\n", crime); crime = crime_read_64 (CRIME_INT_STAT); printk ("CRIME interrupt status: %016lx\n", crime); crime = crime_read_64 (CRIME_HARD_INT); printk ("CRIME hardware interrupt register: %016lx\n", crime); mace = mace_read_32 (MACEISA_INT_MASK); printk ("MACE ISA interrupt mask: %08x\n", mace); mace = mace_read_32 (MACEISA_INT_STAT); printk ("MACE ISA interrupt status: %08x\n", mace); mace = mace_read_32 (MACEPCI_CONTROL); printk ("MACE PCI control register: %08x\n", mace); printk("Register dump:\n"); show_regs(regs); printk("Please mail this report to [email protected]\n"); printk("Spinning..."); while(1) ; }
int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, unsigned long unused, struct task_struct * p, struct pt_regs * regs) { struct pt_regs * childregs; long childksp; extern void save_fp(void*); childksp = (unsigned long)p + KERNEL_STACK_SIZE - 32; if (last_task_used_math == current) if (mips_cpu.options & MIPS_CPU_FPU) { __enable_fpu(); save_fp(p); } /* set up new TSS. */ childregs = (struct pt_regs *) childksp - 1; *childregs = *regs; set_gpreg(childregs, 7, 0); /* Clear error flag */ if(current->personality == PER_LINUX) { set_gpreg(childregs, 2, 0); /* Child gets zero as return value */ set_gpreg(regs, 2, p->pid); } else { /* Under IRIX things are a little different. */ set_gpreg(childregs, 2, 0); set_gpreg(childregs, 3, 1); set_gpreg(regs, 2, p->pid); set_gpreg(regs, 3, 0); } if (childregs->cp0_status & ST0_CU0) { set_gpreg(childregs, 28, (unsigned long) p); set_gpreg(childregs, 29, childksp); p->thread.current_ds = KERNEL_DS; } else { set_gpreg(childregs, 29, usp); p->thread.current_ds = USER_DS; } p->thread.reg29 = (unsigned long) childregs; p->thread.reg31 = (unsigned long) ret_from_fork; /* * New tasks loose permission to use the fpu. This accelerates context * switching for most programs since they don't use the fpu. */ #ifdef CONFIG_PS2 /* keep COP2 usable bit to share the VPU0 context */ p->thread.cp0_status = read_32bit_cp0_register(CP0_STATUS) & ~(ST0_CU1|KU_MASK); childregs->cp0_status &= ~(ST0_CU1); #else p->thread.cp0_status = read_32bit_cp0_register(CP0_STATUS) & ~(ST0_CU2|ST0_CU1|KU_MASK); childregs->cp0_status &= ~(ST0_CU2|ST0_CU1); #endif return 0; }
void ps2_be_board_handler(struct pt_regs *regs) { u_int sr, paddr; sr = read_32bit_cp0_register(CP0_STATUS); paddr = read_32bit_cp0_register($23); /* BadPAddr */ force_sig(SIGBUS, current); show_regs(regs); printk("paddr : %08x\n", paddr); write_32bit_cp0_register(CP0_STATUS, sr & ~(1 << 12)); /* clear BM */ }
asmlinkage void init_arch(int argc, char **argv, char **envp, int *prom_vec) { unsigned int s; /* Disable coprocessors */ s = read_32bit_cp0_register(CP0_STATUS); s &= ~(ST0_CU1|ST0_CU2|ST0_CU3|ST0_KX|ST0_SX); s |= ST0_CU0; write_32bit_cp0_register(CP0_STATUS, s); s = read_32bit_cp0_register(CP0_STATUS); start_kernel(); }
void mips_spurious_interrupt(struct pt_regs *regs) { #if 1 return; #else unsigned long status, cause; printk("got spurious interrupt\n"); status = read_32bit_cp0_register(CP0_STATUS); cause = read_32bit_cp0_register(CP0_CAUSE); printk("status %x cause %x\n", status, cause); printk("epc %x badvaddr %x \n", regs->cp0_epc, regs->cp0_badvaddr); // while(1); #endif }
void __init mips_time_init(void) { unsigned int est_freq, flags; __save_and_cli(flags); /* Set Data mode - binary. */ CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL); printk("calculating r4koff... "); r4k_offset = cal_r4koff(); printk("%08x(%d)\n", r4k_offset, r4k_offset); if ((read_32bit_cp0_register(CP0_PRID) & 0xffff00) == (PRID_COMP_MIPS | PRID_IMP_20KC)) est_freq = r4k_offset*HZ; else est_freq = 2*r4k_offset*HZ; est_freq += 5000; /* round */ est_freq -= est_freq%10000; printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, (est_freq%1000000)*100/1000000); __restore_flags(flags); }
static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask) { unsigned long status = read_32bit_cp0_register(CP0_STATUS); status &= ~((clr_mask & 0xFF) << 8); status |= (set_mask & 0xFF) << 8; write_32bit_cp0_register(CP0_STATUS, status); }
static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { /* Clear the interrupt. */ int val; int status; REG32(TCIR) |= TCIR_TC0IP; #ifdef CONFIG_REMOTE_DEBUG /* call the generic one */ if (kdb_port_info.state) { /* need to init device first */ status = serial_in(&kdb_port_info,UART_LSR); if (status) { if (status & (UART_LSR_BI | UART_LSR_FE)) serial_out(&kdb_port_info,UART_LSR_BI,status); else { val=serial_in(&kdb_port_info, UART_RX); if(val ==(int)'\003') set_async_breakpoint(read_32bit_cp0_register(CP0_EPC)); } } } #endif do_timer(regs); }
void ev64120_setup(void) { unsigned int i, j; //printk(KERN_INFO "ev64120_setup\n"); _machine_restart = galileo_machine_restart; _machine_halt = galileo_machine_halt; _machine_power_off = galileo_machine_power_off; rtc_ops = &galileo_rtc_ops; board_time_init = galileo_time_init; set_io_port_base(KSEG1); #ifdef CONFIG_L2_L3_CACHE #error "external cache not implemented yet" config_register = read_32bit_cp0_register(CP0_CONFIG); printk("\n\n\nchecking second level cache cp0_config = %08lx\n", config_register); if (config_register & CONF_SC) { // second/third level cache available config_register = config_register & (1 << 12); write_32bit_cp0_register(CP0_CONFIG, config_register); printk ("\n\n\nchecking second level cache cp0_config = %08lx\n", config_register); } #endif }
static int __init au1000_init_module(void) { int i; int prid; int base_addr, irq; prid = read_32bit_cp0_register(CP0_PRID); for (i=0; i<NUM_INTERFACES; i++) { if ( (prid & 0xffff0000) == 0x00030000 ) { base_addr = au1000_iflist[i].port; irq = au1000_iflist[i].irq; } else if ( (prid & 0xffff0000) == 0x01030000 ) { base_addr = au1500_iflist[i].port; irq = au1500_iflist[i].irq; } else if ( (prid & 0xffff0000) == 0x02030000 ) { base_addr = au1100_iflist[i].port; irq = au1100_iflist[i].irq; } else { printk(KERN_ERR "au1000 eth: unknown Processor ID\n"); return -ENODEV; } // check for valid entries, au1100 only has one entry if (base_addr && irq) { if (au1000_probe1(NULL, base_addr, irq, i) != 0) { return -ENODEV; } } } return 0; }
static void __inline__ enable_all(void) { unsigned long int_status; int_status = read_32bit_cp0_register(CP0_STATUS); int_status |= 0x1; write_32bit_cp0_register(CP0_STATUS, int_status); }
static void disable_rt2880_cp_int(unsigned int IP_X) { unsigned long int_status; int_status = read_32bit_cp0_register(CP0_STATUS); int_status = int_status & ~(IP_X); write_32bit_cp0_register(CP0_STATUS, int_status); }
unsigned long fixed_rate_gettimeoffset(void) { u32 count; unsigned long res; /* Get last timer tick in absolute kernel time */ count = read_32bit_cp0_register(CP0_COUNT); /* .. relative to previous jiffy (32 bits is enough) */ count -= timerlo; __asm__("multu\t%1,%2\n\t" "mfhi\t%0" :"=r" (res) :"r" (count), "r" (sll32_usecs_per_cycle)); /* * Due to possible jiffies inconsistencies, we need to check * the result so that we'll get a timer that is monotonic. */ if (res >= USECS_PER_JIFFY) res = USECS_PER_JIFFY-1; return res; }
static void disable_rt2880_irq(unsigned int irq) { unsigned long int_status; int_status = read_32bit_cp0_register(CP0_STATUS); if ( irq == 3) int_status = int_status & ~(CAUSEF_IP5); write_32bit_cp0_register(CP0_STATUS, int_status); }
inline unsigned int clear_cp0_status(unsigned int clear) { unsigned int res; res = read_32bit_cp0_register(CP0_STATUS); res &= ~clear; write_32bit_cp0_register(CP0_STATUS, res); }
void dump_tlb(int first, int last) { int i; unsigned int asid; unsigned long entryhi, entrylo0; asid = get_entryhi() & 0xfc0; for(i=first;i<=last;i++) { write_32bit_cp0_register(CP0_INDEX, i<<8); __asm__ __volatile__( ".set\tnoreorder\n\t" "tlbr\n\t" "nop\n\t" ".set\treorder"); entryhi = read_32bit_cp0_register(CP0_ENTRYHI); entrylo0 = read_32bit_cp0_register(CP0_ENTRYLO0); /* Unused entries have a virtual address of KSEG0. */ if ((entryhi & 0xffffe000) != 0x80000000 && (entryhi & 0xfc0) == asid) { /* * Only print entries in use */ printk("Index: %2d ", i); printk("va=%08lx asid=%08lx" " [pa=%06lx n=%d d=%d v=%d g=%d]", (entryhi & 0xffffe000), entryhi & 0xfc0, entrylo0 & PAGE_MASK, (entrylo0 & (1 << 11)) ? 1 : 0, (entrylo0 & (1 << 10)) ? 1 : 0, (entrylo0 & (1 << 9)) ? 1 : 0, (entrylo0 & (1 << 8)) ? 1 : 0); } } printk("\n"); set_entryhi(asid); }
/* * Get the FPU Implementation/Revision. */ static inline unsigned long cpu_get_fpu_id(void) { unsigned long tmp, fpu_id; tmp = read_32bit_cp0_register(CP0_STATUS); __enable_fpu(); fpu_id = read_32bit_cp1_register(CP1_REVISION); write_32bit_cp0_register(CP0_STATUS, tmp); return fpu_id; }
void __init time_init(void) { unsigned int est_freq; printk("calculating r4koff... "); r4k_offset = cal_r4koff(); printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset); //est_freq = 2*r4k_offset*HZ; est_freq = r4k_offset*HZ; est_freq += 5000; /* round */ est_freq -= est_freq%10000; printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, (est_freq%1000000)*100/1000000); set_au1000_speed(est_freq); set_au1000_lcd_clock(); // program the LCD clock r4k_cur = (read_32bit_cp0_register(CP0_COUNT) + r4k_offset); write_32bit_cp0_register(CP0_COMPARE, r4k_cur); /* no RTC on the pb1000 */ xtime.tv_sec = 0; xtime.tv_usec = 0; #ifdef CONFIG_PM /* * setup counter 0, since it keeps ticking after a * 'wait' instruction has been executed. The CP0 timer and * counter 1 do NOT continue running after 'wait' * * It's too early to call request_irq() here, so we handle * counter 0 interrupt as a special irq and it doesn't show * up under /proc/interrupts. */ while (readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S); writel(0, SYS_TOYWRITE); while (readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S); writel(readl(SYS_WAKEMSK) | (1<<8), SYS_WAKEMSK); writel(~0, SYS_WAKESRC); au_sync(); while (readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20); /* setup match20 to interrupt once every 10ms */ last_pc0 = last_match20 = readl(SYS_TOYREAD); writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2); au_sync(); while (readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20); startup_match20_interrupt(); #endif //set_cp0_status(ALLINTS); au_sync(); }
void __init mips_timer_setup(struct irqaction *irq) { /* we are using the cpu counter for timer interrupts */ irq->handler = no_action; /* we use our own handler */ setup_irq(MIPS_CPU_TIMER_IRQ, irq); /* to generate the first timer interrupt */ r4k_cur = (read_32bit_cp0_register(CP0_COUNT) + r4k_offset); write_32bit_cp0_register(CP0_COMPARE, r4k_cur); set_cp0_status(ALLINTS); }
void setup_arch(void) { unsigned long s; s = read_32bit_cp0_register(CP0_STATUS); s |= ST0_BEV; s ^= ST0_BEV; //s |= IE_IRQ0 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5; //wei del s |= IE_IRQ0 | IE_IRQ1|IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5; //wei add, david teach for use timer IRQ 3 write_32bit_cp0_register(CP0_STATUS, s); return ; }
void au1000_restart(char *command) { /* Set all integrated peripherals to disabled states */ u32 prid = read_32bit_cp0_register(CP0_PRID); printk(KERN_NOTICE "\n** Resetting Integrated Peripherals\n"); switch (prid & 0xFF000000) { case 0x00000000: /* Au1000 */ outl(0x02, 0xb0000010); /* ac97_enable */ outl(0x08, 0xb017fffc); /* usbh_enable - early errata */ asm("sync"); outl(0x00, 0xb017fffc); /* usbh_enable */ outl(0x00, 0xb0200058); /* usbd_enable */ outl(0x00, 0xb0300040); /* ir_enable */ outl(0x00, 0xb0520000); /* macen0 */ outl(0x00, 0xb0520004); /* macen1 */ outl(0x00, 0xb1000008); /* i2s_enable */ outl(0x00, 0xb1100100); /* uart0_enable */ outl(0x00, 0xb1200100); /* uart1_enable */ outl(0x00, 0xb1300100); /* uart2_enable */ outl(0x00, 0xb1400100); /* uart3_enable */ outl(0x02, 0xb1600100); /* ssi0_enable */ outl(0x02, 0xb1680100); /* ssi1_enable */ outl(0x00, 0xb1900020); /* sys_freqctrl0 */ outl(0x00, 0xb1900024); /* sys_freqctrl1 */ outl(0x00, 0xb1900028); /* sys_clksrc */ outl(0x00, 0xb1900100); /* sys_pininputen */ break; case 0x01000000: /* Au1500 */ outl(0x02, 0xb0000010); /* ac97_enable */ outl(0x08, 0xb017fffc); /* usbh_enable - early errata */ asm("sync"); outl(0x00, 0xb017fffc); /* usbh_enable */ outl(0x00, 0xb0200058); /* usbd_enable */ outl(0x00, 0xb1520000); /* macen0 */ outl(0x00, 0xb1520004); /* macen1 */ outl(0x00, 0xb1100100); /* uart0_enable */ outl(0x00, 0xb1400100); /* uart3_enable */ outl(0x00, 0xb1900020); /* sys_freqctrl0 */ outl(0x00, 0xb1900024); /* sys_freqctrl1 */ outl(0x00, 0xb1900028); /* sys_clksrc */ outl(0x00, 0xb1900100); /* sys_pininputen */ default: break; } set_cp0_status((ST0_BEV | ST0_ERL)); set_cp0_config(CONF_CM_UNCACHED); flush_cache_all(); write_32bit_cp0_register(CP0_WIRED, 0); __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000)); }
static int read_proc_watchpoint(char * pBuffer, char **start, off_t offset, int length, int *eof, void *data) { int len = 0; unsigned long watchHi, watchLo; watchHi = read_32bit_cp0_register(CP0_WATCHHI); watchLo = read_32bit_cp0_register(CP0_WATCHLO); len = sprintf(pBuffer, "0x%08lx\n", watchLo) - offset; if (len < length) { *eof = 1; if (len <= 0) return 0; } else { len = length; } *start = pBuffer + offset; return len; }
inline unsigned int change_cp0_status(unsigned int change, unsigned int newvalue) { unsigned int res; res = read_32bit_cp0_register(CP0_STATUS); res &= ~change; res |= (newvalue & change); write_32bit_cp0_register(CP0_STATUS, res); return res; }
void mips_timer_interrupt(struct pt_regs *regs) { int irq = 63; unsigned long count; int cpu = smp_processor_id(); irq_enter(cpu, irq); kstat.irqs[cpu][irq]++; #ifdef CONFIG_PM printk(KERN_ERR "Unexpected CP0 interrupt\n"); regs->cp0_status &= ~IE_IRQ5; /* disable CP0 interrupt */ return; #endif if (r4k_offset == 0) goto null; do { count = read_32bit_cp0_register(CP0_COUNT); timerhi += (count < timerlo); /* Wrap around */ timerlo = count; kstat.irqs[0][irq]++; do_timer(regs); r4k_cur += r4k_offset; ack_r4ktimer(r4k_cur); } while (((unsigned long)read_32bit_cp0_register(CP0_COUNT) - r4k_cur) < 0x7fffffff); irq_exit(cpu, irq); if (softirq_pending(cpu)) do_softirq(); return; null: ack_r4ktimer(0); }
static inline void r49_flush_cache_all_d32i32(void) { unsigned long flags, config; __save_and_cli(flags); blast_dcache32_wayLSB(); /* disable icache (set ICE#) */ config = read_32bit_cp0_register(CP0_CONFIG); write_32bit_cp0_register(CP0_CONFIG, config|TX49_CONF_IC); blast_icache32_wayLSB(); write_32bit_cp0_register(CP0_CONFIG, config); __restore_flags(flags); }
void __init it8172_timer_setup(struct irqaction *irq) { puts("timer_setup\n"); put32(NR_IRQS); puts(""); /* we are using the cpu counter for timer interrupts */ setup_irq(MIPS_CPU_TIMER_IRQ, irq); /* to generate the first timer interrupt */ r4k_cur = (read_32bit_cp0_register(CP0_COUNT) + r4k_offset); write_32bit_cp0_register(CP0_COMPARE, r4k_cur); set_cp0_status(ALLINTS); }
void __init arch_init_irq(void) { int i; /* * Mask out all interrupt by writing "1" to all bit position in * the interrupt reset reg. */ #if 1 int mips_cp0_cause, mips_cp0_status; mips_cp0_cause = read_32bit_cp0_register(CP0_CAUSE); mips_cp0_status = read_32bit_cp0_register(CP0_STATUS); printk("cause = %x, status = %x\n", mips_cp0_cause, mips_cp0_status); mips_cp0_status= mips_cp0_status& ~(CAUSEF_IP0|CAUSEF_IP1|CAUSEF_IP2|CAUSEF_IP3|CAUSEF_IP4|CAUSEF_IP5|CAUSEF_IP6|CAUSEF_IP7); write_32bit_cp0_register(CP0_STATUS, mips_cp0_status); #endif memset(irq_desc, 0, sizeof(irq_desc)); for (i = 0; i <= SURFBOARDINT_END; i++) { set_irq_chip(i, &surfboard_irq_type); } /* Enable global interrupt bit */ // surfboard_hw0_icregs->intDisable = 0xffffffff; surfboard_hw0_icregs->intEnable = M_SURFBOARD_GLOBAL_INT; #ifdef CONFIG_RALINK_GPIO ralink_gpio_init_irq(); #endif #ifdef CONFIG_KGDB if (remote_debug) { set_debug_traps(); breakpoint(); } #endif }
int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, unsigned long unused, struct task_struct * p, struct pt_regs * regs) { struct pt_regs * childregs; long childksp; extern void save_fp(void*); childksp = (unsigned long)p + KERNEL_STACK_SIZE - 32; if (last_task_used_math == current) { set_cp0_status(ST0_CU1, ST0_CU1); save_fp(p); } /* set up new TSS. */ childregs = (struct pt_regs *) childksp - 1; *childregs = *regs; childregs->regs[7] = 0; /* Clear error flag */ if(current->personality == PER_LINUX) { childregs->regs[2] = 0; /* Child gets zero as return value */ regs->regs[2] = p->pid; } else { /* Under IRIX things are a little different. */ childregs->regs[2] = 0; childregs->regs[3] = 1; regs->regs[2] = p->pid; regs->regs[3] = 0; } if (childregs->cp0_status & ST0_CU0) { childregs->regs[28] = (unsigned long) p; childregs->regs[29] = childksp; p->thread.current_ds = KERNEL_DS; } else { childregs->regs[29] = usp; p->thread.current_ds = USER_DS; } p->thread.reg29 = (unsigned long) childregs; p->thread.reg31 = (unsigned long) ret_from_fork; /* * New tasks loose permission to use the fpu. This accelerates context * switching for most programs since they don't use the fpu. */ p->thread.cp0_status = read_32bit_cp0_register(CP0_STATUS) & ~(ST0_CU3|ST0_CU2|ST0_CU1|KU_MASK); childregs->cp0_status &= ~(ST0_CU3|ST0_CU2|ST0_CU1); return 0; }
void __init arch_init_irq(void) { int i; /* * Mask out all interrupt by writing "1" to all bit position in * the interrupt reset reg. */ #if 0 int mips_cp0_cause, mips_cp0_status; mips_cp0_cause = read_32bit_cp0_register(CP0_CAUSE); mips_cp0_status = read_32bit_cp0_register(CP0_STATUS); printk("cause = %x, status = %x\n", mips_cp0_cause, mips_cp0_status); mips_cp0_status= mips_cp0_status& ~(CAUSEF_IP0|CAUSEF_IP1|CAUSEF_IP2|CAUSEF_IP3|CAUSEF_IP4|CAUSEF_IP5|CAUSEF_IP6|CAUSEF_IP7); write_32bit_cp0_register(CP0_STATUS, mips_cp0_status); #endif mips_cpu_irq_init(); for (i = 0; i <= SURFBOARDINT_END; i++) { set_irq_chip_and_handler(i, &surfboard_irq_type, handle_level_irq); } /* Enable global interrupt bit */ *(volatile u32 *)(RALINK_INTENA) = M_SURFBOARD_GLOBAL_INT; #ifdef CONFIG_RALINK_GPIO ralink_gpio_init_irq(); #endif set_c0_status(ST0_IM); #ifdef CONFIG_KGDB if (remote_debug) { set_debug_traps(); breakpoint(); } #endif }
/* * Probe whether cpu has config register by trying to play with * alternate cache bit and see whether it matters. * It's used by cpu_probe to distinguish between R3000A and R3081. */ static inline int cpu_has_confreg(void) { #ifdef CONFIG_CPU_R3000 extern unsigned long r3k_cache_size(unsigned long); unsigned long size1, size2; unsigned long cfg = read_32bit_cp0_register(CP0_CONF); size1 = r3k_cache_size(ST0_ISC); write_32bit_cp0_register(CP0_CONF, cfg^CONF_AC); size2 = r3k_cache_size(ST0_ISC); write_32bit_cp0_register(CP0_CONF, cfg); return size1 != size2; #else return 0; #endif }