1 | /* |
---|
2 | * bat.c |
---|
3 | * |
---|
4 | * This file contains the implementation of C function to |
---|
5 | * Instantiate 60x/7xx ppc Block Address Translation (BAT) registers. |
---|
6 | * More detailed information can be found on motorola |
---|
7 | * site and more precisely in the following book : |
---|
8 | * |
---|
9 | * MPC750 |
---|
10 | * Risc Microporcessor User's Manual |
---|
11 | * Mtorola REF : MPC750UM/AD 8/97 |
---|
12 | * |
---|
13 | * Copyright (C) 1999 Eric Valette (valette@crf.canon.fr) |
---|
14 | * Canon Centre Recherche France. |
---|
15 | * |
---|
16 | * The license and distribution terms for this file may be |
---|
17 | * found in the file LICENSE in this distribution or at |
---|
18 | * http://www.rtems.org/license/LICENSE. |
---|
19 | */ |
---|
20 | #include <rtems.h> |
---|
21 | #include <libcpu/bat.h> |
---|
22 | #include <libcpu/spr.h> |
---|
23 | #include <rtems/bspIo.h> |
---|
24 | |
---|
25 | #include <libcpu/cpuIdent.h> |
---|
26 | |
---|
27 | #define TYP_I 1 |
---|
28 | #define TYP_D 0 |
---|
29 | |
---|
30 | typedef union |
---|
31 | { /* BAT register values to be loaded */ |
---|
32 | BAT bat; |
---|
33 | struct |
---|
34 | { |
---|
35 | unsigned int u, l; |
---|
36 | } words; |
---|
37 | } ubat; |
---|
38 | |
---|
39 | typedef struct batrange |
---|
40 | { /* stores address ranges mapped by BATs */ |
---|
41 | unsigned long start; |
---|
42 | unsigned long limit; |
---|
43 | unsigned long phys; |
---|
44 | } batrange; |
---|
45 | |
---|
46 | batrange bat_addrs[2][8] = { { {0,} } }; |
---|
47 | |
---|
48 | /* could encode this in bat_addrs but I don't touch that one for bwds compat. reasons */ |
---|
49 | /* bitmask of used bats */ |
---|
50 | static unsigned bat_in_use[2] = { 0, 0 }; |
---|
51 | |
---|
52 | /* define a few macros */ |
---|
53 | |
---|
54 | #define CLRBAT_ASM(batu,r) \ |
---|
55 | " sync \n" \ |
---|
56 | " isync \n" \ |
---|
57 | " li "#r ", 0 \n" \ |
---|
58 | " mtspr "#batu ", "#r "\n" \ |
---|
59 | " sync \n" \ |
---|
60 | " isync \n" |
---|
61 | |
---|
62 | #define SETBAT_ASM(batu, batl, u, l)\ |
---|
63 | " mtspr "#batl ", "#l " \n" \ |
---|
64 | " sync \n" \ |
---|
65 | " isync \n" \ |
---|
66 | " mtspr "#batu ", "#u " \n" \ |
---|
67 | " sync \n" \ |
---|
68 | " isync \n" |
---|
69 | |
---|
70 | #define CLRBAT(bat) \ |
---|
71 | asm volatile( \ |
---|
72 | CLRBAT_ASM(%0, 0) \ |
---|
73 | : \ |
---|
74 | :"i"(bat##U) \ |
---|
75 | :"0") |
---|
76 | |
---|
77 | #define GETBAT(bat,u,l) \ |
---|
78 | asm volatile( \ |
---|
79 | " mfspr %0, %2 \n" \ |
---|
80 | " mfspr %1, %3 \n" \ |
---|
81 | :"=r"(u),"=r"(l) \ |
---|
82 | :"i"(bat##U),"i"(bat##L) \ |
---|
83 | ) |
---|
84 | |
---|
85 | #define DECL_SETBAT(lcbat,bat) \ |
---|
86 | void \ |
---|
87 | asm_set##lcbat(unsigned int upper, unsigned int lower) \ |
---|
88 | { \ |
---|
89 | asm volatile( \ |
---|
90 | CLRBAT_ASM(%0,0) \ |
---|
91 | SETBAT_ASM(%0,%1,%2,%3) \ |
---|
92 | : \ |
---|
93 | :"i"(bat##U), \ |
---|
94 | "i"(bat##L), \ |
---|
95 | "r"(upper),"r"(lower) \ |
---|
96 | :"0"); \ |
---|
97 | } |
---|
98 | |
---|
99 | /* export the 'asm' versions for historic reasons */ |
---|
100 | DECL_SETBAT (dbat0, DBAT0) |
---|
101 | DECL_SETBAT (dbat1, DBAT1) |
---|
102 | DECL_SETBAT (dbat2, DBAT2) |
---|
103 | DECL_SETBAT (dbat3, DBAT3) |
---|
104 | |
---|
105 | static DECL_SETBAT (dbat4, DBAT4) |
---|
106 | static DECL_SETBAT (dbat5, DBAT5) |
---|
107 | static DECL_SETBAT (dbat6, DBAT6) |
---|
108 | static DECL_SETBAT (dbat7, DBAT7) |
---|
109 | |
---|
110 | static DECL_SETBAT (ibat0, IBAT0) |
---|
111 | static DECL_SETBAT (ibat1, IBAT1) |
---|
112 | static DECL_SETBAT (ibat2, IBAT2) |
---|
113 | static DECL_SETBAT (ibat3, IBAT3) |
---|
114 | static DECL_SETBAT (ibat4, IBAT4) |
---|
115 | static DECL_SETBAT (ibat5, IBAT5) |
---|
116 | static DECL_SETBAT (ibat6, IBAT6) |
---|
117 | static DECL_SETBAT (ibat7, IBAT7) |
---|
118 | |
---|
119 | |
---|
120 | SPR_RO (HID0); |
---|
121 | |
---|
122 | static void |
---|
123 | set_hid0_sync (unsigned long val) |
---|
124 | { |
---|
125 | __asm__ volatile ( |
---|
126 | " sync \n" |
---|
127 | " isync \n" |
---|
128 | " mtspr %0, %1 \n" |
---|
129 | " sync \n" |
---|
130 | " isync \n" |
---|
131 | : |
---|
132 | :"i" (HID0), "r" (val) |
---|
133 | :"memory" /* paranoia */ |
---|
134 | ); |
---|
135 | } |
---|
136 | |
---|
137 | static void |
---|
138 | bat_addrs_put (ubat * bat, int typ, int idx) |
---|
139 | { |
---|
140 | unsigned long bl; |
---|
141 | if (bat->bat.batu.vp || bat->bat.batu.vs) { |
---|
142 | bat_addrs[typ][idx].start = bat->bat.batu.bepi << 17; |
---|
143 | bat_addrs[typ][idx].phys = bat->bat.batl.brpn << 17; |
---|
144 | |
---|
145 | /* extended BL cannot be extracted using BAT union |
---|
146 | * - let's just hope the upper bits read 0 on pre 745x |
---|
147 | * CPUs. |
---|
148 | */ |
---|
149 | bl = (bat->words.u << 15) | ((1 << 17) - 1); |
---|
150 | bat_addrs[typ][idx].limit = bat_addrs[typ][idx].start + bl; |
---|
151 | |
---|
152 | bat_in_use[typ] |= (1 << idx); |
---|
153 | } |
---|
154 | } |
---|
155 | |
---|
156 | /* We don't know how the board was initialized. Therefore, |
---|
157 | * when 'setdbat' is first used we must initialize our |
---|
158 | * cache. |
---|
159 | */ |
---|
160 | static void |
---|
161 | bat_addrs_init (void) |
---|
162 | { |
---|
163 | ubat bat; |
---|
164 | |
---|
165 | GETBAT (DBAT0, bat.words.u, bat.words.l); |
---|
166 | bat_addrs_put (&bat, TYP_D, 0); |
---|
167 | GETBAT (DBAT1, bat.words.u, bat.words.l); |
---|
168 | bat_addrs_put (&bat, TYP_D, 1); |
---|
169 | GETBAT (DBAT2, bat.words.u, bat.words.l); |
---|
170 | bat_addrs_put (&bat, TYP_D, 2); |
---|
171 | GETBAT (DBAT3, bat.words.u, bat.words.l); |
---|
172 | bat_addrs_put (&bat, TYP_D, 3); |
---|
173 | |
---|
174 | GETBAT (IBAT0, bat.words.u, bat.words.l); |
---|
175 | bat_addrs_put (&bat, TYP_I, 0); |
---|
176 | GETBAT (IBAT1, bat.words.u, bat.words.l); |
---|
177 | bat_addrs_put (&bat, TYP_I, 1); |
---|
178 | GETBAT (IBAT2, bat.words.u, bat.words.l); |
---|
179 | bat_addrs_put (&bat, TYP_I, 2); |
---|
180 | GETBAT (IBAT3, bat.words.u, bat.words.l); |
---|
181 | bat_addrs_put (&bat, TYP_I, 3); |
---|
182 | |
---|
183 | |
---|
184 | if ( ppc_cpu_has_8_bats() && (HID0_7455_HIGH_BAT_EN & _read_HID0 ())) { |
---|
185 | GETBAT (DBAT4, bat.words.u, bat.words.l); |
---|
186 | bat_addrs_put (&bat, TYP_D, 4); |
---|
187 | GETBAT (DBAT5, bat.words.u, bat.words.l); |
---|
188 | bat_addrs_put (&bat, TYP_D, 5); |
---|
189 | GETBAT (DBAT6, bat.words.u, bat.words.l); |
---|
190 | bat_addrs_put (&bat, TYP_D, 6); |
---|
191 | GETBAT (DBAT7, bat.words.u, bat.words.l); |
---|
192 | bat_addrs_put (&bat, TYP_D, 7); |
---|
193 | GETBAT (IBAT4, bat.words.u, bat.words.l); |
---|
194 | bat_addrs_put (&bat, TYP_I, 4); |
---|
195 | GETBAT (IBAT5, bat.words.u, bat.words.l); |
---|
196 | bat_addrs_put (&bat, TYP_I, 5); |
---|
197 | GETBAT (IBAT6, bat.words.u, bat.words.l); |
---|
198 | bat_addrs_put (&bat, TYP_I, 6); |
---|
199 | GETBAT (IBAT7, bat.words.u, bat.words.l); |
---|
200 | bat_addrs_put (&bat, TYP_I, 7); |
---|
201 | } |
---|
202 | } |
---|
203 | |
---|
204 | static void |
---|
205 | do_dssall (void) |
---|
206 | { |
---|
207 | /* Before changing BATs, 'dssall' must be issued. |
---|
208 | * We check MSR for MSR_VE and issue a 'dssall' if |
---|
209 | * MSR_VE is set hoping that |
---|
210 | * a) on non-altivec CPUs MSR_VE reads as zero |
---|
211 | * b) all altivec CPUs use the same bit |
---|
212 | * NOTE: psim doesn't implement dssall so we skip if we run on psim |
---|
213 | */ |
---|
214 | if ( (_read_MSR () & MSR_VE) && PPC_PSIM != get_ppc_cpu_type() ) { |
---|
215 | /* this construct is needed because we don't know |
---|
216 | * if this file is compiled with -maltivec. |
---|
217 | * (I plan to add altivec support outside of |
---|
218 | * RTEMS core and hence I'd rather not |
---|
219 | * rely on consistent compiler flags). |
---|
220 | */ |
---|
221 | #define DSSALL 0x7e00066c /* dssall opcode */ |
---|
222 | __asm__ volatile (" .long %0"::"i" (DSSALL)); |
---|
223 | #undef DSSALL |
---|
224 | } |
---|
225 | } |
---|
226 | |
---|
227 | /* Clear I/D bats 4..7 ONLY ON 7455 etc. */ |
---|
228 | static void |
---|
229 | clear_hi_bats (void) |
---|
230 | { |
---|
231 | do_dssall (); |
---|
232 | CLRBAT (DBAT4); |
---|
233 | CLRBAT (DBAT5); |
---|
234 | CLRBAT (DBAT6); |
---|
235 | CLRBAT (DBAT7); |
---|
236 | CLRBAT (IBAT4); |
---|
237 | CLRBAT (IBAT5); |
---|
238 | CLRBAT (IBAT6); |
---|
239 | CLRBAT (IBAT7); |
---|
240 | } |
---|
241 | |
---|
242 | static int |
---|
243 | check_bat_index (int i) |
---|
244 | { |
---|
245 | unsigned long hid0; |
---|
246 | |
---|
247 | if (i >= 0 && i < 4) |
---|
248 | return 0; |
---|
249 | if (i >= 4 && i < 8) { |
---|
250 | if ( ! ppc_cpu_has_8_bats() ) |
---|
251 | return -1; |
---|
252 | /* OK, we're on the right hardware; |
---|
253 | * check if we are already enabled |
---|
254 | */ |
---|
255 | hid0 = _read_HID0 (); |
---|
256 | if (HID0_7455_HIGH_BAT_EN & hid0) |
---|
257 | return 0; |
---|
258 | /* No; enable now */ |
---|
259 | clear_hi_bats (); |
---|
260 | set_hid0_sync (hid0 | HID0_7455_HIGH_BAT_EN); |
---|
261 | return 0; |
---|
262 | } |
---|
263 | return -1; |
---|
264 | } |
---|
265 | |
---|
266 | /* size argument check: |
---|
267 | * - must be a power of two or zero |
---|
268 | * - must be <= 1<<28 ( non 745x cpu ) |
---|
269 | * - can be 1<<29..1<31 or 0xffffffff on 745x |
---|
270 | * - size < 1<<17 means 0 |
---|
271 | * computes and returns the block mask |
---|
272 | * RETURNS: |
---|
273 | * block mask on success or -1 on error |
---|
274 | */ |
---|
275 | static int |
---|
276 | check_bat_size (unsigned long size) |
---|
277 | { |
---|
278 | unsigned long bit; |
---|
279 | unsigned long hid0; |
---|
280 | |
---|
281 | /* First of all, it must be a power of two */ |
---|
282 | if (0 == size) |
---|
283 | return 0; |
---|
284 | |
---|
285 | if (0xffffffff == size) { |
---|
286 | bit = 32; |
---|
287 | } else { |
---|
288 | __asm__ volatile (" cntlzw %0, %1":"=r" (bit):"r" (size)); |
---|
289 | bit = 31 - bit; |
---|
290 | if (1 << bit != size) |
---|
291 | return -1; |
---|
292 | } |
---|
293 | /* bit < 17 is not really legal but we aliased it to 0 in the past */ |
---|
294 | if (bit > (11 + 17)) { |
---|
295 | if ( ! ppc_cpu_has_8_bats() ) |
---|
296 | return -1; |
---|
297 | |
---|
298 | hid0 = _read_HID0 (); |
---|
299 | /* Let's enable the larger block size if necessary */ |
---|
300 | if (!(HID0_7455_XBSEN & hid0)) |
---|
301 | set_hid0_sync (hid0 | HID0_7455_XBSEN); |
---|
302 | } |
---|
303 | |
---|
304 | return (1 << (bit - 17)) - 1; |
---|
305 | } |
---|
306 | |
---|
307 | static int |
---|
308 | check_overlap (int typ, unsigned long start, unsigned long size) |
---|
309 | { |
---|
310 | int i; |
---|
311 | unsigned long limit = start + size - 1; |
---|
312 | for (i = 0; i < sizeof (bat_addrs[typ]) / sizeof (bat_addrs[typ][0]); i++) { |
---|
313 | if (!((1 << i) & bat_in_use[typ])) |
---|
314 | continue; /* unused bat */ |
---|
315 | /* safe is 'limit < bat_addrs[t][i].start || start > bat_addrs[t][i].limit */ |
---|
316 | if (limit >= bat_addrs[typ][i].start && start <= bat_addrs[typ][i].limit) |
---|
317 | return i; |
---|
318 | } |
---|
319 | return -1; |
---|
320 | } |
---|
321 | |
---|
322 | |
---|
323 | /* Take no risks -- the essential parts of this routine run with |
---|
324 | * interrupts disabled! |
---|
325 | */ |
---|
326 | |
---|
327 | static int |
---|
328 | setbat (int typ, int bat_index, unsigned long virt, unsigned long phys, |
---|
329 | unsigned int size, int flags) |
---|
330 | { |
---|
331 | unsigned long level; |
---|
332 | unsigned int bl; |
---|
333 | int err; |
---|
334 | int wimgxpp; |
---|
335 | ubat bat; |
---|
336 | |
---|
337 | if (check_bat_index (bat_index)) { |
---|
338 | printk ("Invalid BAT index\n", bat_index); |
---|
339 | return -1; |
---|
340 | } |
---|
341 | |
---|
342 | if ((int) (bl = check_bat_size (size)) < 0) { |
---|
343 | printk ("Invalid BAT size\n", size); |
---|
344 | return -1; |
---|
345 | } |
---|
346 | |
---|
347 | if (virt & (size - 1)) { |
---|
348 | printk ("BAT effective address 0x%08x misaligned (size is 0x%08x)\n", |
---|
349 | virt, size); |
---|
350 | return -1; |
---|
351 | } |
---|
352 | |
---|
353 | if (phys & (size - 1)) { |
---|
354 | printk ("BAT physical address 0x%08x misaligned (size is 0x%08x)\n", phys, |
---|
355 | size); |
---|
356 | return -1; |
---|
357 | } |
---|
358 | |
---|
359 | if (virt + size - 1 < virt) { |
---|
360 | printk ("BAT range invalid: wraps around zero 0x%08x..0x%08x\n", virt, |
---|
361 | virt + size - 1); |
---|
362 | return -1; |
---|
363 | } |
---|
364 | |
---|
365 | if ( TYP_I == typ && ( ( _PAGE_GUARDED | _PAGE_WRITETHRU ) & flags ) ) { |
---|
366 | printk("IBAT must not have 'guarded' or 'writethrough' attribute\n"); |
---|
367 | return -1; |
---|
368 | } |
---|
369 | |
---|
370 | /* must protect the bat_addrs table -- since this routine is only used for board setup |
---|
371 | * or similar special purposes we don't bother about interrupt latency too much. |
---|
372 | */ |
---|
373 | rtems_interrupt_disable (level); |
---|
374 | |
---|
375 | { /* might have to initialize our cached data */ |
---|
376 | static char init_done = 0; |
---|
377 | if (!init_done) { |
---|
378 | bat_addrs_init (); |
---|
379 | init_done = 1; |
---|
380 | } |
---|
381 | } |
---|
382 | |
---|
383 | err = check_overlap (typ, virt, size); |
---|
384 | if ((size >= (1 << 17)) && (err >= 0) && (err != bat_index)) { |
---|
385 | rtems_interrupt_enable (level); |
---|
386 | printk ("BATs must not overlap; area 0x%08x..0x%08x hits %cBAT %i\n", |
---|
387 | virt, virt + size, (TYP_I == typ ? 'I' : 'D'), err); |
---|
388 | return -1; |
---|
389 | } |
---|
390 | |
---|
391 | /* 603, 604, etc. */ |
---|
392 | wimgxpp = flags & (_PAGE_WRITETHRU | _PAGE_NO_CACHE |
---|
393 | | _PAGE_COHERENT | _PAGE_GUARDED); |
---|
394 | wimgxpp |= (flags & _PAGE_RW) ? BPP_RW : BPP_RX; |
---|
395 | bat.words.u = virt | (bl << 2) | 2; /* Vs=1, Vp=0 */ |
---|
396 | bat.words.l = phys | wimgxpp; |
---|
397 | if (flags & _PAGE_USER) |
---|
398 | bat.bat.batu.vp = 1; |
---|
399 | bat_addrs[typ][bat_index].start = virt; |
---|
400 | bat_addrs[typ][bat_index].limit = virt + ((bl + 1) << 17) - 1; |
---|
401 | bat_addrs[typ][bat_index].phys = phys; |
---|
402 | bat_in_use[typ] |= 1 << bat_index; |
---|
403 | if (size < (1 << 17)) { |
---|
404 | /* size of 0 tells us to switch it off */ |
---|
405 | bat.bat.batu.vp = 0; |
---|
406 | bat.bat.batu.vs = 0; |
---|
407 | bat_in_use[typ] &= ~(1 << bat_index); |
---|
408 | /* mimic old behavior when bl was 0 (bs==0 is actually legal; it doesnt |
---|
409 | * indicate a size of zero. We now accept bl==0 and look at the size. |
---|
410 | */ |
---|
411 | bat_addrs[typ][bat_index].limit = virt; |
---|
412 | } |
---|
413 | do_dssall (); |
---|
414 | if ( TYP_I == typ ) { |
---|
415 | switch (bat_index) { |
---|
416 | case 0: asm_setibat0 (bat.words.u, bat.words.l); break; |
---|
417 | case 1: asm_setibat1 (bat.words.u, bat.words.l); break; |
---|
418 | case 2: asm_setibat2 (bat.words.u, bat.words.l); break; |
---|
419 | case 3: asm_setibat3 (bat.words.u, bat.words.l); break; |
---|
420 | /* cpu check already done in check_index */ |
---|
421 | case 4: asm_setibat4 (bat.words.u, bat.words.l); break; |
---|
422 | case 5: asm_setibat5 (bat.words.u, bat.words.l); break; |
---|
423 | case 6: asm_setibat6 (bat.words.u, bat.words.l); break; |
---|
424 | case 7: asm_setibat7 (bat.words.u, bat.words.l); break; |
---|
425 | default: /* should never get here anyways */ |
---|
426 | break; |
---|
427 | } |
---|
428 | } else { |
---|
429 | switch (bat_index) { |
---|
430 | case 0: asm_setdbat0 (bat.words.u, bat.words.l); break; |
---|
431 | case 1: asm_setdbat1 (bat.words.u, bat.words.l); break; |
---|
432 | case 2: asm_setdbat2 (bat.words.u, bat.words.l); break; |
---|
433 | case 3: asm_setdbat3 (bat.words.u, bat.words.l); break; |
---|
434 | /* cpu check already done in check_index */ |
---|
435 | case 4: asm_setdbat4 (bat.words.u, bat.words.l); break; |
---|
436 | case 5: asm_setdbat5 (bat.words.u, bat.words.l); break; |
---|
437 | case 6: asm_setdbat6 (bat.words.u, bat.words.l); break; |
---|
438 | case 7: asm_setdbat7 (bat.words.u, bat.words.l); break; |
---|
439 | default: /* should never get here anyways */ |
---|
440 | break; |
---|
441 | } |
---|
442 | } |
---|
443 | rtems_interrupt_enable (level); |
---|
444 | |
---|
445 | return 0; |
---|
446 | } |
---|
447 | |
---|
448 | static int |
---|
449 | getbat (int typ, int idx, unsigned long *pu, unsigned long *pl) |
---|
450 | { |
---|
451 | unsigned long u, l; |
---|
452 | |
---|
453 | if (check_bat_index (idx)) { |
---|
454 | printk ("Invalid BAT #%i\n", idx); |
---|
455 | return -1; |
---|
456 | } |
---|
457 | if ( TYP_I == typ ) { |
---|
458 | switch (idx) { |
---|
459 | case 0: GETBAT (IBAT0, u, l); break; |
---|
460 | case 1: GETBAT (IBAT1, u, l); break; |
---|
461 | case 2: GETBAT (IBAT2, u, l); break; |
---|
462 | case 3: GETBAT (IBAT3, u, l); break; |
---|
463 | /* cpu check already done in check_index */ |
---|
464 | case 4: GETBAT (IBAT4, u, l); break; |
---|
465 | case 5: GETBAT (IBAT5, u, l); break; |
---|
466 | case 6: GETBAT (IBAT6, u, l); break; |
---|
467 | case 7: GETBAT (IBAT7, u, l); break; |
---|
468 | default: /* should never get here anyways */ |
---|
469 | return -1; |
---|
470 | } |
---|
471 | } else { |
---|
472 | switch (idx) { |
---|
473 | case 0: GETBAT (DBAT0, u, l); break; |
---|
474 | case 1: GETBAT (DBAT1, u, l); break; |
---|
475 | case 2: GETBAT (DBAT2, u, l); break; |
---|
476 | case 3: GETBAT (DBAT3, u, l); break; |
---|
477 | /* cpu check already done in check_index */ |
---|
478 | case 4: GETBAT (DBAT4, u, l); break; |
---|
479 | case 5: GETBAT (DBAT5, u, l); break; |
---|
480 | case 6: GETBAT (DBAT6, u, l); break; |
---|
481 | case 7: GETBAT (DBAT7, u, l); break; |
---|
482 | default: /* should never get here anyways */ |
---|
483 | return -1; |
---|
484 | } |
---|
485 | } |
---|
486 | if (pu) { |
---|
487 | *pu = u; |
---|
488 | } |
---|
489 | if (pl) { |
---|
490 | *pl = l; |
---|
491 | } |
---|
492 | |
---|
493 | if (!pu && !pl) { |
---|
494 | /* dump */ |
---|
495 | ubat b; |
---|
496 | b.words.u = u; |
---|
497 | b.words.l = l; |
---|
498 | printk ("Raw %cBAT %i contents; UPPER: (0x%08x)", (TYP_I == typ ? 'I' : 'D'), idx, u); |
---|
499 | printk (" BEPI: 0x%08x", b.bat.batu.bepi); |
---|
500 | printk (" BL: 0x%08x", (u >> 2) & ((1 << 15) - 1)); |
---|
501 | printk (" VS: 0b%i", b.bat.batu.vs); |
---|
502 | printk (" VP: 0b%i", b.bat.batu.vp); |
---|
503 | printk ("\n"); |
---|
504 | printk (" LOWER: (0x%08x)", l); |
---|
505 | printk (" RPN: 0x%08x", b.bat.batl.brpn); |
---|
506 | printk (" wimg: 0b%1i%1i%1i%1i", b.bat.batl.w, b.bat.batl.i, |
---|
507 | b.bat.batl.m, b.bat.batl.g); |
---|
508 | printk (" PP: 0x%1x", b.bat.batl.pp); |
---|
509 | printk ("\n"); |
---|
510 | printk ("Covering EA Range: "); |
---|
511 | if (bat_in_use[typ] & (1 << idx)) |
---|
512 | printk ("0x%08x .. 0x%08x\n", bat_addrs[typ][idx].start, |
---|
513 | bat_addrs[typ][idx].limit); |
---|
514 | else |
---|
515 | printk ("<none> (BAT off)\n"); |
---|
516 | |
---|
517 | } |
---|
518 | return u; |
---|
519 | } |
---|
520 | |
---|
521 | int |
---|
522 | setdbat (int bat_index, unsigned long virt, unsigned long phys, |
---|
523 | unsigned int size, int flags) |
---|
524 | { |
---|
525 | return setbat(TYP_D, bat_index, virt, phys, size, flags); |
---|
526 | } |
---|
527 | |
---|
528 | int |
---|
529 | setibat (int bat_index, unsigned long virt, unsigned long phys, |
---|
530 | unsigned int size, int flags) |
---|
531 | { |
---|
532 | return setbat(TYP_I, bat_index, virt, phys, size, flags); |
---|
533 | } |
---|
534 | |
---|
535 | int |
---|
536 | getdbat (int idx, unsigned long *pu, unsigned long *pl) |
---|
537 | { |
---|
538 | return getbat (TYP_D, idx, pu, pl); |
---|
539 | } |
---|
540 | |
---|
541 | int |
---|
542 | getibat (int idx, unsigned long *pu, unsigned long *pl) |
---|
543 | { |
---|
544 | return getbat (TYP_I, idx, pu, pl); |
---|
545 | } |
---|