Update jni/Android.mk
[picodrive.git] / platform / gp2x / code940 / 940init.s
index dcf4368..201ee86 100644 (file)
@@ -1,6 +1,16 @@
-.global code940\r
+@ vim:filetype=armasm:\r
+\r
+@ ARM940 initialization.\r
+@ Based on ogg940 code by Dzz.\r
+@ (c) Copyright 2007, Grazvydas "notaz" Ignotas\r
+\r
+.equ mmsp2_regs, (0xc0000000-0x02000000) @ assume we live @ 0x2000000 bank\r
+.equ shared_ctl,  0x00200000             @ this is where shared_ctl struncture is located\r
 \r
-code940:                          @ interrupt table:\r
+\r
+@ exception table:\r
+.global code940\r
+code940:\r
     b .b_reset                    @ reset\r
     b .b_undef                    @ undefined instructions\r
     b .b_swi                      @ software interrupt\r
@@ -30,19 +40,23 @@ code940:                          @ interrupt table:
     mov     r12, #5\r
     b       .Begin\r
 .b_irq:\r
-    mov     r12, #6\r
     mov     sp, #0x100000       @ reset stack\r
     sub     sp, sp, #4\r
-    mov     r1, #0xbe000000     @ assume we live @ 0x2000000 bank\r
-    orr     r2, r1, #0x3B00\r
-    orr     r2, r2, #0x0046\r
-    mvn     r3, #0\r
-    strh    r3, [r2]            @ clear any pending interrupts from the DUALCPU unit\r
-    orr     r2, r1, #0x4500\r
-    str     r3, [r2]            @ clear all pending interrupts in irq controller's SRCPND register\r
-    orr     r2, r2, #0x0010\r
-    str     r3, [r2]            @ clear all pending interrupts in irq controller's INTPND register\r
-    b       .Enter\r
+    mov     r0, #shared_ctl     @ remember where we were when interrupt happened\r
+    add     r0, r0, #0x20\r
+    str     lr, [r0]\r
+    mov     r0, #shared_ctl     @ increment exception counter (for debug)\r
+    add     r0, r0, #(6*4)\r
+    ldr     r1, [r0]\r
+    add     r1, r1, #1\r
+    str     r1, [r0]\r
+\r
+    bl Main940\r
+\r
+    @ we should never get here\r
+    b .b_reserved\r
+\r
+\r
 .b_fiq:\r
     mov     r12, #7\r
     b       .Begin\r
@@ -69,18 +83,29 @@ code940:                          @ interrupt table:
 \r
     @ set up region 3: 64k 0xbe000000-0xbe010000 (hw control registers)\r
     mov r0, #(0x0f<<1)|1\r
-    orr r0, r0, #0xbe000000\r
+    orr r0, r0, #mmsp2_regs\r
     mcr p15, 0, r0, c6, c3, 0\r
     mcr p15, 0, r0, c6, c3, 1\r
 \r
-    @ set up region 4: 16M 0x01000000-0x02000000 (mp3 area)\r
-    mov r0, #(0x17<<1)|1\r
-    orr r0, r0, #0x01000000\r
+    @ region 4: 4K 0x00000000-0x00001000 (boot code protection region)\r
+    mov r0, #(0x0b<<1)|1\r
     mcr p15, 0, r0, c6, c4, 0\r
     mcr p15, 0, r0, c6, c4, 1\r
 \r
-    @ set regions 1 and 4 to be cacheable (so the first 2M and mp3 area will be cacheable)\r
-    mov r0, #(1<<1)|(1<<4)\r
+    @ region 5: 4M 0x00400000-0x00800000 (mp3 area part1)\r
+    mov r0, #(0x15<<1)|1\r
+    orr r0, r0, #0x00400000\r
+    mcr p15, 0, r0, c6, c5, 0\r
+    mcr p15, 0, r0, c6, c5, 1\r
+\r
+    @ region 6: 8M 0x00800000-0x01000000 (mp3 area part2)\r
+    mov r0, #(0x16<<1)|1\r
+    orr r0, r0, #0x00800000\r
+    mcr p15, 0, r0, c6, c6, 0\r
+    mcr p15, 0, r0, c6, c6, 1\r
+\r
+    @ set regions 1, 4, 5 and 6 to be cacheable (so the first 2M and mp3 area will be cacheable)\r
+    mov r0, #(1<<1)|(1<<4)|(1<<5)|(1<<6)\r
     mcr p15, 0, r0, c2, c0, 0\r
     mcr p15, 0, r0, c2, c0, 1\r
 \r
@@ -88,36 +113,97 @@ code940:                          @ interrupt table:
     mov r0, #(1<<1)\r
     mcr p15, 0, r0, c3, c0, 0\r
 \r
-    @ set protection, allow accsess only to regions 1 and 2\r
-    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
+    @ set access protection\r
+    @ data: [full, full, no, full, full, full, no access] for regions [6 5 4 3 2 1 0]\r
+    mov r0,     #       (3<<12)|(3<<10)|(0<<8)\r
+    orr r0, r0, #(3<<6)|(3<< 4)|(3<< 2)|(0<<0)\r
     mcr p15, 0, r0, c5, c0, 0\r
-    mov r0, #(0<<8)|(0<<6)|(0<<4)|(3<<2)|(0)  @ instructions: [no access, no, no, full, no]\r
+    @ instructions: [no, no, full, no, no, full, no]\r
+    mov r0,     #       (0<<12)|(0<<10)|(3<<8)\r
+    orr r0, r0, #(0<<6)|(0<< 4)|(3<< 2)|(0<<0)\r
     mcr p15, 0, r0, c5, c0, 1\r
 \r
     mrc p15, 0, r0, c1, c0, 0   @ fetch current control reg\r
     orr r0, r0, #1              @ 0x00000001: enable protection unit\r
     orr r0, r0, #4              @ 0x00000004: enable D cache\r
     orr r0, r0, #0x1000         @ 0x00001000: enable I cache\r
-    bic r0, r0, #0xC0000000\r
-    orr r0, r0, #0x40000000     @ 0x40000000: synchronous, faster?\r
-@    orr r0, r0, #0xC0000000     @ 0xC0000000: async\r
+@    bic r0, r0, #0xC0000000\r
+@    orr r0, r0, #0x40000000     @ 0x40000000: synchronous, faster?\r
+    orr r0, r0, #0xC0000000     @ 0xC0000000: async\r
     mcr p15, 0, r0, c1, c0, 0   @ set control reg\r
 \r
     @ flush (invalidate) the cache (just in case)\r
     mov r0, #0\r
     mcr p15, 0, r0, c7, c6, 0\r
 \r
-.Enter:\r
-    mov r0, r12\r
-    bl Main940\r
+    @ remember which exception vector we came from (increment counter for debug)\r
+    mov     r0, #shared_ctl\r
+    add     r0, r0, r12, lsl #2\r
+    ldr     r1, [r0]\r
+    add     r1, r1, #1\r
+    str     r1, [r0]\r
+    \r
+    @ remember last lr (for debug)\r
+    mov     r0, #shared_ctl\r
+    add     r0, r0, #0x20\r
+    str     lr, [r0]\r
+\r
+    @ ready to take first job-interrupt\r
+wait_for_irq:\r
+    mrs     r0, cpsr\r
+    bic     r0, r0, #0x80\r
+    msr     cpsr_c, r0              @ enable interrupts\r
+\r
+    mov     r0, #0\r
+    mcr     p15, 0, r0, c7, c0, 4   @ wait for IRQ\r
+@    mcr     p15, 0, r0, c15, c8, 2\r
+    nop\r
+    nop\r
+    b       .b_reserved\r
+\r
 \r
-    @ we should never get here\r
-.b_deadloop:\r
-    b .b_deadloop\r
 \r
+@ next job getter\r
+.global wait_get_job @ int oldjob\r
 \r
+wait_get_job:\r
+    mov     r3, #mmsp2_regs\r
+    orr     r2, r3, #0x3B00\r
+    orr     r2, r2, #0x0046         @ DUALPEND940 register\r
+    ldrh    r12,[r2]\r
 \r
-@ so asm utils are also defined here:\r
+    tst     r0, r0\r
+    beq     wgj_no_old\r
+    sub     r0, r0, #1\r
+    mov     r1, #1\r
+    mov     r1, r1, lsl r0\r
+    strh    r1, [r2]                @ clear finished job's pending bit\r
+    bic     r12,r12,r1\r
+\r
+wgj_no_old:\r
+    tst     r12,r12\r
+    beq     wgj_no_jobs\r
+    mov     r0, #0\r
+wgj_loop:\r
+    add     r0, r0, #1\r
+    movs    r12,r12,lsr #1\r
+    bxcs    lr\r
+    b       wgj_loop\r
+\r
+wgj_no_jobs:\r
+    mvn     r0, #0\r
+    orr     r2, r3, #0x4500\r
+    str     r0, [r2]            @ clear all pending interrupts in irq controller's SRCPND register\r
+    orr     r2, r2, #0x0010\r
+    str     r0, [r2]            @ clear all pending interrupts in irq controller's INTPND register\r
+    b       wait_for_irq\r
+\r
+.pool\r
+\r
+\r
+\r
+\r
+@ some asm utils are also defined here:\r
 .global spend_cycles @ c\r
 \r
 spend_cycles:\r
@@ -131,16 +217,16 @@ spend_cycles:
 \r
 \r
 @ clean-flush function from ARM940T technical reference manual\r
-.global cache_clean_flush\r
+.global dcache_clean_flush\r
 \r
-cache_clean_flush:\r
+dcache_clean_flush:\r
     mov     r1, #0                  @ init line counter\r
 ccf_outer_loop:\r
     mov     r0, #0                  @ segment counter\r
 ccf_inner_loop:\r
     orr     r2, r1, r0              @ make segment and line address\r
     mcr     p15, 0, r2, c7, c14, 2  @ clean and flush that line\r
-    add     r0, r0, #0x10           @ incremet secment counter\r
+    add     r0, r0, #0x10           @ incremet segment counter\r
     cmp     r0, #0x40               @ complete all 4 segments?\r
     bne     ccf_inner_loop\r
     add     r1, r1, #0x04000000     @ increment line counter\r
@@ -149,17 +235,18 @@ ccf_inner_loop:
     bx      lr\r
 \r
 \r
+\r
 @ clean-only version\r
-.global cache_clean\r
+.global dcache_clean\r
 \r
-cache_clean:\r
+dcache_clean:\r
     mov     r1, #0                  @ init line counter\r
 cf_outer_loop:\r
     mov     r0, #0                  @ segment counter\r
 cf_inner_loop:\r
     orr     r2, r1, r0              @ make segment and line address\r
     mcr     p15, 0, r2, c7, c10, 2  @ clean that line\r
-    add     r0, r0, #0x10           @ incremet secment counter\r
+    add     r0, r0, #0x10           @ incremet segment counter\r
     cmp     r0, #0x40               @ complete all 4 segments?\r
     bne     cf_inner_loop\r
     add     r1, r1, #0x04000000     @ increment line counter\r
@@ -168,18 +255,28 @@ cf_inner_loop:
     bx      lr\r
 \r
 \r
-.global wait_irq\r
-\r
-wait_irq:\r
-    mrs     r0, cpsr\r
-    bic     r0, r0, #0x80\r
-    msr     cpsr_c, r0               @ enable interrupts\r
+@ drain write buffer\r
+.global drain_wb\r
 \r
+drain_wb:\r
     mov     r0, #0\r
-    mcr     p15, 0, r0, c7, c0, 4   @ wait for IRQ\r
-@    mcr     p15, 0, r0, c15, c8, 2\r
-    b       .b_reserved\r
+    mcr     p15, 0, r0, c7, c10, 4\r
+    bx      lr\r
 \r
-.pool\r
 \r
-@ vim:filetype=armasm:\r
+.global set_if_not_changed @ int *val, int oldval, int newval\r
+\r
+set_if_not_changed:\r
+    swp    r3, r2, [r0]\r
+    cmp    r1, r3\r
+    bxeq   lr\r
+    strne  r3, [r0] @ restore value which was changed there by other core\r
+    bx     lr\r
+\r
+\r
+\r
+@ pad the protected region.\r
+.rept 1024\r
+.long 0\r
+.endr\r
+\r