1 from nmigen
import Module
, Signal
2 from nmigen
.cli
import main
4 class PermissionValidator():
5 """ The purpose of this Module is to check the Permissions of a given PTE
6 against the requested access permissions.
8 This module will either validate (by setting the valid bit HIGH)
9 the request or find a permission fault and invalidate (by setting
10 the valid bit LOW) the request
13 def __init__(self
, data_size
):
15 * data_size: (bit count) The size of the data words being processed
18 * valid HIGH when permissions are correct
21 self
.data
= Signal(data_size
);
22 self
.xwr
= Signal(3) # Execute, Write, Read
23 self
.super_mode
= Signal(1) # Supervisor Mode
24 self
.super_access
= Signal(1) # Supervisor Access
25 self
.asid
= Signal(15) # Address Space IDentifier (ASID)
28 self
.valid
= Signal(1) # Denotes if the permissions are correct
30 def elaborate(self
, platform
=None):
32 # Check if the entry is valid
33 with m
.If(self
.data
[0]):
34 # ASID match or Global Permission
35 # Note that the MSB bound is exclusive
36 with m
.If((self
.data
[64:79] == self
.asid
) | self
.data
[5]):
37 # Check Execute, Write, Read (XWR) Permissions
38 with m
.If((self
.data
[3] == self
.xwr
[2]) \
39 & (self
.data
[2] == self
.xwr
[1]) \
40 & (self
.data
[1] == self
.xwr
[0])):
42 with m
.If(self
.super_mode
):
43 # Valid if entry is not in user mode or supervisor
44 # has Supervisor User Memory (SUM) access via the
45 # SUM bit in the sstatus register
46 m
.d
.comb
+= self
.valid
.eq((~self
.data
[4]) | self
.super_access
)
49 # Valid if the entry is in user mode only
50 m
.d
.comb
+= self
.valid
.eq(self
.data
[4])
52 m
.d
.comb
+= self
.valid
.eq(0)
54 m
.d
.comb
+= self
.valid
.eq(0)
56 m
.d
.comb
+= self
.valid
.eq(0)