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

Subversion Repositories or1k

[/] [or1k/] [tags/] [rel-0-3-0-rc1/] [or1ksim/] [mmu/] [dmmu.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 lampret
/* dmmu.c -- Data MMU simulation
2 1748 jeremybenn
 
3 6 lampret
   Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
4 1748 jeremybenn
   Copyright (C) 2008 Embecosm Limited
5 6 lampret
 
6 1748 jeremybenn
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
7 6 lampret
 
8 1748 jeremybenn
   This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
9 6 lampret
 
10 1748 jeremybenn
   This program is free software; you can redistribute it and/or modify it
11
   under the terms of the GNU General Public License as published by the Free
12
   Software Foundation; either version 3 of the License, or (at your option)
13
   any later version.
14 6 lampret
 
15 1748 jeremybenn
   This program is distributed in the hope that it will be useful, but WITHOUT
16
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
18
   more details.
19
 
20
   You should have received a copy of the GNU General Public License along
21
   with this program.  If not, see <http://www.gnu.org/licenses/>.  */
22
 
23
/* This program is commented throughout in a fashion suitable for processing
24
   with Doxygen. */
25
 
26 1539 nogj
/* DMMU model, perfectly functional. */
27 6 lampret
 
28 1748 jeremybenn
 
29
/* Autoconf and/or portability configuration */
30 1350 nogj
#include "config.h"
31 1748 jeremybenn
#include "port.h"
32 1350 nogj
 
33 1748 jeremybenn
/* System includes */
34
#include <stdlib.h>
35 1350 nogj
 
36 1748 jeremybenn
/* Package includes */
37
#include "dmmu.h"
38
#include "sim-config.h"
39 1350 nogj
#include "arch.h"
40 1748 jeremybenn
#include "debug.h"
41 1432 nogj
#include "execute.h"
42 1748 jeremybenn
#include "spr-defs.h"
43 6 lampret
#include "stats.h"
44 1748 jeremybenn
#include "except.h"
45 62 lampret
#include "sprs.h"
46 1555 nogj
#include "misc.h"
47 1748 jeremybenn
#include "sim-cmd.h"
48 6 lampret
 
49 1412 nogj
 
50 1748 jeremybenn
DEFAULT_DEBUG_CHANNEL (dmmu);
51
 
52 1718 nogj
struct dmmu *dmmu_state;
53
 
54 6 lampret
/* Data MMU */
55
 
56 1748 jeremybenn
static uorreg_t *
57
dmmu_find_tlbmr (oraddr_t virtaddr, uorreg_t ** dtlbmr_lru, struct dmmu *dmmu)
58 1539 nogj
{
59
  int set;
60 430 markom
  int i;
61 1539 nogj
  oraddr_t vpn;
62
  uorreg_t *dtlbmr;
63 572 simons
 
64 1539 nogj
  /* Which set to check out? */
65 1748 jeremybenn
  set = DADDR_PAGE (virtaddr) >> dmmu->pagesize_log2;
66 1718 nogj
  set &= dmmu->set_mask;
67
  vpn = virtaddr & dmmu->vpn_mask;
68 1539 nogj
 
69 1748 jeremybenn
  dtlbmr = &cpu_state.sprs[SPR_DTLBMR_BASE (0) + set];
70 1539 nogj
  *dtlbmr_lru = dtlbmr;
71
 
72
  /* FIXME: Should this be reversed? */
73 1748 jeremybenn
  for (i = dmmu->nways; i; i--, dtlbmr += (128 * 2))
74
    {
75
      if (((*dtlbmr & dmmu->vpn_mask) == vpn) && (*dtlbmr & SPR_DTLBMR_V))
76
        return dtlbmr;
77
    }
78 1539 nogj
 
79
  return NULL;
80
}
81
 
82 1748 jeremybenn
oraddr_t
83
dmmu_translate (oraddr_t virtaddr, int write_access)
84 1539 nogj
{
85
  int i;
86
  uorreg_t *dtlbmr;
87
  uorreg_t *dtlbtr;
88
  uorreg_t *dtlbmr_lru;
89 1718 nogj
  struct dmmu *dmmu = dmmu_state;
90 1539 nogj
 
91 1506 nogj
  if (!(cpu_state.sprs[SPR_SR] & SPR_SR_DME) ||
92 1748 jeremybenn
      !(cpu_state.sprs[SPR_UPR] & SPR_UPR_DMP))
93
    {
94
      data_ci = (virtaddr >= 0x80000000);
95
      return virtaddr;
96
    }
97 430 markom
 
98 1748 jeremybenn
  dtlbmr = dmmu_find_tlbmr (virtaddr, &dtlbmr_lru, dmmu);
99 456 simons
 
100 1539 nogj
  /* Did we find our tlb entry? */
101 1748 jeremybenn
  if (dtlbmr)
102
    {                           /* Yes, we did. */
103
      dmmu_stats.loads_tlbhit++;
104 1539 nogj
 
105 1748 jeremybenn
      dtlbtr = dtlbmr + 128;
106 1414 nogj
 
107 1748 jeremybenn
      TRACE ("DTLB hit (virtaddr=%" PRIxADDR ") at %lli.\n", virtaddr,
108
             runtime.sim.cycles);
109 1539 nogj
 
110 1748 jeremybenn
      /* Set LRUs */
111
      for (i = 0; i < dmmu->nways; i++, dtlbmr_lru += (128 * 2))
112
        {
113
          if (*dtlbmr_lru & SPR_DTLBMR_LRU)
114
            *dtlbmr_lru = (*dtlbmr_lru & ~SPR_DTLBMR_LRU) |
115
              ((*dtlbmr_lru & SPR_DTLBMR_LRU) - 0x40);
116
        }
117 1414 nogj
 
118 1748 jeremybenn
      /* This is not necessary `*dtlbmr &= ~SPR_DTLBMR_LRU;' since SPR_DTLBMR_LRU
119
       * is always decremented and the number of sets is always a power of two and
120
       * as such lru_reload has all bits set that get touched during decrementing
121
       * SPR_DTLBMR_LRU */
122
      *dtlbmr |= dmmu->lru_reload;
123 1414 nogj
 
124 1748 jeremybenn
      /* Check if page is cache inhibited */
125
      data_ci = *dtlbtr & SPR_DTLBTR_CI;
126
 
127
      runtime.sim.mem_cycles += dmmu->hitdelay;
128
 
129
      /* Test for page fault */
130
      if (cpu_state.sprs[SPR_SR] & SPR_SR_SM)
131
        {
132
          if ((write_access && !(*dtlbtr & SPR_DTLBTR_SWE))
133
              || (!write_access && !(*dtlbtr & SPR_DTLBTR_SRE)))
134
            except_handle (EXCEPT_DPF, virtaddr);
135
        }
136
      else
137
        {
138
          if ((write_access && !(*dtlbtr & SPR_DTLBTR_UWE))
139
              || (!write_access && !(*dtlbtr & SPR_DTLBTR_URE)))
140
            except_handle (EXCEPT_DPF, virtaddr);
141
        }
142
 
143
      TRACE ("Returning physical address %" PRIxADDR "\n",
144
             (*dtlbtr & SPR_DTLBTR_PPN) | (virtaddr &
145
                                           (dmmu->page_offset_mask)));
146
      return (*dtlbtr & SPR_DTLBTR_PPN) | (virtaddr &
147
                                           (dmmu->page_offset_mask));
148 430 markom
    }
149
 
150 1539 nogj
  /* No, we didn't. */
151
  dmmu_stats.loads_tlbmiss++;
152 430 markom
#if 0
153 1718 nogj
  for (i = 0; i < dmmu->nways; i++)
154 1748 jeremybenn
    if (((cpu_state.sprs[SPR_DTLBMR_BASE (i) + set] & SPR_DTLBMR_LRU) >> 6) <
155
        minlru)
156 1539 nogj
      minway = i;
157 1748 jeremybenn
 
158
  cpu_state.sprs[SPR_DTLBMR_BASE (minway) + set] &= ~SPR_DTLBMR_VPN;
159
  cpu_state.sprs[SPR_DTLBMR_BASE (minway) + set] |= vpn << 12;
160
  for (i = 0; i < dmmu->nways; i++)
161
    {
162
      uorreg_t lru = cpu_state.sprs[SPR_DTLBMR_BASE (i) + set];
163
      if (lru & SPR_DTLBMR_LRU)
164
        {
165
          lru = (lru & ~SPR_DTLBMR_LRU) | ((lru & SPR_DTLBMR_LRU) - 0x40);
166
          cpu_state.sprs[SPR_DTLBMR_BASE (i) + set] = lru;
167
        }
168 1506 nogj
    }
169 1748 jeremybenn
  cpu_state.sprs[SPR_DTLBMR_BASE (way) + set] &= ~SPR_DTLBMR_LRU;
170
  cpu_state.sprs[SPR_DTLBMR_BASE (way) + set] |= (dmmu->nsets - 1) << 6;
171 1506 nogj
 
172 1539 nogj
  /* 1 to 1 mapping */
173 1748 jeremybenn
  cpu_state.sprs[SPR_DTLBTR_BASE (minway) + set] &= ~SPR_DTLBTR_PPN;
174
  cpu_state.sprs[SPR_DTLBTR_BASE (minway) + set] |= vpn << 12;
175 1506 nogj
 
176 1748 jeremybenn
  cpu_state.sprs[SPR_DTLBMR_BASE (minway) + set] |= SPR_DTLBMR_V;
177 430 markom
#endif
178 1748 jeremybenn
  TRACE ("DTLB miss (virtaddr=%" PRIxADDR ") at %lli.\n", virtaddr,
179
         runtime.sim.cycles);
180 1718 nogj
  runtime.sim.mem_cycles += dmmu->missdelay;
181 1539 nogj
  /* if tlb refill implemented in HW */
182 1718 nogj
  /* return ((cpu_state.sprs[SPR_DTLBTR_BASE(minway) + set] & SPR_DTLBTR_PPN) >> 12) * dmmu->pagesize + (virtaddr % dmmu->pagesize); */
183 1539 nogj
 
184 1748 jeremybenn
  except_handle (EXCEPT_DTLBMISS, virtaddr);
185 1539 nogj
  return 0;
186 430 markom
}
187
 
188 1240 phoenix
/* DESC: try to find EA -> PA transaltion without changing
189
 *       any of precessor states. if this is not passible gives up
190
 *       (without triggering exceptions)
191
 *
192
 * PRMS: virtaddr     - EA for which to find translation
193
 *
194
 *       write_access - 0 ignore testing for write access
195
 *                      1 test for write access, if fails
196
 *                        do not return translation
197
 *
198
 *       through_dc   - 1 go through data cache
199
 *                      0 ignore data cache
200
 *
201
 * RTRN: 0            - no DMMU, DMMU disabled or ITLB miss
202
 *       else         - appropriate PA (note it DMMU is not present
203
 *                      PA === EA)
204
 */
205 1748 jeremybenn
oraddr_t
206
peek_into_dtlb (oraddr_t virtaddr, int write_access, int through_dc)
207 1240 phoenix
{
208 1539 nogj
  uorreg_t *dtlbmr;
209
  uorreg_t *dtlbtr;
210
  uorreg_t *dtlbmr_lru;
211 1718 nogj
  struct dmmu *dmmu = dmmu_state;
212 1240 phoenix
 
213 1506 nogj
  if (!(cpu_state.sprs[SPR_SR] & SPR_SR_DME) ||
214 1748 jeremybenn
      !(cpu_state.sprs[SPR_UPR] & SPR_UPR_DMP))
215
    {
216
      if (through_dc)
217
        data_ci = (virtaddr >= 0x80000000);
218
      return virtaddr;
219
    }
220 1240 phoenix
 
221 1748 jeremybenn
  dtlbmr = dmmu_find_tlbmr (virtaddr, &dtlbmr_lru, dmmu);
222 1240 phoenix
 
223 1539 nogj
  /* Did we find our tlb entry? */
224 1748 jeremybenn
  if (dtlbmr)
225
    {                           /* Yes, we did. */
226
      dmmu_stats.loads_tlbhit++;
227 1539 nogj
 
228 1748 jeremybenn
      dtlbtr = dtlbmr + 128;
229 1240 phoenix
 
230 1748 jeremybenn
      TRACE ("DTLB hit (virtaddr=%" PRIxADDR ") at %lli.\n", virtaddr,
231
             runtime.sim.cycles);
232
 
233
      /* Test for page fault */
234
      if (cpu_state.sprs[SPR_SR] & SPR_SR_SM)
235
        {
236
          if ((write_access && !(*dtlbtr & SPR_DTLBTR_SWE)) ||
237
              (!write_access && !(*dtlbtr & SPR_DTLBTR_SRE)))
238
 
239
            /* otherwise exception DPF would be raised */
240
            return (0);
241
        }
242
      else
243
        {
244
          if ((write_access && !(*dtlbtr & SPR_DTLBTR_UWE)) ||
245
              (!write_access && !(*dtlbtr & SPR_DTLBTR_URE)))
246
 
247
            /* otherwise exception DPF would be raised */
248
            return (0);
249
        }
250
 
251
      if (through_dc)
252
        {
253
          /* Check if page is cache inhibited */
254
          data_ci = *dtlbtr & SPR_DTLBTR_CI;
255
        }
256
 
257
      return (*dtlbtr & SPR_DTLBTR_PPN) | (virtaddr &
258
                                           (dmmu->page_offset_mask));
259 1240 phoenix
    }
260
 
261 1748 jeremybenn
  return (0);
262 1240 phoenix
}
263
 
264 1718 nogj
/* FIXME: Is this comment valid? */
265 62 lampret
/* First check if virtual address is covered by DTLB and if it is:
266
    - increment DTLB read hit stats,
267 1718 nogj
    - set 'lru' at this way to dmmu->ustates - 1 and
268 6 lampret
      decrement 'lru' of other ways unless they have reached 0,
269 62 lampret
    - check page access attributes and invoke DMMU page fault exception
270
      handler if necessary
271 6 lampret
   and if not:
272 62 lampret
    - increment DTLB read miss stats
273
    - find lru way and entry and invoke DTLB miss exception handler
274 1718 nogj
    - set 'lru' with dmmu->ustates - 1 and decrement 'lru' of other
275 6 lampret
      ways unless they have reached 0
276
*/
277
 
278 1748 jeremybenn
static void
279
dtlb_status (void *dat)
280 6 lampret
{
281 1718 nogj
  struct dmmu *dmmu = dat;
282 429 markom
  int set;
283
  int way;
284 1718 nogj
  int end_set = dmmu->nsets;
285 62 lampret
 
286 1748 jeremybenn
  if (!(cpu_state.sprs[SPR_UPR] & SPR_UPR_DMP))
287
    {
288
      PRINTF ("DMMU not implemented. Set UPR[DMP].\n");
289
      return;
290
    }
291 102 lampret
 
292 1748 jeremybenn
  if (0 < end_set)
293
    PRINTF ("\nDMMU: ");
294 429 markom
  /* Scan set(s) and way(s). */
295 1748 jeremybenn
  for (set = 0; set < end_set; set++)
296
    {
297
      for (way = 0; way < dmmu->nways; way++)
298
        {
299
          PRINTF ("%s\n", dump_spr (SPR_DTLBMR_BASE (way) + set,
300
                                    cpu_state.sprs[SPR_DTLBMR_BASE (way) +
301
                                                   set]));
302
          PRINTF ("%s\n",
303
                  dump_spr (SPR_DTLBTR_BASE (way) + set,
304
                            cpu_state.sprs[SPR_DTLBTR_BASE (way) + set]));
305
        }
306 429 markom
    }
307 1748 jeremybenn
  if (0 < end_set)
308
    PRINTF ("\n");
309 6 lampret
}
310 1358 nogj
 
311
/*---------------------------------------------------[ DMMU configuration ]---*/
312 1748 jeremybenn
 
313
/*---------------------------------------------------------------------------*/
314
/*!Enable or disable the DMMU
315
 
316
   Set the corresponding field in the UPR
317
 
318
   @param[in] val  The value to use
319
   @param[in] dat  The config data structure                                 */
320
/*---------------------------------------------------------------------------*/
321
static void
322
dmmu_enabled (union param_val val, void *dat)
323 1358 nogj
{
324 1718 nogj
  struct dmmu *dmmu = dat;
325
 
326 1748 jeremybenn
  if (val.int_val)
327
    {
328
      cpu_state.sprs[SPR_UPR] |= SPR_UPR_DMP;
329
    }
330 1506 nogj
  else
331 1748 jeremybenn
    {
332
      cpu_state.sprs[SPR_UPR] &= ~SPR_UPR_DMP;
333
    }
334
 
335 1718 nogj
  dmmu->enabled = val.int_val;
336 1358 nogj
 
337 1748 jeremybenn
}       /* dmmu_enabled() */
338
 
339
 
340
/*---------------------------------------------------------------------------*/
341
/*!Set the number of DMMU sets
342
 
343
   Value must be a power of 2 <= 256. Ignore any other values with a
344
   warning. Set the corresponding DMMU configuration flags.
345
 
346
   @param[in] val  The value to use
347
   @param[in] dat  The config data structure                                 */
348
/*---------------------------------------------------------------------------*/
349
static void
350
dmmu_nsets (union param_val  val,
351
            void            *dat)
352 1358 nogj
{
353 1718 nogj
  struct dmmu *dmmu = dat;
354
 
355 1748 jeremybenn
  if (is_power2 (val.int_val) && val.int_val <= 128)
356
    {
357
      int  set_bits = log2_int (val.int_val);
358 1358 nogj
 
359 1748 jeremybenn
      dmmu->nsets = val.int_val;
360
 
361
      cpu_state.sprs[SPR_DMMUCFGR] &= ~SPR_DMMUCFGR_NTS;
362
      cpu_state.sprs[SPR_DMMUCFGR] |= set_bits << SPR_DMMUCFGR_NTS_OFF;
363
    }
364
  else
365
    {
366
      fprintf (stderr, "Warning DMMU nsets not a power of 2 <= 128: ignored\n");
367
    }
368
}       /* dmmu_nsets() */
369
 
370
 
371
/*---------------------------------------------------------------------------*/
372
/*!Set the number of DMMU ways
373
 
374
   Value must be in the range 1-4. Ignore other values with a warning. Set the
375
   corresponding DMMU configuration flags.
376
 
377
   @param[in] val  The value to use
378
   @param[in] dat  The config data structure                                 */
379
/*---------------------------------------------------------------------------*/
380
static void
381
dmmu_nways (union param_val  val,
382
            void            *dat)
383 1358 nogj
{
384 1718 nogj
  struct dmmu *dmmu = dat;
385
 
386 1748 jeremybenn
  if (val.int_val >= 1 && val.int_val <= 4)
387
    {
388
      int  way_bits = val.int_val - 1;
389
 
390
      dmmu->nways = val.int_val;
391
 
392
      cpu_state.sprs[SPR_DMMUCFGR] &= ~SPR_DMMUCFGR_NTW;
393
      cpu_state.sprs[SPR_DMMUCFGR] |= way_bits << SPR_DMMUCFGR_NTW_OFF;
394
    }
395 1358 nogj
  else
396 1748 jeremybenn
    {
397
      fprintf (stderr, "Warning DMMU nways not in range 1-4: ignored\n");
398
    }
399
}       /* dmmu_nways() */
400 1358 nogj
 
401 1748 jeremybenn
 
402
/*---------------------------------------------------------------------------*/
403
/*!Set the DMMU page size
404
 
405
   Value must be a power of 2. Ignore other values with a warning
406
 
407
   @param[in] val  The value to use
408
   @param[in] dat  The config data structure                                 */
409
/*---------------------------------------------------------------------------*/
410
static void
411
dmmu_pagesize (union param_val  val,
412
               void            *dat)
413 1358 nogj
{
414 1718 nogj
  struct dmmu *dmmu = dat;
415
 
416 1748 jeremybenn
  if (is_power2 (val.int_val))
417
    {
418
      dmmu->pagesize = val.int_val;
419
    }
420 1358 nogj
  else
421 1748 jeremybenn
    {
422
      fprintf (stderr, "Warning DMMU page size must be power of 2: ignored\n");
423
    }
424
}       /* dmmu_pagesize() */
425 1358 nogj
 
426 1748 jeremybenn
 
427
/*---------------------------------------------------------------------------*/
428
/*!Set the DMMU entry size
429
 
430
   Value must be a power of 2. Ignore other values with a warning
431
 
432
   @param[in] val  The value to use
433
   @param[in] dat  The config data structure                                 */
434
/*---------------------------------------------------------------------------*/
435
static void
436
dmmu_entrysize (union param_val  val,
437
                void            *dat)
438 1358 nogj
{
439 1718 nogj
  struct dmmu *dmmu = dat;
440
 
441 1748 jeremybenn
  if (is_power2 (val.int_val))
442
    {
443
      dmmu->entrysize = val.int_val;
444
    }
445 1358 nogj
  else
446 1748 jeremybenn
    {
447
      fprintf (stderr, "Warning DMMU entry size must be power of 2: ignored\n");
448
    }
449
}       /* dmmu_entrysize() */
450 1358 nogj
 
451 1748 jeremybenn
 
452
/*---------------------------------------------------------------------------*/
453
/*!Set the number of DMMU usage states
454
 
455
   Value must be 2, 3 or 4. Ignore other values with a warning
456
 
457
   @param[in] val  The value to use
458
   @param[in] dat  The config data structure                                 */
459
/*---------------------------------------------------------------------------*/
460
static void
461
dmmu_ustates (union param_val  val,
462
              void            *dat)
463 1358 nogj
{
464 1718 nogj
  struct dmmu *dmmu = dat;
465
 
466 1748 jeremybenn
  if ((val.int_val >= 2) && (val.int_val <= 4))
467
    {
468
      dmmu->ustates = val.int_val;
469
    }
470 1358 nogj
  else
471 1748 jeremybenn
    {
472
      fprintf (stderr, "Warning number of DMMU usage states must be 2, 3 or 4:"
473
               "ignored\n");
474
    }
475
}       /* dmmu_ustates() */
476 1358 nogj
 
477 1748 jeremybenn
 
478
static void
479
dmmu_missdelay (union param_val val, void *dat)
480 1358 nogj
{
481 1718 nogj
  struct dmmu *dmmu = dat;
482
 
483
  dmmu->missdelay = val.int_val;
484 1358 nogj
}
485
 
486 1748 jeremybenn
static void
487
dmmu_hitdelay (union param_val val, void *dat)
488 1358 nogj
{
489 1718 nogj
  struct dmmu *dmmu = dat;
490
 
491
  dmmu->hitdelay = val.int_val;
492 1358 nogj
}
493
 
494 1748 jeremybenn
/*---------------------------------------------------------------------------*/
495
/*!Initialize a new DMMU configuration
496
 
497
   ALL parameters are set explicitly to default values. Corresponding SPR
498
   flags are set as appropriate.
499
 
500
   @return  The new memory configuration data structure                      */
501
/*---------------------------------------------------------------------------*/
502
static void *
503
dmmu_start_sec ()
504 1655 nogj
{
505 1718 nogj
  struct dmmu *dmmu;
506 1748 jeremybenn
  int          set_bits;
507
  int          way_bits;
508 1718 nogj
 
509 1748 jeremybenn
  if (NULL == (dmmu = malloc (sizeof (struct dmmu))))
510
    {
511
      fprintf (stderr, "OOM\n");
512
      exit (1);
513
    }
514 1718 nogj
 
515 1748 jeremybenn
  dmmu->enabled   = 0;
516
  dmmu->nsets     = 1;
517
  dmmu->nways     = 1;
518
  dmmu->pagesize  = 8192;
519
  dmmu->entrysize = 1;          /* Not currently used */
520
  dmmu->ustates   = 2;
521
  dmmu->hitdelay  = 1;
522 1718 nogj
  dmmu->missdelay = 1;
523
 
524 1748 jeremybenn
  if (dmmu->enabled)
525
    {
526
      cpu_state.sprs[SPR_UPR] |= SPR_UPR_DMP;
527
    }
528
  else
529
    {
530
      cpu_state.sprs[SPR_UPR] &= ~SPR_UPR_DMP;
531
    }
532
 
533
  set_bits = log2_int (dmmu->nsets);
534
  cpu_state.sprs[SPR_DMMUCFGR] &= ~SPR_DMMUCFGR_NTS;
535
  cpu_state.sprs[SPR_DMMUCFGR] |= set_bits << SPR_DMMUCFGR_NTS_OFF;
536
 
537
  way_bits = dmmu->nways - 1;
538
  cpu_state.sprs[SPR_DMMUCFGR] &= ~SPR_DMMUCFGR_NTW;
539
  cpu_state.sprs[SPR_DMMUCFGR] |= way_bits << SPR_DMMUCFGR_NTW_OFF;
540
 
541 1718 nogj
  dmmu_state = dmmu;
542
  return dmmu;
543 1655 nogj
 
544 1748 jeremybenn
}       /* dmmu_start_sec() */
545
 
546
 
547
static void
548
dmmu_end_sec (void *dat)
549 1655 nogj
{
550
  struct dmmu *dmmu = dat;
551
 
552
  /* Precalculate some values for use during address translation */
553 1748 jeremybenn
  dmmu->pagesize_log2 = log2_int (dmmu->pagesize);
554 1718 nogj
  dmmu->page_offset_mask = dmmu->pagesize - 1;
555
  dmmu->page_mask = ~dmmu->page_offset_mask;
556
  dmmu->vpn_mask = ~((dmmu->pagesize * dmmu->nsets) - 1);
557
  dmmu->set_mask = dmmu->nsets - 1;
558
  dmmu->lru_reload = (dmmu->set_mask << 6) & SPR_DTLBMR_LRU;
559
 
560 1748 jeremybenn
  if (dmmu->enabled)
561
    {
562
      PRINTF ("Data MMU %dKB: %d ways, %d sets, entry size %d bytes\n",
563
              dmmu->nsets * dmmu->entrysize * dmmu->nways / 1024, dmmu->nways,
564
              dmmu->nsets, dmmu->entrysize);
565
      reg_sim_stat (dtlb_status, dmmu);
566
    }
567 1655 nogj
}
568
 
569 1748 jeremybenn
void
570
reg_dmmu_sec (void)
571 1358 nogj
{
572 1748 jeremybenn
  struct config_section *sec = reg_config_sec ("dmmu", dmmu_start_sec,
573
                                               dmmu_end_sec);
574 1358 nogj
 
575 1748 jeremybenn
  reg_config_param (sec, "enabled", paramt_int, dmmu_enabled);
576
  reg_config_param (sec, "nsets", paramt_int, dmmu_nsets);
577
  reg_config_param (sec, "nways", paramt_int, dmmu_nways);
578
  reg_config_param (sec, "pagesize", paramt_int, dmmu_pagesize);
579
  reg_config_param (sec, "entrysize", paramt_int, dmmu_entrysize);
580
  reg_config_param (sec, "ustates", paramt_int, dmmu_ustates);
581
  reg_config_param (sec, "hitdelay", paramt_int, dmmu_hitdelay);
582
  reg_config_param (sec, "missdelay", paramt_int, dmmu_missdelay);
583 1358 nogj
}

powered by: WebSVN 2.1.0

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