|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Minios-devel] [UNIKRAFT PATCH v2 6/8] 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.20.1
_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |