From 620ad5867cfaa2e475e8439e78c29a36b3927317 Mon Sep 17 00:00:00 2001 From: Michalis Pappas Date: Wed, 2 Aug 2023 08:46:25 +0200 Subject: [PATCH] lib/ukmmio: Refactor ukmmio Derive parametrs from libukparam. Rewrite parsing. Notice: This is an interim step before moving this into the virtio-mmio driver. Right now this is not possible as this driver is part of a larger libkvmvirtio library and thus cannot override the library prefix for libukparam to "virtio-mmio". Signed-off-by: Michalis Pappas --- lib/ukmmio/Makefile.uk | 2 +- lib/ukmmio/include/uk/mmio.h | 23 +----- lib/ukmmio/mmio.c | 141 +++++++++++++++-------------------- 3 files changed, 65 insertions(+), 101 deletions(-) diff --git a/lib/ukmmio/Makefile.uk b/lib/ukmmio/Makefile.uk index e07337abd..fc9ff14d3 100644 --- a/lib/ukmmio/Makefile.uk +++ b/lib/ukmmio/Makefile.uk @@ -1,7 +1,7 @@ $(eval $(call addlib_s,libukmmio,$(CONFIG_LIBUKMMIO))) # Register to uklibparam, sets "virtio_mmio" as parameter prefix (virtio_mmio.*) -# $(eval $(call addlib_paramprefix,libukmmio,virtio_mmio)) +$(eval $(call addlib_paramprefix,libukmmio,virtio_mmio)) CINCLUDES-y += -I$(LIBUKMMIO_BASE)/include diff --git a/lib/ukmmio/include/uk/mmio.h b/lib/ukmmio/include/uk/mmio.h index 47810ae96..2d9f3d427 100644 --- a/lib/ukmmio/include/uk/mmio.h +++ b/lib/ukmmio/include/uk/mmio.h @@ -9,18 +9,12 @@ extern "C" { #endif struct uk_mmio_device { - unsigned int id; - UK_TAILQ_ENTRY(struct uk_mmio_device) _list; - - __u64 size; __u64 base_addr; - unsigned long irq; - unsigned long dev_id; + __sz size; + __u32 irq; + __u32 id; }; -/* List of MMIO devices */ -UK_TAILQ_HEAD(uk_mmio_device_list, struct uk_mmio_device); - /** * Get number of mmio devices. * @@ -40,17 +34,6 @@ unsigned int uk_mmio_dev_count(void); */ struct uk_mmio_device * uk_mmio_dev_get(unsigned int id); -/** - * Add a Unikraft MMIO device - * - * @param device - * Cmdline argument represnting a virtio_mmio device. - * @return - * - 0: succesfully registered the device - * - != 0: error on registering the device - */ -int uk_mmio_add_dev(char *device); - #ifdef __cplusplus } #endif diff --git a/lib/ukmmio/mmio.c b/lib/ukmmio/mmio.c index 39c0ae31b..bbd9b731c 100644 --- a/lib/ukmmio/mmio.c +++ b/lib/ukmmio/mmio.c @@ -1,106 +1,87 @@ +#include #include #include #include #include #include -#define MAX_DEV_STR 255 -const char virtio_mmio_identifier[] = "virtio_mmio.device="; +#include +#include -struct uk_alloc *a; -struct uk_mmio_device_list uk_mmio_device_list = -UK_TAILQ_HEAD_INITIALIZER(uk_mmio_device_list); -int uk_mmio_device_count = 0; +#define VIRTIO_MMIO_DEV_MAX 32 /* arbitrary */ +static char *uk_libparam_devices[VIRTIO_MMIO_DEV_MAX] = {0}; -unsigned int uk_mmio_dev_count(void) -{ - return (unsigned int) uk_mmio_device_count; -} +UK_LIBPARAM_PARAM_ARR_ALIAS(device, uk_libparam_devices, charp, + VIRTIO_MMIO_DEV_MAX, "virtio-mmio devices"); -struct uk_mmio_device * uk_mmio_dev_get(unsigned int id) +/* Parse size string with suffix (eg "4K") into number */ +static char *parse_size(const char* size_str, size_t *sz) { - struct uk_mmio_device *dev; - - UK_TAILQ_FOREACH(dev, &uk_mmio_device_list, _list) { - if (dev->id == id) - return dev; + char *endptr; + + *sz = strtoull(size_str, &endptr, 0); + + switch(*endptr) { + case 'k': + case 'K': + *sz *= 1024; + ++endptr; + break; + case 'm': + case 'M': + *sz *= 1024 * 1024; + ++endptr; + break; + case 'g': + case 'G': + *sz *= 1024 * 1024 * 1024; + ++endptr; + break; + default: + break; } - return NULL; + return endptr; } -__u64 get_token_until(char *str, char c, int base, char **pEnd) +/* virtio_mmio.base = @:[:] */ +static struct uk_mmio_device *uk_mmio_parse_dev(char *str) { - __u64 multiplier = 1; - char *p; - - for (p = str; *p && *p != c; p++) { - if (*p == 'K') { - multiplier = 1024; - *p = ' '; - } - } - if (*p) { - *p = ' '; - } - - return strtol(str, pEnd, base) * multiplier; -} - -int uk_mmio_add_dev(char *device) -{ - __u64 size, base_addr; - unsigned long irq, plat_dev_id = 0; - char devStr[MAX_DEV_STR]; - char *pEnd; struct uk_mmio_device *dev; + int chunks = 0; - if (!(a = uk_alloc_get_default())) { - uk_pr_err("No allocator\n"); - return -1; - } + dev = uk_calloc(uk_alloc_get_default(), 1, sizeof(*dev)); + if (unlikely(!dev)) + return NULL; - if (strncmp(device, virtio_mmio_identifier, sizeof(virtio_mmio_identifier) - 1)) { - uk_pr_err("Invalid mmio device cmdline argument\n"); - return -1; - } + str = parse_size(str, &dev->size); + if (unlikely(!dev->size)) + return NULL; - strcpy(devStr, device + sizeof(virtio_mmio_identifier) - 1); - - size = get_token_until(devStr, '@', 0, &pEnd); - if (!size) { - uk_pr_err("Couldn't parse mmio device size\n"); - return -1; - } + chunks = sscanf(str, "@%" PRIx64 ":%" PRIx32 ":%" PRIx32, + &dev->base_addr, &dev->irq, &dev->id); - base_addr = get_token_until(pEnd, ':', 0, &pEnd); - if (!base_addr) { - uk_pr_err("Couldn't parse mmio device base addr\n"); - return -1; - } + if (unlikely(chunks < 2)) + return NULL; - irq = get_token_until(pEnd, ':', 10, &pEnd); - if (!irq) { - uk_pr_err("Couldn't parse mmio device base irq\n"); - return -1; - } + return dev; +} - if (*pEnd) { - plat_dev_id = get_token_until(pEnd, 0, 10, NULL); - } +unsigned int uk_mmio_dev_count(void) +{ + unsigned int count = 0; - dev = uk_calloc(a, 1, sizeof(*dev)); - if (!dev) { - return -1; - } + while (((char **)uk_libparam_devices)[count++]) + count++; + + return count; +} - dev->id = uk_mmio_device_count++; - dev->base_addr = base_addr; - dev->size = size; - dev->irq = irq; - dev->dev_id = plat_dev_id; - UK_TAILQ_INSERT_TAIL(&uk_mmio_device_list, dev, _list); +struct uk_mmio_device *uk_mmio_dev_get(unsigned int id) +{ + if (id >= ARRAY_SIZE(uk_libparam_devices) || !uk_libparam_devices[id]) + return NULL; - uk_pr_info("New mmio device at %#lx of size %#lx and irq %lu\n", base_addr, size, irq); - return 0; + return uk_mmio_parse_dev(((char **)uk_libparam_devices)[id]); } + -- 2.39.5