OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [or1ksim/] [testsuite/] [test-code-or1k/] [mmu/] [mmu.c] - Diff between revs 346 and 458

Show entire file | Details | Blame | View Log

Rev 346 Rev 458
Line 25... Line 25...
   This code is commented throughout for use with Doxygen.
   This code is commented throughout for use with Doxygen.
   --------------------------------------------------------------------------*/
   --------------------------------------------------------------------------*/
 
 
/* This is MMU test for OpenRISC 1200 */
/* This is MMU test for OpenRISC 1200 */
 
 
 
// Tests most functions of the MMUs.
 
// The tests attempt to keep the areas of instruction and data memory working 
 
// as they should, while testing around them, higher in memory. Some linker 
 
// variables are relied upon by the interrupt routines for checking if areas 
 
// are within the expected text areas of memory, but usually we just keep 
 
// above the stack (also set in the linker script) and things go OK.
 
 
 
// The tests for translation setup address translation in the MMU from areas 
 
// in the 512kB - 1024kB region (64 sets in OR1200, 8kByte per set) to halfway
 
// through RAM. Usually the sets taht would encompass the actual program are 
 
// skipped (TLB_TEXT_SET_NB) ie, we say how many sets encompass the program 
 
// text for itlb tests and only do tests above it (so, on sets 8-64, meaning 
 
// when we enable the iMMU and say have the execution bits disabled to force a
 
// page fault the program gets to continue and is translated 1-1 while 
 
// accesses to the areas we are testing will cause a page fault) but it should
 
//  still work to test all sets.
 
 
 
// In essense, the tests are aware that they could be operating out of the 
 
// same memory the tests are being performed in and takes care of this.
 
 
 
// The use of the "match_space" variable is for the addresses we'll access 
 
// when a non-1-1 translation will occur, otherwise usually the 
 
// "translate_space" variable by itself is used (it's first setup to the 
 
// desired address, and either data or the return instructions are placed 
 
// where we expect the MMU to translate to)
 
 
#include "spr-defs.h"
#include "spr-defs.h"
#include "support.h"
#include "support.h"
 
 
 
// Set this to 1 to enable the DMMU tests
 
#define DO_DMMU_TESTS 1
 
 
 
// Symbols defined in linker script
 
extern unsigned long _ram_end;
 
extern unsigned long _src_beg;
 
 
 
unsigned long text_begin_addr;
 
unsigned long end_data_addr;
 
 
/* For shorter simulation run */
/* For shorter simulation run */
#define RTL_SIM 1
#define RTL_SIM 1
 
 
/* Define RAM physical location and size
/* Define RAM physical location and size
   Bottom half will be used for this program, the rest
   Bottom half will be used for this program, the rest
   will be used for testing */
   will be used for testing */
#define FLASH_START 0xf0000000
 
#define FLASH_SIZE  0x00200000
 
#define RAM_START   0x00000000
#define RAM_START   0x00000000
 
// Assume only 2MB memory
#define RAM_SIZE    0x00200000
#define RAM_SIZE    0x00200000
 
 
/* What is the last address in ram that is used by this program */
#define VM_BASE 0xc0000000
#define TEXT_END_ADD (FLASH_START + (FLASH_SIZE / 2))
 
#define DATA_END_ADD (RAM_START + (RAM_SIZE / 2))
 
 
 
#define TLB_TEXT_SET_NB 8
/* What is the last address in ram that is used by this program */
#define TLB_DATA_SET_NB 4
#define TEXT_START_ADD text_begin_addr
 
#define TEXT_END_ADD end_data_addr
 
#define DATA_END_ADD end_data_addr
 
 
 
// Uncomment the following to determine the page to test from at run-time
 
unsigned long TLB_TEXT_SET_NB;
 
unsigned long TLB_DATA_SET_NB;
 
 
/* MMU page size */
/* MMU page size */
#define PAGE_SIZE 8192
#define PAGE_SIZE 8192
 
 
/* Number of DTLB sets used (power of 2, max is 256) */
/* Number of DTLB sets used (power of 2, max is 256) */
Line 76... Line 115...
                          SPR_DTLBTR_SWE  )
                          SPR_DTLBTR_SWE  )
 
 
#define ITLB_PR_NOLIMIT  (SPR_ITLBTR_SXE  | \
#define ITLB_PR_NOLIMIT  (SPR_ITLBTR_SXE  | \
                          SPR_ITLBTR_UXE  )
                          SPR_ITLBTR_UXE  )
 
 
#if 1
 
#define debug printf
 
#else
 
#define debug
 
#endif
 
 
 
/* fails if x is false */
/* fails if x is false */
#define ASSERT(x) ((x)?1: fail (__FUNCTION__, __LINE__))
#define ASSERT(x) ((x)?1: fail (__FUNCTION__, __LINE__))
 
 
//#define TEST_JUMP(x) testjump( ((x) & (RAM_SIZE/2 - 1)) + DATA_END_ADD, (x))
// iMMU and dMMU enable functions
#define TEST_JUMP(x) copy_jump (((x) & (RAM_SIZE/2 - 1)) + DATA_END_ADD); call (x)
 
 
 
/* Extern functions */
 
extern void lo_dmmu_en (void);
extern void lo_dmmu_en (void);
extern void lo_immu_en (void);
extern void lo_immu_en (void);
extern int  lo_dtlb_ci_test (unsigned long, unsigned long);
 
extern int  lo_itlb_ci_test(unsigned long, unsigned long);
 
extern void testjump(unsigned long phy_addr, unsigned long virt_addr);
 
extern void (*jr)(void);
 
 
 
/* Local functions prototypes */
/* Local functions prototypes */
void dmmu_disable (void);
void dmmu_disable (void);
void immu_disable (void);
void immu_disable (void);
 
 
 
// Machine code for l.jr r9 and then l.nop
 
#define OR32_L_JR_R9 0x44004800
 
#define OR32_L_NOP 0x15000000
 
 
/* Global variables */
/* Global variables */
extern unsigned long ram_end;
extern unsigned long ram_end;
 
 
/* DTLB mode status */
/* DTLB mode status */
volatile unsigned long dtlb_val;
volatile unsigned long dtlb_val;
Line 133... Line 165...
unsigned long itlb_miss_ea;
unsigned long itlb_miss_ea;
 
 
/* EA of last insn page fault exception */
/* EA of last insn page fault exception */
unsigned long ipage_fault_ea;
unsigned long ipage_fault_ea;
 
 
void sys_call (void)
 
{
 
  asm("l.sys\t0");
 
}
 
 
 
 
#define sys_call() __asm__ __volatile__("l.sys\t0");
 
/*
 
void sys_call (void)
 
{
 
  asm("l.sys\t0");
 
}
 
*/
void fail (char *func, int line)
void fail (char *func, int line)
{
{
#ifndef __FUNCTION__
#ifndef __FUNCTION__
#define __FUNCTION__ "?"
#define __FUNCTION__ "?"
#endif
#endif
Line 150... Line 185...
  sys_call ();
  sys_call ();
 
 
  immu_disable ();
  immu_disable ();
  dmmu_disable ();
  dmmu_disable ();
 
 
  debug("Test failed in %s:%i\n", func, line);
  report(line);
  report (0xeeeeeeee);
  report (0xeeeeeeee);
  exit (1);
  exit (1);
}
}
 
 
void call(unsigned long add)
void call(unsigned long add)
Line 163... Line 198...
        asm("l.nop" : :);
        asm("l.nop" : :);
}
}
 
 
void jump(void)
void jump(void)
{
{
        asm("jr:");
  return;
        asm("l.jr\t\tr9") ;
  /*asm("_jr:");
        asm("l.nop" : :);
  asm("l.jr\t\tr9") ;
 
  asm("l.nop" : :);*/
}
}
 
 
void copy_jump(unsigned long phy_add)
void copy_jump(unsigned long phy_add)
{
{
        memcpy((void *)phy_add, (void *)&jr, 8);
  memcpy((void *)phy_add, (void *)&jump, (8*4));
}
}
 
 
/* Bus error exception handler */
/* Bus error exception handler */
void bus_err_handler (void)
void bus_err_handler (void)
{
{
  /* This shouldn't happend */
  /* This shouldn't happend */
  debug("Test failed: Bus error\n");
  printf("Test failed: Bus error\n");
  report (0xeeeeeeee);
  report (0xeeeeeeee);
  exit (1);
  exit (1);
}
}
 
 
/* Illegal insn exception handler */
/* Illegal insn exception handler */
void ill_insn_handler (void)
void ill_insn_handler (void)
{
{
  /* This shouldn't happend */
  /* This shouldn't happend */
  debug("Test failed: Illegal insn\n");
  printf("Test failed: Illegal insn\n");
  report (0xeeeeeeee);
  report (0xeeeeeeee);
  exit (1);
  exit (1);
}
}
 
 
/* Sys call exception handler */
/* Sys call exception handler */
Line 217... Line 253...
      way = i;
      way = i;
      break;
      break;
    }
    }
  }
  }
 
 
  debug("ea = %08lx set = %d way = %d\n", ea, set, way);
  printf("dtlb miss ea = %.8lx set = %d way = %d\n", ea, set, way);
 
 
  if (((RAM_START <= ea) && (ea < DATA_END_ADD) ) || ((FLASH_START <= ea) && (ea < TEXT_END_ADD))) {
  // Anything under the stack belongs to the program, direct tranlsate it
 
  if (ea < (unsigned long)&_ram_end){
    /* If this is acces to data of this program set one to one translation */
    /* If this is acces to data of this program set one to one translation */
    mtspr (SPR_DTLBMR_BASE(way) + set, (ea & SPR_DTLBMR_VPN) | SPR_DTLBMR_V);
    mtspr (SPR_DTLBMR_BASE(way) + set, (ea & SPR_DTLBMR_VPN) | SPR_DTLBMR_V);
    mtspr (SPR_DTLBTR_BASE(way) + set, (ea & SPR_DTLBTR_PPN) | DTLB_PR_NOLIMIT);
    mtspr (SPR_DTLBTR_BASE(way) + set, (ea & SPR_DTLBTR_PPN) | DTLB_PR_NOLIMIT);
    return;
    return;
  }
  }
 
 
  /* Update DTLB miss counter and EA */
  /* Update DTLB miss counter and EA */
  dtlb_miss_count++;
  dtlb_miss_count++;
  dtlb_miss_ea = ea;
  dtlb_miss_ea = ea;
 
 
  /* Whatever access is in progress, translated address have to point to physical RAM */
  // Everything gets translated back to the space halfway through RAM
  ta = (ea & ((RAM_SIZE/2) - 1)) + RAM_START + (RAM_SIZE/2);
  ta = (set*PAGE_SIZE) + RAM_START + (RAM_SIZE/2);
  tlbtr = (ta & SPR_DTLBTR_PPN) | (dtlb_val & TLB_PR_MASK);
  tlbtr = (ta & SPR_DTLBTR_PPN) | (dtlb_val & TLB_PR_MASK);
  debug("tlbtr = %08lx dtlb_val = %08lx\n", tlbtr, dtlb_val);
  printf("ta = %.8lx tlbtr = %.8lx dtlb_val = %.8lx\n",ta, tlbtr, dtlb_val);
 
 
  /* Set DTLB entry */
  /* Set DTLB entry */
  mtspr (SPR_DTLBMR_BASE(way) + set, (ea & SPR_DTLBMR_VPN) | SPR_DTLBMR_V);
  mtspr (SPR_DTLBMR_BASE(way) + set, (ea & SPR_DTLBMR_VPN) | SPR_DTLBMR_V);
  mtspr (SPR_DTLBTR_BASE(way) + set, tlbtr);
  mtspr (SPR_DTLBTR_BASE(way) + set, tlbtr);
}
}
Line 253... Line 290...
  ea = mfspr (SPR_EEAR_BASE);
  ea = mfspr (SPR_EEAR_BASE);
 
 
  /* Find TLB set and way */
  /* Find TLB set and way */
  set = (ea / PAGE_SIZE) % DTLB_SETS;
  set = (ea / PAGE_SIZE) % DTLB_SETS;
  for (i = 0; i < DTLB_WAYS; i++) {
  for (i = 0; i < DTLB_WAYS; i++) {
    if ((mfspr (SPR_DTLBMR_BASE(i) + set) & SPR_DTLBMR_VPN) == (ea & SPR_DTLBMR_VPN)) {
    if ((mfspr (SPR_DTLBMR_BASE(i) + set) & SPR_DTLBMR_VPN) ==
 
        (ea & SPR_DTLBMR_VPN)) {
      way = i;
      way = i;
      break;
      break;
    }
    }
  }
  }
 
 
  debug("ea = %08lx set = %d way = %d\n", ea, set, way);
  printf("ea = %.8lx set = %d way = %d\n", ea, set, way);
 
 
  if (((RAM_START <= ea) && (ea < DATA_END_ADD) ) || ((FLASH_START <= ea) && (ea < TEXT_END_ADD))) {
  if (((RAM_START <= ea) & (ea < DATA_END_ADD) ) |
 
      ((TEXT_START_ADD <= ea) & (ea < TEXT_END_ADD))) {
    /* If this is acces to data of this program set one to one translation */
    /* If this is acces to data of this program set one to one translation */
    mtspr (SPR_DTLBTR_BASE(way) + set, (ea & SPR_DTLBTR_PPN) | DTLB_PR_NOLIMIT);
    mtspr (SPR_DTLBTR_BASE(way) + set, (ea & SPR_DTLBTR_PPN) | DTLB_PR_NOLIMIT);
    return;
    return;
  }
  }
 
 
  /* Update data page fault counter and EA */
  /* Update data page fault counter and EA */
  dpage_fault_count++;
  dpage_fault_count++;
  dpage_fault_ea = ea;
  dpage_fault_ea = ea;
 
 
  /* Give permission */
  /* Give permission */
  mtspr (SPR_DTLBTR_BASE(way) + set, (mfspr (SPR_DTLBTR_BASE(way) + set) & ~DTLB_PR_NOLIMIT) | dtlb_val);
  mtspr (SPR_DTLBTR_BASE(way) + set,
 
         (mfspr (SPR_DTLBTR_BASE(way) + set) & ~DTLB_PR_NOLIMIT) | dtlb_val);
}
}
 
 
 
 
/* ITLB miss exception handler */
/* ITLB miss exception handler */
void itlb_miss_handler (void)
void itlb_miss_handler (void)
Line 295... Line 335...
      way = i;
      way = i;
      break;
      break;
    }
    }
  }
  }
 
 
  debug("ea = %08lx set = %d way = %d\n", ea, set, way);
  printf("itlb miss ea = %.8lx set = %d way = %d\n", ea, set, way);
 
 
  if ((FLASH_START <= ea) && (ea < TEXT_END_ADD)) {
  if ((TEXT_START_ADD <= ea) && (ea < TEXT_END_ADD)) {
    /* If this is acces to data of this program set one to one translation */
    /* If this is acces to data of this program set one to one translation */
    mtspr (SPR_ITLBMR_BASE(way) + set, (ea & SPR_ITLBMR_VPN) | SPR_ITLBMR_V);
    mtspr (SPR_ITLBMR_BASE(way) + set, (ea & SPR_ITLBMR_VPN) | SPR_ITLBMR_V);
    mtspr (SPR_ITLBTR_BASE(way) + set, (ea & SPR_ITLBTR_PPN) | ITLB_PR_NOLIMIT);
    mtspr (SPR_ITLBTR_BASE(way) + set, (ea & SPR_ITLBTR_PPN) | ITLB_PR_NOLIMIT);
    return;
    return;
  }
  }
 
 
  /* Update ITLB miss counter and EA */
  /* Update ITLB miss counter and EA */
  itlb_miss_count++;
  itlb_miss_count++;
  itlb_miss_ea = ea;
  itlb_miss_ea = ea;
 
 
  /* Whatever access is in progress, translated address have to point to physical RAM */
  /* Whatever access is in progress, translated address have to point to
  ta = (ea & ((RAM_SIZE/2) - 1)) + DATA_END_ADD;
     physical RAM */
 
 
 
  ta = RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE);
  tlbtr = (ta & SPR_ITLBTR_PPN) | (itlb_val & TLB_PR_MASK);
  tlbtr = (ta & SPR_ITLBTR_PPN) | (itlb_val & TLB_PR_MASK);
 
 
  debug("ta = %08lx\n", ta);
  printf("ta = %.8lx\n", ta);
 
 
  /* Set ITLB entry */
  /* Set ITLB entry */
  mtspr (SPR_ITLBMR_BASE(way) + set, (ea & SPR_ITLBMR_VPN) | SPR_ITLBMR_V);
  mtspr (SPR_ITLBMR_BASE(way) + set, (ea & SPR_ITLBMR_VPN) | SPR_ITLBMR_V);
  mtspr (SPR_ITLBTR_BASE(way) + set, tlbtr);
  mtspr (SPR_ITLBTR_BASE(way) + set, tlbtr);
}
}
Line 338... Line 380...
      way = i;
      way = i;
      break;
      break;
    }
    }
  }
  }
 
 
  debug("ea = %08lx set = %d way = %d\n", ea, set, way);
  printf("ipage fault: ea = %.8lx set = %d way = %d\n", ea, set, way);
 
 
  if ((FLASH_START <= ea) && (ea < TEXT_END_ADD)) {
  if ((TEXT_START_ADD <= ea) && (ea < TEXT_END_ADD)) {
    /* If this is acces to data of this program set one to one translation */
    /* If this is acces to data of this program set one to one translation */
    mtspr (SPR_DTLBTR_BASE(way) + set, (ea & SPR_DTLBTR_PPN) | ITLB_PR_NOLIMIT);
    mtspr (SPR_DTLBTR_BASE(way) + set, (ea & SPR_DTLBTR_PPN) | ITLB_PR_NOLIMIT);
    return;
    return;
  }
  }
 
 
 
  printf("ipage fault was outside of code area\n");
 
 
  /* Update instruction page fault counter and EA */
  /* Update instruction page fault counter and EA */
  ipage_fault_count++;
  ipage_fault_count++;
  ipage_fault_ea = ea;
  ipage_fault_ea = ea;
 
 
  /* Give permission */
  /* Give permission */
Line 358... Line 402...
 
 
/* Invalidate all entries in DTLB and enable DMMU */
/* Invalidate all entries in DTLB and enable DMMU */
void dmmu_enable (void)
void dmmu_enable (void)
{
{
  /* Register DTLB miss handler */
  /* Register DTLB miss handler */
 
        //add_handler(0x9, dtlb_miss_handler);
  excpt_dtlbmiss = (unsigned long)dtlb_miss_handler;
  excpt_dtlbmiss = (unsigned long)dtlb_miss_handler;
 
 
  /* Register data page fault handler */
  /* Register data page fault handler */
 
  //add_handler(0x3, dpage_fault_handler);
  excpt_dpfault = (unsigned long)dpage_fault_handler;
  excpt_dpfault = (unsigned long)dpage_fault_handler;
 
 
  /* Enable DMMU */
  /* Enable DMMU */
  lo_dmmu_en ();
  lo_dmmu_en ();
 
 
}
}
 
 
/* Disable DMMU */
/* Disable DMMU */
void dmmu_disable (void)
void dmmu_disable (void)
{
{
Line 377... Line 424...
 
 
/* Invalidate all entries in ITLB and enable IMMU */
/* Invalidate all entries in ITLB and enable IMMU */
void immu_enable (void)
void immu_enable (void)
{
{
  /* Register ITLB miss handler */
  /* Register ITLB miss handler */
 
  //add_handler(0xa, itlb_miss_handler);
  excpt_itlbmiss = (unsigned long)itlb_miss_handler;
  excpt_itlbmiss = (unsigned long)itlb_miss_handler;
 
 
  /* Register instruction page fault handler */
  /* Register instruction page fault handler */
 
  //add_handler(0x4, ipage_fault_handler);
  excpt_ipfault = (unsigned long)ipage_fault_handler;
  excpt_ipfault = (unsigned long)ipage_fault_handler;
 
 
  /* Enable IMMU */
  /* Enable IMMU */
  lo_immu_en ();
  lo_immu_en ();
 
 
}
}
 
 
/* Disable IMMU */
/* Disable IMMU */
void immu_disable (void)
void immu_disable (void)
{
{
Line 414... Line 464...
  unsigned long ea, ta;
  unsigned long ea, ta;
 
 
  /* Disable DMMU */
  /* Disable DMMU */
  dmmu_disable();
  dmmu_disable();
 
 
 
  printf("dtlb translation test set\n");
 
 
  /* Invalidate all entries in DTLB */
  /* Invalidate all entries in DTLB */
  for (i = 0; i < DTLB_WAYS; i++) {
  for (i = 0; i < DTLB_WAYS; i++) {
    for (j = 0; j < DTLB_SETS; j++) {
    for (j = 0; j < DTLB_SETS; j++) {
      mtspr (SPR_DTLBMR_BASE(i) + j, 0);
      mtspr (SPR_DTLBMR_BASE(i) + j, 0);
      mtspr (SPR_DTLBTR_BASE(i) + j, 0);
      mtspr (SPR_DTLBTR_BASE(i) + j, 0);
    }
    }
  }
  }
 
 
  /* Set one to one translation for the use of this program */
  /* Set one to one translation for program's data space */
  for (i = 0; i < TLB_DATA_SET_NB; i++) {
  for (i = 0; i < TLB_DATA_SET_NB; i++) {
    ea = RAM_START + (i*PAGE_SIZE);
    ea = RAM_START + (i*PAGE_SIZE);
    ta = RAM_START + (i*PAGE_SIZE);
    ta = RAM_START + (i*PAGE_SIZE);
    mtspr (SPR_DTLBMR_BASE(0) + i, ea | SPR_DTLBMR_V);
    mtspr (SPR_DTLBMR_BASE(0) + i, ea | SPR_DTLBMR_V);
    mtspr (SPR_DTLBTR_BASE(0) + i, ta | DTLB_PR_NOLIMIT);
    mtspr (SPR_DTLBTR_BASE(0) + i, ta | (DTLB_PR_NOLIMIT));
  }
  }
 
 
  /* Set dtlb permisions */
  /* Set dtlb permisions */
  dtlb_val = DTLB_PR_NOLIMIT;
  dtlb_val = DTLB_PR_NOLIMIT;
 
 
  /* Write test pattern */
  /* Write test pattern */
  for (i = 0; i < DTLB_SETS; i++) {
  for (i = 0; i < DTLB_SETS; i++) {
    REG32(RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE)) = i;
    ea = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
    REG32(RAM_START + (RAM_SIZE/2) + ((i + 1)*PAGE_SIZE) - 4) = 0xffffffff - i;
    REG32(ea) = i;
 
    ea = RAM_START + (RAM_SIZE/2) + ((i + 1)*PAGE_SIZE) - 4;
 
    REG32(ea) = 0xffffffff - i;
  }
  }
 
 
  /* Set one to one translation of the last way of DTLB */
  /* Set one to one translation */
  for (i = TLB_DATA_SET_NB; i < DTLB_SETS; i++) {
  for (i = TLB_DATA_SET_NB; i < DTLB_SETS; i++) {
    ea = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
    ea = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
    ta = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
    ta = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
    mtspr (SPR_DTLBMR_BASE(DTLB_WAYS - 1) + i, ea | SPR_DTLBMR_V);
    mtspr (SPR_DTLBMR_BASE(DTLB_WAYS - 1) + i, ea | SPR_DTLBMR_V);
    mtspr (SPR_DTLBTR_BASE(DTLB_WAYS - 1) + i, ta | DTLB_PR_NOLIMIT);
    mtspr (SPR_DTLBTR_BASE(DTLB_WAYS - 1) + i, ta | DTLB_PR_NOLIMIT);
Line 460... Line 514...
    ASSERT(REG32(ea) == (0xffffffff - i));
    ASSERT(REG32(ea) == (0xffffffff - i));
  }
  }
 
 
  /* Write new pattern */
  /* Write new pattern */
  for (i = TLB_DATA_SET_NB; i < DTLB_SETS; i++) {
  for (i = TLB_DATA_SET_NB; i < DTLB_SETS; i++) {
    REG32(RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE)) = 0xffffffff - i;
    ea = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
    REG32(RAM_START + (RAM_SIZE/2) + ((i + 1)*PAGE_SIZE) - 4) = i;
    REG32(ea) = 0xffffffff - i;
 
    ea = RAM_START + (RAM_SIZE/2) + ((i + 1)*PAGE_SIZE) - 4;
 
    REG32(ea) = i;
  }
  }
 
 
  /* Set 0 -> RAM_START + (RAM_SIZE/2) translation */
  /* Set 0 -> RAM_START + (RAM_SIZE/2) translation */
  for (i = TLB_DATA_SET_NB; i < DTLB_SETS; i++) {
  for (i = TLB_DATA_SET_NB; i < DTLB_SETS; i++) {
    ea = i*PAGE_SIZE;
    ea = i*PAGE_SIZE;
Line 489... Line 545...
  }
  }
 
 
  /* Set hi -> lo, lo -> hi translation */
  /* Set hi -> lo, lo -> hi translation */
  for (i = TLB_DATA_SET_NB; i < DTLB_SETS; i++) {
  for (i = TLB_DATA_SET_NB; i < DTLB_SETS; i++) {
    ea = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
    ea = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
    ta = RAM_START + (RAM_SIZE/2) + ((DTLB_SETS - i - 1 + TLB_DATA_SET_NB)*PAGE_SIZE);
    ta = RAM_START + (RAM_SIZE/2) + ((DTLB_SETS - i - 1 + TLB_DATA_SET_NB)*
 
                                     PAGE_SIZE);
    mtspr (SPR_DTLBMR_BASE(DTLB_WAYS - 1) + i, ea | SPR_DTLBMR_V);
    mtspr (SPR_DTLBMR_BASE(DTLB_WAYS - 1) + i, ea | SPR_DTLBMR_V);
    mtspr (SPR_DTLBTR_BASE(DTLB_WAYS - 1) + i, ta | DTLB_PR_NOLIMIT);
    mtspr (SPR_DTLBTR_BASE(DTLB_WAYS - 1) + i, ta | DTLB_PR_NOLIMIT);
  }
  }
 
 
  /* Check the pattern */
  /* Check the pattern */
Line 519... Line 576...
    ASSERT(REG32(ea) == (0xffffffff - DTLB_SETS + i + 1 - TLB_DATA_SET_NB));
    ASSERT(REG32(ea) == (0xffffffff - DTLB_SETS + i + 1 - TLB_DATA_SET_NB));
    ea = RAM_START + (RAM_SIZE/2) + ((i + 1)*PAGE_SIZE) - 4;
    ea = RAM_START + (RAM_SIZE/2) + ((i + 1)*PAGE_SIZE) - 4;
    ASSERT(REG32(ea) == (DTLB_SETS - i - 1 + TLB_DATA_SET_NB));
    ASSERT(REG32(ea) == (DTLB_SETS - i - 1 + TLB_DATA_SET_NB));
  }
  }
 
 
 
  printf("OK\n");
 
  printf("-------------------------------------------\n");
 
 
  return 0;
  return 0;
}
}
 
 
/* EA match register test
/* EA match register test
   Shifting one in DTLBMR and performing accesses to boundaries
   Shifting one in DTLBMR and performing accesses to boundaries
   of the page, checking the triggering of exceptions */
   of the page, checking the triggering of exceptions */
int dtlb_match_test (int way, int set)
int dtlb_match_test (int way, int set)
{
{
  int i, j, tmp;
  int i, j, tmp;
  unsigned long add, t_add;
  unsigned long large_offset_addr;
  unsigned long ea, ta;
  unsigned long ea, ta;
 
  unsigned long match_space;
 
  unsigned long translate_space;
 
  unsigned long program_space_offset;
 
 
  /* Disable DMMU */
  /* Disable DMMU */
  dmmu_disable();
  dmmu_disable();
 
 
 
  printf("dtlb_match_test - way %d set %d\n",way, set);
 
 
  /* Invalidate all entries in DTLB */
  /* Invalidate all entries in DTLB */
  for (i = 0; i < DTLB_WAYS; i++) {
  for (i = 0; i < DTLB_WAYS; i++) {
    for (j = 0; j < DTLB_SETS; j++) {
    for (j = 0; j < DTLB_SETS; j++) {
      mtspr (SPR_DTLBMR_BASE(i) + j, 0);
      mtspr (SPR_DTLBMR_BASE(i) + j, 0);
      mtspr (SPR_DTLBTR_BASE(i) + j, 0);
      mtspr (SPR_DTLBTR_BASE(i) + j, 0);
    }
    }
  }
  }
 
 
  /* Set one to one translation for the use of this program */
  // Program text/data pages should be 1-1 translation
  for (i = 0; i < TLB_DATA_SET_NB; i++) {
  for (i = 0; i < TLB_DATA_SET_NB; i++) {
    ea = RAM_START + (i*PAGE_SIZE);
    ea = RAM_START + (i*PAGE_SIZE);
    ta = RAM_START + (i*PAGE_SIZE);
    ta = RAM_START + (i*PAGE_SIZE);
    mtspr (SPR_DTLBMR_BASE(0) + i, ea | SPR_DTLBMR_V);
    mtspr (SPR_DTLBMR_BASE(0) + i, ea | SPR_DTLBMR_V);
    mtspr (SPR_DTLBTR_BASE(0) + i, ta | DTLB_PR_NOLIMIT);
    mtspr (SPR_DTLBTR_BASE(0) + i, ta | DTLB_PR_NOLIMIT);
  }
  }
 
 
  /* Set dtlb permisions */
  /* Set dtlb permisions */
  dtlb_val = DTLB_PR_NOLIMIT;
  dtlb_val = DTLB_PR_NOLIMIT;
 
 
 
  // Determine offset required to skip past area in use by program
 
  program_space_offset = 0;
 
  while (program_space_offset <= DATA_END_ADD)
 
          program_space_offset += (PAGE_SIZE*DTLB_SETS);
 
 
 
  // Setup match area address - based at halfway through RAM, 
 
  // and then offset by the area encompassed by the set we wish to test.
 
  // TODO: Ensure this is on a page boundary
 
  translate_space = RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE);
 
 
  /* Set pattern */
  /* Set pattern */
  REG32(RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE) - 4) = 0x00112233;
  // Last word of page before the one covered by this set
  REG32(RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE)) = 0x44556677;
  REG32(translate_space - 4) = 0x00112233;
  REG32(RAM_START + (RAM_SIZE/2) + (set + 1)*PAGE_SIZE - 4) = 0x8899aabb;
 
  REG32(RAM_START + (RAM_SIZE/2) + (set + 1)*PAGE_SIZE) = 0xccddeeff;
  // First word of page covered by this set
 
  REG32(translate_space) = 0x44556677;
 
 
 
  // Last word of page covered by this set
 
  REG32(translate_space + PAGE_SIZE - 4) = 0x8899aabb;
 
 
 
  // First word of page covered by next set
 
  REG32(translate_space + PAGE_SIZE) = 0xccddeeff;
 
 
  /* Enable DMMU */
  /* Enable DMMU */
  dmmu_enable();
  dmmu_enable();
 
 
  /* Shifting one in DTLBMR */
  /* Shifting one in DTLBMR */
  i = 0;
  i = 0;
  add = (PAGE_SIZE*DTLB_SETS);
 
  t_add = add + (set*PAGE_SIZE);
  // Setup match space - place we will do accesses to, and have them
  while (add != 0x00000000) {
  // tranlsated into the translate space addresses. Ensure it is above the end
    mtspr (SPR_DTLBMR_BASE(way) + set, t_add | SPR_DTLBMR_V);
  // of the program's space.
    mtspr (SPR_DTLBTR_BASE(way) + set, (RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE)) | DTLB_PR_NOLIMIT);
  match_space = program_space_offset + (set*PAGE_SIZE);
 
 
 
  // This is used to provide a large match offset (ie. virtual address)
 
  // We will offset the match address by this each time. This value is 
 
  // shifted left after each test, ensuring the high bits of address are 
 
  // tested.
 
  large_offset_addr = (PAGE_SIZE*DTLB_SETS); // 8kB * 64, 512KB
 
 
 
  while (large_offset_addr != 0x00000000) {
 
    // Set MATCH register for the areas we will access explicitly, and 
 
    // validate them.
 
    mtspr (SPR_DTLBMR_BASE(way) + set, match_space | SPR_DTLBMR_V);
 
 
 
    // Set TRANSLATE register to the areas where we have set our data
 
    mtspr (SPR_DTLBTR_BASE(way) + set, translate_space | DTLB_PR_NOLIMIT);
 
 
    /* Reset DTLB miss counter and EA */
    /* Reset DTLB miss counter and EA */
    dtlb_miss_count = 0;
    dtlb_miss_count = 0;
    dtlb_miss_ea = 0;
    dtlb_miss_ea = 0;
 
    printf("testing match space %8lx translate space %8lx\n",match_space,
    if (((t_add < RAM_START) || (t_add >= DATA_END_ADD)) && ((t_add < FLASH_START) || (t_add >= TEXT_END_ADD))) {
           translate_space);
 
    // Only do the test if we won't tread on any memory being used for data
 
    // and stack. It is unlikely this would occur.
 
    if (match_space > DATA_END_ADD){
 
 
      /* Read last address of previous page */
      /* Read last address of previous page */
      tmp = REG32(t_add - 4);
      tmp = REG32(match_space - 4);
      ASSERT(tmp == 0x00112233);
      ASSERT(tmp == 0x00112233);
      ASSERT(dtlb_miss_count == 1);
      ASSERT(dtlb_miss_count == 1);
 
 
      /* Read first address of the page */
      /* Read first address of the page */
      tmp = REG32(t_add);
      tmp = REG32(match_space);
      ASSERT(tmp == 0x44556677);
      ASSERT(tmp == 0x44556677);
      ASSERT(dtlb_miss_count == 1);
      ASSERT(dtlb_miss_count == 1);
 
 
      /* Read last address of the page */
      /* Read last address of the page */
      tmp = REG32(t_add + PAGE_SIZE - 4);
      tmp = REG32(match_space + PAGE_SIZE - 4);
      ASSERT(tmp == 0x8899aabb);
      ASSERT(tmp == 0x8899aabb);
      ASSERT(dtlb_miss_count == 1);
      ASSERT(dtlb_miss_count == 1);
 
 
      /* Read first address of next page */
      /* Read first address of next page */
      tmp = REG32(t_add + PAGE_SIZE);
      tmp = REG32(match_space + PAGE_SIZE);
      ASSERT(tmp == 0xccddeeff);
      ASSERT(tmp == 0xccddeeff);
      ASSERT(dtlb_miss_count == 2);
      ASSERT(dtlb_miss_count == 2);
    }
    }
 
 
    i++;
    i++;
    add = (PAGE_SIZE*DTLB_SETS) << i;
    large_offset_addr = (PAGE_SIZE*DTLB_SETS) << i;
    t_add = add + (set*PAGE_SIZE);
    match_space = large_offset_addr + program_space_offset + (set*PAGE_SIZE);
 
 
 
    // Clear MR/T for space we just tested
    for (j = 0; j < DTLB_WAYS; j++) {
    for (j = 0; j < DTLB_WAYS; j++) {
      mtspr (SPR_DTLBMR_BASE(j) + ((set - 1) & (DTLB_SETS - 1)), 0);
      mtspr (SPR_DTLBMR_BASE(j) + ((set - 1) & (DTLB_SETS - 1)), 0);
      mtspr (SPR_DTLBMR_BASE(j) + ((set + 1) & (DTLB_SETS - 1)), 0);
      mtspr (SPR_DTLBMR_BASE(j) + ((set + 1) & (DTLB_SETS - 1)), 0);
    }
    }
  }
  }
 
 
  /* Disable DMMU */
  /* Disable DMMU */
  dmmu_disable();
  dmmu_disable();
 
 
 
  printf("OK\n");
 
  printf("-------------------------------------------\n");
 
 
  return 0;
  return 0;
}
}
 
 
/* Valid bit test
/* Valid bit test
   Set all ways of one set to be invalid, perform
   Set all ways of one set to be invalid, perform
Line 625... Line 728...
  unsigned long ea, ta;
  unsigned long ea, ta;
 
 
  /* Disable DMMU */
  /* Disable DMMU */
  dmmu_disable();
  dmmu_disable();
 
 
 
  printf("dtlb_valid_bit_test, set %d\n", set);
 
 
  /* Invalidate all entries in DTLB */
  /* Invalidate all entries in DTLB */
  for (i = 0; i < DTLB_WAYS; i++) {
  for (i = 0; i < DTLB_WAYS; i++) {
    for (j = 0; j < DTLB_SETS; j++) {
    for (j = 0; j < DTLB_SETS; j++) {
      mtspr (SPR_DTLBMR_BASE(i) + j, 0);
      mtspr (SPR_DTLBMR_BASE(i) + j, 0);
      mtspr (SPR_DTLBTR_BASE(i) + j, 0);
      mtspr (SPR_DTLBTR_BASE(i) + j, 0);
Line 694... Line 799...
  }
  }
 
 
  /* Disable DMMU */
  /* Disable DMMU */
  dmmu_disable();
  dmmu_disable();
 
 
 
  printf("OK\n");
 
  printf("-------------------------------------------\n");
 
 
  return 0;
  return 0;
}
}
 
 
/* Permission test
/* Permission test
   Set various permissions, perform r/w access
   Set various permissions, perform r/w access
   in user and supervisor mode and chack triggering
   in user and supervisor mode and chack triggering
   of page fault exceptions */
   of page fault exceptions */
int dtlb_premission_test (int set)
int dtlb_permission_test (int set)
{
{
  int i, j;
  int i, j;
  unsigned long ea, ta, tmp;
  unsigned long ea, ta, tmp;
 
 
 
  printf("dtlb_permission_test, set %d\n", set);
 
 
  /* Disable DMMU */
  /* Disable DMMU */
  dmmu_disable();
  dmmu_disable();
 
 
  /* Invalidate all entries in DTLB */
  /* Invalidate all entries in DTLB */
  for (i = 0; i < DTLB_WAYS; i++) {
  for (i = 0; i < DTLB_WAYS; i++) {
Line 811... Line 921...
  sys_call ();
  sys_call ();
 
 
  /* Disable DMMU */
  /* Disable DMMU */
  dmmu_disable();
  dmmu_disable();
 
 
 
  printf("OK\n");
 
  printf("-------------------------------------------\n");
 
 
  return 0;
  return 0;
}
}
 
 
/* Data cache inhibit bit test
 
   Set and clear CI bit and check the pattern. */
/* Dcache test - check inhibit
int dtlb_ci_test (void)
Write data with cache inhibit on and off, check for coherency
 
 */
 
int dtlb_dcache_test (int set)
{
{
  int i, j;
  int i, j;
  unsigned long ea, ta, ret;
  unsigned long ea, ta, vmea;
 
 
 
  // Check data cache is present and enabled
 
  if (!(mfspr(SPR_UPR)& SPR_UPR_DCP))
 
    return 0;
 
 
 
  if (!(mfspr(SPR_SR) & SPR_SR_DCE))
 
    return 0;
 
 
 
  printf("dtlb_dcache_test, set %d\n", set);
 
 
  /* Disable DMMU */
  /* Disable DMMU */
  dmmu_disable();
  dmmu_disable();
 
 
  /* Invalidate all entries in DTLB */
  /* Invalidate all entries in DTLB */
Line 837... Line 961...
  /* Set one to one translation for the use of this program */
  /* Set one to one translation for the use of this program */
  for (i = 0; i < TLB_DATA_SET_NB; i++) {
  for (i = 0; i < TLB_DATA_SET_NB; i++) {
    ea = RAM_START + (i*PAGE_SIZE);
    ea = RAM_START + (i*PAGE_SIZE);
    ta = RAM_START + (i*PAGE_SIZE);
    ta = RAM_START + (i*PAGE_SIZE);
    mtspr (SPR_DTLBMR_BASE(0) + i, ea | SPR_DTLBMR_V);
    mtspr (SPR_DTLBMR_BASE(0) + i, ea | SPR_DTLBMR_V);
    mtspr (SPR_DTLBTR_BASE(0) + i, ta | DTLB_PR_NOLIMIT  | SPR_DTLBTR_CI);
    mtspr (SPR_DTLBTR_BASE(0) + i, ta | DTLB_PR_NOLIMIT);
  }
  }
 
 
  /* Testing page */
  /* Testing page */
  ea = RAM_START + (RAM_SIZE/2) + (TLB_DATA_SET_NB*PAGE_SIZE);
  ea = RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE);
  ta = RAM_START + (RAM_SIZE/2) + (TLB_DATA_SET_NB*PAGE_SIZE);
 
 
 
  /* Write test pattern */
  ta = RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE);
  REG32(ea) = 0x01234567;
 
  REG32(ea + PAGE_SIZE - 4) = 0x9abcdef;
  vmea = VM_BASE + RAM_START + (RAM_SIZE/2) + ((DTLB_SETS-1)*PAGE_SIZE);
 
 
 
  // Set a 1-1 translation for this page without cache inhibited
 
 
  /* Set one to one translation with CI bit for testing area */
  /* Set match register */
  mtspr (SPR_DTLBMR_BASE(0) + TLB_DATA_SET_NB, ea | SPR_DTLBMR_V);
  mtspr (SPR_DTLBMR_BASE(0) + set, ea | SPR_DTLBMR_V);
  mtspr (SPR_DTLBTR_BASE(0) + TLB_DATA_SET_NB, ta | DTLB_PR_NOLIMIT | SPR_DTLBTR_CI);
  /* Set translate register */
 
  mtspr (SPR_DTLBTR_BASE(0) + set, ta | DTLB_PR_NOLIMIT);
 
 
 
  // Now set a far-off translation, VM_BASE, for this page with cache inhibited
 
  // Use the last set
 
 
 
  /* Set match register */
 
  mtspr (SPR_DTLBMR_BASE(0) + (DTLB_SETS-1),
 
         vmea | SPR_DTLBMR_V);
 
  /* Set translate register */
 
  mtspr (SPR_DTLBTR_BASE(0) + (DTLB_SETS-1),
 
         ta | DTLB_PR_NOLIMIT | SPR_DTLBTR_CI);
 
 
 
  /* Enable DMMU */
 
  dmmu_enable();
 
 
 
  // First do a write with the cache inhibited mapping
 
  unsigned long int testwrite_to_be_cached = 0xfeca1d0d ^ set;
 
  REG32((vmea)) = testwrite_to_be_cached;
 
  // Read it back to check that it's the same, this read should get cached
 
  ASSERT(REG32(ea) == testwrite_to_be_cached);
 
  // Now write again to the cache inhibited location
 
  unsigned long int testwrite_not_to_be_cached = 0xbaadbeef ^ set;
 
  REG32((vmea)) = testwrite_not_to_be_cached;
 
  // Now check that the cached mapping doesn't read this value back
 
  ASSERT(REG32(ea) == testwrite_to_be_cached);
 
 
 
  // Now disable cache inhibition on the 1-1 mapping
 
  /* Set translate register */
 
  mtspr (SPR_DTLBTR_BASE(0) + set,
 
         ea | DTLB_PR_NOLIMIT | SPR_DTLBTR_CI);
 
 
 
  // Check that we now get the second value we wrote
 
  testwrite_to_be_cached = testwrite_not_to_be_cached;
 
  ASSERT(REG32(ea) == testwrite_to_be_cached);
 
 
 
  /* Disable DMMU */
 
  dmmu_disable();
 
 
  ret = lo_dtlb_ci_test(ea, TLB_DATA_SET_NB);
  printf("OK\n");
  ASSERT(ret == 0);
  printf("-------------------------------------------\n");
 
 
  return 0;
  return 0;
 
 
}
}
 
 
/* Translation address register test
/* Translation address register test
   Set various translation and check the pattern */
   Set various translation and check the pattern */
int itlb_translation_test (void)
int itlb_translation_test (void)
{
{
  int i, j;
  int i, j;
  unsigned long ea, ta;
  //unsigned long ea, ta;
 
  unsigned long translate_space;
 
  unsigned long match_space;
 
  printf("itlb_translation_test\n");
 
 
  /* Disable IMMU */
  /* Disable IMMU */
  immu_disable();
  immu_disable();
 
 
  /* Invalidate all entries in ITLB */
  /* Invalidate all entries in DTLB */
  for (i = 0; i < ITLB_WAYS; i++) {
  for (i = 0; i < ITLB_WAYS; i++) {
    for (j = 0; j < ITLB_SETS; j++) {
    for (j = 0; j < ITLB_SETS; j++) {
      mtspr (SPR_ITLBMR_BASE(i) + j, 0);
      mtspr (SPR_ITLBMR_BASE(i) + j, 0);
      mtspr (SPR_ITLBTR_BASE(i) + j, 0);
      mtspr (SPR_ITLBTR_BASE(i) + j, 0);
    }
    }
  }
  }
 
 
  /* Set one to one translation for the use of this program */
  /* Set one to one translation for the use of this program */
  for (i = 0; i < TLB_TEXT_SET_NB; i++) {
  for (i = 0; i < TLB_TEXT_SET_NB; i++) {
    ea = FLASH_START + (i*PAGE_SIZE);
          match_space = /*TEXT_START_ADD +*/ (i*PAGE_SIZE);
    ta = FLASH_START + (i*PAGE_SIZE);
          translate_space = /*TEXT_START_ADD +*/ (i*PAGE_SIZE);
    mtspr (SPR_ITLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
    mtspr (SPR_ITLBMR_BASE(0) + i, match_space | SPR_ITLBMR_V);
    mtspr (SPR_ITLBTR_BASE(0) + i, ta | ITLB_PR_NOLIMIT);
    mtspr (SPR_ITLBTR_BASE(0) + i, translate_space | ITLB_PR_NOLIMIT);
  }
  }
 
 
  /* Set itlb permisions */
  /* Set itlb permisions */
  itlb_val = ITLB_PR_NOLIMIT;
  itlb_val = ITLB_PR_NOLIMIT;
 
 
  /* Write test program */
  /* Write test program */
  for (i = TLB_TEXT_SET_NB; i < ITLB_SETS; i++) {
  for (i = TLB_TEXT_SET_NB; i < ITLB_SETS; i++) {
    copy_jump (RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE) + (i*0x10));
    translate_space = (RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE) + (i*0x10));
 
    //printf("writing app to 0x%8lx to be translated in set %d\n",translate_space, i);
 
    REG32(translate_space) = OR32_L_JR_R9;
 
    REG32(translate_space + 4) = OR32_L_NOP;
 
    // Now flush this in case DC isn't on write-through
 
    mtspr(SPR_DCBFR, translate_space);
 
    mtspr(SPR_DCBFR, translate_space+4);
  }
  }
 
 
  /* Set one to one translation of the last way of ITLB */
  /* Set one to one translation of the last ways of ITLB */
  for (i = TLB_TEXT_SET_NB; i < ITLB_SETS; i++) {
  for (i = TLB_TEXT_SET_NB; i < ITLB_SETS; i++) {
    ea = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
    translate_space = (RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE) + (i*0x10));
    ta = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
    //printf("translate_space: 0x%8lx set %d\n",translate_space, i);
    mtspr (SPR_ITLBMR_BASE(ITLB_WAYS - 1) + i, ea | SPR_ITLBMR_V);
    mtspr (SPR_ITLBMR_BASE(ITLB_WAYS - 1) + i, translate_space | SPR_ITLBMR_V);
    mtspr (SPR_ITLBTR_BASE(ITLB_WAYS - 1) + i, ta | ITLB_PR_NOLIMIT);
    mtspr (SPR_ITLBTR_BASE(ITLB_WAYS - 1) + i,
 
           translate_space | ITLB_PR_NOLIMIT);
  }
  }
 
 
  /* Enable IMMU */
  /* Enable IMMU */
  immu_enable();
  immu_enable();
 
 
  /* Check the pattern */
  /* Check the tranlsation works by jumping there */
  for (i = TLB_TEXT_SET_NB; i < ITLB_SETS; i++) {
  for (i = TLB_TEXT_SET_NB; i < ITLB_SETS; i++) {
    call (RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE) + (i*0x10));
    translate_space = (RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE) + (i*0x10));
  }
    //printf("calling 0x%.8lx - should use set %d\n",translate_space, i);
 
    call (translate_space);
  /* Set FLASH_END -> RAM_START + (RAM_SIZE/2) translation */
 
  for (i = TLB_TEXT_SET_NB; i < ITLB_SETS; i++) {
 
    ea = FLASH_START + FLASH_SIZE + i*PAGE_SIZE;
 
    ta = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
 
    mtspr (SPR_ITLBMR_BASE(ITLB_WAYS - 1) + i, ea | SPR_ITLBMR_V);
 
    mtspr (SPR_ITLBTR_BASE(ITLB_WAYS - 1) + i, ta | ITLB_PR_NOLIMIT);
 
  }
 
 
 
  /* Check the pattern */
 
  for (i = TLB_TEXT_SET_NB; i < ITLB_SETS; i++) {
 
    call (FLASH_START + FLASH_SIZE + (i*PAGE_SIZE) + (i*0x10));
 
  }
  }
 
 
  /* Set hi -> lo, lo -> hi translation */
  /* Set hi -> lo, lo -> hi translation */
  for (i = TLB_TEXT_SET_NB; i < ITLB_SETS; i++) {
  for (i = TLB_TEXT_SET_NB; i < ITLB_SETS; i++) {
    ea = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
    match_space = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
    ta = RAM_START + (RAM_SIZE/2) + ((ITLB_SETS - i - 1 + TLB_TEXT_SET_NB)*PAGE_SIZE);
    translate_space = RAM_START + (RAM_SIZE/2) +
    mtspr (SPR_ITLBMR_BASE(ITLB_WAYS - 1) + i, ea | SPR_ITLBMR_V);
      (((ITLB_SETS-1)+TLB_TEXT_SET_NB - i)*PAGE_SIZE);
    mtspr (SPR_ITLBTR_BASE(ITLB_WAYS - 1) + i, ta | ITLB_PR_NOLIMIT);
    printf("setting itlb set %d match -> trans = 0x%.8lx -> 0x%.8lx\n",
 
           i, match_space, translate_space);
 
    mtspr (SPR_ITLBMR_BASE(ITLB_WAYS - 1) + i, match_space | SPR_ITLBMR_V);
 
    mtspr (SPR_ITLBTR_BASE(ITLB_WAYS - 1) + i, translate_space|ITLB_PR_NOLIMIT);
  }
  }
 
 
  /* Check the pattern */
  /* Check the pattern */
  for (i = TLB_TEXT_SET_NB; i < ITLB_SETS; i++) {
  for (i = TLB_TEXT_SET_NB; i < ITLB_SETS; i++) {
    call (RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE) + ((ITLB_SETS - i - 1 + TLB_TEXT_SET_NB)*0x10));
    match_space = RAM_START + (RAM_SIZE/2) + (((ITLB_SETS-1)+TLB_TEXT_SET_NB - i)*PAGE_SIZE) + (i*0x10);
 
    printf("immu hi->lo check - calling 0x%.8lx\n",match_space);
 
    call(match_space);
  }
  }
 
 
  /* Disable IMMU */
  /* Disable IMMU */
  immu_disable ();
  immu_disable ();
 
 
  /* Check the pattern */
  /* Check the pattern */
  for (i = TLB_TEXT_SET_NB; i < ITLB_SETS; i++) {
  for (i = TLB_TEXT_SET_NB; i < ITLB_SETS; i++) {
    call (RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE) + (i*0x10));
    translate_space = (RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE) + (i*0x10));
 
    //call (RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE) + (i*0x10));
 
    //printf("immu disabled check of set %d - calling 0x%.8lx\n",i, translate_space);
 
    call (translate_space);
  }
  }
 
 
 
  printf("OK\n");
 
  printf("-------------------------------------------\n");
 
 
  return 0;
  return 0;
}
}
 
 
/* EA match register test
/* EA match register test
   Shifting one in ITLBMR and performing accesses to boundaries
   Shifting one in ITLBMR and performing accesses to boundaries
   of the page, checking the triggering of exceptions */
   of the page, checking the triggering of exceptions */
int itlb_match_test (int way, int set)
int itlb_match_test (int way, int set)
{
{
  int i, j;
  int i, j;
  unsigned long add, t_add;
  unsigned long add;
  unsigned long ea, ta;
  unsigned long ea, ta;
 
 
 
  printf("itlb_match_test\n");
 
 
  /* Disable IMMU */
  /* Disable IMMU */
  immu_disable();
  immu_disable();
 
 
  /* Invalidate all entries in ITLB */
  /* Invalidate all entries in ITLB */
  for (i = 0; i < ITLB_WAYS; i++) {
  for (i = 0; i < ITLB_WAYS; i++) {
Line 967... Line 1142...
    }
    }
  }
  }
 
 
  /* Set one to one translation for the use of this program */
  /* Set one to one translation for the use of this program */
  for (i = 0; i < TLB_TEXT_SET_NB; i++) {
  for (i = 0; i < TLB_TEXT_SET_NB; i++) {
    ea = FLASH_START + (i*PAGE_SIZE);
          ea = /*TEXT_START_ADD +*/ (i*PAGE_SIZE);
    ta = FLASH_START + (i*PAGE_SIZE);
          ta = /*TEXT_START_ADD +*/ (i*PAGE_SIZE);
    mtspr (SPR_ITLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
    mtspr (SPR_ITLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
    mtspr (SPR_ITLBTR_BASE(0) + i, ta | ITLB_PR_NOLIMIT);
    mtspr (SPR_ITLBTR_BASE(0) + i, ta | ITLB_PR_NOLIMIT);
  }
  }
 
 
  /* Set dtlb permisions */
  /* Set dtlb permisions */
  itlb_val = ITLB_PR_NOLIMIT;
  itlb_val = ITLB_PR_NOLIMIT;
 
 
  /* Set pattern */
 
  copy_jump (RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE) - 8);
  // Write program which will just return into these places
  copy_jump (RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE));
  unsigned long translate_space = RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE);
  copy_jump (RAM_START + (RAM_SIZE/2) + (set + 1)*PAGE_SIZE - 8);
  //copy_jump (RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE) - 8);
  copy_jump (RAM_START + (RAM_SIZE/2) + (set + 1)*PAGE_SIZE);
  REG32(translate_space-8) = OR32_L_JR_R9;
 
  REG32(translate_space-4) = OR32_L_NOP;
 
  //copy_jump (RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE));
 
  REG32(translate_space) = OR32_L_JR_R9;
 
  REG32(translate_space+4) = OR32_L_NOP;
 
  //copy_jump (RAM_START + (RAM_SIZE/2) + (set + 1)*PAGE_SIZE - 8);
 
  REG32(translate_space + PAGE_SIZE - 8) = OR32_L_JR_R9;
 
  REG32(translate_space + PAGE_SIZE - 4) = OR32_L_NOP;
 
  //copy_jump (RAM_START + (RAM_SIZE/2) + (set + 1)*PAGE_SIZE);
 
  REG32(translate_space + PAGE_SIZE) = OR32_L_JR_R9;
 
  REG32(translate_space + PAGE_SIZE + 4) = OR32_L_NOP;
 
  // Flush these areas incase cache doesn't write them through immediately
 
  mtspr(SPR_DCBFR, translate_space-8);
 
  mtspr(SPR_DCBFR, translate_space);
 
  mtspr(SPR_DCBFR, translate_space+4);
 
  mtspr(SPR_DCBFR, translate_space + PAGE_SIZE - 8);
 
  mtspr(SPR_DCBFR, translate_space + PAGE_SIZE - 4);
 
  mtspr(SPR_DCBFR, translate_space + PAGE_SIZE);
 
  mtspr(SPR_DCBFR, translate_space + PAGE_SIZE + 4);
 
 
  /* Enable IMMU */
  /* Enable IMMU */
  immu_enable();
  immu_enable();
 
 
  /* Shifting one in ITLBMR */
  /* Shifting one in ITLBMR */
  i = 0;
  i = 0;
  add = (PAGE_SIZE*ITLB_SETS);
  add = (PAGE_SIZE*ITLB_SETS);
  t_add = add + (set*PAGE_SIZE);
  //t_add = add + (set*PAGE_SIZE);
 
  // Space we'll access and expect the MMU to translate our requests
 
  unsigned long match_space = (PAGE_SIZE*DTLB_SETS) + (set*PAGE_SIZE);
  while (add != 0x00000000) {
  while (add != 0x00000000) {
    mtspr (SPR_ITLBMR_BASE(way) + set, t_add | SPR_ITLBMR_V);
    mtspr (SPR_ITLBMR_BASE(way) + set,  match_space | SPR_ITLBMR_V);
    mtspr (SPR_ITLBTR_BASE(way) + set, (RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE)) | ITLB_PR_NOLIMIT);
    mtspr (SPR_ITLBTR_BASE(way) + set,  translate_space | ITLB_PR_NOLIMIT);
 
 
    /* Reset ITLB miss counter and EA */
    /* Reset ITLB miss counter and EA */
    itlb_miss_count = 0;
    itlb_miss_count = 0;
    itlb_miss_ea = 0;
    itlb_miss_ea = 0;
 
 
    if (((t_add < RAM_START) || (t_add >= DATA_END_ADD)) && ((t_add < FLASH_START) || (t_add >= TEXT_END_ADD))) {
    //if (((t_add < RAM_START) || (t_add >= DATA_END_ADD)) && ((t_add < TEXT_START_ADD) || (t_add >= TEXT_END_ADD))) {
 
 
      /* Jump on last address of previous page */
      /* Jump on last address of previous page */
      call (t_add - 8);
      call (match_space - 8);
      ASSERT(itlb_miss_count == 1);
      ASSERT(itlb_miss_count == 1);
 
 
      /* Jump on first address of the page */
      /* Jump on first address of the page */
      call (t_add);
      call (match_space);
      ASSERT(itlb_miss_count == 1);
      ASSERT(itlb_miss_count == 1);
 
 
      /* Jump on last address of the page */
      /* Jump on last address of the page */
      call (t_add + PAGE_SIZE - 8);
      call (match_space + PAGE_SIZE - 8);
      ASSERT(itlb_miss_count == 1);
      ASSERT(itlb_miss_count == 1);
 
 
      /* Jump on first address of next page */
      /* Jump on first address of next page */
      call (t_add + PAGE_SIZE);
      call (match_space + PAGE_SIZE);
      ASSERT(itlb_miss_count == 2);
      ASSERT(itlb_miss_count == 2);
    }
      //}
 
 
    i++;
    i++;
    add = (PAGE_SIZE*ITLB_SETS) << i;
    add = (PAGE_SIZE*ITLB_SETS) << i;
    t_add = add + (set*PAGE_SIZE);
    match_space = add + (set*PAGE_SIZE);
 
 
    for (j = 0; j < ITLB_WAYS; j++) {
    for (j = 0; j < ITLB_WAYS; j++) {
      mtspr (SPR_ITLBMR_BASE(j) + ((set - 1) & (ITLB_SETS - 1)), 0);
      mtspr (SPR_ITLBMR_BASE(j) + ((set - 1) & (ITLB_SETS - 1)), 0);
      mtspr (SPR_ITLBMR_BASE(j) + ((set + 1) & (ITLB_SETS - 1)), 0);
      mtspr (SPR_ITLBMR_BASE(j) + ((set + 1) & (ITLB_SETS - 1)), 0);
    }
    }
  }
  }
 
 
 
  printf("OK\n");
 
  printf("-------------------------------------------\n");
 
 
  /* Disable IMMU */
  /* Disable IMMU */
  immu_disable();
  immu_disable();
 
 
  return 0;
  return 0;
}
}
Line 1041... Line 1239...
int itlb_valid_bit_test (int set)
int itlb_valid_bit_test (int set)
{
{
  int i, j;
  int i, j;
  unsigned long ea, ta;
  unsigned long ea, ta;
 
 
 
  printf("itlb_valid_bit_test set = %d\n", set);
 
 
  /* Disable IMMU */
  /* Disable IMMU */
  immu_disable();
  immu_disable();
 
 
  /* Invalidate all entries in ITLB */
  /* Invalidate all entries in ITLB */
  for (i = 0; i < ITLB_WAYS; i++) {
  for (i = 0; i < ITLB_WAYS; i++) {
Line 1054... Line 1254...
    }
    }
  }
  }
 
 
  /* Set one to one translation for the use of this program */
  /* Set one to one translation for the use of this program */
  for (i = 0; i < TLB_TEXT_SET_NB; i++) {
  for (i = 0; i < TLB_TEXT_SET_NB; i++) {
    ea = FLASH_START + (i*PAGE_SIZE);
          ea = /*TEXT_START_ADD +*/ (i*PAGE_SIZE);
    ta = FLASH_START + (i*PAGE_SIZE);
          ta = /*TEXT_START_ADD +*/ (i*PAGE_SIZE);
    mtspr (SPR_ITLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
    mtspr (SPR_ITLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
    mtspr (SPR_ITLBTR_BASE(0) + i, ta | ITLB_PR_NOLIMIT);
    mtspr (SPR_ITLBTR_BASE(0) + i, ta | ITLB_PR_NOLIMIT);
  }
  }
 
 
  /* Reset ITLB miss counter and EA */
  /* Reset ITLB miss counter and EA */
Line 1067... Line 1267...
  itlb_miss_ea = 0;
  itlb_miss_ea = 0;
 
 
  /* Set itlb permisions */
  /* Set itlb permisions */
  itlb_val = ITLB_PR_NOLIMIT;
  itlb_val = ITLB_PR_NOLIMIT;
 
 
  /* Resetv ITLBMR for every way */
  /* Resetv ITLBMR for every way after the program code */
  for (i = 0; i < ITLB_WAYS; i++) {
  for (i = TLB_TEXT_SET_NB; i < ITLB_WAYS; i++) {
    mtspr (SPR_ITLBMR_BASE(i) + set, 0);
    mtspr (SPR_ITLBMR_BASE(i) + set, 0);
  }
  }
 
 
  /* Enable IMMU */
  /* Enable IMMU */
  immu_enable();
  immu_enable();
 
  // Address we'll jump to and expect it to be translated
 
  unsigned long match_space = (PAGE_SIZE*ITLB_SETS) + (set*PAGE_SIZE);
 
  // Address that we will actually access
 
  unsigned long translate_space = RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE);
  /* Perform jumps to address, that is not in ITLB */
  /* Perform jumps to address, that is not in ITLB */
  for (i = 0; i < ITLB_WAYS; i++) {
  printf("writing program to 0x%.8lx\n", translate_space);
    TEST_JUMP(RAM_START + RAM_SIZE + (i*ITLB_SETS*PAGE_SIZE) + (set*PAGE_SIZE));
  REG32(translate_space) = OR32_L_JR_R9;
 
  REG32(translate_space+4) = OR32_L_NOP;
 
  mtspr(SPR_DCBFR, translate_space);
 
  mtspr(SPR_DCBFR, translate_space+4);
 
  printf("jumping to 0x%.8lx, should be itlb miss\n",match_space);
 
  call (match_space);
 
 
    /* Check if there was ITLB miss */
    /* Check if there was ITLB miss */
    ASSERT(itlb_miss_count == (i + 1));
  ASSERT(itlb_miss_count == 1);
    ASSERT(itlb_miss_ea == (RAM_START + RAM_SIZE + (i*ITLB_SETS*PAGE_SIZE) + (set*PAGE_SIZE)));
  ASSERT(itlb_miss_ea == match_space);
  }
 
 
 
  /* Reset ITLB miss counter and EA */
  /* Reset ITLB miss counter and EA */
  itlb_miss_count = 0;
  itlb_miss_count = 0;
  itlb_miss_ea = 0;
  itlb_miss_ea = 0;
 
  printf("jumping to 0x%.8lx again - should not be a miss\n", match_space);
  /* Perform jumps to address, that is now in ITLB */
  /* Perform jumps to address, that is now in ITLB */
  for (i = 0; i < ITLB_WAYS; i++) {
  call (match_space);
    TEST_JUMP(RAM_START + RAM_SIZE + (i*ITLB_SETS*PAGE_SIZE) + (set*PAGE_SIZE));
 
 
 
    /* Check if there was ITLB miss */
    /* Check if there was ITLB miss */
    ASSERT(itlb_miss_count == 0);
    ASSERT(itlb_miss_count == 0);
  }
 
 
 
  /* Reset valid bits */
  /* Reset valid bits */
  for (i = 0; i < ITLB_WAYS; i++) {
  for (i = 0; i < ITLB_WAYS; i++) {
    mtspr (SPR_ITLBMR_BASE(i) + set, mfspr (SPR_ITLBMR_BASE(i) + set) & ~SPR_ITLBMR_V);
    mtspr (SPR_ITLBMR_BASE(i) + set, mfspr (SPR_ITLBMR_BASE(i) + set) & ~SPR_ITLBMR_V);
  }
  }
 
  printf("jumping to 0x%.8lx again - mmu entries invalidated, so should be a miss\n", match_space);
  /* Perform jumps to address, that is now in ITLB but is invalid */
  /* Perform jumps to address, that is now in ITLB but is invalid */
  for (i = 0; i < ITLB_WAYS; i++) {
  call (match_space);
    TEST_JUMP(RAM_START + RAM_SIZE + (i*ITLB_SETS*PAGE_SIZE) + (set*PAGE_SIZE));
 
 
 
    /* Check if there was ITLB miss */
    /* Check if there was ITLB miss */
    ASSERT(itlb_miss_count == (i + 1));
  ASSERT(itlb_miss_count == 1);
    ASSERT(itlb_miss_ea == (RAM_START + RAM_SIZE + (i*ITLB_SETS*PAGE_SIZE) + (set*PAGE_SIZE)));
  ASSERT(itlb_miss_ea == match_space);
  }
 
 
 
  /* Disable IMMU */
  /* Disable IMMU */
  immu_disable ();
  immu_disable ();
 
 
 
  printf("OK\n");
 
  printf("-------------------------------------------\n");
 
 
  return 0;
  return 0;
}
}
 
 
/* Permission test
/* Permission test
   Set various permissions, perform r/w access
   Set various permissions, perform r/w access
   in user and supervisor mode and check triggering
in user and supervisor mode and chack triggering
   of page fault exceptions */
   of page fault exceptions */
int itlb_premission_test (int set)
int itlb_permission_test (int set)
{
{
  int i, j;
  int i, j;
  unsigned long ea, ta;
  unsigned long ea, ta;
 
 
 
  printf("itlb_permission_test set = %d\n", set);
 
 
  /* Disable IMMU */
  /* Disable IMMU */
  immu_disable();
  immu_disable();
 
 
  /* Invalidate all entries in ITLB */
  /* Invalidate all entries in ITLB */
  for (i = 0; i < ITLB_WAYS; i++) {
  for (i = 0; i < ITLB_WAYS; i++) {
Line 1138... Line 1346...
    }
    }
  }
  }
 
 
  /* Set one to one translation for the use of this program */
  /* Set one to one translation for the use of this program */
  for (i = 0; i < TLB_TEXT_SET_NB; i++) {
  for (i = 0; i < TLB_TEXT_SET_NB; i++) {
    ea = FLASH_START + (i*PAGE_SIZE);
          ea = /*TEXT_START_ADD +*/ (i*PAGE_SIZE);
    ta = FLASH_START + (i*PAGE_SIZE);
          ta = /*TEXT_START_ADD +*/ (i*PAGE_SIZE);
    mtspr (SPR_ITLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
    mtspr (SPR_ITLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
    mtspr (SPR_ITLBTR_BASE(0) + i, ta | ITLB_PR_NOLIMIT);
    mtspr (SPR_ITLBTR_BASE(0) + i, ta | ITLB_PR_NOLIMIT);
  }
  }
 
 
  /* Testing page */
  // Address that we will actually access
  ea = RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE);
  unsigned long match_space = RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE);
 
 
  /* Set match register */
  /* Set match register */
  mtspr (SPR_ITLBMR_BASE(ITLB_WAYS - 1) + set, ea | SPR_ITLBMR_V);
  mtspr (SPR_ITLBMR_BASE(ITLB_WAYS - 1) + set, match_space | SPR_ITLBMR_V);
 
 
  /* Reset page fault counter and EA */
  /* Reset page fault counter and EA */
  ipage_fault_count = 0;
  ipage_fault_count = 0;
  ipage_fault_ea = 0;
  ipage_fault_ea = 0;
 
 
  /* Copy the code */
  /* Copy the code */
  copy_jump (ea);
  REG32(match_space+0x0) = OR32_L_JR_R9;
  copy_jump (ea + 8);
  REG32(match_space+0x4) = OR32_L_NOP;
 
  REG32(match_space+0x8) = OR32_L_JR_R9;
 
  REG32(match_space+0xc) = OR32_L_NOP;
 
  mtspr(SPR_DCBFR, match_space);
 
  mtspr(SPR_DCBFR, match_space+4);
 
  mtspr(SPR_DCBFR, match_space+8);
 
  mtspr(SPR_DCBFR, match_space+12);
 
 
  /* Enable IMMU */
  /* Enable IMMU */
  immu_enable ();
  immu_enable ();
 
 
  /* Execute supervisor */
  /* Execute supervisor */
 
  printf("execute disable for supervisor - should cause ipage fault\n");
  itlb_val = SPR_ITLBTR_CI | SPR_ITLBTR_SXE;
  itlb_val = SPR_ITLBTR_CI | SPR_ITLBTR_SXE;
  mtspr (SPR_ITLBTR_BASE(ITLB_WAYS - 1) + set, ea | (ITLB_PR_NOLIMIT & ~SPR_ITLBTR_SXE));
  mtspr (SPR_ITLBTR_BASE(ITLB_WAYS - 1) + set, match_space | (ITLB_PR_NOLIMIT & ~SPR_ITLBTR_SXE));
 
  printf("calling address 0x%.8lx\n", match_space);
  call (ea);
  call (match_space);
  ASSERT(ipage_fault_count == 1);
  ASSERT(ipage_fault_count == 1);
  call (ea + 8);
  call (match_space + 8);
  ASSERT(ipage_fault_count == 1);
  ASSERT(ipage_fault_count == 1);
 
 
  /* Execute user */
  /* Execute user */
 
  printf("execute disable for user - should cause ipage fault\n");
  itlb_val = SPR_ITLBTR_CI | SPR_ITLBTR_UXE;
  itlb_val = SPR_ITLBTR_CI | SPR_ITLBTR_UXE;
  mtspr (SPR_ITLBTR_BASE(ITLB_WAYS - 1) + set, ea | (ITLB_PR_NOLIMIT & ~SPR_ITLBTR_UXE));
  mtspr (SPR_ITLBTR_BASE(ITLB_WAYS - 1) + set, match_space | (ITLB_PR_NOLIMIT & ~SPR_ITLBTR_UXE));
 
 
  /* Set user mode */
  /* Set user mode */
 
  printf("disabling supervisor mode\n");
  mtspr (SPR_SR, mfspr (SPR_SR) & ~SPR_SR_SM);
  mtspr (SPR_SR, mfspr (SPR_SR) & ~SPR_SR_SM);
 
  printf("calling address 0x%.8lx\n", match_space);
  call (ea);
  printf("instruction at jump space: 0x%.8lx\n",REG32(match_space));
 
  call (match_space);
  ASSERT(ipage_fault_count == 2);
  ASSERT(ipage_fault_count == 2);
  call (ea + 8);
  call (match_space + 8);
  ASSERT(ipage_fault_count == 2);
  ASSERT(ipage_fault_count == 2);
 
 
  /* Trigger sys call exception to enable supervisor mode again */
  /* Trigger sys call exception to enable supervisor mode again */
  sys_call ();
  sys_call ();
 
 
  /* Disable IMMU */
  /* Disable IMMU */
  immu_disable ();
  immu_disable ();
 
 
 
  printf("OK\n");
 
  printf("-------------------------------------------\n");
 
 
  return 0;
  return 0;
}
}
 
 
/* Instruction cache inhibit bit test
int main (void)
   Set and clear CI bit and check the pattern. */
 
int itlb_ci_test(void)
 
{
{
  int i, j;
  int i, j;
  unsigned long ea, ta, ret;
 
 
 
  /* Disable IMMU */
 
  immu_disable();
 
 
 
  /* Invalidate all entries in DTLB */
 
  for (i = 0; i < ITLB_WAYS; i++) {
 
    for (j = 0; j < ITLB_SETS; j++) {
 
      mtspr (SPR_ITLBMR_BASE(i) + j, 0);
 
      mtspr (SPR_ITLBTR_BASE(i) + j, 0);
 
    }
 
  }
 
 
 
  /* Set one to one translation for the use of this program */
 
  for (i = 0; i < TLB_TEXT_SET_NB; i++) {
 
    ea = FLASH_START + (i*PAGE_SIZE);
 
    ta = FLASH_START + (i*PAGE_SIZE);
 
    mtspr (SPR_ITLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
 
    mtspr (SPR_ITLBTR_BASE(0) + i, ta | ITLB_PR_NOLIMIT);
 
  }
 
 
 
  /* Testing page */
  text_begin_addr = (unsigned long)&_src_beg;
  ea = RAM_START + (RAM_SIZE/2) + (TLB_TEXT_SET_NB*PAGE_SIZE);
  end_data_addr = (unsigned long)&_ram_end;
 
 
  ret = lo_itlb_ci_test (ea, TLB_TEXT_SET_NB);
  TLB_TEXT_SET_NB =  TLB_DATA_SET_NB = (end_data_addr+PAGE_SIZE) / PAGE_SIZE;
  ASSERT(ret == 0);
 
 
 
  return 0;
  // Some tests check page below, and if this page corresponds with set being
}
  // used by program's data section, then could mean an incorrect mapping ends
 
  // up in the TLB cache, which causes the program to do bad things, so to be
int main (void)
  // safe incrementing the number of pages being used by the program.
{
  TLB_TEXT_SET_NB++;
  int i, j;
  TLB_DATA_SET_NB++;
 
 
  i = j = 0; /* Get rid of warnings */
  i = j = 0; /* Get rid of warnings */
 
 
  /* Register bus error handler */
  /* Register bus error handler */
  excpt_buserr = (unsigned long)bus_err_handler;
  excpt_buserr = (unsigned long)bus_err_handler;
Line 1241... Line 1439...
  excpt_illinsn = (unsigned long)ill_insn_handler;
  excpt_illinsn = (unsigned long)ill_insn_handler;
 
 
  /* Register illegal insn handler */
  /* Register illegal insn handler */
  excpt_syscall = (unsigned long)sys_call_handler;
  excpt_syscall = (unsigned long)sys_call_handler;
 
 
#if 1
#if DO_DMMU_TESTS==1
 
 
  /* Translation test */
  /* Translation test */
  dtlb_translation_test ();
  dtlb_translation_test ();
 
 
 
  printf("DTLB translation tests OK\n");
 
 
  /* Virtual address match test */
  /* Virtual address match test */
#ifndef RTL_SIM
 
  for (j = 0; j < DTLB_WAYS; j++) {
  for (j = 0; j < DTLB_WAYS; j++) {
 
#ifdef SHORT_TEST
 
    for (i = TLB_DATA_SET_NB; i < (TLB_DATA_SET_NB+4 - 1); i++)
 
#else
    for (i = TLB_DATA_SET_NB; i < (DTLB_SETS - 1); i++)
    for (i = TLB_DATA_SET_NB; i < (DTLB_SETS - 1); i++)
 
#endif
      dtlb_match_test (j, i);
      dtlb_match_test (j, i);
  }
  }
#else
  printf("DTLB match tests OK\n");
  dtlb_match_test (0, DTLB_SETS - 2);
 
#endif
 
 
 
  /* Valid bit testing */
  /* Valid bit testing */
#ifndef RTL_SIM
 
  for (i = TLB_DATA_SET_NB; i < (DTLB_SETS - 1); i++)
#ifdef SHORT_TEST
    dtlb_valid_bit_test (i);
  for (i = TLB_DATA_SET_NB; i < (TLB_DATA_SET_NB+4 - 1); i++)
#else
#else
  dtlb_valid_bit_test (DTLB_SETS - 2);
  for (i = TLB_DATA_SET_NB; i < (DTLB_SETS - 1); i++)
#endif
#endif
 
      dtlb_valid_bit_test (i);
 
 
 
  printf("DTLB valid bit tests OK\n");
 
 
  /* Permission test */
  /* Permission test */
#ifndef RTL_SIM
#ifdef SHORT_TEST
  for (i = TLB_DATA_SET_NB; i < (DTLB_SETS - 1); i++)
  for (i = TLB_DATA_SET_NB; i < (TLB_DATA_SET_NB+4 - 1); i++)
    dtlb_premission_test (i);
 
#else
#else
  dtlb_premission_test (DTLB_SETS - 2);
  for (i = TLB_DATA_SET_NB; i < (DTLB_SETS - 1); i++)
#endif
#endif
 
    dtlb_permission_test (i);
 
 
 
  printf("DTLB permission bit tests OK\n");
 
 
  dtlb_ci_test();
  /* Data cache test - Disabled for now */
 
 
 
#if 0 
 
#ifdef SHORT_TEST
 
  for (i = TLB_DATA_SET_NB; i < (TLB_DATA_SET_NB+4 - 1); i++)
 
#else
 
  for (i = TLB_DATA_SET_NB; i < (DTLB_SETS - 2); i++)
 
#endif
 
    dtlb_dcache_test (i);
#endif
#endif
 
 
#if 1
#endif /* end of no DTLB tests */
 
 
 
 
  /* Translation test */
  /* Translation test */
  itlb_translation_test ();
  itlb_translation_test ();
 
 
 
  printf("ITLB translation tests OK\n");
 
 
  /* Virtual address match test */
  /* Virtual address match test */
#ifndef RTL_SIM
 
  for (j = 0; j < DTLB_WAYS; j++) {
  for (j = 0; j < DTLB_WAYS; j++) {
    for (i = TLB_TEXT_SET_NB + 1; i < (DTLB_SETS - 1); i++)
#ifdef SHORT_TEST
      itlb_match_test (j, i);
  for (i = TLB_DATA_SET_NB + 1; i < (TLB_DATA_SET_NB+4 - 1); i++)
  }
 
#else
#else
  itlb_match_test (0, DTLB_SETS - 2);
  for (i = TLB_DATA_SET_NB + 1; i < (ITLB_SETS - 1); i++)
#endif
#endif
 
      itlb_match_test (j, i);
 
  }
 
 
 
  printf("ITLB match tests OK\n");
 
 
  /* Valid bit testing */
  /* Valid bit testing */
#ifndef RTL_SIM
#ifdef SHORT_TEST
  for (i = TLB_TEXT_SET_NB; i < (ITLB_SETS); i++)
  for (i = TLB_DATA_SET_NB; i < (TLB_DATA_SET_NB+4 - 1); i++)
    itlb_valid_bit_test (i);
 
#else
#else
  itlb_valid_bit_test (ITLB_SETS-1);
  for (i = TLB_DATA_SET_NB; i < (ITLB_SETS - 1); i++)
#endif
#endif
 
    itlb_valid_bit_test (i);
 
 
 
  printf("ITLB valid bit tests OK\n");
 
 
 
 
  /* Permission test */
  /* Permission test */
#ifndef RTL_SIM
#ifdef SHORT_TEST
  for (i = TLB_TEXT_SET_NB; i < (ITLB_SETS - 1); i++)
  for (i = TLB_TEXT_SET_NB; i < (TLB_TEXT_SET_NB + 4); i++)
    itlb_premission_test (i);
 
#else
#else
  itlb_premission_test (ITLB_SETS - 2);
  for (i = TLB_TEXT_SET_NB; i < (ITLB_SETS - 1); i++)
#endif
#endif
 
    itlb_permission_test (i);
 
 
  itlb_ci_test();
  printf("ITLB permission tests OK\n");
#endif
 
 
 
 
  printf("Tests completed\n");
  report (0xdeaddead);
  report (0xdeaddead);
 
  report (0x8000000d);
  exit (0);
  exit (0);
  return 0;
 
}
}
 
 
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.