tlb.cc (5568:d14250d688d2) tlb.cc (5569:baeee670d4ce)
1/*
2 * Copyright (c) 2001-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;

--- 31 unchanged lines hidden (view full) ---

40#include "base/str.hh"
41#include "base/trace.hh"
42#include "config/alpha_tlaser.hh"
43#include "cpu/thread_context.hh"
44
45using namespace std;
46
47namespace AlphaISA {
1/*
2 * Copyright (c) 2001-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;

--- 31 unchanged lines hidden (view full) ---

40#include "base/str.hh"
41#include "base/trace.hh"
42#include "config/alpha_tlaser.hh"
43#include "cpu/thread_context.hh"
44
45using namespace std;
46
47namespace AlphaISA {
48
48///////////////////////////////////////////////////////////////////////
49//
50// Alpha TLB
51//
49///////////////////////////////////////////////////////////////////////
50//
51// Alpha TLB
52//
53
52#ifdef DEBUG
53bool uncacheBit39 = false;
54bool uncacheBit40 = false;
55#endif
56
54#ifdef DEBUG
55bool uncacheBit39 = false;
56bool uncacheBit40 = false;
57#endif
58
57#define MODE2MASK(X) (1 << (X))
59#define MODE2MASK(X) (1 << (X))
58
59TLB::TLB(const Params *p)
60 : BaseTLB(p), size(p->size), nlu(0)
61{
62 table = new TlbEntry[size];
63 memset(table, 0, sizeof(TlbEntry[size]));
64 flushCache();
65}

--- 42 unchanged lines hidden (view full) ---

108 }
109 }
110
111 DPRINTF(TLB, "lookup %#x, asn %#x -> %s ppn %#x\n", vpn, (int)asn,
112 retval ? "hit" : "miss", retval ? retval->ppn : 0);
113 return retval;
114}
115
60
61TLB::TLB(const Params *p)
62 : BaseTLB(p), size(p->size), nlu(0)
63{
64 table = new TlbEntry[size];
65 memset(table, 0, sizeof(TlbEntry[size]));
66 flushCache();
67}

--- 42 unchanged lines hidden (view full) ---

110 }
111 }
112
113 DPRINTF(TLB, "lookup %#x, asn %#x -> %s ppn %#x\n", vpn, (int)asn,
114 retval ? "hit" : "miss", retval ? retval->ppn : 0);
115 return retval;
116}
117
116
117Fault
118TLB::checkCacheability(RequestPtr &req, bool itb)
119{
118Fault
119TLB::checkCacheability(RequestPtr &req, bool itb)
120{
120// in Alpha, cacheability is controlled by upper-level bits of the
121// physical address
121 // in Alpha, cacheability is controlled by upper-level bits of the
122 // physical address
122
123
123/*
124 * We support having the uncacheable bit in either bit 39 or bit 40.
125 * The Turbolaser platform (and EV5) support having the bit in 39, but
126 * Tsunami (which Linux assumes uses an EV6) generates accesses with
127 * the bit in 40. So we must check for both, but we have debug flags
128 * to catch a weird case where both are used, which shouldn't happen.
129 */
124 /*
125 * We support having the uncacheable bit in either bit 39 or bit
126 * 40. The Turbolaser platform (and EV5) support having the bit
127 * in 39, but Tsunami (which Linux assumes uses an EV6) generates
128 * accesses with the bit in 40. So we must check for both, but we
129 * have debug flags to catch a weird case where both are used,
130 * which shouldn't happen.
131 */
130
131
132#if ALPHA_TLASER
133 if (req->getPaddr() & PAddrUncachedBit39)
134#else
135 if (req->getPaddr() & PAddrUncachedBit43)
136#endif
137 {
138 // IPR memory space not implemented
139 if (PAddrIprSpace(req->getPaddr())) {
140 return new UnimpFault("IPR memory space not implemented!");
141 } else {
142 // mark request as uncacheable
143 req->setFlags(req->getFlags() | UNCACHEABLE);
144
145#if !ALPHA_TLASER
132
133
134#if ALPHA_TLASER
135 if (req->getPaddr() & PAddrUncachedBit39)
136#else
137 if (req->getPaddr() & PAddrUncachedBit43)
138#endif
139 {
140 // IPR memory space not implemented
141 if (PAddrIprSpace(req->getPaddr())) {
142 return new UnimpFault("IPR memory space not implemented!");
143 } else {
144 // mark request as uncacheable
145 req->setFlags(req->getFlags() | UNCACHEABLE);
146
147#if !ALPHA_TLASER
146 // Clear bits 42:35 of the physical address (10-2 in Tsunami manual)
148 // Clear bits 42:35 of the physical address (10-2 in
149 // Tsunami manual)
147 req->setPaddr(req->getPaddr() & PAddrUncachedMask);
148#endif
149 }
150 // We shouldn't be able to read from an uncachable address in Alpha as
151 // we don't have a ROM and we don't want to try to fetch from a device
152 // register as we destroy any data that is clear-on-read.
153 if (req->isUncacheable() && itb)
154 return new UnimpFault("CPU trying to fetch from uncached I/O");

--- 61 unchanged lines hidden (view full) ---

216 assert(entry->valid);
217
218 // we can't increment i after we erase it, so save a copy and
219 // increment it to get the next entry now
220 PageTable::iterator cur = i;
221 ++i;
222
223 if (!entry->asma) {
150 req->setPaddr(req->getPaddr() & PAddrUncachedMask);
151#endif
152 }
153 // We shouldn't be able to read from an uncachable address in Alpha as
154 // we don't have a ROM and we don't want to try to fetch from a device
155 // register as we destroy any data that is clear-on-read.
156 if (req->isUncacheable() && itb)
157 return new UnimpFault("CPU trying to fetch from uncached I/O");

--- 61 unchanged lines hidden (view full) ---

219 assert(entry->valid);
220
221 // we can't increment i after we erase it, so save a copy and
222 // increment it to get the next entry now
223 PageTable::iterator cur = i;
224 ++i;
225
226 if (!entry->asma) {
224 DPRINTF(TLB, "flush @%d: %#x -> %#x\n", index, entry->tag, entry->ppn);
227 DPRINTF(TLB, "flush @%d: %#x -> %#x\n", index,
228 entry->tag, entry->ppn);
225 entry->valid = false;
226 lookupTable.erase(cur);
227 }
228 }
229}
230
231void
232TLB::flushAddr(Addr addr, uint8_t asn)

--- 46 unchanged lines hidden (view full) ---

279 for (int i = 0; i < size; i++) {
280 table[i].unserialize(cp, csprintf("%s.Entry%d", section, i));
281 if (table[i].valid) {
282 lookupTable.insert(make_pair(table[i].tag, i));
283 }
284 }
285}
286
229 entry->valid = false;
230 lookupTable.erase(cur);
231 }
232 }
233}
234
235void
236TLB::flushAddr(Addr addr, uint8_t asn)

--- 46 unchanged lines hidden (view full) ---

283 for (int i = 0; i < size; i++) {
284 table[i].unserialize(cp, csprintf("%s.Entry%d", section, i));
285 if (table[i].valid) {
286 lookupTable.insert(make_pair(table[i].tag, i));
287 }
288 }
289}
290
287
288///////////////////////////////////////////////////////////////////////
289//
290// Alpha ITB
291//
292ITB::ITB(const Params *p)
293 : TLB(p)
294{}
295

--- 12 unchanged lines hidden (view full) ---

308 .desc("ITB acv");
309 accesses
310 .name(name() + ".accesses")
311 .desc("ITB accesses");
312
313 accesses = hits + misses;
314}
315
291///////////////////////////////////////////////////////////////////////
292//
293// Alpha ITB
294//
295ITB::ITB(const Params *p)
296 : TLB(p)
297{}
298

--- 12 unchanged lines hidden (view full) ---

311 .desc("ITB acv");
312 accesses
313 .name(name() + ".accesses")
314 .desc("ITB accesses");
315
316 accesses = hits + misses;
317}
318
316
317Fault
318ITB::translate(RequestPtr &req, ThreadContext *tc)
319{
320 //If this is a pal pc, then set PHYSICAL
319Fault
320ITB::translate(RequestPtr &req, ThreadContext *tc)
321{
322 //If this is a pal pc, then set PHYSICAL
321 if(FULL_SYSTEM && PcPAL(req->getPC()))
323 if (FULL_SYSTEM && PcPAL(req->getPC()))
322 req->setFlags(req->getFlags() | PHYSICAL);
323
324 if (PcPAL(req->getPC())) {
325 // strip off PAL PC marker (lsb is 1)
326 req->setPaddr((req->getVaddr() & ~3) & PAddrImplMask);
327 hits++;
328 return NoFault;
329 }

--- 68 unchanged lines hidden (view full) ---

398 return checkCacheability(req, true);
399
400}
401
402///////////////////////////////////////////////////////////////////////
403//
404// Alpha DTB
405//
324 req->setFlags(req->getFlags() | PHYSICAL);
325
326 if (PcPAL(req->getPC())) {
327 // strip off PAL PC marker (lsb is 1)
328 req->setPaddr((req->getVaddr() & ~3) & PAddrImplMask);
329 hits++;
330 return NoFault;
331 }

--- 68 unchanged lines hidden (view full) ---

400 return checkCacheability(req, true);
401
402}
403
404///////////////////////////////////////////////////////////////////////
405//
406// Alpha DTB
407//
406 DTB::DTB(const Params *p)
408DTB::DTB(const Params *p)
407 : TLB(p)
408{}
409
410void
411DTB::regStats()
412{
413 read_hits
414 .name(name() + ".read_hits")

--- 64 unchanged lines hidden (view full) ---

479Fault
480DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
481{
482 Addr pc = tc->readPC();
483
484 mode_type mode =
485 (mode_type)DTB_CM_CM(tc->readMiscRegNoEffect(IPR_DTB_CM));
486
409 : TLB(p)
410{}
411
412void
413DTB::regStats()
414{
415 read_hits
416 .name(name() + ".read_hits")

--- 64 unchanged lines hidden (view full) ---

481Fault
482DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
483{
484 Addr pc = tc->readPC();
485
486 mode_type mode =
487 (mode_type)DTB_CM_CM(tc->readMiscRegNoEffect(IPR_DTB_CM));
488
487
488 /**
489 * Check for alignment faults
490 */
491 if (req->getVaddr() & (req->getSize() - 1)) {
492 DPRINTF(TLB, "Alignment Fault on %#x, size = %d", req->getVaddr(),
493 req->getSize());
494 uint64_t flags = write ? MM_STAT_WR_MASK : 0;
495 return new DtbAlignmentFault(req->getVaddr(), req->getFlags(), flags);

--- 21 unchanged lines hidden (view full) ---

517 // Check for "superpage" mapping
518#if ALPHA_TLASER
519 if ((MCSR_SP(tc->readMiscRegNoEffect(IPR_MCSR)) & 2) &&
520 VAddrSpaceEV5(req->getVaddr()) == 2)
521#else
522 if (VAddrSpaceEV6(req->getVaddr()) == 0x7e)
523#endif
524 {
489 /**
490 * Check for alignment faults
491 */
492 if (req->getVaddr() & (req->getSize() - 1)) {
493 DPRINTF(TLB, "Alignment Fault on %#x, size = %d", req->getVaddr(),
494 req->getSize());
495 uint64_t flags = write ? MM_STAT_WR_MASK : 0;
496 return new DtbAlignmentFault(req->getVaddr(), req->getFlags(), flags);

--- 21 unchanged lines hidden (view full) ---

518 // Check for "superpage" mapping
519#if ALPHA_TLASER
520 if ((MCSR_SP(tc->readMiscRegNoEffect(IPR_MCSR)) & 2) &&
521 VAddrSpaceEV5(req->getVaddr()) == 2)
522#else
523 if (VAddrSpaceEV6(req->getVaddr()) == 0x7e)
524#endif
525 {
525
526 // only valid in kernel mode
527 if (DTB_CM_CM(tc->readMiscRegNoEffect(IPR_DTB_CM)) !=
528 mode_kernel) {
529 if (write) { write_acv++; } else { read_acv++; }
530 uint64_t flags = ((write ? MM_STAT_WR_MASK : 0) |
531 MM_STAT_ACV_MASK);
526 // only valid in kernel mode
527 if (DTB_CM_CM(tc->readMiscRegNoEffect(IPR_DTB_CM)) !=
528 mode_kernel) {
529 if (write) { write_acv++; } else { read_acv++; }
530 uint64_t flags = ((write ? MM_STAT_WR_MASK : 0) |
531 MM_STAT_ACV_MASK);
532 return new DtbAcvFault(req->getVaddr(), req->getFlags(), flags);
532
533 return new DtbAcvFault(req->getVaddr(), req->getFlags(),
534 flags);
533 }
534
535 req->setPaddr(req->getVaddr() & PAddrImplMask);
536
537#if !ALPHA_TLASER
538 // sign extend the physical address properly
539 if (req->getPaddr() & PAddrUncachedBit40)
540 req->setPaddr(req->getPaddr() | ULL(0xf0000000000));

--- 29 unchanged lines hidden (view full) ---

570
571 if (write) {
572 if (!(entry->xwe & MODE2MASK(mode))) {
573 // declare the instruction access fault
574 write_acv++;
575 uint64_t flags = MM_STAT_WR_MASK |
576 MM_STAT_ACV_MASK |
577 (entry->fonw ? MM_STAT_FONW_MASK : 0);
535 }
536
537 req->setPaddr(req->getVaddr() & PAddrImplMask);
538
539#if !ALPHA_TLASER
540 // sign extend the physical address properly
541 if (req->getPaddr() & PAddrUncachedBit40)
542 req->setPaddr(req->getPaddr() | ULL(0xf0000000000));

--- 29 unchanged lines hidden (view full) ---

572
573 if (write) {
574 if (!(entry->xwe & MODE2MASK(mode))) {
575 // declare the instruction access fault
576 write_acv++;
577 uint64_t flags = MM_STAT_WR_MASK |
578 MM_STAT_ACV_MASK |
579 (entry->fonw ? MM_STAT_FONW_MASK : 0);
578 return new DtbPageFault(req->getVaddr(), req->getFlags(), flags);
580 return new DtbPageFault(req->getVaddr(), req->getFlags(),
581 flags);
579 }
580 if (entry->fonw) {
581 write_acv++;
582 }
583 if (entry->fonw) {
584 write_acv++;
582 uint64_t flags = MM_STAT_WR_MASK |
583 MM_STAT_FONW_MASK;
584 return new DtbPageFault(req->getVaddr(), req->getFlags(), flags);
585 uint64_t flags = MM_STAT_WR_MASK | MM_STAT_FONW_MASK;
586 return new DtbPageFault(req->getVaddr(), req->getFlags(),
587 flags);
585 }
586 } else {
587 if (!(entry->xre & MODE2MASK(mode))) {
588 read_acv++;
589 uint64_t flags = MM_STAT_ACV_MASK |
590 (entry->fonr ? MM_STAT_FONR_MASK : 0);
588 }
589 } else {
590 if (!(entry->xre & MODE2MASK(mode))) {
591 read_acv++;
592 uint64_t flags = MM_STAT_ACV_MASK |
593 (entry->fonr ? MM_STAT_FONR_MASK : 0);
591 return new DtbAcvFault(req->getVaddr(), req->getFlags(), flags);
594 return new DtbAcvFault(req->getVaddr(), req->getFlags(),
595 flags);
592 }
593 if (entry->fonr) {
594 read_acv++;
595 uint64_t flags = MM_STAT_FONR_MASK;
596 }
597 if (entry->fonr) {
598 read_acv++;
599 uint64_t flags = MM_STAT_FONR_MASK;
596 return new DtbPageFault(req->getVaddr(), req->getFlags(), flags);
600 return new DtbPageFault(req->getVaddr(), req->getFlags(),
601 flags);
597 }
598 }
599 }
600
601 if (write)
602 write_hits++;
603 else
604 read_hits++;

--- 12 unchanged lines hidden (view full) ---

617 TlbEntry *entry = &table[nlu];
618
619 if (advance)
620 nextnlu();
621
622 return *entry;
623}
624
602 }
603 }
604 }
605
606 if (write)
607 write_hits++;
608 else
609 read_hits++;

--- 12 unchanged lines hidden (view full) ---

622 TlbEntry *entry = &table[nlu];
623
624 if (advance)
625 nextnlu();
626
627 return *entry;
628}
629
625} // namespace AlphaISA
630/* end namespace AlphaISA */ }
626
627AlphaISA::ITB *
628AlphaITBParams::create()
629{
630 return new AlphaISA::ITB(this);
631}
632
633AlphaISA::DTB *
634AlphaDTBParams::create()
635{
636 return new AlphaISA::DTB(this);
637}
631
632AlphaISA::ITB *
633AlphaITBParams::create()
634{
635 return new AlphaISA::ITB(this);
636}
637
638AlphaISA::DTB *
639AlphaDTBParams::create()
640{
641 return new AlphaISA::DTB(this);
642}