Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added submissions/mreddybalaji/Output file.docx
Binary file not shown.
80 changes: 80 additions & 0 deletions submissions/mreddybalaji/pmp_check.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import sys

def parse_pmp_config(file_path):
with open(file_path, 'r') as f:
lines = [line.strip() for line in f.readlines()]

if len(lines) != 128:
raise ValueError("PMP configuration file must contain exactly 128 lines.")

pmpcfg = [int(lines[i], 16) for i in range(64)]
pmpaddr = [int(lines[i], 16) for i in range(64, 128)]

return pmpcfg, pmpaddr

def check_pmp_access(pmpcfg, pmpaddr, address, privilege_mode, operation):
for i in range(64):
cfg = (pmpcfg[i // 8] >> ((i % 8) * 8)) & 0xFF
addr = pmpaddr[i] << 2 # pmpaddr is in 4-byte granularity

A = (cfg >> 3) & 0b11 # Address-matching mode
R = (cfg >> 0) & 1 # Read permission
W = (cfg >> 1) & 1 # Write permission
X = (cfg >> 2) & 1 # Execute permission

print(f"PMP Entry {i}: A={A}, R={R}, W={W}, X={X}, addr={hex(addr)}") # Debugging output

if A == 0: # Disabled
continue
elif A == 1: # TOR (Top of Range)
if i == 0:
continue
lower_bound = pmpaddr[i - 1] << 2
upper_bound = addr
print(f" Checking TOR: [{hex(lower_bound)}, {hex(upper_bound)})")
if lower_bound <= address < upper_bound:
return validate_access(R, W, X, privilege_mode, operation)
elif A == 2: # NA4 (Naturally aligned 4-byte region)
print(f" Checking NA4: {hex(addr)}")
if addr == address:
return validate_access(R, W, X, privilege_mode, operation)
elif A == 3: # NAPOT (Naturally aligned power-of-two region)
size = 1 << ((~addr & (addr + 1)).bit_length()) # Corrected NAPOT size calculation
base = addr & ~(size - 1)
print(f" Checking NAPOT: Base={hex(base)}, Size={hex(size)}")
if base <= address < base + size:
return validate_access(R, W, X, privilege_mode, operation)

# If no PMP entry matches, access is **allowed in M-mode** but **faulted in U-mode**
return privilege_mode == 'U' # True = fault, False = allowed

def validate_access(R, W, X, privilege_mode, operation):
if operation == 'R' and not R:
return True
if operation == 'W' and not W:
return True
if operation == 'X' and not X:
return True
return False # No fault

def main():
if len(sys.argv) != 5:
print("Usage: python pmp_check.py <pmp_config_file> <address> <privilege_mode> <operation>")
sys.exit(1)

pmp_config_file = sys.argv[1]
address = int(sys.argv[2], 16)
privilege_mode = sys.argv[3]
operation = sys.argv[4]

if privilege_mode not in {'M', 'S', 'U'} or operation not in {'R', 'W', 'X'}:
print("Invalid privilege mode or operation.")
sys.exit(1)

pmpcfg, pmpaddr = parse_pmp_config(pmp_config_file)
access_fault = check_pmp_access(pmpcfg, pmpaddr, address, privilege_mode, operation)

print("Access Fault" if access_fault else "Access Allowed")

if __name__ == "__main__":
main()
128 changes: 128 additions & 0 deletions submissions/mreddybalaji/pmp_configuration.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
0x00000000
0x00000001
0x00000003
0x00000007
0x0000000F
0x0000001F
0x0000003F
0x0000007F
0x000000FF
0x000001FF
0x000003FF
0x000007FF
0x00000FFF
0x00001FFF
0x00003FFF
0x00007FFF
0x0000FFFF
0x0001FFFF
0x0003FFFF
0x0007FFFF
0x000FFFFF
0x001FFFFF
0x003FFFFF
0x007FFFFF
0x00FFFFFF
0x01FFFFFF
0x03FFFFFF
0x07FFFFFF
0x0FFFFFFF
0x1FFFFFFF
0x3FFFFFFF
0x7FFFFFFF
0x80000000
0x80000001
0x80000003
0x80000007
0x8000000F
0x8000001F
0x8000003F
0x8000007F
0x800000FF
0x800001FF
0x800003FF
0x800007FF
0x80000FFF
0x80001FFF
0x80003FFF
0x80007FFF
0x8000FFFF
0x8001FFFF
0x8003FFFF
0x8007FFFF
0x800FFFFF
0x801FFFFF
0x803FFFFF
0x807FFFFF
0x80FFFFFF
0x81FFFFFF
0x83FFFFFF
0x87FFFFFF
0x8FFFFFFF
0x9FFFFFFF
0xAFFFFFFF
0xBFFFFFFF
0xC0000000
0xC0000001
0xC0000003
0xC0000007
0xC000000F
0xC000001F
0xC000003F
0xC000007F
0xC00000FF
0xC00001FF
0xC00003FF
0xC00007FF
0xC0000FFF
0xC0001FFF
0xC0003FFF
0xC0007FFF
0xC000FFFF
0xC001FFFF
0xC003FFFF
0xC007FFFF
0xC00FFFFF
0xC01FFFFF
0xC03FFFFF
0xC07FFFFF
0xC0FFFFFF
0xC1FFFFFF
0xC3FFFFFF
0xC7FFFFFF
0xCFFFFFFF
0xDFFFFFFF
0xEFFFFFFF
0xF0000000
0xF0000001
0xF0000003
0xF0000007
0xF000000F
0xF000001F
0xF000003F
0xF000007F
0xF00000FF
0xF00001FF
0xF00003FF
0xF00007FF
0xF0000FFF
0xF0001FFF
0xF0003FFF
0xF0007FFF
0xF000FFFF
0xF001FFFF
0xF003FFFF
0xF007FFFF
0xF00FFFFF
0xF01FFFFF
0xF03FFFFF
0xF07FFFFF
0xF0FFFFFF
0xF1FFFFFF
0xF3FFFFFF
0xF7FFFFFF
0xFFFFFFFF
0xFFFFFFFFFFFFFFFF
0xFFFFFFFFFFFFFFFE
0xFFFFFFFFFFFFFFFC
0xFFFFFFFFFFFFFFF8