|
|
391fb8 |
From e91399538669c6480ace3eb0f63b1c99645924bc Mon Sep 17 00:00:00 2001
|
|
|
391fb8 |
From: Laszlo Ersek <lersek@redhat.com>
|
|
|
391fb8 |
Date: Mon, 22 Dec 2014 13:11:35 +0100
|
|
|
391fb8 |
Subject: [PATCH 04/15] fw_cfg: hard separation between the MMIO and I/O port
|
|
|
391fb8 |
mappings
|
|
|
391fb8 |
|
|
|
391fb8 |
We are going to introduce a wide data register for fw_cfg, but only for
|
|
|
391fb8 |
the MMIO mapped device. The wide data register will also require the
|
|
|
391fb8 |
tightening of endiannesses.
|
|
|
391fb8 |
|
|
|
391fb8 |
However we don't want to touch the I/O port mapped fw_cfg device at all.
|
|
|
391fb8 |
|
|
|
391fb8 |
Currently QEMU provides a single fw_cfg device type that can handle both
|
|
|
391fb8 |
I/O port and MMIO mapping. This flexibility is not actually exploited by
|
|
|
391fb8 |
any board in the tree, but it renders restricting the above changes to
|
|
|
391fb8 |
MMIO very hard.
|
|
|
391fb8 |
|
|
|
391fb8 |
Therefore, let's derive two classes from TYPE_FW_CFG: TYPE_FW_CFG_IO and
|
|
|
391fb8 |
TYPE_FW_CFG_MEM.
|
|
|
391fb8 |
|
|
|
391fb8 |
TYPE_FW_CFG_IO incorporates the base I/O port and the related combined
|
|
|
391fb8 |
MemoryRegion. (NB: all boards in the tree that use the I/O port mapped
|
|
|
391fb8 |
flavor opt for the combined mapping; that is, when the data port overlays
|
|
|
391fb8 |
the high address byte of the selector port. Therefore we can drop the
|
|
|
391fb8 |
capability to map those I/O ports separately.)
|
|
|
391fb8 |
|
|
|
391fb8 |
TYPE_FW_CFG_MEM incorporates the base addresses for the MMIO selector and
|
|
|
391fb8 |
data registers, and their respective MemoryRegions.
|
|
|
391fb8 |
|
|
|
391fb8 |
The "realize" and "props" class members are specific to each new derived
|
|
|
391fb8 |
class, and become unused for the base class. The base class retains the
|
|
|
391fb8 |
"reset" member and the "vmsd" member, because the reset functionality and
|
|
|
391fb8 |
the set of migrated data are not specific to the mapping.
|
|
|
391fb8 |
|
|
|
391fb8 |
The new functions fw_cfg_init_io() and fw_cfg_init_mem() expose the
|
|
|
391fb8 |
possible mappings in separation. For now fw_cfg_init() is retained as a
|
|
|
391fb8 |
compatibility shim that enforces the above assumptions.
|
|
|
391fb8 |
|
|
|
391fb8 |
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
|
|
|
391fb8 |
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
391fb8 |
Message-id: 1419250305-31062-2-git-send-email-pbonzini@redhat.com
|
|
|
391fb8 |
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
|
|
391fb8 |
(cherry picked from commit 5712db6ae5101db645f71edc393368cd59bfd314)
|
|
|
391fb8 |
---
|
|
|
391fb8 |
hw/nvram/fw_cfg.c | 181 +++++++++++++++++++++++++++++++---------------
|
|
|
391fb8 |
include/hw/nvram/fw_cfg.h | 2 +
|
|
|
391fb8 |
include/qemu/typedefs.h | 2 +
|
|
|
391fb8 |
3 files changed, 128 insertions(+), 57 deletions(-)
|
|
|
391fb8 |
|
|
|
391fb8 |
diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
|
|
|
391fb8 |
index c4b78ed..ab7bfff 100644
|
|
|
391fb8 |
--- a/hw/nvram/fw_cfg.c
|
|
|
391fb8 |
+++ b/hw/nvram/fw_cfg.c
|
|
|
391fb8 |
@@ -32,10 +32,16 @@
|
|
|
391fb8 |
|
|
|
391fb8 |
#define FW_CFG_SIZE 2
|
|
|
391fb8 |
#define FW_CFG_DATA_SIZE 1
|
|
|
391fb8 |
-#define TYPE_FW_CFG "fw_cfg"
|
|
|
391fb8 |
#define FW_CFG_NAME "fw_cfg"
|
|
|
391fb8 |
#define FW_CFG_PATH "/machine/" FW_CFG_NAME
|
|
|
391fb8 |
-#define FW_CFG(obj) OBJECT_CHECK(FWCfgState, (obj), TYPE_FW_CFG)
|
|
|
391fb8 |
+
|
|
|
391fb8 |
+#define TYPE_FW_CFG "fw_cfg"
|
|
|
391fb8 |
+#define TYPE_FW_CFG_IO "fw_cfg_io"
|
|
|
391fb8 |
+#define TYPE_FW_CFG_MEM "fw_cfg_mem"
|
|
|
391fb8 |
+
|
|
|
391fb8 |
+#define FW_CFG(obj) OBJECT_CHECK(FWCfgState, (obj), TYPE_FW_CFG)
|
|
|
391fb8 |
+#define FW_CFG_IO(obj) OBJECT_CHECK(FWCfgIoState, (obj), TYPE_FW_CFG_IO)
|
|
|
391fb8 |
+#define FW_CFG_MEM(obj) OBJECT_CHECK(FWCfgMemState, (obj), TYPE_FW_CFG_MEM)
|
|
|
391fb8 |
|
|
|
391fb8 |
typedef struct FWCfgEntry {
|
|
|
391fb8 |
uint32_t len;
|
|
|
391fb8 |
@@ -50,8 +56,6 @@ struct FWCfgState {
|
|
|
391fb8 |
SysBusDevice parent_obj;
|
|
|
391fb8 |
/*< public >*/
|
|
|
391fb8 |
|
|
|
391fb8 |
- MemoryRegion ctl_iomem, data_iomem, comb_iomem;
|
|
|
391fb8 |
- uint32_t ctl_iobase, data_iobase;
|
|
|
391fb8 |
FWCfgEntry entries[2][FW_CFG_MAX_ENTRY];
|
|
|
391fb8 |
FWCfgFiles *files;
|
|
|
391fb8 |
uint16_t cur_entry;
|
|
|
391fb8 |
@@ -59,6 +63,23 @@ struct FWCfgState {
|
|
|
391fb8 |
Notifier machine_ready;
|
|
|
391fb8 |
};
|
|
|
391fb8 |
|
|
|
391fb8 |
+struct FWCfgIoState {
|
|
|
391fb8 |
+ /*< private >*/
|
|
|
391fb8 |
+ FWCfgState parent_obj;
|
|
|
391fb8 |
+ /*< public >*/
|
|
|
391fb8 |
+
|
|
|
391fb8 |
+ MemoryRegion comb_iomem;
|
|
|
391fb8 |
+ uint32_t iobase;
|
|
|
391fb8 |
+};
|
|
|
391fb8 |
+
|
|
|
391fb8 |
+struct FWCfgMemState {
|
|
|
391fb8 |
+ /*< private >*/
|
|
|
391fb8 |
+ FWCfgState parent_obj;
|
|
|
391fb8 |
+ /*< public >*/
|
|
|
391fb8 |
+
|
|
|
391fb8 |
+ MemoryRegion ctl_iomem, data_iomem;
|
|
|
391fb8 |
+};
|
|
|
391fb8 |
+
|
|
|
391fb8 |
#define JPG_FILE 0
|
|
|
391fb8 |
#define BMP_FILE 1
|
|
|
391fb8 |
|
|
|
391fb8 |
@@ -560,19 +581,11 @@ static void fw_cfg_machine_ready(struct Notifier *n, void *data)
|
|
|
391fb8 |
qemu_register_reset(fw_cfg_machine_reset, s);
|
|
|
391fb8 |
}
|
|
|
391fb8 |
|
|
|
391fb8 |
-FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
|
|
|
391fb8 |
- hwaddr ctl_addr, hwaddr data_addr)
|
|
|
391fb8 |
+
|
|
|
391fb8 |
+
|
|
|
391fb8 |
+static void fw_cfg_init1(DeviceState *dev)
|
|
|
391fb8 |
{
|
|
|
391fb8 |
- DeviceState *dev;
|
|
|
391fb8 |
- SysBusDevice *d;
|
|
|
391fb8 |
- FWCfgState *s;
|
|
|
391fb8 |
-
|
|
|
391fb8 |
- dev = qdev_create(NULL, TYPE_FW_CFG);
|
|
|
391fb8 |
- qdev_prop_set_uint32(dev, "ctl_iobase", ctl_port);
|
|
|
391fb8 |
- qdev_prop_set_uint32(dev, "data_iobase", data_port);
|
|
|
391fb8 |
- d = SYS_BUS_DEVICE(dev);
|
|
|
391fb8 |
-
|
|
|
391fb8 |
- s = FW_CFG(dev);
|
|
|
391fb8 |
+ FWCfgState *s = FW_CFG(dev);
|
|
|
391fb8 |
|
|
|
391fb8 |
assert(!object_resolve_path(FW_CFG_PATH, NULL));
|
|
|
391fb8 |
|
|
|
391fb8 |
@@ -580,12 +593,6 @@ FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
|
|
|
391fb8 |
|
|
|
391fb8 |
qdev_init_nofail(dev);
|
|
|
391fb8 |
|
|
|
391fb8 |
- if (ctl_addr) {
|
|
|
391fb8 |
- sysbus_mmio_map(d, 0, ctl_addr);
|
|
|
391fb8 |
- }
|
|
|
391fb8 |
- if (data_addr) {
|
|
|
391fb8 |
- sysbus_mmio_map(d, 1, data_addr);
|
|
|
391fb8 |
- }
|
|
|
391fb8 |
fw_cfg_add_bytes(s, FW_CFG_SIGNATURE, (char *)"QEMU", 4);
|
|
|
391fb8 |
fw_cfg_add_bytes(s, FW_CFG_UUID, qemu_uuid, 16);
|
|
|
391fb8 |
fw_cfg_add_i16(s, FW_CFG_NOGRAPHIC, (uint16_t)(display_type == DT_NOGRAPHIC));
|
|
|
391fb8 |
@@ -596,48 +603,48 @@ FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
|
|
|
391fb8 |
|
|
|
391fb8 |
s->machine_ready.notify = fw_cfg_machine_ready;
|
|
|
391fb8 |
qemu_add_machine_init_done_notifier(&s->machine_ready);
|
|
|
391fb8 |
+}
|
|
|
391fb8 |
+
|
|
|
391fb8 |
+FWCfgState *fw_cfg_init_io(uint32_t iobase)
|
|
|
391fb8 |
+{
|
|
|
391fb8 |
+ DeviceState *dev;
|
|
|
391fb8 |
|
|
|
391fb8 |
- return s;
|
|
|
391fb8 |
+ dev = qdev_create(NULL, TYPE_FW_CFG_IO);
|
|
|
391fb8 |
+ qdev_prop_set_uint32(dev, "iobase", iobase);
|
|
|
391fb8 |
+ fw_cfg_init1(dev);
|
|
|
391fb8 |
+
|
|
|
391fb8 |
+ return FW_CFG(dev);
|
|
|
391fb8 |
}
|
|
|
391fb8 |
|
|
|
391fb8 |
-static void fw_cfg_initfn(Object *obj)
|
|
|
391fb8 |
+FWCfgState *fw_cfg_init_mem(hwaddr ctl_addr, hwaddr data_addr)
|
|
|
391fb8 |
{
|
|
|
391fb8 |
- SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
|
|
|
391fb8 |
- FWCfgState *s = FW_CFG(obj);
|
|
|
391fb8 |
-
|
|
|
391fb8 |
- memory_region_init_io(&s->ctl_iomem, OBJECT(s), &fw_cfg_ctl_mem_ops, s,
|
|
|
391fb8 |
- "fwcfg.ctl", FW_CFG_SIZE);
|
|
|
391fb8 |
- sysbus_init_mmio(sbd, &s->ctl_iomem);
|
|
|
391fb8 |
- memory_region_init_io(&s->data_iomem, OBJECT(s), &fw_cfg_data_mem_ops, s,
|
|
|
391fb8 |
- "fwcfg.data", FW_CFG_DATA_SIZE);
|
|
|
391fb8 |
- sysbus_init_mmio(sbd, &s->data_iomem);
|
|
|
391fb8 |
- /* In case ctl and data overlap: */
|
|
|
391fb8 |
- memory_region_init_io(&s->comb_iomem, OBJECT(s), &fw_cfg_comb_mem_ops, s,
|
|
|
391fb8 |
- "fwcfg", FW_CFG_SIZE);
|
|
|
391fb8 |
+ DeviceState *dev;
|
|
|
391fb8 |
+ SysBusDevice *sbd;
|
|
|
391fb8 |
+
|
|
|
391fb8 |
+ dev = qdev_create(NULL, TYPE_FW_CFG_MEM);
|
|
|
391fb8 |
+ fw_cfg_init1(dev);
|
|
|
391fb8 |
+
|
|
|
391fb8 |
+ sbd = SYS_BUS_DEVICE(dev);
|
|
|
391fb8 |
+ sysbus_mmio_map(sbd, 0, ctl_addr);
|
|
|
391fb8 |
+ sysbus_mmio_map(sbd, 1, data_addr);
|
|
|
391fb8 |
+
|
|
|
391fb8 |
+ return FW_CFG(dev);
|
|
|
391fb8 |
}
|
|
|
391fb8 |
|
|
|
391fb8 |
-static void fw_cfg_realize(DeviceState *dev, Error **errp)
|
|
|
391fb8 |
+
|
|
|
391fb8 |
+FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
|
|
|
391fb8 |
+ hwaddr crl_addr, hwaddr data_addr)
|
|
|
391fb8 |
{
|
|
|
391fb8 |
- FWCfgState *s = FW_CFG(dev);
|
|
|
391fb8 |
- SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
|
|
|
391fb8 |
-
|
|
|
391fb8 |
- if (s->ctl_iobase + 1 == s->data_iobase) {
|
|
|
391fb8 |
- sysbus_add_io(sbd, s->ctl_iobase, &s->comb_iomem);
|
|
|
391fb8 |
- } else {
|
|
|
391fb8 |
- if (s->ctl_iobase) {
|
|
|
391fb8 |
- sysbus_add_io(sbd, s->ctl_iobase, &s->ctl_iomem);
|
|
|
391fb8 |
- }
|
|
|
391fb8 |
- if (s->data_iobase) {
|
|
|
391fb8 |
- sysbus_add_io(sbd, s->data_iobase, &s->data_iomem);
|
|
|
391fb8 |
- }
|
|
|
391fb8 |
+ if (ctl_port + 1 == data_port && crl_addr == 0 && data_addr == 0) {
|
|
|
391fb8 |
+ return fw_cfg_init_io(ctl_port);
|
|
|
391fb8 |
+ }
|
|
|
391fb8 |
+ if (ctl_port == 0 && data_port == 0 && crl_addr != 0 && data_addr != 0) {
|
|
|
391fb8 |
+ return fw_cfg_init_mem(crl_addr, data_addr);
|
|
|
391fb8 |
}
|
|
|
391fb8 |
+ assert(false);
|
|
|
391fb8 |
+ return NULL;
|
|
|
391fb8 |
}
|
|
|
391fb8 |
|
|
|
391fb8 |
-static Property fw_cfg_properties[] = {
|
|
|
391fb8 |
- DEFINE_PROP_UINT32("ctl_iobase", FWCfgState, ctl_iobase, -1),
|
|
|
391fb8 |
- DEFINE_PROP_UINT32("data_iobase", FWCfgState, data_iobase, -1),
|
|
|
391fb8 |
- DEFINE_PROP_END_OF_LIST(),
|
|
|
391fb8 |
-};
|
|
|
391fb8 |
|
|
|
391fb8 |
FWCfgState *fw_cfg_find(void)
|
|
|
391fb8 |
{
|
|
|
391fb8 |
@@ -648,23 +655,83 @@ static void fw_cfg_class_init(ObjectClass *klass, void *data)
|
|
|
391fb8 |
{
|
|
|
391fb8 |
DeviceClass *dc = DEVICE_CLASS(klass);
|
|
|
391fb8 |
|
|
|
391fb8 |
- dc->realize = fw_cfg_realize;
|
|
|
391fb8 |
dc->reset = fw_cfg_reset;
|
|
|
391fb8 |
dc->vmsd = &vmstate_fw_cfg;
|
|
|
391fb8 |
- dc->props = fw_cfg_properties;
|
|
|
391fb8 |
}
|
|
|
391fb8 |
|
|
|
391fb8 |
static const TypeInfo fw_cfg_info = {
|
|
|
391fb8 |
.name = TYPE_FW_CFG,
|
|
|
391fb8 |
.parent = TYPE_SYS_BUS_DEVICE,
|
|
|
391fb8 |
.instance_size = sizeof(FWCfgState),
|
|
|
391fb8 |
- .instance_init = fw_cfg_initfn,
|
|
|
391fb8 |
.class_init = fw_cfg_class_init,
|
|
|
391fb8 |
};
|
|
|
391fb8 |
|
|
|
391fb8 |
+
|
|
|
391fb8 |
+static Property fw_cfg_io_properties[] = {
|
|
|
391fb8 |
+ DEFINE_PROP_UINT32("iobase", FWCfgIoState, iobase, -1),
|
|
|
391fb8 |
+ DEFINE_PROP_END_OF_LIST(),
|
|
|
391fb8 |
+};
|
|
|
391fb8 |
+
|
|
|
391fb8 |
+static void fw_cfg_io_realize(DeviceState *dev, Error **errp)
|
|
|
391fb8 |
+{
|
|
|
391fb8 |
+ FWCfgIoState *s = FW_CFG_IO(dev);
|
|
|
391fb8 |
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
|
|
|
391fb8 |
+
|
|
|
391fb8 |
+ memory_region_init_io(&s->comb_iomem, OBJECT(s), &fw_cfg_comb_mem_ops,
|
|
|
391fb8 |
+ FW_CFG(s), "fwcfg", FW_CFG_SIZE);
|
|
|
391fb8 |
+ sysbus_add_io(sbd, s->iobase, &s->comb_iomem);
|
|
|
391fb8 |
+}
|
|
|
391fb8 |
+
|
|
|
391fb8 |
+static void fw_cfg_io_class_init(ObjectClass *klass, void *data)
|
|
|
391fb8 |
+{
|
|
|
391fb8 |
+ DeviceClass *dc = DEVICE_CLASS(klass);
|
|
|
391fb8 |
+
|
|
|
391fb8 |
+ dc->realize = fw_cfg_io_realize;
|
|
|
391fb8 |
+ dc->props = fw_cfg_io_properties;
|
|
|
391fb8 |
+}
|
|
|
391fb8 |
+
|
|
|
391fb8 |
+static const TypeInfo fw_cfg_io_info = {
|
|
|
391fb8 |
+ .name = TYPE_FW_CFG_IO,
|
|
|
391fb8 |
+ .parent = TYPE_FW_CFG,
|
|
|
391fb8 |
+ .instance_size = sizeof(FWCfgIoState),
|
|
|
391fb8 |
+ .class_init = fw_cfg_io_class_init,
|
|
|
391fb8 |
+};
|
|
|
391fb8 |
+
|
|
|
391fb8 |
+
|
|
|
391fb8 |
+static void fw_cfg_mem_realize(DeviceState *dev, Error **errp)
|
|
|
391fb8 |
+{
|
|
|
391fb8 |
+ FWCfgMemState *s = FW_CFG_MEM(dev);
|
|
|
391fb8 |
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
|
|
|
391fb8 |
+
|
|
|
391fb8 |
+ memory_region_init_io(&s->ctl_iomem, OBJECT(s), &fw_cfg_ctl_mem_ops,
|
|
|
391fb8 |
+ FW_CFG(s), "fwcfg.ctl", FW_CFG_SIZE);
|
|
|
391fb8 |
+ sysbus_init_mmio(sbd, &s->ctl_iomem);
|
|
|
391fb8 |
+
|
|
|
391fb8 |
+ memory_region_init_io(&s->data_iomem, OBJECT(s), &fw_cfg_data_mem_ops,
|
|
|
391fb8 |
+ FW_CFG(s), "fwcfg.data", FW_CFG_DATA_SIZE);
|
|
|
391fb8 |
+ sysbus_init_mmio(sbd, &s->data_iomem);
|
|
|
391fb8 |
+}
|
|
|
391fb8 |
+
|
|
|
391fb8 |
+static void fw_cfg_mem_class_init(ObjectClass *klass, void *data)
|
|
|
391fb8 |
+{
|
|
|
391fb8 |
+ DeviceClass *dc = DEVICE_CLASS(klass);
|
|
|
391fb8 |
+
|
|
|
391fb8 |
+ dc->realize = fw_cfg_mem_realize;
|
|
|
391fb8 |
+}
|
|
|
391fb8 |
+
|
|
|
391fb8 |
+static const TypeInfo fw_cfg_mem_info = {
|
|
|
391fb8 |
+ .name = TYPE_FW_CFG_MEM,
|
|
|
391fb8 |
+ .parent = TYPE_FW_CFG,
|
|
|
391fb8 |
+ .instance_size = sizeof(FWCfgMemState),
|
|
|
391fb8 |
+ .class_init = fw_cfg_mem_class_init,
|
|
|
391fb8 |
+};
|
|
|
391fb8 |
+
|
|
|
391fb8 |
+
|
|
|
391fb8 |
static void fw_cfg_register_types(void)
|
|
|
391fb8 |
{
|
|
|
391fb8 |
type_register_static(&fw_cfg_info);
|
|
|
391fb8 |
+ type_register_static(&fw_cfg_io_info);
|
|
|
391fb8 |
+ type_register_static(&fw_cfg_mem_info);
|
|
|
391fb8 |
}
|
|
|
391fb8 |
|
|
|
391fb8 |
type_init(fw_cfg_register_types)
|
|
|
391fb8 |
diff --git a/include/hw/nvram/fw_cfg.h b/include/hw/nvram/fw_cfg.h
|
|
|
391fb8 |
index 56e1ed7..fcc88ea 100644
|
|
|
391fb8 |
--- a/include/hw/nvram/fw_cfg.h
|
|
|
391fb8 |
+++ b/include/hw/nvram/fw_cfg.h
|
|
|
391fb8 |
@@ -80,6 +80,8 @@ void *fw_cfg_modify_file(FWCfgState *s, const char *filename, void *data,
|
|
|
391fb8 |
size_t len);
|
|
|
391fb8 |
FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
|
|
|
391fb8 |
hwaddr crl_addr, hwaddr data_addr);
|
|
|
391fb8 |
+FWCfgState *fw_cfg_init_io(uint32_t iobase);
|
|
|
391fb8 |
+FWCfgState *fw_cfg_init_mem(hwaddr ctl_addr, hwaddr data_addr);
|
|
|
391fb8 |
|
|
|
391fb8 |
FWCfgState *fw_cfg_find(void);
|
|
|
391fb8 |
|
|
|
391fb8 |
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
|
|
|
391fb8 |
index 57ff47f..f2bbaaf 100644
|
|
|
391fb8 |
--- a/include/qemu/typedefs.h
|
|
|
391fb8 |
+++ b/include/qemu/typedefs.h
|
|
|
391fb8 |
@@ -22,6 +22,8 @@ typedef struct DisplayState DisplayState;
|
|
|
391fb8 |
typedef struct DisplaySurface DisplaySurface;
|
|
|
391fb8 |
typedef struct DriveInfo DriveInfo;
|
|
|
391fb8 |
typedef struct EventNotifier EventNotifier;
|
|
|
391fb8 |
+typedef struct FWCfgIoState FWCfgIoState;
|
|
|
391fb8 |
+typedef struct FWCfgMemState FWCfgMemState;
|
|
|
391fb8 |
typedef struct FWCfgState FWCfgState;
|
|
|
391fb8 |
typedef struct HCIInfo HCIInfo;
|
|
|
391fb8 |
typedef struct I2CBus I2CBus;
|
|
|
391fb8 |
--
|
|
|
391fb8 |
2.1.0
|
|
|
391fb8 |
|