region detection, cd states wip, fixes, stuff
[picodrive.git] / platform / gp2x / code940 / 940init.s
CommitLineData
cc68a136 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
b837b69b 34 mov sp, #0x100000 @ reset stack\r
35 sub sp, sp, #4\r
36 mov r1, #0xbe000000 @ assume we live @ 0x2000000 bank\r
cc68a136 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
b837b69b 51 mov sp, #0x100000 @ set the stack top (1M)\r
52 sub sp, sp, #4 @ minus 4\r
cc68a136 53\r
b837b69b 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
cc68a136 58\r
59 @ set up region 1 which is the first 2 megabytes.\r
b837b69b 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
cc68a136 63\r
64 @ set up region 2: 64k 0x200000-0x210000\r
b837b69b 65 mov r0, #(0x0f<<1)|1\r
cc68a136 66 orr r0, r0, #0x200000\r
b837b69b 67 mcr p15, 0, r0, c6, c2, 0\r
68 mcr p15, 0, r0, c6, c2, 1\r
cc68a136 69\r
b837b69b 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
cc68a136 75\r
42c7b147 76 @ set up region 4: 16M 0x01000000-0x02000000 (mp3 area)\r
77 mov r0, #(0x17<<1)|1\r
78 orr r0, r0, #0x01000000\r
79 mcr p15, 0, r0, c6, c4, 0\r
80 mcr p15, 0, r0, c6, c4, 1\r
81\r
82 @ set regions 1 and 4 to be cacheable (so the first 2M and mp3 area will be cacheable)\r
83 mov r0, #(1<<1)|(1<<4)\r
b837b69b 84 mcr p15, 0, r0, c2, c0, 0\r
85 mcr p15, 0, r0, c2, c0, 1\r
cc68a136 86\r
87 @ set region 1 to be bufferable too (only data)\r
42c7b147 88 mov r0, #(1<<1)\r
b837b69b 89 mcr p15, 0, r0, c3, c0, 0\r
cc68a136 90\r
91 @ set protection, allow accsess only to regions 1 and 2\r
42c7b147 92 mov r0, #(3<<8)|(3<<6)|(3<<4)|(3<<2)|(0) @ data: [full, full, full, full, no access] for regions [4 3 2 1 0]\r
b837b69b 93 mcr p15, 0, r0, c5, c0, 0\r
42c7b147 94 mov r0, #(0<<8)|(0<<6)|(0<<4)|(3<<2)|(0) @ instructions: [no access, no, no, full, no]\r
b837b69b 95 mcr p15, 0, r0, c5, c0, 1\r
96\r
97 mrc p15, 0, r0, c1, c0, 0 @ fetch current control reg\r
98 orr r0, r0, #1 @ 0x00000001: enable protection unit\r
99 orr r0, r0, #4 @ 0x00000004: enable D cache\r
100 orr r0, r0, #0x1000 @ 0x00001000: enable I cache\r
42c7b147 101 bic r0, r0, #0xC0000000\r
102 orr r0, r0, #0x40000000 @ 0x40000000: synchronous, faster?\r
103@ orr r0, r0, #0xC0000000 @ 0xC0000000: async\r
b837b69b 104 mcr p15, 0, r0, c1, c0, 0 @ set control reg\r
cc68a136 105\r
106 @ flush (invalidate) the cache (just in case)\r
107 mov r0, #0\r
108 mcr p15, 0, r0, c7, c6, 0\r
109\r
110.Enter:\r
111 mov r0, r12\r
112 bl Main940\r
113\r
114 @ we should never get here\r
115.b_deadloop:\r
116 b .b_deadloop\r
117\r
118\r
119\r
120@ so asm utils are also defined here:\r
121.global spend_cycles @ c\r
122\r
123spend_cycles:\r
124 mov r0, r0, lsr #2 @ 4 cycles/iteration\r
125 sub r0, r0, #2 @ entry/exit/init\r
126.sc_loop:\r
127 subs r0, r0, #1\r
128 bpl .sc_loop\r
129\r
130 bx lr\r
131\r
132\r
133@ clean-flush function from ARM940T technical reference manual\r
134.global cache_clean_flush\r
135\r
136cache_clean_flush:\r
137 mov r1, #0 @ init line counter\r
138ccf_outer_loop:\r
139 mov r0, #0 @ segment counter\r
140ccf_inner_loop:\r
141 orr r2, r1, r0 @ make segment and line address\r
142 mcr p15, 0, r2, c7, c14, 2 @ clean and flush that line\r
143 add r0, r0, #0x10 @ incremet secment counter\r
144 cmp r0, #0x40 @ complete all 4 segments?\r
145 bne ccf_inner_loop\r
146 add r1, r1, #0x04000000 @ increment line counter\r
147 cmp r1, #0 @ complete all lines?\r
148 bne ccf_outer_loop\r
149 bx lr\r
150\r
151\r
152@ clean-only version\r
153.global cache_clean\r
154\r
155cache_clean:\r
156 mov r1, #0 @ init line counter\r
157cf_outer_loop:\r
158 mov r0, #0 @ segment counter\r
159cf_inner_loop:\r
160 orr r2, r1, r0 @ make segment and line address\r
161 mcr p15, 0, r2, c7, c10, 2 @ clean that line\r
162 add r0, r0, #0x10 @ incremet secment counter\r
163 cmp r0, #0x40 @ complete all 4 segments?\r
164 bne cf_inner_loop\r
165 add r1, r1, #0x04000000 @ increment line counter\r
166 cmp r1, #0 @ complete all lines?\r
167 bne cf_outer_loop\r
168 bx lr\r
169\r
170\r
171.global wait_irq\r
172\r
173wait_irq:\r
174 mrs r0, cpsr\r
175 bic r0, r0, #0x80\r
176 msr cpsr_c, r0 @ enable interrupts\r
177\r
178 mov r0, #0\r
179 mcr p15, 0, r0, c7, c0, 4 @ wait for IRQ\r
180@ mcr p15, 0, r0, c15, c8, 2\r
181 b .b_reserved\r
182\r
183.pool\r
b837b69b 184\r
51a902ae 185\r
186.global set_if_not_changed @ int *val, int oldval, int newval\r
187\r
188set_if_not_changed:\r
189 swp r3, r2, [r0]\r
190 cmp r1, r3\r
191 bxeq lr\r
192 strne r3, [r0] @ restore value which was changed there by other core\r
193 bx lr\r
194\r
42c7b147 195@ vim:filetype=armasm:\r