2 * Copyright (c) 2001-2005 The Regents of The University of Michigan
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;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include "arch/sparc/asi.hh"
32 #include "arch/sparc/miscregfile.hh"
33 #include "arch/sparc/tlb.hh"
34 #include "base/trace.hh"
35 #include "cpu/thread_context.hh"
36 #include "cpu/base.hh"
37 #include "mem/packet_access.hh"
38 #include "mem/request.hh"
39 #include "sim/builder.hh"
41 /* @todo remove some of the magic constants. -- ali
46 TLB::TLB(const std::string
&name
, int s
)
47 : SimObject(name
), size(s
)
49 // To make this work you'll have to change the hypervisor and OS
51 fatal("SPARC T1 TLB registers don't support more than 64 TLB entries.");
53 tlb
= new TlbEntry
[size
];
54 memset(tlb
, 0, sizeof(TlbEntry
) * size
);
61 for (i
= lookupTable
.begin(); i
!= lookupTable
.end();) {
62 TlbEntry
*t
= i
->second
;
63 if (!t
->pte
.locked()) {
72 TLB::insert(Addr va
, int partition_id
, int context_id
, bool real
,
73 const PageTableEntry
& PTE
)
80 DPRINTF(TLB
, "TLB: Inserting TLB Entry; va=%#x, pid=%d cid=%d r=%d\n",
81 va
, partition_id
, context_id
, (int)real
);
84 for (x
= 0; x
< size
; x
++) {
85 if (!tlb
[x
].valid
|| !tlb
[x
].used
) {
91 // Update the last ently if their all locked
96 new_entry
->range
.va
= va
;
97 new_entry
->range
.size
= PTE
.size();
98 new_entry
->range
.partitionId
= partition_id
;
99 new_entry
->range
.contextId
= context_id
;
100 new_entry
->range
.real
= real
;
101 new_entry
->pte
= PTE
;
102 new_entry
->used
= true;;
103 new_entry
->valid
= true;
107 // Demap any entry that conflicts
108 i
= lookupTable
.find(new_entry
->range
);
109 if (i
!= lookupTable
.end()) {
110 i
->second
->valid
= false;
111 if (i
->second
->used
) {
112 i
->second
->used
= false;
115 DPRINTF(TLB
, "TLB: Found conflicting entry, deleting it\n");
116 lookupTable
.erase(i
);
119 lookupTable
.insert(new_entry
->range
, new_entry
);;
121 // If all entries have there used bit set, clear it on them all, but the
122 // one we just inserted
123 if (usedEntries
== size
) {
125 new_entry
->used
= true;
133 TLB::lookup(Addr va
, int partition_id
, bool real
, int context_id
)
139 DPRINTF(TLB
, "TLB: Looking up entry va=%#x pid=%d cid=%d r=%d\n",
140 va
, partition_id
, context_id
, real
);
141 // Assemble full address structure
143 tr
.size
= va
+ MachineBytes
;
144 tr
.contextId
= context_id
;
145 tr
.partitionId
= partition_id
;
148 // Try to find the entry
149 i
= lookupTable
.find(tr
);
150 if (i
== lookupTable
.end()) {
151 DPRINTF(TLB
, "TLB: No valid entry found\n");
154 DPRINTF(TLB
, "TLB: Valid entry found\n");
156 // Mark the entries used bit and clear other used bits in needed
161 if (usedEntries
== size
) {
173 TLB::demapPage(Addr va
, int partition_id
, bool real
, int context_id
)
178 // Assemble full address structure
180 tr
.size
= va
+ MachineBytes
;
181 tr
.contextId
= context_id
;
182 tr
.partitionId
= partition_id
;
185 // Demap any entry that conflicts
186 i
= lookupTable
.find(tr
);
187 if (i
!= lookupTable
.end()) {
188 i
->second
->valid
= false;
189 if (i
->second
->used
) {
190 i
->second
->used
= false;
193 lookupTable
.erase(i
);
198 TLB::demapContext(int partition_id
, int context_id
)
201 for (x
= 0; x
< size
; x
++) {
202 if (tlb
[x
].range
.contextId
== context_id
&&
203 tlb
[x
].range
.partitionId
== partition_id
) {
204 tlb
[x
].valid
= false;
209 lookupTable
.erase(tlb
[x
].range
);
215 TLB::demapAll(int partition_id
)
218 for (x
= 0; x
< size
; x
++) {
219 if (!tlb
[x
].pte
.locked() && tlb
[x
].range
.partitionId
== partition_id
) {
220 tlb
[x
].valid
= false;
225 lookupTable
.erase(tlb
[x
].range
);
234 for (x
= 0; x
< size
; x
++) {
235 tlb
[x
].valid
= false;
241 TLB::TteRead(int entry
) {
242 assert(entry
< size
);
243 return tlb
[entry
].pte();
247 TLB::TagRead(int entry
) {
248 assert(entry
< size
);
251 tag
= tlb
[entry
].range
.contextId
| tlb
[entry
].range
.va
|
252 (uint64_t)tlb
[entry
].range
.partitionId
<< 61;
253 tag
|= tlb
[entry
].range
.real
? ULL(1) << 60 : 0;
254 tag
|= (uint64_t)~tlb
[entry
].pte
._size() << 56;
259 TLB::validVirtualAddress(Addr va
, bool am
)
263 if (va
>= StartVAddrHole
&& va
<= EndVAddrHole
)
269 TLB::writeSfsr(ThreadContext
*tc
, int reg
, bool write
, ContextType ct
,
270 bool se
, FaultTypes ft
, int asi
)
273 sfsr
= tc
->readMiscReg(reg
);
287 tc
->setMiscReg(reg
, sfsr
);
292 ITB::writeSfsr(ThreadContext
*tc
, bool write
, ContextType ct
,
293 bool se
, FaultTypes ft
, int asi
)
295 DPRINTF(TLB
, "TLB: ITB Fault: w=%d ct=%d ft=%d asi=%d\n",
296 (int)write
, ct
, ft
, asi
);
297 TLB::writeSfsr(tc
, MISCREG_MMU_ITLB_SFSR
, write
, ct
, se
, ft
, asi
);
301 DTB::writeSfr(ThreadContext
*tc
, Addr a
, bool write
, ContextType ct
,
302 bool se
, FaultTypes ft
, int asi
)
304 DPRINTF(TLB
, "TLB: DTB Fault: A=%#x w=%d ct=%d ft=%d asi=%d\n",
305 a
, (int)write
, ct
, ft
, asi
);
306 TLB::writeSfsr(tc
, MISCREG_MMU_DTLB_SFSR
, write
, ct
, se
, ft
, asi
);
307 tc
->setMiscReg(MISCREG_MMU_DTLB_SFAR
, a
);
312 ITB::translate(RequestPtr
&req
, ThreadContext
*tc
)
314 uint64_t hpstate
= tc
->readMiscReg(MISCREG_HPSTATE
);
315 uint64_t pstate
= tc
->readMiscReg(MISCREG_PSTATE
);
316 bool lsuIm
= tc
->readMiscReg(MISCREG_MMU_LSU_CTRL
) >> 2 & 0x1;
317 uint64_t tl
= tc
->readMiscReg(MISCREG_TL
);
318 uint64_t part_id
= tc
->readMiscReg(MISCREG_MMU_PART_ID
);
319 bool addr_mask
= pstate
>> 3 & 0x1;
320 bool priv
= pstate
>> 2 & 0x1;
321 Addr vaddr
= req
->getVaddr();
328 DPRINTF(TLB
, "TLB: ITB Request to translate va=%#x size=%d\n",
329 vaddr
, req
->getSize());
331 assert(req
->getAsi() == ASI_IMPLICIT
);
340 context
= tc
->readMiscReg(MISCREG_MMU_P_CONTEXT
);
343 if ( hpstate
>> 2 & 0x1 || hpstate
>> 5 & 0x1 ) {
344 req
->setPaddr(req
->getVaddr() & PAddrImplMask
);
348 // If the asi is unaligned trap
350 writeSfsr(tc
, false, ct
, false, OtherFault
, asi
);
351 return new MemAddressNotAligned
;
355 vaddr
= vaddr
& VAddrAMask
;
357 if (!validVirtualAddress(vaddr
, addr_mask
)) {
358 writeSfsr(tc
, false, ct
, false, VaOutOfRange
, asi
);
359 return new InstructionAccessException
;
363 e
= lookup(req
->getVaddr(), part_id
, true);
367 e
= lookup(vaddr
, part_id
, false, context
);
370 if (e
== NULL
|| !e
->valid
) {
371 tc
->setMiscReg(MISCREG_MMU_ITLB_TAG_ACCESS
,
372 vaddr
& ~BytesInPageMask
| context
);
374 return new InstructionRealTranslationMiss
;
376 return new FastInstructionAccessMMUMiss
;
379 // were not priviledged accesing priv page
380 if (!priv
&& e
->pte
.priv()) {
381 writeSfsr(tc
, false, ct
, false, PrivViolation
, asi
);
382 return new InstructionAccessException
;
385 req
->setPaddr(e
->pte
.paddr() & ~e
->pte
.size() |
386 req
->getVaddr() & e
->pte
.size());
393 DTB::translate(RequestPtr
&req
, ThreadContext
*tc
, bool write
)
395 /* @todo this could really use some profiling and fixing to make it faster! */
396 uint64_t hpstate
= tc
->readMiscReg(MISCREG_HPSTATE
);
397 uint64_t pstate
= tc
->readMiscReg(MISCREG_PSTATE
);
398 bool lsuDm
= tc
->readMiscReg(MISCREG_MMU_LSU_CTRL
) >> 3 & 0x1;
399 uint64_t tl
= tc
->readMiscReg(MISCREG_TL
);
400 uint64_t part_id
= tc
->readMiscReg(MISCREG_MMU_PART_ID
);
401 bool hpriv
= hpstate
>> 2 & 0x1;
402 bool red
= hpstate
>> 5 >> 0x1;
403 bool addr_mask
= pstate
>> 3 & 0x1;
404 bool priv
= pstate
>> 2 & 0x1;
405 bool implicit
= false;
407 Addr vaddr
= req
->getVaddr();
408 Addr size
= req
->getSize();
415 asi
= (ASI
)req
->getAsi();
416 DPRINTF(TLB
, "TLB: DTB Request to translate va=%#x size=%d asi=%#x\n",
419 if (asi
== ASI_IMPLICIT
)
430 context
= tc
->readMiscReg(MISCREG_MMU_P_CONTEXT
);
432 } else if (!hpriv
&& !red
) {
433 if (tl
> 0 || AsiIsNucleus(asi
)) {
436 } else if (AsiIsSecondary(asi
)) {
438 context
= tc
->readMiscReg(MISCREG_MMU_S_CONTEXT
);
440 context
= tc
->readMiscReg(MISCREG_MMU_P_CONTEXT
);
444 // We need to check for priv level/asi priv
445 if (!priv
&& !AsiIsUnPriv(asi
)) {
446 // It appears that context should be Nucleus in these cases?
447 writeSfr(tc
, vaddr
, write
, Nucleus
, false, IllegalAsi
, asi
);
448 return new PrivilegedAction
;
450 if (priv
&& AsiIsHPriv(asi
)) {
451 writeSfr(tc
, vaddr
, write
, Nucleus
, false, IllegalAsi
, asi
);
452 return new DataAccessException
;
457 // If the asi is unaligned trap
458 if (vaddr
& size
-1) {
459 writeSfr(tc
, vaddr
, false, ct
, false, OtherFault
, asi
);
460 return new MemAddressNotAligned
;
464 vaddr
= vaddr
& VAddrAMask
;
466 if (!validVirtualAddress(vaddr
, addr_mask
)) {
467 writeSfr(tc
, vaddr
, false, ct
, true, VaOutOfRange
, asi
);
468 return new DataAccessException
;
472 if (AsiIsLittle(asi
))
473 panic("Little Endian ASIs not supported\n");
475 panic("Block ASIs not supported\n");
476 if (AsiIsNoFault(asi
))
477 panic("No Fault ASIs not supported\n");
479 panic("Twin ASIs not supported\n");
480 if (AsiIsPartialStore(asi
))
481 panic("Partial Store ASIs not supported\n");
484 goto handleMmuRegAccess
;
485 if (AsiIsScratchPad(asi
))
486 goto handleScratchRegAccess
;
488 if (!AsiIsReal(asi
) && !AsiIsNucleus(asi
))
489 panic("Accessing ASI %#X. Should we?\n", asi
);
492 if ((!lsuDm
&& !hpriv
) || AsiIsReal(asi
)) {
497 if (hpriv
&& (implicit
|| (!AsiIsAsIfUser(asi
) && !AsiIsReal(asi
)))) {
498 req
->setPaddr(req
->getVaddr() & PAddrImplMask
);
502 e
= lookup(req
->getVaddr(), part_id
, real
, context
);
504 if (e
== NULL
|| !e
->valid
) {
505 tc
->setMiscReg(MISCREG_MMU_DTLB_TAG_ACCESS
,
506 vaddr
& ~BytesInPageMask
| context
);
507 DPRINTF(TLB
, "TLB: DTB Failed to find matching TLB entry\n");
509 return new DataRealTranslationMiss
;
511 return new FastDataAccessMMUMiss
;
516 if (write
&& !e
->pte
.writable()) {
517 writeSfr(tc
, vaddr
, write
, ct
, e
->pte
.sideffect(), OtherFault
, asi
);
518 return new FastDataAccessProtection
;
521 if (e
->pte
.nofault() && !AsiIsNoFault(asi
)) {
522 writeSfr(tc
, vaddr
, write
, ct
, e
->pte
.sideffect(), LoadFromNfo
, asi
);
523 return new DataAccessException
;
526 if (e
->pte
.sideffect())
527 req
->setFlags(req
->getFlags() | UNCACHEABLE
);
530 if (!priv
&& e
->pte
.priv()) {
531 writeSfr(tc
, vaddr
, write
, ct
, e
->pte
.sideffect(), PrivViolation
, asi
);
532 return new DataAccessException
;
535 req
->setPaddr(e
->pte
.paddr() & ~e
->pte
.size() |
536 req
->getVaddr() & e
->pte
.size());
538 /** Normal flow ends here. */
540 handleScratchRegAccess
:
541 if (vaddr
> 0x38 || (vaddr
>= 0x20 && vaddr
< 0x30 && !hpriv
)) {
542 writeSfr(tc
, vaddr
, write
, Primary
, true, IllegalAsi
, asi
);
543 return new DataAccessException
;
546 DPRINTF(TLB
, "TLB: DTB Translating MM IPR access\n");
547 req
->setMmapedIpr(true);
548 req
->setPaddr(req
->getVaddr());
553 DTB::doMmuRegRead(ThreadContext
*tc
, Packet
*pkt
)
555 Addr va
= pkt
->getAddr();
556 ASI asi
= (ASI
)pkt
->req
->getAsi();
558 DPRINTF(IPR
, "Memory Mapped IPR Read: asi=%#X a=%#x\n",
559 (uint32_t)pkt
->req
->getAsi(), pkt
->getAddr());
562 case ASI_LSU_CONTROL_REG
:
564 pkt
->set(tc
->readMiscRegWithEffect(MISCREG_MMU_LSU_CTRL
));
569 pkt
->set(tc
->readMiscRegWithEffect(MISCREG_MMU_P_CONTEXT
));
572 pkt
->set(tc
->readMiscRegWithEffect(MISCREG_MMU_S_CONTEXT
));
578 case ASI_DMMU_CTXT_ZERO_TSB_BASE_PS0
:
580 pkt
->set(tc
->readMiscRegWithEffect(MISCREG_MMU_DTLB_C0_TSB_PS0
));
582 case ASI_DMMU_CTXT_ZERO_TSB_BASE_PS1
:
584 pkt
->set(tc
->readMiscRegWithEffect(MISCREG_MMU_DTLB_C0_TSB_PS1
));
586 case ASI_DMMU_CTXT_ZERO_CONFIG
:
588 pkt
->set(tc
->readMiscRegWithEffect(MISCREG_MMU_DTLB_C0_CONFIG
));
590 case ASI_IMMU_CTXT_ZERO_TSB_BASE_PS0
:
592 pkt
->set(tc
->readMiscRegWithEffect(MISCREG_MMU_ITLB_C0_TSB_PS0
));
594 case ASI_IMMU_CTXT_ZERO_TSB_BASE_PS1
:
596 pkt
->set(tc
->readMiscRegWithEffect(MISCREG_MMU_ITLB_C0_TSB_PS1
));
598 case ASI_IMMU_CTXT_ZERO_CONFIG
:
600 pkt
->set(tc
->readMiscRegWithEffect(MISCREG_MMU_ITLB_C0_CONFIG
));
602 case ASI_DMMU_CTXT_NONZERO_TSB_BASE_PS0
:
604 pkt
->set(tc
->readMiscRegWithEffect(MISCREG_MMU_DTLB_CX_TSB_PS0
));
606 case ASI_DMMU_CTXT_NONZERO_TSB_BASE_PS1
:
608 pkt
->set(tc
->readMiscRegWithEffect(MISCREG_MMU_DTLB_CX_TSB_PS1
));
610 case ASI_DMMU_CTXT_NONZERO_CONFIG
:
612 pkt
->set(tc
->readMiscRegWithEffect(MISCREG_MMU_DTLB_CX_CONFIG
));
614 case ASI_IMMU_CTXT_NONZERO_TSB_BASE_PS0
:
616 pkt
->set(tc
->readMiscRegWithEffect(MISCREG_MMU_ITLB_CX_TSB_PS0
));
618 case ASI_IMMU_CTXT_NONZERO_TSB_BASE_PS1
:
620 pkt
->set(tc
->readMiscRegWithEffect(MISCREG_MMU_ITLB_CX_TSB_PS1
));
622 case ASI_IMMU_CTXT_NONZERO_CONFIG
:
624 pkt
->set(tc
->readMiscRegWithEffect(MISCREG_MMU_ITLB_CX_CONFIG
));
626 case ASI_HYP_SCRATCHPAD
:
628 pkt
->set(tc
->readMiscRegWithEffect(MISCREG_SCRATCHPAD_R0
+ (va
>> 3)));
633 pkt
->set(tc
->readMiscRegWithEffect(MISCREG_MMU_PART_ID
));
641 panic("need to impl DTB::doMmuRegRead() got asi=%#x, va=%#x\n",
644 pkt
->result
= Packet::Success
;
645 return tc
->getCpuPtr()->cycles(1);
649 DTB::doMmuRegWrite(ThreadContext
*tc
, Packet
*pkt
)
651 uint64_t data
= gtoh(pkt
->get
<uint64_t>());
652 Addr va
= pkt
->getAddr();
653 ASI asi
= (ASI
)pkt
->req
->getAsi();
655 DPRINTF(IPR
, "Memory Mapped IPR Write: asi=#%X a=%#x d=%#X\n",
656 (uint32_t)asi
, va
, data
);
659 case ASI_LSU_CONTROL_REG
:
661 tc
->setMiscRegWithEffect(MISCREG_MMU_LSU_CTRL
, data
);
666 tc
->setMiscRegWithEffect(MISCREG_MMU_P_CONTEXT
, data
);
669 tc
->setMiscRegWithEffect(MISCREG_MMU_S_CONTEXT
, data
);
672 goto doMmuWriteError
;
675 case ASI_DMMU_CTXT_ZERO_TSB_BASE_PS0
:
677 tc
->setMiscRegWithEffect(MISCREG_MMU_DTLB_C0_TSB_PS0
, data
);
679 case ASI_DMMU_CTXT_ZERO_TSB_BASE_PS1
:
681 tc
->setMiscRegWithEffect(MISCREG_MMU_DTLB_C0_TSB_PS1
, data
);
683 case ASI_DMMU_CTXT_ZERO_CONFIG
:
685 tc
->setMiscRegWithEffect(MISCREG_MMU_DTLB_C0_CONFIG
, data
);
687 case ASI_IMMU_CTXT_ZERO_TSB_BASE_PS0
:
689 tc
->setMiscRegWithEffect(MISCREG_MMU_ITLB_C0_TSB_PS0
, data
);
691 case ASI_IMMU_CTXT_ZERO_TSB_BASE_PS1
:
693 tc
->setMiscRegWithEffect(MISCREG_MMU_ITLB_C0_TSB_PS1
, data
);
695 case ASI_IMMU_CTXT_ZERO_CONFIG
:
697 tc
->setMiscRegWithEffect(MISCREG_MMU_ITLB_C0_CONFIG
, data
);
699 case ASI_DMMU_CTXT_NONZERO_TSB_BASE_PS0
:
701 tc
->setMiscRegWithEffect(MISCREG_MMU_DTLB_CX_TSB_PS0
, data
);
703 case ASI_DMMU_CTXT_NONZERO_TSB_BASE_PS1
:
705 tc
->setMiscRegWithEffect(MISCREG_MMU_DTLB_CX_TSB_PS1
, data
);
707 case ASI_DMMU_CTXT_NONZERO_CONFIG
:
709 tc
->setMiscRegWithEffect(MISCREG_MMU_DTLB_CX_CONFIG
, data
);
711 case ASI_IMMU_CTXT_NONZERO_TSB_BASE_PS0
:
713 tc
->setMiscRegWithEffect(MISCREG_MMU_ITLB_CX_TSB_PS0
, data
);
715 case ASI_IMMU_CTXT_NONZERO_TSB_BASE_PS1
:
717 tc
->setMiscRegWithEffect(MISCREG_MMU_ITLB_CX_TSB_PS1
, data
);
719 case ASI_IMMU_CTXT_NONZERO_CONFIG
:
721 tc
->setMiscRegWithEffect(MISCREG_MMU_ITLB_CX_CONFIG
, data
);
723 case ASI_HYP_SCRATCHPAD
:
725 tc
->setMiscRegWithEffect(MISCREG_SCRATCHPAD_R0
+ (va
>> 3), data
);
730 tc
->setMiscRegWithEffect(MISCREG_MMU_PART_ID
, data
);
733 goto doMmuWriteError
;
738 panic("need to impl DTB::doMmuRegWrite() got asi=%#x, va=%#x d=%#x\n",
739 (uint32_t)pkt
->req
->getAsi(), pkt
->getAddr(), data
);
741 pkt
->result
= Packet::Success
;
742 return tc
->getCpuPtr()->cycles(1);
746 TLB::serialize(std::ostream
&os
)
748 panic("Need to implement serialize tlb for SPARC\n");
752 TLB::unserialize(Checkpoint
*cp
, const std::string
§ion
)
754 panic("Need to implement unserialize tlb for SPARC\n");
758 DEFINE_SIM_OBJECT_CLASS_NAME("SparcTLB", TLB
)
760 BEGIN_DECLARE_SIM_OBJECT_PARAMS(ITB
)
764 END_DECLARE_SIM_OBJECT_PARAMS(ITB
)
766 BEGIN_INIT_SIM_OBJECT_PARAMS(ITB
)
768 INIT_PARAM_DFLT(size
, "TLB size", 48)
770 END_INIT_SIM_OBJECT_PARAMS(ITB
)
773 CREATE_SIM_OBJECT(ITB
)
775 return new ITB(getInstanceName(), size
);
778 REGISTER_SIM_OBJECT("SparcITB", ITB
)
780 BEGIN_DECLARE_SIM_OBJECT_PARAMS(DTB
)
784 END_DECLARE_SIM_OBJECT_PARAMS(DTB
)
786 BEGIN_INIT_SIM_OBJECT_PARAMS(DTB
)
788 INIT_PARAM_DFLT(size
, "TLB size", 64)
790 END_INIT_SIM_OBJECT_PARAMS(DTB
)
793 CREATE_SIM_OBJECT(DTB
)
795 return new DTB(getInstanceName(), size
);
798 REGISTER_SIM_OBJECT("SparcDTB", DTB
)