diff --git a/.cmake-format.yaml b/.cmake-format.yaml index 721a7f42f2a..fa8b105861b 100644 --- a/.cmake-format.yaml +++ b/.cmake-format.yaml @@ -24,8 +24,10 @@ additional_commands: DEFAULT: '*' DEPENDS: '*' cppfile: + pargs: + nargs: '3' kwargs: - EXACT_NAME: '*' + EXACT_NAME: '?' EXTRA_DEPS: '*' EXTRA_FLAGS: '*' gen_invocation_header: @@ -42,16 +44,16 @@ additional_commands: PREFIX: '*' declare_default_headers: kwargs: - TIMER_FREQUENCY: '*' - MAX_IRQ: '*' - NUM_PPI: '*' - INTERRUPT_CONTROLLER: '*' - TIMER: '*' - KERNEL_WCET: '*' - CLK_MAGIC: '*' - CLK_SHIFT: '*' - TIMER_PRECISION: '*' - TIMER_OVERHEAD_TICKS: '*' - SMMU: '*' - MAX_SID: '*' - MAX_CB: '*' + TIMER_FREQUENCY: '1' + MAX_IRQ: '1' + NUM_PPI: '1' + INTERRUPT_CONTROLLER: '1' + TIMER: '1' + KERNEL_WCET: '1' + CLK_MAGIC: '1' + CLK_SHIFT: '1' + TIMER_PRECISION: '1' + TIMER_OVERHEAD_TICKS: '1' + SMMU: '1' + MAX_SID: '1' + MAX_CB: '1' diff --git a/include/arch/arm/arch/32/mode/object/structures.h b/include/arch/arm/arch/32/mode/object/structures.h index f6bb938df6a..7e572e5f506 100644 --- a/include/arch/arm/arch/32/mode/object/structures.h +++ b/include/arch/arm/arch/32/mode/object/structures.h @@ -42,7 +42,6 @@ typedef pde_t vspace_root_t; #define PGDE_SIZE_BITS seL4_PGDEntryBits #define PDE_SIZE_BITS seL4_PageDirEntryBits -#define PTE_SIZE_BITS seL4_PageTableEntryBits #define PGD_INDEX_BITS seL4_PGDIndexBits #define PD_INDEX_BITS seL4_PageDirIndexBits #define PT_INDEX_BITS seL4_PageTableIndexBits diff --git a/include/arch/arm/arch/64/mode/object/structures.h b/include/arch/arm/arch/64/mode/object/structures.h index 781aff1517f..47493bd7267 100644 --- a/include/arch/arm/arch/64/mode/object/structures.h +++ b/include/arch/arm/arch/64/mode/object/structures.h @@ -30,7 +30,6 @@ enum vm_rights { }; typedef word_t vm_rights_t; -#define PTE_SIZE_BITS seL4_PageTableEntryBits #define PT_INDEX_BITS seL4_PageTableIndexBits #define PT_INDEX_OFFSET (seL4_PageBits) diff --git a/include/arch/riscv/arch/32/mode/machine.h b/include/arch/riscv/arch/32/mode/machine.h index b3933a116ec..2fc0a06a3c0 100644 --- a/include/arch/riscv/arch/32/mode/machine.h +++ b/include/arch/riscv/arch/32/mode/machine.h @@ -8,9 +8,40 @@ #include #include +#include #include #include +/* Read a consistent 64-bit counter value from two 32-bit registers. The value + * from the low register is used only if there was no roll over, otherwise it is + * simply taken as 0. This is an acceptable optimization if the value must have + * been 0 at some point anyway and certain jitter is acceptable. For high + * frequency counters the preference usually not on getting an exact value, but + * a value close to the point in time where the read function was called. For a + * low frequency counter, the low value is likely 0 anyway when a roll over + * happens. + */ +#define declare_helper_riscv_read_csr64cntr(_name_, _id_hi_, _id_lo_) \ + static inline uint64_t riscv_read_csr64cntr_##_name_(void) \ + { \ + register word_t nH_prev, nH, nL; \ + RISCV_CSR_READ(_id_hi_, nH_prev); \ + RISCV_CSR_READ(_id_lo_, nL); \ + RISCV_CSR_READ(_id_hi_, nH); \ + if (nH_prev != nH) { RISCV_CSR_READ(_id_lo_, nL); } \ + return (((uint64_t)nH) << 32) | nL; \ + } + +/* create riscv_read_csr64cntr_time() */ +declare_helper_riscv_read_csr64cntr(time, RISCV_CSR_TIMEH, RISCV_CSR_TIME) + +/* create riscv_read_csr64cntr_cycle() */ +declare_helper_riscv_read_csr64cntr(cycle, RISCV_CSR_CYCLEH, RISCV_CSR_CYCLE) + +/* create get_riscv_csr64cntr_instret() */ +declare_helper_riscv_read_csr64cntr(instret, RISCV_CSR_INSTRETH, RISCV_CSR_INSTRET) + + #ifdef CONFIG_RISCV_USE_CLINT_MTIME /* * Currently all RISC-V 32-bit platforms supported have the mtime register @@ -18,50 +49,44 @@ */ #define CLINT_MTIME_OFFSET_LO 0xbff8 #define CLINT_MTIME_OFFSET_HI 0xbffc -#endif -static inline uint64_t riscv_read_time(void) +static inline uint32_t riscv_read_clint_u32(word_t offset) { - word_t nH1, nL, nH2; + return *(volatile uint32_t *)(CLINT_PPTR + offset); +} -#ifdef CONFIG_RISCV_USE_CLINT_MTIME - nH1 = *(volatile uint32_t *)(CLINT_PPTR + CLINT_MTIME_OFFSET_HI); - nL = *(volatile uint32_t *)(CLINT_PPTR + CLINT_MTIME_OFFSET_LO); - nH2 = *(volatile uint32_t *)(CLINT_PPTR + CLINT_MTIME_OFFSET_HI); - if (nH1 != nH2) { - /* Ensure that the time is correct if there is a rollover in the - * high bits between reading the low and high bits. */ - nL = *(volatile uint32_t *)(CLINT_PPTR + CLINT_MTIME_OFFSET_LO); +static inline uint64_t riscv_read_clint_mtime(void) +{ + /* + * Ensure that the time is correct if there is a rollover in the + * high bits between reading the low and high bits. + */ + uint32_t nH_prev = riscv_read_clint_u32(CLINT_MTIME_OFFSET_HI); + uint32_t nL = riscv_read_clint_u32(CLINT_MTIME_OFFSET_LO); + uint32_t nH = riscv_read_clint_u32(CLINT_MTIME_OFFSET_HI); + if (nH_prev != nH) { + nL = riscv_read_clint_u32(CLINT_MTIME_OFFSET_LO); } + return (((uint64_t)nH) << 32) | nL; +} + +#endif /* CONFIG_RISCV_USE_CLINT_MTIME */ + +static inline uint64_t riscv_read_time(void) +{ +#ifdef CONFIG_RISCV_USE_CLINT_MTIME + return riscv_read_clint_mtime(); #else - asm volatile( - "rdtimeh %0\n" - "rdtime %1\n" - "rdtimeh %2\n" - : "=r"(nH1), "=r"(nL), "=r"(nH2)); - if (nH1 != nH2) { - /* Ensure that the time is correct if there is a rollover in the - * high bits between reading the low and high bits. */ - asm volatile("rdtime %0\n" : "=r"(nL)); - } + return riscv_read_csr64cntr_time(); #endif - - return (((uint64_t)nH2) << 32) | nL; } - static inline uint64_t riscv_read_cycle(void) { - word_t nH1, nL, nH2; - asm volatile( - "rdcycleh %0\n" - "rdcycle %1\n" - "rdcycleh %2\n" - : "=r"(nH1), "=r"(nL), "=r"(nH2)); - if (nH1 != nH2) { - /* Ensure that the cycles are correct if there is a rollover in the - * high bits between reading the low and high bits. */ - asm volatile("rdcycle %0\n" : "=r"(nL)); - } - return (((uint64_t)nH2) << 32) | nL; + return riscv_read_csr64cntr_cycle(); +} + +static inline uint64_t riscv_read_instret(void) +{ + return riscv_read_csr64cntr_instret(); } diff --git a/include/arch/riscv/arch/64/mode/machine.h b/include/arch/riscv/arch/64/mode/machine.h index be4d5dc9300..d478c2e41bc 100644 --- a/include/arch/riscv/arch/64/mode/machine.h +++ b/include/arch/riscv/arch/64/mode/machine.h @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -17,22 +18,34 @@ * mapped at the same offset of the base address of the CLINT. */ #define CLINT_MTIME_OFFSET 0xbff8 -#endif + +static inline uint64_t riscv_read_clint_u64(word_t offset) +{ + return *(volatile uint64_t *)(CLINT_PPTR + offset); +} + +static inline uint64_t riscv_read_clint_mtime(void) +{ + return riscv_read_clint_u64(CLINT_MTIME_OFFSET); +} + +#endif /* CONFIG_RISCV_USE_CLINT_MTIME */ static inline uint64_t riscv_read_time(void) { - word_t n; #ifdef CONFIG_RISCV_USE_CLINT_MTIME - n = *(volatile word_t *)(CLINT_PPTR + CLINT_MTIME_OFFSET); + return riscv_read_clint_mtime(); #else - asm volatile("rdtime %0" : "=r"(n)); + return riscv_read_csr_time(); #endif - return n; } static inline uint64_t riscv_read_cycle(void) { - word_t n; - asm volatile("rdcycle %0" : "=r"(n)); - return n; + return riscv_read_csr_cycle(); +} + +static inline uint64_t riscv_read_instret(void) +{ + return riscv_read_csr_instret(); } diff --git a/include/arch/riscv/arch/machine/hardware.h b/include/arch/riscv/arch/machine/hardware.h index 1c8506fb931..05b61a1b782 100644 --- a/include/arch/riscv/arch/machine/hardware.h +++ b/include/arch/riscv/arch/machine/hardware.h @@ -45,8 +45,8 @@ * configured RISC-V system with CONFIG_PT_LEVEL (which can be 2 on Sv32, * 3 on Sv39, or 4 on Sv48) */ -#define RISCV_GET_PT_INDEX(addr, n) (((addr) >> (((PT_INDEX_BITS) * (((CONFIG_PT_LEVELS) - 1) - (n))) + seL4_PageBits)) & MASK(PT_INDEX_BITS)) -#define RISCV_GET_LVL_PGSIZE_BITS(n) (((PT_INDEX_BITS) * (((CONFIG_PT_LEVELS) - 1) - (n))) + seL4_PageBits) +#define RISCV_GET_PT_INDEX(addr, n) (((addr) >> (((seL4_PageTableIndexBits) * (((CONFIG_PT_LEVELS) - 1) - (n))) + seL4_PageBits)) & MASK(seL4_PageTableIndexBits)) +#define RISCV_GET_LVL_PGSIZE_BITS(n) (((seL4_PageTableIndexBits) * (((CONFIG_PT_LEVELS) - 1) - (n))) + seL4_PageBits) #define RISCV_GET_LVL_PGSIZE(n) BIT(RISCV_GET_LVL_PGSIZE_BITS((n))) /* * These values are defined in RISC-V priv-1.10 manual, they represent the diff --git a/include/arch/riscv/arch/machine/registerset.h b/include/arch/riscv/arch/machine/registerset.h index 118fbbd211e..a748cfe7225 100644 --- a/include/arch/riscv/arch/machine/registerset.h +++ b/include/arch/riscv/arch/machine/registerset.h @@ -184,5 +184,46 @@ static inline word_t CONST sanitiseRegister(register_t reg, word_t v, bool_t arc [seL4_TimeoutReply_TP] = TP, \ } -#endif /* __ASSEMBLER__ */ +#define RISCV_CSR_CYCLE 0xc00 +#define RISCV_CSR_TIME 0xc01 +#define RISCV_CSR_INSTRET 0xc02 +#ifdef CONFIG_ARCH_RISCV32 +#define RISCV_CSR_CYCLEH 0xc80 +#define RISCV_CSR_TIMEH 0xc81 +#define RISCV_CSR_INSTRETH 0xc82 +#endif /* CONFIG_ARCH_RISCV32 */ + + +#define RISCV_CSR_READ(_id_, _var_) \ + asm volatile("csrr %0, " #_id_ : "=r" (_var_) : : "memory") + +#define declare_helper_riscv_read_csr(_name_, _id_) \ + static inline word_t riscv_read_csr_##_name_(void) \ + { \ + register word_t val; \ + RISCV_CSR_READ(_id_, val); \ + return val; \ + } + +/* create riscv_read_csr_cycle() */ +declare_helper_riscv_read_csr(cycle, RISCV_CSR_CYCLE) +#ifdef CONFIG_ARCH_RISCV32 +/* create riscv_read_csr_cycleh() */ +declare_helper_riscv_read_csr(cycleh, RISCV_CSR_CYCLEH) +#endif + +/* create riscv_read_csr_time() */ +declare_helper_riscv_read_csr(time, RISCV_CSR_TIME) +#ifdef CONFIG_ARCH_RISCV32 +/* create riscv_read_csr_timeh() */ +declare_helper_riscv_read_csr(timeh, RISCV_CSR_TIMEH) +#endif +/* create riscv_read_csr_instret() */ +declare_helper_riscv_read_csr(instret, RISCV_CSR_INSTRET) +#ifdef CONFIG_ARCH_RISCV32 +/* create riscv_read_csr_instreth() */ +declare_helper_riscv_read_csr(instreth, RISCV_CSR_INSTRETH) +#endif + +#endif /* __ASSEMBLER__ */ diff --git a/include/arch/riscv/arch/model/statedata.h b/include/arch/riscv/arch/model/statedata.h index c7b0af85fa8..b0401252329 100644 --- a/include/arch/riscv/arch/model/statedata.h +++ b/include/arch/riscv/arch/model/statedata.h @@ -25,14 +25,14 @@ NODE_STATE_END(archNodeState); extern asid_pool_t *riscvKSASIDTable[BIT(asidHighBits)]; /* Kernel Page Tables */ -extern pte_t kernel_root_pageTable[BIT(PT_INDEX_BITS)] VISIBLE; +extern pte_t kernel_root_pageTable[BIT(seL4_PageTableIndexBits)] VISIBLE; /* We need to introduce a level2 pagetable in order to map OpenSBI to a separate * page entry to avoid PMP exception. */ #if __riscv_xlen != 32 -extern pte_t kernel_image_level2_pt[BIT(PT_INDEX_BITS)]; -extern pte_t kernel_image_level2_dev_pt[BIT(PT_INDEX_BITS)]; +extern pte_t kernel_image_level2_pt[BIT(seL4_PageTableIndexBits)]; +extern pte_t kernel_image_level2_dev_pt[BIT(seL4_PageTableIndexBits)]; #elif defined(CONFIG_KERNEL_LOG_BUFFER) -extern pte_t kernel_image_level2_log_buffer_pt[BIT(PT_INDEX_BITS)]; +extern pte_t kernel_image_level2_log_buffer_pt[BIT(seL4_PageTableIndexBits)]; #endif diff --git a/include/arch/riscv/arch/object/structures.h b/include/arch/riscv/arch/object/structures.h index 35c216a2118..6170ec2a5e8 100644 --- a/include/arch/riscv/arch/object/structures.h +++ b/include/arch/riscv/arch/object/structures.h @@ -54,16 +54,9 @@ typedef pte_t pde_t; #define PTE_PTR(r) ((pte_t *)(r)) #define PTE_REF(p) ((word_t)(p)) -#define PT_SIZE_BITS 12 #define PT_PTR(r) ((pte_t *)(r)) #define PT_REF(p) ((word_t)(p)) -#define PTE_SIZE_BITS seL4_PageTableEntryBits -#define PT_INDEX_BITS seL4_PageTableIndexBits - -#define WORD_BITS (8 * sizeof(word_t)) -#define WORD_PTR(r) ((word_t *)(r)) - static inline bool_t CONST cap_get_archCapIsPhysical(cap_t cap) { cap_tag_t ctag; @@ -98,10 +91,11 @@ static inline word_t CONST cap_get_archCapSizeBits(cap_t cap) switch (ctag) { case cap_frame_cap: + /* ToDo: could we simply use seL4_PageBits here? */ return pageBitsForSize(cap_frame_cap_get_capFSize(cap)); case cap_page_table_cap: - return PT_SIZE_BITS; + return seL4_PageTableBits; case cap_asid_control_cap: return 0; diff --git a/include/arch/riscv/arch/sbi.h b/include/arch/riscv/arch/sbi.h index 60927d2e212..c13e902b87e 100644 --- a/include/arch/riscv/arch/sbi.h +++ b/include/arch/riscv/arch/sbi.h @@ -1,7 +1,8 @@ /* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright (c) 2010-2017, The Regents of the University of California - * (Regents). All Rights Reserved. + * (Regents). All Rights Reserved. + * Copyright 2021, HENSOLDT Cyber * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -33,6 +34,20 @@ #pragma once #include +#if defined(CONFIG_RISCV_SBI_NONE) +/* nothing here if there is no SBI */ +#else + +/* We check for specific SBI implementation here, but actually this is checking + * for a specific SBI interface. It does not matter what SBI implementation is + * running on a platform implementing this interface. + */ +#if !defined(CONFIG_RISCV_SBI_OPENSBI) \ + && !defined(CONFIG_RISCV_SBI_BBL) \ + && !defined(CONFIG_RISCV_SBI_ROM) +#error Unknown SBI implementation +#endif + #include /* See https://github.com/riscv/riscv-sbi-doc/blob/master/riscv-sbi.adoc for @@ -155,3 +170,4 @@ static inline void sbi_remote_sfence_vma_asid(word_t hart_mask, } #endif /* ENABLE_SMP_SUPPORT */ +#endif /* not CONFIG_RISCV_SBI_NONE */ diff --git a/include/arch/riscv/arch/smp/ipi.h b/include/arch/riscv/arch/smp/ipi.h index c3aef5f8b34..1b25d18ec6b 100644 --- a/include/arch/riscv/arch/smp/ipi.h +++ b/include/arch/riscv/arch/smp/ipi.h @@ -9,6 +9,7 @@ #include #ifdef ENABLE_SMP_SUPPORT + typedef enum { IpiRemoteCall_Stall, IpiRemoteCall_switchFpuOwner, @@ -18,5 +19,5 @@ typedef enum { void ipi_send_target(irq_t irq, word_t cpuTargetList); irq_t ipi_get_irq(void); void ipi_clear_irq(irq_t irq); -#endif +#endif /* ENABLE_SMP_SUPPORT */ diff --git a/libsel4/sel4_arch_include/riscv32/sel4/sel4_arch/constants.h b/libsel4/sel4_arch_include/riscv32/sel4/sel4_arch/constants.h index 9b3dec98e1d..1ba4621953c 100644 --- a/libsel4/sel4_arch_include/riscv32/sel4/sel4_arch/constants.h +++ b/libsel4/sel4_arch_include/riscv32/sel4/sel4_arch/constants.h @@ -33,18 +33,28 @@ #define seL4_MinUntypedBits 4 #define seL4_MaxUntypedBits 29 -/* RISC-V Sv32 pages/ptes sizes */ -#define seL4_PageTableEntryBits 2 -#define seL4_PageTableIndexBits 10 - +/* In the RISC-V architecture (Sv32) a page is 4 KiB and each page table uses + * exactly one page. A VSpace is simply the root page table. Since each page + * table entry has 2^2 = 4 byte = 32 bit per entry, a page table has 1024 + * entries. Thus each page table level can cover 2^10 (=1024) times the size of + * one entry, which give 4 MiB (2^22) "megapages" + */ #define seL4_PageBits 12 -#define seL4_LargePageBits 22 -#define seL4_PageTableBits 12 +#define seL4_PageTableBits seL4_PageBits #define seL4_VSpaceBits seL4_PageTableBits -#define seL4_NumASIDPoolsBits 5 +#define seL4_PageTableEntryBits 2 +#define seL4_PageTableIndexBits (seL4_PageTableBits - seL4_PageTableEntryBits) + +/* megapages are LargePages in the seL4 terminology */ +#define seL4_LargePageBits (seL4_PageBits + seL4_PageTableIndexBits) + + +/* The ASID pool uses one page */ +#define seL4_ASIDPoolBits seL4_PageBits +#define seL4_NumASIDPoolsBits 5 #define seL4_ASIDPoolIndexBits 4 -#define seL4_ASIDPoolBits 12 + #ifndef __ASSEMBLER__ typedef enum { diff --git a/libsel4/sel4_arch_include/riscv64/sel4/sel4_arch/constants.h b/libsel4/sel4_arch_include/riscv64/sel4/sel4_arch/constants.h index 90458028e91..9682acca79b 100644 --- a/libsel4/sel4_arch_include/riscv64/sel4/sel4_arch/constants.h +++ b/libsel4/sel4_arch_include/riscv64/sel4/sel4_arch/constants.h @@ -29,20 +29,33 @@ #define seL4_TCBBits 10 #endif -/* Sv39/Sv48 pages/ptes sizes */ +/* In the RISC-V architecture (Sv39/Sv48/Sv57) a page is 4 KiB and each page + * table uses exactly one page. A VSpace is simply the root page table. Since + * each page table entry has 2^3 = 8 byte = 64 bit per entry, a page table has + * 512 entries. Each page table level can cover 2^9 (=512) times the size of one + * single entry, which gives 2 MiB (2^21) "megapages", 1 GiB (2^30) + * "gigapages", 512 GiB (2^39) "terapages" and 256 TiB (2^48) "petapages" + */ +#define seL4_PageBits 12 +#define seL4_PageTableBits seL4_PageBits +#define seL4_VSpaceBits seL4_PageTableBits + #define seL4_PageTableEntryBits 3 -#define seL4_PageTableIndexBits 9 +#define seL4_PageTableIndexBits (seL4_PageTableBits - seL4_PageTableEntryBits) -#define seL4_PageBits 12 -#define seL4_LargePageBits 21 -#define seL4_HugePageBits 30 -#define seL4_TeraPageBits 39 -#define seL4_PageTableBits 12 -#define seL4_VSpaceBits seL4_PageTableBits +/* "megapages" are LargePages and "gigapages" are HugePages in the seL4 + * terminology. This names come from the ARM port and kept here for consistency + * in the generic code. + */ +#define seL4_LargePageBits (seL4_PageBits + seL4_PageTableIndexBits) +#define seL4_HugePageBits (seL4_LargePageBits + seL4_PageTableIndexBits) +#define seL4_TeraPageBits (seL4_HugePageBits + seL4_PageTableIndexBits) +#define seL4_PetaPageBits (seL4_TeraPageBits + seL4_PageTableIndexBits) +/* The ASID pool uses one page */ +#define seL4_ASIDPoolBits seL4_PageBits #define seL4_NumASIDPoolsBits 7 #define seL4_ASIDPoolIndexBits 9 -#define seL4_ASIDPoolBits 12 /* Untyped size limits */ #define seL4_MinUntypedBits 4 diff --git a/src/arch/arm/32/kernel/vspace.c b/src/arch/arm/32/kernel/vspace.c index 4f57027c0fb..fbf6b59e541 100644 --- a/src/arch/arm/32/kernel/vspace.c +++ b/src/arch/arm/32/kernel/vspace.c @@ -40,7 +40,7 @@ /* helper stuff to avoid fencepost errors when * getting the last byte of a PTE or PDE */ -#define LAST_BYTE_PTE(PTE,LENGTH) ((word_t)&(PTE)[(LENGTH)-1] + (BIT(PTE_SIZE_BITS)-1)) +#define LAST_BYTE_PTE(PTE,LENGTH) ((word_t)&(PTE)[(LENGTH)-1] + (BIT(seL4_PageTableEntryBits)-1)) #define LAST_BYTE_PDE(PDE,LENGTH) ((word_t)&(PDE)[(LENGTH)-1] + (BIT(PDE_SIZE_BITS)-1)) #ifdef CONFIG_ARM_HYPERVISOR_SUPPORT diff --git a/src/arch/arm/32/object/objecttype.c b/src/arch/arm/32/object/objecttype.c index 03587173830..6e1f972e1df 100644 --- a/src/arch/arm/32/object/objecttype.c +++ b/src/arch/arm/32/object/objecttype.c @@ -359,7 +359,7 @@ word_t Arch_getObjectSize(word_t t) case seL4_ARM_SuperSectionObject: return ARMSuperSectionBits; case seL4_ARM_PageTableObject: - return PTE_SIZE_BITS + PT_INDEX_BITS; + return seL4_PageTableEntryBits + PT_INDEX_BITS; case seL4_ARM_PageDirectoryObject: return PDE_SIZE_BITS + PD_INDEX_BITS; #ifdef CONFIG_TK1_SMMU diff --git a/src/arch/riscv/common_riscv.lds b/src/arch/riscv/common_riscv.lds index b45368c6de0..44044ff59d1 100644 --- a/src/arch/riscv/common_riscv.lds +++ b/src/arch/riscv/common_riscv.lds @@ -46,7 +46,7 @@ SECTIONS { . = ALIGN(4K); - /* Traps and fastpath */ + /* Traps and fastpath */ *(.text.traps) *(.text.fastpath) diff --git a/src/arch/riscv/config.cmake b/src/arch/riscv/config.cmake index 1179ece980f..76d49cddc74 100644 --- a/src/arch/riscv/config.cmake +++ b/src/arch/riscv/config.cmake @@ -1,5 +1,6 @@ # # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) +# Copyright 2021, HENSOLDT Cyber # # SPDX-License-Identifier: GPL-2.0-only # @@ -38,6 +39,16 @@ config_option( DEPENDS "KernelArchRiscV" ) +config_choice( + KernelRiscVSBI + RISCV_SBI + "RISC-V SBI implementation" + "OpenSBI;KernelRiscvSBI_OpenSBI;RISCV_SBI_OPENSBI;KernelArchRiscV" + "none;KernelRiscvSBI_None;RISCV_SBI_NONE;KernelArchRiscV" + "ROM;KernelRiscvSBI_ROM;RISCV_SBI_ROM;KernelArchRiscV" + "BBL;KernelRiscvSBI_BBL;RISCV_SBI_BBL;KernelArchRiscV" +) + # Until RISC-V has instructions to count leading/trailing zeros, we provide # library implementations. Platforms that implement the bit manipulation # extension can override these settings to remove the library functions from diff --git a/src/arch/riscv/kernel/vspace.c b/src/arch/riscv/kernel/vspace.c index e3ecdb6a688..4b229c5d3f5 100644 --- a/src/arch/riscv/kernel/vspace.c +++ b/src/arch/riscv/kernel/vspace.c @@ -348,7 +348,7 @@ void copyGlobalMappings(pte_t *newLvl1pt) unsigned long i; pte_t *global_kernel_vspace = kernel_root_pageTable; - for (i = RISCV_GET_PT_INDEX(PPTR_BASE, 0); i < BIT(PT_INDEX_BITS); i++) { + for (i = RISCV_GET_PT_INDEX(PPTR_BASE, 0); i < BIT(seL4_PageTableIndexBits); i++) { newLvl1pt[i] = global_kernel_vspace[i]; } } @@ -399,14 +399,14 @@ lookupPTSlot_ret_t lookupPTSlot(pte_t *lvl1pt, vptr_t vptr) * final value of this after the walk is the size of the frame that can be inserted, * or already exists, in ret.ptSlot. The following formulation is an invariant of * the loop: */ - ret.ptBitsLeft = PT_INDEX_BITS * level + seL4_PageBits; - ret.ptSlot = pt + ((vptr >> ret.ptBitsLeft) & MASK(PT_INDEX_BITS)); + ret.ptBitsLeft = seL4_PageTableIndexBits * level + seL4_PageBits; + ret.ptSlot = pt + ((vptr >> ret.ptBitsLeft) & MASK(seL4_PageTableIndexBits)); while (isPTEPageTable(ret.ptSlot) && likely(0 < level)) { level--; - ret.ptBitsLeft -= PT_INDEX_BITS; + ret.ptBitsLeft -= seL4_PageTableIndexBits; pt = getPPtrFromHWPTE(ret.ptSlot); - ret.ptSlot = pt + ((vptr >> ret.ptBitsLeft) & MASK(PT_INDEX_BITS)); + ret.ptSlot = pt + ((vptr >> ret.ptBitsLeft) & MASK(seL4_PageTableIndexBits)); } return ret; @@ -1224,7 +1224,7 @@ exception_t benchmark_arch_map_logBuffer(word_t frame_cptr) #if __riscv_xlen == 32 paddr_t physical_address = ksUserLogBuffer; - for (word_t i = 0; i < BIT(PT_INDEX_BITS); i += 1) { + for (word_t i = 0; i < BIT(seL4_PageTableIndexBits); i += 1) { kernel_image_level2_log_buffer_pt[i] = pte_next(physical_address, true); physical_address += BIT(PAGE_BITS); } diff --git a/src/arch/riscv/machine/capdl.c b/src/arch/riscv/machine/capdl.c index 0450ecbe14f..510f1d99f6f 100644 --- a/src/arch/riscv/machine/capdl.c +++ b/src/arch/riscv/machine/capdl.c @@ -52,11 +52,11 @@ static void riscv_cap_pt_print_slots(pte_t *upperPtSlot, word_t ptIndex, int lev } level -= 1; - word_t ptBitsLeft = PT_INDEX_BITS * level + seL4_PageBits; + word_t ptBitsLeft = seL4_PageTableIndexBits * level + seL4_PageBits; /* - 1 to avoid overflowing */ - for (word_t i = 0; i < BIT(ptBitsLeft + PT_INDEX_BITS) - 1; i += (1 << (ptBitsLeft))) { - word_t ptSlotIndex = ((i >> ptBitsLeft) & MASK(PT_INDEX_BITS)); + for (word_t i = 0; i < BIT(ptBitsLeft + seL4_PageTableIndexBits) - 1; i += (1 << (ptBitsLeft))) { + word_t ptSlotIndex = ((i >> ptBitsLeft) & MASK(seL4_PageTableIndexBits)); pte_t *ptSlot = pt + ptSlotIndex; if (pte_ptr_get_valid(ptSlot)) { if (level) { /* pt */ @@ -69,8 +69,8 @@ static void riscv_cap_pt_print_slots(pte_t *upperPtSlot, word_t ptIndex, int lev } printf("}\n"); /* lvl1pt/pt */ - for (word_t i = 0; i < BIT(ptBitsLeft + PT_INDEX_BITS) - 1; i += (1 << (ptBitsLeft))) { - word_t ptSlotIndex = ((i >> ptBitsLeft) & MASK(PT_INDEX_BITS)); + for (word_t i = 0; i < BIT(ptBitsLeft + seL4_PageTableIndexBits) - 1; i += (1 << (ptBitsLeft))) { + word_t ptSlotIndex = ((i >> ptBitsLeft) & MASK(seL4_PageTableIndexBits)); pte_t *ptSlot = pt + ptSlotIndex; if (pte_ptr_get_valid(ptSlot)) { if (level) { /* pt */ @@ -115,7 +115,7 @@ static void cap_frame_print_attrs_vptr(word_t vptr, pte_t *lvl1pt) { lookupPTSlot_ret_t lu_ret = lookupPTSlot(lvl1pt, vptr); assert(lu_ret.ptBitsLeft == seL4_PageBits); - word_t slot = ((vptr >> lu_ret.ptBitsLeft) & MASK(PT_INDEX_BITS)); + word_t slot = ((vptr >> lu_ret.ptBitsLeft) & MASK(seL4_PageTableIndexBits)); printf("frame_%p_%04lu ", lu_ret.ptSlot, slot); cap_frame_print_attrs_pt(lu_ret.ptSlot); @@ -129,8 +129,8 @@ void print_cap_arch(cap_t cap) findVSpaceForASID_ret_t find_ret = findVSpaceForASID(asid); vptr_t vptr = cap_page_table_cap_get_capPTMappedAddress(cap); - word_t ptBitsLeft = PT_INDEX_BITS * CONFIG_PT_LEVELS + seL4_PageBits; - word_t slot = ((vptr >> ptBitsLeft) & MASK(PT_INDEX_BITS)); + word_t ptBitsLeft = seL4_PageTableIndexBits * CONFIG_PT_LEVELS + seL4_PageBits; + word_t slot = ((vptr >> ptBitsLeft) & MASK(seL4_PageTableIndexBits)); if (asid) { printf("pt_%p_%04lu (asid: %lu)\n", lookupPTSlot(find_ret.vspace_root, vptr).ptSlot, slot, (long unsigned int)asid); @@ -195,10 +195,10 @@ void print_object_arch(cap_t cap) static void riscv_obj_pt_print_slots(pte_t *lvl1pt, pte_t *pt, int level) { - word_t ptBitsLeft = PT_INDEX_BITS * level + seL4_PageBits; + word_t ptBitsLeft = seL4_PageTableIndexBits * level + seL4_PageBits; - for (word_t i = 0; i < BIT(ptBitsLeft + PT_INDEX_BITS); i += (1 << (ptBitsLeft))) { - word_t ptIndex = ((i >> ptBitsLeft) & MASK(PT_INDEX_BITS)); + for (word_t i = 0; i < BIT(ptBitsLeft + seL4_PageTableIndexBits); i += (1 << (ptBitsLeft))) { + word_t ptIndex = ((i >> ptBitsLeft) & MASK(seL4_PageTableIndexBits)); pte_t *ptSlot = pt + ptIndex; if (pte_ptr_get_valid(ptSlot)) { if (level) { /* pt */ diff --git a/src/arch/riscv/machine/io.c b/src/arch/riscv/machine/io.c index 6987319dd24..1462cbfaf41 100644 --- a/src/arch/riscv/machine/io.c +++ b/src/arch/riscv/machine/io.c @@ -1,6 +1,7 @@ /* * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) * Copyright 2015, 2016 Hesham Almatary + * Copyright 2021, HENSOLDT Cyber * * SPDX-License-Identifier: GPL-2.0-only */ @@ -12,12 +13,23 @@ #ifdef CONFIG_PRINTING void kernel_putDebugChar(unsigned char c) { - /* Don't use any UART driver, but write to the SBI console. It depends on - * the SBI implementation if printing a '\r' (CR) before any '\n' (LF) is - * required explicitly or if SBI takes care of this. Currently BBL requires - * it, while OpenSBI takes care of this internally. Since we dropped BBL - * support in favor of OpenSBI, we do not print a '\r' (CR) here. + +#if defined(CONFIG_RISCV_SBI_NONE) +#error Implment a UART driver for RISC-V if no SBI console exists +#endif + + /* Don't use any UART driver, but write to the SBI console. */ + +#if defined(CONFIG_RISCV_SBI_BBL) + /* BBL does not implement ab abstract console, but passes data to the UART + * transparently. Thus we must take care of printing a '\r' (CR) before any + * '\n' (LF) to comply with the common serial terminal usage. */ + if (c == '\n') { + sbi_console_putchar('\r'); + } +#endif + sbi_console_putchar(c); } #endif /* CONFIG_PRINTING */ @@ -25,6 +37,11 @@ void kernel_putDebugChar(unsigned char c) #ifdef CONFIG_DEBUG_BUILD unsigned char kernel_getDebugChar(void) { + +#if defined(CONFIG_RISCV_SBI_NONE) +#error Implment a UART driver for RISC-V if no SBI console exists +#endif + /* Don't use UART, but read from the SBI console. */ return sbi_console_getchar(); } diff --git a/src/arch/riscv/model/statedata.c b/src/arch/riscv/model/statedata.c index e0cc5a73368..78bc939f967 100644 --- a/src/arch/riscv/model/statedata.c +++ b/src/arch/riscv/model/statedata.c @@ -18,13 +18,13 @@ asid_pool_t *riscvKSASIDTable[BIT(asidHighBits)]; /* Kernel Page Tables */ -pte_t kernel_root_pageTable[BIT(PT_INDEX_BITS)] ALIGN_BSS(BIT(seL4_PageTableBits)); +pte_t kernel_root_pageTable[BIT(seL4_PageTableIndexBits)] ALIGN_BSS(BIT(seL4_PageTableBits)); #if __riscv_xlen != 32 -pte_t kernel_image_level2_pt[BIT(PT_INDEX_BITS)] ALIGN_BSS(BIT(seL4_PageTableBits)); -pte_t kernel_image_level2_dev_pt[BIT(PT_INDEX_BITS)] ALIGN_BSS(BIT(seL4_PageTableBits)); +pte_t kernel_image_level2_pt[BIT(seL4_PageTableIndexBits)] ALIGN_BSS(BIT(seL4_PageTableBits)); +pte_t kernel_image_level2_dev_pt[BIT(seL4_PageTableIndexBits)] ALIGN_BSS(BIT(seL4_PageTableBits)); #elif defined(CONFIG_KERNEL_LOG_BUFFER) -pte_t kernel_image_level2_log_buffer_pt[BIT(PT_INDEX_BITS)] ALIGN_BSS(BIT(seL4_PageTableBits)); +pte_t kernel_image_level2_log_buffer_pt[BIT(seL4_PageTableIndexBits)] ALIGN_BSS(BIT(seL4_PageTableBits)); #endif SMP_STATE_DEFINE(core_map_t, coreMap); diff --git a/src/arch/riscv/smp/ipi.c b/src/arch/riscv/smp/ipi.c index bb004388de0..742f23abbfc 100644 --- a/src/arch/riscv/smp/ipi.c +++ b/src/arch/riscv/smp/ipi.c @@ -5,12 +5,13 @@ */ #include + +#ifdef ENABLE_SMP_SUPPORT + #include #include #include -#ifdef ENABLE_SMP_SUPPORT - /* the remote call being requested */ static volatile IpiRemoteCall_t remoteCall; static volatile irq_t ipiIrq[CONFIG_MAX_NUM_NODES]; @@ -71,7 +72,6 @@ irq_t ipi_get_irq(void) void ipi_clear_irq(irq_t irq) { ipiIrq[getCurrentCPUIndex()] = irqInvalid; - return; } /* this function is called with a single hart id. */ @@ -89,4 +89,4 @@ void ipi_send_target(irq_t irq, word_t hart_id) sbi_send_ipi(hart_mask); } -#endif +#endif /* ENABLE_SMP_SUPPORT */ diff --git a/src/arch/x86/config.cmake b/src/arch/x86/config.cmake index 2c170bd0911..4204f8cec8b 100644 --- a/src/arch/x86/config.cmake +++ b/src/arch/x86/config.cmake @@ -72,8 +72,8 @@ config_option( config_string( KernelCacheLnSz CACHE_LN_SZ "Define cache line size for the current architecture" DEFAULT 64 - DEPENDS "KernelArchX86" UNDEF_DISABLED - UNQUOTE + DEPENDS "KernelArchX86" + UNDEF_DISABLED UNQUOTE ) config_option( @@ -181,7 +181,8 @@ config_string( 2 - AVX \ FPU and SSE is guaranteed to exist if XSAVE exists." DEFAULT 3 - DEPENDS "KernelFPUXSave" DEFAULT_DISABLED 0 + DEPENDS "KernelFPUXSave" + DEFAULT_DISABLED 0 UNQUOTE ) @@ -197,7 +198,8 @@ config_string( XSAVE_FEATURE_SET that have been requested. Default is 576 for the FPU and SSE state, unless XSAVE is not in use then it should be 512 for the legacy FXSAVE region." DEFAULT ${default_xsave_size} - DEPENDS "KernelArchX86" DEFAULT_DISABLED 0 + DEPENDS "KernelArchX86" + DEFAULT_DISABLED 0 UNQUOTE ) @@ -229,8 +231,8 @@ config_string( "The bits per pixel of the linear graphics mode ot request. Value of zero indicates \ no preference." DEFAULT 32 - DEPENDS "KernelMultibootGFXModeLinear" UNDEF_DISABLED - UNQUOTE + DEPENDS "KernelMultibootGFXModeLinear" + UNDEF_DISABLED UNQUOTE ) config_string( @@ -239,8 +241,8 @@ config_string( number of pixels. For a text mode this is the number of characters, value of zero \ indicates no preference." DEFAULT 0 - DEPENDS "KernelMultibootGFXModeText OR KernelMultibootGFXModeLinear" UNDEF_DISABLED - UNQUOTE + DEPENDS "KernelMultibootGFXModeText OR KernelMultibootGFXModeLinear" + UNDEF_DISABLED UNQUOTE ) config_string( KernelMultibootGFXHeight MULTIBOOT_GRAPHICS_MODE_HEIGHT @@ -248,8 +250,8 @@ config_string( number of pixels. For a text mode this is the number of characters, value of zero \ indicates no preference." DEFAULT 0 - DEPENDS "KernelMultibootGFXModeText OR KernelMultibootGFXModeLinear" UNDEF_DISABLED - UNQUOTE + DEPENDS "KernelMultibootGFXModeText OR KernelMultibootGFXModeLinear" + UNDEF_DISABLED UNQUOTE ) config_option(