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