Committer: Michael Beasley <mike@snafu.setup>
[mikesnafu-overlay.git] / include / asm-mips / mach-pnx8550 / kernel-entry-init.h
blobbdde00c9199b6f65ecffbc351be30870279b1a84
1 /*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
6 * Copyright (C) 2005 Embedded Alley Solutions, Inc
7 */
8 #ifndef __ASM_MACH_KERNEL_ENTRY_INIT_H
9 #define __ASM_MACH_KERNEL_ENTRY_INIT_H
11 #include <asm/cacheops.h>
12 #include <asm/addrspace.h>
14 #define CO_CONFIGPR_VALID 0x3F1F41FF /* valid bits to write to ConfigPR */
15 #define HAZARD_CP0 nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;
16 #define CACHE_OPC 0xBC000000 /* MIPS cache instruction opcode */
17 #define ICACHE_LINE_SIZE 32 /* Instruction cache line size bytes */
18 #define DCACHE_LINE_SIZE 32 /* Data cache line size in bytes */
20 #define ICACHE_SET_COUNT 256 /* Instruction cache set count */
21 #define DCACHE_SET_COUNT 128 /* Data cache set count */
23 #define ICACHE_SET_SIZE (ICACHE_SET_COUNT * ICACHE_LINE_SIZE)
24 #define DCACHE_SET_SIZE (DCACHE_SET_COUNT * DCACHE_LINE_SIZE)
26 .macro kernel_entry_setup
27 .set push
28 .set noreorder
30 * PNX8550 entry point, when running a non compressed
31 * kernel. When loading a zImage, the head.S code in
32 * arch/mips/zboot/pnx8550 will init the caches and,
33 * decompress the kernel, and branch to kernel_entry.
35 cache_begin: li t0, (1<<28)
36 mtc0 t0, CP0_STATUS /* cp0 usable */
37 HAZARD_CP0
39 mtc0 zero, CP0_CAUSE
40 HAZARD_CP0
43 /* Set static virtual to phys address translation and TLB disabled */
44 mfc0 t0, CP0_CONFIG, 7
45 HAZARD_CP0
47 and t0, ~((1<<19) | (1<<20)) /* TLB/MAP cleared */
48 mtc0 t0, CP0_CONFIG, 7
49 HAZARD_CP0
51 /* CPU boots with kseg0 cache algo set to 0x2 -- uncached */
53 init_icache
54 nop
55 init_dcache
56 nop
58 cachePr4450ICReset
59 nop
61 cachePr4450DCReset
62 nop
64 /* read ConfigPR into t0 */
65 mfc0 t0, CP0_CONFIG, 7
66 HAZARD_CP0
68 /* enable the TLB */
69 or t0, (1<<19)
71 /* disable the ICACHE: at least 10x slower */
72 /* or t0, (1<<26) */
74 /* disable the DCACHE; CONFIG_CPU_HAS_LLSC should not be set */
75 /* or t0, (1<<27) */
77 and t0, CO_CONFIGPR_VALID
79 /* enable TLB. */
80 mtc0 t0, CP0_CONFIG, 7
81 HAZARD_CP0
82 cache_end:
83 /* Setup CMEM_0 to MMIO address space, 2MB */
84 lui t0, 0x1BE0
85 addi t0, t0, 0x3
86 mtc0 $8, $22, 4
87 nop
89 /* Setup CMEM_1, 128MB */
90 lui t0, 0x1000
91 addi t0, t0, 0xf
92 mtc0 $8, $22, 5
93 nop
96 /* Setup CMEM_2, 32MB */
97 lui t0, 0x1C00
98 addi t0, t0, 0xb
99 mtc0 $8, $22, 6
102 /* Setup CMEM_3, 0MB */
103 lui t0, 0x0
104 addi t0, t0, 0x0
105 mtc0 $8, $22, 7
108 /* Enable cache */
109 mfc0 t0, CP0_CONFIG
110 HAZARD_CP0
111 and t0, t0, 0xFFFFFFF8
112 or t0, t0, 3
113 mtc0 t0, CP0_CONFIG
114 HAZARD_CP0
115 .set pop
116 .endm
118 .macro init_icache
119 .set push
120 .set noreorder
122 /* Get Cache Configuration */
123 mfc0 t3, CP0_CONFIG, 1
124 HAZARD_CP0
126 /* get cache Line size */
128 srl t1, t3, 19 /* C0_CONFIGPR_IL_SHIFT */
129 andi t1, t1, 0x7 /* C0_CONFIGPR_IL_MASK */
130 beq t1, zero, pr4450_instr_cache_invalidated /* if zero instruction cache is absent */
132 addiu t0, t1, 1
133 ori t1, zero, 1
134 sllv t1, t1, t0
136 /* get max cache Index */
137 srl t2, t3, 22 /* C0_CONFIGPR_IS_SHIFT */
138 andi t2, t2, 0x7 /* C0_CONFIGPR_IS_MASK */
139 addiu t0, t2, 6
140 ori t2, zero, 1
141 sllv t2, t2, t0
143 /* get max cache way */
144 srl t3, t3, 16 /* C0_CONFIGPR_IA_SHIFT */
145 andi t3, t3, 0x7 /* C0_CONFIGPR_IA_MASK */
146 addiu t3, t3, 1
148 /* total no of cache lines */
149 multu t2, t3 /* max index * max way */
150 mflo t2
151 addiu t2, t2, -1
153 move t0, zero
154 pr4450_next_instruction_cache_set:
155 cache Index_Invalidate_I, 0(t0)
156 addu t0, t0, t1 /* add bytes in a line */
157 bne t2, zero, pr4450_next_instruction_cache_set
158 addiu t2, t2, -1 /* reduce no of lines to invalidate by one */
159 pr4450_instr_cache_invalidated:
160 .set pop
161 .endm
163 .macro init_dcache
164 .set push
165 .set noreorder
166 move t1, zero
168 /* Store Tag Information */
169 mtc0 zero, CP0_TAGLO, 0
170 HAZARD_CP0
172 mtc0 zero, CP0_TAGHI, 0
173 HAZARD_CP0
175 /* Cache size is 16384 = 512 lines x 32 bytes per line */
176 or t2, zero, (128*4)-1 /* 512 lines */
177 /* Invalidate all lines */
179 cache Index_Store_Tag_D, 0(t1)
180 addiu t2, t2, -1
181 bne t2, zero, 2b
182 addiu t1, t1, 32 /* 32 bytes in a line */
183 .set pop
184 .endm
186 .macro cachePr4450ICReset
187 .set push
188 .set noreorder
190 /* Save CP0 status reg on entry; */
191 /* disable interrupts during cache reset */
192 mfc0 t0, CP0_STATUS /* T0 = interrupt status on entry */
193 HAZARD_CP0
195 mtc0 zero, CP0_STATUS /* disable CPU interrupts */
196 HAZARD_CP0
198 or t1, zero, zero /* T1 = starting cache index (0) */
199 ori t2, zero, (256 - 1) /* T2 = inst cache set cnt - 1 */
201 icache_invd_loop:
202 /* 9 == register t1 */
203 .word CACHE_OPC | (9 << 21) | (Index_Invalidate_I << 16) | \
204 (0 * ICACHE_SET_SIZE) /* invalidate inst cache WAY0 */
205 .word CACHE_OPC | (9 << 21) | (Index_Invalidate_I << 16) | \
206 (1 * ICACHE_SET_SIZE) /* invalidate inst cache WAY1 */
208 addiu t1, t1, ICACHE_LINE_SIZE /* T1 = next cache line index */
209 bne t2, zero, icache_invd_loop /* T2 = 0 if all sets invalidated */
210 addiu t2, t2, -1 /* decrement T2 set cnt (delay slot) */
212 /* Initialize the latches in the instruction cache tag */
213 /* that drive the way selection tri-state bus drivers, by doing a */
214 /* dummy load while the instruction cache is still disabled. */
215 /* TODO: Is this needed ? */
216 la t1, KSEG0 /* T1 = cached memory base address */
217 lw zero, 0x0000(t1) /* (dummy read of first memory word) */
219 mtc0 t0, CP0_STATUS /* restore interrupt status on entry */
220 HAZARD_CP0
221 .set pop
222 .endm
224 .macro cachePr4450DCReset
225 .set push
226 .set noreorder
227 mfc0 t0, CP0_STATUS /* T0 = interrupt status on entry */
228 HAZARD_CP0
229 mtc0 zero, CP0_STATUS /* disable CPU interrupts */
230 HAZARD_CP0
232 /* Writeback/invalidate entire data cache sets/ways/lines */
233 or t1, zero, zero /* T1 = starting cache index (0) */
234 ori t2, zero, (DCACHE_SET_COUNT - 1) /* T2 = data cache set cnt - 1 */
236 dcache_wbinvd_loop:
237 /* 9 == register t1 */
238 .word CACHE_OPC | (9 << 21) | (Index_Writeback_Inv_D << 16) | \
239 (0 * DCACHE_SET_SIZE) /* writeback/invalidate WAY0 */
240 .word CACHE_OPC | (9 << 21) | (Index_Writeback_Inv_D << 16) | \
241 (1 * DCACHE_SET_SIZE) /* writeback/invalidate WAY1 */
242 .word CACHE_OPC | (9 << 21) | (Index_Writeback_Inv_D << 16) | \
243 (2 * DCACHE_SET_SIZE) /* writeback/invalidate WAY2 */
244 .word CACHE_OPC | (9 << 21) | (Index_Writeback_Inv_D << 16) | \
245 (3 * DCACHE_SET_SIZE) /* writeback/invalidate WAY3 */
247 addiu t1, t1, DCACHE_LINE_SIZE /* T1 = next data cache line index */
248 bne t2, zero, dcache_wbinvd_loop /* T2 = 0 when wbinvd entire cache */
249 addiu t2, t2, -1 /* decrement T2 set cnt (delay slot) */
251 /* Initialize the latches in the data cache tag that drive the way
252 selection tri-state bus drivers, by doing a dummy load while the
253 data cache is still in the disabled mode. TODO: Is this needed ? */
254 la t1, KSEG0 /* T1 = cached memory base address */
255 lw zero, 0x0000(t1) /* (dummy read of first memory word) */
257 mtc0 t0, CP0_STATUS /* restore interrupt status on entry */
258 HAZARD_CP0
259 .set pop
260 .endm
262 #endif /* __ASM_MACH_KERNEL_ENTRY_INIT_H */