os/kernelhwsrv/kernel/eka/include/nkern/arm/entry.h
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of the License "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
// e32/include/nkern/arm/entry.h
sl@0
    15
// 
sl@0
    16
//
sl@0
    17
sl@0
    18
extern "C" {
sl@0
    19
sl@0
    20
extern void __ArmVectorReset();
sl@0
    21
extern void __ArmVectorUndef();
sl@0
    22
extern void __ArmVectorSwi();
sl@0
    23
extern void __ArmVectorAbortPrefetch();
sl@0
    24
extern void __ArmVectorAbortData();
sl@0
    25
extern void __ArmVectorReserved();
sl@0
    26
extern void __ArmVectorIrq();
sl@0
    27
extern void __ArmVectorFiq();
sl@0
    28
sl@0
    29
#define __DECLARE_UNDEFINED_INSTRUCTION_HANDLER		asm(".word __ArmVectorUndef ")
sl@0
    30
#define __DECLARE_PREFETCH_ABORT_HANDLER			asm(".word __ArmVectorAbortPrefetch ")
sl@0
    31
#define __DECLARE_DATA_ABORT_HANDLER				asm(".word __ArmVectorAbortData ")
sl@0
    32
sl@0
    33
/* NOTE: We must ensure that this code goes at the beginning of the kernel image.
sl@0
    34
*/
sl@0
    35
__NAKED__ void __this_must_go_at_the_beginning_of_the_kernel_image()
sl@0
    36
	{
sl@0
    37
	asm("ldr	pc, __reset_vector ");		// 00 = Reset vector
sl@0
    38
	asm("ldr	pc, __undef_vector ");		// 04 = Undefined instruction vector
sl@0
    39
	asm("ldr	pc, __swi_vector ");		// 08 = SWI vector
sl@0
    40
	asm("ldr	pc, __pabt_vector ");		// 0C = Prefetch abort vector
sl@0
    41
	asm("ldr	pc, __dabt_vector ");		// 10 = Data abort vector
sl@0
    42
	asm("ldr	pc, __unused_vector ");		// 14 = unused
sl@0
    43
	asm("b		HandleIrq ");				// 18 = IRQ vector
sl@0
    44
											// 1C = FIQ vector, code in situ
sl@0
    45
	asm("ldr r12, __ArmInterrupt ");	// THIS MUST BE AN IDEMPOTENT INSTRUCTION TO AVOID A PROBLEM WITH XSCALE PXA255
sl@0
    46
	asm("sub lr, lr, #4 ");
sl@0
    47
	asm("str lr, [sp, #-4]! ");
sl@0
    48
	// we assume FIQ handler preserves r0-r7 but not r8-r12
sl@0
    49
	// hence must be assembler, so stack misalignment OK
sl@0
    50
#if defined(__CPU_ARM_HAS_WORKING_CLREX)
sl@0
    51
	CLREX
sl@0
    52
#elif defined(__CPU_ARM_HAS_LDREX_STREX)
sl@0
    53
	STREX(8,14, 13);		// dummy STREX to reset exclusivity monitor
sl@0
    54
#endif
sl@0
    55
#ifdef __USER_MEMORY_GUARDS_ENABLED__
sl@0
    56
	USER_MEMORY_GUARD_ON(,lr,r8);
sl@0
    57
	asm("str lr, [sp, #-4]! ");
sl@0
    58
#endif
sl@0
    59
#ifdef BTRACE_CPU_USAGE
sl@0
    60
	asm("ldrb r8, [r12,#%a0]" : : "i" _FOFF(SArmInterruptInfo,iCpuUsageFilter));
sl@0
    61
	asm("ldr lr, _ArmVectorFiq ");
sl@0
    62
	asm("mov r10, #%a0" : : "i" ((TInt)(BTrace::ECpuUsage<<BTrace::ECategoryIndex*8)+(BTrace::EFiqStart<<BTrace::ESubCategoryIndex*8)) );
sl@0
    63
	asm("cmp r8,#0");
sl@0
    64
	asm("bne btrace_fiq");
sl@0
    65
	asm("ldr pc, [r12,#%a0]" : : "i" _FOFF(SArmInterruptInfo,iFiqHandler)); // call FIQ handler, return to ArmVectorFiq
sl@0
    66
sl@0
    67
	asm("btrace_fiq:");		// call trace handler before fiq handler...
sl@0
    68
	asm("stmdb sp!, {r0-r3} ");
sl@0
    69
	asm("add r0, r10, #%a0" : : "i" ((TInt)4) ); // add size of trace into header
sl@0
    70
	asm("mov lr, pc");
sl@0
    71
	asm("ldr pc, [r12,#%a0]" : : "i" _FOFF(SArmInterruptInfo,iBTraceHandler));
sl@0
    72
	asm("ldr r12, __ArmInterrupt ");
sl@0
    73
	asm("ldmia sp!, {r0-r3} ");
sl@0
    74
#endif	
sl@0
    75
	asm("ldr lr, _ArmVectorFiq ");
sl@0
    76
	asm("ldr pc, [r12,#%a0]" : : "i" _FOFF(SArmInterruptInfo,iFiqHandler)); // call FIQ handler, return to ArmVectorFiq
sl@0
    77
sl@0
    78
	asm("HandleIrq: ");
sl@0
    79
	asm("sub lr, lr, #4 ");
sl@0
    80
	asm("stmfd sp!, {r0-r3,r12,lr} ");
sl@0
    81
#if defined(__CPU_ARM_HAS_WORKING_CLREX)
sl@0
    82
	CLREX
sl@0
    83
#elif defined(__CPU_ARM_HAS_LDREX_STREX)
sl@0
    84
	STREX(12, 0, 13);	// dummy STREX to reset exclusivity monitor
sl@0
    85
#endif
sl@0
    86
#ifdef __USER_MEMORY_GUARDS_ENABLED__
sl@0
    87
	USER_MEMORY_GUARD_ON(,lr,r12);
sl@0
    88
	asm("str lr, [sp, #-8]! ");
sl@0
    89
#endif
sl@0
    90
	asm("ldr r12, __ArmInterrupt ");
sl@0
    91
#ifdef BTRACE_CPU_USAGE
sl@0
    92
	asm("mov r0, #%a0" : : "i" ((TInt)(BTrace::ECpuUsage<<BTrace::ECategoryIndex*8)+(BTrace::EIrqStart<<BTrace::ESubCategoryIndex*8)) );
sl@0
    93
	asm("add r0, r0, #%a0" : : "i" ((TInt)4) ); // add size of trace into header
sl@0
    94
	asm("ldrb r1, [r12,#%a0]" : : "i" _FOFF(SArmInterruptInfo,iCpuUsageFilter));
sl@0
    95
	asm("ldr lr, _ArmVectorIrq ");
sl@0
    96
	asm("cmp r1,#0");
sl@0
    97
	asm("bne btrace_irq");
sl@0
    98
	asm("ldr pc, [r12,#%a0]" : : "i" _FOFF(SArmInterruptInfo,iIrqHandler));  // call IRQ handler, return to ArmVectorIrq
sl@0
    99
sl@0
   100
	asm("btrace_irq:");	// call trace handler before irq handler...
sl@0
   101
	asm("mov lr, pc");
sl@0
   102
	asm("ldr pc, [r12,#%a0]" : : "i" _FOFF(SArmInterruptInfo,iBTraceHandler));
sl@0
   103
	asm("ldr r12, __ArmInterrupt ");
sl@0
   104
#endif
sl@0
   105
	asm("ldr lr, _ArmVectorIrq ");
sl@0
   106
	asm("ldr pc, [r12,#%a0]" : : "i" _FOFF(SArmInterruptInfo,iIrqHandler)); // call IRQ handler, return to ArmVectorIrq
sl@0
   107
sl@0
   108
	asm("__reset_vector:");
sl@0
   109
	asm(".word	__ArmVectorReset "); 
sl@0
   110
	asm("__undef_vector:");
sl@0
   111
	__DECLARE_UNDEFINED_INSTRUCTION_HANDLER;
sl@0
   112
	asm("__swi_vector:");
sl@0
   113
	asm(".word	__ArmVectorSwi "); 
sl@0
   114
	asm("__pabt_vector:");
sl@0
   115
	__DECLARE_PREFETCH_ABORT_HANDLER;
sl@0
   116
	asm("__dabt_vector:");
sl@0
   117
	__DECLARE_DATA_ABORT_HANDLER;
sl@0
   118
	asm("__unused_vector:");
sl@0
   119
	asm(".word	__ArmVectorReserved ");
sl@0
   120
sl@0
   121
	asm("__ArmInterrupt: ");
sl@0
   122
	asm(".word  ArmInterruptInfo ");
sl@0
   123
	asm("_ArmVectorIrq:");
sl@0
   124
	asm(".word __ArmVectorIrq"); 
sl@0
   125
	asm("_ArmVectorFiq:");
sl@0
   126
	asm(".word __ArmVectorFiq ");
sl@0
   127
	}
sl@0
   128
}
sl@0
   129