Thank you for your reply, Mr. Madell.
>From the code you've shown us that looks like it ought to work,
Do you mean that you can change a QOM register value by the "set" command via GBD if there is no bug?
When I wrote the source code, I reffered dma/pl080.c.
I'm a beginner of qemu, so I lack knowledge to find where is the bug...
Could you help me?
I make a qom in the board code like this.
----------------------------------------------------------
dev = qdev_create(NULL, "test_hw");
object_property_set_link(OBJECT(dev), OBJECT(get_system_memory()), "downstream", &error_fatal);qdev_init_nofail(dev);sysbus_mmio_map_overlap(SYS_BUS_DEVICE(dev), 0, 0x40000000, 1);----------------------------------------------------------
The bottom source code is QOM named "test_hw".
----------------------------------------------------------
#include "qemu/osdep.h"#include "hw/sysbus.h"#include "migration/vmstate.h"#include "exec/address-spaces.h"#include "qemu/log.h"#include "qemu/module.h"#include "hw/dma/pl080.h"#include "hw/hw.h"#include "hw/irq.h"#include "hw/qdev-properties.h"#include "qapi/error.h"#include "hw/sysbus.h"#include "qapi/error.h"#include "qemu/error-report.h"typedef struct TestState { SysBusDevice parent_obj; MemoryRegion iomem; uint32_t src; uint32_t fix_value; MemoryRegion *downstream; AddressSpace downstream_as;} TestState;#define TYPE_TEST "test_hw"#define TEST(obj) OBJECT_CHECK(TestState, (obj), TYPE_TEST)// to allocate the orders and size of registers in address spacestatic const VMStateDescription vmstate_test_channel = { .name = "test", .version_id = 1, .minimum_version_id = 1, .fields = (VMStateField[]) { VMSTATE_UINT32(src, TestState), VMSTATE_UINT32(fix_value, TestState), VMSTATE_END_OF_LIST() }};static uint64_t test_read(void *opaque, hwaddr offset, unsigned size){ error_report("access test_read %d", (int)offset); TestState *s = (TestState *)opaque; switch ((int)offset) { case 0: return s->src; case 4: return s->fix_value; default: error_report("bad offset : %d", (int)offset); return 0; }}static void test_write(void *opaque, hwaddr offset, uint64_t value, unsigned size){ error_report("access test_write %d %d", (int)offset, (int)size); TestState *s = (TestState *)opaque; if(offset == 0){ s->src = "">
}else{
qemu_log_mask(LOG_GUEST_ERROR,"test_write: can't change %x\n", (int)offset);
}
}
static const MemoryRegionOps test_ops = {
.read = test_read,
.write = test_write,
.endianness = DEVICE_NATIVE_ENDIAN,
};
// register reset function
static void test_reset(DeviceState *dev)
{
TestState *s = TEST(dev);
s->src = "">
s->fix_value = 999;
}
static void test_init(Object *obj)
{
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
TestState *s = TEST(obj);
memory_region_init_io(&s->iomem, OBJECT(s), &test_ops, s, "test_hw", 0x1000);
sysbus_init_mmio(sbd, &s->iomem);
}
static void test_realize(DeviceState *dev, Error **errp)
{
TestState *s = TEST(dev);
if (!s->downstream) {
error_setg(errp, "test 'downstream' link not set");
return;
}
address_space_init(&s->downstream_as, s->downstream, "test-downstream");
}
static Property test_properties[] = {
DEFINE_PROP_LINK("downstream", TestState, downstream,
TYPE_MEMORY_REGION, MemoryRegion *),
DEFINE_PROP_END_OF_LIST(),
};
static void test_class_init(ObjectClass *oc, void *data)
{
DeviceClass *dc = DEVICE_CLASS(oc);
dc->vmsd = &vmstate_test_channel;
dc->realize = test_realize;
device_class_set_props(dc, test_properties);
dc->reset = test_reset;
}
static const TypeInfo test_info = {
.name = TYPE_TEST,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(TestState),
.instance_init = test_init,
.class_init = test_class_init,
};
/* The PL080 and PL081 are the same except for the number of channels
they implement (8 and 2 respectively). */
static void test_register_types(void)
{
type_register_static(&test_info);
}
type_init(test_register_types)