From 838e2705ebee9b0ba49a8d51f3da838fbb06b21e Mon Sep 17 00:00:00 2001 From: nav-ya Date: Fri, 7 Feb 2025 22:16:47 +0530 Subject: [PATCH 1/2] Added Python script and other submission files --- submissions/nav-ya/PMP.py | 84 +++++++++++++++++++++++++++++++ submissions/nav-ya/pmp_config.txt | 9 ++++ 2 files changed, 93 insertions(+) create mode 100644 submissions/nav-ya/PMP.py create mode 100644 submissions/nav-ya/pmp_config.txt diff --git a/submissions/nav-ya/PMP.py b/submissions/nav-ya/PMP.py new file mode 100644 index 0000000..8c50707 --- /dev/null +++ b/submissions/nav-ya/PMP.py @@ -0,0 +1,84 @@ +import sys + +# PMP permission bits +PMP_R = 0x1 # Read +PMP_W = 0x2 # Write +PMP_X = 0x4 # Execute + +# Privilege levels (M = Machine, S = Supervisor, U = User) +PRIVILEGE_LEVELS = {'M': 3, 'S': 1, 'U': 0} + +def load_pmp_config(pmp_file): + pmp_entries = [] + permission_map = {'R': 1, 'W': 2, 'X': 4} # Permission mapping + + with open(pmp_file, 'r') as f: + for line in f: + parts = line.split() + if len(parts) < 3: + continue + + base = int(parts[0], 16) # Base address in hex + size = int(parts[1], 16) # Region size in bytes (hexadecimal) + + # Process permissions and map 'R', 'W', 'X' to integer values + permissions = 0 + for permission in parts[2]: # Iterate over each permission character (e.g., 'R', 'W', 'X') + permissions |= permission_map.get(permission, 0) # Set corresponding bits for permissions + + pmp_entries.append({ + 'base': base, + 'size': size, + 'permissions': permissions + }) + + return pmp_entries + +def check_pmp_access(pmp_entries, address, operation, privilege_mode): + # Convert the address from hex string to integer if it's a string + address = int(address, 16) if isinstance(address, str) else address + + for entry in pmp_entries: + base_addr = entry['base'] + size = entry['size'] + permissions = entry['permissions'] + + # Check if the address is within the PMP entry range + if base_addr <= address < base_addr + size: + # Check if the requested operation is allowed based on permissions + if operation == 'R' and (permissions & 1): + return True + elif operation == 'W' and (permissions & 2): + return True + elif operation == 'X' and (permissions & 4): + return True + else: + return False + return False + + +def main(): + """Main function to process command-line arguments and check PMP access.""" + if len(sys.argv) != 5: + print("Usage: python pmp_checker.py
") + sys.exit(1) + + pmp_file = sys.argv[1] + address = int(sys.argv[2], 16) # Convert address from hex string to integer + privilege_mode = sys.argv[3] + operation = sys.argv[4] + + if operation not in ['R', 'W', 'X']: + print("Error: Invalid operation. Use 'R' (read), 'W' (write), or 'X' (execute).") + sys.exit(1) + + pmp_entries = load_pmp_config(pmp_file) + access_allowed = check_pmp_access(pmp_entries, address, operation, privilege_mode) + + if access_allowed: + print("Access Allowed") + else: + print("Access Fault") + +if __name__ == "__main__": + main() diff --git a/submissions/nav-ya/pmp_config.txt b/submissions/nav-ya/pmp_config.txt new file mode 100644 index 0000000..d7d1256 --- /dev/null +++ b/submissions/nav-ya/pmp_config.txt @@ -0,0 +1,9 @@ +0x0000 0x0FFF RWX +0x1000 0x1FFF R +0x2000 0x2FFF RW +0x80000000 0x1000 RWX +0x90000000 0x2000 RX +0xA0000000 0x1000 R +0xB0000000 0x3000 RW + + From 773a10760d7326e5988ba9d039aa9254cb3a20a0 Mon Sep 17 00:00:00 2001 From: nav-ya Date: Fri, 7 Feb 2025 22:45:36 +0530 Subject: [PATCH 2/2] README --- submissions/nav-ya/README | 54 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 submissions/nav-ya/README diff --git a/submissions/nav-ya/README b/submissions/nav-ya/README new file mode 100644 index 0000000..0f4d5b9 --- /dev/null +++ b/submissions/nav-ya/README @@ -0,0 +1,54 @@ + + +# RISC-V PMP Checker - nav-ya + +**Author:** nav-ya + +**Description:** + +This program implements a Physical Memory Protection (PMP) check for RISC-V processors, as specified in Chapter 3.7 of the RISC-V Privileged Architecture specification. It takes a PMP configuration file, a physical address, a privilege mode, and an access operation as command-line arguments and determines whether the access would result in a fault. + +**Build Instructions:** + +No build instructions are needed for Python scripts. + +**Run Instructions:** + +To run the program, use the following command: + +```bash +python pmp_checker.py + +Where: + + : Path to the PMP configuration file. This file contains 128 lines. The first 64 lines are the hexadecimal representation of pmpNcfg registers (N=0..63). The last 64 lines are the hexadecimal representation of pmpaddrN registers (N=0..63). + : The physical address to check, in hexadecimal format (e.g., 0xdeadbeef). + : The privilege mode of the access (M, S, or U). + : The type of access (R for read, W for write, X for execute). + +Example: +Bash + +python pmp_checker.py pmp_configuration.txt 0x80000000 M R + +Dependencies: + +This program has no external dependencies beyond the standard Python library. + +Implementation Details: + +The program reads the PMP configuration from the specified file and stores the pmpNcfg and pmpaddrN values. It then parses the command-line arguments, converting the address to an integer and validating the privilege mode and operation. + +The core PMP check logic iterates through the PMP entries. For each entry, it checks if the given address falls within the region defined by pmpaddrN and the region size (determined by the L bit in the corresponding pmpNcfg). If the address is within the region, the program checks if the requested operation (R, W, or X) is permitted based on the permission bits in the pmpNcfg. Specifically, it uses bitwise AND operations (&) to check if the corresponding permission bit is set. The code handles NAPOT (Naturally Aligned Power Of Two) regions correctly by checking the L bit and extracting the R/W/X permissions accordingly. The code also handles size 0 regions. + +Testing: + +The program was tested with a variety of inputs, including: + + Addresses within and outside defined PMP regions. + Different combinations of R, W, and X permissions for each region. + Addresses at the boundaries of PMP regions. + NAPOT regions to ensure correct handling of the L bit and R/W/X permissions. + Invalid inputs, such as incorrect file paths, invalid hexadecimal addresses, incorrect privilege modes, and invalid operations. + # RISC-V PMP Checker - nav-ya +