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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_47/] [or1ksim/] [testbench/] [mmu.c] - Blame information for rev 410

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 410 simons
/* This is MMU test for OpenRISC 1200 */
2
 
3
#include "spr_defs.h"
4
#include "support.h"
5
 
6
/* Define RAM physical location and size
7
   Bottom half will be used for this program, the rest
8
   will be used for testing */
9
#define RAM_START 0x40000000
10
#define RAM_SIZE  0x00200000
11
 
12
/* What is the last address in ram that is used by this program */
13
#define CODE_END_ADD (RAM_START + (RAM_SIZE / 2))
14
 
15
/* MMU page size */
16
#define PAGE_SIZE 4096
17
 
18
/* Number of DTLB sets used (power of 2, max is 256) */
19
#define DTLB_SETS 16
20
 
21
/* Number of DTLB ways (1, 2, 3 etc., max is 4). */
22
#define DTLB_WAYS 2
23
 
24
/* Number of ITLB sets used (power of 2, max is 256) */
25
#define ITLB_SETS 16
26
 
27
/* Number of ITLB ways (1, 2, 3 etc., max is 4). */
28
#define ITLB_WAYS 2
29
 
30
/* TLB mode codes */
31
#define TLB_CODE_ONE_TO_ONE     0x00000000
32
#define TLB_CODE_PLUS_ONE_PAGE  0x10000000
33
#define TLB_CODE_MINUS_ONE_PAGE 0x20000000
34
 
35
#define TLB_CODE_MASK 0xfffff000
36
#define TLB_PR_MASK   0x00000fff
37
 
38
/* Extern functions */
39
extern void lo_dmmu_en (void);
40
extern void lo_immu_en (void);
41
 
42
/* Global variables */
43
extern unsigned long ram_end;
44
 
45
/* DTLB mode status */
46
unsigned long dtlb_val;
47
 
48
/* ITLB mode status */
49
unsigned long itlb_val;
50
 
51
/*inline static
52
unsigned int dtlb_write_entry (int way, int entry, unsigned int val)
53
{
54
  mtspr (SPR_DTLBMR_BASE(way) + entry, val);
55
}
56
*/
57
 
58
/* DTLB miss exception handler */
59
void dtlb_miss_handler (void)
60
{
61
  unsigned long ea, ta, tlbtr;
62
  int set, way = 0;
63
  int i;
64
 
65
  /* Get EA that cause the exception */
66
  ea = mfspr (SPR_EEAR_BASE);
67
printf("ea = %.8lx\n", ea);
68
  /* Find TLB set and LRU way */
69
  set = (ea / PAGE_SIZE) % DTLB_SETS;
70
  for (i = 0; i < DTLB_WAYS; i++) {
71
    if ((mfspr (SPR_DTLBMR_BASE(i) + set) & SPR_DTLBMR_LRU) == 0) {
72
      way = i;
73
      break;
74
    }
75
  }
76
 
77
printf("set = %.8lx\n", set);
78
  if (RAM_START < ea < CODE_END_ADD) {
79
 
80
printf("RAM_START< ea < CODE_END_ADD\n", ea);
81
    /* If this is acces to data of this program set one to one translation */
82
    mtspr (SPR_DTLBMR_BASE(way) + set, (ea & SPR_DTLBMR_VPN) | SPR_DTLBMR_V);
83
    mtspr (SPR_DTLBTR_BASE(way) + set, (ea & SPR_DTLBTR_PPN) | SPR_DTLBTR_CI | SPR_DTLBTR_URE | SPR_DTLBTR_UWE | SPR_DTLBTR_SRE | SPR_DTLBTR_SWE);
84
    return;
85
  }
86
 
87
  /* Whatever access is in progress, translated address have to point to physical RAM */
88
  ta = (ea & ((RAM_SIZE/2) - 1)) + RAM_START;
89
 
90
  /* Set appropriate TLB entry */
91
  switch (dtlb_val & TLB_CODE_MASK) {
92
    case TLB_CODE_ONE_TO_ONE:
93
      tlbtr = (ta & SPR_DTLBTR_PPN) | (dtlb_val | TLB_PR_MASK);
94
      break;
95
    case TLB_CODE_PLUS_ONE_PAGE:
96
      if ((ta + PAGE_SIZE) >= (RAM_START + RAM_SIZE))
97
        /* Wrapp last page */
98
        tlbtr = (((ta & ((RAM_SIZE/2) - 1)) + RAM_START + (RAM_SIZE/2)) & SPR_DTLBTR_PPN) | (dtlb_val | TLB_PR_MASK);
99
      else
100
        tlbtr = ((ta + PAGE_SIZE) & SPR_DTLBTR_PPN) | (dtlb_val | TLB_PR_MASK);
101
      break;
102
    case TLB_CODE_MINUS_ONE_PAGE:
103
      if ((ta - PAGE_SIZE) < (RAM_START + (RAM_SIZE/2)))
104
        /* Wrapp first page */
105
        tlbtr = ((ta - PAGE_SIZE + (RAM_SIZE/2)) & SPR_DTLBTR_PPN) | (dtlb_val | TLB_PR_MASK);
106
      else
107
        tlbtr = ((ta - PAGE_SIZE) & SPR_DTLBTR_PPN) | (dtlb_val | TLB_PR_MASK);
108
      break;
109
  }
110
 
111
  /* Set DTLB entry */
112
  mtspr (SPR_DTLBMR_BASE(way) + set, (ea & SPR_DTLBMR_VPN) | SPR_DTLBMR_V);
113
  mtspr (SPR_DTLBTR_BASE(way) + set, tlbtr);
114
}
115
 
116
 
117
/* ITLB miss exception handler */
118
void itlb_miss_handler (void)
119
{
120
 
121
 
122
}
123
 
124
/* Invalidate all entries in DTLB and enable DMMU */
125
void dmmu_enable (void)
126
{
127
  int i, j;
128
 
129
  /* Invalidate all entries in DTLB */
130
  for (i = 0; i < DTLB_WAYS; i++) {
131
    for (j = 0; j < DTLB_SETS; j++) {
132
      mtspr (SPR_DTLBMR_BASE(i) + j, 0);
133
      mtspr (SPR_DTLBTR_BASE(i) + j, 0);
134
    }
135
  }
136
 
137
  /* Register DTLB miss handler */
138
  excpt_dtlbmiss = (unsigned long)dtlb_miss_handler;
139
 
140
  /* Enable DMMU */
141
  lo_dmmu_en ();
142
}
143
 
144
/* Invalidate all entries in ITLB and enable IMMU */
145
void immu_enable (void)
146
{
147
  int i, j;
148
 
149
  /* Invalidate all entries in ITLB */
150
  for (i = 0; i < ITLB_WAYS; i++) {
151
    for (j = 0; j < ITLB_SETS; i++) {
152
      mtspr (SPR_ITLBMR_BASE(i) + j, 0);
153
      mtspr (SPR_ITLBTR_BASE(i) + j, 0);
154
    }
155
  }
156
 
157
  /* Register ITLB miss handler */
158
  excpt_itlbmiss = (unsigned long)itlb_miss_handler;
159
 
160
  /* Enable IMMU */
161
  lo_immu_en ();
162
}
163
 
164
void write_pattern(unsigned long start, unsigned long end)
165
{
166
  unsigned long add;
167
 
168
  add = start;
169
  while (add < end) {
170
    REG32(add) = add;
171
    add += PAGE_SIZE;
172
  }
173
 
174
}
175
 
176
int main (void)
177
{
178
 
179
  dtlb_val = SPR_DTLBTR_CI | SPR_DTLBTR_URE | SPR_DTLBTR_UWE | SPR_DTLBTR_SRE | SPR_DTLBTR_SWE;
180
  /* Enable DMMU */
181
  dmmu_enable();
182
 
183
  /* Write pattern */
184
  write_pattern(0x40000000, 0x40100000);
185
 
186
  /* Enable IMMU */
187
//  immu_enable();
188
 
189
  exit(0);
190
  return 0;
191
}

powered by: WebSVN 2.1.0

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