diff --git a/examples/nuc14mnk-x86_64/zone1_linux.json b/examples/nuc14mnk-x86_64/zone1_linux.json index 67ecb66..6f9882e 100644 --- a/examples/nuc14mnk-x86_64/zone1_linux.json +++ b/examples/nuc14mnk-x86_64/zone1_linux.json @@ -79,7 +79,7 @@ "acpi_memory_region_id": "0x3", "screen_base": "0x70000000" }, - "pci_config": { + "pci_config": [{ "ecam_base": "0xc0000000", "ecam_size": "0x300000", "io_base": "0x0", @@ -90,10 +90,19 @@ "pci_mem32_base": "0x0", "mem64_base": "0x0", "mem64_size": "0x0", - "pci_mem64_base": "0x0" - }, + "pci_mem64_base": "0x0", + "bus_range_begin": "0x0", + "bus_range_end": "0x1f", + "domain": "0x0" + }], "num_pci_devs": 1, "alloc_pci_devs": [ - 0 + { + "domain": "0x0", + "bus": "0x0", + "device": "0x0", + "function": "0x0", + "dev_type": "0x0" + } ] } \ No newline at end of file diff --git a/examples/nxp-aarch64/zone1-ruxos.json b/examples/nxp-aarch64/zone1-ruxos.json index b882694..f7b32bf 100644 --- a/examples/nxp-aarch64/zone1-ruxos.json +++ b/examples/nxp-aarch64/zone1-ruxos.json @@ -74,5 +74,5 @@ }, "num_pci_devs": 0, "alloc_pci_devs": [], - "pci_config": {} + "pci_config": [{}] } diff --git a/examples/qemu-aarch64/with_virtio_blk_console/qemu_aarch64.rs b/examples/qemu-aarch64/with_virtio_blk_console/qemu_aarch64.rs index b2af1da..0efc082 100644 --- a/examples/qemu-aarch64/with_virtio_blk_console/qemu_aarch64.rs +++ b/examples/qemu-aarch64/with_virtio_blk_console/qemu_aarch64.rs @@ -48,7 +48,7 @@ pub const ROOT_ARCH_ZONE_CONFIG: HvArchZoneConfig = HvArchZoneConfig { gits_size: 0x20000, }; -pub const ROOT_PCI_CONFIG: HvPciConfig = HvPciConfig { +pub const ROOT_PCI_CONFIG: [HvPciConfig; 1] = [HvPciConfig { ecam_base: 0x4010000000, ecam_size: 0x10000000, io_base: 0x3eff0000, @@ -60,8 +60,26 @@ pub const ROOT_PCI_CONFIG: HvPciConfig = HvPciConfig { mem64_base: 0x8000000000, mem64_size: 0x8000000000, pci_mem64_base: 0x8000000000, -}; + bus_range_begin: 0, + bus_range_end: 0xff, + domain: 0x0, +}]; pub const ROOT_ZONE_IVC_CONFIG: [HvIvcConfig; 0] = []; -pub const ROOT_PCI_DEVS: [u64; 2] = [0, 1 << 3]; \ No newline at end of file +pub const ROOT_PCI_DEVS: [HvPciDevConfig; 2] = [ + HvPciDevConfig { + domain: 0x0, + bus: 0x0, + device: 0x0, + function: 0x0, + dev_type: 0, + }, + HvPciDevConfig { + domain: 0x0, + bus: 0x0, + device: 0x2, + function: 0x0, + dev_type: 0, + }, +]; \ No newline at end of file diff --git a/examples/qemu-aarch64/with_virtio_blk_console/zone1_linux_with_pci.json b/examples/qemu-aarch64/with_virtio_blk_console/zone1_linux_with_pci.json new file mode 100644 index 0000000..834d403 --- /dev/null +++ b/examples/qemu-aarch64/with_virtio_blk_console/zone1_linux_with_pci.json @@ -0,0 +1,69 @@ +{ + "name": "linux2", + "zone_id": 1, + "cpus": [2, 3], + "memory_regions": [ + { + "type": "ram", + "physical_start": "0x50000000", + "virtual_start": "0x50000000", + "size": "0x30000000" + }, + { + "type": "virtio", + "physical_start": "0xa000000", + "virtual_start": "0xa000000", + "size": "0x4000" + } + ], + "interrupts": [76, 78], + "ivc_configs": [], + "kernel_filepath": "./Image", + "dtb_filepath": "./linux2.dtb", + "kernel_load_paddr": "0x50400000", + "dtb_load_paddr": "0x50000000", + "entry_point": "0x50400000", + "arch_config": { + "gic_version": "v3", + "gicd_base": "0x8000000", + "gicd_size": "0x10000", + "gicr_base": "0x80a0000", + "gicr_size": "0xf60000", + "gits_base": "0x8080000", + "gits_size": "0x20000", + "is_aarch32": false + }, + "pci_config": [{ + "ecam_base": "0x4010000000", + "ecam_size": "0x10000000", + "io_base": "0x3eff0000", + "io_size": "0x10000", + "pci_io_base": "0x0", + "mem32_base": "0x10000000", + "mem32_size": "0x2eff0000", + "pci_mem32_base": "0x10000000", + "mem64_base": "0x8000000000", + "mem64_size": "0x8000000000", + "pci_mem64_base": "0x8000000000", + "bus_range_begin": "0x0", + "bus_range_end": "0x1f", + "domain": "0x0" + }], + "num_pci_devs": 2, + "alloc_pci_devs": [ + { + "domain": "0x0", + "bus": "0x0", + "device": "0x0", + "function": "0x0", + "dev_type": "0" + }, + { + "domain": "0x0", + "bus": "0x0", + "device": "0x11", + "function": "0x0", + "dev_type": "0" + } + ] +} \ No newline at end of file diff --git a/examples/qemu-aarch64/with_virtio_gpu/qemu_aarch64.rs b/examples/qemu-aarch64/with_virtio_gpu/qemu_aarch64.rs index 1ec1776..2029892 100644 --- a/examples/qemu-aarch64/with_virtio_gpu/qemu_aarch64.rs +++ b/examples/qemu-aarch64/with_virtio_gpu/qemu_aarch64.rs @@ -48,7 +48,7 @@ pub const ROOT_ARCH_ZONE_CONFIG: HvArchZoneConfig = HvArchZoneConfig { gits_size: 0x20000, }; -pub const ROOT_PCI_CONFIG: HvPciConfig = HvPciConfig { +pub const ROOT_PCI_CONFIG: [HvPciConfig; 1] = [HvPciConfig { ecam_base: 0x4010000000, ecam_size: 0x10000000, io_base: 0x3eff0000, @@ -60,8 +60,33 @@ pub const ROOT_PCI_CONFIG: HvPciConfig = HvPciConfig { mem64_base: 0x8000000000, mem64_size: 0x8000000000, pci_mem64_base: 0x8000000000, -}; + bus_range_begin: 0, + bus_range_end: 0xff, + domain: 0x0, +}]; pub const ROOT_ZONE_IVC_CONFIG: [HvIvcConfig; 0] = []; -pub const ROOT_PCI_DEVS: [u64; 3] = [0, 1 << 3, 6 << 3]; +pub const ROOT_PCI_DEVS: [HvPciDevConfig; 3] = [ + HvPciDevConfig { + domain: 0x0, + bus: 0x0, + device: 0x0, + function: 0x0, + dev_type: 0, + }, + HvPciDevConfig { + domain: 0x0, + bus: 0x0, + device: 0x1, + function: 0x0, + dev_type: 0, + }, + HvPciDevConfig { + domain: 0x0, + bus: 0x0, + device: 0x2, + function: 0x0, + dev_type: 0, + }, +]; diff --git a/examples/qemu-riscv64/linux2-aia.json b/examples/qemu-riscv64/linux2-aia.json index 8d75cd3..32642ec 100644 --- a/examples/qemu-riscv64/linux2-aia.json +++ b/examples/qemu-riscv64/linux2-aia.json @@ -36,7 +36,7 @@ "aplic_base": "0xd000000", "aplic_size": "0x8000" }, - "pci_config": { + "pci_config": [{ "ecam_base": "0x30000000", "ecam_size": "0x10000000", "io_base": "0x3000000", @@ -47,8 +47,33 @@ "pci_mem32_base": "0x40000000", "mem64_base": "0x400000000", "mem64_size": "0x400000000", - "pci_mem64_base": "0x400000000" - }, - "num_pci_devs": 2, - "alloc_pci_devs": [0, 16] + "pci_mem64_base": "0x400000000", + "bus_range_begin": "0x0", + "bus_range_end": "0x1f", + "domain": "0x0" + }], + "num_pci_devs": 3, + "alloc_pci_devs": [ + { + "domain": "0x0", + "bus": "0x0", + "device": "0x0", + "function": "0x0", + "dev_type": "0x0" + }, + { + "domain": "0x0", + "bus": "0x0", + "device": "0x2", + "function": "0x0", + "dev_type": "0x0" + }, + { + "domain": "0x0", + "bus": "0x0", + "device": "0x4", + "function": "0x0", + "dev_type": "0x0" + } + ] } diff --git a/examples/qemu-riscv64/linux2.json b/examples/qemu-riscv64/linux2.json index 5bc73bb..1bb365f 100644 --- a/examples/qemu-riscv64/linux2.json +++ b/examples/qemu-riscv64/linux2.json @@ -36,7 +36,7 @@ "aplic_base": "0xd000000", "aplic_size": "0x8000" }, - "pci_config": { + "pci_config": [{ "ecam_base": "0x30000000", "ecam_size": "0x10000000", "io_base": "0x3000000", @@ -47,8 +47,33 @@ "pci_mem32_base": "0x40000000", "mem64_base": "0x400000000", "mem64_size": "0x400000000", - "pci_mem64_base": "0x400000000" - }, - "num_pci_devs": 2, - "alloc_pci_devs": [0, 16] + "pci_mem64_base": "0x400000000", + "bus_range_begin": "0x0", + "bus_range_end": "0x1f", + "domain": "0x0" + }], + "num_pci_devs": 3, + "alloc_pci_devs": [ + { + "domain": "0x0", + "bus": "0x0", + "device": "0x0", + "function": "0x0", + "dev_type": "0x0" + }, + { + "domain": "0x0", + "bus": "0x0", + "device": "0x2", + "function": "0x0", + "dev_type": "0x0" + }, + { + "domain": "0x0", + "bus": "0x0", + "device": "0x4", + "function": "0x0", + "dev_type": "0x0" + } + ] } diff --git a/examples/qemu-x86_64/zone1_linux.json b/examples/qemu-x86_64/zone1_linux.json index 9a35cc9..f5799f4 100644 --- a/examples/qemu-x86_64/zone1_linux.json +++ b/examples/qemu-x86_64/zone1_linux.json @@ -79,7 +79,7 @@ "acpi_memory_region_id": "0x3", "screen_base": "0x70000000" }, - "pci_config": { + "pci_config": [{ "ecam_base": "0xe0000000", "ecam_size": "0x200000", "io_base": "0x0", @@ -90,11 +90,26 @@ "pci_mem32_base": "0x0", "mem64_base": "0x0", "mem64_size": "0x0", - "pci_mem64_base": "0x0" - }, + "pci_mem64_base": "0x0", + "bus_range_begin": "0x0", + "bus_range_end": "0x1f", + "domain": "0x0" + }], "num_pci_devs": 2, "alloc_pci_devs": [ - 0, - 264 + { + "domain": "0x0", + "bus": "0x0", + "device": "0x0", + "function": "0x0", + "dev_type": "0x0" + }, + { + "domain": "0x0", + "bus": "0x1", + "device": "0x1", + "function": "0x0", + "dev_type": "0x0" + } ] } \ No newline at end of file diff --git a/include/zone_config.h b/include/zone_config.h index cb0d99d..cd8838c 100644 --- a/include/zone_config.h +++ b/include/zone_config.h @@ -26,6 +26,7 @@ typedef __u32 BitmapWord; #define CONFIG_MAX_ZONES 32 #define CONFIG_NAME_MAXLEN 32 #define CONFIG_MAX_PCI_DEV 32 +#define CONFIG_PCI_BUS_MAXNUM 4 #define IVC_PROTOCOL_USER 0x0 #define IVC_PROTOCOL_HVISOR 0x01 @@ -39,6 +40,16 @@ struct memory_region { typedef struct memory_region memory_region_t; +struct hv_pci_dev_config { + __u8 domain; + __u8 bus; + __u8 device; + __u8 function; + __u32 dev_type; +}; + +typedef struct hv_pci_dev_config hv_pci_dev_config_t; + struct pci_config { __u64 ecam_base; __u64 ecam_size; @@ -51,6 +62,9 @@ struct pci_config { __u64 mem64_base; __u64 mem64_size; __u64 pci_mem64_base; + __u32 bus_range_begin; + __u32 bus_range_end; + __u8 domain; }; typedef struct pci_config pci_config_t; @@ -142,7 +156,7 @@ struct ivc_config { }; typedef struct ivc_config ivc_config_t; -#define CONFIG_MAGIC_VERSION 0x04 +#define CONFIG_MAGIC_VERSION 0x05 // Every time you change the struct, you should also change the // `CONFIG_MAGIC_VERSION` @@ -164,9 +178,10 @@ struct zone_config { char name[CONFIG_NAME_MAXLEN]; arch_zone_config_t arch_config; - pci_config_t pci_config; + __u64 num_pci_bus; + pci_config_t pci_config[CONFIG_PCI_BUS_MAXNUM]; __u64 num_pci_devs; - __u64 alloc_pci_devs[CONFIG_MAX_PCI_DEV]; + hv_pci_dev_config_t alloc_pci_devs[CONFIG_MAX_PCI_DEV]; }; typedef struct zone_config zone_config_t; diff --git a/tools/hvisor.c b/tools/hvisor.c index 7b9e4b3..d77938e 100644 --- a/tools/hvisor.c +++ b/tools/hvisor.c @@ -505,80 +505,133 @@ static int parse_arch_config(cJSON *root, zone_config_t *config) { } static int parse_pci_config(cJSON *root, zone_config_t *config) { - cJSON *pci_config_json = SAFE_CJSON_GET_OBJECT_ITEM(root, "pci_config"); - if (pci_config_json == NULL) { - log_warn("No pci_config field found."); - return -1; - } else { - printf("pci_config field found.\n"); - } + cJSON *pci_configs_json = SAFE_CJSON_GET_OBJECT_ITEM(root, "pci_config"); + CHECK_JSON_NULL_ERR_OUT(pci_configs_json, "pci_config") #if defined(ARM64) || defined(LOONGARCH64) || (defined X86_64) - cJSON *ecam_base_json = - SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "ecam_base"); - cJSON *io_base_json = - SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "io_base"); - cJSON *pci_io_base_json = - SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "pci_io_base"); - cJSON *mem32_base_json = - SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "mem32_base"); - cJSON *pci_mem32_base_json = - SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "pci_mem32_base"); - cJSON *mem64_base_json = - SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "mem64_base"); - cJSON *pci_mem64_base_json = - SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "pci_mem64_base"); - cJSON *ecam_size_json = - SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "ecam_size"); - cJSON *io_size_json = - SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "io_size"); - cJSON *mem32_size_json = - SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "mem32_size"); - cJSON *mem64_size_json = - SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "mem64_size"); - - CHECK_JSON_NULL(ecam_base_json, "ecam_base") - CHECK_JSON_NULL(io_base_json, "io_base") - CHECK_JSON_NULL(mem32_base_json, "mem32_base") - CHECK_JSON_NULL(mem64_base_json, "mem64_base") - CHECK_JSON_NULL(ecam_size_json, "ecam_size") - CHECK_JSON_NULL(io_size_json, "io_size") - CHECK_JSON_NULL(mem32_size_json, "mem32_size") - CHECK_JSON_NULL(mem64_size_json, "mem64_size") - CHECK_JSON_NULL(pci_io_base_json, "pci_io_base") - CHECK_JSON_NULL(pci_mem32_base_json, "pci_mem32_base") - CHECK_JSON_NULL(pci_mem64_base_json, "pci_mem64_base") - - config->pci_config.ecam_base = - strtoull(ecam_base_json->valuestring, NULL, 16); - config->pci_config.io_base = strtoull(io_base_json->valuestring, NULL, 16); - config->pci_config.mem32_base = - strtoull(mem32_base_json->valuestring, NULL, 16); - config->pci_config.mem64_base = - strtoull(mem64_base_json->valuestring, NULL, 16); - config->pci_config.pci_io_base = - strtoull(pci_io_base_json->valuestring, NULL, 16); - config->pci_config.pci_mem32_base = - strtoull(pci_mem32_base_json->valuestring, NULL, 16); - config->pci_config.pci_mem64_base = - strtoull(pci_mem64_base_json->valuestring, NULL, 16); - config->pci_config.ecam_size = - strtoull(ecam_size_json->valuestring, NULL, 16); - config->pci_config.io_size = strtoull(io_size_json->valuestring, NULL, 16); - config->pci_config.mem32_size = - strtoull(mem32_size_json->valuestring, NULL, 16); - config->pci_config.mem64_size = - strtoull(mem64_size_json->valuestring, NULL, 16); + int num_pci_bus = SAFE_CJSON_GET_ARRAY_SIZE(pci_configs_json); + if (num_pci_bus > CONFIG_PCI_BUS_MAXNUM) { + log_error("Exceeded maximum allowed pci configs."); + goto err_out; + } + + config->num_pci_bus = num_pci_bus; + log_info("num pci bus %d", num_pci_bus); + + for (int i = 0; i < num_pci_bus; i++) { + cJSON *pci_config_json = SAFE_CJSON_GET_ARRAY_ITEM(pci_configs_json, i); + pci_config_t *pci_config = &config->pci_config[i]; + + cJSON *ecam_base_json = + SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "ecam_base"); + CHECK_JSON_NULL_ERR_OUT(ecam_base_json, "ecam_base") + cJSON *ecam_size_json = + SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "ecam_size"); + CHECK_JSON_NULL_ERR_OUT(ecam_size_json, "ecam_size") + cJSON *io_base_json = + SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "io_base"); + CHECK_JSON_NULL_ERR_OUT(io_base_json, "io_base") + cJSON *io_size_json = + SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "io_size"); + CHECK_JSON_NULL_ERR_OUT(io_size_json, "io_size") + cJSON *pci_io_base_json = + SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "pci_io_base"); + CHECK_JSON_NULL_ERR_OUT(pci_io_base_json, "pci_io_base") + cJSON *mem32_base_json = + SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "mem32_base"); + CHECK_JSON_NULL_ERR_OUT(mem32_base_json, "mem32_base") + cJSON *mem32_size_json = + SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "mem32_size"); + CHECK_JSON_NULL_ERR_OUT(mem32_size_json, "mem32_size") + cJSON *pci_mem32_base_json = + SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "pci_mem32_base"); + CHECK_JSON_NULL_ERR_OUT(pci_mem32_base_json, "pci_mem32_base") + cJSON *mem64_base_json = + SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "mem64_base"); + CHECK_JSON_NULL_ERR_OUT(mem64_base_json, "mem64_base") + cJSON *mem64_size_json = + SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "mem64_size"); + CHECK_JSON_NULL_ERR_OUT(mem64_size_json, "mem64_size") + cJSON *pci_mem64_base_json = + SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "pci_mem64_base"); + CHECK_JSON_NULL_ERR_OUT(pci_mem64_base_json, "pci_mem64_base") + cJSON *bus_range_begin_json = + SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "bus_range_begin"); + CHECK_JSON_NULL_ERR_OUT(bus_range_begin_json, "bus_range_begin") + cJSON *bus_range_end_json = + SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "bus_range_end"); + CHECK_JSON_NULL_ERR_OUT(bus_range_end_json, "bus_range_end") + cJSON *domain_json = + SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "domain"); + CHECK_JSON_NULL_ERR_OUT(domain_json, "domain") + + pci_config->ecam_base = strtoull(ecam_base_json->valuestring, NULL, 16); + pci_config->ecam_size = strtoull(ecam_size_json->valuestring, NULL, 16); + pci_config->io_base = strtoull(io_base_json->valuestring, NULL, 16); + pci_config->io_size = strtoull(io_size_json->valuestring, NULL, 16); + pci_config->pci_io_base = + strtoull(pci_io_base_json->valuestring, NULL, 16); + pci_config->mem32_base = + strtoull(mem32_base_json->valuestring, NULL, 16); + pci_config->mem32_size = + strtoull(mem32_size_json->valuestring, NULL, 16); + pci_config->pci_mem32_base = + strtoull(pci_mem32_base_json->valuestring, NULL, 16); + pci_config->mem64_base = + strtoull(mem64_base_json->valuestring, NULL, 16); + pci_config->mem64_size = + strtoull(mem64_size_json->valuestring, NULL, 16); + pci_config->pci_mem64_base = + strtoull(pci_mem64_base_json->valuestring, NULL, 16); + pci_config->bus_range_begin = + strtoull(bus_range_begin_json->valuestring, NULL, 16); + pci_config->bus_range_end = + strtoull(bus_range_end_json->valuestring, NULL, 16); + pci_config->domain = strtoull(domain_json->valuestring, NULL, 16); + + // log_info("pci_config %d: ecam_base=0x%llx, ecam_size=0x%llx, " + // "io_base=0x%llx, io_size=0x%llx, " + // "pci_io_base=0x%llx, mem32_base=0x%llx, mem32_size=0x%llx, " + // "pci_mem32_base=0x%llx, mem64_base=0x%llx, + // mem64_size=0x%llx, " "pci_mem64_base=0x%llx", i, + // pci_config->ecam_base, pci_config->ecam_size, + // pci_config->io_base, pci_config->io_size, + // pci_config->pci_io_base, pci_config->mem32_base, + // pci_config->mem32_size, pci_config->pci_mem32_base, + // pci_config->mem64_base, pci_config->mem64_size, + // pci_config->pci_mem64_base); + } + cJSON *alloc_pci_devs_json = SAFE_CJSON_GET_OBJECT_ITEM(root, "alloc_pci_devs"); int num_pci_devs = SAFE_CJSON_GET_ARRAY_SIZE(alloc_pci_devs_json); config->num_pci_devs = num_pci_devs; for (int i = 0; i < num_pci_devs; i++) { - config->alloc_pci_devs[i] = - SAFE_CJSON_GET_ARRAY_ITEM(alloc_pci_devs_json, i)->valueint; + cJSON *dev_config_json = + SAFE_CJSON_GET_ARRAY_ITEM(alloc_pci_devs_json, i); + hv_pci_dev_config_t *dev_config = &config->alloc_pci_devs[i]; + dev_config->domain = strtoull( + SAFE_CJSON_GET_OBJECT_ITEM(dev_config_json, "domain")->valuestring, + NULL, 16); + dev_config->bus = strtoull( + SAFE_CJSON_GET_OBJECT_ITEM(dev_config_json, "bus")->valuestring, + NULL, 16); + dev_config->device = strtoull( + SAFE_CJSON_GET_OBJECT_ITEM(dev_config_json, "device")->valuestring, + NULL, 16); + dev_config->function = + strtoull(SAFE_CJSON_GET_OBJECT_ITEM(dev_config_json, "function") + ->valuestring, + NULL, 16); + dev_config->dev_type = + strtoull(SAFE_CJSON_GET_OBJECT_ITEM(dev_config_json, "dev_type") + ->valuestring, + NULL, 8); } #endif return 0; +err_out: + return -1; } static int zone_start_from_json(const char *json_config_path,