e7c3b774625ca32d5b7c3cf709c035afbb307ec6
[soc.git] / TLB / PermissionValidator.py
1 from nmigen import Signal, Module, If, Else
2 from nmigen.cli import main
3
4 # The expected form of the data is
5 # Item (Bits)
6 # Tag (N - 79) / ASID (78 - 64) / PTE (63 - 0)
7
8 # The purpose of this Module is to check the Permissions of a given PTE
9 # against the requested access permissions.
10 # This module will either validate (by setting the valid bit HIGH) the request
11 # or find a permission fault and invalidate (by setting the valid bit LOW)
12 # the request
13 class PermissionValidator():
14 def __init__(self, data_size):
15 # Input
16 self.data = Signal(data_size);
17 self.xwr = Signal(3) # Execute, Write, Read
18 self.super = Signal(1) # Supervisor Mode
19 self.super_access = Signal(1) # Supervisor Access
20 self.asid = Signal(15) # Address Space IDentifier (ASID)
21
22 # Output
23 self.valid = Signal(1) # Denotes if the permissions are correct
24
25 def elaborate(self, platform):
26 m = Module()
27 m.d.comb += [
28 # Check if ASID matches OR entry is global
29 If(data[64:78] == self.asid or data[5] == 1,
30 # Check Execute, Write, Read (XWR) Permissions
31 If(data[3] == self.xwr[2] and data[2] == self.xwr[1] \
32 and data[1] == self.xwr[0],
33 # Check if supervisor
34 If(self.super == 1,
35 # Check if entry is in user mode
36 # Check if supervisor has access
37 If(data[4] == 0,
38 self.valid.eq(1)
39 ).Elif(self.super_access == 1,
40 self.valid.eq(1)
41 ).Else(
42 self.valid.eq(0)
43 )
44 ).Else(
45 # Check if entry is in user mode
46 If(data[4] == 1,
47 self.valid.eq(1)
48 ).Else(
49 self.valid.eq(0)
50 )
51 )
52 ).Else(
53 self.valid.eq(0)
54 )
55 ).Else(
56 self.valid.eq(0)
57 )
58 ]