From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:60894) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1R8RFR-000139-T2 for qemu-devel@nongnu.org; Tue, 27 Sep 2011 02:34:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1R8RFQ-0001Dw-Fh for qemu-devel@nongnu.org; Tue, 27 Sep 2011 02:34:33 -0400 Received: from mail-wy0-f173.google.com ([74.125.82.173]:62933) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1R8RFQ-0001Do-BG for qemu-devel@nongnu.org; Tue, 27 Sep 2011 02:34:32 -0400 Received: by wyh22 with SMTP id 22so7591308wyh.4 for ; Mon, 26 Sep 2011 23:34:31 -0700 (PDT) MIME-Version: 1.0 In-Reply-To: <87litcs1ly.fsf@ginnungagap.bsc.es> References: <87litcs1ly.fsf@ginnungagap.bsc.es> Date: Tue, 27 Sep 2011 14:34:31 +0800 Message-ID: From: Zhi Yong Wu Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Subject: Re: [Qemu-devel] Help writing a trivial device List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: =?ISO-8859-1?Q?Llu=EDs_Vilanova?= Cc: qemu-devel@nongnu.org 2011/9/26 Llu=EDs Vilanova : > 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: > =A0 =A0 =A0 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 wha= t it > could be. > > > The testing system is a Linux 2.6.32, with this: > > int fd =3D open("/sys/devices/pci0000:00/000000:00:004.00/resource0", O_R= DWR); > void *addr =3D mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0= ); > printf("-> %ld\n", *(uint64_t*)addr); This is the way about how to test bar? Does bar1 correspond to guest file /sys/devices/pci0000:00/000000:00:004.00/resource0? > > > The device is something like (some code changed for brevity): > > typedef struct State > { > =A0 =A0PCIDevice dev; > =A0 =A0MemoryRegion control; > } State; > > > static uint64_t control_io_read(void *opaque, target_phys_addr_t addr, un= signed size) > { > =A0 =A0return 0xcafe; > } > > static void control_io_write(void *opaque, target_phys_addr_t addr, uint6= 4_t data, unsigned size) > { > =A0 =A0/* do something */ > } > > static const MemoryRegionOps control_ops =3D { > =A0 =A0.read =3D control_io_read, > =A0 =A0.write =3D control_io_write, > =A0 =A0.endianness =3D DEVICE_NATIVE_ENDIAN, > =A0 =A0.valid =3D { > =A0 =A0 =A0 =A0.min_access_size =3D 8, > =A0 =A0 =A0 =A0.max_access_size =3D 8, > =A0 =A0}, > }; > > > static int init(PCIDevice *dev) > { > =A0 =A0State *s =3D DO_UPCAST(State, dev, dev); > > =A0 =A0memory_region_init_io(&s->control, &control_ops, s, "backdoor.cont= rol", > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0TARGET_PAGE_SIZE); > =A0 =A0pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->co= ntrol); > > =A0 =A0return 0; > } > > static int fini(PCIDevice *dev) > { > =A0 =A0State *s =3D DO_UPCAST(State, dev, dev); > > =A0 =A0memory_region_destroy(&s->control); > > =A0 =A0return 0; > } > > > static PCIDeviceInfo info =3D { > =A0 =A0.qdev.name =A0=3D "foo", > =A0 =A0.qdev.size =A0=3D sizeof(State), > =A0 =A0.init =A0 =A0 =A0 =3D init, > =A0 =A0.exit =A0 =A0 =A0 =3D fini, > =A0 =A0.vendor_id =A0=3D PCI_VENDOR_ID_REDHAT_QUMRANET, > =A0 =A0.device_id =A0=3D 0x1005, > =A0 =A0.class_id =A0 =3D PCI_CLASS_MEMORY_RAM, > }; > > static void register_devices(void) > { > =A0 =A0pci_qdev_register(&info); > } > > device_init(register_devices) > > > > Is there something blatantly wrong in the device code? > > > Thanks a lot, > =A0 =A0Lluis > > -- > =A0"And it's much the same thing with knowledge, for whenever you learn > =A0something new, the whole world becomes that much richer." > =A0-- The Princess of Pure Reason, as told by Norton Juster in The Phanto= m > =A0Tollbooth > > --=20 Regards, Zhi Yong Wu