ARM: Added support for Access Flag and some CP15 regs (V2PCWPR, V2PCWPW, V2PCWUR...
authorDam Sunwoo <dam.sunwoo@arm.com>
Wed, 2 Jun 2010 17:58:18 +0000 (12:58 -0500)
committerDam Sunwoo <dam.sunwoo@arm.com>
Wed, 2 Jun 2010 17:58:18 +0000 (12:58 -0500)
src/arch/arm/isa.cc
src/arch/arm/miscregs.hh
src/arch/arm/pagetable.hh
src/arch/arm/table_walker.cc
src/arch/arm/table_walker.hh
src/arch/arm/tlb.cc
src/arch/arm/tlb.hh

index 25e616e8e334f28e0f0f5c7fa8cb4a47a900a373..60f00e43837a8719ef2fcd50e13a60102c05874e 100644 (file)
@@ -117,6 +117,38 @@ ISA::clear()
 
     miscRegs[MISCREG_MPIDR] = 0;
 
+    // Reset values of PRRR and NMRR are implementation dependent
+
+    miscRegs[MISCREG_PRRR] =
+        (1 << 19) | // 19
+        (0 << 18) | // 18
+        (0 << 17) | // 17
+        (1 << 16) | // 16
+        (2 << 14) | // 15:14
+        (0 << 12) | // 13:12
+        (2 << 10) | // 11:10
+        (2 << 8)  | // 9:8
+        (2 << 6)  | // 7:6
+        (2 << 4)  | // 5:4
+        (1 << 2)  | // 3:2
+        0;          // 1:0
+    miscRegs[MISCREG_NMRR] =
+        (1 << 30) | // 31:30
+        (0 << 26) | // 27:26
+        (0 << 24) | // 25:24
+        (3 << 22) | // 23:22
+        (2 << 20) | // 21:20
+        (0 << 18) | // 19:18
+        (0 << 16) | // 17:16
+        (1 << 14) | // 15:14
+        (0 << 12) | // 13:12
+        (2 << 10) | // 11:10
+        (0 << 8)  | // 9:8
+        (3 << 6)  | // 7:6
+        (2 << 4)  | // 5:4
+        (0 << 2)  | // 3:2
+        0;          // 1:0
+
     //XXX We need to initialize the rest of the state.
 }
 
@@ -362,6 +394,63 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
           case MISCREG_DTLBIASID:
             tc->getDTBPtr()->flushAsid(bits(newVal, 7,0));
             return;
+          case MISCREG_V2PCWPR:
+          case MISCREG_V2PCWPW:
+          case MISCREG_V2PCWUR:
+          case MISCREG_V2PCWUW:
+          case MISCREG_V2POWPR:
+          case MISCREG_V2POWPW:
+          case MISCREG_V2POWUR:
+          case MISCREG_V2POWUW:
+            {
+              RequestPtr req = new Request;
+              unsigned flags;
+              BaseTLB::Mode mode;
+              Fault fault;
+              switch(misc_reg) {
+                  case MISCREG_V2PCWPR:
+                      flags = TLB::MustBeOne;
+                      mode = BaseTLB::Read;
+                      break;
+                  case MISCREG_V2PCWPW:
+                      flags = TLB::MustBeOne;
+                      mode = BaseTLB::Write;
+                      break;
+                  case MISCREG_V2PCWUR:
+                      flags = TLB::MustBeOne | TLB::UserMode;
+                      mode = BaseTLB::Read;
+                      break;
+                  case MISCREG_V2PCWUW:
+                      flags = TLB::MustBeOne | TLB::UserMode;
+                      mode = BaseTLB::Write;
+                      break;
+                  case MISCREG_V2POWPR:
+                  case MISCREG_V2POWPW:
+                  case MISCREG_V2POWUR:
+                  case MISCREG_V2POWUW:
+                      panic("Security Extensions not implemented!");
+              }
+              req->setVirt(0, val, 1, flags, tc->readPC());
+              fault = tc->getDTBPtr()->translateAtomic(req, tc, mode);
+              if (fault == NoFault) {
+                  miscRegs[MISCREG_PAR] =
+                      (req->getPaddr() & 0xfffff000) |
+                      (tc->getDTBPtr()->getAttr() );
+                  DPRINTF(MiscRegs,
+                          "MISCREG: Translated addr 0x%08x: PAR: 0x%08x\n",
+                          val, miscRegs[MISCREG_PAR]);
+              }
+              else {
+                  // Set fault bit and FSR
+                  FSR fsr = miscRegs[MISCREG_DFSR];
+                  miscRegs[MISCREG_PAR] =
+                      (fsr.ext << 6) |
+                      (fsr.fsHigh << 5) |
+                      (fsr.fsLow << 1) |
+                      0x1; // F bit
+              }
+              return;
+            }
         }
     }
     setMiscRegNoEffect(misc_reg, newVal);
index ad8f01dd02216586fbe496e89039be95f45c47e5..267626e74d8d19d7527ffeb56f7da3c40da5a470 100644 (file)
@@ -138,6 +138,15 @@ namespace ArmISA
         MISCREG_CTR,
         MISCREG_SCR,
         MISCREG_SDER,
+        MISCREG_PAR,
+        MISCREG_V2PCWPR,
+        MISCREG_V2PCWPW,
+        MISCREG_V2PCWUR,
+        MISCREG_V2PCWUW,
+        MISCREG_V2POWPR,
+        MISCREG_V2POWPW,
+        MISCREG_V2POWUR,
+        MISCREG_V2POWUW,
         MISCREG_CP15_UNIMP_START,
         MISCREG_TCMTR = MISCREG_CP15_UNIMP_START,
         MISCREG_ID_PFR1,
@@ -153,7 +162,6 @@ namespace ArmISA
         MISCREG_ID_ISAR3,
         MISCREG_ID_ISAR4,
         MISCREG_ID_ISAR5,
-        MISCREG_PAR,
         MISCREG_AIDR,
         MISCREG_ACTLR,
         MISCREG_ADFSR,
@@ -163,14 +171,6 @@ namespace ArmISA
         MISCREG_MCCSW,
         MISCREG_DCCMVAU,
         MISCREG_NSACR,
-        MISCREG_V2PCWPR,
-        MISCREG_V2PCWPW,
-        MISCREG_V2PCWUR,
-        MISCREG_V2PCWUW,
-        MISCREG_V2POWPR,
-        MISCREG_V2POWPW,
-        MISCREG_V2POWUR,
-        MISCREG_V2POWUW,
         MISCREG_VBAR,
         MISCREG_MVBAR,
         MISCREG_ISR,
@@ -206,20 +206,20 @@ namespace ArmISA
         "dtlbiall", "dtlbimva", "dtlbiasid",
         "tlbiall", "tlbimva", "tlbiasid", "tlbimvaa",
         "dfsr", "ifsr", "dfar", "ifar", "mpidr",
-        "prrr", "nmrr",  "ttbcr", "id_pfr0", "ctr"
-        "scr", "sder"
+        "prrr", "nmrr",  "ttbcr", "id_pfr0", "ctr",
+        "scr", "sder", "par",
+        "v2pcwpr", "v2pcwpw", "v2pcwur", "v2pcwuw",
+        "v2powpr", "v2powpw", "v2powur", "v2powuw",
         // Unimplemented below
         "tcmtr",
         "id_pfr1", "id_dfr0", "id_afr0",
         "id_mmfr0", "id_mmfr1", "id_mmfr2", "id_mmfr3",
         "id_isar0", "id_isar1", "id_isar2", "id_isar3", "id_isar4", "id_isar5",
-        "par", "aidr", "actlr",
+        "aidr", "actlr",
         "adfsr", "aifsr",
         "dcimvac", "dcisw", "mccsw",
         "dccmvau",
         "nsacr",
-        "v2pcwpr", "v2pcwpw", "v2pcwur", "v2pcwuw",
-        "v2powpr", "v2powpw", "v2powur", "v2powuw",
         "vbar", "mvbar", "isr", "fceidr",
         "nop", "raz"
     };
index f1e86f0ccff3c7369a224a5a73423f865e5545e7..76b0e3bb838f25b62b5e55fc334058338d1eb60d 100644 (file)
@@ -133,6 +133,14 @@ struct TlbEntry
     bool nonCacheable;     // Can we wrap this in mtype?
     bool sNp;      // Section descriptor
 
+    // Memory Attributes
+    MemoryType mtype;
+    uint8_t innerAttrs;
+    uint8_t outerAttrs;
+    bool shareable;
+    uint32_t attributes;    // Memory attributes formatted for PAR
+
+
     // Access permissions
     bool xn;                // Execute Never
     uint8_t ap:3;           // Access permissions bits
index e3ecb7ddd6d95ea0a25f506fa848b0928c5a949c..85d5b00cf67c610b872f474cd45c7716b0650607 100644 (file)
@@ -96,8 +96,8 @@ TableWalker::walk(RequestPtr _req, ThreadContext *_tc, uint8_t _cid, TLB::Mode m
     contextId = _cid;
     timing = _timing;
 
-    // XXX These should be cached or grabbed from cached copies in
-    // the TLB, all these miscreg reads are expensive
+    /** @todo These should be cached or grabbed from cached copies in
+     the TLB, all these miscreg reads are expensive */
     vaddr = req->getVaddr() & ~PcModeMask;
     sctlr = tc->readMiscReg(MISCREG_SCTLR);
     cpsr = tc->readMiscReg(MISCREG_CPSR);
@@ -149,58 +149,224 @@ TableWalker::walk(RequestPtr _req, ThreadContext *_tc, uint8_t _cid, TLB::Mode m
 }
 
 void
-TableWalker::memAttrs(TlbEntry &te, uint8_t texcb)
+TableWalker::memAttrs(TlbEntry &te, uint8_t texcb, bool s)
 {
-
+    DPRINTF(TLBVerbose, "memAttrs texcb:%d s:%d\n", texcb, s);
+    te.shareable = false; // default value
+    bool outer_shareable = false;
     if (sctlr.tre == 0) {
         switch(texcb) {
-          case 0:
-          case 1:
-          case 4:
-          case 8:
+          case 0: // Stongly-ordered
+            te.nonCacheable = true;
+            te.mtype = TlbEntry::StronglyOrdered;
+            te.shareable = true;
+            te.innerAttrs = 1;
+            te.outerAttrs = 0;
+            break;
+          case 1: // Shareable Device
             te.nonCacheable = true;
+            te.mtype = TlbEntry::Device;
+            te.shareable = true;
+            te.innerAttrs = 3;
+            te.outerAttrs = 0;
+            break;
+          case 2: // Outer and Inner Write-Through, no Write-Allocate
+            te.mtype = TlbEntry::Normal;
+            te.shareable = s;
+            te.innerAttrs = 6;
+            te.outerAttrs = bits(texcb, 1, 0);
+            break;
+          case 3: // Outer and Inner Write-Back, no Write-Allocate
+            te.mtype = TlbEntry::Normal;
+            te.shareable = s;
+            te.innerAttrs = 7;
+            te.outerAttrs = bits(texcb, 1, 0);
+            break;
+          case 4: // Outer and Inner Non-cacheable
+            te.nonCacheable = true;
+            te.mtype = TlbEntry::Normal;
+            te.shareable = s;
+            te.innerAttrs = 0;
+            te.outerAttrs = bits(texcb, 1, 0);
+            break;
+          case 5: // Reserved
+            break;
+          case 6: // Implementation Defined
             break;
-          case 16:
+          case 7: // Outer and Inner Write-Back, Write-Allocate
+            te.mtype = TlbEntry::Normal;
+            te.shareable = s;
+            te.innerAttrs = 5;
+            te.outerAttrs = 1;
+            break;
+          case 8: // Non-shareable Device
+            te.nonCacheable = true;
+            te.mtype = TlbEntry::Device;
+            te.shareable = false;
+            te.innerAttrs = 3;
+            te.outerAttrs = 0;
+            break;
+          case 9 ... 15:  // Reserved
+            break;
+          case 16 ... 31: // Cacheable Memory
+            te.mtype = TlbEntry::Normal;
+            te.shareable = s;
             if (bits(texcb, 1,0) == 0 || bits(texcb, 3,2) == 0)
                 te.nonCacheable = true;
+            te.innerAttrs = bits(texcb, 1, 0);
+            te.outerAttrs = bits(texcb, 3, 2);
             break;
+          default:
+            panic("More than 32 states for 5 bits?\n");
         }
     } else {
         PRRR prrr = tc->readMiscReg(MISCREG_PRRR);
         NMRR nmrr = tc->readMiscReg(MISCREG_NMRR);
+        DPRINTF(TLBVerbose, "memAttrs PRRR:%08x NMRR:%08x\n", prrr, nmrr);
+        uint8_t curr_tr, curr_ir, curr_or;
         switch(bits(texcb, 2,0)) {
           case 0:
-            if (nmrr.ir0 == 0 || nmrr.or0 == 0 || prrr.tr0 != 0x2)
-                te.nonCacheable = true;
+            curr_tr = prrr.tr0;
+            curr_ir = nmrr.ir0;
+            curr_or = nmrr.or0;
+            outer_shareable = (prrr.nos0 == 0);
             break;
           case 1:
-            if (nmrr.ir1 == 0 || nmrr.or1 == 0 || prrr.tr1 != 0x2)
-                te.nonCacheable = true;
+            curr_tr = prrr.tr1;
+            curr_ir = nmrr.ir1;
+            curr_or = nmrr.or1;
+            outer_shareable = (prrr.nos1 == 0);
             break;
           case 2:
-            if (nmrr.ir2 == 0 || nmrr.or2 == 0 || prrr.tr2 != 0x2)
-                te.nonCacheable = true;
+            curr_tr = prrr.tr2;
+            curr_ir = nmrr.ir2;
+            curr_or = nmrr.or2;
+            outer_shareable = (prrr.nos2 == 0);
             break;
           case 3:
-            if (nmrr.ir3 == 0 || nmrr.or3 == 0 || prrr.tr3 != 0x2)
-                te.nonCacheable = true;
+            curr_tr = prrr.tr3;
+            curr_ir = nmrr.ir3;
+            curr_or = nmrr.or3;
+            outer_shareable = (prrr.nos3 == 0);
             break;
           case 4:
-            if (nmrr.ir4 == 0 || nmrr.or4 == 0 || prrr.tr4 != 0x2)
-                te.nonCacheable = true;
+            curr_tr = prrr.tr4;
+            curr_ir = nmrr.ir4;
+            curr_or = nmrr.or4;
+            outer_shareable = (prrr.nos4 == 0);
             break;
           case 5:
-            if (nmrr.ir5 == 0 || nmrr.or5 == 0 || prrr.tr5 != 0x2)
-                te.nonCacheable = true;
+            curr_tr = prrr.tr5;
+            curr_ir = nmrr.ir5;
+            curr_or = nmrr.or5;
+            outer_shareable = (prrr.nos5 == 0);
             break;
           case 6:
             panic("Imp defined type\n");
           case 7:
-            if (nmrr.ir7 == 0 || nmrr.or7 == 0 || prrr.tr7 != 0x2)
-                te.nonCacheable = true;
+            curr_tr = prrr.tr7;
+            curr_ir = nmrr.ir7;
+            curr_or = nmrr.or7;
+            outer_shareable = (prrr.nos7 == 0);
             break;
         }
+
+        switch(curr_tr) {
+          case 0:
+            DPRINTF(TLBVerbose, "StronglyOrdered\n");
+            te.mtype = TlbEntry::StronglyOrdered;
+            te.nonCacheable = true;
+            te.innerAttrs = 1;
+            te.outerAttrs = 0;
+            te.shareable = true;
+            break;
+          case 1:
+            DPRINTF(TLBVerbose, "Device ds1:%d ds0:%d s:%d\n",
+                    prrr.ds1, prrr.ds0, s);
+            te.mtype = TlbEntry::Device;
+            te.nonCacheable = true;
+            te.innerAttrs = 3;
+            te.outerAttrs = 0;
+            if (prrr.ds1 && s)
+                te.shareable = true;
+            if (prrr.ds0 && !s)
+                te.shareable = true;
+            break;
+          case 2:
+            DPRINTF(TLBVerbose, "Normal ns1:%d ns0:%d s:%d\n",
+                    prrr.ns1, prrr.ns0, s);
+            te.mtype = TlbEntry::Normal;
+            if (prrr.ns1 && s)
+                te.shareable = true;
+            if (prrr.ns0 && !s)
+                te.shareable = true;
+            //te.shareable = outer_shareable;
+            break;
+          case 3:
+            panic("Reserved type");
+        }
+
+        if (te.mtype == TlbEntry::Normal){
+            switch(curr_ir) {
+              case 0:
+                te.nonCacheable = true;
+                te.innerAttrs = 0;
+                break;
+              case 1:
+                te.innerAttrs = 5;
+                break;
+              case 2:
+                te.innerAttrs = 6;
+                break;
+              case 3:
+                te.innerAttrs = 7;
+                break;
+            }
+
+            switch(curr_or) {
+              case 0:
+                te.nonCacheable = true;
+                te.outerAttrs = 0;
+                break;
+              case 1:
+                te.outerAttrs = 1;
+                break;
+              case 2:
+                te.outerAttrs = 2;
+                break;
+              case 3:
+                te.outerAttrs = 3;
+                break;
+            }
+        }
     }
+
+    /** Formatting for Physical Address Register (PAR)
+     *  Only including lower bits (TLB info here)
+     *  PAR:
+     *  PA [31:12]
+     *  Reserved [11]
+     *  TLB info [10:1]
+     *      NOS  [10] (Not Outer Sharable)
+     *      NS   [9]  (Non-Secure)
+     *      --   [8]  (Implementation Defined)
+     *      SH   [7]  (Sharable)
+     *      Inner[6:4](Inner memory attributes)
+     *      Outer[3:2](Outer memory attributes)
+     *      SS   [1]  (SuperSection)
+     *      F    [0]  (Fault, Fault Status in [6:1] if faulted)
+     */
+    te.attributes = (
+                ((outer_shareable ? 0:1) << 10) |
+                // TODO: NS Bit
+                ((te.shareable ? 1:0) << 7) |
+                (te.innerAttrs << 4) |
+                (te.outerAttrs << 2)
+                // TODO: Supersection bit
+                // TODO: Fault bit
+                );
+
+
 }
 
 void
@@ -218,11 +384,19 @@ TableWalker::doL1Descriptor()
         if (isFetch)
             fault = new PrefetchAbort(vaddr, ArmFault::Translation0);
         else
-            fault = new DataAbort(vaddr, NULL, isWrite, ArmFault::Translation0);
+            fault = new DataAbort(vaddr, NULL, isWrite,
+                                  ArmFault::Translation0);
         return;
       case L1Descriptor::Section:
-        if (sctlr.afe && bits(l1Desc.ap(), 0) == 0)
-            panic("Haven't implemented AFE\n");
+        if (sctlr.afe && bits(l1Desc.ap(), 0) == 0) {
+            /** @todo: check sctlr.ha (bit[17]) if Hardware Access Flag is
+              * enabled if set, do l1.Desc.setAp0() instead of generating
+              * AccessFlag0
+              */
+
+            fault = new DataAbort(vaddr, NULL, isWrite,
+                                    ArmFault::AccessFlag0);
+        }
 
         if (l1Desc.supersection()) {
             panic("Haven't implemented supersections\n");
@@ -238,7 +412,7 @@ TableWalker::doL1Descriptor()
         te.ap =  l1Desc.ap();
         te.domain = l1Desc.domain();
         te.asid = contextId;
-        memAttrs(te, l1Desc.texcb());
+        memAttrs(te, l1Desc.texcb(), l1Desc.shareable());
 
         DPRINTF(TLB, "Inserting Section Descriptor into TLB\n");
         DPRINTF(TLB, " - N%d pfn:%#x size: %#x global:%d valid: %d\n",
@@ -256,7 +430,8 @@ TableWalker::doL1Descriptor()
       case L1Descriptor::PageTable:
         Addr l2desc_addr;
         l2desc_addr = l1Desc.l2Addr() | (bits(vaddr, 19,12) << 2);
-        DPRINTF(TLB, "L1 descriptor points to page table at: %#x\n", l2desc_addr);
+        DPRINTF(TLB, "L1 descriptor points to page table at: %#x\n",
+                l2desc_addr);
 
         // Trickbox address check
         fault = tlb->walkTrickBoxCheck(l2desc_addr, vaddr, sizeof(uint32_t),
@@ -288,9 +463,6 @@ TableWalker::doL2Descriptor()
     DPRINTF(TLB, "L2 descriptor for %#x is %#x\n", vaddr, l2Desc.data);
     TlbEntry te;
 
-    if (sctlr.afe && bits(l1Desc.ap(), 0) == 0)
-        panic("Haven't implemented AFE\n");
-
     if (l2Desc.invalid()) {
         DPRINTF(TLB, "L2 descriptor invalid, causing fault\n");
         tc = NULL;
@@ -298,10 +470,19 @@ TableWalker::doL2Descriptor()
         if (isFetch)
             fault = new PrefetchAbort(vaddr, ArmFault::Translation1);
         else
-            fault = new DataAbort(vaddr, l1Desc.domain(), isWrite, ArmFault::Translation1);
+            fault = new DataAbort(vaddr, l1Desc.domain(), isWrite,
+                                    ArmFault::Translation1);
         return;
     }
 
+    if (sctlr.afe && bits(l2Desc.ap(), 0) == 0) {
+        /** @todo: check sctlr.ha (bit[17]) if Hardware Access Flag is enabled
+          * if set, do l2.Desc.setAp0() instead of generating AccessFlag0
+          */
+
+        fault = new DataAbort(vaddr, NULL, isWrite, ArmFault::AccessFlag1);
+    }
+
     if (l2Desc.large()) {
       te.N = 16;
       te.pfn = l2Desc.pfn();
@@ -319,7 +500,7 @@ TableWalker::doL2Descriptor()
     te.xn = l2Desc.xn();
     te.ap = l2Desc.ap();
     te.domain = l1Desc.domain();
-    memAttrs(te, l2Desc.texcb());
+    memAttrs(te, l2Desc.texcb(), l2Desc.shareable());
 
     tc = NULL;
     req = NULL;
index 8e851acd7976008553296ff92b1bb0f1daa8b915..f6d3bee06cc328317a296d5546405f5c6c6d1b38 100644 (file)
@@ -68,8 +68,13 @@ class TableWalker : public MemObject
             Reserved
         };
 
+        /** The raw bits of the entry */
         uint32_t data;
 
+        /** This entry has been modified (access flag set) and needs to be
+         * written back to memory */
+        bool _dirty;
+
         EntryType type() const
         {
             return (EntryType)(data & 0x3);
@@ -127,19 +132,48 @@ class TableWalker : public MemObject
             return mbits(data, 31,10);
         }
 
-        /** Memory region attributes: ARM DDI 0406B: B3-32 */
+        /** Memory region attributes: ARM DDI 0406B: B3-32.
+         * These bits are largly ignored by M5 and only used to
+         * provide the illusion that the memory system cares about
+         * anything but cachable vs. uncachable.
+         */
         uint8_t texcb() const
         {
             return bits(data, 2) | bits(data,3) << 1 | bits(data, 14, 12) << 2;
         }
 
+        /** If the section is shareable. See texcb() comment. */
+        bool shareable() const
+        {
+            return bits(data, 16);
+        }
+
+        /** Set access flag that this entry has been touched. Mark
+         * the entry as requiring a writeback, in the future.
+         */
+        void setAp0()
+        {
+            data |= 1 << 10;
+            _dirty = true;
+        }
+
+        /** This entry needs to be written back to memory */
+        bool dirty() const
+        {
+            return _dirty;
+        }
     };
 
     /** Level 2 page table descriptor */
     struct L2Descriptor {
 
+        /** The raw bits of the entry. */
         uint32_t data;
 
+        /** This entry has been modified (access flag set) and needs to be
+         * written back to memory */
+        bool _dirty;
+
         /** Is the entry invalid */
         bool invalid() const
         {
@@ -184,6 +218,27 @@ class TableWalker : public MemObject
             return large() ? bits(data, 31, 16) : bits(data, 31, 12);
         }
 
+        /** If the section is shareable. See texcb() comment. */
+        bool shareable() const
+        {
+            return bits(data, 10);
+        }
+
+        /** Set access flag that this entry has been touched. Mark
+         * the entry as requiring a writeback, in the future.
+         */
+        void setAp0()
+        {
+            data |= 1 << 4;
+            _dirty = true;
+        }
+
+        /** This entry needs to be written back to memory */
+        bool dirty() const
+        {
+            return _dirty;
+        }
+
     };
 
     /** Port to issue translation requests from */
@@ -252,9 +307,9 @@ class TableWalker : public MemObject
             TLB::Translation *_trans, bool timing);
 
     void setTlb(TLB *_tlb) { tlb = _tlb; }
+    void memAttrs(TlbEntry &te, uint8_t texcb, bool s);
 
   private:
-    void memAttrs(TlbEntry &te, uint8_t texcb);
 
     void doL1Descriptor();
     EventWrapper<TableWalker, &TableWalker::doL1Descriptor> doL1DescEvent;
index 05d65457ce47e8d5ee2ded2aa46972838987c59b..7f02061b0d130fc00711d2768e0dfc4e076e3a7c 100644 (file)
@@ -384,6 +384,16 @@ TLB::translateFs(RequestPtr req, ThreadContext *tc, Mode mode,
             if (nmrr.ir0 == 0 || nmrr.or0 == 0 || prrr.tr0 != 0x2)
                req->setFlags(Request::UNCACHEABLE);
         }
+
+        // Set memory attributes
+        TlbEntry temp_te;
+        tableWalker->memAttrs(temp_te, 0, 1);
+        temp_te.shareable = true;
+        DPRINTF(TLBVerbose, "(No MMU) setting memory attributes: shareable:\
+                %d, innerAttrs: %d, outerAttrs: %d\n", temp_te.shareable,
+                temp_te.innerAttrs, temp_te.outerAttrs);
+        setAttr(temp_te.attributes);
+
         return trickBoxCheck(req, mode, 0, false);
     }
 
@@ -409,6 +419,13 @@ TLB::translateFs(RequestPtr req, ThreadContext *tc, Mode mode,
         assert(te);
     }
 
+    // Set memory attributes
+    DPRINTF(TLBVerbose,
+            "Setting memory attributes: shareable: %d, innerAttrs: %d, \
+            outerAttrs: %d\n",
+            te->shareable, te->innerAttrs, te->outerAttrs);
+    setAttr(te->attributes);
+
     uint32_t dacr = tc->readMiscReg(MISCREG_DACR);
     switch ( (dacr >> (te->domain * 2)) & 0x3) {
       case 0:
index c2894e5cdfdc363a29bf6ee59a1300f5bf112855..a779a492d6fafc41675c32a9b7206fe273845f36 100644 (file)
@@ -88,6 +88,8 @@ class TLB : public BaseTLB
     int size;                  // TLB Size
     int nlu;                   // not last used entry (for replacement)
 
+    uint32_t _attr;      // Memory attributes for last accessed TLB entry
+
 #if FULL_SYSTEM
     TableWalker *tableWalker;
 #endif
@@ -151,6 +153,19 @@ class TLB : public BaseTLB
 
     static bool validVirtualAddress(Addr vaddr);
 
+    /** Accessor functions for memory attributes for last accessed TLB entry
+     */
+    void
+    setAttr(uint32_t attr)
+    {
+        _attr = attr;
+    }
+    uint32_t
+    getAttr() const
+    {
+        return _attr;
+    }
+
 #if FULL_SYSTEM
     Fault translateFs(RequestPtr req, ThreadContext *tc, Mode mode,
             Translation *translation, bool &delay, bool timing);