2c2
< * Copyright (c) 2010, 2012-2013 ARM Limited
---
> * Copyright (c) 2010, 2012-2014 ARM Limited
223c223
< currState->ttbcr = currState->tc->readMiscReg(MISCREG_TCR_EL1);
---
> currState->tcr = currState->tc->readMiscReg(MISCREG_TCR_EL1);
229c229
< // currState->ttbcr = currState->tc->readMiscReg(MISCREG_TCR_EL2);
---
> // currState->tcr = currState->tc->readMiscReg(MISCREG_TCR_EL2);
234c234
< currState->ttbcr = currState->tc->readMiscReg(MISCREG_TCR_EL3);
---
> currState->tcr = currState->tc->readMiscReg(MISCREG_TCR_EL3);
628,629c628
< currState->longDesc.largeGrain = false;
< currState->longDesc.grainSize = 12;
---
> currState->longDesc.grainSize = Grain4KB;
666,667c665,666
< DPRINTF(TLB, "Beginning table walk for address %#llx, TTBCR: %#llx\n",
< currState->vaddr_tainted, currState->ttbcr);
---
> DPRINTF(TLB, "Beginning table walk for address %#llx, TCR: %#llx\n",
> currState->vaddr_tainted, currState->tcr);
668a668,672
> static const GrainSize GrainMapDefault[] =
> { Grain4KB, Grain64KB, Grain16KB, ReservedGrain };
> static const GrainSize GrainMap_EL1_tg1[] =
> { ReservedGrain, Grain16KB, Grain4KB, Grain64KB };
>
672c676
< bool large_grain = false;
---
> GrainSize tg = Grain4KB; // grain size computed from tg* field
681,682c685,686
< tsz = adjustTableSizeAArch64(64 - currState->ttbcr.t0sz);
< large_grain = currState->ttbcr.tg0;
---
> tsz = adjustTableSizeAArch64(64 - currState->tcr.t0sz);
> tg = GrainMapDefault[currState->tcr.tg0];
684c688
< currState->ttbcr.epd0)
---
> currState->tcr.epd0)
690,691c694,695
< tsz = adjustTableSizeAArch64(64 - currState->ttbcr.t1sz);
< large_grain = currState->ttbcr.tg1;
---
> tsz = adjustTableSizeAArch64(64 - currState->tcr.t1sz);
> tg = GrainMap_EL1_tg1[currState->tcr.tg1];
693c697
< currState->ttbcr.epd1)
---
> currState->tcr.epd1)
700c704
< ps = currState->ttbcr.ips;
---
> ps = currState->tcr.ips;
706,712c710,716
< DPRINTF(TLB, " - Selecting TTBR0 (AArch64)\n");
< if (currState->el == EL2)
< ttbr = currState->tc->readMiscReg(MISCREG_TTBR0_EL2);
< else
< ttbr = currState->tc->readMiscReg(MISCREG_TTBR0_EL3);
< tsz = adjustTableSizeAArch64(64 - currState->ttbcr.t0sz);
< large_grain = currState->ttbcr.tg0;
---
> DPRINTF(TLB, " - Selecting TTBR0 (AArch64)\n");
> if (currState->el == EL2)
> ttbr = currState->tc->readMiscReg(MISCREG_TTBR0_EL2);
> else
> ttbr = currState->tc->readMiscReg(MISCREG_TTBR0_EL3);
> tsz = adjustTableSizeAArch64(64 - currState->tcr.t0sz);
> tg = GrainMapDefault[currState->tcr.tg0];
716c720
< fault = true;
---
> fault = true;
718c722
< ps = currState->ttbcr.ps;
---
> ps = currState->tcr.ips;
746a751,759
> if (tg == ReservedGrain) {
> warn_once("Reserved granule size requested; gem5's IMPLEMENTATION "
> "DEFINED behavior takes this to mean 4KB granules\n");
> tg = Grain4KB;
> }
>
> int stride = tg - 3;
> LookupLevel start_lookup_level = MAX_LOOKUP_LEVELS;
>
748,767c761,794
< LookupLevel start_lookup_level;
< int grain_size, stride;
< if (large_grain) { // 64 KB granule
< grain_size = 16;
< stride = grain_size - 3;
< if (tsz > grain_size + 2 * stride)
< start_lookup_level = L1;
< else if (tsz > grain_size + stride)
< start_lookup_level = L2;
< else
< start_lookup_level = L3;
< } else { // 4 KB granule
< grain_size = 12;
< stride = grain_size - 3;
< if (tsz > grain_size + 3 * stride)
< start_lookup_level = L0;
< else if (tsz > grain_size + 2 * stride)
< start_lookup_level = L1;
< else
< start_lookup_level = L2;
---
> // See aarch64/translation/walk in Appendix G: ARMv8 Pseudocode Library
> // in ARM DDI 0487A. These table values correspond to the cascading tests
> // to compute the lookup level and are of the form
> // (grain_size + N*stride), for N = {1, 2, 3}.
> // A value of 64 will never succeed and a value of 0 will always succeed.
> {
> struct GrainMap {
> GrainSize grain_size;
> unsigned lookup_level_cutoff[MAX_LOOKUP_LEVELS];
> };
> static const GrainMap GM[] = {
> { Grain4KB, { 39, 30, 0, 0 } },
> { Grain16KB, { 47, 36, 25, 0 } },
> { Grain64KB, { 64, 42, 29, 0 } }
> };
>
> const unsigned *lookup = NULL; // points to a lookup_level_cutoff
>
> for (unsigned i = 0; i < 3; ++i) { // choose entry of GM[]
> if (tg == GM[i].grain_size) {
> lookup = GM[i].lookup_level_cutoff;
> break;
> }
> }
> assert(lookup);
>
> for (int L = L0; L != MAX_LOOKUP_LEVELS; ++L) {
> if (tsz > lookup[L]) {
> start_lookup_level = (LookupLevel) L;
> break;
> }
> }
> panic_if(start_lookup_level == MAX_LOOKUP_LEVELS,
> "Table walker couldn't find lookup level\n");
771,772c798
< int base_addr_lo = 3 + tsz - stride * (3 - start_lookup_level) -
< grain_size;
---
> int base_addr_lo = 3 + tsz - stride * (3 - start_lookup_level) - tg;
815c841
< stride * (3 - start_lookup_level) + grain_size) << 3);
---
> stride * (3 - start_lookup_level) + tg) << 3);
842,843c868
< currState->longDesc.largeGrain = large_grain;
< currState->longDesc.grainSize = grain_size;
---
> currState->longDesc.grainSize = tg;