/** * @file memory_protection.c * @brief Memory Protection for safety-critical applications */ #include "kernel.h" #include "task.h" #include /* 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 */ } }