qemu-discuss
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Fwd: How do you set a value to a QOM register from GDB?


From: 清水寛子
Subject: Fwd: How do you set a value to a QOM register from GDB?
Date: Sat, 3 Jul 2021 20:14:39 +0900

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 space
static 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)
---------------------------------------------

Best regard, 
Hiroko

 
(removed qemu-stable from cc: -- that list is for cc'ing on patches
that should be backported to a stable release.)

>From the code you've shown us that looks like it ought to work,
so probably the bug is in a bit of code that you've written but
haven't shown us (eg the MemoryRegionOps or the board code).

-- PMM

reply via email to

[Prev in Thread] Current Thread [Next in Thread]