1 from nmigen
import Module
, Signal
, Elaboratable
2 from nmigen
.cli
import main
4 from TLB
.PteEntry
import PteEntry
7 class PermissionValidator(Elaboratable
):
8 """ The purpose of this Module is to check the Permissions of a given PTE
9 against the requested access permissions.
11 This module will either validate (by setting the valid bit HIGH)
12 the request or find a permission fault and invalidate (by setting
13 the valid bit LOW) the request
16 def __init__(self
, asid_size
, pte_size
):
18 * asid_size: (bit count) The size of the asid to be processed
19 * pte_size: (bit count) The size of the pte to be processed
22 * valid HIGH when permissions are correct
25 self
.pte_entry
= PteEntry(asid_size
, pte_size
)
28 self
.data
= Signal(asid_size
+ pte_size
);
29 self
.xwr
= Signal(3) # Execute, Write, Read
30 self
.super_mode
= Signal(1) # Supervisor Mode
31 self
.super_access
= Signal(1) # Supervisor Access
32 self
.asid
= Signal(15) # Address Space IDentifier (ASID)
35 self
.valid
= Signal(1) # Denotes if the permissions are correct
37 def elaborate(self
, platform
=None):
40 m
.submodules
.pte_entry
= self
.pte_entry
42 m
.d
.comb
+= self
.pte_entry
.i
.eq(self
.data
)
44 # Check if the entry is valid
45 with m
.If(self
.pte_entry
.v
):
46 # ASID match or Global Permission
47 # Note that the MSB bound is exclusive
48 with m
.If((self
.pte_entry
.asid
== self
.asid
) | self
.pte_entry
.g
):
49 # Check Execute, Write, Read (XWR) Permissions
50 with m
.If(self
.pte_entry
.xwr
== self
.xwr
):
52 with m
.If(self
.super_mode
):
53 # Valid if entry is not in user mode or supervisor
54 # has Supervisor User Memory (SUM) access via the
55 # SUM bit in the sstatus register
56 m
.d
.comb
+= self
.valid
.eq((~self
.pte_entry
.u
) \
60 # Valid if the entry is in user mode only
61 m
.d
.comb
+= self
.valid
.eq(self
.pte_entry
.u
)
63 m
.d
.comb
+= self
.valid
.eq(0)
65 m
.d
.comb
+= self
.valid
.eq(0)
67 m
.d
.comb
+= self
.valid
.eq(0)