qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Hervé Poussineau" <hpoussin@reactos.org>
To: qemu-devel@nongnu.org
Cc: "Hervé Poussineau" <hpoussin@reactos.org>,
	" Andreas Färber" <andreas.faerber@web.de>,
	qemu-ppc@nongnu.org
Subject: [Qemu-devel] [PATCH v2 03/10] raven: move BIOS loading from board code to PCI host
Date: Wed,  4 Sep 2013 00:29:03 +0200	[thread overview]
Message-ID: <1378247351-8446-4-git-send-email-hpoussin@reactos.org> (raw)
In-Reply-To: <1378247351-8446-1-git-send-email-hpoussin@reactos.org>

Raven datasheet explains where firmware lives in system memory, so do
it there instead of in board code. Other boards using the same PCI
host will not have to copy the firmware loading code.

However, add a specific hack for Open Hack'Ware, which provides only
a 512KB blob to be loaded at 0xfff00000, but expects valid code at
0xfffffffc (specific Open Hack'Ware reset instruction pointer).

Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
---
 hw/pci-host/prep.c |   51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 hw/ppc/prep.c      |   50 +++++++++++++-------------------------------------
 2 files changed, 64 insertions(+), 37 deletions(-)

diff --git a/hw/pci-host/prep.c b/hw/pci-host/prep.c
index 557486e..25baef1 100644
--- a/hw/pci-host/prep.c
+++ b/hw/pci-host/prep.c
@@ -28,7 +28,9 @@
 #include "hw/pci/pci_bus.h"
 #include "hw/pci/pci_host.h"
 #include "hw/i386/pc.h"
+#include "hw/loader.h"
 #include "exec/address-spaces.h"
+#include "elf.h"
 
 #define TYPE_RAVEN_PCI_DEVICE "raven"
 #define TYPE_RAVEN_PCI_HOST_BRIDGE "raven-pcihost"
@@ -38,6 +40,9 @@
 
 typedef struct RavenPCIState {
     PCIDevice dev;
+    uint32_t elf_machine;
+    char *bios_name;
+    MemoryRegion bios;
 } RavenPCIState;
 
 #define RAVEN_PCI_HOST_BRIDGE(obj) \
@@ -52,6 +57,8 @@ typedef struct PRePPCIState {
     RavenPCIState pci_dev;
 } PREPPCIState;
 
+#define BIOS_SIZE (1024 * 1024)
+
 static inline uint32_t PPC_PCIIO_config(hwaddr addr)
 {
     int i;
@@ -169,10 +176,46 @@ static void raven_pcihost_initfn(Object *obj)
 
 static int raven_init(PCIDevice *d)
 {
+    Object *obj = OBJECT(d);
+    RavenPCIState *s = RAVEN_PCI_DEVICE(d);
+    char *filename;
+    int bios_size = -1;
+
     d->config[0x0C] = 0x08; // cache_line_size
     d->config[0x0D] = 0x10; // latency_timer
     d->config[0x34] = 0x00; // capabilities_pointer
 
+    memory_region_init_ram(&s->bios, obj, "bios", BIOS_SIZE);
+    memory_region_set_readonly(&s->bios, true);
+    memory_region_add_subregion(get_system_memory(), (uint32_t)(-BIOS_SIZE),
+                                &s->bios);
+    vmstate_register_ram_global(&s->bios);
+    if (s->bios_name) {
+        filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, s->bios_name);
+        if (filename) {
+            if (s->elf_machine != EM_NONE) {
+                bios_size = load_elf(filename, NULL, NULL, NULL,
+                                     NULL, NULL, 1, s->elf_machine, 0);
+            }
+            if (bios_size < 0) {
+                bios_size = get_image_size(filename);
+                if (bios_size > 0 && bios_size <= BIOS_SIZE) {
+                    hwaddr bios_addr;
+                    bios_size = (bios_size + 0xfff) & ~0xfff;
+                    bios_addr = (uint32_t)(-BIOS_SIZE);
+                    bios_size = load_image_targphys(filename, bios_addr,
+                                                    bios_size);
+                }
+            }
+        }
+        if (bios_size < 0 || bios_size > BIOS_SIZE) {
+            hw_error("qemu: could not load bios image '%s'\n", s->bios_name);
+        }
+        if (filename) {
+            g_free(filename);
+        }
+    }
+
     return 0;
 }
 
@@ -208,12 +251,20 @@ static const TypeInfo raven_info = {
     .class_init = raven_class_init,
 };
 
+static Property raven_pcihost_properties[] = {
+    DEFINE_PROP_UINT32("elf-machine", PREPPCIState, pci_dev.elf_machine,
+                       EM_NONE),
+    DEFINE_PROP_STRING("bios-name", PREPPCIState, pci_dev.bios_name),
+    DEFINE_PROP_END_OF_LIST()
+};
+
 static void raven_pcihost_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
 
     set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
     dc->realize = raven_pcihost_realizefn;
+    dc->props = raven_pcihost_properties;
     dc->fw_name = "pci";
     dc->no_user = 1;
 }
diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
index efc892d..6df4324 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -456,7 +456,6 @@ static void ppc_prep_init(QEMUMachineInitArgs *args)
     MemoryRegion *sysmem = get_system_memory();
     PowerPCCPU *cpu = NULL;
     CPUPPCState *env = NULL;
-    char *filename;
     nvram_t nvram;
     M48t59State *m48t59;
     MemoryRegion *PPC_io_memory = g_new(MemoryRegion, 1);
@@ -464,7 +463,7 @@ static void ppc_prep_init(QEMUMachineInitArgs *args)
 #if 0
     MemoryRegion *xcsr = g_new(MemoryRegion, 1);
 #endif
-    int linux_boot, i, nb_nics1, bios_size;
+    int linux_boot, i, nb_nics1;
     MemoryRegion *ram = g_new(MemoryRegion, 1);
     MemoryRegion *bios = g_new(MemoryRegion, 1);
     uint32_t kernel_base, initrd_base;
@@ -510,41 +509,13 @@ static void ppc_prep_init(QEMUMachineInitArgs *args)
     memory_region_add_subregion(sysmem, 0, ram);
 
     /* allocate and load BIOS */
-    memory_region_init_ram(bios, NULL, "ppc_prep.bios", BIOS_SIZE);
-    memory_region_set_readonly(bios, true);
-    memory_region_add_subregion(sysmem, (uint32_t)(-BIOS_SIZE), bios);
-    vmstate_register_ram_global(bios);
-    if (bios_name == NULL)
-        bios_name = BIOS_FILENAME;
-    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
-    if (filename) {
-        bios_size = load_elf(filename, NULL, NULL, NULL,
-                             NULL, NULL, 1, ELF_MACHINE, 0);
-        if (bios_size < 0) {
-            bios_size = get_image_size(filename);
-            if (bios_size > 0 && bios_size <= BIOS_SIZE) {
-                hwaddr bios_addr;
-                bios_size = (bios_size + 0xfff) & ~0xfff;
-                bios_addr = (uint32_t)(-bios_size);
-                bios_size = load_image_targphys(filename, bios_addr, bios_size);
-            }
-            if (bios_size > BIOS_SIZE) {
-                fprintf(stderr, "qemu: PReP bios '%s' is too large (0x%x)\n",
-                        bios_name, bios_size);
-                exit(1);
-            }
-        }
-    } else {
-        bios_size = -1;
-    }
-    if (bios_size < 0 && !qtest_enabled()) {
-        fprintf(stderr, "qemu: could not load PPC PReP bios '%s'\n",
-                bios_name);
-        exit(1);
-    }
-    if (filename) {
-        g_free(filename);
-    }
+    /* Open Hack'Ware hack: bios size is 512K and is loaded at 0xfff00000.
+     * However, reset address is 0xfffffffc. Mirror the bios from
+     * 0xfff00000 to 0xfff80000.
+     */
+    memory_region_init_alias(bios, NULL, "bios-alias", sysmem, 0xfff00000,
+                             0x00080000);
+    memory_region_add_subregion_overlap(sysmem, 0xfff80000, bios, 1);
 
     if (linux_boot) {
         kernel_base = KERNEL_LOAD_ADDR;
@@ -593,6 +564,11 @@ static void ppc_prep_init(QEMUMachineInitArgs *args)
     }
 
     dev = qdev_create(NULL, "raven-pcihost");
+    if (bios_name == NULL) {
+        bios_name = BIOS_FILENAME;
+    }
+    qdev_prop_set_string(dev, "bios-name", bios_name);
+    qdev_prop_set_uint32(dev, "elf-machine", ELF_MACHINE);
     pcihost = PCI_HOST_BRIDGE(dev);
     object_property_add_child(qdev_get_machine(), "raven", OBJECT(dev), NULL);
     qdev_init_nofail(dev);
-- 
1.7.10.4

  parent reply	other threads:[~2013-09-03 22:28 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-09-03 22:29 [Qemu-devel] [PATCH v2 00/10] prep: improve Raven PCI host emulation Hervé Poussineau
2013-09-03 22:29 ` [Qemu-devel] [PATCH v2 01/10] prep: kill get_system_io() usage Hervé Poussineau
2013-09-04  6:13   ` Paolo Bonzini
2013-09-04 18:29     ` Hervé Poussineau
2013-09-03 22:29 ` [Qemu-devel] [PATCH v2 02/10] raven: use constant PCI_NUM_PINS instead of 4 Hervé Poussineau
2013-09-03 22:29 ` Hervé Poussineau [this message]
2013-09-03 22:29 ` [Qemu-devel] [PATCH v2 04/10] raven: rename intack region to pci_intack Hervé Poussineau
2013-09-03 22:29 ` [Qemu-devel] [PATCH v2 05/10] raven: set a correct PCI I/O memory region Hervé Poussineau
2013-09-04  6:01   ` Paolo Bonzini
2013-09-04  7:22     ` Peter Maydell
2013-09-04  8:11       ` Paolo Bonzini
2013-09-04  8:25         ` Peter Maydell
2013-09-04  8:31           ` Paolo Bonzini
2013-09-04  8:51             ` Peter Maydell
2013-09-04  8:54           ` Andreas Färber
2013-09-09 20:57           ` Hervé Poussineau
2013-09-09 21:33             ` Peter Maydell
2013-09-10  7:43             ` Paolo Bonzini
2013-09-03 22:29 ` [Qemu-devel] [PATCH v2 06/10] raven: set a correct PCI " Hervé Poussineau
2013-09-03 22:29 ` [Qemu-devel] [PATCH v2 07/10] raven: add PCI bus mastering address space Hervé Poussineau
2013-09-03 22:29 ` [Qemu-devel] [PATCH v2 08/10] raven: implement non-contiguous I/O region Hervé Poussineau
2013-09-03 22:29 ` [Qemu-devel] [PATCH v2 09/10] raven: fix PCI bus accesses with size > 1 Hervé Poussineau
2013-09-03 22:29 ` [Qemu-devel] [PATCH v2 10/10] raven: use raven_ for all function prefixes Hervé Poussineau

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1378247351-8446-4-git-send-email-hpoussin@reactos.org \
    --to=hpoussin@reactos.org \
    --cc=andreas.faerber@web.de \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).