--- zzzz-none-000/linux-2.6.32.61/arch/mips/kernel/genex.S 2013-06-10 09:43:48.000000000 +0000 +++ virian-300e-630/linux-2.6.32.61/arch/mips/kernel/genex.S 2014-06-26 16:17:09.000000000 +0000 @@ -21,6 +21,9 @@ #include #include #include +#if CONFIG_ATH_DDR_RELEASE_TIMER +#include +#endif #define PANIC_PIC(msg) \ .set push; \ @@ -60,6 +63,21 @@ #ifdef CONFIG_64BIT dsll k1, k1, 1 #endif +#ifdef CONFIG_MIPS_MT_SMTC +#define FIRST_YIELD_TC 2 + /*--------------------------------------------------------------------------------*\ + * AVM(mbahr): special exception handling for yield-context + \*--------------------------------------------------------------------------------*/ + mfc0 k0, CP0_TCBIND + sra k0, k0, TCBIND_CURTC_SHIFT + andi k0, k0, 0xff + slti k0, k0, FIRST_YIELD_TC + bnez k0, 1f + nop + j yield_exception_handler + nop +1: +#endif PTR_L k0, exception_handlers(k1) jr k0 .set pop @@ -195,6 +213,73 @@ 1: .set pop #endif + +#if CONFIG_ATH_DDR_RELEASE_TIMER + /* Check whether the MISC interrupt is enabled and present */ + mfc0 k0, CP0_STATUS, 0 + mfc0 k1, CP0_CAUSE, 0 + and k0, k0, k1 + andi k0, k0, CAUSEF_IP6 + beqz k0, 2f + + /* Check whether the interrupt is Timer interrupt in the MISC space */ + li k0, RST_GENERAL_BASE + lw k1, RST_MISC_INTERRUPT_STATUS_OFFSET(k0) + lw k0, RST_MISC_INTERRUPT_MASK_OFFSET(k0) + and k0, k0, k1 + andi k0, k0, RST_MISC_INTERRUPT_STATUS_TIMER2_INT_MASK + beqz k0, 2f + + /* Clear the interrupt */ + li k0, RST_GENERAL_BASE + lw k1, RST_MISC_INTERRUPT_STATUS_OFFSET(k0) + ori k1, k1, RST_MISC_INTERRUPT_STATUS_TIMER2_INT_MASK + xori k1, k1, RST_MISC_INTERRUPT_STATUS_TIMER2_INT_MASK + sw k1, RST_MISC_INTERRUPT_STATUS_OFFSET(k0) + +#if 0 + /* Fixed delay Part of the routine */ + li k1, 0x200 +3: + addiu k1, k1, -1 + bnez k1, 3b + nop +#else + /* Save GPRS a0, a1 for using them in this routine */ + li k0, KSEG1ADDR(ATH_SRAM_BASE) + sw a0, 0x0(k0) + sw a1, 0x4(k0) + + /* Reset the DDR Performance counters - Client is CPU */ + li k0, DDR_CONFIG_BASE + li k1, 0x7 + sw k1, DDRMON_CTL_OFFSET(k0) + sw $0, DDRMON_CTL_OFFSET(k0) + + /* Delay between reading the Performance counters while polling */ + lw k1, DDRMON_GNT_OFFSET(k0) +4: + ori a0, k1, 0x0 + li a1, 0x20 +12: + addiu a1, a1, -1 + bnez a1, 12b + + /* Read and compare whether the CPU didnt get any grant */ + lw k1, DDRMON_GNT_OFFSET(k0) + bne a0, k1, 4b + + /* Put the values back to a0 and a1 and continue */ + li k0, KSEG1ADDR(ATH_SRAM_BASE) + lw a0, 0x0(k0) + lw a1, 0x4(k0) + +#endif +5: + eret + +2: +#endif SAVE_ALL CLI TRACE_IRQS_OFF @@ -217,7 +302,11 @@ * to fit into space reserved for the exception handler. */ NESTED(except_vec4, 0, sp) -1: j 1b /* Dummy, will be replaced */ +FEXPORT(except_vec4_lui) + lui k0, 0 /* Patched */ +FEXPORT(except_vec4_ori) + ori k0, 0 /* Patched */ + jr k0 END(except_vec4) /* @@ -278,6 +367,7 @@ * service routine will have cleared the state, and any active * level represents a new or otherwised unserviced event... */ + mfc0 t1, CP0_STATUS and t0, a0, t1 #ifdef CONFIG_MIPS_MT_SMTC_IM_BACKSTOP @@ -359,6 +449,70 @@ __FINIT +#ifdef CONFIG_MIPS_MT_SMTC +/*--------------------------------------------------------------------------------*\ + * AVM(mbahr): special exception handling for yield-context + * do not save some register on linux-stack !!! +\*--------------------------------------------------------------------------------*/ +NESTED(yield_exception_handler, PT_SIZE, sp) + .set push + .set noat + .set mips32r2 + bgtz sp, 2f /* < check for valid: YIELD-SP < KSEG0 -> pt_regs == NULL */ + lui k0,0x9000 /* < check for valid: YIELD-SP >= KSEG1 -> pt_regs == NULL */ + sltu k0, sp,k0 + beqz k0, 2f + move k0, sp + move k1, sp + .set noreorder + PTR_SUBU k1, PT_SIZE + move sp, k1 + LONG_S k0, PT_R29(sp) + LONG_S $3, PT_R3(sp) + LONG_S $0, PT_R0(sp) + mfc0 v1, CP0_STATUS + LONG_S $2, PT_R2(sp) + LONG_S v1, PT_STATUS(sp) + mfc0 v1, CP0_TCSTATUS + LONG_S $4, PT_R4(sp) + LONG_S v1, PT_TCSTATUS(sp) + mfc0 v1, CP0_CAUSE + LONG_S $5, PT_R5(sp) + LONG_S v1, PT_CAUSE(sp) + LONG_S $6, PT_R6(sp) + MFC0 v1, CP0_EPC + LONG_S $7, PT_R7(sp) + LONG_S v1, PT_EPC(sp) + LONG_S $25, PT_R25(sp) + LONG_S $28, PT_R28(sp) + MFC0 v1, CP0_BADVADDR + LONG_S $31, PT_R31(sp) + PTR_S v1, PT_BVADDR(sp) + SAVE_AT + SAVE_TEMP + SAVE_STATIC + + jal do_yield + move a0, k1 /* pt_reg */ + move k0, v0 /* new stackpointer */ + LONG_L v1, PT_R4(sp) + LONG_L v0, PT_R3(sp) + PTR_ADDU sp, PT_SIZE + beqz k0, 1f + nop + move sp, k0 +1: + eret + nop +2: + jal do_yield + move a0, zero + eret + nop + .set pop + END(yield_exception_handler) +#endif + NESTED(nmi_handler, PT_SIZE, sp) .set push .set noat