5.4 Virtual Address Space and Translation

<< Click to Display Table of Contents >>

Navigation:  ASA-EMulatR Reference Guide > Introduction > Architecture Overview > Chapter 5 - Memory System Architecture >

5.4 Virtual Address Space and Translation

5.4.1 Virtual Address Space

 

All instructions operate on virtual addresses. The emulator models per-CPU ITB (Instruction TLB) and DTB (Data TLB) with ASN (Address Space Number) tagging and page-level permissions.

 


 

5.4.2 Translation Responsibility

 

Address translation occurs in MBox during the EX stage. The Ev6Translator (ev6Translation_struct.h, 1,336 lines) provides the translation engine. Translation responsibilities include: VA→PA conversion, ITB/DTB miss detection, access violation detection, alignment fault detection, and precise translation fault raising.

 

Translation never occurs in fetch (IBox translates instruction addresses separately), decode, or writeback.

 

The translator supports two paths:

 

ev6TranslateFastVA() — checks canonical address, tries KSEG fast-path (kernel segment direct mapping), then TLB lookup. Returns TranslationResult on miss without walking.

 

ev6TranslateFullVA() — same checks plus full page table walk on TLB miss, using the three-level Alpha page table structure (L1/L2/L3).

 

TranslationResult values: Success, TlbMiss, NonCanonical, PageNotPresent, FaultOnWrite, FaultOnRead, FaultOnExecute, AccessViolation, BusError.

 


 

5.4.3 Translation Order-of-Operations Contract (Normative)

 

Every data access (load or store) must follow this exact ordered sequence. No step may be skipped or reordered. A fault at any step terminates the sequence — subsequent steps do not execute.

 

Step 1 — Canonical VA Check. Bits above (vaBits−1) must be a sign-extension of bit (vaBits−1). A non-canonical address produces TranslationResult::NonCanonical and raises a non-canonical address fault via makeNonCanonicalAddressEvent(). No TLB lookup is attempted.

 

Step 2 — KSEG Fast-Path Check. If the VA falls in the kernel segment direct-mapping region, the PA is computed directly without TLB involvement. This applies only in kernel mode (CM=0). KSEG addresses bypass Steps 3–6 entirely.

 

Step 3 — TLB Lookup. The SPAM TLB cache is probed: globalEv6SPAM().tlbLookup(cpuId, realm, va, asn, pfn, perm, sizeClass). The lookup uses VPN = VA >> pageShift plus ASN matching (entry.asn == currentASN || entry.global). On hit, the TLB returns three values: pfn (page frame number), perm (permission mask), and sizeClass (granularity hint from the PTE that filled this entry). On miss, the sequence raises makeDTBMissEvent() or makeITBMissEvent() and terminates — PAL handles the page table walk and TLB refill.

 

Step 4 — PTE Valid Bit Check. The permission mask returned by the TLB is checked for validity via AlphaN_S::isValid(perm). An invalid entry produces TranslationResult::AccessViolation.

 

Step 5 — Fault-On-Access Bit Check. The PTE fault bits are checked: FOR (Fault-On-Read) for loads via AlphaN_S::isFaultOnRead(perm), FOW (Fault-On-Write) for stores via AlphaN_S::isFaultOnWrite(perm), FOE (Fault-On-Execute) for instruction fetches via AlphaN_S::isFaultOnExecute(perm). These bits support copy-on-write (FOW), demand paging (FOR), and execute-disable (FOE). A set fault bit produces the corresponding TranslationResult and raises the appropriate fault event.

 

Step 6 — Permission Check Against Current Mode. The access is checked against the current processor mode (CM) obtained from getCM_Active(cpuId). For kernel mode: AlphaN_S::canReadKernel(perm) / canWriteKernel(perm). For user mode: canReadUser(perm) / canWriteUser(perm). Executive and supervisor modes use their respective permission fields. A denied access produces TranslationResult::AccessViolation.

 

Step 7 — Physical Address Calculation. On success, the PA is computed from the TLB hit results (see Section 5.4.6 below).

 

Instruction fetches follow the same sequence using Realm::I (ITB) instead of Realm::D (DTB), with FOE checked instead of FOR/FOW, and execute permission checked instead of read/write.

 


 

5.4.4 Alpha VA Format

 

The Alpha AXP virtual address format is implementation-dependent, selected at CPU/board bring-up, not inferred from VA bits. The format is determined by page size (pageShift) and implemented VA width (vaBits):

 

8K pages — pageShift=13, levelBits=10, vaBits=43. Fields: SEG[42:41], L1[40:33] (8 bits), L2[32:23] (10 bits), L3[22:13] (10 bits), OFFSET[12:0] (13 bits).

 

16K pages — pageShift=14, levelBits=11, vaBits=43..47. L2 and L3 are 11 bits each. L1 width = vaBits − 2 − (14 + 22), ranging from 5 bits (vaBits=43) to 9 bits (vaBits=47).

 

32K pages — pageShift=15, levelBits=12, vaBits=43..51. L2 and L3 are 12 bits each. L1 width ranges from 2 bits (minimum, vaBits=43) to 10 bits (vaBits=51).

 

64K pages — pageShift=16, levelBits=13, vaBits=46..55. L2 and L3 are 13 bits each. Minimum vaBits=46 required to satisfy the architectural constraint that L1 must be at least 2 bits (L1 width = vaBits − 44).

 

In all cases, bits above (vaBits−1) must be a sign-extension of bit (vaBits−1) for the address to be canonical. The segment field (2 bits) selects the address space quadrant. The three-level page table uses L1, L2, and L3 fields to index into page table entries, with the offset field providing the byte-within-page address.

 

The VA field boundaries are derived from the selected option, not detected from the VA itself:

 

offsetMask = (1ULL << pageShift) - 1

Segment = VA[vaBits-1 : vaBits-2]

L3 = VA[pageShift + levelBits - 1 : pageShift]

L2 = VA[pageShift + 2*levelBits - 1 : pageShift + levelBits]

L1 width = vaBits - 2 - (pageShift + 2*levelBits)

L1 = VA[vaBits-3 : pageShift + 2*levelBits]

 


 

5.4.5 Size Class Contract (Normative)

 

There are two distinct page-size concepts in the Alpha architecture, and conflating them is a common source of implementation errors:

 

Base page size (VA format option) is fixed at implementation time. For EV6, this is always 8 KB (pageShift=13). It determines how the VA fields are decoded (Section 5.4.4) and is a compile-time constant. It never changes during execution.

 

Granularity Hint (GH) superpages are per-PTE attributes established only at TLB fill time. On EV6, GH encodes four size classes: GH=0 → 8 KB (1 page), GH=1 → 64 KB (8 pages), GH=2 → 512 KB (64 pages), GH=3 → 4 MB (512 pages). GH is stored in the PTE and copied into the TLB entry when the entry is created.

 

Size class is not:

 

A property of the VA — you cannot determine the size class by examining any VA bits. A property of the instruction — the instruction does not encode or imply page size. A property of the ASN — different pages within the same address space may have different GH values. A global CPU mode — there is no "superpage mode" that applies to all translations.

 

Size class lifecycle:

 

Instruction generates VA

 ↓

TLB lookup miss

 ↓

PAL / hardware page table walk

 ↓

PTE is read from page table in memory

 ↓

PTE GH bits decoded → sizeClass determined

 ↓

TLB entry created: { VPN (masked by sizeClass), PFN, ASN, perms, sizeClass }

 

The only authoritative source of size class is the PTE used to fill the TLB entry. Once stored, the TLB entry's sizeClass determines how the PA is calculated on subsequent hits. TLB invalidation (TBIS/TBISD) invalidates by VA range and ASN without needing to know the sizeClass — the sizeClass is an attribute of the entry being invalidated, not a parameter to the invalidation.

 

Implementation consequence: The TLB lookup does not accept sizeClass as an input parameter. The lookup probes by VPN and ASN; on hit, it returns sizeClass as an output alongside pfn and perm. The caller uses the returned sizeClass to compute the PA (Section 5.4.6). On most workloads, the vast majority of TLB entries use GH=0 (8 KB); superpages (GH=1..3) are rare, typically used for kernel large mappings and shared library text segments.

 


 

5.4.6 Physical Address Calculation Contract (Normative)

 

After a successful TLB hit (Step 7 of the translation sequence), the physical address is calculated from three values returned by the TLB lookup:

 

Value

Source

pfn

Page Frame Number from the TLB entry (originally from PTE bits [52:32] on EV6)

sizeClass

Granularity hint from the TLB entry (originally from PTE GH bits, decoded at fill time)

va

The original virtual address from the instruction

 

The calculation:

 

pageShift = PageSizeHelpers::pageShift(sizeClass) // 13, 16, 19, or 22

pageMask = (1ULL << pageShift) - 1 // offset within page

PA = (pfn << 13) | (va & pageMask) // always shift by 13

 

Critical detail: The PFN shift is always 13 (the base page shift), regardless of the GH size class. This is because the PFN in the PTE is defined relative to the base 8 KB page size. For superpages, the offset mask (pageMask) is wider — it extracts more bits from the VA to form the byte offset within the larger page. The PFN itself already accounts for the superpage alignment: a 64 KB superpage (GH=1) has its low 3 PFN bits zero by construction, a 512 KB superpage (GH=2) has its low 6 PFN bits zero, and so on.

 

GH

Page Size

pageShift

Offset Bits from VA

0

8 KB

13

VA[12:0]

1

64 KB

16

VA[15:0]

2

512 KB

19

VA[18:0]

3

4 MB

22

VA[21:0]

 

Invariant: The pageMask used to extract the offset from the VA is determined solely by the sizeClass stored in the TLB entry that matched — never by examining VA bits, never by a global mode, and never by the instruction. The PFN is always shifted left by 13 regardless of GH.

 


 

5.4.7 Alpha VA Field Boundary Reference

 

8K Pages (EV6 default: pageShift=13, levelBits=10, vaBits=43):

 [42:41] [40:33] [32:23] [22:13] [12:0]

 SEG L1 L2 L3 OFFSET(8K)

 

16K Pages (pageShift=14, levelBits=11, vaBits=43 minimum):

 [42:41] [40:36] [35:25] [24:14] [13:0]

 SEG L1 L2 L3 OFFSET(16K)

 

32K Pages (pageShift=15, levelBits=12, vaBits=43 minimum):

 [42:41] [40:39] [38:27] [26:15] [14:0]

 SEG L1 L2 L3 OFFSET(32K)

 

64K Pages (pageShift=16, levelBits=13, vaBits=46 minimum):

 [45:44] [43:42] [41:29] [28:16] [15:0]

 SEG L1 L2 L3 OFFSET(64K)

 

Implementation note: The VA option is selected once at configuration time. EV6 is hardwired to 8K pages (pageShift=13, vaBits=43). The TLB lookup uses VPN = VA >> pageShift plus ASN/global/mode checks. Mixed page sizes within a single VA option are handled as TLB entry attributes (sizeClass from GH), not by reinterpreting VA fields. Do not scan VA options (8K/16K/32K/64K) on every lookup.

 

See Also: pteLib/ev6Translation_struct.h; Chapter 17 – Address Translation, TLB, and PTE ; Appendix A – EV6 Internal Processor Register (IPR) Reference  (DTB_TAG, DTB_PTE IPRs); Alpha Architecture Reference Manual v6, Memory Management chapter.