Beispiel #1
0
asmlinkage void plat_irq_dispatch(void)
{
	unsigned int pending;

	pending = read_c0_cause() & read_c0_status() & ST0_IM;

	/* machine-specific plat_irq_dispatch */
	mach_irq_dispatch(pending);
}
Beispiel #2
0
u32 do_general_exception(arch_regs_t *uregs)
{
    u32 cp0_cause = read_c0_cause();
    u32 cp0_status = read_c0_status();
    mips32_entryhi_t ehi;
    u32 victim_asid;
    u32 victim_inst;
    struct vmm_vcpu *c_vcpu;
    u8 delay_slot_exception = IS_BD_SET(cp0_cause);

    ehi._entryhi = read_c0_entryhi();
    victim_asid = ehi._s_entryhi.asid >> ASID_SHIFT;
    c_vcpu = vmm_scheduler_current_vcpu();

    /*
     * When exception is happening in the delay slot. We need to emulate
     * the corresponding branch instruction first. If its one of the "likely"
     * instructions, we don't need to emulate the faulting instruction since
     * "likely" instructions don't allow slot to be executed if branch is not
     * taken.
     */
    if (delay_slot_exception) {
        victim_inst = *((u32 *)(uregs->cp0_epc + 4));

        /*
         * If this function returns zero, the branch instruction was a
         * "likely" instruction and the branch wasn't taken. So don't
         * execute the delay slot, just return. The correct EPC to return
         * to will be programmed under our feet.
         */
        if (!cpu_vcpu_emulate_branch_and_jump_inst(c_vcpu, *((u32 *)uregs->cp0_epc), uregs)) {
            return VMM_OK;
        }
    } else {
        victim_inst = *((u32 *)uregs->cp0_epc);
    }

    switch (EXCEPTION_CAUSE(cp0_cause)) {
    case EXEC_CODE_COPU:
        cpu_vcpu_emulate_cop_inst(c_vcpu, victim_inst, uregs);

        if (!delay_slot_exception)
            uregs->cp0_epc += 4;

        break;

    case EXEC_CODE_TLBL:
        if (CPU_IN_USER_MODE(cp0_status) && is_vmm_asid(ehi._s_entryhi.asid)) {
            ehi._s_entryhi.asid = (0x1 << ASID_SHIFT);
            write_c0_entryhi(ehi._entryhi);
            vmm_panic("CPU is in user mode and ASID is pointing to VMM!!\n");
        }
        break;
    }

    return VMM_OK;
}
void handle_tlb_refill(struct trapframe *tf) {
	unsigned long	entryhi=read_c0_entryhi();
	unsigned long	vpn=TLB_VPN(entryhi);
	unsigned long	pfn=pt[ENTRYHI_ASID(entryhi)][vpn];
	if(pfn) {
		unsigned long entrylo=( TLB_PFN(pfn, entryhi) | TLB_COHERENT | TLB_VALID | TLB_DIRTY | TLB_GLOBAL)^TLB_GLOBAL;
		write_c0_entrylo0(entrylo);
		write_c0_entrylo1(TLB_ELO0TO1(entrylo));
		tlbwr();
	} else {
		kprintf("Fatal error, invalied page: %x with ASID= %d, rebooting...\n",vpn, ENTRYHI_ASID(entryhi));
		unsigned long* reg=(unsigned long*)tf;
		write_c0_status((read_c0_status()|ST_KSU)^ST_KSU);
		reg[ORD_STATUS]=(read_c0_status()|ST_KSU)^ST_KSU;
		reg[ORD_EPC]=__reset;
	}
	return;
}
void arch_vcpu_regs_switch(struct vmm_vcpu *tvcpu, 
			  struct vmm_vcpu *vcpu,
			  arch_regs_t *regs)
{
	if (tvcpu) {
		vmm_memcpy(mips_uregs(tvcpu), regs, sizeof(arch_regs_t));
	}

	if (vcpu) {
		if (!vcpu->is_normal) {
			mips_uregs(vcpu)->cp0_status = read_c0_status() & ~(0x01UL << CP0_STATUS_UM_SHIFT);
		} else {
			mips_uregs(vcpu)->cp0_status = read_c0_status() | (0x01UL << CP0_STATUS_UM_SHIFT);
		}

		vmm_memcpy(regs, mips_uregs(vcpu), sizeof(arch_regs_t));
	}
}
Beispiel #5
0
void save_processor_state(void)
{
	saved_status = read_c0_status();

	if (is_fpu_owner())
		save_fp(current);
	if (cpu_has_dsp)
		save_dsp(current);
}
Beispiel #6
0
/*
 * Get the FPU Implementation/Revision.
 */
static inline unsigned long cpu_get_fpu_id(void)
{
	unsigned long tmp, fpu_id;

	tmp = read_c0_status();
	__enable_fpu();
	fpu_id = read_32bit_cp1_register(CP1_REVISION);
	write_c0_status(tmp);
	return fpu_id;
}
Beispiel #7
0
asmlinkage void plat_irq_dispatch(void)
{
	unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
	if (pending & STATUSF_IP7)		/* cpu timer */
		do_IRQ(7);
	else if (pending & STATUSF_IP2)		/* int0 hardware line */
		ar7_cascade();
	else
		spurious_interrupt();
}
Beispiel #8
0
asmlinkage void plat_irq_dispatch(void)
{
    unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
    if (pending & STATUSF_IP2)
        do_IRQ(2);
    else if (pending & STATUSF_IP3)
        do_IRQ(3);
    else
        spurious_interrupt();
}
Beispiel #9
0
asmlinkage void plat_irq_dispatch(void)
{
	unsigned int pending;
#if defined (CONFIG_RALINK_RT3883) || defined (CONFIG_RALINK_MT7620) || \
    defined (CONFIG_RALINK_MT7628)
	unsigned int pci_status;
#endif

	pending = read_c0_status() & read_c0_cause() & ST0_IM;
	if (!pending) {
		spurious_interrupt();
		return;
	}

	if (pending & CAUSEF_IP7) {
		do_IRQ(SURFBOARDINT_MIPS_TIMER);	// CPU Timer
		return;
	}

	if (pending & CAUSEF_IP5)
		do_IRQ(SURFBOARDINT_FE);		// Frame Engine

	if (pending & CAUSEF_IP6)
		do_IRQ(SURFBOARDINT_WLAN);		// Wireless

	if (pending & CAUSEF_IP4) {
#if defined (CONFIG_RALINK_RT3883)
		pci_status = RALINK_PCI_PCIINT_ADDR;
		if (pci_status & 0x100000)
			do_IRQ(SURFBOARDINT_PCIE0);
#if defined (CONFIG_PCI_ONLY) || defined (CONFIG_PCIE_PCI_CONCURRENT)
		else if (pci_status & 0x040000)
			do_IRQ(SURFBOARDINT_PCI0);
		else
			do_IRQ(SURFBOARDINT_PCI1);
#endif
#elif defined (CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7628)
		pci_status = RALINK_PCI_PCIINT_ADDR;
		if (pci_status & 0x100000)
			do_IRQ(SURFBOARDINT_PCIE0);
#endif
	}

	if (pending & CAUSEF_IP3)
		ralink_hw0_irqdispatch(1);
	else
	if (pending & CAUSEF_IP2)
		ralink_hw0_irqdispatch(0);

#if 0
	/* clear new potentially pending IP6..IP2 */
	set_c0_status( STATUSF_IP6 | STATUSF_IP5 | STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 );
#endif
}
Beispiel #10
0
void mips_cpu_timer_enable(void)
{
	uint32_t sr = read_c0_status();
	sr |= ((0x1UL << 7) << 8);
	write_c0_status(sr);

	uint32_t cause = read_c0_cause();
	cause &= ~(0x1UL << 27);
	write_c0_cause(cause);
	write_c0_compare(read_c0_count() + COUNTER_TICK_COUNT);
}
asmlinkage void plat_irq_dispatch(void)
{
	unsigned int pending = read_c0_status() & read_c0_cause();

	if (pending & STATUSF_IP4)
		pic_dispatch();
	else if (pending & STATUSF_IP7)
		do_IRQ(PNX833X_TIMER_IRQ);
	else
		spurious_interrupt();
}
void __init plat_time_init(void)
{
    /* JU: TBD: there was some special SMP handling added here in original kernel */
    mips_hpt_frequency = calculateCpuSpeed() / 2;
#if defined(CONFIG_BCM_PWRMNGT) || defined(CONFIG_BCM_PWRMNGT_MODULE)
    BcmPwrMngtInitC0Speed();
#else
    // Enable cp0 counter/compare interrupt only when not using power management
    write_c0_status(IE_IRQ5 | read_c0_status());
#endif
}
Beispiel #13
0
asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
{
	u32 pending;

	pending = read_c0_status() & read_c0_cause();

	/*
	 * jump to the correct interrupt routine
	 * These are arranged in priority order and the timer
	 * comes first!
	 */

#ifdef CONFIG_IRQ_MSP_CIC	/* break out the CIC stuff for now */
	if (pending & C_IRQ4)	/* do the peripherals first, that's the timer */
		msp_cic_irq_dispatch();

	else if (pending & C_IRQ0)
		do_IRQ(MSP_INT_MAC0);

	else if (pending & C_IRQ1)
		do_IRQ(MSP_INT_MAC1);

	else if (pending & C_IRQ2)
		do_IRQ(MSP_INT_USB);

	else if (pending & C_IRQ3)
		do_IRQ(MSP_INT_SAR);

	else if (pending & C_IRQ5)
		do_IRQ(MSP_INT_SEC);

#else
	if (pending & C_IRQ5)
		do_IRQ(MSP_INT_TIMER);

	else if (pending & C_IRQ0)
		do_IRQ(MSP_INT_MAC0);

	else if (pending & C_IRQ1)
		do_IRQ(MSP_INT_MAC1);

	else if (pending & C_IRQ3)
		do_IRQ(MSP_INT_VE);

	else if (pending & C_IRQ4)
		msp_slp_irq_dispatch();
#endif

	else if (pending & C_SW0)	/* do software after hardware */
		do_IRQ(MSP_INT_SW0);

	else if (pending & C_SW1)
		do_IRQ(MSP_INT_SW1);
}
Beispiel #14
0
asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
{
	unsigned int pending;

#ifdef CONFIG_SIBYTE_BCM1480_PROF
	/* Set compare to count to silence count/compare timer interrupts */
	write_c0_compare(read_c0_count());
#endif

	pending = read_c0_cause() & read_c0_status();

#ifdef CONFIG_SIBYTE_BCM1480_PROF
	if (pending & CAUSEF_IP7)	/* Cpu performance counter interrupt */
		sbprof_cpu_intr(exception_epc(regs));
	else
#endif

	if (pending & CAUSEF_IP4)
		bcm1480_timer_interrupt(regs);

#ifdef CONFIG_SMP
	else if (pending & CAUSEF_IP3)
		bcm1480_mailbox_interrupt(regs);
#endif

#ifdef CONFIG_KGDB
	else if (pending & CAUSEF_IP6)
		bcm1480_kgdb_interrupt(regs);		/* KGDB (uart 1) */
#endif

	else if (pending & CAUSEF_IP2) {
		unsigned long long mask_h, mask_l;
		unsigned long base;

		/*
		 * Default...we've hit an IP[2] interrupt, which means we've
		 * got to check the 1480 interrupt registers to figure out what
		 * to do.  Need to detect which CPU we're on, now that
		 * smp_affinity is supported.
		 */
		base = A_BCM1480_IMR_MAPPER(smp_processor_id());
		mask_h = __raw_readq(
			IOADDR(base + R_BCM1480_IMR_INTERRUPT_STATUS_BASE_H));
		mask_l = __raw_readq(
			IOADDR(base + R_BCM1480_IMR_INTERRUPT_STATUS_BASE_L));

		if (mask_h) {
			if (mask_h ^ 1)
				do_IRQ(fls64(mask_h) - 1, regs);
			else
				do_IRQ(63 + fls64(mask_l), regs);
		}
	}
}
Beispiel #15
0
/*
 * IRQs on the SEAD board look basically are combined together on hardware
 * interrupt 0 (MIPS IRQ 2)) like:
 *
 *	MIPS IRQ	Source
 *      --------        ------
 *             0	Software (ignored)
 *             1        Software (ignored)
 *             2        UART0 (hw0)
 *             3        UART1 (hw1)
 *             4        Hardware (ignored)
 *             5        Hardware (ignored)
 *             6        Hardware (ignored)
 *             7        R4k timer (what we use)
 *
 * We handle the IRQ according to _our_ priority which is:
 *
 * Highest ----     R4k Timer
 * Lowest  ----     Combined hardware interrupt
 *
 * then we just return, if multiple IRQs are pending then we will just take
 * another exception, big deal.
 */
asmlinkage void plat_irq_dispatch(void)
{
	unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
	int irq;

	irq = irq_ffs(pending);

	if (irq >= 0)
		do_IRQ(MIPSCPU_INT_BASE + irq);
	else
		spurious_interrupt(regs);
}
Beispiel #16
0
asmlinkage void plat_irq_dispatch(void)
{
	unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
	unsigned int i;

	if (pending & CAUSEF_IP7) {
		do_IRQ(MIPS_CPU_TIMER_IRQ);
		goto out;
	} else {
		for (i = 0; i < 5; i++) {
			if (pending & (CAUSEF_IP2 << i)) {
				ltq_hw_irqdispatch(i);
				goto out;
			}
		}
	}
	pr_alert("Spurious IRQ: CAUSE=0x%08x\n", read_c0_status());

out:
	return;
}
Beispiel #17
0
/**
 * Disable access to Octeon's COP2 crypto hardware in the kernel.
 * This must be called after an octeon_crypto_enable() before any
 * context switch or return to userspace.
 *
 * @param state  COP2 state to restore
 * @param flags  Return value from octeon_crypto_enable()
 */
void octeon_crypto_disable(struct octeon_cop2_state *state,
			   unsigned long crypto_flags)
{
	unsigned long flags;

	local_irq_save(flags);
	if (crypto_flags & ST0_CU2)
		octeon_cop2_restore(state);
	else
		write_c0_status(read_c0_status() & ~ST0_CU2);
	local_irq_restore(flags);
}
Beispiel #18
0
asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
{
        unsigned int pending = read_c0_cause() & read_c0_status();

        if (pending & STATUSF_IP7)
                brcm_mips_int7_dispatch(regs);
        else if (pending & STATUSF_IP2)
                brcm_mips_int2_dispatch(regs);
        else
                spurious_interrupt(regs);

}
Beispiel #19
0
asmlinkage void plat_irq_dispatch(void)
{
	unsigned long pending;

	pending = read_c0_status() & read_c0_cause() & ST0_IM;

	if (pending & STATUSF_IP7)
		do_IRQ(ADM5120_IRQ_COUNTER);
	else if (pending & STATUSF_IP2)
		adm5120_intc_irq_dispatch();
	else
		spurious_interrupt();
}
Beispiel #20
0
asmlinkage void plat_irq_dispatch(void)
{
	unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;

	if (pending & STATUSF_IP7)
		do_IRQ(WRPPMC_MIPS_TIMER_IRQ);	/* CPU Compare/Count internal timer */
	else if (pending & STATUSF_IP6)
		do_IRQ(WRPPMC_UART16550_IRQ);	/* UART 16550 port */
	else if (pending & STATUSF_IP3)
		do_IRQ(WRPPMC_PCI_INTA_IRQ);	/* PCI INT_A */
	else
		spurious_interrupt();
}
Beispiel #21
0
void __init arch_init_irq(void)
{
	int i;
	//extern irq_desc_t irq_desc[];

	/* init CPU irqs */
	mips_cpu_irq_init();

	/* init sys irqs */
	sys_irq_base = M36_SYS_IRQ_BASE;
	for (i=sys_irq_base; i < sys_irq_base + M36_NUM_SYS_IRQ; i++)
		irq_set_chip_and_handler(i, &sys_irq_controller,handle_percpu_irq);

	/* Default all ICU IRQs to off and enable IM bit(IP3) of CP0 status for sys IRQ */
#if 	1
	*((unsigned long *)(0xB8000038)) = 0;
	*((unsigned long *)(0xB800003C)) = 0;
	*((unsigned long *)(0xB80000EC)) = 0;
	write_c0_status(read_c0_status() | STATUSF_IP3);
#else
	*M6303_MSYSINT1REG = 0;
	*M6303_MSYSINT2REG = 0;
#endif 

#ifdef CONFIG_REMOTE_DEBUG
	printk("Setting debug traps - please connect the remote debugger.\n");

	set_debug_traps();

	// you may move this line to whereever you want
	breakpoint();
#endif

	if((*(unsigned short *)0xB8000002 == 0x3901)  \
      || (*(unsigned short *)0xB8000002 == 0x3701) \
	  || (*(unsigned short *)0xB8000002 == 0x3503))
	{
		sys_rpc_addr = 0xB8040037;
		sys_rpc_mask = 0x0C;
		sys_rpc_irq1_mask = 0x08;
		sys_rpc_irq2_mask = 0x04;
	}
	else
	{
		sys_rpc_addr = 0xB8040036;
		sys_rpc_mask = 0xC0;
		sys_rpc_irq1_mask = 0x80;
		sys_rpc_irq2_mask = 0x40;		
	}
}
Beispiel #22
0
void mips_spurious_interrupt(struct pt_regs *regs)
{
#if 1
	return;
#else
	unsigned long status, cause;

	printk("got spurious interrupt\n");
	status = read_c0_status();
	cause = read_c0_cause();
	printk("status %x cause %x\n", status, cause);
	printk("epc %x badvaddr %x \n", regs->cp0_epc, regs->cp0_badvaddr);
#endif
}
Beispiel #23
0
/*
 * System irq dispatch
 */
void plat_irq_dispatch(void)
{
	unsigned int pending;

	pending = read_c0_cause() & read_c0_status() & ST0_IM;

	/* timer interrupt, that we renumbered */
	if (pending & STATUSF_IP7)
		do_IRQ(MIPS_CPU_IRQ_BASE + 7);
	else if (pending & STATUSF_IP2)
		adm8668_irq_cascade();
	else
		spurious_interrupt();
}
Beispiel #24
0
static void jzsoc_smp_showregs(void)
{
	int cpu = smp_processor_id();
	unsigned int val;
	printk("CPU%d:\n",cpu);
#define P(reg) do {				\
	val = get_smp_##reg();		\
	printk(#reg ":\t%08x\n",val);	\
} while(0)
	P(ctrl); P(status); P(reim); P(mbox0); P(mbox1);
	//P(val);  P(lock);
	printk("cp0 status:\t%08x\n",read_c0_status());
	printk("cp0 cause:\t%08x\n",read_c0_cause());
	}
Beispiel #25
0
asmlinkage void plat_irq_dispatch(void)
{
	unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
	int irq;

	irq = irq_ffs(pending);

	if (irq == MIPSCPU_INT_I8259A)
		malta_hw0_irqdispatch();
	else if (irq > 0)
		do_IRQ(MIPS_CPU_IRQ_BASE + irq);
	else
		spurious_interrupt();
}
asmlinkage void plat_irq_dispatch(void)
{
    u32 cause;

#if defined(CONFIG_BCM_PWRMNGT)	|| defined(CONFIG_BCM_PWRMNGT_MODULE)
//    BcmPwrMngtResumeFullSpeed();
#endif

    while((cause = (read_c0_cause() & read_c0_status() & CAUSEF_IP))) {
        if (cause & CAUSEF_IP7)
        {
            do_IRQ(MIPS_TIMER_INT);
        }
        else if (cause & CAUSEF_IP0)
            do_IRQ(INTERRUPT_ID_SOFTWARE_0);
        else if (cause & CAUSEF_IP1)
            do_IRQ(INTERRUPT_ID_SOFTWARE_1);
#if defined(CONFIG_BCM93380)
#if defined(CONFIG_BCM_LOT1)
	    else if (cause & CAUSEF_IP4)
            irq_dispatch_int(3);
        else if (cause & CAUSEF_IP6)
            irq_dispatch_int(4);
#endif
	    else if (cause & CAUSEF_IP3)
            irq_dispatch_int(0);
        else if (cause & CAUSEF_IP5)
            irq_dispatch_int(1);
#elif defined(CONFIG_BCMKILAUEA) || defined(CONFIG_BCM93383)
#if defined(CONFIG_BCM_LOT1)
	else if (cause & CAUSEF_IP4)
            irq_dispatch_int(3);
        else if (cause & CAUSEF_IP6)
            irq_dispatch_int(4);
#else
        else if (cause & CAUSEF_IP5)
            irq_dispatch_int(0);
	else if (cause & CAUSEF_IP2)
	    irq_dispatch_int(1);
#endif	
#else
#if defined (CONFIG_SMP)
        else if (cause & (CAUSEF_IP2 | CAUSEF_IP3))
#else 
        else if (cause & CAUSEF_IP2)
#endif
            irq_dispatch_int();
#endif
    }
}
Beispiel #27
0
/*
 * IRQs on the Atlas board look basically like (all external interrupt
 * sources are combined together on hardware interrupt 0 (MIPS IRQ 2)):
 *
 *      MIPS IRQ        Source
 *      --------        ------
 *             0        Software 0 (reschedule IPI on MT)
 *             1        Software 1 (remote call IPI on MT)
 *             2        Combined Atlas hardware interrupt (hw0)
 *             3        Hardware (ignored)
 *             4        Hardware (ignored)
 *             5        Hardware (ignored)
 *             6        Hardware (ignored)
 *             7        R4k timer (what we use)
 *
 * We handle the IRQ according to _our_ priority which is:
 *
 * Highest ----     R4k Timer
 * Lowest  ----     Software 0
 *
 * then we just return, if multiple IRQs are pending then we will just take
 * another exception, big deal.
 */
asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
{
	unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
	int irq;

	irq = irq_ffs(pending);

	if (irq == MIPSCPU_INT_ATLAS)
		atlas_hw0_irqdispatch(regs);
	else if (irq >= 0)
		do_IRQ(MIPSCPU_INT_BASE + irq, regs);
	else
		spurious_interrupt(regs);
}
Beispiel #28
0
void gic_send_ipi(unsigned int intr)
{
#if gic_wedgeb2bok == 0
    unsigned long flags;
#endif
    pr_debug("CPU%d: %s status %08x\n", smp_processor_id(), __func__,
         read_c0_status());
    if (!gic_wedgeb2bok)
        spin_lock_irqsave(&gic_wedgeb2b_lock, flags);
    GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), 0x80000000 | intr);
    if (!gic_wedgeb2bok) {
        (void) GIC_REG(SHARED, GIC_SH_CONFIG);
        spin_unlock_irqrestore(&gic_wedgeb2b_lock, flags);
    }
}
Beispiel #29
0
asmlinkage void plat_irq_dispatch(void)
{
	unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;

	if (pending & STATUSF_IP7)
		do_IRQ(CPU_IRQ_BASE + 7);
	else if (pending & VR5477INTS)
		vrc5477_irq_dispatch();
	else if (pending & STATUSF_IP0)
		do_IRQ(CPU_IRQ_BASE);
	else if (pending & STATUSF_IP1)
		do_IRQ(CPU_IRQ_BASE + 1);
	else
		spurious_interrupt();
}
Beispiel #30
0
asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
{
	unsigned int pending = read_c0_cause() & read_c0_status();

	if (pending & STATUSF_IP7)
		do_IRQ(CPU_IRQ_BASE + 7, regs);
	else if (pending & VR5477INTS)
		vrc5477_irq_dispatch(regs);
	else if (pending & STATUSF_IP0)
		do_IRQ(CPU_IRQ_BASE, regs);
	else if (pending & STATUSF_IP1)
		do_IRQ(CPU_IRQ_BASE + 1, regs);
	else
		spurious_interrupt(regs);
}