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. 5 * 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 10 11#include <asm/cacheops.h> 12#include <asm/addrspace.h> 13 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 */ 19 20#define ICACHE_SET_COUNT 256 /* Instruction cache set count */ 21#define DCACHE_SET_COUNT 128 /* Data cache set count */ 22 23#define ICACHE_SET_SIZE (ICACHE_SET_COUNT * ICACHE_LINE_SIZE) 24#define DCACHE_SET_SIZE (DCACHE_SET_COUNT * DCACHE_LINE_SIZE) 25 26 .macro kernel_entry_setup 27 .set push 28 .set noreorder 29 /* 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. 34 */ 35cache_begin: li t0, (1<<28) 36 mtc0 t0, CP0_STATUS /* cp0 usable */ 37 HAZARD_CP0 38 39 mtc0 zero, CP0_CAUSE 40 HAZARD_CP0 41 42 43 /* Set static virtual to phys address translation and TLB disabled */ 44 mfc0 t0, CP0_CONFIG, 7 45 HAZARD_CP0 46 47 and t0, ~((1<<19) | (1<<20)) /* TLB/MAP cleared */ 48 mtc0 t0, CP0_CONFIG, 7 49 HAZARD_CP0 50 51 /* CPU boots with kseg0 cache algo set to 0x2 -- uncached */ 52 53 init_icache 54 nop 55 init_dcache 56 nop 57 58 cachePr4450ICReset 59 nop 60 61 cachePr4450DCReset 62 nop 63 64 /* read ConfigPR into t0 */ 65 mfc0 t0, CP0_CONFIG, 7 66 HAZARD_CP0 67 68 /* enable the TLB */ 69 or t0, (1<<19) 70 71 /* disable the ICACHE: at least 10x slower */ 72 /* or t0, (1<<26) */ 73 74 /* disable the DCACHE; CONFIG_CPU_HAS_LLSC should not be set */ 75 /* or t0, (1<<27) */ 76 77 and t0, CO_CONFIGPR_VALID 78 79 /* enable TLB. */ 80 mtc0 t0, CP0_CONFIG, 7 81 HAZARD_CP0 82cache_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 88 89 /* Setup CMEM_1, 128MB */ 90 lui t0, 0x1000 91 addi t0, t0, 0xf 92 mtc0 $8, $22, 5 93 nop 94 95 96 /* Setup CMEM_2, 32MB */ 97 lui t0, 0x1C00 98 addi t0, t0, 0xb 99 mtc0 $8, $22, 6 100 nop 101 102 /* Setup CMEM_3, 0MB */ 103 lui t0, 0x0 104 addi t0, t0, 0x0 105 mtc0 $8, $22, 7 106 nop 107 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 117 118 .macro init_icache 119 .set push 120 .set noreorder 121 122 /* Get Cache Configuration */ 123 mfc0 t3, CP0_CONFIG, 1 124 HAZARD_CP0 125 126 /* get cache Line size */ 127 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 */ 131 nop 132 addiu t0, t1, 1 133 ori t1, zero, 1 134 sllv t1, t1, t0 135 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 142 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 147 148 /* total no of cache lines */ 149 multu t2, t3 /* max index * max way */ 150 mflo t2 151 addiu t2, t2, -1 152 153 move t0, zero 154pr4450_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 */ 159pr4450_instr_cache_invalidated: 160 .set pop 161 .endm 162 163 .macro init_dcache 164 .set push 165 .set noreorder 166 move t1, zero 167 168 /* Store Tag Information */ 169 mtc0 zero, CP0_TAGLO, 0 170 HAZARD_CP0 171 172 mtc0 zero, CP0_TAGHI, 0 173 HAZARD_CP0 174 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 */ 1782: 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 185 186 .macro cachePr4450ICReset 187 .set push 188 .set noreorder 189 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 194 195 mtc0 zero, CP0_STATUS /* disable CPU interrupts */ 196 HAZARD_CP0 197 198 or t1, zero, zero /* T1 = starting cache index (0) */ 199 ori t2, zero, (256 - 1) /* T2 = inst cache set cnt - 1 */ 200 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 */ 207 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) */ 211 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) */ 218 219 mtc0 t0, CP0_STATUS /* restore interrupt status on entry */ 220 HAZARD_CP0 221 .set pop 222 .endm 223 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 231 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 */ 235 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 */ 246 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) */ 250 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) */ 256 257 mtc0 t0, CP0_STATUS /* restore interrupt status on entry */ 258 HAZARD_CP0 259 .set pop 260 .endm 261 262#endif /* __ASM_MACH_KERNEL_ENTRY_INIT_H */ 263