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
139 changes: 139 additions & 0 deletions submissions/Rupa-Rd/pmp_check.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <stdexcept>
#include <cstdint>
#include <iomanip>

const int PMP_ENTRIES = 64;

struct PMPConfig {
uint8_t R : 1;
uint8_t W : 1;
uint8_t X : 1;
uint8_t A : 2;
uint8_t reserved : 2;
uint8_t L : 1;
};

struct PMPEntry {
PMPConfig config;
uint64_t address;
};

void parseArguments(int argc, char* argv[], std::string& configFile, uint64_t& address, char& mode, char& operation) {
if (argc != 5) {
throw std::invalid_argument("Usage: program <config_file> <address> <mode> <operation>");
}

configFile = argv[1];

// Check if address starts with "0x"
std::string addrStr = argv[2];
if (addrStr.size() < 2 || addrStr.substr(0, 2) != "0x") {
throw std::invalid_argument("Physical address must start with '0x'.");
}
address = std::stoull(addrStr, nullptr, 16);

mode = argv[3][0];
operation = argv[4][0];

if (mode != 'M' && mode != 'S' && mode != 'U') {
throw std::invalid_argument("Invalid privilege mode. Must be 'M', 'S', or 'U'.");
}

if (operation != 'R' && operation != 'W' && operation != 'X') {
throw std::invalid_argument("Invalid operation. Must be 'R', 'W', or 'X'.");
}
}

void readPMPConfig(const std::string& configFile, std::vector<PMPEntry>& pmpEntries) {
std::ifstream file(configFile);
if (!file.is_open()) {
throw std::runtime_error("Could not open PMP configuration file.");
}

for (int i = 0; i < PMP_ENTRIES; ++i) {
std::string line;
if (!std::getline(file, line)) {
throw std::runtime_error("Invalid PMP configuration file format.");
}

uint8_t configValue = std::stoul(line, nullptr, 16);
pmpEntries[i].config = *reinterpret_cast<PMPConfig*>(&configValue);
}

for (int i = 0; i < PMP_ENTRIES; ++i) {
std::string line;
if (!std::getline(file, line)) {
throw std::runtime_error("Invalid PMP configuration file format.");
}

pmpEntries[i].address = std::stoull(line, nullptr, 16);
}
}

bool checkPMPAccess(const std::vector<PMPEntry>& pmpEntries, uint64_t address, char mode, char operation) {
for (int i = 0; i < PMP_ENTRIES; ++i) {
const PMPEntry& entry = pmpEntries[i];

if (entry.config.A == 0) continue; // Skip disabled entries

uint64_t lowerBound = 0;
uint64_t upperBound = 0;

if (entry.config.A == 1) { // TOR mode
if (i == 0) {
lowerBound = 0;
} else {
lowerBound = pmpEntries[i - 1].address;
}
upperBound = entry.address;
} else if (entry.config.A == 2) { // NA4 mode
lowerBound = entry.address & ~0x3ULL;
upperBound = lowerBound + 4;
} else if (entry.config.A == 3) { // NAPOT mode
uint64_t mask = ~(entry.address | (entry.address - 1));
lowerBound = entry.address & mask;
upperBound = lowerBound + (mask + 1);
}

if (address >= lowerBound && address < upperBound) {
if (mode == 'M' && !entry.config.L) {
return true; // M-mode access succeeds if L bit is clear
}

if (operation == 'R' && !entry.config.R) return false;
if (operation == 'W' && !entry.config.W) return false;
if (operation == 'X' && !entry.config.X) return false;

return true;
}
}

// If no PMP entry matches, M-mode access succeeds, S/U-mode access fails
return mode == 'M';
}

int main(int argc, char* argv[]) {
try {
std::string configFile;
uint64_t address;
char mode, operation;

parseArguments(argc, argv, configFile, address, mode, operation);

std::vector<PMPEntry> pmpEntries(PMP_ENTRIES);
readPMPConfig(configFile, pmpEntries);

bool accessAllowed = checkPMPAccess(pmpEntries, address, mode, operation);

std::cout << "Access " << (accessAllowed ? "allowed" : "denied") << std::endl;
} catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
return 1;
}

return 0;
}
Binary file added submissions/Rupa-Rd/pmp_check.exe
Binary file not shown.
128 changes: 128 additions & 0 deletions submissions/Rupa-Rd/pmp_configuration.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
0x07
0x01
0x03
0x00
0x07
0x01
0x03
0x00
0x07
0x01
0x03
0x00
0x07
0x01
0x03
0x00
0x07
0x01
0x03
0x00
0x07
0x01
0x03
0x00
0x07
0x01
0x03
0x00
0x07
0x01
0x03
0x00
0x07
0x01
0x03
0x00
0x07
0x01
0x03
0x00
0x07
0x01
0x03
0x00
0x07
0x01
0x03
0x00
0x07
0x01
0x03
0x00
0x07
0x01
0x03
0x00
0x07
0x01
0x03
0x00
0x07
0x01
0x03
0x00
0x1000
0x2000
0x3000
0x4000
0x5000
0x6000
0x7000
0x8000
0x9000
0x10000
0x11000
0x12000
0x13000
0x14000
0x15000
0x16000
0x17000
0x18000
0x19000
0x20000
0x21000
0x22000
0x23000
0x24000
0x25000
0x26000
0x27000
0x28000
0x29000
0x30000
0x31000
0x32000
0x33000
0x34000
0x35000
0x36000
0x37000
0x38000
0x39000
0x40000
0x41000
0x42000
0x43000
0x44000
0x45000
0x46000
0x47000
0x48000
0x49000
0x50000
0x51000
0x52000
0x53000
0x54000
0x55000
0x56000
0x57000
0x58000
0x59000
0x60000
0x61000
0x62000
0x63000
0x64000