Skip to content
Draft
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
10 changes: 6 additions & 4 deletions src/fw/drivers/mpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,11 @@ void mpu_enable(void) {
s_cache_settings[MpuCachePolicy_WriteBackNoWriteAllocate]);
#endif

#ifdef MICRO_FAMILY_SF32LB52
ARM_MPU_Enable(MPU_CTRL_PRIVDEFENA_Msk | MPU_CTRL_HFNMIENA_Msk);
#else
ARM_MPU_Enable(MPU_CTRL_PRIVDEFENA_Msk);
#endif
}

void mpu_disable(void) {
Expand Down Expand Up @@ -269,18 +273,16 @@ void mpu_set_task_configurable_regions(MemoryRegion_t *memory_regions,
// If not region defined, use unused
if (mpu_region == NULL) {
mpu_region = &unused_region;
base_reg = 0;
attr_reg = 0; // Has a 0 in the enable bit, so this region won't be enabled.
} else {
// Make sure that the region numbers passed in jive with the configurable region numbers.
PBL_ASSERTN(mpu_region->region_num == region_num);
// Our FreeRTOS port makes the assumption that the ulParameters field contains exactly what
// should be placed into the MPU_RASR register. It will figure out the MPU_RBAR from the
// pvBaseAddress field.
mpu_get_register_settings(mpu_region, &base_reg, &attr_reg);
}

memory_regions[region_idx] = (MemoryRegion_t) {
.pvBaseAddress = (void *)mpu_region->base_address,
.pvBaseAddress = (void *)(uintptr_t)base_reg,
.ulLengthInBytes = mpu_region->size,
.ulParameters = attr_reg,
};
Expand Down
19 changes: 15 additions & 4 deletions src/fw/kernel/pebble_tasks.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "util/size.h"

#include "FreeRTOS.h"
#include "portmacro.h"
#include "task.h"
#include "queue.h"

Expand Down Expand Up @@ -197,14 +198,22 @@ void pebble_task_create(PebbleTask pebble_task, TaskParameters_t *task_params,
WTF;
}

app_region.region_num = portFIRST_CONFIGURABLE_REGION;
worker_region.region_num = portFIRST_CONFIGURABLE_REGION + 1;

MpuRegion stack_guard_copy;
const MpuRegion *stack_guard_ptr = NULL;
if (stack_guard_region != NULL) {
stack_guard_copy = *stack_guard_region;
stack_guard_copy.region_num = portFIRST_CONFIGURABLE_REGION + 2;
stack_guard_ptr = &stack_guard_copy;
}

const MpuRegion *region_ptrs[portNUM_CONFIGURABLE_REGIONS] = {
// FIXME(SF32LB52): Not supported on ARMv8 MPU yet
#ifndef MICRO_FAMILY_SF32LB52
&app_region,
&worker_region,
stack_guard_region,
stack_guard_ptr,
NULL
#endif
};
mpu_set_task_configurable_regions(task_params->xRegions, region_ptrs);

Expand Down Expand Up @@ -232,6 +241,8 @@ void pebble_task_configure_idle_task(void) {
false /* allow_user_access */);
mpu_init_region_from_region(&worker_region, memory_layout_get_worker_region(),
false /* allow_user_access */);
app_region.region_num = portFIRST_CONFIGURABLE_REGION;
worker_region.region_num = portFIRST_CONFIGURABLE_REGION + 1;
const MpuRegion *region_ptrs[portNUM_CONFIGURABLE_REGIONS] = {
&app_region,
&worker_region,
Expand Down
24 changes: 14 additions & 10 deletions src/fw/wscript
Original file line number Diff line number Diff line change
Expand Up @@ -264,17 +264,13 @@ def _generate_memory_layout(bld):
app_ram_size_3x = APP_RAM_SIZES['basalt']
app_ram_size_4x = APP_RAM_SIZES['emery']
# We have 512K of SRAM, last 1K reserved for LCPU IPC
# FIXME(SF32LB52): due to MPU find_subregions_for_region assuming
# ARMv7 subregion limitations, we need to reserve 32K!
total_ram = (0x20000000, (512 - 32) * 1024)
total_ram = (0x20000000, (512 - 1) * 1024)
elif bld.is_getafix():
app_ram_size_2x = APP_UNSUPPORTED
app_ram_size_3x = APP_RAM_SIZES['chalk']
app_ram_size_4x = APP_RAM_SIZES['gabbro']
# We have 512K of SRAM, last 1K reserved for LCPU IPC
# FIXME(SF32LB52): due to MPU find_subregions_for_region assuming
# ARMv7 subregion limitations, we need to reserve 32K!
total_ram = (0x20000000, (512 - 32) * 1024)
total_ram = (0x20000000, (512 - 1) * 1024)
else:
bld.fatal("No set of supported SDK platforms defined for this board")

Expand Down Expand Up @@ -320,18 +316,26 @@ def _generate_memory_layout(bld):
FLASH_SIZE=flash_size,
BOOTLOADER_SYMBOLS=bootloader_symbol_definitions)

app_mpu_region = tools.mpu_calc.find_subregions_for_region(app_ram[0], app_ram[1])
worker_mpu_region = tools.mpu_calc.find_subregions_for_region(worker_ram[0], worker_ram[1])
if bld.env.MICRO_FAMILY == 'SF32LB52':
app_mpu_region = tools.mpu_calc.find_region_for_armv8(app_ram[0], app_ram[1])
worker_mpu_region = tools.mpu_calc.find_region_for_armv8(worker_ram[0], worker_ram[1])
app_disabled_sub = "0"
worker_disabled_sub = "0"
else:
app_mpu_region = tools.mpu_calc.find_subregions_for_region(app_ram[0], app_ram[1])
worker_mpu_region = tools.mpu_calc.find_subregions_for_region(worker_ram[0], worker_ram[1])
app_disabled_sub = "0b{:08b}".format(app_mpu_region.disabled_subregion)
worker_disabled_sub = " 0b{:08b}".format(worker_mpu_region.disabled_subregion)

bld(features='subst',
source=bld.path.find_node('kernel/mpu_regions.template.h'),
target=bld.path.get_bld().make_node('kernel/mpu_regions.auto.h'),
APP_BASE_ADDRESS="0x{:x}".format(app_mpu_region.address),
APP_SIZE="0x{:x}".format(app_mpu_region.size),
APP_DISABLED_SUBREGIONS="0b{:08b}".format(app_mpu_region.disabled_subregion),
APP_DISABLED_SUBREGIONS=app_disabled_sub,
WORKER_BASE_ADDRESS="0x{:x}".format(worker_mpu_region.address),
WORKER_SIZE="0x{:x}".format(worker_mpu_region.size),
WORKER_DISABLED_SUBREGIONS=" 0b{:08b}".format(worker_mpu_region.disabled_subregion))
WORKER_DISABLED_SUBREGIONS=worker_disabled_sub)

bld(features='subst',
source=bld.path.find_node('process_management/sdk_memory_limits.template.h'),
Expand Down
4 changes: 1 addition & 3 deletions third_party/freertos/wscript
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,9 @@ def build(bld):
for d in freertos_source_paths], [])
freertos_defines = []

# FIXME(SF32LB52): Add valid regions once MPU can be used
# This currently results in 0 regions!
if bld.env.MICRO_FAMILY == 'SF32LB52':
freertos_defines += [
'FREERTOS_FIRST_MPU_REGION=8',
'FREERTOS_FIRST_MPU_REGION=4',
'FREERTOS_LAST_MPU_REGION=7',
]

Expand Down
15 changes: 15 additions & 0 deletions tools/mpu_calc.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,21 @@ def find_subregions_for_region(address, size):
raise Exception("No solution found")


def find_region_for_armv8(address, size):
"""Find MPU region for ARMv8-M (no subregions, arbitrary 32-byte-aligned size).

ARMv8-M MPU supports regions of any size aligned to 32 bytes.
Returns MpuRegion(address, size, 0) with disabled_subregion=0 (unused on ARMv8).
"""
if address % 32 != 0:
raise Exception("Address must be 32-byte aligned for ARMv8-M MPU")
if size % 32 != 0:
raise Exception("Size must be 32-byte aligned for ARMv8-M MPU")
if size < MIN_REGION_SIZE:
raise Exception("Size must be at least 32 bytes")
return MpuRegion(address=address, size=size, disabled_subregion=0)


if __name__ == "__main__":
import doctest

Expand Down
Loading