Adds SM501 usb host emulation feature.
[qemu] / hw / r2d.c
index 88853e7..950576c 100644 (file)
--- a/hw/r2d.c
+++ b/hw/r2d.c
@@ -37,6 +37,9 @@
 
 #define SM501_VRAM_SIZE 0x800000
 
+/* CONFIG_BOOT_LINK_OFFSET of Linux kernel */
+#define LINUX_LOAD_OFFSET 0x800000
+
 #define PA_IRLMSK      0x00
 #define PA_POWOFF      0x30
 #define PA_VERREG      0x32
@@ -170,8 +173,6 @@ static qemu_irq *r2d_fpga_init(target_phys_addr_t base, qemu_irq irl)
     r2d_fpga_t *s;
 
     s = qemu_mallocz(sizeof(r2d_fpga_t));
-    if (!s)
-        return NULL;
 
     s->irl = irl;
 
@@ -193,13 +194,13 @@ static int r2d_pci_map_irq(PCIDevice *d, int irq_num)
 }
 
 static void r2d_init(ram_addr_t ram_size, int vga_ram_size,
-              const char *boot_device, DisplayState * ds,
+              const char *boot_device,
              const char *kernel_filename, const char *kernel_cmdline,
              const char *initrd_filename, const char *cpu_model)
 {
     CPUState *env;
     struct SH7750State *s;
-    ram_addr_t sdram_addr, sm501_vga_ram_addr;
+    ram_addr_t sdram_addr;
     qemu_irq *irq;
     PCIBus *pci;
     int i;
@@ -221,36 +222,39 @@ static void r2d_init(ram_addr_t ram_size, int vga_ram_size,
     irq = r2d_fpga_init(0x04000000, sh7750_irl(s));
     pci = sh_pci_register_bus(r2d_pci_set_irq, r2d_pci_map_irq, irq, 0, 4);
 
-    sm501_vga_ram_addr = qemu_ram_alloc(SM501_VRAM_SIZE);
-    sm501_init(ds, 0x10000000, sm501_vga_ram_addr, SM501_VRAM_SIZE,
-              serial_hds[2]);
+    sm501_init(0x10000000, SM501_VRAM_SIZE, irq[SM501], serial_hds[2]);
 
     /* onboard CF (True IDE mode, Master only). */
-    mmio_ide_init(0x14001000, 0x1400080c, irq[CF_IDE], 1,
-        drives_table[drive_get_index(IF_IDE, 0, 0)].bdrv, NULL);
+    if ((i = drive_get_index(IF_IDE, 0, 0)) != -1)
+       mmio_ide_init(0x14001000, 0x1400080c, irq[CF_IDE], 1,
+                     drives_table[i].bdrv, NULL);
 
     /* NIC: rtl8139 on-board, and 2 slots. */
-    pci_nic_init(pci, &nd_table[0], 2 << 3, "rtl8139");
-    for (i = 1; i < nb_nics; i++)
-        pci_nic_init(pci, &nd_table[i], -1, "ne2k_pci");
+    for (i = 0; i < nb_nics; i++)
+        pci_nic_init(pci, &nd_table[i], (i==0)? 2<<3: -1, "rtl8139");
 
     /* Todo: register on board registers */
-    {
+    if (kernel_filename) {
       int kernel_size;
       /* initialization which should be done by firmware */
-      uint32_t bcr1 = 1 << 3; /* cs3 SDRAM */
-      uint16_t bcr2 = 3 << (3 * 2); /* cs3 32-bit */
-      cpu_physical_memory_write(SH7750_BCR1_A7, (uint8_t *)&bcr1, 4);
-      cpu_physical_memory_write(SH7750_BCR2_A7, (uint8_t *)&bcr2, 2);
-
-      kernel_size = load_image(kernel_filename, phys_ram_base);
+      stl_phys(SH7750_BCR1, 1<<3); /* cs3 SDRAM */
+      stw_phys(SH7750_BCR2, 3<<(3*2)); /* cs3 32bit */
+
+      if (kernel_cmdline) {
+          kernel_size = load_image_targphys(kernel_filename,
+                                  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);
+      } else {
+          kernel_size = load_image_targphys(kernel_filename, SDRAM_BASE, SDRAM_SIZE);
+          env->pc = SDRAM_BASE | 0xa0000000; /* Start from P2 area */
+      }
 
       if (kernel_size < 0) {
         fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename);
         exit(1);
       }
-
-      env->pc = SDRAM_BASE | 0xa0000000; /* Start from P2 area */
     }
 }
 
@@ -258,5 +262,4 @@ QEMUMachine r2d_machine = {
     .name = "r2d",
     .desc = "r2d-plus board",
     .init = r2d_init,
-    .ram_require = (SDRAM_SIZE + SM501_VRAM_SIZE) | RAMSIZE_FIXED,
 };