|
1 // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of the License "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // e32\euser\epoc\arm\uc_exe.cia |
|
15 // |
|
16 // |
|
17 |
|
18 #include <e32cia.h> |
|
19 #include <u32std.h> |
|
20 // Include this to get imports from User (i.e. User::Invariant and User::HandleException). |
|
21 // This sets VISIBILITY to DEFAULT for BPABI builds. |
|
22 #include <e32std.h> |
|
23 |
|
24 extern "C" { |
|
25 |
|
26 void _xxxx_call_user_invariant(); |
|
27 void _xxxx_call_user_handle_exception(void *); |
|
28 |
|
29 extern void RunThread(TBool aNotFirst, SThreadCreateInfo& aInfo); |
|
30 |
|
31 // NOTE: This MUST be the first function in this module |
|
32 __NAKED__ TInt _E32Startup() |
|
33 { |
|
34 // Process entry point |
|
35 // R4 = entry reason |
|
36 // SP points to information block |
|
37 EKA2_ENTRY_POINT_VERSION_IDENTIFIER; // DUMMY INSTRUCTION TO INDICATE EKA2 ENTRY POINT |
|
38 asm("cmp r4, #%a0" : : "i" ((TInt)KModuleEntryReasonThreadInit) ); |
|
39 asm("b 1f "); // branch over space for unique ID |
|
40 |
|
41 asm(".word 0 "); // loader will replace with code seg unique ID |
|
42 // for RAM-loaded code segment |
|
43 // MUST BE AT OFFSET 12 FROM ENTRY POINT |
|
44 |
|
45 asm("1: "); |
|
46 asm("movls r0, r4 "); // r0 = aNotFirst |
|
47 asm("movls r1, sp "); // r1 -> parameter block |
|
48 asm("bls RunThread "); // process or thread init |
|
49 asm("cmp r4, #%a0" : : "i" ((TInt)KModuleEntryReasonException) ); |
|
50 // asm("bne " CSM_ZN4User9InvariantEv ); // invalid entry reason |
|
51 asm("bne _xxxx_call_user_invariant " ); // invalid entry reason |
|
52 |
|
53 // exception entry |
|
54 // NOTE: THUMB only works on ARMv5 and above |
|
55 asm("mov r0, sp "); // r0->parameter block |
|
56 asm("ldr r4, [sp, #16]"); // r4 = saved CPSR |
|
57 asm("tst r4, #0x20 "); // test for THUMB |
|
58 asm("ldrne r1, [sp, #80] "); // r1 = saved return addr |
|
59 asm("orrne r1, r1, #1 "); |
|
60 asm("strne r1, [sp, #80] "); // if THUMB, set bit 0 of return addr |
|
61 |
|
62 asm("mov r11, sp "); // save stack pointer |
|
63 |
|
64 // The frame starts 84 bytes (up) from r11 i.e. CFA is r11 + 84 |
|
65 __EH_FRAME_ADDRESS(r11, 84) |
|
66 // we can only restore callee-save values, but that's what we want if we 'leave' |
|
67 // saved link is -8 bytes from CFA (= r11 + 0x24 + 0x20 + 0x8) |
|
68 __EH_FRAME_SAVE1(lr, -8) |
|
69 |
|
70 // the other callee saves start at -48 from CFA (= r11 + 0x24) |
|
71 #if 0 |
|
72 // would like to say this |
|
73 __EH_FRAME_SAVE1(r4-r11, -48) |
|
74 // but the macro expansion gives rise to odd code so we do what follows |
|
75 #endif |
|
76 #ifdef __ARMCC__ |
|
77 FRAME SAVE {r4-r11}, -48 |
|
78 #endif |
|
79 |
|
80 asm("bic sp, sp, #4 "); // align stack to 8 byte boundary |
|
81 // asm("bl " CSM_ZN4User15HandleExceptionEPv ); |
|
82 asm("bl _xxxx_call_user_handle_exception "); |
|
83 asm("add sp, r11, #16 "); // skip exc type, exc code, FAR, FSR |
|
84 asm("ldr r4, [sp], #4 "); // r4 = saved CPSR |
|
85 asm("bic r4, r4, #0x20 "); // clear THUMB bit |
|
86 asm("msr cpsr, r4 "); // restore flags |
|
87 asm("ldmia sp, {r0-r15} "); // restore r0-r15 |
|
88 |
|
89 #ifdef __ARMCC__ |
|
90 #ifdef __SUPPORT_CPP_EXCEPTIONS__ |
|
91 |
|
92 |
|
93 /* It is possible no functions included in the image require |
|
94 * a handler table. Therefore make only a weak reference to |
|
95 * the handler table base symbol, which may be absent. |
|
96 */ |
|
97 extern |.ARM.exidx$$Base|; |
|
98 extern |.ARM.exidx$$Limit|; |
|
99 extern |.ARM.extab$$Base| [WEAK]; |
|
100 extern |Image$$ER_RO$$Base|; |
|
101 extern |Image$$ER_RO$$Limit|; |
|
102 export |Symbian$$CPP$$Exception$$Descriptor|; |
|
103 |
|
104 |Symbian$$CPP$$Exception$$Descriptor| |
|
105 #ifdef __LEAVE_EQUALS_THROW__ |
|
106 |Symbian$$eit_base| dcd |.ARM.exidx$$Base|; /* index table base */ |
|
107 |Symbian$$eit_limit| dcd |.ARM.exidx$$Limit| ; /* index table limit */ |
|
108 #endif |
|
109 #if __ARMCC_VERSION > 220000 |
|
110 |Symbian$$code_seg_base| dcd |Image$$ER_RO$$Base| + 1 ; /* RO segment base + mark as ehabi v2 */ |
|
111 |Symbian$$code_seg_limit| dcd |Image$$ER_RO$$Limit| ;/* RO segment limit */ |
|
112 |Symbian$$reserved| dcd 0 ; /* reserved for future use */ |
|
113 #else |
|
114 |Symbian$$code_seg_base| dcd |Image$$ER_RO$$Base| ; /* RO segment base */ |
|
115 |Symbian$$code_seg_limit| dcd |Image$$ER_RO$$Limit| ;/* RO segment limit */ |
|
116 #endif |
|
117 |
|
118 #endif |
|
119 #endif |
|
120 |
|
121 } |
|
122 void _xxxx_call_user_invariant() { User::Invariant(); } |
|
123 void _xxxx_call_user_handle_exception(void * arg) { User::HandleException(arg); } |
|
124 |
|
125 } |
|
126 |