diff options
Diffstat (limited to 'arch/sparc64')
-rw-r--r-- | arch/sparc64/kernel/head.S | 549 | ||||
-rw-r--r-- | arch/sparc64/kernel/setup.c | 15 | ||||
-rw-r--r-- | arch/sparc64/kernel/trampoline.S | 16 | ||||
-rw-r--r-- | arch/sparc64/mm/init.c | 98 | ||||
-rw-r--r-- | arch/sparc64/prom/Makefile | 2 | ||||
-rw-r--r-- | arch/sparc64/prom/console.c | 2 | ||||
-rw-r--r-- | arch/sparc64/prom/devops.c | 2 | ||||
-rw-r--r-- | arch/sparc64/prom/init.c | 2 | ||||
-rw-r--r-- | arch/sparc64/prom/map.S | 72 | ||||
-rw-r--r-- | arch/sparc64/prom/misc.c | 34 | ||||
-rw-r--r-- | arch/sparc64/prom/p1275.c | 2 | ||||
-rw-r--r-- | arch/sparc64/prom/printf.c | 2 | ||||
-rw-r--r-- | arch/sparc64/prom/tree.c | 50 |
13 files changed, 221 insertions, 625 deletions
diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S index dc3551f46b76..8b83520e4272 100644 --- a/arch/sparc64/kernel/head.S +++ b/arch/sparc64/kernel/head.S | |||
@@ -80,15 +80,165 @@ sparc_ramdisk_image64: | |||
80 | .xword 0 | 80 | .xword 0 |
81 | .word _end | 81 | .word _end |
82 | 82 | ||
83 | /* We must be careful, 32-bit OpenBOOT will get confused if it | 83 | /* PROM cif handler code address is in %o4. */ |
84 | * tries to save away a register window to a 64-bit kernel | 84 | sparc64_boot: |
85 | * stack address. Flush all windows, disable interrupts, | 85 | 1: rd %pc, %g7 |
86 | * remap if necessary, jump onto kernel trap table, then kernel | 86 | set 1b, %g1 |
87 | * stack, or else we die. | 87 | cmp %g1, %g7 |
88 | be,pn %xcc, sparc64_boot_after_remap | ||
89 | mov %o4, %l7 | ||
90 | |||
91 | /* We need to remap the kernel. Use position independant | ||
92 | * code to remap us to KERNBASE. | ||
88 | * | 93 | * |
89 | * PROM entry point is on %o4 | 94 | * SILO can invoke us with 32-bit address masking enabled, |
95 | * so make sure that's clear. | ||
90 | */ | 96 | */ |
91 | sparc64_boot: | 97 | rdpr %pstate, %g1 |
98 | andn %g1, PSTATE_AM, %g1 | ||
99 | wrpr %g1, 0x0, %pstate | ||
100 | ba,a,pt %xcc, 1f | ||
101 | |||
102 | .globl prom_finddev_name, prom_chosen_path | ||
103 | .globl prom_getprop_name, prom_mmu_name | ||
104 | .globl prom_callmethod_name, prom_translate_name | ||
105 | .globl prom_map_name, prom_unmap_name, prom_mmu_ihandle_cache | ||
106 | .globl prom_boot_mapped_pc, prom_boot_mapping_mode | ||
107 | .globl prom_boot_mapping_phys_high, prom_boot_mapping_phys_low | ||
108 | prom_finddev_name: | ||
109 | .asciz "finddevice" | ||
110 | prom_chosen_path: | ||
111 | .asciz "/chosen" | ||
112 | prom_getprop_name: | ||
113 | .asciz "getprop" | ||
114 | prom_mmu_name: | ||
115 | .asciz "mmu" | ||
116 | prom_callmethod_name: | ||
117 | .asciz "call-method" | ||
118 | prom_translate_name: | ||
119 | .asciz "translate" | ||
120 | prom_map_name: | ||
121 | .asciz "map" | ||
122 | prom_unmap_name: | ||
123 | .asciz "unmap" | ||
124 | .align 4 | ||
125 | prom_mmu_ihandle_cache: | ||
126 | .word 0 | ||
127 | prom_boot_mapped_pc: | ||
128 | .word 0 | ||
129 | prom_boot_mapping_mode: | ||
130 | .word 0 | ||
131 | .align 8 | ||
132 | prom_boot_mapping_phys_high: | ||
133 | .xword 0 | ||
134 | prom_boot_mapping_phys_low: | ||
135 | .xword 0 | ||
136 | 1: | ||
137 | rd %pc, %l0 | ||
138 | mov (1b - prom_finddev_name), %l1 | ||
139 | mov (1b - prom_chosen_path), %l2 | ||
140 | mov (1b - prom_boot_mapped_pc), %l3 | ||
141 | sub %l0, %l1, %l1 | ||
142 | sub %l0, %l2, %l2 | ||
143 | sub %l0, %l3, %l3 | ||
144 | stw %l0, [%l3] | ||
145 | sub %sp, (192 + 128), %sp | ||
146 | |||
147 | /* chosen_node = prom_finddevice("/chosen") */ | ||
148 | stx %l1, [%sp + 2047 + 128 + 0x00] ! service, "finddevice" | ||
149 | mov 1, %l3 | ||
150 | stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 1 | ||
151 | stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 1 | ||
152 | stx %l2, [%sp + 2047 + 128 + 0x18] ! arg1, "/chosen" | ||
153 | stx %g0, [%sp + 2047 + 128 + 0x20] ! ret1 | ||
154 | call %l7 | ||
155 | add %sp, (2047 + 128), %o0 ! argument array | ||
156 | |||
157 | ldx [%sp + 2047 + 128 + 0x20], %l4 ! chosen device node | ||
158 | |||
159 | mov (1b - prom_getprop_name), %l1 | ||
160 | mov (1b - prom_mmu_name), %l2 | ||
161 | mov (1b - prom_mmu_ihandle_cache), %l5 | ||
162 | sub %l0, %l1, %l1 | ||
163 | sub %l0, %l2, %l2 | ||
164 | sub %l0, %l5, %l5 | ||
165 | |||
166 | /* prom_mmu_ihandle_cache = prom_getint(chosen_node, "mmu") */ | ||
167 | stx %l1, [%sp + 2047 + 128 + 0x00] ! service, "getprop" | ||
168 | mov 4, %l3 | ||
169 | stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 4 | ||
170 | mov 1, %l3 | ||
171 | stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 1 | ||
172 | stx %l4, [%sp + 2047 + 128 + 0x18] ! arg1, chosen_node | ||
173 | stx %l2, [%sp + 2047 + 128 + 0x20] ! arg2, "mmu" | ||
174 | stx %l5, [%sp + 2047 + 128 + 0x28] ! arg3, &prom_mmu_ihandle_cache | ||
175 | mov 4, %l3 | ||
176 | stx %l3, [%sp + 2047 + 128 + 0x30] ! arg4, sizeof(arg3) | ||
177 | stx %g0, [%sp + 2047 + 128 + 0x38] ! ret1 | ||
178 | call %l7 | ||
179 | add %sp, (2047 + 128), %o0 ! argument array | ||
180 | |||
181 | mov (1b - prom_callmethod_name), %l1 | ||
182 | mov (1b - prom_translate_name), %l2 | ||
183 | sub %l0, %l1, %l1 | ||
184 | sub %l0, %l2, %l2 | ||
185 | lduw [%l5], %l5 ! prom_mmu_ihandle_cache | ||
186 | |||
187 | stx %l1, [%sp + 2047 + 128 + 0x00] ! service, "call-method" | ||
188 | mov 3, %l3 | ||
189 | stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 3 | ||
190 | mov 5, %l3 | ||
191 | stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 5 | ||
192 | stx %l2, [%sp + 2047 + 128 + 0x18] ! arg1: "translate" | ||
193 | stx %l5, [%sp + 2047 + 128 + 0x20] ! arg2: prom_mmu_ihandle_cache | ||
194 | srlx %l0, 22, %l3 | ||
195 | sllx %l3, 22, %l3 | ||
196 | stx %l3, [%sp + 2047 + 128 + 0x28] ! arg3: vaddr, our PC | ||
197 | stx %g0, [%sp + 2047 + 128 + 0x30] ! res1 | ||
198 | stx %g0, [%sp + 2047 + 128 + 0x38] ! res2 | ||
199 | stx %g0, [%sp + 2047 + 128 + 0x40] ! res3 | ||
200 | stx %g0, [%sp + 2047 + 128 + 0x48] ! res4 | ||
201 | stx %g0, [%sp + 2047 + 128 + 0x50] ! res5 | ||
202 | call %l7 | ||
203 | add %sp, (2047 + 128), %o0 ! argument array | ||
204 | |||
205 | ldx [%sp + 2047 + 128 + 0x40], %l1 ! translation mode | ||
206 | mov (1b - prom_boot_mapping_mode), %l4 | ||
207 | sub %l0, %l4, %l4 | ||
208 | stw %l1, [%l4] | ||
209 | mov (1b - prom_boot_mapping_phys_high), %l4 | ||
210 | sub %l0, %l4, %l4 | ||
211 | ldx [%sp + 2047 + 128 + 0x48], %l2 ! physaddr high | ||
212 | stx %l2, [%l4 + 0x0] | ||
213 | ldx [%sp + 2047 + 128 + 0x50], %l3 ! physaddr low | ||
214 | stx %l3, [%l4 + 0x8] | ||
215 | |||
216 | /* Leave service as-is, "call-method" */ | ||
217 | mov 7, %l3 | ||
218 | stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 7 | ||
219 | mov 1, %l3 | ||
220 | stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 7 | ||
221 | mov (1b - prom_map_name), %l3 | ||
222 | sub %l0, %l3, %l3 | ||
223 | stx %l3, [%sp + 2047 + 128 + 0x18] ! arg1: "map" | ||
224 | /* Leave arg2 as-is, prom_mmu_ihandle_cache */ | ||
225 | mov -1, %l3 | ||
226 | stx %l3, [%sp + 2047 + 128 + 0x28] ! arg3: mode (-1 default) | ||
227 | sethi %hi(8 * 1024 * 1024), %l3 | ||
228 | stx %l3, [%sp + 2047 + 128 + 0x30] ! arg4: size (8MB) | ||
229 | sethi %hi(KERNBASE), %l3 | ||
230 | stx %l3, [%sp + 2047 + 128 + 0x38] ! arg5: vaddr (KERNBASE) | ||
231 | stx %g0, [%sp + 2047 + 128 + 0x40] ! arg6: empty | ||
232 | mov (1b - prom_boot_mapping_phys_low), %l3 | ||
233 | sub %l0, %l3, %l3 | ||
234 | ldx [%l3], %l3 | ||
235 | stx %l3, [%sp + 2047 + 128 + 0x48] ! arg7: phys addr | ||
236 | call %l7 | ||
237 | add %sp, (2047 + 128), %o0 ! argument array | ||
238 | |||
239 | add %sp, (192 + 128), %sp | ||
240 | |||
241 | sparc64_boot_after_remap: | ||
92 | BRANCH_IF_CHEETAH_BASE(g1,g7,cheetah_boot) | 242 | BRANCH_IF_CHEETAH_BASE(g1,g7,cheetah_boot) |
93 | BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g7,cheetah_plus_boot) | 243 | BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g7,cheetah_plus_boot) |
94 | ba,pt %xcc, spitfire_boot | 244 | ba,pt %xcc, spitfire_boot |
@@ -125,185 +275,7 @@ cheetah_generic_boot: | |||
125 | stxa %g0, [%g3] ASI_IMMU | 275 | stxa %g0, [%g3] ASI_IMMU |
126 | membar #Sync | 276 | membar #Sync |
127 | 277 | ||
128 | wrpr %g0, (PSTATE_PRIV|PSTATE_PEF|PSTATE_IE), %pstate | 278 | ba,a,pt %xcc, jump_to_sun4u_init |
129 | wr %g0, 0, %fprs | ||
130 | |||
131 | /* Just like for Spitfire, we probe itlb-2 for a mapping which | ||
132 | * matches our current %pc. We take the physical address in | ||
133 | * that mapping and use it to make our own. | ||
134 | */ | ||
135 | |||
136 | /* %g5 holds the tlb data */ | ||
137 | sethi %uhi(_PAGE_VALID | _PAGE_SZ4MB), %g5 | ||
138 | sllx %g5, 32, %g5 | ||
139 | or %g5, (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W | _PAGE_G), %g5 | ||
140 | |||
141 | /* Put PADDR tlb data mask into %g3. */ | ||
142 | sethi %uhi(_PAGE_PADDR), %g3 | ||
143 | or %g3, %ulo(_PAGE_PADDR), %g3 | ||
144 | sllx %g3, 32, %g3 | ||
145 | sethi %hi(_PAGE_PADDR), %g7 | ||
146 | or %g7, %lo(_PAGE_PADDR), %g7 | ||
147 | or %g3, %g7, %g3 | ||
148 | |||
149 | set 2 << 16, %l0 /* TLB entry walker. */ | ||
150 | set 0x1fff, %l2 /* Page mask. */ | ||
151 | rd %pc, %l3 | ||
152 | andn %l3, %l2, %g2 /* vaddr comparator */ | ||
153 | |||
154 | 1: ldxa [%l0] ASI_ITLB_TAG_READ, %g1 | ||
155 | membar #Sync | ||
156 | andn %g1, %l2, %g1 | ||
157 | cmp %g1, %g2 | ||
158 | be,pn %xcc, cheetah_got_tlbentry | ||
159 | nop | ||
160 | and %l0, (127 << 3), %g1 | ||
161 | cmp %g1, (127 << 3) | ||
162 | blu,pt %xcc, 1b | ||
163 | add %l0, (1 << 3), %l0 | ||
164 | |||
165 | /* Search the small TLB. OBP never maps us like that but | ||
166 | * newer SILO can. | ||
167 | */ | ||
168 | clr %l0 | ||
169 | |||
170 | 1: ldxa [%l0] ASI_ITLB_TAG_READ, %g1 | ||
171 | membar #Sync | ||
172 | andn %g1, %l2, %g1 | ||
173 | cmp %g1, %g2 | ||
174 | be,pn %xcc, cheetah_got_tlbentry | ||
175 | nop | ||
176 | cmp %l0, (15 << 3) | ||
177 | blu,pt %xcc, 1b | ||
178 | add %l0, (1 << 3), %l0 | ||
179 | |||
180 | /* BUG() if we get here... */ | ||
181 | ta 0x5 | ||
182 | |||
183 | cheetah_got_tlbentry: | ||
184 | ldxa [%l0] ASI_ITLB_DATA_ACCESS, %g0 | ||
185 | ldxa [%l0] ASI_ITLB_DATA_ACCESS, %g1 | ||
186 | membar #Sync | ||
187 | and %g1, %g3, %g1 | ||
188 | set 0x5fff, %l0 | ||
189 | andn %g1, %l0, %g1 | ||
190 | or %g5, %g1, %g5 | ||
191 | |||
192 | /* Clear out any KERNBASE area entries. */ | ||
193 | set 2 << 16, %l0 | ||
194 | sethi %hi(KERNBASE), %g3 | ||
195 | sethi %hi(KERNBASE<<1), %g7 | ||
196 | mov TLB_TAG_ACCESS, %l7 | ||
197 | |||
198 | /* First, check ITLB */ | ||
199 | 1: ldxa [%l0] ASI_ITLB_TAG_READ, %g1 | ||
200 | membar #Sync | ||
201 | andn %g1, %l2, %g1 | ||
202 | cmp %g1, %g3 | ||
203 | blu,pn %xcc, 2f | ||
204 | cmp %g1, %g7 | ||
205 | bgeu,pn %xcc, 2f | ||
206 | nop | ||
207 | stxa %g0, [%l7] ASI_IMMU | ||
208 | membar #Sync | ||
209 | stxa %g0, [%l0] ASI_ITLB_DATA_ACCESS | ||
210 | membar #Sync | ||
211 | |||
212 | 2: and %l0, (127 << 3), %g1 | ||
213 | cmp %g1, (127 << 3) | ||
214 | blu,pt %xcc, 1b | ||
215 | add %l0, (1 << 3), %l0 | ||
216 | |||
217 | /* Next, check DTLB */ | ||
218 | set 2 << 16, %l0 | ||
219 | 1: ldxa [%l0] ASI_DTLB_TAG_READ, %g1 | ||
220 | membar #Sync | ||
221 | andn %g1, %l2, %g1 | ||
222 | cmp %g1, %g3 | ||
223 | blu,pn %xcc, 2f | ||
224 | cmp %g1, %g7 | ||
225 | bgeu,pn %xcc, 2f | ||
226 | nop | ||
227 | stxa %g0, [%l7] ASI_DMMU | ||
228 | membar #Sync | ||
229 | stxa %g0, [%l0] ASI_DTLB_DATA_ACCESS | ||
230 | membar #Sync | ||
231 | |||
232 | 2: and %l0, (511 << 3), %g1 | ||
233 | cmp %g1, (511 << 3) | ||
234 | blu,pt %xcc, 1b | ||
235 | add %l0, (1 << 3), %l0 | ||
236 | |||
237 | /* On Cheetah+, have to check second DTLB. */ | ||
238 | BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,l0,2f) | ||
239 | ba,pt %xcc, 9f | ||
240 | nop | ||
241 | |||
242 | 2: set 3 << 16, %l0 | ||
243 | 1: ldxa [%l0] ASI_DTLB_TAG_READ, %g1 | ||
244 | membar #Sync | ||
245 | andn %g1, %l2, %g1 | ||
246 | cmp %g1, %g3 | ||
247 | blu,pn %xcc, 2f | ||
248 | cmp %g1, %g7 | ||
249 | bgeu,pn %xcc, 2f | ||
250 | nop | ||
251 | stxa %g0, [%l7] ASI_DMMU | ||
252 | membar #Sync | ||
253 | stxa %g0, [%l0] ASI_DTLB_DATA_ACCESS | ||
254 | membar #Sync | ||
255 | |||
256 | 2: and %l0, (511 << 3), %g1 | ||
257 | cmp %g1, (511 << 3) | ||
258 | blu,pt %xcc, 1b | ||
259 | add %l0, (1 << 3), %l0 | ||
260 | |||
261 | 9: | ||
262 | |||
263 | /* Now lock the TTE we created into ITLB-0 and DTLB-0, | ||
264 | * entry 15 (and maybe 14 too). | ||
265 | */ | ||
266 | sethi %hi(KERNBASE), %g3 | ||
267 | set (0 << 16) | (15 << 3), %g7 | ||
268 | stxa %g3, [%l7] ASI_DMMU | ||
269 | membar #Sync | ||
270 | stxa %g5, [%g7] ASI_DTLB_DATA_ACCESS | ||
271 | membar #Sync | ||
272 | stxa %g3, [%l7] ASI_IMMU | ||
273 | membar #Sync | ||
274 | stxa %g5, [%g7] ASI_ITLB_DATA_ACCESS | ||
275 | membar #Sync | ||
276 | flush %g3 | ||
277 | membar #Sync | ||
278 | sethi %hi(_end), %g3 /* Check for bigkernel case */ | ||
279 | or %g3, %lo(_end), %g3 | ||
280 | srl %g3, 23, %g3 /* Check if _end > 8M */ | ||
281 | brz,pt %g3, 1f | ||
282 | sethi %hi(KERNBASE), %g3 /* Restore for fixup code below */ | ||
283 | sethi %hi(0x400000), %g3 | ||
284 | or %g3, %lo(0x400000), %g3 | ||
285 | add %g5, %g3, %g5 /* New tte data */ | ||
286 | andn %g5, (_PAGE_G), %g5 | ||
287 | sethi %hi(KERNBASE+0x400000), %g3 | ||
288 | or %g3, %lo(KERNBASE+0x400000), %g3 | ||
289 | set (0 << 16) | (14 << 3), %g7 | ||
290 | stxa %g3, [%l7] ASI_DMMU | ||
291 | membar #Sync | ||
292 | stxa %g5, [%g7] ASI_DTLB_DATA_ACCESS | ||
293 | membar #Sync | ||
294 | stxa %g3, [%l7] ASI_IMMU | ||
295 | membar #Sync | ||
296 | stxa %g5, [%g7] ASI_ITLB_DATA_ACCESS | ||
297 | membar #Sync | ||
298 | flush %g3 | ||
299 | membar #Sync | ||
300 | sethi %hi(KERNBASE), %g3 /* Restore for fixup code below */ | ||
301 | ba,pt %xcc, 1f | ||
302 | nop | ||
303 | |||
304 | 1: set sun4u_init, %g2 | ||
305 | jmpl %g2 + %g0, %g0 | ||
306 | nop | ||
307 | 279 | ||
308 | spitfire_boot: | 280 | spitfire_boot: |
309 | /* Typically PROM has already enabled both MMU's and both on-chip | 281 | /* Typically PROM has already enabled both MMU's and both on-chip |
@@ -313,6 +285,7 @@ spitfire_boot: | |||
313 | stxa %g1, [%g0] ASI_LSU_CONTROL | 285 | stxa %g1, [%g0] ASI_LSU_CONTROL |
314 | membar #Sync | 286 | membar #Sync |
315 | 287 | ||
288 | jump_to_sun4u_init: | ||
316 | /* | 289 | /* |
317 | * Make sure we are in privileged mode, have address masking, | 290 | * Make sure we are in privileged mode, have address masking, |
318 | * using the ordinary globals and have enabled floating | 291 | * using the ordinary globals and have enabled floating |
@@ -324,151 +297,6 @@ spitfire_boot: | |||
324 | wrpr %g0, (PSTATE_PRIV|PSTATE_PEF|PSTATE_IE), %pstate | 297 | wrpr %g0, (PSTATE_PRIV|PSTATE_PEF|PSTATE_IE), %pstate |
325 | wr %g0, 0, %fprs | 298 | wr %g0, 0, %fprs |
326 | 299 | ||
327 | spitfire_create_mappings: | ||
328 | /* %g5 holds the tlb data */ | ||
329 | sethi %uhi(_PAGE_VALID | _PAGE_SZ4MB), %g5 | ||
330 | sllx %g5, 32, %g5 | ||
331 | or %g5, (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W | _PAGE_G), %g5 | ||
332 | |||
333 | /* Base of physical memory cannot reliably be assumed to be | ||
334 | * at 0x0! Figure out where it happens to be. -DaveM | ||
335 | */ | ||
336 | |||
337 | /* Put PADDR tlb data mask into %g3. */ | ||
338 | sethi %uhi(_PAGE_PADDR_SF), %g3 | ||
339 | or %g3, %ulo(_PAGE_PADDR_SF), %g3 | ||
340 | sllx %g3, 32, %g3 | ||
341 | sethi %hi(_PAGE_PADDR_SF), %g7 | ||
342 | or %g7, %lo(_PAGE_PADDR_SF), %g7 | ||
343 | or %g3, %g7, %g3 | ||
344 | |||
345 | /* Walk through entire ITLB, looking for entry which maps | ||
346 | * our %pc currently, stick PADDR from there into %g5 tlb data. | ||
347 | */ | ||
348 | clr %l0 /* TLB entry walker. */ | ||
349 | set 0x1fff, %l2 /* Page mask. */ | ||
350 | rd %pc, %l3 | ||
351 | andn %l3, %l2, %g2 /* vaddr comparator */ | ||
352 | 1: | ||
353 | /* Yes, the nops seem to be necessary for now, don't ask me why. -DaveM */ | ||
354 | ldxa [%l0] ASI_ITLB_TAG_READ, %g1 | ||
355 | nop | ||
356 | nop | ||
357 | nop | ||
358 | andn %g1, %l2, %g1 /* Get vaddr */ | ||
359 | cmp %g1, %g2 | ||
360 | be,a,pn %xcc, spitfire_got_tlbentry | ||
361 | ldxa [%l0] ASI_ITLB_DATA_ACCESS, %g1 | ||
362 | cmp %l0, (63 << 3) | ||
363 | blu,pt %xcc, 1b | ||
364 | add %l0, (1 << 3), %l0 | ||
365 | |||
366 | /* BUG() if we get here... */ | ||
367 | ta 0x5 | ||
368 | |||
369 | spitfire_got_tlbentry: | ||
370 | /* Nops here again, perhaps Cheetah/Blackbird are better behaved... */ | ||
371 | nop | ||
372 | nop | ||
373 | nop | ||
374 | and %g1, %g3, %g1 /* Mask to just get paddr bits. */ | ||
375 | set 0x5fff, %l3 /* Mask offset to get phys base. */ | ||
376 | andn %g1, %l3, %g1 | ||
377 | |||
378 | /* NOTE: We hold on to %g1 paddr base as we need it below to lock | ||
379 | * NOTE: the PROM cif code into the TLB. | ||
380 | */ | ||
381 | |||
382 | or %g5, %g1, %g5 /* Or it into TAG being built. */ | ||
383 | |||
384 | clr %l0 /* TLB entry walker. */ | ||
385 | sethi %hi(KERNBASE), %g3 /* 4M lower limit */ | ||
386 | sethi %hi(KERNBASE<<1), %g7 /* 8M upper limit */ | ||
387 | mov TLB_TAG_ACCESS, %l7 | ||
388 | 1: | ||
389 | /* Yes, the nops seem to be necessary for now, don't ask me why. -DaveM */ | ||
390 | ldxa [%l0] ASI_ITLB_TAG_READ, %g1 | ||
391 | nop | ||
392 | nop | ||
393 | nop | ||
394 | andn %g1, %l2, %g1 /* Get vaddr */ | ||
395 | cmp %g1, %g3 | ||
396 | blu,pn %xcc, 2f | ||
397 | cmp %g1, %g7 | ||
398 | bgeu,pn %xcc, 2f | ||
399 | nop | ||
400 | stxa %g0, [%l7] ASI_IMMU | ||
401 | stxa %g0, [%l0] ASI_ITLB_DATA_ACCESS | ||
402 | membar #Sync | ||
403 | 2: | ||
404 | cmp %l0, (63 << 3) | ||
405 | blu,pt %xcc, 1b | ||
406 | add %l0, (1 << 3), %l0 | ||
407 | |||
408 | nop; nop; nop | ||
409 | |||
410 | clr %l0 /* TLB entry walker. */ | ||
411 | 1: | ||
412 | /* Yes, the nops seem to be necessary for now, don't ask me why. -DaveM */ | ||
413 | ldxa [%l0] ASI_DTLB_TAG_READ, %g1 | ||
414 | nop | ||
415 | nop | ||
416 | nop | ||
417 | andn %g1, %l2, %g1 /* Get vaddr */ | ||
418 | cmp %g1, %g3 | ||
419 | blu,pn %xcc, 2f | ||
420 | cmp %g1, %g7 | ||
421 | bgeu,pn %xcc, 2f | ||
422 | nop | ||
423 | stxa %g0, [%l7] ASI_DMMU | ||
424 | stxa %g0, [%l0] ASI_DTLB_DATA_ACCESS | ||
425 | membar #Sync | ||
426 | 2: | ||
427 | cmp %l0, (63 << 3) | ||
428 | blu,pt %xcc, 1b | ||
429 | add %l0, (1 << 3), %l0 | ||
430 | |||
431 | nop; nop; nop | ||
432 | |||
433 | |||
434 | /* PROM never puts any TLB entries into the MMU with the lock bit | ||
435 | * set. So we gladly use tlb entry 63 for KERNBASE. And maybe 62 too. | ||
436 | */ | ||
437 | |||
438 | sethi %hi(KERNBASE), %g3 | ||
439 | mov (63 << 3), %g7 | ||
440 | stxa %g3, [%l7] ASI_DMMU /* KERNBASE into TLB TAG */ | ||
441 | stxa %g5, [%g7] ASI_DTLB_DATA_ACCESS /* TTE into TLB DATA */ | ||
442 | membar #Sync | ||
443 | stxa %g3, [%l7] ASI_IMMU /* KERNBASE into TLB TAG */ | ||
444 | stxa %g5, [%g7] ASI_ITLB_DATA_ACCESS /* TTE into TLB DATA */ | ||
445 | membar #Sync | ||
446 | flush %g3 | ||
447 | membar #Sync | ||
448 | sethi %hi(_end), %g3 /* Check for bigkernel case */ | ||
449 | or %g3, %lo(_end), %g3 | ||
450 | srl %g3, 23, %g3 /* Check if _end > 8M */ | ||
451 | brz,pt %g3, 2f | ||
452 | sethi %hi(KERNBASE), %g3 /* Restore for fixup code below */ | ||
453 | sethi %hi(0x400000), %g3 | ||
454 | or %g3, %lo(0x400000), %g3 | ||
455 | add %g5, %g3, %g5 /* New tte data */ | ||
456 | andn %g5, (_PAGE_G), %g5 | ||
457 | sethi %hi(KERNBASE+0x400000), %g3 | ||
458 | or %g3, %lo(KERNBASE+0x400000), %g3 | ||
459 | mov (62 << 3), %g7 | ||
460 | stxa %g3, [%l7] ASI_DMMU | ||
461 | stxa %g5, [%g7] ASI_DTLB_DATA_ACCESS | ||
462 | membar #Sync | ||
463 | stxa %g3, [%l7] ASI_IMMU | ||
464 | stxa %g5, [%g7] ASI_ITLB_DATA_ACCESS | ||
465 | membar #Sync | ||
466 | flush %g3 | ||
467 | membar #Sync | ||
468 | sethi %hi(KERNBASE), %g3 /* Restore for fixup code below */ | ||
469 | 2: ba,pt %xcc, 1f | ||
470 | nop | ||
471 | 1: | ||
472 | set sun4u_init, %g2 | 300 | set sun4u_init, %g2 |
473 | jmpl %g2 + %g0, %g0 | 301 | jmpl %g2 + %g0, %g0 |
474 | nop | 302 | nop |
@@ -483,38 +311,12 @@ sun4u_init: | |||
483 | stxa %g0, [%g7] ASI_DMMU | 311 | stxa %g0, [%g7] ASI_DMMU |
484 | membar #Sync | 312 | membar #Sync |
485 | 313 | ||
486 | /* We are now safely (we hope) in Nucleus context (0), rewrite | ||
487 | * the KERNBASE TTE's so they no longer have the global bit set. | ||
488 | * Don't forget to setup TAG_ACCESS first 8-) | ||
489 | */ | ||
490 | mov TLB_TAG_ACCESS, %g2 | ||
491 | stxa %g3, [%g2] ASI_IMMU | ||
492 | stxa %g3, [%g2] ASI_DMMU | ||
493 | membar #Sync | ||
494 | |||
495 | BRANCH_IF_ANY_CHEETAH(g1,g7,cheetah_tlb_fixup) | 314 | BRANCH_IF_ANY_CHEETAH(g1,g7,cheetah_tlb_fixup) |
496 | 315 | ||
497 | ba,pt %xcc, spitfire_tlb_fixup | 316 | ba,pt %xcc, spitfire_tlb_fixup |
498 | nop | 317 | nop |
499 | 318 | ||
500 | cheetah_tlb_fixup: | 319 | cheetah_tlb_fixup: |
501 | set (0 << 16) | (15 << 3), %g7 | ||
502 | ldxa [%g7] ASI_ITLB_DATA_ACCESS, %g0 | ||
503 | ldxa [%g7] ASI_ITLB_DATA_ACCESS, %g1 | ||
504 | andn %g1, (_PAGE_G), %g1 | ||
505 | stxa %g1, [%g7] ASI_ITLB_DATA_ACCESS | ||
506 | membar #Sync | ||
507 | |||
508 | ldxa [%g7] ASI_DTLB_DATA_ACCESS, %g0 | ||
509 | ldxa [%g7] ASI_DTLB_DATA_ACCESS, %g1 | ||
510 | andn %g1, (_PAGE_G), %g1 | ||
511 | stxa %g1, [%g7] ASI_DTLB_DATA_ACCESS | ||
512 | membar #Sync | ||
513 | |||
514 | /* Kill instruction prefetch queues. */ | ||
515 | flush %g3 | ||
516 | membar #Sync | ||
517 | |||
518 | mov 2, %g2 /* Set TLB type to cheetah+. */ | 320 | mov 2, %g2 /* Set TLB type to cheetah+. */ |
519 | BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g7,1f) | 321 | BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g7,1f) |
520 | 322 | ||
@@ -551,21 +353,6 @@ cheetah_tlb_fixup: | |||
551 | nop | 353 | nop |
552 | 354 | ||
553 | spitfire_tlb_fixup: | 355 | spitfire_tlb_fixup: |
554 | mov (63 << 3), %g7 | ||
555 | ldxa [%g7] ASI_ITLB_DATA_ACCESS, %g1 | ||
556 | andn %g1, (_PAGE_G), %g1 | ||
557 | stxa %g1, [%g7] ASI_ITLB_DATA_ACCESS | ||
558 | membar #Sync | ||
559 | |||
560 | ldxa [%g7] ASI_DTLB_DATA_ACCESS, %g1 | ||
561 | andn %g1, (_PAGE_G), %g1 | ||
562 | stxa %g1, [%g7] ASI_DTLB_DATA_ACCESS | ||
563 | membar #Sync | ||
564 | |||
565 | /* Kill instruction prefetch queues. */ | ||
566 | flush %g3 | ||
567 | membar #Sync | ||
568 | |||
569 | /* Set TLB type to spitfire. */ | 356 | /* Set TLB type to spitfire. */ |
570 | mov 0, %g2 | 357 | mov 0, %g2 |
571 | sethi %hi(tlb_type), %g1 | 358 | sethi %hi(tlb_type), %g1 |
@@ -578,24 +365,6 @@ tlb_fixup_done: | |||
578 | mov %sp, %l6 | 365 | mov %sp, %l6 |
579 | mov %o4, %l7 | 366 | mov %o4, %l7 |
580 | 367 | ||
581 | #if 0 /* We don't do it like this anymore, but for historical hack value | ||
582 | * I leave this snippet here to show how crazy we can be sometimes. 8-) | ||
583 | */ | ||
584 | |||
585 | /* Setup "Linux Current Register", thanks Sun 8-) */ | ||
586 | wr %g0, 0x1, %pcr | ||
587 | |||
588 | /* Blackbird errata workaround. See commentary in | ||
589 | * smp.c:smp_percpu_timer_interrupt() for more | ||
590 | * information. | ||
591 | */ | ||
592 | ba,pt %xcc, 99f | ||
593 | nop | ||
594 | .align 64 | ||
595 | 99: wr %g6, %g0, %pic | ||
596 | rd %pic, %g0 | ||
597 | #endif | ||
598 | |||
599 | wr %g0, ASI_P, %asi | 368 | wr %g0, ASI_P, %asi |
600 | mov 1, %g1 | 369 | mov 1, %g1 |
601 | sllx %g1, THREAD_SHIFT, %g1 | 370 | sllx %g1, THREAD_SHIFT, %g1 |
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c index ddbed3341a23..0296cb00fc99 100644 --- a/arch/sparc64/kernel/setup.c +++ b/arch/sparc64/kernel/setup.c | |||
@@ -536,20 +536,7 @@ void __init setup_arch(char **cmdline_p) | |||
536 | } | 536 | } |
537 | pfn_base = phys_base >> PAGE_SHIFT; | 537 | pfn_base = phys_base >> PAGE_SHIFT; |
538 | 538 | ||
539 | switch (tlb_type) { | 539 | kern_base = (prom_boot_mapping_phys_low >> 22UL) << 22UL; |
540 | default: | ||
541 | case spitfire: | ||
542 | kern_base = spitfire_get_itlb_data(sparc64_highest_locked_tlbent()); | ||
543 | kern_base &= _PAGE_PADDR_SF; | ||
544 | break; | ||
545 | |||
546 | case cheetah: | ||
547 | case cheetah_plus: | ||
548 | kern_base = cheetah_get_litlb_data(sparc64_highest_locked_tlbent()); | ||
549 | kern_base &= _PAGE_PADDR; | ||
550 | break; | ||
551 | }; | ||
552 | |||
553 | kern_size = (unsigned long)&_end - (unsigned long)KERNBASE; | 540 | kern_size = (unsigned long)&_end - (unsigned long)KERNBASE; |
554 | 541 | ||
555 | if (!root_flags) | 542 | if (!root_flags) |
diff --git a/arch/sparc64/kernel/trampoline.S b/arch/sparc64/kernel/trampoline.S index 3a145fc39cf2..89f2fcfcd662 100644 --- a/arch/sparc64/kernel/trampoline.S +++ b/arch/sparc64/kernel/trampoline.S | |||
@@ -119,8 +119,8 @@ startup_continue: | |||
119 | sethi %hi(itlb_load), %g2 | 119 | sethi %hi(itlb_load), %g2 |
120 | or %g2, %lo(itlb_load), %g2 | 120 | or %g2, %lo(itlb_load), %g2 |
121 | stx %g2, [%sp + 2047 + 128 + 0x18] | 121 | stx %g2, [%sp + 2047 + 128 + 0x18] |
122 | sethi %hi(mmu_ihandle_cache), %g2 | 122 | sethi %hi(prom_mmu_ihandle_cache), %g2 |
123 | lduw [%g2 + %lo(mmu_ihandle_cache)], %g2 | 123 | lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2 |
124 | stx %g2, [%sp + 2047 + 128 + 0x20] | 124 | stx %g2, [%sp + 2047 + 128 + 0x20] |
125 | sethi %hi(KERNBASE), %g2 | 125 | sethi %hi(KERNBASE), %g2 |
126 | stx %g2, [%sp + 2047 + 128 + 0x28] | 126 | stx %g2, [%sp + 2047 + 128 + 0x28] |
@@ -156,8 +156,8 @@ startup_continue: | |||
156 | sethi %hi(itlb_load), %g2 | 156 | sethi %hi(itlb_load), %g2 |
157 | or %g2, %lo(itlb_load), %g2 | 157 | or %g2, %lo(itlb_load), %g2 |
158 | stx %g2, [%sp + 2047 + 128 + 0x18] | 158 | stx %g2, [%sp + 2047 + 128 + 0x18] |
159 | sethi %hi(mmu_ihandle_cache), %g2 | 159 | sethi %hi(prom_mmu_ihandle_cache), %g2 |
160 | lduw [%g2 + %lo(mmu_ihandle_cache)], %g2 | 160 | lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2 |
161 | stx %g2, [%sp + 2047 + 128 + 0x20] | 161 | stx %g2, [%sp + 2047 + 128 + 0x20] |
162 | sethi %hi(KERNBASE + 0x400000), %g2 | 162 | sethi %hi(KERNBASE + 0x400000), %g2 |
163 | stx %g2, [%sp + 2047 + 128 + 0x28] | 163 | stx %g2, [%sp + 2047 + 128 + 0x28] |
@@ -190,8 +190,8 @@ do_dtlb: | |||
190 | sethi %hi(dtlb_load), %g2 | 190 | sethi %hi(dtlb_load), %g2 |
191 | or %g2, %lo(dtlb_load), %g2 | 191 | or %g2, %lo(dtlb_load), %g2 |
192 | stx %g2, [%sp + 2047 + 128 + 0x18] | 192 | stx %g2, [%sp + 2047 + 128 + 0x18] |
193 | sethi %hi(mmu_ihandle_cache), %g2 | 193 | sethi %hi(prom_mmu_ihandle_cache), %g2 |
194 | lduw [%g2 + %lo(mmu_ihandle_cache)], %g2 | 194 | lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2 |
195 | stx %g2, [%sp + 2047 + 128 + 0x20] | 195 | stx %g2, [%sp + 2047 + 128 + 0x20] |
196 | sethi %hi(KERNBASE), %g2 | 196 | sethi %hi(KERNBASE), %g2 |
197 | stx %g2, [%sp + 2047 + 128 + 0x28] | 197 | stx %g2, [%sp + 2047 + 128 + 0x28] |
@@ -228,8 +228,8 @@ do_dtlb: | |||
228 | sethi %hi(dtlb_load), %g2 | 228 | sethi %hi(dtlb_load), %g2 |
229 | or %g2, %lo(dtlb_load), %g2 | 229 | or %g2, %lo(dtlb_load), %g2 |
230 | stx %g2, [%sp + 2047 + 128 + 0x18] | 230 | stx %g2, [%sp + 2047 + 128 + 0x18] |
231 | sethi %hi(mmu_ihandle_cache), %g2 | 231 | sethi %hi(prom_mmu_ihandle_cache), %g2 |
232 | lduw [%g2 + %lo(mmu_ihandle_cache)], %g2 | 232 | lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2 |
233 | stx %g2, [%sp + 2047 + 128 + 0x20] | 233 | stx %g2, [%sp + 2047 + 128 + 0x20] |
234 | sethi %hi(KERNBASE + 0x400000), %g2 | 234 | sethi %hi(KERNBASE + 0x400000), %g2 |
235 | stx %g2, [%sp + 2047 + 128 + 0x28] | 235 | stx %g2, [%sp + 2047 + 128 + 0x28] |
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index ec47de494c1f..e0b9eebf21ce 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c | |||
@@ -505,108 +505,20 @@ static int read_obp_translations(void) | |||
505 | return n; | 505 | return n; |
506 | } | 506 | } |
507 | 507 | ||
508 | static inline void early_spitfire_errata32(void) | ||
509 | { | ||
510 | /* Spitfire Errata #32 workaround */ | ||
511 | /* NOTE: Using plain zero for the context value is | ||
512 | * correct here, we are not using the Linux trap | ||
513 | * tables yet so we should not use the special | ||
514 | * UltraSPARC-III+ page size encodings yet. | ||
515 | */ | ||
516 | __asm__ __volatile__("stxa %0, [%1] %2\n\t" | ||
517 | "flush %%g6" | ||
518 | : /* No outputs */ | ||
519 | : "r" (0), "r" (PRIMARY_CONTEXT), | ||
520 | "i" (ASI_DMMU)); | ||
521 | } | ||
522 | |||
523 | static void lock_remap_func_page(unsigned long phys_page) | ||
524 | { | ||
525 | unsigned long tte_data = (phys_page | pgprot_val(PAGE_KERNEL)); | ||
526 | |||
527 | if (tlb_type == spitfire) { | ||
528 | /* Lock this into i/d tlb entry 59 */ | ||
529 | __asm__ __volatile__( | ||
530 | "stxa %%g0, [%2] %3\n\t" | ||
531 | "stxa %0, [%1] %4\n\t" | ||
532 | "membar #Sync\n\t" | ||
533 | "flush %%g6\n\t" | ||
534 | "stxa %%g0, [%2] %5\n\t" | ||
535 | "stxa %0, [%1] %6\n\t" | ||
536 | "membar #Sync\n\t" | ||
537 | "flush %%g6" | ||
538 | : /* no outputs */ | ||
539 | : "r" (tte_data), "r" (59 << 3), "r" (TLB_TAG_ACCESS), | ||
540 | "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), | ||
541 | "i" (ASI_IMMU), "i" (ASI_ITLB_DATA_ACCESS) | ||
542 | : "memory"); | ||
543 | } else { | ||
544 | /* Lock this into i/d tlb-0 entry 11 */ | ||
545 | __asm__ __volatile__( | ||
546 | "stxa %%g0, [%2] %3\n\t" | ||
547 | "stxa %0, [%1] %4\n\t" | ||
548 | "membar #Sync\n\t" | ||
549 | "flush %%g6\n\t" | ||
550 | "stxa %%g0, [%2] %5\n\t" | ||
551 | "stxa %0, [%1] %6\n\t" | ||
552 | "membar #Sync\n\t" | ||
553 | "flush %%g6" | ||
554 | : /* no outputs */ | ||
555 | : "r" (tte_data), "r" ((0 << 16) | (11 << 3)), | ||
556 | "r" (TLB_TAG_ACCESS), "i" (ASI_DMMU), | ||
557 | "i" (ASI_DTLB_DATA_ACCESS), "i" (ASI_IMMU), | ||
558 | "i" (ASI_ITLB_DATA_ACCESS) | ||
559 | : "memory"); | ||
560 | } | ||
561 | } | ||
562 | |||
563 | static void remap_kernel(void) | 508 | static void remap_kernel(void) |
564 | { | 509 | { |
565 | unsigned long phys_page, tte_vaddr, tte_data; | 510 | unsigned long phys_page, tte_vaddr, tte_data; |
566 | void (*remap_func)(unsigned long, unsigned long, int); | ||
567 | int tlb_ent = sparc64_highest_locked_tlbent(); | 511 | int tlb_ent = sparc64_highest_locked_tlbent(); |
568 | 512 | ||
569 | early_spitfire_errata32(); | ||
570 | |||
571 | if (tlb_type == spitfire) | ||
572 | phys_page = spitfire_get_dtlb_data(tlb_ent); | ||
573 | else | ||
574 | phys_page = cheetah_get_ldtlb_data(tlb_ent); | ||
575 | |||
576 | phys_page &= _PAGE_PADDR; | ||
577 | phys_page += ((unsigned long)&prom_boot_page - | ||
578 | (unsigned long)KERNBASE); | ||
579 | |||
580 | lock_remap_func_page(phys_page); | ||
581 | |||
582 | tte_vaddr = (unsigned long) KERNBASE; | 513 | tte_vaddr = (unsigned long) KERNBASE; |
583 | 514 | phys_page = (prom_boot_mapping_phys_low >> 22UL) << 22UL; | |
584 | early_spitfire_errata32(); | 515 | tte_data = (phys_page | (_PAGE_VALID | _PAGE_SZ4MB | |
585 | 516 | _PAGE_CP | _PAGE_CV | _PAGE_P | | |
586 | if (tlb_type == spitfire) | 517 | _PAGE_L | _PAGE_W)); |
587 | tte_data = spitfire_get_dtlb_data(tlb_ent); | ||
588 | else | ||
589 | tte_data = cheetah_get_ldtlb_data(tlb_ent); | ||
590 | 518 | ||
591 | kern_locked_tte_data = tte_data; | 519 | kern_locked_tte_data = tte_data; |
592 | 520 | ||
593 | remap_func = (void *) ((unsigned long) &prom_remap - | 521 | /* Now lock us into the TLBs via OBP. */ |
594 | (unsigned long) &prom_boot_page); | ||
595 | |||
596 | early_spitfire_errata32(); | ||
597 | |||
598 | phys_page = tte_data & _PAGE_PADDR; | ||
599 | remap_func(phys_page, KERNBASE, prom_get_mmu_ihandle()); | ||
600 | if (bigkernel) | ||
601 | remap_func(phys_page + 0x400000, | ||
602 | KERNBASE + 0x400000, | ||
603 | prom_get_mmu_ihandle()); | ||
604 | |||
605 | /* Flush out that temporary mapping. */ | ||
606 | spitfire_flush_dtlb_nucleus_page(0x0); | ||
607 | spitfire_flush_itlb_nucleus_page(0x0); | ||
608 | |||
609 | /* Now lock us back into the TLBs via OBP. */ | ||
610 | prom_dtlb_load(tlb_ent, tte_data, tte_vaddr); | 522 | prom_dtlb_load(tlb_ent, tte_data, tte_vaddr); |
611 | prom_itlb_load(tlb_ent, tte_data, tte_vaddr); | 523 | prom_itlb_load(tlb_ent, tte_data, tte_vaddr); |
612 | if (bigkernel) { | 524 | if (bigkernel) { |
diff --git a/arch/sparc64/prom/Makefile b/arch/sparc64/prom/Makefile index 8f2420d9e9e6..c7898a5ee456 100644 --- a/arch/sparc64/prom/Makefile +++ b/arch/sparc64/prom/Makefile | |||
@@ -7,4 +7,4 @@ EXTRA_AFLAGS := -ansi | |||
7 | EXTRA_CFLAGS := -Werror | 7 | EXTRA_CFLAGS := -Werror |
8 | 8 | ||
9 | lib-y := bootstr.o devops.o init.o memory.o misc.o \ | 9 | lib-y := bootstr.o devops.o init.o memory.o misc.o \ |
10 | tree.o console.o printf.o p1275.o map.o cif.o | 10 | tree.o console.o printf.o p1275.o cif.o |
diff --git a/arch/sparc64/prom/console.c b/arch/sparc64/prom/console.c index 028a53fcb1ec..eae5db8dda56 100644 --- a/arch/sparc64/prom/console.c +++ b/arch/sparc64/prom/console.c | |||
@@ -67,7 +67,7 @@ prom_putchar(char c) | |||
67 | } | 67 | } |
68 | 68 | ||
69 | void | 69 | void |
70 | prom_puts(char *s, int len) | 70 | prom_puts(const char *s, int len) |
71 | { | 71 | { |
72 | p1275_cmd("write", P1275_ARG(1,P1275_ARG_IN_BUF)| | 72 | p1275_cmd("write", P1275_ARG(1,P1275_ARG_IN_BUF)| |
73 | P1275_INOUT(3,1), | 73 | P1275_INOUT(3,1), |
diff --git a/arch/sparc64/prom/devops.c b/arch/sparc64/prom/devops.c index 2c99b21b6981..4641839eb39a 100644 --- a/arch/sparc64/prom/devops.c +++ b/arch/sparc64/prom/devops.c | |||
@@ -16,7 +16,7 @@ | |||
16 | * Returns 0 on failure. | 16 | * Returns 0 on failure. |
17 | */ | 17 | */ |
18 | int | 18 | int |
19 | prom_devopen(char *dstr) | 19 | prom_devopen(const char *dstr) |
20 | { | 20 | { |
21 | return p1275_cmd ("open", P1275_ARG(0,P1275_ARG_IN_STRING)| | 21 | return p1275_cmd ("open", P1275_ARG(0,P1275_ARG_IN_STRING)| |
22 | P1275_INOUT(1,1), | 22 | P1275_INOUT(1,1), |
diff --git a/arch/sparc64/prom/init.c b/arch/sparc64/prom/init.c index 817faae058cd..8b4b622d0909 100644 --- a/arch/sparc64/prom/init.c +++ b/arch/sparc64/prom/init.c | |||
@@ -46,7 +46,7 @@ void __init prom_init(void *cif_handler, void *cif_stack) | |||
46 | if((prom_root_node == 0) || (prom_root_node == -1)) | 46 | if((prom_root_node == 0) || (prom_root_node == -1)) |
47 | prom_halt(); | 47 | prom_halt(); |
48 | 48 | ||
49 | prom_chosen_node = prom_finddevice("/chosen"); | 49 | prom_chosen_node = prom_finddevice(prom_chosen_path); |
50 | if (!prom_chosen_node || prom_chosen_node == -1) | 50 | if (!prom_chosen_node || prom_chosen_node == -1) |
51 | prom_halt(); | 51 | prom_halt(); |
52 | 52 | ||
diff --git a/arch/sparc64/prom/map.S b/arch/sparc64/prom/map.S deleted file mode 100644 index 21b3f9c99ea7..000000000000 --- a/arch/sparc64/prom/map.S +++ /dev/null | |||
@@ -1,72 +0,0 @@ | |||
1 | /* $Id: map.S,v 1.2 1999/11/19 05:53:02 davem Exp $ | ||
2 | * map.S: Tricky coding required to fixup the kernel OBP maps | ||
3 | * properly. | ||
4 | * | ||
5 | * Copyright (C) 1999 David S. Miller (davem@redhat.com) | ||
6 | */ | ||
7 | |||
8 | .text | ||
9 | .align 8192 | ||
10 | .globl prom_boot_page | ||
11 | prom_boot_page: | ||
12 | call_method: | ||
13 | .asciz "call-method" | ||
14 | .align 8 | ||
15 | map: | ||
16 | .asciz "map" | ||
17 | .align 8 | ||
18 | |||
19 | /* When we are invoked, our caller has remapped us to | ||
20 | * page zero, therefore we must use PC relative addressing | ||
21 | * for everything after we begin performing the unmap/map | ||
22 | * calls. | ||
23 | */ | ||
24 | .globl prom_remap | ||
25 | prom_remap: /* %o0 = physpage, %o1 = virtpage, %o2 = mmu_ihandle */ | ||
26 | rd %pc, %g1 | ||
27 | srl %o2, 0, %o2 ! kill sign extension | ||
28 | sethi %hi(p1275buf), %g2 | ||
29 | or %g2, %lo(p1275buf), %g2 | ||
30 | ldx [%g2 + 0x10], %g3 ! prom_cif_stack | ||
31 | save %g3, -(192 + 128), %sp | ||
32 | ldx [%g2 + 0x08], %l0 ! prom_cif_handler | ||
33 | mov %g6, %i3 | ||
34 | mov %g4, %i4 | ||
35 | mov %g5, %i5 | ||
36 | flushw | ||
37 | |||
38 | sethi %hi(prom_remap - call_method), %g7 | ||
39 | or %g7, %lo(prom_remap - call_method), %g7 | ||
40 | sub %g1, %g7, %l2 ! call-method string | ||
41 | sethi %hi(prom_remap - map), %g7 | ||
42 | or %g7, %lo(prom_remap - map), %g7 | ||
43 | sub %g1, %g7, %l4 ! map string | ||
44 | |||
45 | /* OK, map the 4MB region we really live at. */ | ||
46 | stx %l2, [%sp + 2047 + 128 + 0x00] ! call-method | ||
47 | mov 7, %l5 | ||
48 | stx %l5, [%sp + 2047 + 128 + 0x08] ! num_args | ||
49 | mov 1, %l5 | ||
50 | stx %l5, [%sp + 2047 + 128 + 0x10] ! num_rets | ||
51 | stx %l4, [%sp + 2047 + 128 + 0x18] ! map | ||
52 | stx %i2, [%sp + 2047 + 128 + 0x20] ! mmu_ihandle | ||
53 | mov -1, %l5 | ||
54 | stx %l5, [%sp + 2047 + 128 + 0x28] ! mode == default | ||
55 | sethi %hi(4 * 1024 * 1024), %l5 | ||
56 | stx %l5, [%sp + 2047 + 128 + 0x30] ! size | ||
57 | stx %i1, [%sp + 2047 + 128 + 0x38] ! vaddr | ||
58 | stx %g0, [%sp + 2047 + 128 + 0x40] ! filler | ||
59 | stx %i0, [%sp + 2047 + 128 + 0x48] ! paddr | ||
60 | call %l0 | ||
61 | add %sp, (2047 + 128), %o0 ! argument array | ||
62 | |||
63 | /* Restore hard-coded globals. */ | ||
64 | mov %i3, %g6 | ||
65 | mov %i4, %g4 | ||
66 | mov %i5, %g5 | ||
67 | |||
68 | /* Wheee.... we are done. */ | ||
69 | ret | ||
70 | restore | ||
71 | |||
72 | .align 8192 | ||
diff --git a/arch/sparc64/prom/misc.c b/arch/sparc64/prom/misc.c index 19c44e97e9ee..9b895faf077b 100644 --- a/arch/sparc64/prom/misc.c +++ b/arch/sparc64/prom/misc.c | |||
@@ -17,14 +17,14 @@ | |||
17 | #include <asm/system.h> | 17 | #include <asm/system.h> |
18 | 18 | ||
19 | /* Reset and reboot the machine with the command 'bcommand'. */ | 19 | /* Reset and reboot the machine with the command 'bcommand'. */ |
20 | void prom_reboot(char *bcommand) | 20 | void prom_reboot(const char *bcommand) |
21 | { | 21 | { |
22 | p1275_cmd("boot", P1275_ARG(0, P1275_ARG_IN_STRING) | | 22 | p1275_cmd("boot", P1275_ARG(0, P1275_ARG_IN_STRING) | |
23 | P1275_INOUT(1, 0), bcommand); | 23 | P1275_INOUT(1, 0), bcommand); |
24 | } | 24 | } |
25 | 25 | ||
26 | /* Forth evaluate the expression contained in 'fstring'. */ | 26 | /* Forth evaluate the expression contained in 'fstring'. */ |
27 | void prom_feval(char *fstring) | 27 | void prom_feval(const char *fstring) |
28 | { | 28 | { |
29 | if (!fstring || fstring[0] == 0) | 29 | if (!fstring || fstring[0] == 0) |
30 | return; | 30 | return; |
@@ -148,21 +148,19 @@ void prom_set_trap_table(unsigned long tba) | |||
148 | p1275_cmd("SUNW,set-trap-table", P1275_INOUT(1, 0), tba); | 148 | p1275_cmd("SUNW,set-trap-table", P1275_INOUT(1, 0), tba); |
149 | } | 149 | } |
150 | 150 | ||
151 | int mmu_ihandle_cache = 0; | ||
152 | |||
153 | int prom_get_mmu_ihandle(void) | 151 | int prom_get_mmu_ihandle(void) |
154 | { | 152 | { |
155 | int node, ret; | 153 | int node, ret; |
156 | 154 | ||
157 | if (mmu_ihandle_cache != 0) | 155 | if (prom_mmu_ihandle_cache != 0) |
158 | return mmu_ihandle_cache; | 156 | return prom_mmu_ihandle_cache; |
159 | 157 | ||
160 | node = prom_finddevice("/chosen"); | 158 | node = prom_finddevice(prom_chosen_path); |
161 | ret = prom_getint(node, "mmu"); | 159 | ret = prom_getint(node, prom_mmu_name); |
162 | if (ret == -1 || ret == 0) | 160 | if (ret == -1 || ret == 0) |
163 | mmu_ihandle_cache = -1; | 161 | prom_mmu_ihandle_cache = -1; |
164 | else | 162 | else |
165 | mmu_ihandle_cache = ret; | 163 | prom_mmu_ihandle_cache = ret; |
166 | 164 | ||
167 | return ret; | 165 | return ret; |
168 | } | 166 | } |
@@ -190,7 +188,7 @@ long prom_itlb_load(unsigned long index, | |||
190 | unsigned long tte_data, | 188 | unsigned long tte_data, |
191 | unsigned long vaddr) | 189 | unsigned long vaddr) |
192 | { | 190 | { |
193 | return p1275_cmd("call-method", | 191 | return p1275_cmd(prom_callmethod_name, |
194 | (P1275_ARG(0, P1275_ARG_IN_STRING) | | 192 | (P1275_ARG(0, P1275_ARG_IN_STRING) | |
195 | P1275_ARG(2, P1275_ARG_IN_64B) | | 193 | P1275_ARG(2, P1275_ARG_IN_64B) | |
196 | P1275_ARG(3, P1275_ARG_IN_64B) | | 194 | P1275_ARG(3, P1275_ARG_IN_64B) | |
@@ -207,7 +205,7 @@ long prom_dtlb_load(unsigned long index, | |||
207 | unsigned long tte_data, | 205 | unsigned long tte_data, |
208 | unsigned long vaddr) | 206 | unsigned long vaddr) |
209 | { | 207 | { |
210 | return p1275_cmd("call-method", | 208 | return p1275_cmd(prom_callmethod_name, |
211 | (P1275_ARG(0, P1275_ARG_IN_STRING) | | 209 | (P1275_ARG(0, P1275_ARG_IN_STRING) | |
212 | P1275_ARG(2, P1275_ARG_IN_64B) | | 210 | P1275_ARG(2, P1275_ARG_IN_64B) | |
213 | P1275_ARG(3, P1275_ARG_IN_64B) | | 211 | P1275_ARG(3, P1275_ARG_IN_64B) | |
@@ -223,13 +221,13 @@ long prom_dtlb_load(unsigned long index, | |||
223 | int prom_map(int mode, unsigned long size, | 221 | int prom_map(int mode, unsigned long size, |
224 | unsigned long vaddr, unsigned long paddr) | 222 | unsigned long vaddr, unsigned long paddr) |
225 | { | 223 | { |
226 | int ret = p1275_cmd("call-method", | 224 | int ret = p1275_cmd(prom_callmethod_name, |
227 | (P1275_ARG(0, P1275_ARG_IN_STRING) | | 225 | (P1275_ARG(0, P1275_ARG_IN_STRING) | |
228 | P1275_ARG(3, P1275_ARG_IN_64B) | | 226 | P1275_ARG(3, P1275_ARG_IN_64B) | |
229 | P1275_ARG(4, P1275_ARG_IN_64B) | | 227 | P1275_ARG(4, P1275_ARG_IN_64B) | |
230 | P1275_ARG(6, P1275_ARG_IN_64B) | | 228 | P1275_ARG(6, P1275_ARG_IN_64B) | |
231 | P1275_INOUT(7, 1)), | 229 | P1275_INOUT(7, 1)), |
232 | "map", | 230 | prom_map_name, |
233 | prom_get_mmu_ihandle(), | 231 | prom_get_mmu_ihandle(), |
234 | mode, | 232 | mode, |
235 | size, | 233 | size, |
@@ -244,12 +242,12 @@ int prom_map(int mode, unsigned long size, | |||
244 | 242 | ||
245 | void prom_unmap(unsigned long size, unsigned long vaddr) | 243 | void prom_unmap(unsigned long size, unsigned long vaddr) |
246 | { | 244 | { |
247 | p1275_cmd("call-method", | 245 | p1275_cmd(prom_callmethod_name, |
248 | (P1275_ARG(0, P1275_ARG_IN_STRING) | | 246 | (P1275_ARG(0, P1275_ARG_IN_STRING) | |
249 | P1275_ARG(2, P1275_ARG_IN_64B) | | 247 | P1275_ARG(2, P1275_ARG_IN_64B) | |
250 | P1275_ARG(3, P1275_ARG_IN_64B) | | 248 | P1275_ARG(3, P1275_ARG_IN_64B) | |
251 | P1275_INOUT(4, 0)), | 249 | P1275_INOUT(4, 0)), |
252 | "unmap", | 250 | prom_unmap_name, |
253 | prom_get_mmu_ihandle(), | 251 | prom_get_mmu_ihandle(), |
254 | size, | 252 | size, |
255 | vaddr); | 253 | vaddr); |
@@ -258,7 +256,7 @@ void prom_unmap(unsigned long size, unsigned long vaddr) | |||
258 | /* Set aside physical memory which is not touched or modified | 256 | /* Set aside physical memory which is not touched or modified |
259 | * across soft resets. | 257 | * across soft resets. |
260 | */ | 258 | */ |
261 | unsigned long prom_retain(char *name, | 259 | unsigned long prom_retain(const char *name, |
262 | unsigned long pa_low, unsigned long pa_high, | 260 | unsigned long pa_low, unsigned long pa_high, |
263 | long size, long align) | 261 | long size, long align) |
264 | { | 262 | { |
@@ -290,7 +288,7 @@ int prom_getunumber(int syndrome_code, | |||
290 | unsigned long phys_addr, | 288 | unsigned long phys_addr, |
291 | char *buf, int buflen) | 289 | char *buf, int buflen) |
292 | { | 290 | { |
293 | return p1275_cmd("call-method", | 291 | return p1275_cmd(prom_callmethod_name, |
294 | (P1275_ARG(0, P1275_ARG_IN_STRING) | | 292 | (P1275_ARG(0, P1275_ARG_IN_STRING) | |
295 | P1275_ARG(3, P1275_ARG_OUT_BUF) | | 293 | P1275_ARG(3, P1275_ARG_OUT_BUF) | |
296 | P1275_ARG(6, P1275_ARG_IN_64B) | | 294 | P1275_ARG(6, P1275_ARG_IN_64B) | |
diff --git a/arch/sparc64/prom/p1275.c b/arch/sparc64/prom/p1275.c index 59fe38bba39e..a5a7c5712028 100644 --- a/arch/sparc64/prom/p1275.c +++ b/arch/sparc64/prom/p1275.c | |||
@@ -46,7 +46,7 @@ static inline unsigned long spitfire_get_primary_context(void) | |||
46 | */ | 46 | */ |
47 | DEFINE_SPINLOCK(prom_entry_lock); | 47 | DEFINE_SPINLOCK(prom_entry_lock); |
48 | 48 | ||
49 | long p1275_cmd (char *service, long fmt, ...) | 49 | long p1275_cmd(const char *service, long fmt, ...) |
50 | { | 50 | { |
51 | char *p, *q; | 51 | char *p, *q; |
52 | unsigned long flags; | 52 | unsigned long flags; |
diff --git a/arch/sparc64/prom/printf.c b/arch/sparc64/prom/printf.c index a6df82cafa0d..660943ee4c2a 100644 --- a/arch/sparc64/prom/printf.c +++ b/arch/sparc64/prom/printf.c | |||
@@ -34,7 +34,7 @@ prom_write(const char *buf, unsigned int n) | |||
34 | } | 34 | } |
35 | 35 | ||
36 | void | 36 | void |
37 | prom_printf(char *fmt, ...) | 37 | prom_printf(const char *fmt, ...) |
38 | { | 38 | { |
39 | va_list args; | 39 | va_list args; |
40 | int i; | 40 | int i; |
diff --git a/arch/sparc64/prom/tree.c b/arch/sparc64/prom/tree.c index ccf73258ebf7..b1ff9e87dcc6 100644 --- a/arch/sparc64/prom/tree.c +++ b/arch/sparc64/prom/tree.c | |||
@@ -69,7 +69,7 @@ prom_getsibling(int node) | |||
69 | * Return -1 on error. | 69 | * Return -1 on error. |
70 | */ | 70 | */ |
71 | __inline__ int | 71 | __inline__ int |
72 | prom_getproplen(int node, char *prop) | 72 | prom_getproplen(int node, const char *prop) |
73 | { | 73 | { |
74 | if((!node) || (!prop)) return -1; | 74 | if((!node) || (!prop)) return -1; |
75 | return p1275_cmd ("getproplen", | 75 | return p1275_cmd ("getproplen", |
@@ -83,20 +83,20 @@ prom_getproplen(int node, char *prop) | |||
83 | * was successful the length will be returned, else -1 is returned. | 83 | * was successful the length will be returned, else -1 is returned. |
84 | */ | 84 | */ |
85 | __inline__ int | 85 | __inline__ int |
86 | prom_getproperty(int node, char *prop, char *buffer, int bufsize) | 86 | prom_getproperty(int node, const char *prop, char *buffer, int bufsize) |
87 | { | 87 | { |
88 | int plen; | 88 | int plen; |
89 | 89 | ||
90 | plen = prom_getproplen(node, prop); | 90 | plen = prom_getproplen(node, prop); |
91 | if((plen > bufsize) || (plen == 0) || (plen == -1)) | 91 | if ((plen > bufsize) || (plen == 0) || (plen == -1)) { |
92 | return -1; | 92 | return -1; |
93 | else { | 93 | } else { |
94 | /* Ok, things seem all right. */ | 94 | /* Ok, things seem all right. */ |
95 | return p1275_cmd ("getprop", | 95 | return p1275_cmd(prom_getprop_name, |
96 | P1275_ARG(1,P1275_ARG_IN_STRING)| | 96 | P1275_ARG(1,P1275_ARG_IN_STRING)| |
97 | P1275_ARG(2,P1275_ARG_OUT_BUF)| | 97 | P1275_ARG(2,P1275_ARG_OUT_BUF)| |
98 | P1275_INOUT(4, 1), | 98 | P1275_INOUT(4, 1), |
99 | node, prop, buffer, P1275_SIZE(plen)); | 99 | node, prop, buffer, P1275_SIZE(plen)); |
100 | } | 100 | } |
101 | } | 101 | } |
102 | 102 | ||
@@ -104,7 +104,7 @@ prom_getproperty(int node, char *prop, char *buffer, int bufsize) | |||
104 | * on failure. | 104 | * on failure. |
105 | */ | 105 | */ |
106 | __inline__ int | 106 | __inline__ int |
107 | prom_getint(int node, char *prop) | 107 | prom_getint(int node, const char *prop) |
108 | { | 108 | { |
109 | int intprop; | 109 | int intprop; |
110 | 110 | ||
@@ -119,7 +119,7 @@ prom_getint(int node, char *prop) | |||
119 | */ | 119 | */ |
120 | 120 | ||
121 | int | 121 | int |
122 | prom_getintdefault(int node, char *property, int deflt) | 122 | prom_getintdefault(int node, const char *property, int deflt) |
123 | { | 123 | { |
124 | int retval; | 124 | int retval; |
125 | 125 | ||
@@ -131,7 +131,7 @@ prom_getintdefault(int node, char *property, int deflt) | |||
131 | 131 | ||
132 | /* Acquire a boolean property, 1=TRUE 0=FALSE. */ | 132 | /* Acquire a boolean property, 1=TRUE 0=FALSE. */ |
133 | int | 133 | int |
134 | prom_getbool(int node, char *prop) | 134 | prom_getbool(int node, const char *prop) |
135 | { | 135 | { |
136 | int retval; | 136 | int retval; |
137 | 137 | ||
@@ -145,7 +145,7 @@ prom_getbool(int node, char *prop) | |||
145 | * buffer. | 145 | * buffer. |
146 | */ | 146 | */ |
147 | void | 147 | void |
148 | prom_getstring(int node, char *prop, char *user_buf, int ubuf_size) | 148 | prom_getstring(int node, const char *prop, char *user_buf, int ubuf_size) |
149 | { | 149 | { |
150 | int len; | 150 | int len; |
151 | 151 | ||
@@ -160,7 +160,7 @@ prom_getstring(int node, char *prop, char *user_buf, int ubuf_size) | |||
160 | * YES = 1 NO = 0 | 160 | * YES = 1 NO = 0 |
161 | */ | 161 | */ |
162 | int | 162 | int |
163 | prom_nodematch(int node, char *name) | 163 | prom_nodematch(int node, const char *name) |
164 | { | 164 | { |
165 | char namebuf[128]; | 165 | char namebuf[128]; |
166 | prom_getproperty(node, "name", namebuf, sizeof(namebuf)); | 166 | prom_getproperty(node, "name", namebuf, sizeof(namebuf)); |
@@ -172,7 +172,7 @@ prom_nodematch(int node, char *name) | |||
172 | * 'nodename'. Return node if successful, zero if not. | 172 | * 'nodename'. Return node if successful, zero if not. |
173 | */ | 173 | */ |
174 | int | 174 | int |
175 | prom_searchsiblings(int node_start, char *nodename) | 175 | prom_searchsiblings(int node_start, const char *nodename) |
176 | { | 176 | { |
177 | 177 | ||
178 | int thisnode, error; | 178 | int thisnode, error; |
@@ -294,7 +294,7 @@ prom_firstprop(int node, char *buffer) | |||
294 | * property types for this node. | 294 | * property types for this node. |
295 | */ | 295 | */ |
296 | __inline__ char * | 296 | __inline__ char * |
297 | prom_nextprop(int node, char *oprop, char *buffer) | 297 | prom_nextprop(int node, const char *oprop, char *buffer) |
298 | { | 298 | { |
299 | char buf[32]; | 299 | char buf[32]; |
300 | 300 | ||
@@ -314,15 +314,17 @@ prom_nextprop(int node, char *oprop, char *buffer) | |||
314 | } | 314 | } |
315 | 315 | ||
316 | int | 316 | int |
317 | prom_finddevice(char *name) | 317 | prom_finddevice(const char *name) |
318 | { | 318 | { |
319 | if(!name) return 0; | 319 | if (!name) |
320 | return p1275_cmd ("finddevice", P1275_ARG(0,P1275_ARG_IN_STRING)| | 320 | return 0; |
321 | P1275_INOUT(1, 1), | 321 | return p1275_cmd(prom_finddev_name, |
322 | name); | 322 | P1275_ARG(0,P1275_ARG_IN_STRING)| |
323 | P1275_INOUT(1, 1), | ||
324 | name); | ||
323 | } | 325 | } |
324 | 326 | ||
325 | int prom_node_has_property(int node, char *prop) | 327 | int prom_node_has_property(int node, const char *prop) |
326 | { | 328 | { |
327 | char buf [32]; | 329 | char buf [32]; |
328 | 330 | ||
@@ -339,7 +341,7 @@ int prom_node_has_property(int node, char *prop) | |||
339 | * of 'size' bytes. Return the number of bytes the prom accepted. | 341 | * of 'size' bytes. Return the number of bytes the prom accepted. |
340 | */ | 342 | */ |
341 | int | 343 | int |
342 | prom_setprop(int node, char *pname, char *value, int size) | 344 | prom_setprop(int node, const char *pname, char *value, int size) |
343 | { | 345 | { |
344 | if(size == 0) return 0; | 346 | if(size == 0) return 0; |
345 | if((pname == 0) || (value == 0)) return 0; | 347 | if((pname == 0) || (value == 0)) return 0; |
@@ -364,7 +366,7 @@ prom_inst2pkg(int inst) | |||
364 | * FIXME: Should work for v0 as well | 366 | * FIXME: Should work for v0 as well |
365 | */ | 367 | */ |
366 | int | 368 | int |
367 | prom_pathtoinode(char *path) | 369 | prom_pathtoinode(const char *path) |
368 | { | 370 | { |
369 | int node, inst; | 371 | int node, inst; |
370 | 372 | ||