Patchwork Reorganize option rom (+linux kernel) loading.

login
register
mail settings
Submitter Gerd Hoffmann
Date Oct. 6, 2009, 9:18 p.m.
Message ID <4ACBB40C.7030209@redhat.com>
Download mbox | patch
Permalink /patch/35140/
State Rejected
Headers show

Comments

Gerd Hoffmann - Oct. 6, 2009, 9:18 p.m.
On 10/02/09 19:58, Blue Swirl wrote:
> On Fri, Oct 2, 2009 at 6:19 PM, Gerd Hoffmann<kraxel@redhat.com>  wrote:
>> On 10/02/09 13:40, Gerd Hoffmann wrote:
>>>>
>>>> OK, V2 seems to work, except that the command line is not passed:
>>>> NET: Registered protocol family 1
>>>> NET: Registered protocol family 17
>>>> Kernel panic - not syncing: VFS: Unable to mount root fs on
>>>> unknown-block(1,0)
>>>> <0>Press L1-A to return to the boot prom
>>>
>>> So you are booting sparc via -kernel I guess?
>>
>> One more question: Fails it on first boot or only after reset?
>> In case it fails after reset only: Does that work without the patch?
>
> First boot, identical result after reset. Without patch:
>
> NET: Registered protocol family 1
> NET: Registered protocol family 17
> RAMDISK: ext2 filesystem found at block 0
> RAMDISK: Loading 4096KiB [1 disk] into ram disk... done.
> VFS: Mounted root (ext2 filesystem) readonly.
> Freeing unused kernel memory: 156k freed
> sh: can't access tty; job control turned off
> #

Incremental fix attached.

Booting works now.
system_reset in monitor works fine too.

Will respin the patch tomorrow.

cheers,
   Gerd
From 73928f9846fc8493d56f5a42c25b68707f6679e7 Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Tue, 6 Oct 2009 23:09:50 +0200
Subject: [PATCH] fix sparc.

---
 hw/axis_dev88.c               |    2 +-
 hw/etraxfs.c                  |    2 +-
 hw/loader.c                   |   38 ++++++++++++++++++++++++++++++++------
 hw/loader.h                   |    4 +++-
 hw/mips_malta.c               |    2 +-
 hw/mips_r4k.c                 |    2 +-
 hw/pc.c                       |    2 +-
 hw/petalogix_s3adsp1800_mmu.c |    2 +-
 hw/ppc.c                      |    2 +-
 hw/ppc_newworld.c             |    2 +-
 hw/ppc_oldworld.c             |    2 +-
 hw/r2d.c                      |    2 +-
 hw/sun4m.c                    |   14 ++++++++------
 hw/sun4u.c                    |    2 +-
 14 files changed, 54 insertions(+), 24 deletions(-)

Patch

diff --git a/hw/axis_dev88.c b/hw/axis_dev88.c
index 81a41c9..2a79d33 100644
--- a/hw/axis_dev88.c
+++ b/hw/axis_dev88.c
@@ -365,7 +365,7 @@  void axisdev88_init (ram_addr_t ram_size,
             /* Let the kernel know we are modifying the cmdline.  */
             env->regs[10] = 0x87109563;
             env->regs[11] = 0x40000000;
-            pstrcpy_targphys(env->regs[11], 256, kernel_cmdline);
+            pstrcpy_targphys("cmdline", env->regs[11], 256, kernel_cmdline);
         }
     }
     env->pc = bootstrap_pc;
diff --git a/hw/etraxfs.c b/hw/etraxfs.c
index 4f451c5..9304b15 100644
--- a/hw/etraxfs.c
+++ b/hw/etraxfs.c
@@ -157,7 +157,7 @@  void bareetraxfs_init (ram_addr_t ram_size,
             /* Let the kernel know we are modifying the cmdline.  */
             env->regs[10] = 0x87109563;
             env->regs[11] = 0x40000000;
-            pstrcpy_targphys(env->regs[11], 256, kernel_cmdline);
+            pstrcpy_targphys("cmdline", env->regs[11], 256, kernel_cmdline);
         }
     }
     env->pc = bootstrap_pc;
diff --git a/hw/loader.c b/hw/loader.c
index c436ec6..40112b9 100644
--- a/hw/loader.c
+++ b/hw/loader.c
@@ -108,20 +108,20 @@  int load_image_targphys(const char *filename,
     return size;
 }
 
-void pstrcpy_targphys(target_phys_addr_t dest, int buf_size,
+void pstrcpy_targphys(const char *name, target_phys_addr_t dest, int buf_size,
                       const char *source)
 {
-    static const uint8_t nul_byte = 0;
     const char *nulp;
+    char *ptr;
 
     if (buf_size <= 0) return;
     nulp = memchr(source, 0, buf_size);
     if (nulp) {
-	cpu_physical_memory_write_rom(dest, (uint8_t *)source,
-                                      (nulp - source) + 1);
+        rom_add_blob_fixed(name, source, (nulp - source) + 1, dest);
     } else {
-	cpu_physical_memory_write_rom(dest, (uint8_t *)source, buf_size - 1);
-	cpu_physical_memory_write_rom(dest, &nul_byte, 1);
+        rom_add_blob_fixed(name, source, buf_size, dest);
+        ptr = rom_ptr(dest + buf_size - 1);
+        *ptr = 0;
     }
 }
 
@@ -672,6 +672,32 @@  int rom_load_all(void)
     return 0;
 }
 
+static Rom *find_rom(target_phys_addr_t addr)
+{
+    Rom *rom;
+
+    QTAILQ_FOREACH(rom, &roms, next) {
+        if (rom->max)
+            continue;
+        if (rom->min > addr)
+            continue;
+        if (rom->min + rom->romsize < addr)
+            continue;
+        return rom;
+    }
+    return NULL;
+}
+
+void *rom_ptr(target_phys_addr_t addr)
+{
+    Rom *rom;
+
+    rom = find_rom(addr);
+    if (!rom || !rom->data)
+        return NULL;
+    return rom->data + (addr - rom->min);
+}
+
 void do_info_roms(Monitor *mon)
 {
     Rom *rom;
diff --git a/hw/loader.h b/hw/loader.h
index 031e6ad..945c662 100644
--- a/hw/loader.h
+++ b/hw/loader.h
@@ -15,7 +15,8 @@  int load_uimage(const char *filename, target_phys_addr_t *ep,
 
 int read_targphys(const char *name,
                   int fd, target_phys_addr_t dst_addr, size_t nbytes);
-void pstrcpy_targphys(target_phys_addr_t dest, int buf_size,
+void pstrcpy_targphys(const char *name,
+                      target_phys_addr_t dest, int buf_size,
                       const char *source);
 
 int rom_add_file(const char *file,
@@ -23,6 +24,7 @@  int rom_add_file(const char *file,
 int rom_add_blob(const char *name, const void *blob, size_t len,
                  target_phys_addr_t min, target_phys_addr_t max, int align);
 int rom_load_all(void);
+void *rom_ptr(target_phys_addr_t addr);
 void do_info_roms(Monitor *mon);
 
 #define rom_add_file_fixed(_f, _a)              \
diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index d0266d5..6b224e5 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -679,7 +679,7 @@  static void prom_set(int index, const char *string, ...)
     va_start(ap, string);
     vsnprintf(buf, ENVP_ENTRY_SIZE, string, ap);
     va_end(ap);
-    pstrcpy_targphys(table_addr + VIRT_TO_PHYS_ADDEND, ENVP_ENTRY_SIZE, buf);
+    pstrcpy_targphys("prom", table_addr + VIRT_TO_PHYS_ADDEND, ENVP_ENTRY_SIZE, buf);
 }
 
 /* Kernel */
diff --git a/hw/mips_r4k.c b/hw/mips_r4k.c
index d7b301a..d525c63 100644
--- a/hw/mips_r4k.c
+++ b/hw/mips_r4k.c
@@ -130,7 +130,7 @@  static void load_kernel (CPUState *env)
     } else {
         ret = 0;
     }
-    pstrcpy_targphys((16 << 20) - 256 + ret, 256,
+    pstrcpy_targphys("cmdline", (16 << 20) - 256 + ret, 256,
                      loaderparams.kernel_cmdline);
 
     stl_phys((16 << 20) - 260, 0x12345678);
diff --git a/hw/pc.c b/hw/pc.c
index b72a1a9..d7ab47d 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -865,7 +865,7 @@  static void load_linux(void *fw_cfg,
     	initrd_max = max_ram_size-ACPI_DATA_SIZE-1;
 
     /* kernel command line */
-    rom_add_blob_fixed("linux-cmdline", kernel_cmdline,
+    rom_add_blob_fixed("cmdline", kernel_cmdline,
                        strlen(kernel_cmdline)+1, cmdline_addr);
 
     if (protocol >= 0x202) {
diff --git a/hw/petalogix_s3adsp1800_mmu.c b/hw/petalogix_s3adsp1800_mmu.c
index f343dbf..93ce87f 100644
--- a/hw/petalogix_s3adsp1800_mmu.c
+++ b/hw/petalogix_s3adsp1800_mmu.c
@@ -176,7 +176,7 @@  petalogix_s3adsp1800_init(ram_addr_t ram_size,
 
         env->regs[5] = ddr_base + kernel_size;
         if (kernel_cmdline && (kcmdline_len = strlen(kernel_cmdline))) {
-            pstrcpy_targphys(env->regs[5], 256, kernel_cmdline);
+            pstrcpy_targphys("cmdline", env->regs[5], 256, kernel_cmdline);
         }
         env->regs[6] = 0;
         /* Provide a device-tree.  */
diff --git a/hw/ppc.c b/hw/ppc.c
index 09ee2e4..2502e21 100644
--- a/hw/ppc.c
+++ b/hw/ppc.c
@@ -1256,7 +1256,7 @@  int PPC_NVRAM_set_params (nvram_t *nvram, uint16_t NVRAM_size,
     NVRAM_set_lword(nvram,  0x3C, kernel_size);
     if (cmdline) {
         /* XXX: put the cmdline in NVRAM too ? */
-        pstrcpy_targphys(CMDLINE_ADDR, RAM_size - CMDLINE_ADDR, cmdline);
+        pstrcpy_targphys("cmdline", CMDLINE_ADDR, RAM_size - CMDLINE_ADDR, cmdline);
         NVRAM_set_lword(nvram,  0x40, CMDLINE_ADDR);
         NVRAM_set_lword(nvram,  0x44, strlen(cmdline));
     } else {
diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c
index d1a82bf..d9f45b5 100644
--- a/hw/ppc_newworld.c
+++ b/hw/ppc_newworld.c
@@ -364,7 +364,7 @@  static void ppc_core99_init (ram_addr_t ram_size,
     fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
     if (kernel_cmdline) {
         fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, CMDLINE_ADDR);
-        pstrcpy_targphys(CMDLINE_ADDR, TARGET_PAGE_SIZE, kernel_cmdline);
+        pstrcpy_targphys("cmdline", CMDLINE_ADDR, TARGET_PAGE_SIZE, kernel_cmdline);
     } else {
         fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);
     }
diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c
index 79f17e8..3f23713 100644
--- a/hw/ppc_oldworld.c
+++ b/hw/ppc_oldworld.c
@@ -384,7 +384,7 @@  static void ppc_heathrow_init (ram_addr_t ram_size,
     fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
     if (kernel_cmdline) {
         fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, CMDLINE_ADDR);
-        pstrcpy_targphys(CMDLINE_ADDR, TARGET_PAGE_SIZE, kernel_cmdline);
+        pstrcpy_targphys("cmdline", CMDLINE_ADDR, TARGET_PAGE_SIZE, kernel_cmdline);
     } else {
         fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);
     }
diff --git a/hw/r2d.c b/hw/r2d.c
index f8a5968..c074a6e 100644
--- a/hw/r2d.c
+++ b/hw/r2d.c
@@ -250,7 +250,7 @@  static void r2d_init(ram_addr_t ram_size,
 				   SDRAM_BASE + LINUX_LOAD_OFFSET,
 				   SDRAM_SIZE - LINUX_LOAD_OFFSET);
           env->pc = (SDRAM_BASE + LINUX_LOAD_OFFSET) | 0xa0000000;
-          pstrcpy_targphys(SDRAM_BASE + 0x10100, 256, kernel_cmdline);
+          pstrcpy_targphys("cmdline", SDRAM_BASE + 0x10100, 256, kernel_cmdline);
       } else {
           kernel_size = load_image_targphys(kernel_filename, SDRAM_BASE, SDRAM_SIZE);
           env->pc = SDRAM_BASE | 0xa0000000; /* Start from P2 area */
diff --git a/hw/sun4m.c b/hw/sun4m.c
index 01c7cb4..144bec1 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -299,6 +299,7 @@  static unsigned long sun4m_load_kernel(const char *kernel_filename,
     int linux_boot;
     unsigned int i;
     long initrd_size, kernel_size;
+    uint8_t *ptr;
 
     linux_boot = (kernel_filename != NULL);
 
@@ -341,9 +342,10 @@  static unsigned long sun4m_load_kernel(const char *kernel_filename,
         }
         if (initrd_size > 0) {
             for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) {
-                if (ldl_phys(KERNEL_LOAD_ADDR + i) == 0x48647253) { // HdrS
-                    stl_phys(KERNEL_LOAD_ADDR + i + 16, INITRD_LOAD_ADDR);
-                    stl_phys(KERNEL_LOAD_ADDR + i + 20, initrd_size);
+                ptr = rom_ptr(KERNEL_LOAD_ADDR + i);
+                if (ldl_p(ptr) == 0x48647253) { // HdrS
+                    stl_p(ptr + 16, INITRD_LOAD_ADDR);
+                    stl_p(ptr + 20, initrd_size);
                     break;
                 }
             }
@@ -875,7 +877,7 @@  static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size,
     fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
     if (kernel_cmdline) {
         fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, CMDLINE_ADDR);
-        pstrcpy_targphys(CMDLINE_ADDR, TARGET_PAGE_SIZE, kernel_cmdline);
+        pstrcpy_targphys("cmdline", CMDLINE_ADDR, TARGET_PAGE_SIZE, kernel_cmdline);
     } else {
         fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);
     }
@@ -1457,7 +1459,7 @@  static void sun4d_hw_init(const struct sun4d_hwdef *hwdef, ram_addr_t RAM_size,
     fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
     if (kernel_cmdline) {
         fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, CMDLINE_ADDR);
-        pstrcpy_targphys(CMDLINE_ADDR, TARGET_PAGE_SIZE, kernel_cmdline);
+        pstrcpy_targphys("cmdline", CMDLINE_ADDR, TARGET_PAGE_SIZE, kernel_cmdline);
     } else {
         fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);
     }
@@ -1645,7 +1647,7 @@  static void sun4c_hw_init(const struct sun4c_hwdef *hwdef, ram_addr_t RAM_size,
     fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
     if (kernel_cmdline) {
         fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, CMDLINE_ADDR);
-        pstrcpy_targphys(CMDLINE_ADDR, TARGET_PAGE_SIZE, kernel_cmdline);
+        pstrcpy_targphys("cmdline", CMDLINE_ADDR, TARGET_PAGE_SIZE, kernel_cmdline);
     } else {
         fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);
     }
diff --git a/hw/sun4u.c b/hw/sun4u.c
index 58d708a..30f5138 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -651,7 +651,7 @@  static void sun4uv_init(ram_addr_t RAM_size,
     fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
     if (kernel_cmdline) {
         fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, CMDLINE_ADDR);
-        pstrcpy_targphys(CMDLINE_ADDR, TARGET_PAGE_SIZE, kernel_cmdline);
+        pstrcpy_targphys("cmdline", CMDLINE_ADDR, TARGET_PAGE_SIZE, kernel_cmdline);
     } else {
         fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);
     }