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