Changeset 486d6ec in rtems


Ignore:
Timestamp:
Nov 30, 2007, 1:05:08 AM (13 years ago)
Author:
Till Straumann <strauman@…>
Branches:
4.10, 4.11, 4.9, master
Children:
a725a4d7
Parents:
da8e974a
Message:

2007-11-29 Till Straumann <strauman@…>

  • mpc6xx/mmu/bat.c, mpc6xx/mmu/bat.h: Added support for setting & reading IBATs.
Location:
c/src/lib/libcpu/powerpc
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libcpu/powerpc/ChangeLog

    rda8e974a r486d6ec  
     12007-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
    162007-11-28      Joel Sherrill <joel.sherrill@OARcorp.com>
    27
  • c/src/lib/libcpu/powerpc/mpc6xx/mmu/bat.c

    rda8e974a r486d6ec  
    2727#include <libcpu/cpuIdent.h>
    2828
     29#define TYP_I   1
     30#define TYP_D   0
     31
    2932typedef union
    3033{                               /* BAT register values to be loaded */
     
    4346} batrange;
    4447
    45 batrange bat_addrs[8] = { {0,} };
     48batrange bat_addrs[2][8] = { { {0,} } };
    4649
    4750/* could encode this in bat_addrs but I don't touch that one for bwds compat. reasons */
    4851/* bitmask of used bats */
    49 static unsigned bat_in_use = 0;
     52static unsigned bat_in_use[2] = { 0, 0 };
    5053
    5154/* define a few macros */
     
    107110static DECL_SETBAT (dbat7, DBAT7)
    108111
     112static DECL_SETBAT (ibat0, IBAT0)
     113static DECL_SETBAT (ibat1, IBAT1)
     114static DECL_SETBAT (ibat2, IBAT2)
     115static DECL_SETBAT (ibat3, IBAT3)
     116static DECL_SETBAT (ibat4, IBAT4)
     117static DECL_SETBAT (ibat5, IBAT5)
     118static DECL_SETBAT (ibat6, IBAT6)
     119static DECL_SETBAT (ibat7, IBAT7)
     120
     121
    109122SPR_RO (HID0);
    110123
     
    125138
    126139static void
    127 bat_addrs_put (ubat * bat, int idx)
     140bat_addrs_put (ubat * bat, int typ, int idx)
    128141{
    129142  unsigned long bl;
    130143  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;
    133146
    134147    /* extended BL cannot be extracted using BAT union
     
    137150     */
    138151    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);
    142155  }
    143156}
     
    155168
    156169  GETBAT (DBAT0, bat.words.u, bat.words.l);
    157   bat_addrs_put (&bat, 0);
     170  bat_addrs_put (&bat, TYP_D, 0);
    158171  GETBAT (DBAT1, bat.words.u, bat.words.l);
    159   bat_addrs_put (&bat, 1);
     172  bat_addrs_put (&bat, TYP_D, 1);
    160173  GETBAT (DBAT2, bat.words.u, bat.words.l);
    161   bat_addrs_put (&bat, 2);
     174  bat_addrs_put (&bat, TYP_D, 2);
    162175  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
    164187
    165188  if ((cpu == PPC_7455 || cpu == PPC_7457)
    166189      && (HID0_7455_HIGH_BAT_EN & _read_HID0 ())) {
    167190    GETBAT (DBAT4, bat.words.u, bat.words.l);
    168     bat_addrs_put (&bat, 4);
     191    bat_addrs_put (&bat, TYP_D, 4);
    169192    GETBAT (DBAT5, bat.words.u, bat.words.l);
    170     bat_addrs_put (&bat, 5);
     193    bat_addrs_put (&bat, TYP_D, 5);
    171194    GETBAT (DBAT6, bat.words.u, bat.words.l);
    172     bat_addrs_put (&bat, 6);
     195    bat_addrs_put (&bat, TYP_D, 6);
    173196    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);
    175206  }
    176207}
     
    283314
    284315static int
    285 check_overlap (unsigned long start, unsigned long size)
     316check_overlap (int typ, unsigned long start, unsigned long size)
    286317{
    287318  int i;
    288319  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]))
    291322      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)
    294325      return i;
    295326  }
     
    302333 */
    303334
    304 void
    305 setdbat (int bat_index, unsigned long virt, unsigned long phys,
     335static int
     336setbat (int typ, int bat_index, unsigned long virt, unsigned long phys,
    306337         unsigned int size, int flags)
    307338{
     
    314345  if (check_bat_index (bat_index)) {
    315346    printk ("Invalid BAT index\n", bat_index);
    316     return;
     347    return -1;
    317348  }
    318349
    319350  if ((int) (bl = check_bat_size (size)) < 0) {
    320351    printk ("Invalid BAT size\n", size);
    321     return;
     352    return -1;
    322353  }
    323354
     
    325356    printk ("BAT effective address 0x%08x misaligned (size is 0x%08x)\n",
    326357            virt, size);
    327     return;
     358    return -1;
    328359  }
    329360
     
    331362    printk ("BAT physical address 0x%08x misaligned (size is 0x%08x)\n", phys,
    332363            size);
    333     return;
     364    return -1;
    334365  }
    335366
     
    337368    printk ("BAT range invalid: wraps around zero 0x%08x..0x%08x\n", virt,
    338369            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;
    340376  }
    341377
     
    353389  }
    354390
    355   if (size >= (1 << 17) && (err = check_overlap (virt, size)) >= 0) {
     391  if (size >= (1 << 17) && (err = check_overlap (typ, virt, size)) >= 0) {
    356392    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;
    360396  }
    361397
     
    368404  if (flags & _PAGE_USER)
    369405    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;
    374410  if (size < (1 << 17)) {
    375411    /* size of 0 tells us to switch it off */
    376412    bat.bat.batu.vp = 0;
    377413    bat.bat.batu.vs = 0;
    378     bat_in_use &= ~(1 << bat_index);
     414    bat_in_use[typ] &= ~(1 << bat_index);
    379415    /* mimic old behavior when bl was 0 (bs==0 is actually legal; it doesnt
    380416     * indicate a size of zero. We now accept bl==0 and look at the size.
    381417     */
    382     bat_addrs[bat_index].limit = virt;
     418    bat_addrs[typ][bat_index].limit = virt;
    383419  }
    384420  do_dssall ();
    385   switch (bat_index) {
    386   case 0:
    387     asm_setdbat0 (bat.words.u, bat.words.l);
    388     break;
    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     break;
    395   case 3:
    396     asm_setdbat3 (bat.words.u, bat.words.l);
    397     break;
    398     /* cpu check already done in check_index */
    399   case 4:
    400     asm_setdbat4 (bat.words.u, bat.words.l);
    401     break;
    402   case 5:
    403     asm_setdbat5 (bat.words.u, bat.words.l);
    404     break;
    405   case 6:
    406     asm_setdbat6 (bat.words.u, bat.words.l);
    407     break;
    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          }
    413449  }
    414450  rtems_interrupt_enable (level);
    415 }
    416 
    417 int
    418 getdbat (int idx, unsigned long *pu, unsigned long *pl)
     451
     452  return 0;
     453}
     454
     455static int
     456getbat (int typ, int idx, unsigned long *pu, unsigned long *pl)
    419457{
    420458  unsigned long u, l;
     
    424462    return -1;
    425463  }
    426   switch (idx) {
    427   case 0:
    428     GETBAT (DBAT0, u, l);
    429     break;
    430   case 1:
    431     GETBAT (DBAT1, u, l);
    432     break;
    433   case 2:
    434     GETBAT (DBAT2, u, l);
    435     break;
    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     break;
    443   case 5:
    444     GETBAT (DBAT5, u, l);
    445     break;
    446   case 6:
    447     GETBAT (DBAT6, u, l);
    448     break;
    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          }
    454492  }
    455493  if (pu) {
     
    465503    b.words.u = u;
    466504    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);
    468506    printk (" BEPI: 0x%08x", b.bat.batu.bepi);
    469507    printk (" BL: 0x%08x", (u >> 2) & ((1 << 15) - 1));
     
    478516    printk ("\n");
    479517    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);
    483521    else
    484522      printk ("<none> (BAT off)\n");
     
    487525  return u;
    488526}
     527
     528int
     529setdbat (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
     535int
     536setibat (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
     542int
     543getdbat (int idx, unsigned long *pu, unsigned long *pl)
     544{
     545        return getbat (TYP_D, idx, pu, pl);
     546}
     547
     548int
     549getibat (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  
    4646 *   - Physical & virtual addresses must be aligned
    4747 *     to the size.
     48 *
     49 * RETURNS: zero on success, nonzero on failure.
    4850 */
    49 extern void setdbat(int bat_index, unsigned long virt, unsigned long phys,
     51extern int setdbat(int bat_index, unsigned long virt, unsigned long phys,
    5052                    unsigned int size, int flags);
    5153
    52 /* read DBAT # 'idx' into *pu/*pl. NULL pointers may be passed.
     54/* Same as setdbat but sets IBAT */
     55extern 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.
    5359 * If pu and pl are NULL, the bat contents are dumped to the console (printk).
    5460 *
     
    5763extern int getdbat(int bat_index, unsigned long *pu, unsigned long *pl);
    5864
     65/* Same as getdbat but reads IBAT */
     66extern 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 */
    5969extern void asm_setdbat0(unsigned int uperPart, unsigned int lowerPart);
    6070extern void asm_setdbat1(unsigned int uperPart, unsigned int lowerPart);
Note: See TracChangeset for help on using the changeset viewer.