Sonic CD runs on GP2X
[libpicofe.git] / gp2x / 940init.s
CommitLineData
720ee7f6 1.global code940\r
2\r
3code940: @ interrupt table:\r
4 b .b_reset @ reset\r
5 b .b_undef @ undefined instructions\r
6 b .b_swi @ software interrupt\r
7 b .b_pabort @ prefetch abort\r
8 b .b_dabort @ data abort\r
9 b .b_reserved @ reserved\r
10 b .b_irq @ IRQ\r
11 b .b_fiq @ FIQ\r
12\r
13@ test\r
14.b_reset:\r
15 mov r12, #0\r
16 b .Begin\r
17.b_undef:\r
18 mov r12, #1\r
19 b .Begin\r
20.b_swi:\r
21 mov r12, #2\r
22 b .Begin\r
23.b_pabort:\r
24 mov r12, #3\r
25 b .Begin\r
26.b_dabort:\r
27 mov r12, #4\r
28 b .Begin\r
29.b_reserved:\r
30 mov r12, #5\r
31 b .Begin\r
32.b_irq:\r
33 mov r12, #6\r
8dfb9fd5 34 mov sp, #0x100000 @ reset stack\r
35 sub sp, sp, #4\r
36 mov r1, #0xbe000000 @ assume we live @ 0x2000000 bank\r
720ee7f6 37 orr r2, r1, #0x3B00\r
38 orr r2, r2, #0x0046\r
39 mvn r3, #0\r
40 strh r3, [r2] @ clear any pending interrupts from the DUALCPU unit\r
41 orr r2, r1, #0x4500\r
42 str r3, [r2] @ clear all pending interrupts in irq controller's SRCPND register\r
43 orr r2, r2, #0x0010\r
44 str r3, [r2] @ clear all pending interrupts in irq controller's INTPND register\r
45 b .Enter\r
46.b_fiq:\r
47 mov r12, #7\r
48 b .Begin\r
49\r
50.Begin:\r
8dfb9fd5 51 mov sp, #0x100000 @ set the stack top (1M)\r
52 sub sp, sp, #4 @ minus 4\r
720ee7f6 53\r
8dfb9fd5 54 @ set up memory region 0 -- the whole 4GB address space\r
55 mov r0, #(0x1f<<1)|1 @ region data\r
56 mcr p15, 0, r0, c6, c0, 0 @ opcode2 ~ data/instr\r
57 mcr p15, 0, r0, c6, c0, 1\r
720ee7f6 58\r
59 @ set up region 1 which is the first 2 megabytes.\r
8dfb9fd5 60 mov r0, #(0x14<<1)|1 @ region data\r
61 mcr p15, 0, r0, c6, c1, 0\r
62 mcr p15, 0, r0, c6, c1, 1\r
720ee7f6 63\r
64 @ set up region 2: 64k 0x200000-0x210000\r
8dfb9fd5 65 mov r0, #(0x0f<<1)|1\r
720ee7f6 66 orr r0, r0, #0x200000\r
8dfb9fd5 67 mcr p15, 0, r0, c6, c2, 0\r
68 mcr p15, 0, r0, c6, c2, 1\r
720ee7f6 69\r
8dfb9fd5 70 @ set up region 3: 64k 0xbe000000-0xbe010000 (hw control registers)\r
71 mov r0, #(0x0f<<1)|1\r
72 orr r0, r0, #0xbe000000\r
73 mcr p15, 0, r0, c6, c3, 0\r
74 mcr p15, 0, r0, c6, c3, 1\r
720ee7f6 75\r
76 @ set region 1 to be cacheable (so the first 2M will be cacheable)\r
8dfb9fd5 77 mov r0, #2\r
78 mcr p15, 0, r0, c2, c0, 0\r
79 mcr p15, 0, r0, c2, c0, 1\r
720ee7f6 80\r
81 @ set region 1 to be bufferable too (only data)\r
8dfb9fd5 82 mcr p15, 0, r0, c3, c0, 0\r
720ee7f6 83\r
84 @ set protection, allow accsess only to regions 1 and 2\r
8dfb9fd5 85 mov r0, #(3<<6)|(3<<4)|(3<<2)|(0) @ data: [full, full, full, no access] for regions [3 2 1 0]\r
86 mcr p15, 0, r0, c5, c0, 0\r
87 mov r0, #(0<<6)|(0<<4)|(3<<2)|(0) @ instructions: [no access, no, full, no]\r
88 mcr p15, 0, r0, c5, c0, 1\r
89\r
90 mrc p15, 0, r0, c1, c0, 0 @ fetch current control reg\r
91 orr r0, r0, #1 @ 0x00000001: enable protection unit\r
92 orr r0, r0, #4 @ 0x00000004: enable D cache\r
93 orr r0, r0, #0x1000 @ 0x00001000: enable I cache\r
94 orr r0, r0, #0xC0000000 @ 0xC0000000: async+fastbus\r
95 mcr p15, 0, r0, c1, c0, 0 @ set control reg\r
720ee7f6 96\r
97 @ flush (invalidate) the cache (just in case)\r
98 mov r0, #0\r
99 mcr p15, 0, r0, c7, c6, 0\r
100\r
101.Enter:\r
102 mov r0, r12\r
103 bl Main940\r
104\r
105 @ we should never get here\r
106.b_deadloop:\r
107 b .b_deadloop\r
108\r
109\r
110\r
111@ so asm utils are also defined here:\r
112.global spend_cycles @ c\r
113\r
114spend_cycles:\r
115 mov r0, r0, lsr #2 @ 4 cycles/iteration\r
116 sub r0, r0, #2 @ entry/exit/init\r
117.sc_loop:\r
118 subs r0, r0, #1\r
119 bpl .sc_loop\r
120\r
121 bx lr\r
122\r
123\r
124@ clean-flush function from ARM940T technical reference manual\r
125.global cache_clean_flush\r
126\r
127cache_clean_flush:\r
128 mov r1, #0 @ init line counter\r
129ccf_outer_loop:\r
130 mov r0, #0 @ segment counter\r
131ccf_inner_loop:\r
132 orr r2, r1, r0 @ make segment and line address\r
133 mcr p15, 0, r2, c7, c14, 2 @ clean and flush that line\r
134 add r0, r0, #0x10 @ incremet secment counter\r
135 cmp r0, #0x40 @ complete all 4 segments?\r
136 bne ccf_inner_loop\r
137 add r1, r1, #0x04000000 @ increment line counter\r
138 cmp r1, #0 @ complete all lines?\r
139 bne ccf_outer_loop\r
140 bx lr\r
141\r
142\r
143@ clean-only version\r
144.global cache_clean\r
145\r
146cache_clean:\r
147 mov r1, #0 @ init line counter\r
148cf_outer_loop:\r
149 mov r0, #0 @ segment counter\r
150cf_inner_loop:\r
151 orr r2, r1, r0 @ make segment and line address\r
152 mcr p15, 0, r2, c7, c10, 2 @ clean that line\r
153 add r0, r0, #0x10 @ incremet secment counter\r
154 cmp r0, #0x40 @ complete all 4 segments?\r
155 bne cf_inner_loop\r
156 add r1, r1, #0x04000000 @ increment line counter\r
157 cmp r1, #0 @ complete all lines?\r
158 bne cf_outer_loop\r
159 bx lr\r
160\r
161\r
162.global wait_irq\r
163\r
164wait_irq:\r
165 mrs r0, cpsr\r
166 bic r0, r0, #0x80\r
167 msr cpsr_c, r0 @ enable interrupts\r
168\r
169 mov r0, #0\r
170 mcr p15, 0, r0, c7, c0, 4 @ wait for IRQ\r
171@ mcr p15, 0, r0, c15, c8, 2\r
172 b .b_reserved\r
173\r
174.pool\r
8dfb9fd5 175\r
176@ vim:filetype=ignored:\r