From 15099976afbf9e2f6497b030fd42fe213fb21b41 Mon Sep 17 00:00:00 2001 From: Raissa Coelho <72715305+raissa-coelho@users.noreply.github.com> Date: Sat, 8 Feb 2025 21:21:59 -0300 Subject: [PATCH 1/4] Create raissa-coelho --- submissions/raissa-coelho | 1 + 1 file changed, 1 insertion(+) create mode 100644 submissions/raissa-coelho diff --git a/submissions/raissa-coelho b/submissions/raissa-coelho new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/submissions/raissa-coelho @@ -0,0 +1 @@ + From aa58aabdb60524644ec0c0023bf9a222e048c765 Mon Sep 17 00:00:00 2001 From: Raissa Coelho <72715305+raissa-coelho@users.noreply.github.com> Date: Sat, 8 Feb 2025 21:23:34 -0300 Subject: [PATCH 2/4] Delete submissions directory --- submissions/raissa-coelho | 1 - 1 file changed, 1 deletion(-) delete mode 100644 submissions/raissa-coelho diff --git a/submissions/raissa-coelho b/submissions/raissa-coelho deleted file mode 100644 index 8b13789..0000000 --- a/submissions/raissa-coelho +++ /dev/null @@ -1 +0,0 @@ - From 88bfda2ca94e3041a52c3eb93c61822487d66547 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=ADssa?= Date: Sat, 8 Feb 2025 21:40:10 -0300 Subject: [PATCH 3/4] add basic --- submissions/raissa-coelho/README.md | 0 submissions/raissa-coelho/config.txt | 8 +++ submissions/raissa-coelho/pmp.py | 88 ++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+) create mode 100644 submissions/raissa-coelho/README.md create mode 100644 submissions/raissa-coelho/config.txt create mode 100644 submissions/raissa-coelho/pmp.py diff --git a/submissions/raissa-coelho/README.md b/submissions/raissa-coelho/README.md new file mode 100644 index 0000000..e69de29 diff --git a/submissions/raissa-coelho/config.txt b/submissions/raissa-coelho/config.txt new file mode 100644 index 0000000..c8cca2c --- /dev/null +++ b/submissions/raissa-coelho/config.txt @@ -0,0 +1,8 @@ +0x00 +0x08 +0x18 +0x3FFC +0x80000000 +0x100000000 +0x3FF0 +0x200000000 \ No newline at end of file diff --git a/submissions/raissa-coelho/pmp.py b/submissions/raissa-coelho/pmp.py new file mode 100644 index 0000000..8aaa720 --- /dev/null +++ b/submissions/raissa-coelho/pmp.py @@ -0,0 +1,88 @@ +## Made By Raíssa Coelho + +import argparse + +def read_config(path): + pmpcfg = [] + pmpaddr = [] + + with open(path, "r") as file: + for _ in range(4): + pmpcfg.append(bin(int(file.readline().strip(), 16))[2:].zfill(8)) + + for _ in range(4): + pmpaddr.append(file.readline().strip()) + + return pmpcfg, pmpaddr + +def check_pmpcfg(pmcfg): + L = pmcfg[0] + A = pmcfg[3:5] + X = pmcfg[5] + W = pmcfg[6] + R = pmcfg[7] + + return L, A, X, W, R + +def pmp(pmpcfg, pmpaddr, physical_addr, mode, op): + print("PMP Configuration:") + physical_addr = int(physical_addr, 16) + + for i in range(4): + cfg = pmpcfg[i] + addr = [int(a, 16) for a in pmpaddr] + L, A, X, W, R = check_pmpcfg(pmpcfg[i]) + + #Lock + if L == "1": + print(f'PMP region {i} is locked\n') + continue + if A == "00": + # OFF - Null region + print(f'OFF - Null Region\n') + if A == "01": + # TOR - Top of range + if i == 0: + continue + if addr[i - 1] <= physical_addr < addr[i]: + if mode == "M": + print(f'Access granted.') + elif mode == "S": + print(f'Acess granted.') + elif mode == "U": + print(f'Acess granted.') + if A == "10": + # NA4 - Naturally aligned four-byte region + print(f'NA4') + if addr[i] <= physical_addr < addr[i] + 4: + print(f'Physical address {physical_addr} is in the region {i}') + if A == "11": + # NAPOT - Naturally aligned power-of-two region + print(f'NAPOT') + napot = addr[i] & 0b111111111111 + size = 1 << (napot.bit_length()) + + base = addr[i] & ~(size - 1) + if base <= physical_addr < base + size: + print(f'Physical address {hex(physical_addr)} is in the region {i}') + #print(f" CFG{i}: {cfg} ADDR{i}: {addr} L: {L} A: {A} X: {X} W: {W} R: {R}") + +def main(): + parser = argparse.ArgumentParser(description='Verify acess.') + + parser.add_argument('path', type=str, help='pmp_configuration file') + #parser.add_argument('addr', type=lambda x: int(x, 16), help='physical address in hexadecimal') + parser.add_argument('addr', type=str, help='physical address in hexadecimal') + parser.add_argument('mode', type=str, help='privilege mode') + parser.add_argument('op', type=str, help='operation: read,write,execute/fetch') + + args = parser.parse_args() + pmpcfg, pmpaddr = read_config(args.path) + + #print(pmpcfg) + #print(pmpaddr) + + pmp(pmpcfg, pmpaddr, args.addr, args.mode, args.op) + +if __name__ == '__main__': + main() \ No newline at end of file From 1c1875562b168ab066a13f2a9eb4fac5ae7b70e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=ADssa?= Date: Sat, 8 Feb 2025 23:37:10 -0300 Subject: [PATCH 4/4] add README and change pmp.py --- submissions/raissa-coelho/README.md | 17 ++++ submissions/raissa-coelho/config.txt | 136 +++++++++++++++++++++++++-- submissions/raissa-coelho/pmp.py | 129 +++++++++++++++++++------ 3 files changed, 244 insertions(+), 38 deletions(-) diff --git a/submissions/raissa-coelho/README.md b/submissions/raissa-coelho/README.md index e69de29..bf8b633 100644 --- a/submissions/raissa-coelho/README.md +++ b/submissions/raissa-coelho/README.md @@ -0,0 +1,17 @@ + +# PMP + +Made by Raíssa Coelho +Python version: 3.13.0 + +## Project Description + +This project is a solution to the IDL challenge. + +## Usage + +To run the project, use the following command: + +```sh +python pmp.py
+``` diff --git a/submissions/raissa-coelho/config.txt b/submissions/raissa-coelho/config.txt index c8cca2c..32d235e 100644 --- a/submissions/raissa-coelho/config.txt +++ b/submissions/raissa-coelho/config.txt @@ -1,8 +1,128 @@ -0x00 -0x08 -0x18 -0x3FFC -0x80000000 -0x100000000 -0x3FF0 -0x200000000 \ No newline at end of file +0x3A +0x7F +0x1C +0x9D +0x4E +0xB2 +0x5F +0x8A +0x2B +0x6C +0xF1 +0x0D +0xE4 +0x59 +0x3B +0xA7 +0x8E +0x42 +0x6D +0xC9 +0x1F +0x7A +0x5B +0x0E +0x93 +0x2D +0x4A +0x8C +0x6F +0xB5 +0x1A +0x3E +0x7D +0x0F +0x9B +0x2C +0x5A +0x8D +0xE7 +0x4B +0x6A +0x1E +0x3D +0x7C +0x0A +0x9F +0x2E +0x5C +0x8B +0xE1 +0x4D +0x6E +0x1B +0x3F +0x7E +0x0C +0x9A +0x2F +0x5D +0x89 +0xE3 +0x4F +0x6B +0x1D +0x1A +0x3F7 +0xB2C +0x4DF9 +0x7E +0x1F8A +0x5C3 +0x9D4 +0x2EB +0x6A1F +0x3D +0x8C7 +0x1B5 +0x4E2 +0x7F9A +0x2C +0x5F3 +0x9A8 +0x1E7 +0x3B4 +0x6D +0x8F2 +0x1C9 +0x4A5 +0x7B +0x2F8 +0x5E6 +0x9C1 +0x1D3 +0x3A +0x6F4 +0x8D +0x1E2 +0x4B9 +0x7C5 +0x2A +0x5D7 +0x9E +0x1F +0x3C8 +0x6B +0x8A +0x1D5 +0x4E +0x7F +0x2B3 +0x5C +0x9F +0x1A2 +0x3E +0x6D4 +0x8B +0x1C +0x4F +0x7A +0x2D +0x5E +0x9B +0x1F3 +0x3A5 +0x6C +0x8E +0x1D6 +0x4B \ No newline at end of file diff --git a/submissions/raissa-coelho/pmp.py b/submissions/raissa-coelho/pmp.py index 8aaa720..7283f52 100644 --- a/submissions/raissa-coelho/pmp.py +++ b/submissions/raissa-coelho/pmp.py @@ -2,19 +2,36 @@ import argparse +"""read_config reads the PMP configuration file + Args: + path: path to the PMP configuration file + Returns: + pmpcfg: PMP configuration bits +""" def read_config(path): pmpcfg = [] pmpaddr = [] with open(path, "r") as file: - for _ in range(4): + for _ in range(64): pmpcfg.append(bin(int(file.readline().strip(), 16))[2:].zfill(8)) - for _ in range(4): + for _ in range(64): pmpaddr.append(file.readline().strip()) return pmpcfg, pmpaddr + +"""check_pmpcfg checks the PMP configuration bits + Args: + pmcfg: PMP configuration bits + Returns: + L: locked region + A: address-matching mode + X: execute permission + W: write permission + R: read permission +""" def check_pmpcfg(pmcfg): L = pmcfg[0] A = pmcfg[3:5] @@ -24,54 +41,109 @@ def check_pmpcfg(pmcfg): return L, A, X, W, R +"""check_permission checks if the access is granted + or denied based on the mode and the permission bits +""" +def check_permission(mode, op, R, W, X): + if mode == "M": + print(f'Access granted.') + elif mode == "S" or mode == "U": + if op == "R" and R == "0": + print(f'Access denied.') + elif op == "W" and W == "0": + print(f'Access denied.') + elif op == "X" and X == "0": + print(f'Access denied.') + else: + print(f'Access granted.') + +"""pmp checks the PMP configuration and address + Args: + pmpcfg: PMP configuration + pmpaddr: PMP address + physical_addr: physical address + mode: privilege mode - M, S, U + op: operation: read,write,execute - R, W, X +""" def pmp(pmpcfg, pmpaddr, physical_addr, mode, op): - print("PMP Configuration:") physical_addr = int(physical_addr, 16) - for i in range(4): - cfg = pmpcfg[i] - addr = [int(a, 16) for a in pmpaddr] + addr = [int(a, 16) for a in pmpaddr] + for i in range(64): L, A, X, W, R = check_pmpcfg(pmpcfg[i]) - #Lock - if L == "1": - print(f'PMP region {i} is locked\n') + """ Locked region + """ + if int(L) == 1: + print(f'PMP region {i} is locked') continue + + """ Null region + """ if A == "00": - # OFF - Null region - print(f'OFF - Null Region\n') + if mode == "M": + print(f'Access granted.') + else: + print(f'Access denied.') + + """TOR - Top of range + Args: + addr: base address of the region + physical_addr: physical address + """ if A == "01": - # TOR - Top of range if i == 0: continue if addr[i - 1] <= physical_addr < addr[i]: + check_permission(mode, op, R, W, X) + else: if mode == "M": print(f'Access granted.') - elif mode == "S": - print(f'Acess granted.') - elif mode == "U": - print(f'Acess granted.') + elif mode == "S" or mode == "U": + print(f'Access denied.') + + """NA4 - Naturally aligned four-byte region + Args: + addr: base address of the region + physical_addr: physical address + """ if A == "10": - # NA4 - Naturally aligned four-byte region - print(f'NA4') if addr[i] <= physical_addr < addr[i] + 4: - print(f'Physical address {physical_addr} is in the region {i}') + check_permission(mode, op, R, W, X) + else: + if mode == "M": + print(f'Access granted.') + elif mode == "S" or mode == "U": + print(f'Access denied.') + + """NAPOT - Naturally aligned power-of-two region + Args: + napot: number of address bits to be used + size: size of the region + base: base address of the region + """ if A == "11": - # NAPOT - Naturally aligned power-of-two region - print(f'NAPOT') - napot = addr[i] & 0b111111111111 - size = 1 << (napot.bit_length()) + napot = addr[i] ^ (addr[i] + 1) + size = napot + 1 base = addr[i] & ~(size - 1) if base <= physical_addr < base + size: - print(f'Physical address {hex(physical_addr)} is in the region {i}') - #print(f" CFG{i}: {cfg} ADDR{i}: {addr} L: {L} A: {A} X: {X} W: {W} R: {R}") - + check_permission(mode, op, R, W, X) + else: + if mode == "M": + print(f'Access granted.') + elif mode == "S" or mode == "U": + print(f'Access denied.') def main(): parser = argparse.ArgumentParser(description='Verify acess.') + """Arguments: + path: pmp_configuration file + addr: physical address in hexadecimal + mode: privilege mode + op: operation: read,write,execute/fetch + """ parser.add_argument('path', type=str, help='pmp_configuration file') - #parser.add_argument('addr', type=lambda x: int(x, 16), help='physical address in hexadecimal') parser.add_argument('addr', type=str, help='physical address in hexadecimal') parser.add_argument('mode', type=str, help='privilege mode') parser.add_argument('op', type=str, help='operation: read,write,execute/fetch') @@ -79,9 +151,6 @@ def main(): args = parser.parse_args() pmpcfg, pmpaddr = read_config(args.path) - #print(pmpcfg) - #print(pmpaddr) - pmp(pmpcfg, pmpaddr, args.addr, args.mode, args.op) if __name__ == '__main__':