1# 2# Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3# 4# SPDX-License-Identifier: GPL-2.0-only 5# 6 7 8class Config: 9 ''' Abstract config class ''' 10 arch = 'unknown' 11 12 def __init__(self, addrspace_max): 13 self.addrspace_max = addrspace_max 14 15 def get_kernel_phys_align(self) -> int: 16 ''' Used to align the base of physical memory. Returns alignment size in bits. ''' 17 return 0 18 19 def get_bootloader_reserve(self) -> int: 20 ''' Used to reserve a fixed amount of memory for the bootloader. Offsets 21 the kernel load address by the amount returned in bytes. ''' 22 return 0 23 24 def get_page_bits(self) -> int: 25 ''' Get page size in bits for this arch ''' 26 return 12 # 4096-byte pages 27 28 def get_device_page_bits(self) -> int: 29 ''' Get page size in bits for mapping devices for this arch ''' 30 return self.get_page_bits() 31 32 33class ARMConfig(Config): 34 ''' Config class for ARM ''' 35 SUPERSECTION_BITS = 24 36 arch = 'arm' 37 38 def get_kernel_phys_align(self) -> int: 39 ''' on ARM the ELF loader expects to be able to map a supersection page to load the kernel. ''' 40 return self.SUPERSECTION_BITS 41 42 43class RISCVConfig(Config): 44 ''' Config class for RISCV ''' 45 MEGA_PAGE_SIZE = 0x200000 46 arch = 'riscv' 47 48 def get_bootloader_reserve(self) -> int: 49 ''' on RISC-V the BBL is loaded at the start 50 of physical memory. Mark it as unavailable. ''' 51 return self.MEGA_PAGE_SIZE 52 53 def get_device_page_bits(self) -> int: 54 ''' Get page size in bits for mapping devices for this arch ''' 55 if self.addrspace_max > (1 << 32): 56 # rv39 and rv48 use 2MiB device pages 57 return 21 58 else: 59 # rv32 uses 4MiB device pages 60 return 22 61 62 63def get_arch_config(arch: str, addrspace_max: int) -> Config: 64 ''' Return an appropriate Config object for the given architecture ''' 65 if arch == 'arm': 66 return ARMConfig(addrspace_max) 67 elif arch == 'riscv': 68 return RISCVConfig(addrspace_max) 69 raise ValueError('Unsupported arch specified.') 70