diff --git a/config.cmake b/config.cmake index 6d48d32e6..fb833fee1 100644 --- a/config.cmake +++ b/config.cmake @@ -184,8 +184,8 @@ if(DEFINED KernelDTSList AND (NOT "${KernelDTSList}" STREQUAL "")) ${PYTHON3} "${HARDWARE_GEN_PATH}" --dtb "${KernelDTBPath}" --compat-strings --compat-strings-out "${compatibility_outfile}" --c-header --header-out "${device_dest}" --hardware-config "${config_file}" --hardware-schema - "${config_schema}" --yaml --yaml-out "${platform_yaml}" --arch "${KernelArch}" - --addrspace-max "${KernelPaddrUserTop}" + "${config_schema}" --yaml --yaml-out "${platform_yaml}" --sel4arch + "${KernelSel4Arch}" --addrspace-max "${KernelPaddrUserTop}" RESULT_VARIABLE error ) if(error) diff --git a/tools/hardware/config.py b/tools/hardware/config.py index 210dcf678..20f4018d3 100644 --- a/tools/hardware/config.py +++ b/tools/hardware/config.py @@ -11,7 +11,8 @@ class Config: ''' Abstract config class ''' arch = 'unknown' - def __init__(self, addrspace_max): + def __init__(self, sel4arch, addrspace_max): + self.sel4arch = sel4arch self.addrspace_max = addrspace_max def get_kernel_phys_align(self) -> int: @@ -46,8 +47,8 @@ class Config: class ARMConfig(Config): ''' Config class for ARM ''' - SUPERSECTION_BITS = 24 arch = 'arm' + SUPERSECTION_BITS = 24 # 2^24 = 16 MiByte def get_kernel_phys_align(self) -> int: ''' on ARM the ELF loader expects to be able to map a supersection page to load the kernel. ''' @@ -70,13 +71,17 @@ class ARMConfig(Config): class RISCVConfig(Config): ''' Config class for RISCV ''' - MEGA_PAGE_SIZE = 0x200000 arch = 'riscv' + MEGAPAGE_BITS_RV32 = 22 # 2^22 = 4 MiByte + MEGAPAGE_BITS_RV64 = 21 # 2^21 = 2 MiByte + MEGA_PAGE_SIZE_RV64 = 2**MEGAPAGE_BITS_RV64 def get_bootloader_reserve(self) -> int: - ''' on RISC-V OpenSBI is loaded at the start - of physical memory. Mark it as unavailable. ''' - return self.MEGA_PAGE_SIZE + ''' OpenSBI reserved the first 2 MiByte of physical memory on rv64, + which is exactly a megapage. For rv32 we use the same value for now, as + this seems to work nicely - even if this is just half of the 4 MiByte + magepages that exist there. ''' + return self.MEGA_PAGE_SIZE_RV64 def align_memory(self, regions: Set[Region]) -> List[Region]: ''' Currently the RISC-V port expects physBase to be the address that the @@ -95,18 +100,20 @@ class RISCVConfig(Config): def get_device_page_bits(self) -> int: ''' Get page size in bits for mapping devices for this arch ''' - if self.addrspace_max > (1 << 32): - # rv39 and rv48 use 2MiB device pages - return 21 - else: - # rv32 uses 4MiB device pages - return 22 + if (self.sel4arch == 'riscv32'): + # 4MiB device pages + return self.MEGAPAGE_BITS_RV32 + elif (self.sel4arch == 'riscv64'): + # 2MiB device pages for sv39 and sv48 + return self.MEGAPAGE_BITS_RV64 + raise ValueError('Unsupported sel4arch "{}" specified.'.format(self.sel4arch)) -def get_arch_config(arch: str, addrspace_max: int) -> Config: +def get_arch_config(sel4arch: str, addrspace_max: int) -> Config: ''' Return an appropriate Config object for the given architecture ''' - if arch == 'arm': - return ARMConfig(addrspace_max) - elif arch == 'riscv': - return RISCVConfig(addrspace_max) - raise ValueError('Unsupported arch specified.') + if sel4arch in ['aarch32', 'aarch64', 'arm_hyp']: + return ARMConfig(sel4arch, addrspace_max) + elif sel4arch in ['riscv32', 'riscv64']: + return RISCVConfig(sel4arch, addrspace_max) + else: + raise ValueError('Unsupported sel4arch "{}" specified.'.format(sel4arch)) diff --git a/tools/hardware/outputs/c_header.py b/tools/hardware/outputs/c_header.py index 4fa7e3d1a..63fb990c4 100644 --- a/tools/hardware/outputs/c_header.py +++ b/tools/hardware/outputs/c_header.py @@ -78,7 +78,7 @@ static const kernel_frame_t BOOT_RODATA kernel_device_frames[] = { /* contains {{ ', '.join(group.labels.keys()) }} */ .pptr = KDEV_BASE + {{ "0x{:x}".format(map_addr) }}, {% endif %} - {% if args.arch == 'arm' %} + {% if config.arch == 'arm' %} .armExecuteNever = true, {% endif %} .userAvailable = {{ str(group.user_ok).lower() }} @@ -176,7 +176,7 @@ def get_interrupts(tree: FdtParser, hw_yaml: HardwareYaml) -> List: return ret -def create_c_header_file(args, kernel_irqs: List, kernel_macros: Dict, +def create_c_header_file(config, kernel_irqs: List, kernel_macros: Dict, kernel_regions: List, physBase: int, physical_memory, outputStream): @@ -187,7 +187,7 @@ def create_c_header_file(args, kernel_irqs: List, kernel_macros: Dict, template_args = dict( builtins.__dict__, **{ - 'args': args, + 'config': config, 'kernel_irqs': kernel_irqs, 'kernel_macros': kernel_macros, 'kernel_regions': kernel_regions, @@ -207,7 +207,7 @@ def run(tree: FdtParser, hw_yaml: HardwareYaml, config: Config, args: argparse.N kernel_regions, kernel_macros = get_kernel_devices(tree, hw_yaml) create_c_header_file( - args, + config, get_interrupts(tree, hw_yaml), kernel_macros, kernel_regions, diff --git a/tools/hardware_gen.py b/tools/hardware_gen.py index 6d084a1c6..a97d23f0d 100644 --- a/tools/hardware_gen.py +++ b/tools/hardware_gen.py @@ -49,7 +49,7 @@ def add_task_args(outputs: dict, parser: argparse.ArgumentParser): def main(args: argparse.Namespace): ''' Parse the DT and hardware config YAML and run each selected output method. ''' - cfg = hardware.config.get_arch_config(args.arch, args.addrspace_max) + cfg = hardware.config.get_arch_config(args.sel4arch, args.addrspace_max) parsed_dt = FdtParser(args.dtb) rules = yaml.load(args.hardware_config, Loader=yaml.FullLoader) schema = yaml.load(args.hardware_schema, Loader=yaml.FullLoader) @@ -73,7 +73,8 @@ if __name__ == '__main__': required=True, type=argparse.FileType('r')) parser.add_argument('--hardware-schema', help='YAML file containing schema for hardware config', required=True, type=argparse.FileType('r')) - parser.add_argument('--arch', help='architecture to generate for', default='arm') + parser.add_argument('--sel4arch', help='seL4 architecture to generate for', + required=True) parser.add_argument('--addrspace-max', help='maximum address that is available as device untyped', type=int, default=32)