qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] Help writing a trivial device


From: Lluís Vilanova
Subject: [Qemu-devel] Help writing a trivial device
Date: Mon, 26 Sep 2011 00:23:21 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.3 (gnu/linux)

Hi. I started writing a trivial device on QEMU that should get called on every
read and write on the memory it provides.

The problems are that:

1) Cannot start QEMU with KVM when the device is enabled:
       kvm_set_phys_mem: error registering slot: Invalid argument

2) The driver never gets called on a read/write to its memory

I'm sure this is due to some error in my code, but I'm clueless as to what it
could be.


The testing system is a Linux 2.6.32, with this:

int fd = open("/sys/devices/pci0000:00/000000:00:004.00/resource0", O_RDWR);
void *addr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
printf("-> %ld\n", *(uint64_t*)addr);


The device is something like (some code changed for brevity):

typedef struct State
{
    PCIDevice dev;
    MemoryRegion control;
} State;


static uint64_t control_io_read(void *opaque, target_phys_addr_t addr, unsigned 
size)
{
    return 0xcafe;
}

static void control_io_write(void *opaque, target_phys_addr_t addr, uint64_t 
data, unsigned size)
{
    /* do something */
}

static const MemoryRegionOps control_ops = {
    .read = control_io_read,
    .write = control_io_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
    .valid = {
        .min_access_size = 8,
        .max_access_size = 8,
    },
};


static int init(PCIDevice *dev)
{
    State *s = DO_UPCAST(State, dev, dev);

    memory_region_init_io(&s->control, &control_ops, s, "backdoor.control",
                          TARGET_PAGE_SIZE);
    pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->control);

    return 0;
}

static int fini(PCIDevice *dev)
{
    State *s = DO_UPCAST(State, dev, dev);

    memory_region_destroy(&s->control);

    return 0;
}


static PCIDeviceInfo info = {
    .qdev.name  = "foo",
    .qdev.size  = sizeof(State),
    .init       = init,
    .exit       = fini,
    .vendor_id  = PCI_VENDOR_ID_REDHAT_QUMRANET,
    .device_id  = 0x1005,
    .class_id   = PCI_CLASS_MEMORY_RAM,
};

static void register_devices(void)
{
    pci_qdev_register(&info);
}

device_init(register_devices)



Is there something blatantly wrong in the device code?


Thanks a lot,
    Lluis

-- 
 "And it's much the same thing with knowledge, for whenever you learn
 something new, the whole world becomes that much richer."
 -- The Princess of Pure Reason, as told by Norton Juster in The Phantom
 Tollbooth



reply via email to

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