]> git.proxmox.com Git - qemu.git/blobdiff - hw/omap_gpmc.c
exec: move include files to include/exec/
[qemu.git] / hw / omap_gpmc.c
index 02f0c521071b1ffdc8bf87916a58e3e0732a503e..02ab0ab568627583dc67944463a96e949102ce5d 100644 (file)
@@ -21,8 +21,8 @@
 #include "hw.h"
 #include "flash.h"
 #include "omap.h"
-#include "memory.h"
-#include "exec-memory.h"
+#include "exec/memory.h"
+#include "exec/address-spaces.h"
 
 /* General-Purpose Memory Controller */
 struct omap_gpmc_s {
@@ -121,7 +121,7 @@ static void omap_gpmc_dma_update(struct omap_gpmc_s *s, int value)
  * all addresses in the region behave like accesses to the relevant
  * GPMC_NAND_DATA_i register (which is actually implemented to call these)
  */
-static uint64_t omap_nand_read(void *opaque, target_phys_addr_t addr,
+static uint64_t omap_nand_read(void *opaque, hwaddr addr,
                                unsigned size)
 {
     struct omap_gpmc_cs_file_s *f = (struct omap_gpmc_cs_file_s *)opaque;
@@ -180,6 +180,7 @@ static void omap_nand_setio(DeviceState *dev, uint64_t value,
             nand_setio(dev, (value >> 24) & 0xff);
             break;
         }
+        break;
     case OMAP_GPMC_16BIT:
         switch (size) {
         case 1:
@@ -195,10 +196,11 @@ static void omap_nand_setio(DeviceState *dev, uint64_t value,
             nand_setio(dev, (value >> 16) & 0xffff);
             break;
         }
+        break;
     }
 }
 
-static void omap_nand_write(void *opaque, target_phys_addr_t addr,
+static void omap_nand_write(void *opaque, hwaddr addr,
                             uint64_t value, unsigned size)
 {
     struct omap_gpmc_cs_file_s *f = (struct omap_gpmc_cs_file_s *)opaque;
@@ -279,7 +281,7 @@ static void fill_prefetch_fifo(struct omap_gpmc_s *s)
  * engine is enabled -- all addresses in the region behave alike:
  * data is read or written to the FIFO.
  */
-static uint64_t omap_gpmc_prefetch_read(void *opaque, target_phys_addr_t addr,
+static uint64_t omap_gpmc_prefetch_read(void *opaque, hwaddr addr,
                                         unsigned size)
 {
     struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
@@ -309,7 +311,7 @@ static uint64_t omap_gpmc_prefetch_read(void *opaque, target_phys_addr_t addr,
     return data;
 }
 
-static void omap_gpmc_prefetch_write(void *opaque, target_phys_addr_t addr,
+static void omap_gpmc_prefetch_write(void *opaque, hwaddr addr,
                                      uint64_t value, unsigned size)
 {
     struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
@@ -441,6 +443,12 @@ void omap_gpmc_reset(struct omap_gpmc_s *s)
     s->irqst = 0;
     s->irqen = 0;
     omap_gpmc_int_update(s);
+    for (i = 0; i < 8; i++) {
+        /* This has to happen before we change any of the config
+         * used to determine which memory regions are mapped or unmapped.
+         */
+        omap_gpmc_cs_unmap(s, i);
+    }
     s->timeout = 0;
     s->config = 0xa00;
     s->prefetch.config1 = 0x00004000;
@@ -449,7 +457,6 @@ void omap_gpmc_reset(struct omap_gpmc_s *s)
     s->prefetch.fifopointer = 0;
     s->prefetch.count = 0;
     for (i = 0; i < 8; i ++) {
-        omap_gpmc_cs_unmap(s, i);
         s->cs_file[i].config[1] = 0x101001;
         s->cs_file[i].config[2] = 0x020201;
         s->cs_file[i].config[3] = 0x10031003;
@@ -477,7 +484,7 @@ void omap_gpmc_reset(struct omap_gpmc_s *s)
         ecc_reset(&s->ecc[i]);
 }
 
-static int gpmc_wordaccess_only(target_phys_addr_t addr)
+static int gpmc_wordaccess_only(hwaddr addr)
 {
     /* Return true if the register offset is to a register that
      * only permits word width accesses.
@@ -495,7 +502,7 @@ static int gpmc_wordaccess_only(target_phys_addr_t addr)
     return 1;
 }
 
-static uint64_t omap_gpmc_read(void *opaque, target_phys_addr_t addr,
+static uint64_t omap_gpmc_read(void *opaque, hwaddr addr,
                                unsigned size)
 {
     struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
@@ -569,6 +576,13 @@ static uint64_t omap_gpmc_read(void *opaque, target_phys_addr_t addr,
     case 0x1ec:        /* GPMC_PREFETCH_CONTROL */
         return s->prefetch.startengine;
     case 0x1f0:        /* GPMC_PREFETCH_STATUS */
+        /* NB: The OMAP3 TRM is inconsistent about whether the GPMC
+         * FIFOTHRESHOLDSTATUS bit should be set when
+         * FIFOPOINTER > FIFOTHRESHOLD or when it is >= FIFOTHRESHOLD.
+         * Apparently the underlying functional spec from which the TRM was
+         * created states that the behaviour is ">=", and this also
+         * makes more conceptual sense.
+         */
         return (s->prefetch.fifopointer << 24) |
                 ((s->prefetch.fifopointer >=
                   ((s->prefetch.config1 >> 8) & 0x7f) ? 1 : 0) << 16) |
@@ -600,7 +614,7 @@ static uint64_t omap_gpmc_read(void *opaque, target_phys_addr_t addr,
     return 0;
 }
 
-static void omap_gpmc_write(void *opaque, target_phys_addr_t addr,
+static void omap_gpmc_write(void *opaque, hwaddr addr,
                             uint64_t value, unsigned size)
 {
     struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
@@ -632,7 +646,7 @@ static void omap_gpmc_write(void *opaque, target_phys_addr_t addr,
         break;
 
     case 0x018:        /* GPMC_IRQSTATUS */
-        s->irqen &= ~value;
+        s->irqst &= ~value;
         omap_gpmc_int_update(s);
         break;
 
@@ -707,24 +721,31 @@ static void omap_gpmc_write(void *opaque, target_phys_addr_t addr,
 
     case 0x1e0:        /* GPMC_PREFETCH_CONFIG1 */
         if (!s->prefetch.startengine) {
-            uint32_t oldconfig1 = s->prefetch.config1;
+            uint32_t newconfig1 = value & 0x7f8f7fbf;
             uint32_t changed;
-            s->prefetch.config1 = value & 0x7f8f7fbf;
-            changed = oldconfig1 ^ s->prefetch.config1;
+            changed = newconfig1 ^ s->prefetch.config1;
             if (changed & (0x80 | 0x7000000)) {
                 /* Turning the engine on or off, or mapping it somewhere else.
                  * cs_map() and cs_unmap() check the prefetch config and
                  * overall CSVALID bits, so it is sufficient to unmap-and-map
-                 * both the old cs and the new one.
+                 * both the old cs and the new one. Note that we adhere to
+                 * the "unmap/change config/map" order (and not unmap twice
+                 * if newcs == oldcs), otherwise we'll try to delete the wrong
+                 * memory region.
                  */
-                int oldcs = prefetch_cs(oldconfig1);
-                int newcs = prefetch_cs(s->prefetch.config1);
+                int oldcs = prefetch_cs(s->prefetch.config1);
+                int newcs = prefetch_cs(newconfig1);
                 omap_gpmc_cs_unmap(s, oldcs);
-                omap_gpmc_cs_map(s, oldcs);
-                if (newcs != oldcs) {
+                if (oldcs != newcs) {
                     omap_gpmc_cs_unmap(s, newcs);
+                }
+                s->prefetch.config1 = newconfig1;
+                omap_gpmc_cs_map(s, oldcs);
+                if (oldcs != newcs) {
                     omap_gpmc_cs_map(s, newcs);
                 }
+            } else {
+                s->prefetch.config1 = newconfig1;
             }
         }
         break;
@@ -798,7 +819,7 @@ static const MemoryRegionOps omap_gpmc_ops = {
 };
 
 struct omap_gpmc_s *omap_gpmc_init(struct omap_mpu_state_s *mpu,
-                                   target_phys_addr_t base,
+                                   hwaddr base,
                                    qemu_irq irq, qemu_irq drq)
 {
     int cs;