]> git.proxmox.com Git - qemu.git/blobdiff - hw/stellaris.c
Use correct types to enable > 2G support, based on a patch from
[qemu.git] / hw / stellaris.c
index 01ed374a8c79a74d86024a8f83c8e62fcc6df272..a32f86fe90e87f5a5a058f20af5ae35e83a653b1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Luminary Micro Stellaris preipherals
+ * Luminary Micro Stellaris peripherals
  *
  * Copyright (c) 2006 CodeSourcery.
  * Written by Paul Brook
@@ -14,6 +14,7 @@
 #include "qemu-timer.h"
 #include "i2c.h"
 #include "net.h"
+#include "sd.h"
 #include "sysemu.h"
 #include "boards.h"
 
@@ -1000,6 +1001,51 @@ static qemu_irq stellaris_adc_init(uint32_t base, qemu_irq irq)
     return qi[0];
 }
 
+/* Some boards have both an OLED controller and SD card connected to
+   the same SSI port, with the SD card chip select connected to a
+   GPIO pin.  Technically the OLED chip select is connected to the SSI
+   Fss pin.  We do not bother emulating that as both devices should
+   never be selected simultaneously, and our OLED controller ignores stray
+   0xff commands that occur when deselecting the SD card.  */
+
+typedef struct {
+    ssi_xfer_cb xfer_cb[2];
+    void *opaque[2];
+    qemu_irq irq;
+    int current_dev;
+} stellaris_ssi_bus_state;
+
+static void stellaris_ssi_bus_select(void *opaque, int irq, int level)
+{
+    stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque;
+
+    s->current_dev = level;
+}
+
+static int stellaris_ssi_bus_xfer(void *opaque, int val)
+{
+    stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque;
+
+    return s->xfer_cb[s->current_dev](s->opaque[s->current_dev], val);
+}
+
+static void *stellaris_ssi_bus_init(qemu_irq *irqp,
+                                    ssi_xfer_cb cb0, void *opaque0,
+                                    ssi_xfer_cb cb1, void *opaque1)
+{
+    qemu_irq *qi;
+    stellaris_ssi_bus_state *s;
+
+    s = (stellaris_ssi_bus_state *)qemu_mallocz(sizeof(stellaris_ssi_bus_state));
+    s->xfer_cb[0] = cb0;
+    s->opaque[0] = opaque0;
+    s->xfer_cb[1] = cb1;
+    s->opaque[1] = opaque1;
+    qi = qemu_allocate_irqs(stellaris_ssi_bus_select, s, 1);
+    *irqp = *qi;
+    return s;
+}
+
 /* Board init.  */
 static stellaris_board_info stellaris_boards[] = {
   { "LM3S811EVB",
@@ -1085,9 +1131,21 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
     if (board->dc2 & (1 << 4)) {
         if (board->peripherals & BP_OLED_SSI) {
             void * oled;
-            /* FIXME: Implement chip select for OLED/MMC.  */
+            void * sd;
+            void *ssi_bus;
+            int index;
+
             oled = ssd0323_init(ds, &gpio_out[GPIO_C][7]);
-            pl022_init(0x40008000, pic[7], ssd0323_xfer_ssi, oled);
+            index = drive_get_index(IF_SD, 0, 0);
+            sd = ssi_sd_init(drives_table[index].bdrv);
+
+            ssi_bus = stellaris_ssi_bus_init(&gpio_out[GPIO_D][0],
+                                             ssi_sd_xfer, sd,
+                                             ssd0323_xfer_ssi, oled);
+
+            pl022_init(0x40008000, pic[7], stellaris_ssi_bus_xfer, ssi_bus);
+            /* Make sure the select pin is high.  */
+            qemu_irq_raise(gpio_out[GPIO_D][0]);
         } else {
             pl022_init(0x40008000, pic[7], NULL, NULL);
         }
@@ -1111,7 +1169,7 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
 }
 
 /* FIXME: Figure out how to generate these from stellaris_boards.  */
-static void lm3s811evb_init(int ram_size, int vga_ram_size,
+static void lm3s811evb_init(ram_addr_t ram_size, int vga_ram_size,
                      const char *boot_device, DisplayState *ds,
                      const char *kernel_filename, const char *kernel_cmdline,
                      const char *initrd_filename, const char *cpu_model)
@@ -1119,7 +1177,7 @@ static void lm3s811evb_init(int ram_size, int vga_ram_size,
     stellaris_init(kernel_filename, cpu_model, ds, &stellaris_boards[0]);
 }
 
-static void lm3s6965evb_init(int ram_size, int vga_ram_size,
+static void lm3s6965evb_init(ram_addr_t ram_size, int vga_ram_size,
                      const char *boot_device, DisplayState *ds,
                      const char *kernel_filename, const char *kernel_cmdline,
                      const char *initrd_filename, const char *cpu_model)
@@ -1131,10 +1189,12 @@ QEMUMachine lm3s811evb_machine = {
     "lm3s811evb",
     "Stellaris LM3S811EVB",
     lm3s811evb_init,
+    (64 * 1024 + 8 * 1024) | RAMSIZE_FIXED,
 };
 
 QEMUMachine lm3s6965evb_machine = {
     "lm3s6965evb",
     "Stellaris LM3S6965EVB",
     lm3s6965evb_init,
+    (256 * 1024 + 64 * 1024) | RAMSIZE_FIXED,
 };