Changeset 912ab10e in rtems


Ignore:
Timestamp:
Nov 3, 2005, 1:54:59 AM (15 years ago)
Author:
Till Straumann <strauman@…>
Branches:
4.10, 4.11, 4.8, 4.9, 5, master
Children:
ec58ea04
Parents:
2628ebb
Message:

2005-11-02 straumanatslacdotstanford.edu

  • mpc6xx/mmu/bat.c, mpc6xx/mmu/bat.h, mpc6xx/mmu/mmuAsm.S: moved assembly code to C; setdbat now supports high bats on 7450 CPUs; added argument checking to setdbat; added getdbat; moved early initialization code (clear_bats) from BSP to libcpu (CPU_clear_bats_early)
Location:
c/src/lib/libcpu/powerpc
Files:
4 edited

Legend:

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

    r2628ebb r912ab10e  
     12005-11-02      straumanatslacdotstanford.edu
     2
     3        * mpc6xx/mmu/bat.c, mpc6xx/mmu/bat.h, mpc6xx/mmu/mmuAsm.S: moved
     4        assembly code to C; setdbat now supports high bats on 7450 CPUs;
     5        added argument checking to setdbat; added getdbat; moved early
     6        initialization code (clear_bats) from BSP to libcpu
     7        (CPU_clear_bats_early)
     8
    192005-11-02      straumanatslacdotstanford.edu
    210 
  • c/src/lib/libcpu/powerpc/mpc6xx/mmu/bat.c

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

    r2628ebb r912ab10e  
    2626#include <libcpu/mmu.h>
    2727#include <libcpu/pgtable.h>
    28 #include <rtems/bspIo.h>
    2928
    3029#define IO_PAGE (_PAGE_NO_CACHE | _PAGE_GUARDED | _PAGE_RW)
    3130
     31#ifndef ASM
     32/* Take no risks -- the essential parts of this routine run with
     33 * interrupts disabled!
     34 *
     35 * The routine does basic parameter checks:
     36 *   - Index must be 0..3 (0..7 on 7455, 7457).
     37 *     If an index > 3 is requested the 745x is
     38 *     programmed to enable the higher BATs.
     39 *   - Size must be a power of two and <= 1<<28
     40 *     (<=1<<31 on 7455, 7457. Also, on these processors
     41 *     the special value 0xffffffff is allowed which stands
     42 *     for 1<<32).
     43 *     If a size > 1<<28 is requested, the 745x is
     44 *     programmed to enable the larger block sizes.
     45 *   - Bat ranges must not overlap.
     46 *   - Physical & virtual addresses must be aligned
     47 *     to the size.
     48 */
    3249extern void setdbat(int bat_index, unsigned long virt, unsigned long phys,
    3350                    unsigned int size, int flags);
    3451
     52/* read DBAT # 'idx' into *pu/*pl. NULL pointers may be passed.
     53 * If pu and pl are NULL, the bat contents are dumped to the console (printk).
     54 *
     55 * RETURNS: upper BAT contents or (-1) if index is invalid
     56 */
     57extern int getdbat(int bat_index, unsigned long *pu, unsigned long *pl);
     58
     59extern void asm_setdbat0(unsigned int uperPart, unsigned int lowerPart);
    3560extern void asm_setdbat1(unsigned int uperPart, unsigned int lowerPart);
    3661extern void asm_setdbat2(unsigned int uperPart, unsigned int lowerPart);
    3762extern void asm_setdbat3(unsigned int uperPart, unsigned int lowerPart);
    38 extern void asm_setdbat4(unsigned int uperPart, unsigned int lowerPart);
     63#else
     64
     65/* Initialize all bats (upper and lower) to zero. This routine should *only*
     66 * be called during early BSP initialization when no C-ABI is available
     67 * yet.
     68 * This routine clobbers r3 and r4.
     69 * NOTE: on 7450 CPUs all 8 dbat/ibat units are cleared. On 601 CPUs only
     70 *       4 ibats.
     71 */
     72        .globl CPU_clear_bats_early
     73        .type  CPU_clear_bats_early,@function
     74
     75#endif
    3976
    4077#endif /* _LIBCPU_BAT_H */
  • c/src/lib/libcpu/powerpc/mpc6xx/mmu/mmuAsm.S

    r2628ebb r912ab10e  
    1111 *  The license and distribution terms for this file may be
    1212 *  found in found in the file LICENSE in this distribution or at
    13  *  http://www.rtems.com/license/LICENSE.
     13 *  http://www.OARcorp.com/rtems/license.html.
    1414 *     
    1515 *  T. Straumann - 11/2001: added support for 7400 (no AltiVec yet)
     
    2121#include <rtems/score/cpu.h>
    2222#include <libcpu/io.h>
     23#include <libcpu/bat.h>
    2324
    2425/* Unfortunately, the CPU types defined in cpu.h are
     
    3536#define PPC_7400  0xC
    3637#define PPC_7455  0x8001
     38#define PPC_7457  0x8002
    3739#define PPC_620   0x16
    3840#define PPC_860   0x50
     
    5456#define L2HWF   (1<<(31-20))
    5557       
    56 /*
    57  * Each setdbat routine start by invalidating the DBAT as some
    58  * proc (604e) request the valid bit set to 0 before accepting
    59  * to write in BAT
    60  */
    61 
    62         .globl  asm_setdbat0
    63         .type   asm_setdbat0,@function
    64 asm_setdbat0:
    65         li      r0,0
    66         sync
    67         isync
    68         mtspr   DBAT0U,r0
    69         mtspr   DBAT0L,r0
    70         sync
    71         isync
    72         mtspr DBAT0L, r4
    73         mtspr DBAT0U, r3
    74         sync
    75         isync
    76         blr
    77 
    78         .globl  asm_setdbat1
    79         .type   asm_setdbat1,@function
    80 asm_setdbat1:
    81         li      r0,0
    82         sync
    83         isync
    84         mtspr   DBAT1U,r0
    85         mtspr   DBAT1L,r0
    86         sync
    87         isync
    88         mtspr DBAT1L, r4
    89         mtspr DBAT1U, r3
    90         sync
    91         isync
    92         blr
    93 
    94         .globl  asm_setdbat2
    95         .type   asm_setdbat2,@function
    96 asm_setdbat2:   
    97         li      r0,0
    98         sync
    99         isync
    100         mtspr   DBAT2U,r0
    101         mtspr   DBAT2L,r0
    102         sync
    103         isync
    104         mtspr DBAT2L, r4
    105         mtspr DBAT2U, r3
    106         sync
    107         isync
    108         blr
    109 
    110         .globl  asm_setdbat3
    111         .type   asm_setdbat3,@function
    112 asm_setdbat3:   
    113         li      r0,0
    114         sync
    115         isync
    116         mtspr   DBAT3U,r0
    117         mtspr   DBAT3L,r0
    118         sync
    119         isync
    120         mtspr DBAT3L, r4
    121         mtspr DBAT3U, r3
    122         sync
    123         isync
    124         blr
    125                
     58#FIXME Should really move this to C code
     59
    12660        .globl L1_caches_enables
    12761        .type  L1_caches_enables, @function
     
    15892        cror    6,6,10         
    15993        cmpli   0,r9,PPC_7455   /* or 7455 */
    160         bne     2f
     94        beq     1f
     95        cmpli   0,r9,PPC_7457   /* or 7457 */
     96        bne             2f
     971:
    16198        /* 7455:link register stack,branch folding &
    16299         * TBEN : enable the time base and decrementer.
     
    1691062:      cror    2,2,10 
    170107        bne     3f
    171         ori     r11,r11,HID0_BTIC       /* enable branch tgt cache on 7400 & 7455 */
     108        ori     r11,r11,HID0_BTIC       /* enable branch tgt cache on 7400 , 7455 , 7457 */
    1721093:      cror    2,2,6
    173110        bne     4f
     
    199136        beq     1f
    200137        cmplwi  r3,PPC_7455     /* it's a 7455 */
     138        beq     1f     
     139        cmplwi  r3,PPC_7457     /* it's a 7457 */
    201140        beq     1f     
    202141        li      r3,-1
     
    249188        cmplwi  r0,PPC_7455
    250189        beq     thisIs750       
     190        cmplwi  r0,PPC_7457
     191        beq     thisIs750       
    251192        li      r3,-1
    252193        blr
     
    294235        isync                           /* make sure memory accesses have completed */
    295236        cmplwi  r0,PPC_7455             /* 7455 ? */
     237        beq     1f
     238        cmplwi  r0,PPC_7457             /* 7457 ? */
    296239        bne     not745x
    297         /* 7455:L1 Load/Flush, L2, L3 :  hardware flush */
    298         /* If not using AltiVec data streaming instructions,DSSALL not necessary */
     2401:
     241        /* 745x:L1 Load/Flush, L2, L3 :  hardware flush */
     242        DSSALL
    299243        sync
    300244        mfspr   r4, MSSCR0     
     
    407351        cmplwi  r3,PPC_7455     /* it's a 7455 */
    408352        beq     1f     
     353        cmplwi  r3,PPC_7457     /* it's a 7457 */
     354        beq     1f     
    409355        li      r3,-1
    410356        blr
     
    434380        rlwinm  r0,r0,16,16,31
    435381        cmplwi  r0,PPC_7455
     382        beq     thisIs7455     
     383        cmplwi  r0,PPC_7457
    436384        beq     thisIs7455     
    437385        li      r3,-1
     
    516464        sync
    517465        blr
     466
     467/*
     468 * An undocumented "feature" of 604e requires that the v bit
     469 * be cleared before changing BAT values.
     470 *
     471 * Also, newer IBM firmware does not clear bat3 and 4 so
     472 * this makes sure it's done.
     473 *  -- Cort
     474 */
     475        .globl  CPU_clear_bats_early
     476        .type   CPU_clear_bats_early,@function
     477CPU_clear_bats_early:
     478        li              r3,0
     479        mfspr   r4,PVR
     480        rlwinm  r4,r4,16,16,31          /* r4 = 1 for 601, 4 for 604 */
     481        cmpwi   r4, 1
     482        sync
     483        isync
     484        beq     1f
     485        cmplwi  r4,0x8001                       /* 7445, 7455 (0x8001), 7447, 7457 (0x8002)      */
     486        blt 2f                                          /* 7447a (0x8003) and 7448 (0x8004) have 16 bats */
     487        cmplwi  r4,0x8004
     488        bgt 2f
     489        mtspr   DBAT4U,r3
     490        mtspr   DBAT4L,r3
     491        mtspr   DBAT5U,r3
     492        mtspr   DBAT5L,r3
     493        mtspr   DBAT6U,r3
     494        mtspr   DBAT6L,r3
     495        mtspr   DBAT7U,r3
     496        mtspr   DBAT7L,r3
     497        mtspr   IBAT4U,r3
     498        mtspr   IBAT4L,r3
     499        mtspr   IBAT5U,r3
     500        mtspr   IBAT5L,r3
     501        mtspr   IBAT6U,r3
     502        mtspr   IBAT6L,r3
     503        mtspr   IBAT7U,r3
     504        mtspr   IBAT7L,r3
     5052:
     506        mtspr   DBAT0U,r3
     507        mtspr   DBAT0L,r3
     508        mtspr   DBAT1U,r3
     509        mtspr   DBAT1L,r3
     510        mtspr   DBAT2U,r3
     511        mtspr   DBAT2L,r3
     512        mtspr   DBAT3U,r3
     513        mtspr   DBAT3L,r3
     5141:
     515        mtspr   IBAT0U,r3
     516        mtspr   IBAT0L,r3
     517        mtspr   IBAT1U,r3
     518        mtspr   IBAT1L,r3
     519        mtspr   IBAT2U,r3
     520        mtspr   IBAT2L,r3
     521        mtspr   IBAT3U,r3
     522        mtspr   IBAT3L,r3
     523        sync
     524        isync
     525        blr
     526
Note: See TracChangeset for help on using the changeset viewer.