Add valid bit check to permission validator
[soc.git] / TLB / src / PermissionValidator.py
1 from nmigen import Module, Signal
2 from nmigen.cli import main
3
4 class PermissionValidator():
5 """ The purpose of this Module is to check the Permissions of a given PTE
6 against the requested access permissions.
7
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
11 """
12
13 def __init__(self, data_size):
14 """ Arguments:
15 * data_size: (bit count) The size of the data words being processed
16
17 Return:
18 * valid HIGH when permissions are correct
19 """
20 # Input
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)
26
27 # Output
28 self.valid = Signal(1) # Denotes if the permissions are correct
29
30 def elaborate(self, platform=None):
31 m = Module()
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])):
41 # Supervisor Logic
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)
47 # User logic
48 with m.Else():
49 # Valid if the entry is in user mode only
50 m.d.comb += self.valid.eq(self.data[4])
51 with m.Else():
52 m.d.comb += self.valid.eq(0)
53 with m.Else():
54 m.d.comb += self.valid.eq(0)
55 with m.Else():
56 m.d.comb += self.valid.eq(0)
57 return m