kernel/eka/include/nkernsmp/arm/entry.h
branchRCL_3
changeset 44 3e88ff8f41d5
parent 43 c1f20ce4abcf
equal deleted inserted replaced
43:c1f20ce4abcf 44:3e88ff8f41d5
    38 extern void btrace_irq_entry(TInt);
    38 extern void btrace_irq_entry(TInt);
    39 extern void btrace_fiq_entry();
    39 extern void btrace_fiq_entry();
    40 #endif
    40 #endif
    41 
    41 
    42 extern void handle_crash_ipi();
    42 extern void handle_crash_ipi();
    43 extern void handle_indirect_powerdown_ipi();
       
    44 
    43 
    45 #ifdef _DEBUG
    44 #ifdef _DEBUG
    46 extern void __DebugMsgIrq(TUint aIrqNumber);
    45 extern void __DebugMsgIrq(TUint aIrqNumber);
    47 #endif
    46 #endif
    48 
    47 
   123 #endif
   122 #endif
   124 	GET_RWNO_TID(,r4);
   123 	GET_RWNO_TID(,r4);
   125 	asm("mov	r5, sp ");
   124 	asm("mov	r5, sp ");
   126 	asm("str	r1, [sp, #%a0]" : : "i" _FOFF(SThreadExcStack,iExcCode));	// word describing exception type
   125 	asm("str	r1, [sp, #%a0]" : : "i" _FOFF(SThreadExcStack,iExcCode));	// word describing exception type
   127 	__ASM_STI2_MODE(MODE_SYS);			// mode_sys, IRQs off, FIQs on
   126 	__ASM_STI2_MODE(MODE_SYS);			// mode_sys, IRQs off, FIQs on
   128 	asm("ldr	sp, [r4, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iIrqStackTop));
   127 	asm("ldr	sp, [r4, #%a0]" : : "i" _FOFF(TSubScheduler, i_IrqStackTop));
   129 	USER_MEMORY_GUARD_ON(,r8,r0);		// r8 = original DACR if user memory guards in use
   128 	USER_MEMORY_GUARD_ON(,r8,r0);		// r8 = original DACR if user memory guards in use
   130 
   129 
   131 	asm("nested_irq_rejoin: ");
   130 	asm("nested_irq_rejoin: ");
   132 	asm("ldr	r0, [r4, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iIrqCount));
   131 	asm("ldr	r0, [r4, #%a0]" : : "i" _FOFF(TSubScheduler, i_IrqCount));
   133 	asm("ldr	r7, [r4, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iIrqNestCount));
   132 	asm("ldr	r7, [r4, #%a0]" : : "i" _FOFF(TSubScheduler, i_IrqNestCount));
   134 	asm("ldr	r12, __ArmInterrupt ");
   133 	asm("ldr	r12, __ArmInterrupt ");
   135 	asm("ldr	r10, _ArmVectorIrq ");
   134 	asm("ldr	r10, _ArmVectorIrq ");
   136 	asm("add	r0, r0, #1 ");
   135 	asm("add	r0, r0, #1 ");
   137 	asm("add	r7, r7, #1 ");
   136 	asm("add	r7, r7, #1 ");
   138 	__DATA_MEMORY_BARRIER_Z__(r2);		// ensure memory accesses in interrupted code are observed before
   137 	__DATA_MEMORY_BARRIER_Z__(r2);		// ensure memory accesses in interrupted code are observed before
   139 										// the writes to i_IrqCount, i_IrqNestCount
   138 										// the writes to i_IrqCount, i_IrqNestCount
   140 	asm("str	r0, [r4, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iIrqCount));		// increment i_IrqCount
   139 	asm("str	r0, [r4, #%a0]" : : "i" _FOFF(TSubScheduler, i_IrqCount));		// increment i_IrqCount
   141 	asm("ldr	r11, [r12,#%a0]" : : "i" _FOFF(SArmInterruptInfo,iIrqHandler));		// address if IRQ handler
   140 	asm("ldr	r11, [r12,#%a0]" : : "i" _FOFF(SArmInterruptInfo,iIrqHandler));	// address of IRQ handler
   142 	asm("ldr	r6, [r4, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iGicCpuIfcAddr));
   141 	asm("ldr	r6, [r4, #%a0]" : : "i" _FOFF(TSubScheduler, i_GicCpuIfcAddr));
   143 	asm("str	r7, [r4, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iIrqNestCount));	// increment i_IrqNestCount
   142 	asm("str	r7, [r4, #%a0]" : : "i" _FOFF(TSubScheduler, i_IrqNestCount));	// increment i_IrqNestCount
   144 
   143 
   145 	asm("1: ");
   144 	asm("1: ");
   146 #ifdef BTRACE_CPU_USAGE
   145 #ifdef BTRACE_CPU_USAGE
   147 	asm("ldr	r2, __BTraceCpuUsageFilter ");
   146 	asm("ldr	r2, __BTraceCpuUsageFilter ");
   148 #endif
   147 #endif
   186 	asm("beq	do_resched_ipi ");
   185 	asm("beq	do_resched_ipi ");
   187 	asm("cmp	r2, #%a0" : : "i" ((TInt)GENERIC_IPI_VECTOR));
   186 	asm("cmp	r2, #%a0" : : "i" ((TInt)GENERIC_IPI_VECTOR));
   188 	asm("beq	do_generic_ipi ");
   187 	asm("beq	do_generic_ipi ");
   189 	asm("cmp	r2, #%a0" : : "i" ((TInt)TRANSFERRED_IRQ_VECTOR));
   188 	asm("cmp	r2, #%a0" : : "i" ((TInt)TRANSFERRED_IRQ_VECTOR));
   190 	asm("beq	do_transferred_ipi ");
   189 	asm("beq	do_transferred_ipi ");
   191 	asm("cmp	r2, #%a0" : : "i" ((TInt)INDIRECT_POWERDOWN_IPI_VECTOR));
       
   192 	asm("beq	do_indirect_powerdown_ipi ");
       
   193 	asm("cmp	r2, #15 ");
   190 	asm("cmp	r2, #15 ");
   194 	__JUMP(hi,	r11);					// if >15 but not TIMESLICE_VECTOR, call dispatcher
   191 	__JUMP(hi,	r11);					// if >15 but not TIMESLICE_VECTOR, call dispatcher
   195 
   192 
   196 	// else assume CRASH_IPI
   193 	// else assume CRASH_IPI
   197 	asm("str	r0, [r6, #%a0]" : : "i" _FOFF(GicCpuIfc, iEoi));		// acknowledge interrupt
   194 	asm("str	r0, [r6, #%a0]" : : "i" _FOFF(GicCpuIfc, iEoi));		// acknowledge interrupt
   199 	asm("ldr	r1, __HandleCrashIPI ");
   196 	asm("ldr	r1, __HandleCrashIPI ");
   200 	__JUMP(,	r1);					// CRASH IPI, so crash
   197 	__JUMP(,	r1);					// CRASH IPI, so crash
   201 
   198 
   202 	// TIMESLICE, RESCHED or TRANSFERRED
   199 	// TIMESLICE, RESCHED or TRANSFERRED
   203 	asm("do_timeslice_irq: ");
   200 	asm("do_timeslice_irq: ");
   204 	asm("ldr	r2, [r4, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iLocalTimerAddr));
   201 	asm("ldr	r2, [r4, #%a0]" : : "i" _FOFF(TSubScheduler, i_LocalTimerAddr));
   205 	asm("mov	r1, #1 ");
   202 	asm("mov	r1, #1 ");
   206 	asm("str	r1, [r2, #%a0]" : : "i" _FOFF(ArmLocalTimer, iTimerIntStatus));	// clear timer event flag
   203 	asm("str	r1, [r2, #%a0]" : : "i" _FOFF(ArmLocalTimer, iTimerIntStatus));	// clear timer event flag
   207 	asm("do_resched_ipi: ");
   204 	asm("do_resched_ipi: ");
   208 	asm("mov	r1, #1 ");
   205 	asm("mov	r1, #1 ");
   209 	asm("strb	r1, [r4, #%a0]" : : "i" _FOFF(TSubScheduler, iRescheduleNeededFlag));
   206 	asm("strb	r1, [r4, #%a0]" : : "i" _FOFF(TSubScheduler, iRescheduleNeededFlag));
   212 	__DATA_SYNC_BARRIER_Z__(r1);		// ensure writes to i_IrqCount, i_IrqNestCount, iRescheduleNeededFlag complete before SEV
   209 	__DATA_SYNC_BARRIER_Z__(r1);		// ensure writes to i_IrqCount, i_IrqNestCount, iRescheduleNeededFlag complete before SEV
   213 										// also ensure EOI is written before we return from the interrupt
   210 										// also ensure EOI is written before we return from the interrupt
   214 	ARM_SEV;							// kick any CPUs waiting for us to enter the ISR
   211 	ARM_SEV;							// kick any CPUs waiting for us to enter the ISR
   215 	asm("b		1b ");
   212 	asm("b		1b ");
   216 
   213 
   217 	asm("do_indirect_powerdown_ipi: ");
       
   218 	asm("str	r0, [r6, #%a0]" : : "i" _FOFF(GicCpuIfc, iEoi));		// acknowledge interrupt
       
   219 	__DATA_SYNC_BARRIER_Z__(r1);		// ensure writes to i_IrqCount, i_IrqNestCount, iRescheduleNeededFlag complete before SEV
       
   220 										// also ensure EOI is written before we return from the interrupt
       
   221 	ARM_SEV;							// kick any CPUs waiting for us to enter the ISR
       
   222 	asm("stmfd	sp!, {r0-r3,r12,lr} ");
       
   223 	asm("bl		call_ipd_handler ");
       
   224 	asm("ldmfd	sp!, {r0-r3,r12,lr} ");
       
   225 	asm("b		1b ");
       
   226 
       
   227 	// GENERIC_IPI
   214 	// GENERIC_IPI
   228 	asm("do_generic_ipi: ");
   215 	asm("do_generic_ipi: ");
   229 	asm("ldr	r2, _GenericIPIIsr ");
   216 	asm("ldr	r2, _GenericIPIIsr ");
   230 	asm("str	r0, [r6, #%a0]" : : "i" _FOFF(GicCpuIfc, iEoi));		// acknowledge interrupt
   217 	asm("str	r0, [r6, #%a0]" : : "i" _FOFF(GicCpuIfc, iEoi));		// acknowledge interrupt
   231 	asm("mov	r0, r4 ");				// r0->SubScheduler
   218 	asm("mov	r0, r4 ");				// r0->SubScheduler
   232 	__DATA_SYNC_BARRIER_Z__(r1);
   219 	__DATA_SYNC_BARRIER_Z__(r1);
   233 	__JUMP(,	r2);
   220 	__JUMP(,	r2);
   234 
   221 
   235 	asm("__DebugMsg_longjump_Irq: ");
   222 	asm("__DebugMsg_longjump_Irq: ");
   236 	asm("ldr	pc, _dmIrq ");
   223 	asm("ldr	pc, _dmIrq ");
   237 
       
   238 	asm("call_ipd_handler: ");
       
   239 	asm("ldr	pc, __handle_ipd_ipi ");
       
   240 
   224 
   241 	asm("__reset_vector:");
   225 	asm("__reset_vector:");
   242 	asm(".word	__ArmVectorReset "); 
   226 	asm(".word	__ArmVectorReset "); 
   243 	asm("__undef_vector:");
   227 	asm("__undef_vector:");
   244 	__DECLARE_UNDEFINED_INSTRUCTION_HANDLER;
   228 	__DECLARE_UNDEFINED_INSTRUCTION_HANDLER;
   269 	asm("__btrace_fiq_entry: ");
   253 	asm("__btrace_fiq_entry: ");
   270 	asm(".word btrace_fiq_entry ");
   254 	asm(".word btrace_fiq_entry ");
   271 #endif
   255 #endif
   272 	asm("_dmIrq: ");
   256 	asm("_dmIrq: ");
   273 	asm(".word __DebugMsgIrq ");
   257 	asm(".word __DebugMsgIrq ");
   274 	asm("__handle_ipd_ipi: ");
       
   275 	asm(".word handle_indirect_powerdown_ipi ");
       
   276 	}
   258 	}
   277 }
   259 }
   278 
   260