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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_47/] [or1ksim/] [testbench/] [mmu.c] - Diff between revs 413 and 415

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 413 Rev 415
Line 44... Line 44...
                          SPR_DTLBTR_SWE  )
                          SPR_DTLBTR_SWE  )
 
 
/* 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) 
#define TEST_JUMP(x) testjump( ((x) & (RAM_SIZE/2 - 1)) + DATA_END_ADD, (x))
 
 
/* Extern functions */
/* 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 void testjump(unsigned long phy_addr, unsigned long virt_addr);
 
 
 
/* Local functions prototypes */
 
void dmmu_disable (void);
 
void immu_disable (void);
 
 
/* Global variables */
/* Global variables */
extern unsigned long ram_end;
extern unsigned long ram_end;
 
 
/* DTLB mode status */
/* DTLB mode status */
Line 60... Line 65...
 
 
/* ITLB mode status */
/* ITLB mode status */
unsigned long itlb_val;
unsigned long itlb_val;
 
 
/* DTLB miss counter */
/* DTLB miss counter */
int dtlb_miss_count;
volatile int dtlb_miss_count;
 
 
/* ITLB miss counter */
/* ITLB miss counter */
int itlb_miss_count;
volatile int itlb_miss_count;
 
 
/* EA of last DTLB miss exception */
/* EA of last DTLB miss exception */
unsigned long dtlb_miss_ea;
unsigned long dtlb_miss_ea;
 
 
/* EA of last ITLB miss exception */
/* EA of last ITLB miss exception */
unsigned long itlb_miss_ea;
unsigned long itlb_miss_ea;
 
 
/*inline static
 
unsigned int dtlb_write_entry (int way, int entry, unsigned int val)
 
{
 
  mtspr (SPR_DTLBMR_BASE(way) + entry, val);
 
}
 
*/
 
 
 
void fail (char *func, int line)
void fail (char *func, int line)
{
{
#ifndef __FUNCTION__
#ifndef __FUNCTION__
#define __FUNCTION__ "?"
#define __FUNCTION__ "?"
#endif
#endif
 
  immu_disable ();
 
  dmmu_disable ();
  printf ("Test failed in %s:%i\n", func, line);
  printf ("Test failed in %s:%i\n", func, line);
  report(0xeeeeeeee);
  report(0xeeeeeeee);
  exit (1);
  exit (1);
}
}
 
 
 
/* Bus error exception handler */
 
void bus_err_handler (void)
 
{
 
  /* This shouldn't happend */
 
  printf ("Test failed: Bus error\n");
 
  report (0xeeeeeeee);
 
  exit (1);
 
}
 
 
 
/* Illegal insn exception handler */
 
void ill_insn_handler (void)
 
{
 
  /* This shouldn't happend */
 
  printf ("Test failed: Illegal insn\n");
 
  report (0xeeeeeeee);
 
  exit (1);
 
}
 
 
/* DTLB miss exception handler */
/* DTLB miss exception handler */
void dtlb_miss_handler (void)
void dtlb_miss_handler (void)
{
{
  unsigned long ea, ta, tlbtr;
  unsigned long ea, ta, tlbtr;
  int set, way = 0;
  int set, way = 0;
Line 109... Line 127...
    }
    }
  }
  }
 
 
printf("ea = %.8lx 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)) {
  if (((RAM_START <= ea) && (ea < DATA_END_ADD) ) || ((FLASH_START <= 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_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) | TLB_PR_NOLIMIT);
    mtspr (SPR_DTLBTR_BASE(way) + set, (ea & SPR_DTLBTR_PPN) | TLB_PR_NOLIMIT);
    return;
    return;
  }
  }
Line 121... Line 139...
  /* 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 */
  /* Whatever access is in progress, translated address have to point to physical RAM */
  ta = (ea & ((RAM_SIZE/2) - 1)) + DATA_END_ADD;
  ta = (ea & ((RAM_SIZE/2) - 1)) + RAM_START + (RAM_SIZE/2);
printf("ta = %.8lx\n", ta);
 
 
 
  /* Set appropriate TLB entry */
 
  switch (dtlb_val & TLB_CODE_MASK) {
 
    case TLB_CODE_ONE_TO_ONE:
 
      tlbtr = (ta & SPR_DTLBTR_PPN) | (dtlb_val & TLB_PR_MASK);
      tlbtr = (ta & SPR_DTLBTR_PPN) | (dtlb_val & TLB_PR_MASK);
printf("1: tlbtr = %.8lx\n", tlbtr);
printf("ta = %.8lx\n", ta);
      break;
 
    case TLB_CODE_PLUS_ONE_PAGE:
 
      if ((ta + PAGE_SIZE) >= (RAM_START + RAM_SIZE))
 
        /* Wrapp last page */
 
        tlbtr = (((ta & ((RAM_SIZE/2) - 1)) + RAM_START + (RAM_SIZE/2)) & SPR_DTLBTR_PPN) | (dtlb_val & TLB_PR_MASK);
 
      else
 
        tlbtr = ((ta + PAGE_SIZE) & SPR_DTLBTR_PPN) | (dtlb_val & TLB_PR_MASK);
 
printf("2: tlbtr = %.8lx\n", tlbtr);
 
      break;
 
    case TLB_CODE_MINUS_ONE_PAGE:
 
      if ((ta - PAGE_SIZE) < (RAM_START + (RAM_SIZE/2)))
 
        /* Wrapp first page */
 
        tlbtr = ((ta - PAGE_SIZE + (RAM_SIZE/2)) & SPR_DTLBTR_PPN) | (dtlb_val & TLB_PR_MASK);
 
      else
 
        tlbtr = ((ta - PAGE_SIZE) & SPR_DTLBTR_PPN) | (dtlb_val & TLB_PR_MASK);
 
printf("3: tlbtr = %.8lx\n", tlbtr);
 
      break;
 
  }
 
 
 
  /* 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 162... Line 157...
  unsigned long ea, ta, tlbtr;
  unsigned long ea, ta, tlbtr;
  int set, way = 0;
  int set, way = 0;
  int i;
  int i;
 
 
  /* Get EA that cause the exception */
  /* Get EA that cause the exception */
  ea = mfspr (SPR_EEAR_BASE);
  ea = mfspr (SPR_EPCR_BASE);
 
 
  /* Find TLB set and LRU way */
  /* Find TLB set and LRU way */
  set = (ea / PAGE_SIZE) % ITLB_SETS;
  set = (ea / PAGE_SIZE) % ITLB_SETS;
  for (i = 0; i < ITLB_WAYS; i++) {
  for (i = 0; i < ITLB_WAYS; i++) {
    if ((mfspr (SPR_ITLBMR_BASE(i) + set) & SPR_ITLBMR_LRU) == 0) {
    if ((mfspr (SPR_ITLBMR_BASE(i) + set) & SPR_ITLBMR_LRU) == 0) {
Line 188... Line 183...
  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 physical RAM */
  ta = (ea & ((FLASH_SIZE/2) - 1)) + TEXT_END_ADD;
  ta = (ea & ((FLASH_SIZE/2) - 1)) + TEXT_END_ADD;
printf("ta = %.8lx\n", ta);
 
 
 
  /* Set appropriate TLB entry */
 
  switch (itlb_val & TLB_CODE_MASK) {
 
    case TLB_CODE_ONE_TO_ONE:
 
      tlbtr = (ta & SPR_ITLBTR_PPN) | (itlb_val & TLB_PR_MASK);
      tlbtr = (ta & SPR_ITLBTR_PPN) | (itlb_val & TLB_PR_MASK);
printf("1: tlbtr = %.8lx\n", tlbtr);
printf("ta = %.8lx\n", ta);
      break;
 
    case TLB_CODE_PLUS_ONE_PAGE:
 
      if ((ta + PAGE_SIZE) >= (FLASH_START + FLASH_SIZE))
 
        /* Wrapp last page */
 
        tlbtr = (((ta & ((FLASH_SIZE/2) - 1)) + TEXT_END_ADD) & SPR_ITLBTR_PPN) | (itlb_val & TLB_PR_MASK);
 
      else
 
        tlbtr = ((ta + PAGE_SIZE) & SPR_ITLBTR_PPN) | (itlb_val & TLB_PR_MASK);
 
printf("2: tlbtr = %.8lx\n", tlbtr);
 
      break;
 
    case TLB_CODE_MINUS_ONE_PAGE:
 
      if ((ta - PAGE_SIZE) < TEXT_END_ADD)
 
        /* Wrapp first page */
 
        tlbtr = ((ta - PAGE_SIZE + (FLASH_SIZE/2)) & SPR_ITLBTR_PPN) | (itlb_val & TLB_PR_MASK);
 
      else
 
        tlbtr = ((ta - PAGE_SIZE) & SPR_ITLBTR_PPN) | (itlb_val & TLB_PR_MASK);
 
printf("3: tlbtr = %.8lx\n", tlbtr);
 
      break;
 
  }
 
 
 
  /* 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);
}
}
 
 
/* Invalidate all entries in DTLB and enable DMMU */
/* Invalidate all entries in DTLB and enable DMMU */
void dmmu_enable (void)
void dmmu_enable (void)
{
{
  int i, j;
 
 
 
  /* Invalidate all entries in DTLB */
 
  for (i = 0; i < DTLB_WAYS; i++) {
 
    for (j = 0; j < DTLB_SETS; j++) {
 
      mtspr (SPR_DTLBMR_BASE(i) + j, 0);
 
      mtspr (SPR_DTLBTR_BASE(i) + j, 0);
 
    }
 
  }
 
 
 
  /* Register DTLB miss handler */
  /* Register DTLB miss handler */
  excpt_dtlbmiss = (unsigned long)dtlb_miss_handler;
  excpt_dtlbmiss = (unsigned long)dtlb_miss_handler;
 
 
  /* Enable DMMU */
  /* Enable DMMU */
  lo_dmmu_en ();
  lo_dmmu_en ();
}
}
 
 
/* Invalidate all entries in ITLB and enable IMMU */
/* Disable DMMU */
void immu_enable (void)
void dmmu_disable (void)
{
{
  int i, j;
  mtspr (SPR_SR, mfspr (SPR_SR) & ~SPR_SR_DME);
 
 
  /* Invalidate all entries in ITLB */
 
  for (i = 0; i < ITLB_WAYS; i++) {
 
    for (j = 0; j < ITLB_SETS; i++) {
 
      mtspr (SPR_ITLBMR_BASE(i) + j, 0);
 
      mtspr (SPR_ITLBTR_BASE(i) + j, 0);
 
    }
 
  }
  }
 
 
 
/* Invalidate all entries in ITLB and enable IMMU */
 
void immu_enable (void)
 
{
  /* Register ITLB miss handler */
  /* Register ITLB miss handler */
  excpt_itlbmiss = (unsigned long)itlb_miss_handler;
  excpt_itlbmiss = (unsigned long)itlb_miss_handler;
 
 
  /* Enable IMMU */
  /* Enable IMMU */
  lo_immu_en ();
  lo_immu_en ();
}
}
 
 
 
/* Disable IMMU */
 
void immu_disable (void)
 
{
 
  mtspr (SPR_SR, mfspr (SPR_SR) & ~SPR_SR_IME);
 
}
 
 
void write_pattern(unsigned long start, unsigned long end)
void write_pattern(unsigned long start, unsigned long end)
{
{
  unsigned long add;
  unsigned long add;
 
 
  add = start;
  add = start;
Line 271... Line 235...
    add += PAGE_SIZE;
    add += PAGE_SIZE;
  }
  }
 
 
}
}
 
 
 
/* Translation address register test
 
   Set various translation and check the pattern */
 
int dtlb_translation_test (void)
 
{
 
  int i, j;
 
  unsigned long ea, ta;
 
 
 
  /* Disable DMMU */
 
  dmmu_disable();
 
 
 
  /* Invalidate all entries in DTLB */
 
  for (i = 0; i < DTLB_WAYS; i++) {
 
    for (j = 0; j < DTLB_SETS; j++) {
 
      mtspr (SPR_DTLBMR_BASE(i) + j, 0);
 
      mtspr (SPR_DTLBTR_BASE(i) + j, 0);
 
    }
 
  }
 
 
 
  /* Set one to one translation for the use of this program */
 
  for (i = 0; i < 2; i++) {
 
    ea = RAM_START + (i*PAGE_SIZE);
 
    ta = RAM_START + (i*PAGE_SIZE);
 
    mtspr (SPR_DTLBMR_BASE(0) + i, ea | SPR_DTLBMR_V);
 
    mtspr (SPR_DTLBTR_BASE(0) + i, ta | TLB_PR_NOLIMIT);
 
  }
 
 
 
   /* Set dtlb permisions */
 
  dtlb_val = TLB_PR_NOLIMIT;
 
 
 
  /* Write test pattern */
 
  for (i = 0; i < DTLB_SETS; i++) {
 
    REG32(RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE)) = i;
 
    REG32(RAM_START + (RAM_SIZE/2) + ((i + 1)*PAGE_SIZE) - 4) = 0xffffffff - i;
 
  }
 
 
 
  /* Set one to one translation of the last way of DTLB */
 
  for (i = 0; i < DTLB_SETS; i++) {
 
    ea = 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_DTLBTR_BASE(DTLB_WAYS - 1) + i, ta | TLB_PR_NOLIMIT);
 
  }
 
 
 
  /* Enable DMMU */
 
  dmmu_enable();
 
 
 
  /* Check the pattern */
 
  for (i = 0; i < DTLB_SETS; i++) {
 
    ea = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
 
    ASSERT(REG32(ea) == i);
 
    ea = RAM_START + (RAM_SIZE/2) + ((i + 1)*PAGE_SIZE) - 4;
 
    ASSERT(REG32(ea) == (0xffffffff - i));
 
  }
 
 
 
  /* Write new pattern */
 
  for (i = 0; i < DTLB_SETS; i++) {
 
    REG32(RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE)) = 0xffffffff - i;
 
    REG32(RAM_START + (RAM_SIZE/2) + ((i + 1)*PAGE_SIZE) - 4) = i;
 
  }
 
 
 
  /* Set 0 -> RAM_START + (RAM_SIZE/2) translation */
 
  for (i = 0; i < DTLB_SETS; i++) {
 
    ea = 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_DTLBTR_BASE(DTLB_WAYS - 1) + i, ta | TLB_PR_NOLIMIT);
 
  }
 
 
 
  /* Check the pattern */
 
  for (i = 0; i < DTLB_SETS; i++) {
 
    ea = i*PAGE_SIZE;
 
    ASSERT(REG32(ea) == (0xffffffff - i));
 
    ea = ((i + 1)*PAGE_SIZE) - 4;
 
    ASSERT(REG32(ea) == i);
 
  }
 
 
 
  /* Write new pattern */
 
  for (i = 0; i < DTLB_SETS; i++) {
 
    REG32(i*PAGE_SIZE) = i;
 
    REG32(((i + 1)*PAGE_SIZE) - 4) = 0xffffffff - i;
 
  }
 
 
 
  /* Set hi -> lo, lo -> hi translation */
 
  for (i = 0; i < DTLB_SETS; i++) {
 
    ea = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
 
    ta = RAM_START + (RAM_SIZE/2) + ((DTLB_SETS - i - 1)*PAGE_SIZE);
 
    mtspr (SPR_DTLBMR_BASE(DTLB_WAYS - 1) + i, ea | SPR_DTLBMR_V);
 
    mtspr (SPR_DTLBTR_BASE(DTLB_WAYS - 1) + i, ta | TLB_PR_NOLIMIT);
 
  }
 
 
 
  /* Check the pattern */
 
  for (i = 0; i < DTLB_SETS; i++) {
 
    ea = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
 
    ASSERT(REG32(ea) == (DTLB_SETS - i - 1));
 
    ea = RAM_START + (RAM_SIZE/2) + ((i + 1)*PAGE_SIZE) - 4;
 
    ASSERT(REG32(ea) == (0xffffffff - DTLB_SETS + i + 1));
 
  }
 
 
 
  /* Write new pattern */
 
  for (i = 0; i < DTLB_SETS; i++) {
 
    REG32(RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE)) = 0xffffffff - i;
 
    REG32(RAM_START + (RAM_SIZE/2) + ((i + 1)*PAGE_SIZE) - 4) = i;
 
  }
 
 
 
  /* Disable DMMU */
 
  dmmu_disable();
 
 
 
  /* Check the pattern */
 
  for (i = 0; i < DTLB_SETS; i++) {
 
    ea = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
 
    ASSERT(REG32(ea) == (0xffffffff - DTLB_SETS + i + 1));
 
    ea = RAM_START + (RAM_SIZE/2) + ((i + 1)*PAGE_SIZE) - 4;
 
    ASSERT(REG32(ea) == (DTLB_SETS - i - 1));
 
  }
 
 
 
  return 0;
 
}
 
 
 
/* EA match register test
 
   Shifting one in DTLBMR and performing accesses to boundaries
 
   of the page, checking the triggering of exceptions */
 
int dtlb_match_test (int way, int set)
 
{
 
  int i, j, tmp;
 
  unsigned long add, t_add;
 
  unsigned long ea, ta;
 
 
 
  /* Disable DMMU */
 
  dmmu_disable();
 
 
 
  /* Invalidate all entries in DTLB */
 
  for (i = 0; i < DTLB_WAYS; i++) {
 
    for (j = 0; j < DTLB_SETS; j++) {
 
      mtspr (SPR_DTLBMR_BASE(i) + j, 0);
 
      mtspr (SPR_DTLBTR_BASE(i) + j, 0);
 
    }
 
  }
 
 
 
  /* Set one to one translation for the use of this program */
 
  for (i = 0; i < 2; i++) {
 
    ea = RAM_START + (i*PAGE_SIZE);
 
    ta = RAM_START + (i*PAGE_SIZE);
 
    mtspr (SPR_DTLBMR_BASE(0) + i, ea | SPR_DTLBMR_V);
 
    mtspr (SPR_DTLBTR_BASE(0) + i, ta | TLB_PR_NOLIMIT);
 
  }
 
 
 
  /* Set dtlb permisions */
 
  dtlb_val = TLB_PR_NOLIMIT;
 
 
 
  /* Set pattern */
 
  REG32(RAM_START + (RAM_SIZE/2) + PAGE_SIZE - 4) = 0x00112233;
 
  REG32(RAM_START + (RAM_SIZE/2) + PAGE_SIZE) = 0x44556677;
 
  REG32(RAM_START + (RAM_SIZE/2) + 2*PAGE_SIZE - 4) = 0x8899aabb;
 
  REG32(RAM_START + (RAM_SIZE/2) + 2*PAGE_SIZE) = 0xccddeeff;
 
 
 
  /* Enable DMMU */
 
  dmmu_enable();
 
 
 
  /* Shifting one in DTLBMR */
 
  i = 0;
 
  add = (PAGE_SIZE*DTLB_SETS);
 
  t_add = add + (set*PAGE_SIZE);
 
  while (add != 0x00000000) {
 
    mtspr (SPR_DTLBMR_BASE(way) + set, t_add | SPR_DTLBMR_V);
 
    mtspr (SPR_DTLBTR_BASE(way) + set, (RAM_START + (RAM_SIZE/2) + PAGE_SIZE) | TLB_PR_NOLIMIT);
 
 
 
    /* Reset DTLB miss counter and EA */
 
    dtlb_miss_count = 0;
 
    dtlb_miss_ea = 0;
 
 
 
    if (((t_add < RAM_START) || (add >= DATA_END_ADD)) && ((t_add < FLASH_START) || (add >= TEXT_END_ADD))) {
 
 
 
      /* Read last address of previous page */
 
      tmp = REG32(t_add - 4);
 
      ASSERT(dtlb_miss_count == 1);
 
 
 
      /* Read first address of the page */
 
      tmp = REG32(t_add);
 
      ASSERT(tmp == 0x44556677);
 
      ASSERT(dtlb_miss_count == 1);
 
 
 
      /* Read last address of the page */
 
      tmp = REG32(t_add + PAGE_SIZE - 4);
 
      ASSERT(tmp == 0x8899aabb);
 
      ASSERT(dtlb_miss_count == 1);
 
 
 
      /* Read first address of next page */
 
      tmp = REG32(t_add + PAGE_SIZE);
 
      ASSERT(dtlb_miss_count == 2);
 
    }
 
 
 
    i++;
 
    add = (PAGE_SIZE*DTLB_SETS) << i;
 
    t_add = add + (set*PAGE_SIZE);
 
 
 
    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);
 
    }
 
  }
 
 
 
  /* Disable DMMU */
 
  dmmu_disable();
 
 
 
  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
   access so miss handler will set them to valid,
   access so miss handler will set them to valid,
   try access again - there should be no miss exceptions */
   try access again - there should be no miss exceptions */
int dtlb_valid_bit_test (int set)
int dtlb_valid_bit_test (int set)
{
{
  int i;
  int i, j;
 
  unsigned long ea, ta;
 
 
 
  /* Disable DMMU */
 
  dmmu_disable();
 
 
 
  /* Invalidate all entries in DTLB */
 
  for (i = 0; i < DTLB_WAYS; i++) {
 
    for (j = 0; j < DTLB_SETS; j++) {
 
      mtspr (SPR_DTLBMR_BASE(i) + j, 0);
 
      mtspr (SPR_DTLBTR_BASE(i) + j, 0);
 
    }
 
  }
 
 
 
  /* Set one to one translation for the use of this program */
 
  for (i = 0; i < 2; i++) {
 
    ea = RAM_START + (i*PAGE_SIZE);
 
    ta = RAM_START + (i*PAGE_SIZE);
 
    mtspr (SPR_DTLBMR_BASE(0) + i, ea | SPR_DTLBMR_V);
 
    mtspr (SPR_DTLBTR_BASE(0) + i, ta | TLB_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;
 
 
Line 291... Line 482...
  /* Resetv DTLBMR for every way */
  /* Resetv DTLBMR for every way */
  for (i = 0; i < DTLB_WAYS; i++) {
  for (i = 0; i < DTLB_WAYS; i++) {
    mtspr (SPR_DTLBMR_BASE(i) + set, 0);
    mtspr (SPR_DTLBMR_BASE(i) + set, 0);
  }
  }
 
 
 
  /* Enable DMMU */
 
  dmmu_enable();
 
 
  /* Perform writes to address, that is not in DTLB */
  /* Perform writes to address, that is not in DTLB */
  for (i = 0; i < DTLB_WAYS; i++) {
  for (i = 0; i < DTLB_WAYS; i++) {
    REG32(RAM_START + RAM_SIZE + (i*DTLB_SETS*PAGE_SIZE) + (set*PAGE_SIZE)) = i;
    REG32(RAM_START + RAM_SIZE + (i*DTLB_SETS*PAGE_SIZE) + (set*PAGE_SIZE)) = i;
 
 
    /* Check if there was DTLB miss */
    /* Check if there was DTLB miss */
Line 326... Line 520...
    /* Check if there was DTLB miss */
    /* Check if there was DTLB miss */
    ASSERT(dtlb_miss_count == (i + 1));
    ASSERT(dtlb_miss_count == (i + 1));
    ASSERT(dtlb_miss_ea == (RAM_START + RAM_SIZE + (i*DTLB_SETS*PAGE_SIZE) + (set*PAGE_SIZE)));
    ASSERT(dtlb_miss_ea == (RAM_START + RAM_SIZE + (i*DTLB_SETS*PAGE_SIZE) + (set*PAGE_SIZE)));
  }
  }
 
 
 
  /* Disable DMMU */
 
  dmmu_disable();
 
 
  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 389... Line 586...
  return 0;
  return 0;
}
}
 
 
int main (void)
int main (void)
{
{
  int i;
  int i, j;
 
 
  /* Enable DMMU */
  /* Register bus error handler */
  dmmu_enable();
  excpt_buserr = (unsigned long)bus_err_handler;
 
 
  /* Valid bit testing */
  /* Register illegal insn handler */
  for (i = 0; i < 15; i++)
  excpt_illinsn = (unsigned long)ill_insn_handler;
    dtlb_valid_bit_test (DTLB_SETS - i - 1);
 
 
 
  /* Valid bit testing */
#if 0
  for (i = 0; i < 15; i++)
  /* Translation test */
    itlb_valid_bit_test (ITLB_SETS - i - 1);
  dtlb_translation_test ();
 
 
 
  /* Virtual address match test */
 
  for (j = 0; j < DTLB_WAYS; j++) {
 
    for (i = 2; i < (DTLB_SETS - 1); i++)
 
      dtlb_match_test (j, DTLB_SETS - i);
 
  }
 
 
  /* Write pattern */
  /* Valid bit testing */
//  write_pattern(0x40000000, 0x40100000);
  for (i = 1; i < (DTLB_SETS - 1); i++)
 
    dtlb_valid_bit_test (DTLB_SETS - i);
 
#endif
 
 
  /* Enable IMMU */
  /* Enable IMMU */
//  immu_enable();
  immu_enable();
 
 
 
  /* Translation test */
 
  itlb_valid_bit_test (DTLB_SETS - 2);
 
 
 
  report (0xdeaddead);
  exit(0);
  exit(0);
  return 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.