diff options
-rw-r--r-- | utils/hwstub/stub/asm/mips/system.S | 27 | ||||
-rw-r--r-- | utils/hwstub/stub/jz4760b/crt0.S | 66 | ||||
-rw-r--r-- | utils/hwstub/stub/jz4760b/hwstub.lds | 13 | ||||
-rw-r--r-- | utils/hwstub/stub/jz4760b/target-config.h | 1 |
4 files changed, 106 insertions, 1 deletions
diff --git a/utils/hwstub/stub/asm/mips/system.S b/utils/hwstub/stub/asm/mips/system.S index 97b0207ec9..2d89bde096 100644 --- a/utils/hwstub/stub/asm/mips/system.S +++ b/utils/hwstub/stub/asm/mips/system.S | |||
@@ -49,6 +49,33 @@ set_data_abort_jmp: | |||
49 | sw ra, 40(v0) | 49 | sw ra, 40(v0) |
50 | jr ra | 50 | jr ra |
51 | move v0, zero | 51 | move v0, zero |
52 | |||
53 | /* restore context on read/write error, performs the interrupt return */ | ||
54 | .global restore_data_abort_jmp | ||
55 | restore_data_abort_jmp: | ||
56 | la k1, data_abort_jmp_ctx_ptr | ||
57 | lw s0, 0(k1) | ||
58 | lw s1, 4(k1) | ||
59 | lw s2, 8(k1) | ||
60 | lw s3, 12(k1) | ||
61 | lw s4, 16(k1) | ||
62 | lw s5, 20(k1) | ||
63 | lw s6, 24(k1) | ||
64 | lw s7, 28(k1) | ||
65 | lw sp, 32(k1) | ||
66 | lw s8, 36(k1) | ||
67 | lw k1, 40(k1) | ||
68 | mtc0 k1, C0_EPC | ||
69 | #ifdef CONFIG_JZ4760B | ||
70 | /* XBurst has a 3 interlock cycle delay, but we don't know if the interlock | ||
71 | * works with eret */ | ||
72 | nop | ||
73 | #else | ||
74 | ehb | ||
75 | #endif | ||
76 | li v0, 1 | ||
77 | eret | ||
78 | nop | ||
52 | .set reorder | 79 | .set reorder |
53 | 80 | ||
54 | #ifdef CONFIG_FLUSH_CACHES | 81 | #ifdef CONFIG_FLUSH_CACHES |
diff --git a/utils/hwstub/stub/jz4760b/crt0.S b/utils/hwstub/stub/jz4760b/crt0.S index 73dbe20428..94d95b3e73 100644 --- a/utils/hwstub/stub/jz4760b/crt0.S +++ b/utils/hwstub/stub/jz4760b/crt0.S | |||
@@ -51,7 +51,7 @@ reloc_loop: | |||
51 | 51 | ||
52 | /* Tricky part: as explained earlier, tcsm0 is uncached so no need to commit | 52 | /* Tricky part: as explained earlier, tcsm0 is uncached so no need to commit |
53 | * the dcache but we want to invalidate the icache ONLY AT THIS LOCATION. | 53 | * the dcache but we want to invalidate the icache ONLY AT THIS LOCATION. |
54 | * Indeed, if the invalidate the entire icache in the cache-as-ram case, we | 54 | * Indeed, if we invalidate the entire icache in the cache-as-ram case, we |
55 | * will miserably crash */ | 55 | * will miserably crash */ |
56 | cache ICHitInv, 0(t0) /* invalidate virtual address in icache */ | 56 | cache ICHitInv, 0(t0) /* invalidate virtual address in icache */ |
57 | 57 | ||
@@ -92,7 +92,71 @@ clear_bss_loop: | |||
92 | stack_setup: | 92 | stack_setup: |
93 | la sp, oc_stackend | 93 | la sp, oc_stackend |
94 | 94 | ||
95 | /* the tcsm0 is usually accessed by its weird 0xf4000000 address but this | ||
96 | * address is not in the range available for EBASE (because EBASE[31:30] | ||
97 | * is hardwired to 0b10). Fortunately, the TCSM0 can be accessed by its | ||
98 | * physical address (0x132b0000) if we ungate the AHB1 */ | ||
99 | la t0, 0xb0000028 /* CPM_CLKGATE1 */ | ||
100 | lw t1, 0(t0) | ||
101 | li t2, 0xffffff7e /* AHB1 */ | ||
102 | and t1, t2 /* clear AHB1 */ | ||
103 | sw t1, 0(t0) | ||
104 | /* keep interrupts disabled, use normal exception vectors (to use EBASE) */ | ||
105 | li t0, 0 | ||
106 | mtc0 t0, C0_STATUS | ||
107 | /* set EBASE */ | ||
108 | la t0, irqbase | ||
109 | mtc0 t0, C0_EBASE | ||
95 | /* jump to C code */ | 110 | /* jump to C code */ |
96 | la t0, main | 111 | la t0, main |
97 | jr t0 | 112 | jr t0 |
98 | move a0, k0 | 113 | move a0, k0 |
114 | |||
115 | die_blink: | ||
116 | /* die blinking */ | ||
117 | la a0, 0xb0010400 | ||
118 | li a1, 2 | ||
119 | sw a1, 0x48(a0) /* clear function (gpio or interrupt) */ | ||
120 | sw a1, 0x58(a0) /* clear select (gpio) */ | ||
121 | sw a1, 0x64(a0) /* set direction (out) */ | ||
122 | sw a1, 0x34(a0) /* set pull (disable) */ | ||
123 | /* turn backlight on and off */ | ||
124 | la a0, 0xb0010414 | ||
125 | li a1, 2 | ||
126 | .blink_loop: | ||
127 | sw a1, (a0) | ||
128 | la v0, 10000000 | ||
129 | .wait: | ||
130 | bnez v0, .wait | ||
131 | subu v0, 1 | ||
132 | sw a1, 4(a0) | ||
133 | la v0, 10000000 | ||
134 | .wait2: | ||
135 | bnez v0, .wait2 | ||
136 | subu v0, 1 | ||
137 | j .blink_loop | ||
138 | nop | ||
139 | |||
140 | /* restore_data_abort_jmp restores the context and returns from exception */ | ||
141 | .extern restore_data_abort_jmp | ||
142 | |||
143 | .global tlb_refill_handler | ||
144 | .section .exception.tlb_refill,"ax",%progbits | ||
145 | tlb_refill_handler: | ||
146 | la k0, restore_data_abort_jmp | ||
147 | jr k0 | ||
148 | nop | ||
149 | |||
150 | .global cache_error_handler | ||
151 | .section .exception.cache_error,"ax",%progbits | ||
152 | cache_error_handler: | ||
153 | la k0, restore_data_abort_jmp | ||
154 | jr k0 | ||
155 | nop | ||
156 | |||
157 | .global general_exception_handler | ||
158 | .section .exception.general_exception,"ax",%progbits | ||
159 | general_exception_handler: | ||
160 | la k0, restore_data_abort_jmp | ||
161 | jr k0 | ||
162 | nop | ||
diff --git a/utils/hwstub/stub/jz4760b/hwstub.lds b/utils/hwstub/stub/jz4760b/hwstub.lds index 33aad51ebd..f0460284ca 100644 --- a/utils/hwstub/stub/jz4760b/hwstub.lds +++ b/utils/hwstub/stub/jz4760b/hwstub.lds | |||
@@ -20,10 +20,23 @@ SECTIONS | |||
20 | *(.icode*) | 20 | *(.icode*) |
21 | *(.data*) | 21 | *(.data*) |
22 | *(.rodata*) | 22 | *(.rodata*) |
23 | /* exceptions needs to be on a 0x1000 boundary */ | ||
24 | . = ALIGN(0x1000); | ||
25 | tcsm0_irqbase = .; | ||
26 | KEEP(*(.exception.tlb_refill)) | ||
27 | . = tcsm0_irqbase + 0x100; | ||
28 | KEEP(*(.exception.cache_error)) | ||
29 | . = tcsm0_irqbase + 0x180; | ||
30 | KEEP(*(.exception.general_exception)) | ||
23 | . = ALIGN(4); | 31 | . = ALIGN(4); |
24 | relocend = .; | 32 | relocend = .; |
25 | } > TCSM0 | 33 | } > TCSM0 |
26 | 34 | ||
35 | /* tcsm0_irqbase is the address in the 0xf400xxxx address space, but for | ||
36 | * EBASE, we want to the corresponding k1seg address, that maps to the | ||
37 | * physical address of TCSM0 */ | ||
38 | irqbase = tcsm0_irqbase - TCSM0_ORIG + TCSM0_UNCACHED_ADDRESS; | ||
39 | |||
27 | .bss (NOLOAD) : | 40 | .bss (NOLOAD) : |
28 | { | 41 | { |
29 | bssbegin = .; | 42 | bssbegin = .; |
diff --git a/utils/hwstub/stub/jz4760b/target-config.h b/utils/hwstub/stub/jz4760b/target-config.h index 681e17e6f6..5737e0bc87 100644 --- a/utils/hwstub/stub/jz4760b/target-config.h +++ b/utils/hwstub/stub/jz4760b/target-config.h | |||
@@ -1,6 +1,7 @@ | |||
1 | #define CONFIG_JZ4760B | 1 | #define CONFIG_JZ4760B |
2 | #define TCSM0_ORIG 0xf4000000 | 2 | #define TCSM0_ORIG 0xf4000000 |
3 | #define TCSM0_SIZE 0x4000 | 3 | #define TCSM0_SIZE 0x4000 |
4 | #define TCSM0_UNCACHED_ADDRESS 0xb32b0000 | ||
4 | #define CPU_MIPS | 5 | #define CPU_MIPS |
5 | #define STACK_SIZE 0x300 | 6 | #define STACK_SIZE 0x300 |
6 | #define DCACHE_SIZE 0x4000 /* 16 kB */ | 7 | #define DCACHE_SIZE 0x4000 /* 16 kB */ |