Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
kernel-entry-init.h
Go to the documentation of this file.
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  */
35 cache_begin: li t0, (1<<28)
36  mtc0 t0, CP0_STATUS /* cp0 usable */
38 
39  mtc0 zero, CP0_CAUSE
41 
42 
43  /* Set static virtual to phys address translation and TLB disabled */
44  mfc0 t0, CP0_CONFIG, 7
46 
47  and t0, ~((1<<19) | (1<<20)) /* TLB/MAP cleared */
48  mtc0 t0, CP0_CONFIG, 7
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
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 
78 
79  /* enable TLB. */
80  mtc0 t0, CP0_CONFIG, 7
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
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
154 pr4450_next_instruction_cache_set:
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
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 */
178 2:
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 */