[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Minios-devel] [UNIKRAFT PATCH 3/5] plat/kvm: Introduce platform configuration struct
Instead of having individual platform-global variables that hold configuration found during setup (e.g., _libkvmplat_heap_start, _libkvmplat_stack_top, _libkvmplat_mem_end), we introduce a configuration struct. We do this for readability reasons. Signed-off-by: Simon Kuenzer <simon.kuenzer@xxxxxxxxx> --- plat/common/arm/pl011.c | 15 ++++---- plat/common/arm/time.c | 13 ++++--- plat/kvm/arm/setup.c | 67 ++++++++++++++++++++++------------- plat/kvm/include/kvm/config.h | 63 ++++++++++++++++++++++++++++++++ plat/kvm/memory.c | 18 +++------- plat/kvm/x86/setup.c | 39 ++++++++++++-------- 6 files changed, 153 insertions(+), 62 deletions(-) create mode 100644 plat/kvm/include/kvm/config.h diff --git a/plat/common/arm/pl011.c b/plat/common/arm/pl011.c index 206c0bf4..0b0d672b 100644 --- a/plat/common/arm/pl011.c +++ b/plat/common/arm/pl011.c @@ -23,6 +23,11 @@ #include <uk/assert.h> #include <arm/cpu.h> +/* TODO: For now this file is KVM dependent. As soon as we have more + * Arm platforms that are using this file, we need to introduce a + * portable way to handover the DTB entry point to common platform code */ +#include <kvm/config.h> + /* PL011 UART registers and masks*/ /* Data register */ #define REG_UARTDR_OFFSET 0x00 @@ -83,8 +88,6 @@ static uint64_t pl011_uart_bas = 0; #define PL011_REG_READ(r) ioreg_read16(PL011_REG(r)) #define PL011_REG_WRITE(r, v) ioreg_write16(PL011_REG(r), v) -extern void *_libkvmplat_dtb; - static void init_pl011(uint64_t bas) { pl011_uart_bas = bas; @@ -115,20 +118,20 @@ void _libkvmplat_init_console(void) uk_pr_info("Serial initializing\n"); - offset = fdt_node_offset_by_compatible(_libkvmplat_dtb, \ + offset = fdt_node_offset_by_compatible(_libkvmplat_cfg.dtb, \ -1, "arm,pl011"); if (offset < 0) UK_CRASH("No console UART found!\n"); - naddr = fdt_address_cells(_libkvmplat_dtb, offset); + naddr = fdt_address_cells(_libkvmplat_cfg.dtb, offset); if (naddr < 0 || naddr >= FDT_MAX_NCELLS) UK_CRASH("Could not find proper address cells!\n"); - nsize = fdt_size_cells(_libkvmplat_dtb, offset); + nsize = fdt_size_cells(_libkvmplat_cfg.dtb, offset); if (nsize < 0 || nsize >= FDT_MAX_NCELLS) UK_CRASH("Could not find proper size cells!\n"); - regs = fdt_getprop(_libkvmplat_dtb, offset, "reg", &len); + regs = fdt_getprop(_libkvmplat_cfg.dtb, offset, "reg", &len); if (regs == NULL || (len < (int)sizeof(fdt32_t) * (naddr + nsize))) UK_CRASH("Bad 'reg' property: %p %d\n", regs, len); diff --git a/plat/common/arm/time.c b/plat/common/arm/time.c index 57a62354..1b30903b 100644 --- a/plat/common/arm/time.c +++ b/plat/common/arm/time.c @@ -39,9 +39,13 @@ #include <uk/bitops.h> #include <cpu.h> +/* TODO: For now this file is KVM dependent. As soon as we have more + * Arm platforms that are using this file, we need to introduce a + * portable way to handover the DTB entry point to common platform code */ +#include <kvm/config.h> + static uint64_t boot_ticks; static uint32_t counter_freq; -extern void *_libkvmplat_dtb; /* * Shift factor for counter scaling multiplier; referred to as S in the @@ -73,17 +77,18 @@ static uint32_t get_counter_frequency(void) const uint64_t *fdt_freq; /* Try to find arm,armv8-timer first */ - fdt_archtimer = fdt_node_offset_by_compatible(_libkvmplat_dtb, + fdt_archtimer = fdt_node_offset_by_compatible(_libkvmplat_cfg.dtb, -1, "arm,armv8-timer"); /* If failed, try to find arm,armv7-timer */ if (fdt_archtimer < 0) - fdt_archtimer = fdt_node_offset_by_compatible(_libkvmplat_dtb, + fdt_archtimer = fdt_node_offset_by_compatible( + _libkvmplat_cfg.dtb, -1, "arm,armv7-timer"); /* DT doesn't provide arch timer information */ if (fdt_archtimer < 0) goto endnofreq; - fdt_freq = fdt_getprop(_libkvmplat_dtb, + fdt_freq = fdt_getprop(_libkvmplat_cfg.dtb, fdt_archtimer, "clock-frequency", &len); if (!fdt_freq || (len <= 0)) { uk_pr_info("No clock-frequency found, reading from register directly.\n"); diff --git a/plat/kvm/arm/setup.c b/plat/kvm/arm/setup.c index 15a884a2..301b5a14 100644 --- a/plat/kvm/arm/setup.c +++ b/plat/kvm/arm/setup.c @@ -21,16 +21,13 @@ #include <libfdt.h> #include <sections.h> #include <kvm/console.h> +#include <kvm/config.h> #include <uk/assert.h> #include <kvm-arm/mm.h> #include <arm/cpu.h> #include <uk/arch/limits.h> -void *_libkvmplat_pagetable; -void *_libkvmplat_heap_start; -void *_libkvmplat_stack_top; -void *_libkvmplat_mem_end; -void *_libkvmplat_dtb; +struct kvmplat_config _libkvmplat_cfg = { 0 }; #define MAX_CMDLINE_SIZE 1024 static char cmdline[MAX_CMDLINE_SIZE]; @@ -47,7 +44,7 @@ static void _init_dtb(void *dtb_pointer) if ((ret = fdt_check_header(dtb_pointer))) UK_CRASH("Invalid DTB: %s\n", fdt_strerror(ret)); - _libkvmplat_dtb = dtb_pointer; + _libkvmplat_cfg.dtb = dtb_pointer; uk_pr_info("Found device tree on: %p\n", dtb_pointer); } @@ -60,17 +57,17 @@ static void _dtb_get_psci_method(void) * We just support PSCI-0.2 and PSCI-1.0, the PSCI-0.1 would not * be supported. */ - fdtpsci = fdt_node_offset_by_compatible(_libkvmplat_dtb, + fdtpsci = fdt_node_offset_by_compatible(_libkvmplat_cfg.dtb, -1, "arm,psci-1.0"); if (fdtpsci < 0) - fdtpsci = fdt_node_offset_by_compatible(_libkvmplat_dtb, + fdtpsci = fdt_node_offset_by_compatible(_libkvmplat_cfg.dtb, -1, "arm,psci-0.2"); if (fdtpsci < 0) { uk_pr_info("No PSCI conduit found in DTB\n"); goto enomethod; } - fdtmethod = fdt_getprop(_libkvmplat_dtb, fdtpsci, "method", &len); + fdtmethod = fdt_getprop(_libkvmplat_cfg.dtb, fdtpsci, "method", &len); if (!fdtmethod || (len <= 0)) { uk_pr_info("No PSCI method found\n"); goto enomethod; @@ -102,10 +99,10 @@ static void _init_dtb_mem(void) uint64_t mem_base, mem_size, max_addr; /* search for assigned VM memory in DTB */ - if (fdt_num_mem_rsv(_libkvmplat_dtb) != 0) + if (fdt_num_mem_rsv(_libkvmplat_cfg.dtb) != 0) uk_pr_warn("Reserved memory is not supported\n"); - fdt_mem = fdt_node_offset_by_prop_value(_libkvmplat_dtb, -1, + fdt_mem = fdt_node_offset_by_prop_value(_libkvmplat_cfg.dtb, -1, "device_type", "memory", sizeof("memory")); if (fdt_mem < 0) { @@ -113,11 +110,11 @@ static void _init_dtb_mem(void) return; } - naddr = fdt_address_cells(_libkvmplat_dtb, fdt_mem); + naddr = fdt_address_cells(_libkvmplat_cfg.dtb, fdt_mem); if (naddr < 0 || naddr >= FDT_MAX_NCELLS) UK_CRASH("Could not find proper address cells!\n"); - nsize = fdt_size_cells(_libkvmplat_dtb, fdt_mem); + nsize = fdt_size_cells(_libkvmplat_cfg.dtb, fdt_mem); if (nsize < 0 || nsize >= FDT_MAX_NCELLS) UK_CRASH("Could not find proper size cells!\n"); @@ -125,7 +122,7 @@ static void _init_dtb_mem(void) * QEMU will always provide us at least one bank of memory. * unikraft will use the first bank for the time-being. */ - regs = fdt_getprop(_libkvmplat_dtb, fdt_mem, "reg", &prop_len); + regs = fdt_getprop(_libkvmplat_cfg.dtb, fdt_mem, "reg", &prop_len); /* * The property must contain at least the start address @@ -145,12 +142,28 @@ static void _init_dtb_mem(void) UK_CRASH("Fatal: Image outside of RAM\n"); max_addr = mem_base + mem_size; - _libkvmplat_pagetable = (void *) ALIGN_DOWN((size_t)__END, __PAGE_SIZE); - _libkvmplat_heap_start = _libkvmplat_pagetable + page_table_size; - _libkvmplat_mem_end = (void *) max_addr; + _libkvmplat_cfg.pagetable.start = ALIGN_DOWN((uintptr_t)__END, + __PAGE_SIZE); + _libkvmplat_cfg.pagetable.len = ALIGN_UP(page_table_size, + __PAGE_SIZE); + _libkvmplat_cfg.pagetable.end = _libkvmplat_cfg.pagetable.start + + _libkvmplat_cfg.pagetable.len; /* AArch64 require stack be 16-bytes alignment by default */ - _libkvmplat_stack_top = (void *) ALIGN_UP(max_addr, __STACK_ALIGN_SIZE); + _libkvmplat_cfg.bstack.end = ALIGN_DOWN(max_addr, + __STACK_ALIGN_SIZE); + _libkvmplat_cfg.bstack.len = ALIGN_UP(__STACK_SIZE, + __STACK_ALIGN_SIZE); + _libkvmplat_cfg.bstack.start = _libkvmplat_cfg.bstack.end + - _libkvmplat_cfg.bstack.len; + + _libkvmplat_cfg.heap.start = _libkvmplat_cfg.pagetable.end; + _libkvmplat_cfg.heap.end = _libkvmplat_cfg.bstack.start; + _libkvmplat_cfg.heap.len = _libkvmplat_cfg.heap.end + - _libkvmplat_cfg.heap.start; + + if (_libkvmplat_cfg.heap.start > _libkvmplat_cfg.heap.end) + UK_CRASH("Not enough memory, giving up...\n"); } static void _dtb_get_cmdline(char *cmdline, size_t maxlen) @@ -159,10 +172,11 @@ static void _dtb_get_cmdline(char *cmdline, size_t maxlen) const char *fdtcmdline; /* TODO: Proper error handling */ - fdtchosen = fdt_path_offset(_libkvmplat_dtb, "/chosen"); + fdtchosen = fdt_path_offset(_libkvmplat_cfg.dtb, "/chosen"); if (!fdtchosen) goto enocmdl; - fdtcmdline = fdt_getprop(_libkvmplat_dtb, fdtchosen, "bootargs", &len); + fdtcmdline = fdt_getprop(_libkvmplat_cfg.dtb, fdtchosen, "bootargs", + &len); if (!fdtcmdline || (len <= 0)) goto enocmdl; @@ -200,16 +214,19 @@ void _libkvmplat_start(void *dtb_pointer) /* Initialize memory from DTB */ _init_dtb_mem(); - uk_pr_info("pagetable start: %p\n", _libkvmplat_pagetable); - uk_pr_info(" heap start: %p\n", _libkvmplat_heap_start); - uk_pr_info(" stack top: %p\n", _libkvmplat_stack_top); + uk_pr_info("pagetable start: %p\n", + (void *) _libkvmplat_cfg.pagetable.start); + uk_pr_info(" heap start: %p\n", + (void *) _libkvmplat_cfg.heap.start); + uk_pr_info(" stack top: %p\n", + (void *) _libkvmplat_cfg.bstack.start); /* * Switch away from the bootstrap stack as early as possible. */ uk_pr_info("Switch from bootstrap stack to stack @%p\n", - _libkvmplat_stack_top); + (void *) _libkvmplat_cfg.bstack.end); - _libkvmplat_newstack((uint64_t) _libkvmplat_stack_top, + _libkvmplat_newstack((uint64_t) _libkvmplat_cfg.bstack.end, _libkvmplat_entry2, NULL); } diff --git a/plat/kvm/include/kvm/config.h b/plat/kvm/include/kvm/config.h new file mode 100644 index 00000000..ee82731b --- /dev/null +++ b/plat/kvm/include/kvm/config.h @@ -0,0 +1,63 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Authors: Simon Kuenzer <simon.kuenzer@xxxxxxxxx> + * Wei Chen <Wei.Chen@xxxxxxx> + * + * Copyright (c) 2019, NEC Laboratories Europe GmbH, NEC Corporation, + * All rights reserved. + * Copyright (c) 2018, Arm Ltd., All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY. + */ + +#ifndef __KVM_CONFIG_H__ +#define __KVM_CONFIG_H__ + +#include <inttypes.h> +#include <sys/types.h> + +struct kvmplat_config_memregion { + uintptr_t start; + uintptr_t end; + size_t len; +}; + +struct kvmplat_config { + struct kvmplat_config_memregion heap; + struct kvmplat_config_memregion bstack; + +#ifdef CONFIG_ARCH_ARM_64 + struct kvmplat_config_memregion pagetable; + void *dtb; +#endif +}; + +/* Initialized and defined in setup.c */ +extern struct kvmplat_config _libkvmplat_cfg; + +#endif /* __KVM_CONFIG_H__ */ diff --git a/plat/kvm/memory.c b/plat/kvm/memory.c index e45b88c5..d8293293 100644 --- a/plat/kvm/memory.c +++ b/plat/kvm/memory.c @@ -23,13 +23,7 @@ #include <sys/types.h> #include <uk/plat/memory.h> #include <uk/assert.h> - -/* - * Provided by setup.c - */ -extern void *_libkvmplat_heap_start; -extern void *_libkvmplat_stack_top; -extern void *_libkvmplat_mem_end; +#include <kvm/config.h> int ukplat_memregion_count(void) { @@ -118,9 +112,8 @@ int ukplat_memregion_get(int i, struct ukplat_memregion_desc *m) ret = 0; break; case 7: /* heap */ - m->base = _libkvmplat_heap_start; - m->len = (size_t) _libkvmplat_stack_top - - (size_t) _libkvmplat_heap_start; + m->base = (void *) _libkvmplat_cfg.heap.start; + m->len = _libkvmplat_cfg.heap.len; m->flags = UKPLAT_MEMRF_ALLOCATABLE; #if CONFIG_UKPLAT_MEMRNAME m->name = "heap"; @@ -128,9 +121,8 @@ int ukplat_memregion_get(int i, struct ukplat_memregion_desc *m) ret = 0; break; case 8: /* stack */ - m->base = _libkvmplat_stack_top; - m->len = (size_t) _libkvmplat_mem_end - - (size_t) _libkvmplat_stack_top; + m->base = (void *) _libkvmplat_cfg.bstack.start; + m->len = _libkvmplat_cfg.bstack.len; m->flags = (UKPLAT_MEMRF_RESERVED | UKPLAT_MEMRF_READABLE | UKPLAT_MEMRF_WRITABLE); diff --git a/plat/kvm/x86/setup.c b/plat/kvm/x86/setup.c index df25592f..c3959c40 100644 --- a/plat/kvm/x86/setup.c +++ b/plat/kvm/x86/setup.c @@ -30,6 +30,7 @@ #include <sections.h> #include <x86/cpu.h> #include <x86/traps.h> +#include <kvm/config.h> #include <kvm/console.h> #include <kvm/intctrl.h> #include <kvm-x86/multiboot.h> @@ -46,12 +47,10 @@ #define MAX_CMDLINE_SIZE 8192 static char cmdline[MAX_CMDLINE_SIZE]; -void *_libkvmplat_heap_start; -void *_libkvmplat_stack_top; -void *_libkvmplat_mem_end; +struct kvmplat_config _libkvmplat_cfg = { 0 }; -extern void _libkvmplat_newstack(__u64 stack_start, void (*tramp)(void *), - void *arg); +extern void _libkvmplat_newstack(uintptr_t stack_start, void (*tramp)(void *), + void *arg); static inline void _mb_get_cmdline(struct multiboot_info *mi) { @@ -99,11 +98,21 @@ static inline void _mb_init_mem(struct multiboot_info *mi) max_addr = m->addr + m->len; if (max_addr > PLATFORM_MAX_MEM_ADDR) max_addr = PLATFORM_MAX_MEM_ADDR; - UK_ASSERT((size_t)__END <= max_addr); + UK_ASSERT((size_t) __END <= max_addr); - _libkvmplat_heap_start = (void *) ALIGN_UP((size_t)__END, __PAGE_SIZE); - _libkvmplat_mem_end = (void *) max_addr; - _libkvmplat_stack_top = (void *) (max_addr - __STACK_SIZE); + /* + * Reserve space for boot stack at the end of found memory + */ + if ((max_addr - m->addr) < __STACK_SIZE) + UK_CRASH("Not enough memory to allocate boot stack\n"); + + _libkvmplat_cfg.heap.start = ALIGN_UP((uintptr_t) __END, __PAGE_SIZE); + _libkvmplat_cfg.heap.end = (uintptr_t) max_addr - __STACK_SIZE; + _libkvmplat_cfg.heap.len = _libkvmplat_cfg.heap.end + - _libkvmplat_cfg.heap.start; + _libkvmplat_cfg.bstack.start = _libkvmplat_cfg.heap.end; + _libkvmplat_cfg.bstack.end = max_addr; + _libkvmplat_cfg.bstack.len = __STACK_SIZE; } static void _libkvmplat_entry2(void *arg __attribute__((unused))) @@ -130,14 +139,16 @@ void _libkvmplat_entry(void *arg) _mb_get_cmdline(mi); _mb_init_mem(mi); - uk_pr_info(" heap start: %p\n", _libkvmplat_heap_start); - uk_pr_info(" stack top: %p\n", _libkvmplat_stack_top); + uk_pr_info(" heap start: %p\n", + (void *) _libkvmplat_cfg.heap.start); + uk_pr_info(" stack top: %p\n", + (void *) _libkvmplat_cfg.bstack.start); /* * Switch away from the bootstrap stack as early as possible. */ uk_pr_info("Switch from bootstrap stack to stack @%p\n", - _libkvmplat_mem_end); - _libkvmplat_newstack((__u64) _libkvmplat_mem_end, - _libkvmplat_entry2, 0); + (void *) _libkvmplat_cfg.bstack.end); + _libkvmplat_newstack(_libkvmplat_cfg.bstack.end, + _libkvmplat_entry2, 0); } -- 2.21.0 _______________________________________________ Minios-devel mailing list Minios-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/minios-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |