ca13734bf0
Add kernel (Cortex-M0/M3/M4, Tricore, S32K, RISC-V ports), drivers, middleware (CAN stack, diagnostics, safety), applications, board support, build/test tooling, and documentation.
166 lines
4.5 KiB
C
166 lines
4.5 KiB
C
/**
|
|
* @file memory_protection.c
|
|
* @brief Memory Protection for safety-critical applications
|
|
*/
|
|
|
|
#include "kernel.h"
|
|
#include "task.h"
|
|
#include <string.h>
|
|
|
|
/* Memory Protection Configuration */
|
|
#define MPU_MAX_REGIONS 8
|
|
#define MEMORY_PROTECTION_ALIGNMENT 32 /* 32 bytes minimum */
|
|
|
|
/* Memory Region Attributes */
|
|
typedef struct {
|
|
uint32_t base_address;
|
|
uint32_t size;
|
|
uint8_t permissions;
|
|
bool executable;
|
|
bool cacheable;
|
|
bool bufferable;
|
|
} MemoryRegion_t;
|
|
|
|
/* Memory Protection State */
|
|
typedef struct {
|
|
bool initialized;
|
|
bool enabled;
|
|
MemoryRegion_t regions[MPU_MAX_REGIONS];
|
|
uint8_t region_count;
|
|
TaskHandle_t current_task;
|
|
Mutex_t mutex;
|
|
} MemoryProtectionState_t;
|
|
|
|
static MemoryProtectionState_t memory_protection;
|
|
|
|
/* Initialize Memory Protection */
|
|
KernelStatus_t memory_protection_init(void) {
|
|
if (memory_protection.initialized) {
|
|
return KERNEL_ERROR;
|
|
}
|
|
|
|
memset(&memory_protection, 0, sizeof(MemoryProtectionState_t));
|
|
memory_protection.enabled = false;
|
|
memory_protection.region_count = 0;
|
|
|
|
mutex_create(&memory_protection.mutex, false);
|
|
|
|
memory_protection.initialized = true;
|
|
return KERNEL_OK;
|
|
}
|
|
|
|
/* Configure Memory Region */
|
|
KernelStatus_t memory_protection_configure_region(uint32_t base_address,
|
|
uint32_t size,
|
|
uint8_t permissions,
|
|
bool executable) {
|
|
if (!memory_protection.initialized) {
|
|
return KERNEL_ERROR;
|
|
}
|
|
|
|
if (memory_protection.region_count >= MPU_MAX_REGIONS) {
|
|
return KERNEL_OUT_OF_MEMORY;
|
|
}
|
|
|
|
/* Validate alignment */
|
|
if ((base_address % MEMORY_PROTECTION_ALIGNMENT) != 0 ||
|
|
(size % MEMORY_PROTECTION_ALIGNMENT) != 0) {
|
|
return KERNEL_INVALID_PARAMETER;
|
|
}
|
|
|
|
mutex_lock(&memory_protection.mutex, 100);
|
|
|
|
MemoryRegion_t* region = &memory_protection.regions[memory_protection.region_count];
|
|
region->base_address = base_address;
|
|
region->size = size;
|
|
region->permissions = permissions;
|
|
region->executable = executable;
|
|
|
|
memory_protection.region_count++;
|
|
|
|
mutex_unlock(&memory_protection.mutex);
|
|
|
|
return KERNEL_OK;
|
|
}
|
|
|
|
/* Enable Memory Protection */
|
|
KernelStatus_t memory_protection_enable(void) {
|
|
if (!memory_protection.initialized) {
|
|
return KERNEL_ERROR;
|
|
}
|
|
|
|
/* Configure MPU hardware */
|
|
hal_mpu_enable();
|
|
|
|
/* Configure regions */
|
|
for (uint8_t i = 0; i < memory_protection.region_count; i++) {
|
|
MemoryRegion_t* region = &memory_protection.regions[i];
|
|
hal_mpu_configure_region(i, region->base_address, region->size,
|
|
region->permissions, region->executable);
|
|
}
|
|
|
|
memory_protection.enabled = true;
|
|
|
|
return KERNEL_OK;
|
|
}
|
|
|
|
/* Disable Memory Protection */
|
|
KernelStatus_t memory_protection_disable(void) {
|
|
if (!memory_protection.initialized) {
|
|
return KERNEL_ERROR;
|
|
}
|
|
|
|
hal_mpu_disable();
|
|
memory_protection.enabled = false;
|
|
|
|
return KERNEL_OK;
|
|
}
|
|
|
|
/* Set Task Memory Region */
|
|
KernelStatus_t memory_protection_set_task_region(TaskHandle_t task,
|
|
uint32_t base_address,
|
|
uint32_t size) {
|
|
if (!memory_protection.initialized || task == NULL) {
|
|
return KERNEL_ERROR;
|
|
}
|
|
|
|
/* Configure task-specific memory region */
|
|
hal_mpu_configure_task_region(task, base_address, size);
|
|
|
|
return KERNEL_OK;
|
|
}
|
|
|
|
/* Check Memory Access */
|
|
bool memory_protection_check_access(uint32_t address, uint8_t access_type) {
|
|
if (!memory_protection.initialized || !memory_protection.enabled) {
|
|
return true; /* Protection disabled */
|
|
}
|
|
|
|
/* Check if address is within any protected region */
|
|
for (uint8_t i = 0; i < memory_protection.region_count; i++) {
|
|
MemoryRegion_t* region = &memory_protection.regions[i];
|
|
|
|
if (address >= region->base_address &&
|
|
address < (region->base_address + region->size)) {
|
|
/* Check permissions */
|
|
if ((region->permissions & access_type) == 0) {
|
|
return false; /* Access denied */
|
|
}
|
|
return true; /* Access allowed */
|
|
}
|
|
}
|
|
|
|
return false; /* Address not in any region */
|
|
}
|
|
|
|
/* Memory Protection Fault Handler */
|
|
void memory_protection_fault_handler(uint32_t fault_address) {
|
|
/* Log fault */
|
|
fault_handler_process(2, fault_address, 0);
|
|
|
|
/* Enter safe state */
|
|
while (1) {
|
|
/* Wait for watchdog reset */
|
|
}
|
|
}
|