]> xenbits.xensource.com Git - unikraft/unikraft.git/commitdiff
lib/ukmmio: Refactor ukmmio
authorMichalis Pappas <michalis@unikraft.io>
Wed, 2 Aug 2023 06:46:25 +0000 (08:46 +0200)
committerMichalis Pappas <michalis@unikraft.io>
Tue, 22 Aug 2023 09:04:44 +0000 (11:04 +0200)
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 <michalis@unikraft.io>
lib/ukmmio/Makefile.uk
lib/ukmmio/include/uk/mmio.h
lib/ukmmio/mmio.c

index e07337abd5e06b6ebd0820800c4893f1acf9a767..fc9ff14d363a56929e6b89620be2d75853753874 100644 (file)
@@ -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
 
index 47810ae963ffc4af09dba83cff0d7d3715a698ca..2d9f3d4275dbb94bf3d35eee93bc164b16b6db69 100644 (file)
@@ -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
index 39c0ae31bf19351b6c408659995fa04c6b0554ef..bbd9b731c37a90c975b21daf06b36c5c20bcd066 100644 (file)
+#include <inttypes.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <uk/alloc.h>
 #include <uk/mmio.h>
 
-#define MAX_DEV_STR 255
-const char virtio_mmio_identifier[] = "virtio_mmio.device=";
+#include <uk/libparam.h>
+#include <uk/essentials.h>
 
-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 = <size>@<base>:<irq>[:<id>] */
+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]);
 }
+