region detection, cd states wip, fixes, stuff
[picodrive.git] / platform / gp2x / code940 / 940init.s
1 .global code940\r
2 \r
3 code940:                          @ 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
34     mov     sp, #0x100000       @ reset stack\r
35     sub     sp, sp, #4\r
36     mov     r1, #0xbe000000     @ assume we live @ 0x2000000 bank\r
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
51     mov sp, #0x100000           @ set the stack top (1M)\r
52     sub sp, sp, #4              @ minus 4\r
53 \r
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
58 \r
59     @ set up region 1 which is the first 2 megabytes.\r
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
63 \r
64     @ set up region 2: 64k 0x200000-0x210000\r
65     mov r0, #(0x0f<<1)|1\r
66     orr r0, r0, #0x200000\r
67     mcr p15, 0, r0, c6, c2, 0\r
68     mcr p15, 0, r0, c6, c2, 1\r
69 \r
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
75 \r
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
84     mcr p15, 0, r0, c2, c0, 0\r
85     mcr p15, 0, r0, c2, c0, 1\r
86 \r
87     @ set region 1 to be bufferable too (only data)\r
88     mov r0, #(1<<1)\r
89     mcr p15, 0, r0, c3, c0, 0\r
90 \r
91     @ set protection, allow accsess only to regions 1 and 2\r
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
93     mcr p15, 0, r0, c5, c0, 0\r
94     mov r0, #(0<<8)|(0<<6)|(0<<4)|(3<<2)|(0)  @ instructions: [no access, no, no, full, no]\r
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
101     bic r0, r0, #0xC0000000\r
102     orr r0, r0, #0x40000000     @ 0x40000000: synchronous, faster?\r
103 @    orr r0, r0, #0xC0000000     @ 0xC0000000: async\r
104     mcr p15, 0, r0, c1, c0, 0   @ set control reg\r
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
123 spend_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
136 cache_clean_flush:\r
137     mov     r1, #0                  @ init line counter\r
138 ccf_outer_loop:\r
139     mov     r0, #0                  @ segment counter\r
140 ccf_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
155 cache_clean:\r
156     mov     r1, #0                  @ init line counter\r
157 cf_outer_loop:\r
158     mov     r0, #0                  @ segment counter\r
159 cf_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
173 wait_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
184 \r
185 \r
186 .global set_if_not_changed @ int *val, int oldval, int newval\r
187 \r
188 set_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
195 @ vim:filetype=armasm:\r