Skip to content

Override ROM/RAM start/size for TrustZone targets #7133

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jun 21, 2018
Merged
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
109 changes: 85 additions & 24 deletions tools/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,25 @@
except NameError:
unicode = str
PATH_OVERRIDES = set(["target.bootloader_img"])
BOOTLOADER_OVERRIDES = set(["target.bootloader_img", "target.restrict_size",
"target.header_format", "target.header_offset",
"target.app_offset",
"target.mbed_app_start", "target.mbed_app_size"])
ROM_OVERRIDES = set([
# managed BL
"target.bootloader_img", "target.restrict_size",
"target.header_format", "target.header_offset",
"target.app_offset",

# unmanaged BL
"target.mbed_app_start", "target.mbed_app_size",

# both
"target.mbed_rom_start", "target.mbed_rom_size",
])
RAM_OVERRIDES = set([
# both
"target.mbed_ram_start", "target.mbed_ram_size",
])

BOOTLOADER_OVERRIDES = ROM_OVERRIDES | RAM_OVERRIDES



# Base class for all configuration exceptions
Expand Down Expand Up @@ -355,6 +370,7 @@ def _process_macros(mlist, macros, unit_name, unit_kind):


Region = namedtuple("Region", "name start size active filename")
RamRegion = namedtuple("RamRegion", "name start size active")

class Config(object):
"""'Config' implements the mbed configuration mechanism"""
Expand Down Expand Up @@ -525,7 +541,16 @@ def add_config_files(self, flist):
@property
def has_regions(self):
"""Does this config have regions defined?"""
for override in BOOTLOADER_OVERRIDES:
for override in ROM_OVERRIDES:
_, attr = override.split(".")
if getattr(self.target, attr, None):
return True
return False

@property
def has_ram_regions(self):
"""Does this config have regions defined?"""
for override in RAM_OVERRIDES:
_, attr = override.split(".")
if getattr(self.target, attr, None):
return True
Expand All @@ -545,9 +570,7 @@ def sectors(self):
return sectors
raise ConfigException("No sector info available")

@property
def regions(self):
"""Generate a list of regions from the config"""
def _get_cmsis_part(self):
if not self.target.bootloader_supported:
raise ConfigException("Bootloader not supported on this target.")
if not hasattr(self.target, "device_name"):
Expand All @@ -558,30 +581,68 @@ def regions(self):
raise ConfigException("Bootloader not supported on this target: "
"targets.json `device_name` not found in "
"arm_pack_manager index.")
cmsis_part = cache.index[self.target.device_name]
return cache.index[self.target.device_name]

def _get_mem_specs(self, memories, cmsis_part, exception_text):
for memory in memories:
try:
size = cmsis_part['memory'][memory]['size']
start = cmsis_part['memory'][memory]['start']
return (start, size)
except KeyError:
continue
raise ConfigException(exception_text)

@property
def rom(self):
"""Get rom information as a pair of start_addr, size"""
# Override rom_start/rom_size
#
# This is usually done for a target which:
# 1. Doesn't support CMSIS pack, or
# 2. Supports TrustZone and user needs to change its flash partition
cmsis_part = self._get_cmsis_part()
rom_start, rom_size = self._get_mem_specs(
["IROM1", "PROGRAM_FLASH"],
cmsis_part,
"Not enough information in CMSIS packs to build a bootloader "
"project"
)
rom_start = int(getattr(self.target, "mbed_rom_start", False) or rom_start, 0)
rom_size = int(getattr(self.target, "mbed_rom_size", False) or rom_size, 0)
return (rom_start, rom_size)

@property
def ram_regions(self):
"""Generate a list of ram regions from the config"""
cmsis_part = self._get_cmsis_part()
ram_start, ram_size = self._get_mem_specs(
["IRAM1", "SRAM0"],
cmsis_part,
"Not enough information in CMSIS packs to build a ram sharing project"
)
# Override ram_start/ram_size
#
# This is usually done for a target which:
# 1. Doesn't support CMSIS pack, or
# 2. Supports TrustZone and user needs to change its flash partition
ram_start = getattr(self.target, "mbed_ram_start", False) or ram_start
ram_size = getattr(self.target, "mbed_ram_size", False) or ram_size
return [RamRegion("application_ram", int(ram_start, 0), int(ram_size, 0), True)]

@property
def regions(self):
"""Generate a list of regions from the config"""
if ((self.target.bootloader_img or self.target.restrict_size) and
(self.target.mbed_app_start or self.target.mbed_app_size)):
raise ConfigException(
"target.bootloader_img and target.restirct_size are "
"incompatible with target.mbed_app_start and "
"target.mbed_app_size")
try:
rom_size = int(cmsis_part['memory']['IROM1']['size'], 0)
rom_start = int(cmsis_part['memory']['IROM1']['start'], 0)
except KeyError:
try:
rom_size = int(cmsis_part['memory']['PROGRAM_FLASH']['size'], 0)
rom_start = int(cmsis_part['memory']['PROGRAM_FLASH']['start'], 0)
except KeyError:
raise ConfigException("Not enough information in CMSIS packs to "
"build a bootloader project")
if self.target.bootloader_img or self.target.restrict_size:
return self._generate_bootloader_build(rom_start, rom_size)
elif self.target.mbed_app_start or self.target.mbed_app_size:
return self._generate_linker_overrides(rom_start, rom_size)
return self._generate_bootloader_build(*self.rom)
else:
raise ConfigException(
"Bootloader build requested but no bootlader configuration")
return self._generate_linker_overrides(*self.rom)

@staticmethod
def header_member_size(member):
Expand Down
62 changes: 45 additions & 17 deletions tools/toolchains/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
from itertools import chain
from inspect import getmro
from copy import deepcopy
from collections import namedtuple
from abc import ABCMeta, abstractmethod
from distutils.spawn import find_executable
from multiprocessing import Pool, cpu_count
Expand All @@ -39,6 +40,7 @@
from .. import hooks
from ..notifier.term import TerminalNotifier
from ..memap import MemapParser
from ..config import ConfigException


#Disables multiprocessing if set to higher number than the host machine CPUs
Expand Down Expand Up @@ -1184,33 +1186,59 @@ def mem_stats(self, map):

return None

def add_regions(self):
"""Add regions to the build profile, if there are any.
"""
regions = list(self.config.regions)
self.notify.info("Using regions %s in this build."
% ", ".join(region.name for region in regions))
for region in regions:
for define in [(region.name.upper() + "_ADDR", region.start),
(region.name.upper() + "_SIZE", region.size)]:
define_string = "-D%s=0x%x" % define
self.cc.append(define_string)
self.cppc.append(define_string)
self.flags["common"].append(define_string)
def _add_defines_from_region(self, region, suffixes=['_ADDR', '_SIZE']):
for define in [(region.name.upper() + suffixes[0], region.start),
(region.name.upper() + suffixes[1], region.size)]:
define_string = "-D%s=0x%x" % define
self.cc.append(define_string)
self.cppc.append(define_string)
self.flags["common"].append(define_string)

def _add_all_regions(self, region_list, active_region_name):
for region in region_list:
self._add_defines_from_region(region)
if region.active:
for define in [("MBED_APP_START", region.start),
("MBED_APP_SIZE", region.size)]:
for define in [
("%s_START" % active_region_name, region.start),
("%s_SIZE" % active_region_name, region.size)
]:
define_string = self.make_ld_define(*define)
self.ld.append(define_string)
self.flags["ld"].append(define_string)
self.notify.info(" Region %s: size 0x%x, offset 0x%x"
% (region.name, region.size, region.start))

def add_regions(self):
"""Add regions to the build profile, if there are any.
"""
if self.config.has_regions:
regions = list(self.config.regions)
self.notify.info("Using ROM region%s %s in this build." % (
"s" if len(regions) > 1 else "",
", ".join(r.name for r in regions)
))
self._add_all_regions(regions, "MBED_APP")
if self.config.has_ram_regions:
regions = list(self.config.ram_regions)
self.notify.info("Using RAM region%s %s in this build." % (
"s" if len(regions) > 1 else "",
", ".join(r.name for r in regions)
))
self._add_all_regions(regions, "MBED_RAM")
try:
rom_start, rom_size = self.config.rom
Region = namedtuple("Region", "name start size")
self._add_defines_from_region(
Region("MBED_ROM", rom_start, rom_size),
suffixes=["_START", "_SIZE"]
)
except ConfigException:
pass

# Set the configuration data
def set_config_data(self, config_data):
self.config_data = config_data
if self.config.has_regions:
self.add_regions()
self.add_regions()

# Creates the configuration header if needed:
# - if there is no configuration data, "mbed_config.h" is not create (or deleted if it exists).
Expand Down