]> Git Repo - qemu.git/blobdiff - hw/loader.c
pseries: Remove "busname" property for PCI host bridge
[qemu.git] / hw / loader.c
index 415cdce534f1453121447ff0f4046068007e8517..6ce66fb5bb10d4d681a82d370c3307e85d5983ce 100644 (file)
  * with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "hw.h"
-#include "disas.h"
-#include "monitor.h"
-#include "sysemu.h"
-#include "uboot_image.h"
-#include "loader.h"
-#include "fw_cfg.h"
-#include "memory.h"
-#include "exec-memory.h"
+#include "hw/hw.h"
+#include "disas/disas.h"
+#include "monitor/monitor.h"
+#include "sysemu/sysemu.h"
+#include "hw/uboot_image.h"
+#include "hw/loader.h"
+#include "hw/fw_cfg.h"
+#include "exec/memory.h"
+#include "exec/address-spaces.h"
 
 #include <zlib.h>
 
@@ -88,7 +88,7 @@ int load_image(const char *filename, uint8_t *addr)
 
 /* read()-like version */
 ssize_t read_targphys(const char *name,
-                      int fd, target_phys_addr_t dst_addr, size_t nbytes)
+                      int fd, hwaddr dst_addr, size_t nbytes)
 {
     uint8_t *buf;
     ssize_t did;
@@ -103,7 +103,7 @@ ssize_t read_targphys(const char *name,
 
 /* return the size or -1 if error */
 int load_image_targphys(const char *filename,
-                       target_phys_addr_t addr, int max_sz)
+                        hwaddr addr, uint64_t max_sz)
 {
     int size;
 
@@ -117,7 +117,7 @@ int load_image_targphys(const char *filename,
     return size;
 }
 
-void pstrcpy_targphys(const char *name, target_phys_addr_t dest, int buf_size,
+void pstrcpy_targphys(const char *name, hwaddr dest, int buf_size,
                       const char *source)
 {
     const char *nulp;
@@ -179,8 +179,8 @@ static void bswap_ahdr(struct exec *e)
      : (_N_SEGMENT_ROUND (_N_TXTENDADDR(x, target_page_size), target_page_size)))
 
 
-int load_aout(const char *filename, target_phys_addr_t addr, int max_sz,
-              int bswap_needed, target_phys_addr_t target_page_size)
+int load_aout(const char *filename, hwaddr addr, int max_sz,
+              int bswap_needed, hwaddr target_page_size)
 {
     int fd;
     ssize_t size, ret;
@@ -260,7 +260,7 @@ static void *load_at(int fd, int offset, int size)
 #define elf_word        uint32_t
 #define elf_sword        int32_t
 #define bswapSZs       bswap32s
-#include "elf_ops.h"
+#include "hw/elf_ops.h"
 
 #undef elfhdr
 #undef elf_phdr
@@ -280,7 +280,7 @@ static void *load_at(int fd, int offset, int size)
 #define elf_sword        int64_t
 #define bswapSZs       bswap64s
 #define SZ             64
-#include "elf_ops.h"
+#include "hw/elf_ops.h"
 
 /* return < 0 if error, otherwise the number of bytes loaded in memory */
 int load_elf(const char *filename, uint64_t (*translate_fn)(void *, uint64_t),
@@ -377,9 +377,9 @@ static void zfree(void *x, void *addr)
 
 #define DEFLATED       8
 
-/* This is the maximum in uboot, so if a uImage overflows this, it would
+/* This is the usual maximum in uboot, so if a uImage overflows this, it would
  * overflow on real hardware too. */
-#define UBOOT_MAX_GUNZIP_BYTES 0x800000
+#define UBOOT_MAX_GUNZIP_BYTES (64 << 20)
 
 static ssize_t gunzip(void *dst, size_t dstlen, uint8_t *src,
                       size_t srclen)
@@ -434,8 +434,8 @@ static ssize_t gunzip(void *dst, size_t dstlen, uint8_t *src,
 }
 
 /* Load a U-Boot image.  */
-int load_uimage(const char *filename, target_phys_addr_t *ep,
-                target_phys_addr_t *loadaddr, int *is_linux)
+int load_uimage(const char *filename, hwaddr *ep,
+                hwaddr *loadaddr, int *is_linux)
 {
     int fd;
     int size;
@@ -533,13 +533,20 @@ typedef struct Rom Rom;
 struct Rom {
     char *name;
     char *path;
+
+    /* datasize is the amount of memory allocated in "data". If datasize is less
+     * than romsize, it means that the area from datasize to romsize is filled
+     * with zeros.
+     */
     size_t romsize;
+    size_t datasize;
+
     uint8_t *data;
     int isrom;
     char *fw_dir;
     char *fw_file;
 
-    target_phys_addr_t addr;
+    hwaddr addr;
     QTAILQ_ENTRY(Rom) next;
 };
 
@@ -565,7 +572,7 @@ static void rom_insert(Rom *rom)
 }
 
 int rom_add_file(const char *file, const char *fw_dir,
-                 target_phys_addr_t addr, int32_t bootindex)
+                 hwaddr addr, int32_t bootindex)
 {
     Rom *rom;
     int rc, fd = -1;
@@ -589,14 +596,15 @@ int rom_add_file(const char *file, const char *fw_dir,
         rom->fw_dir  = g_strdup(fw_dir);
         rom->fw_file = g_strdup(file);
     }
-    rom->addr    = addr;
-    rom->romsize = lseek(fd, 0, SEEK_END);
-    rom->data    = g_malloc0(rom->romsize);
+    rom->addr     = addr;
+    rom->romsize  = lseek(fd, 0, SEEK_END);
+    rom->datasize = rom->romsize;
+    rom->data     = g_malloc0(rom->datasize);
     lseek(fd, 0, SEEK_SET);
-    rc = read(fd, rom->data, rom->romsize);
-    if (rc != rom->romsize) {
+    rc = read(fd, rom->data, rom->datasize);
+    if (rc != rom->datasize) {
         fprintf(stderr, "rom: file %-20s: read error: rc=%d (expected %zd)\n",
-                rom->name, rc, rom->romsize);
+                rom->name, rc, rom->datasize);
         goto err;
     }
     close(fd);
@@ -633,20 +641,41 @@ err:
 }
 
 int rom_add_blob(const char *name, const void *blob, size_t len,
-                 target_phys_addr_t addr)
+                 hwaddr addr)
 {
     Rom *rom;
 
-    rom = g_malloc0(sizeof(*rom));
-    rom->name    = g_strdup(name);
-    rom->addr    = addr;
-    rom->romsize = len;
-    rom->data    = g_malloc0(rom->romsize);
+    rom           = g_malloc0(sizeof(*rom));
+    rom->name     = g_strdup(name);
+    rom->addr     = addr;
+    rom->romsize  = len;
+    rom->datasize = len;
+    rom->data     = g_malloc0(rom->datasize);
     memcpy(rom->data, blob, len);
     rom_insert(rom);
     return 0;
 }
 
+/* This function is specific for elf program because we don't need to allocate
+ * all the rom. We just allocate the first part and the rest is just zeros. This
+ * is why romsize and datasize are different. Also, this function seize the
+ * memory ownership of "data", so we don't have to allocate and copy the buffer.
+ */
+int rom_add_elf_program(const char *name, void *data, size_t datasize,
+                        size_t romsize, hwaddr addr)
+{
+    Rom *rom;
+
+    rom           = g_malloc0(sizeof(*rom));
+    rom->name     = g_strdup(name);
+    rom->addr     = addr;
+    rom->datasize = datasize;
+    rom->romsize  = romsize;
+    rom->data     = data;
+    rom_insert(rom);
+    return 0;
+}
+
 int rom_add_vga(const char *file)
 {
     return rom_add_file(file, "vgaroms", 0, -1);
@@ -668,7 +697,7 @@ static void rom_reset(void *unused)
         if (rom->data == NULL) {
             continue;
         }
-        cpu_physical_memory_write_rom(rom->addr, rom->data, rom->romsize);
+        cpu_physical_memory_write_rom(rom->addr, rom->data, rom->datasize);
         if (rom->isrom) {
             /* rom needs to be written only once */
             g_free(rom->data);
@@ -679,7 +708,7 @@ static void rom_reset(void *unused)
 
 int rom_load_all(void)
 {
-    target_phys_addr_t addr = 0;
+    hwaddr addr = 0;
     MemoryRegionSection section;
     Rom *rom;
 
@@ -709,7 +738,7 @@ void rom_set_fw(void *f)
     fw_cfg = f;
 }
 
-static Rom *find_rom(target_phys_addr_t addr)
+static Rom *find_rom(hwaddr addr)
 {
     Rom *rom;
 
@@ -733,9 +762,9 @@ static Rom *find_rom(target_phys_addr_t addr)
  * a ROM between addr and addr + size is copied. Note that this can involve
  * multiple ROMs, which need not start at addr and need not end at addr + size.
  */
-int rom_copy(uint8_t *dest, target_phys_addr_t addr, size_t size)
+int rom_copy(uint8_t *dest, hwaddr addr, size_t size)
 {
-    target_phys_addr_t end = addr + size;
+    hwaddr end = addr + size;
     uint8_t *s, *d = dest;
     size_t l = 0;
     Rom *rom;
@@ -756,19 +785,39 @@ int rom_copy(uint8_t *dest, target_phys_addr_t addr, size_t size)
 
         d = dest + (rom->addr - addr);
         s = rom->data;
-        l = rom->romsize;
+        l = rom->datasize;
 
         if ((d + l) > (dest + size)) {
             l = dest - d;
         }
 
         memcpy(d, s, l);
+
+        if (rom->romsize > rom->datasize) {
+            /* If datasize is less than romsize, it means that we didn't
+             * allocate all the ROM because the trailing data are only zeros.
+             */
+
+            d += l;
+            l = rom->romsize - rom->datasize;
+
+            if ((d + l) > (dest + size)) {
+                /* Rom size doesn't fit in the destination area. Adjust to avoid
+                 * overflow.
+                 */
+                l = dest - d;
+            }
+
+            if (l > 0) {
+                memset(d, 0x0, l);
+            }
+        }
     }
 
     return (d + l) - dest;
 }
 
-void *rom_ptr(target_phys_addr_t addr)
+void *rom_ptr(hwaddr addr)
 {
     Rom *rom;
 
@@ -778,7 +827,7 @@ void *rom_ptr(target_phys_addr_t addr)
     return rom->data + (addr - rom->addr);
 }
 
-void do_info_roms(Monitor *mon)
+void do_info_roms(Monitor *mon, const QDict *qdict)
 {
     Rom *rom;
 
This page took 0.035216 seconds and 4 git commands to generate.