Changeset 486d6ec in rtems
- Timestamp:
- 11/30/07 01:05:08 (15 years ago)
- Branches:
- 4.10, 4.11, 4.9, 5, master
- Children:
- a725a4d7
- Parents:
- da8e974a
- Location:
- c/src/lib/libcpu/powerpc
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
c/src/lib/libcpu/powerpc/ChangeLog
rda8e974a r486d6ec 1 2007-11-29 Till Straumann <strauman@slac.stanford.edu> 2 3 * mpc6xx/mmu/bat.c, mpc6xx/mmu/bat.h: Added support 4 for setting & reading IBATs. 5 1 6 2007-11-28 Joel Sherrill <joel.sherrill@OARcorp.com> 2 7 -
c/src/lib/libcpu/powerpc/mpc6xx/mmu/bat.c
rda8e974a r486d6ec 27 27 #include <libcpu/cpuIdent.h> 28 28 29 #define TYP_I 1 30 #define TYP_D 0 31 29 32 typedef union 30 33 { /* BAT register values to be loaded */ … … 43 46 } batrange; 44 47 45 batrange bat_addrs[ 8] = { {0,} };48 batrange bat_addrs[2][8] = { { {0,} } }; 46 49 47 50 /* could encode this in bat_addrs but I don't touch that one for bwds compat. reasons */ 48 51 /* bitmask of used bats */ 49 static unsigned bat_in_use = 0;52 static unsigned bat_in_use[2] = { 0, 0 }; 50 53 51 54 /* define a few macros */ … … 107 110 static DECL_SETBAT (dbat7, DBAT7) 108 111 112 static DECL_SETBAT (ibat0, IBAT0) 113 static DECL_SETBAT (ibat1, IBAT1) 114 static DECL_SETBAT (ibat2, IBAT2) 115 static DECL_SETBAT (ibat3, IBAT3) 116 static DECL_SETBAT (ibat4, IBAT4) 117 static DECL_SETBAT (ibat5, IBAT5) 118 static DECL_SETBAT (ibat6, IBAT6) 119 static DECL_SETBAT (ibat7, IBAT7) 120 121 109 122 SPR_RO (HID0); 110 123 … … 125 138 126 139 static void 127 bat_addrs_put (ubat * bat, int idx)140 bat_addrs_put (ubat * bat, int typ, int idx) 128 141 { 129 142 unsigned long bl; 130 143 if (bat->bat.batu.vp || bat->bat.batu.vs) { 131 bat_addrs[ idx].start = bat->bat.batu.bepi << 17;132 bat_addrs[ idx].phys = bat->bat.batl.brpn << 17;144 bat_addrs[typ][idx].start = bat->bat.batu.bepi << 17; 145 bat_addrs[typ][idx].phys = bat->bat.batl.brpn << 17; 133 146 134 147 /* extended BL cannot be extracted using BAT union … … 137 150 */ 138 151 bl = (bat->words.u << 15) | ((1 << 17) - 1); 139 bat_addrs[ idx].limit = bat_addrs[idx].start + bl;140 141 bat_in_use |= (1 << idx);152 bat_addrs[typ][idx].limit = bat_addrs[typ][idx].start + bl; 153 154 bat_in_use[typ] |= (1 << idx); 142 155 } 143 156 } … … 155 168 156 169 GETBAT (DBAT0, bat.words.u, bat.words.l); 157 bat_addrs_put (&bat, 0);170 bat_addrs_put (&bat, TYP_D, 0); 158 171 GETBAT (DBAT1, bat.words.u, bat.words.l); 159 bat_addrs_put (&bat, 1);172 bat_addrs_put (&bat, TYP_D, 1); 160 173 GETBAT (DBAT2, bat.words.u, bat.words.l); 161 bat_addrs_put (&bat, 2);174 bat_addrs_put (&bat, TYP_D, 2); 162 175 GETBAT (DBAT3, bat.words.u, bat.words.l); 163 bat_addrs_put (&bat, 3); 176 bat_addrs_put (&bat, TYP_D, 3); 177 178 GETBAT (IBAT0, bat.words.u, bat.words.l); 179 bat_addrs_put (&bat, TYP_I, 0); 180 GETBAT (IBAT1, bat.words.u, bat.words.l); 181 bat_addrs_put (&bat, TYP_I, 1); 182 GETBAT (IBAT2, bat.words.u, bat.words.l); 183 bat_addrs_put (&bat, TYP_I, 2); 184 GETBAT (IBAT3, bat.words.u, bat.words.l); 185 bat_addrs_put (&bat, TYP_I, 3); 186 164 187 165 188 if ((cpu == PPC_7455 || cpu == PPC_7457) 166 189 && (HID0_7455_HIGH_BAT_EN & _read_HID0 ())) { 167 190 GETBAT (DBAT4, bat.words.u, bat.words.l); 168 bat_addrs_put (&bat, 4);191 bat_addrs_put (&bat, TYP_D, 4); 169 192 GETBAT (DBAT5, bat.words.u, bat.words.l); 170 bat_addrs_put (&bat, 5);193 bat_addrs_put (&bat, TYP_D, 5); 171 194 GETBAT (DBAT6, bat.words.u, bat.words.l); 172 bat_addrs_put (&bat, 6);195 bat_addrs_put (&bat, TYP_D, 6); 173 196 GETBAT (DBAT7, bat.words.u, bat.words.l); 174 bat_addrs_put (&bat, 7); 197 bat_addrs_put (&bat, TYP_D, 7); 198 GETBAT (IBAT4, bat.words.u, bat.words.l); 199 bat_addrs_put (&bat, TYP_I, 4); 200 GETBAT (IBAT5, bat.words.u, bat.words.l); 201 bat_addrs_put (&bat, TYP_I, 5); 202 GETBAT (IBAT6, bat.words.u, bat.words.l); 203 bat_addrs_put (&bat, TYP_I, 6); 204 GETBAT (IBAT7, bat.words.u, bat.words.l); 205 bat_addrs_put (&bat, TYP_I, 7); 175 206 } 176 207 } … … 283 314 284 315 static int 285 check_overlap ( unsigned long start, unsigned long size)316 check_overlap (int typ, unsigned long start, unsigned long size) 286 317 { 287 318 int i; 288 319 unsigned long limit = start + size - 1; 289 for (i = 0; i < sizeof (bat_addrs ) / sizeof (bat_addrs[0]); i++) {290 if (!((1 << i) & bat_in_use ))320 for (i = 0; i < sizeof (bat_addrs[typ]) / sizeof (bat_addrs[typ][0]); i++) { 321 if (!((1 << i) & bat_in_use[typ])) 291 322 continue; /* unused bat */ 292 /* safe is 'limit < bat_addrs[ i].start || start > bat_addrs[i].limit */293 if (limit >= bat_addrs[ i].start && start <= bat_addrs[i].limit)323 /* safe is 'limit < bat_addrs[t][i].start || start > bat_addrs[t][i].limit */ 324 if (limit >= bat_addrs[typ][i].start && start <= bat_addrs[typ][i].limit) 294 325 return i; 295 326 } … … 302 333 */ 303 334 304 void 305 set dbat (int bat_index, unsigned long virt, unsigned long phys,335 static int 336 setbat (int typ, int bat_index, unsigned long virt, unsigned long phys, 306 337 unsigned int size, int flags) 307 338 { … … 314 345 if (check_bat_index (bat_index)) { 315 346 printk ("Invalid BAT index\n", bat_index); 316 return ;347 return -1; 317 348 } 318 349 319 350 if ((int) (bl = check_bat_size (size)) < 0) { 320 351 printk ("Invalid BAT size\n", size); 321 return ;352 return -1; 322 353 } 323 354 … … 325 356 printk ("BAT effective address 0x%08x misaligned (size is 0x%08x)\n", 326 357 virt, size); 327 return ;358 return -1; 328 359 } 329 360 … … 331 362 printk ("BAT physical address 0x%08x misaligned (size is 0x%08x)\n", phys, 332 363 size); 333 return ;364 return -1; 334 365 } 335 366 … … 337 368 printk ("BAT range invalid: wraps around zero 0x%08x..0x%08x\n", virt, 338 369 virt + size - 1); 339 return; 370 return -1; 371 } 372 373 if ( TYP_I == typ && ( ( _PAGE_GUARDED | _PAGE_WRITETHRU ) & flags ) ) { 374 printk("IBAT must not have 'guarded' or 'writethrough' attribute\n"); 375 return -1; 340 376 } 341 377 … … 353 389 } 354 390 355 if (size >= (1 << 17) && (err = check_overlap ( virt, size)) >= 0) {391 if (size >= (1 << 17) && (err = check_overlap (typ, virt, size)) >= 0) { 356 392 rtems_interrupt_enable (level); 357 printk ("BATs must not overlap; area 0x%08x..0x%08x hits BAT %i\n",358 virt, virt + size, err);359 return ;393 printk ("BATs must not overlap; area 0x%08x..0x%08x hits %cBAT %i\n", 394 virt, virt + size, (TYP_I == typ ? 'I' : 'D'), err); 395 return -1; 360 396 } 361 397 … … 368 404 if (flags & _PAGE_USER) 369 405 bat.bat.batu.vp = 1; 370 bat_addrs[ bat_index].start = virt;371 bat_addrs[ bat_index].limit = virt + ((bl + 1) << 17) - 1;372 bat_addrs[ bat_index].phys = phys;373 bat_in_use |= 1 << bat_index;406 bat_addrs[typ][bat_index].start = virt; 407 bat_addrs[typ][bat_index].limit = virt + ((bl + 1) << 17) - 1; 408 bat_addrs[typ][bat_index].phys = phys; 409 bat_in_use[typ] |= 1 << bat_index; 374 410 if (size < (1 << 17)) { 375 411 /* size of 0 tells us to switch it off */ 376 412 bat.bat.batu.vp = 0; 377 413 bat.bat.batu.vs = 0; 378 bat_in_use &= ~(1 << bat_index);414 bat_in_use[typ] &= ~(1 << bat_index); 379 415 /* mimic old behavior when bl was 0 (bs==0 is actually legal; it doesnt 380 416 * indicate a size of zero. We now accept bl==0 and look at the size. 381 417 */ 382 bat_addrs[ bat_index].limit = virt;418 bat_addrs[typ][bat_index].limit = virt; 383 419 } 384 420 do_dssall (); 385 switch (bat_index) {386 case 0: 387 asm_setdbat0 (bat.words.u, bat.words.l);388 389 case 1: 390 asm_setdbat1 (bat.words.u, bat.words.l);391 break; 392 case 2: 393 asm_setdbat2 (bat.words.u, bat.words.l);394 395 case 3: 396 asm_setdbat3 (bat.words.u, bat.words.l); 397 398 /* cpu check already done in check_index */ 399 case 4:400 asm_setdbat4 (bat.words.u, bat.words.l); 401 402 case 5: 403 asm_setdbat5 (bat.words.u, bat.words.l);404 405 case 6: 406 asm_setdbat6 (bat.words.u, bat.words.l);407 408 case 7: 409 asm_setdbat7 (bat.words.u, bat.words.l);410 break; 411 default: /* should never get here anyways */ 412 break; 421 if ( TYP_I == typ ) { 422 switch (bat_index) { 423 case 0: asm_setibat0 (bat.words.u, bat.words.l); break; 424 case 1: asm_setibat1 (bat.words.u, bat.words.l); break; 425 case 2: asm_setibat2 (bat.words.u, bat.words.l); break; 426 case 3: asm_setibat3 (bat.words.u, bat.words.l); break; 427 /* cpu check already done in check_index */ 428 case 4: asm_setibat4 (bat.words.u, bat.words.l); break; 429 case 5: asm_setibat5 (bat.words.u, bat.words.l); break; 430 case 6: asm_setibat6 (bat.words.u, bat.words.l); break; 431 case 7: asm_setibat7 (bat.words.u, bat.words.l); break; 432 default: /* should never get here anyways */ 433 break; 434 } 435 } else { 436 switch (bat_index) { 437 case 0: asm_setdbat0 (bat.words.u, bat.words.l); break; 438 case 1: asm_setdbat1 (bat.words.u, bat.words.l); break; 439 case 2: asm_setdbat2 (bat.words.u, bat.words.l); break; 440 case 3: asm_setdbat3 (bat.words.u, bat.words.l); break; 441 /* cpu check already done in check_index */ 442 case 4: asm_setdbat4 (bat.words.u, bat.words.l); break; 443 case 5: asm_setdbat5 (bat.words.u, bat.words.l); break; 444 case 6: asm_setdbat6 (bat.words.u, bat.words.l); break; 445 case 7: asm_setdbat7 (bat.words.u, bat.words.l); break; 446 default: /* should never get here anyways */ 447 break; 448 } 413 449 } 414 450 rtems_interrupt_enable (level); 415 } 416 417 int 418 getdbat (int idx, unsigned long *pu, unsigned long *pl) 451 452 return 0; 453 } 454 455 static int 456 getbat (int typ, int idx, unsigned long *pu, unsigned long *pl) 419 457 { 420 458 unsigned long u, l; … … 424 462 return -1; 425 463 } 426 switch (idx) {427 case 0: 428 GETBAT (DBAT0, u, l);429 430 case 1: 431 GETBAT (DBAT1, u, l);432 break; 433 case 2: 434 GETBAT (DBAT2, u, l);435 436 case 3: 437 GETBAT (DBAT3, u, l); 438 break;439 /* cpu check already done in check_index */ 440 case 4:441 GETBAT (DBAT4, u, l); 442 443 case 5: 444 GETBAT (DBAT5, u, l);445 446 case 6: 447 GETBAT (DBAT6, u, l);448 449 case 7: 450 GETBAT (DBAT7, u, l);451 break; 452 default: /* should never get here anyways */ 453 return -1; 464 if ( TYP_I == typ ) { 465 switch (idx) { 466 case 0: GETBAT (IBAT0, u, l); break; 467 case 1: GETBAT (IBAT1, u, l); break; 468 case 2: GETBAT (IBAT2, u, l); break; 469 case 3: GETBAT (IBAT3, u, l); break; 470 /* cpu check already done in check_index */ 471 case 4: GETBAT (IBAT4, u, l); break; 472 case 5: GETBAT (IBAT5, u, l); break; 473 case 6: GETBAT (IBAT6, u, l); break; 474 case 7: GETBAT (IBAT7, u, l); break; 475 default: /* should never get here anyways */ 476 return -1; 477 } 478 } else { 479 switch (idx) { 480 case 0: GETBAT (DBAT0, u, l); break; 481 case 1: GETBAT (DBAT1, u, l); break; 482 case 2: GETBAT (DBAT2, u, l); break; 483 case 3: GETBAT (DBAT3, u, l); break; 484 /* cpu check already done in check_index */ 485 case 4: GETBAT (DBAT4, u, l); break; 486 case 5: GETBAT (DBAT5, u, l); break; 487 case 6: GETBAT (DBAT6, u, l); break; 488 case 7: GETBAT (DBAT7, u, l); break; 489 default: /* should never get here anyways */ 490 return -1; 491 } 454 492 } 455 493 if (pu) { … … 465 503 b.words.u = u; 466 504 b.words.l = l; 467 printk ("Raw DBAT %i contents; UPPER: (0x%08x)", idx, u);505 printk ("Raw %cBAT %i contents; UPPER: (0x%08x)", (TYP_I == typ ? 'I' : 'D'), idx, u); 468 506 printk (" BEPI: 0x%08x", b.bat.batu.bepi); 469 507 printk (" BL: 0x%08x", (u >> 2) & ((1 << 15) - 1)); … … 478 516 printk ("\n"); 479 517 printk ("Covering EA Range: "); 480 if (bat_in_use & (1 << idx))481 printk ("0x%08x .. 0x%08x\n", bat_addrs[ idx].start,482 bat_addrs[ idx].limit);518 if (bat_in_use[typ] & (1 << idx)) 519 printk ("0x%08x .. 0x%08x\n", bat_addrs[typ][idx].start, 520 bat_addrs[typ][idx].limit); 483 521 else 484 522 printk ("<none> (BAT off)\n"); … … 487 525 return u; 488 526 } 527 528 int 529 setdbat (int bat_index, unsigned long virt, unsigned long phys, 530 unsigned int size, int flags) 531 { 532 return setbat(TYP_D, bat_index, virt, phys, size, flags); 533 } 534 535 int 536 setibat (int bat_index, unsigned long virt, unsigned long phys, 537 unsigned int size, int flags) 538 { 539 return setbat(TYP_I, bat_index, virt, phys, size, flags); 540 } 541 542 int 543 getdbat (int idx, unsigned long *pu, unsigned long *pl) 544 { 545 return getbat (TYP_D, idx, pu, pl); 546 } 547 548 int 549 getibat (int idx, unsigned long *pu, unsigned long *pl) 550 { 551 return getbat (TYP_I, idx, pu, pl); 552 } -
c/src/lib/libcpu/powerpc/mpc6xx/mmu/bat.h
rda8e974a r486d6ec 46 46 * - Physical & virtual addresses must be aligned 47 47 * to the size. 48 * 49 * RETURNS: zero on success, nonzero on failure. 48 50 */ 49 extern voidsetdbat(int bat_index, unsigned long virt, unsigned long phys,51 extern int setdbat(int bat_index, unsigned long virt, unsigned long phys, 50 52 unsigned int size, int flags); 51 53 52 /* read DBAT # 'idx' into *pu/*pl. NULL pointers may be passed. 54 /* Same as setdbat but sets IBAT */ 55 extern int setibat(int bat_index, unsigned long virt, unsigned long phys, 56 unsigned int size, int flags); 57 58 /* read DBAT # 'idx' into *pu / *pl. NULL pointers may be passed. 53 59 * If pu and pl are NULL, the bat contents are dumped to the console (printk). 54 60 * … … 57 63 extern int getdbat(int bat_index, unsigned long *pu, unsigned long *pl); 58 64 65 /* Same as getdbat but reads IBAT */ 66 extern int getibat(int bat_index, unsigned long *pu, unsigned long *pl); 67 68 /* Do not use the asm routines; they are obsolete; use setdbat() instead */ 59 69 extern void asm_setdbat0(unsigned int uperPart, unsigned int lowerPart); 60 70 extern void asm_setdbat1(unsigned int uperPart, unsigned int lowerPart);
Note: See TracChangeset
for help on using the changeset viewer.