[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 2/2] extboot: qemu code.
From: |
Gerd Hoffmann |
Subject: |
[Qemu-devel] [PATCH 2/2] extboot: qemu code. |
Date: |
Mon, 16 Nov 2009 19:04:38 +0100 |
booting from scsi + virtio works now.
usage: -device extboot,drive=<name>
where <name> is the name of your boot drive. You can either use the
names qemu assignes by default (virtio0, scsi0-hd0, ...) or explitly
name your drives via '-drive id=<name>,...' and use that one.
Signed-off-by: Gerd Hoffmann <address@hidden>
---
Makefile.target | 2 +-
hw/extboot.c | 168 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 169 insertions(+), 1 deletions(-)
create mode 100644 hw/extboot.c
diff --git a/Makefile.target b/Makefile.target
index 7068dc5..b165456 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -197,7 +197,7 @@ obj-i386-y += fdc.o mc146818rtc.o serial.o i8259.o i8254.o
pcspk.o pc.o
obj-i386-y += cirrus_vga.o apic.o ioapic.o parallel.o acpi.o piix_pci.o
obj-i386-y += usb-uhci.o vmmouse.o vmport.o vmware_vga.o hpet.o
obj-i386-y += device-hotplug.o pci-hotplug.o smbios.o wdt_ib700.o
-obj-i386-y += ne2000-isa.o
+obj-i386-y += ne2000-isa.o extboot.o
# shared objects
obj-ppc-y = ppc.o ide/core.o ide/qdev.o ide/isa.o ide/pci.o ide/macio.o
diff --git a/hw/extboot.c b/hw/extboot.c
new file mode 100644
index 0000000..3465558
--- /dev/null
+++ b/hw/extboot.c
@@ -0,0 +1,168 @@
+/*
+ * Extended boot option ROM support.
+ *
+ * Copyright IBM, Corp. 2007
+ *
+ * Authors:
+ * Anthony Liguori <address@hidden>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include "hw.h"
+#include "pc.h"
+#include "isa.h"
+#include "block.h"
+#include "loader.h"
+
+typedef struct ExtbootState {
+ ISADevice dev;
+ DriveInfo *dinfo;
+ BlockDriverState *bs;
+} ExtbootState;
+
+union extboot_cmd
+{
+ uint16_t type;
+ struct {
+ uint16_t type;
+ uint16_t cylinders;
+ uint16_t heads;
+ uint16_t sectors;
+ uint64_t nb_sectors;
+ } query_geometry;
+ struct {
+ uint16_t type;
+ uint16_t nb_sectors;
+ uint16_t segment;
+ uint16_t offset;
+ uint64_t sector;
+ } xfer;
+};
+
+static void get_translated_chs(BlockDriverState *bs, int *c, int *h, int *s)
+{
+ bdrv_get_geometry_hint(bs, c, h, s);
+
+ if (*c <= 1024) {
+ *c >>= 0;
+ *h <<= 0;
+ } else if (*c <= 2048) {
+ *c >>= 1;
+ *h <<= 1;
+ } else if (*c <= 4096) {
+ *c >>= 2;
+ *h <<= 2;
+ } else if (*c <= 8192) {
+ *c >>= 3;
+ *h <<= 3;
+ } else {
+ *c >>= 4;
+ *h <<= 4;
+ }
+
+ /* what is the correct algorithm for this?? */
+ if (*h == 256) {
+ *h = 255;
+ *c = *c + 1;
+ }
+}
+
+static uint32_t extboot_read(void *opaque, uint32_t addr)
+{
+ return 1;
+}
+
+static void extboot_write(void *opaque, uint32_t addr, uint32_t value)
+{
+ ExtbootState *s = opaque;
+ union extboot_cmd cmd;
+ int cylinders, heads, sectors, err;
+ uint64_t nb_sectors;
+ target_phys_addr_t pa = 0;
+ int blen = 0;
+ void *buf = NULL;
+
+ cpu_physical_memory_read((value & 0xFFFF) << 4, (uint8_t *)&cmd,
+ sizeof(cmd));
+
+ if (cmd.type == 0x01 || cmd.type == 0x02) {
+ pa = cmd.xfer.segment * 16 + cmd.xfer.offset;
+ blen = cmd.xfer.nb_sectors * 512;
+ buf = qemu_memalign(512, blen);
+ }
+
+ switch (cmd.type) {
+ case 0x00:
+ get_translated_chs(s->bs, &cylinders, &heads, §ors);
+ bdrv_get_geometry(s->bs, &nb_sectors);
+ cmd.query_geometry.cylinders = cylinders;
+ cmd.query_geometry.heads = heads;
+ cmd.query_geometry.sectors = sectors;
+ cmd.query_geometry.nb_sectors = nb_sectors;
+ break;
+ case 0x01:
+ err = bdrv_read(s->bs, cmd.xfer.sector, buf, cmd.xfer.nb_sectors);
+ if (err)
+ printf("Read failed\n");
+
+ cpu_physical_memory_write(pa, buf, blen);
+
+ break;
+ case 0x02:
+ cpu_physical_memory_read(pa, buf, blen);
+
+ err = bdrv_write(s->bs, cmd.xfer.sector, buf, cmd.xfer.nb_sectors);
+ if (err)
+ printf("Write failed\n");
+
+ break;
+ }
+
+ cpu_physical_memory_write((value & 0xFFFF) << 4, (uint8_t *)&cmd,
+ sizeof(cmd));
+ if (buf)
+ qemu_free(buf);
+}
+
+static int extboot_init(ISADevice *dev)
+{
+ ExtbootState *s = DO_UPCAST(ExtbootState, dev, dev);
+ int cyls, heads, secs;
+
+ if (!s->dinfo) {
+ fprintf(stderr, "extboot: no drive specified\n");
+ return -1;
+ }
+ if (!s->dinfo->bdrv) {
+ fprintf(stderr, "extboot: drive %s is empty\n", s->dinfo->id);
+ return -1;
+ }
+
+ s->bs = s->dinfo->bdrv;
+ bdrv_guess_geometry(s->bs, &cyls, &heads, &secs);
+ bdrv_set_geometry_hint(s->bs, cyls, heads, secs);
+ register_ioport_read(0x404, 1, 1, extboot_read, s);
+ register_ioport_write(0x405, 1, 2, extboot_write, s);
+ rom_add_option("extboot.bin");
+ return 0;
+}
+
+static ISADeviceInfo extboot_info = {
+ .qdev.name = "extboot",
+ .qdev.size = sizeof(ExtbootState),
+ .init = extboot_init,
+ .qdev.props = (Property[]) {
+ DEFINE_PROP_DRIVE("drive", ExtbootState, dinfo),
+ DEFINE_PROP_END_OF_LIST(),
+ },
+};
+
+static void extboot_register(void)
+{
+ isa_qdev_register(&extboot_info);
+};
+
+device_init(extboot_register);
--
1.6.2.5
- [Qemu-devel] [PATCH 0/2] extboot reloaded., Gerd Hoffmann, 2009/11/16
- [Qemu-devel] [PATCH 2/2] extboot: qemu code.,
Gerd Hoffmann <=
- [Qemu-devel] [PATCH 1/2] extboot: add option rom., Gerd Hoffmann, 2009/11/16
- Re: [Qemu-devel] [PATCH 0/2] extboot reloaded., Anthony Liguori, 2009/11/16
- Re: [Qemu-devel] [PATCH 0/2] extboot reloaded., Gerd Hoffmann, 2009/11/16
- Re: [Qemu-devel] [PATCH 0/2] extboot reloaded., Anthony Liguori, 2009/11/16
- Re: [Qemu-devel] [PATCH 0/2] extboot reloaded., Paul Brook, 2009/11/17
- Re: [Qemu-devel] [PATCH 0/2] extboot reloaded., Gerd Hoffmann, 2009/11/17
- Re: [Qemu-devel] [PATCH 0/2] extboot reloaded., Paul Brook, 2009/11/17
- Re: [Qemu-devel] [PATCH 0/2] extboot reloaded., Gerd Hoffmann, 2009/11/17
- Re: [Qemu-devel] [PATCH 0/2] extboot reloaded., Paul Brook, 2009/11/17
- Re: [Qemu-devel] [PATCH 0/2] extboot reloaded., Alexander Graf, 2009/11/17