Merge gblack@m5.eecs.umich.edu:/bk/multiarch
[gem5.git] / dev / ide_ctrl.cc
index 6ad80e69d0eb00a341f3f2bf63f68816e06dc0c1..18c988b81d7a1eb3426faac6129a8756777a2d6c 100644 (file)
@@ -48,6 +48,7 @@
 #include "sim/sim_object.hh"
 
 using namespace std;
+using namespace TheISA;
 
 ////
 // Initialization and destruction
@@ -90,21 +91,24 @@ IdeController::IdeController(Params *p)
     bm_enabled = false;
     memset(cmd_in_progress, 0, sizeof(cmd_in_progress));
 
+    pioInterface = NULL;
+    dmaInterface = NULL;
     // create the PIO and DMA interfaces
-    if (params()->host_bus) {
-        pioInterface = newPioInterface(name(), params()->hier,
-                                       params()->host_bus, this,
+    if (params()->pio_bus) {
+        pioInterface = newPioInterface(name() + ".pio", params()->hier,
+                                       params()->pio_bus, this,
                                        &IdeController::cacheAccess);
+        pioLatency = params()->pio_latency * params()->pio_bus->clockRate;
+    }
 
+    if (params()->dma_bus) {
         dmaInterface = new DMAInterface<Bus>(name() + ".dma",
-                                             params()->host_bus,
-                                             params()->host_bus, 1,
-                                             true);
-        pioLatency = params()->pio_latency * params()->host_bus->clockRate;
+                                             params()->dma_bus,
+                                             params()->dma_bus, 1, true);
     }
 
     // setup the disks attached to controller
-    memset(disks, 0, sizeof(IdeDisk *) * 4);
+    memset(disks, 0, sizeof(disks));
     dev[0] = 0;
     dev[1] = 0;
 
@@ -299,8 +303,10 @@ IdeController::writeConfig(int offset, int size, const uint8_t *data)
         switch(size) {
           case sizeof(uint8_t):
             config_regs.data[config_offset] = *data;
+            break;
           case sizeof(uint16_t):
             *(uint16_t*)&config_regs.data[config_offset] = *(uint16_t*)data;
+            break;
           case sizeof(uint32_t):
             *(uint32_t*)&config_regs.data[config_offset] = *(uint32_t*)data;
             break;
@@ -385,7 +391,7 @@ IdeController::writeConfig(int offset, int size, const uint8_t *data)
     }
 }
 
-Fault
+Fault *
 IdeController::read(MemReqPtr &req, uint8_t *data)
 {
     Addr offset;
@@ -396,7 +402,7 @@ IdeController::read(MemReqPtr &req, uint8_t *data)
     parseAddr(req->paddr, offset, channel, reg_type);
 
     if (!io_enabled)
-        return No_Fault;
+        return NoFault;
 
     switch (reg_type) {
       case BMI_BLOCK:
@@ -452,10 +458,10 @@ IdeController::read(MemReqPtr &req, uint8_t *data)
     DPRINTF(IdeCtrl, "read from offset: %#x size: %#x data: %#x\n",
             offset, req->size, *(uint32_t*)data);
 
-    return No_Fault;
+    return NoFault;
 }
 
-Fault
+Fault *
 IdeController::write(MemReqPtr &req, const uint8_t *data)
 {
     Addr offset;
@@ -467,12 +473,12 @@ IdeController::write(MemReqPtr &req, const uint8_t *data)
     parseAddr(req->paddr, offset, channel, reg_type);
 
     if (!io_enabled)
-        return No_Fault;
+        return NoFault;
 
     switch (reg_type) {
       case BMI_BLOCK:
         if (!bm_enabled)
-            return No_Fault;
+            return NoFault;
 
         switch (offset) {
             // Bus master IDE command register
@@ -484,8 +490,8 @@ IdeController::write(MemReqPtr &req, const uint8_t *data)
             // select the current disk based on DEV bit
             disk = getDisk(channel);
 
-            oldVal = letoh(bmi_regs.chan[channel].bmic);
-            newVal = letoh(*data);
+            oldVal = bmi_regs.chan[channel].bmic;
+            newVal = *data;
 
             // if a DMA transfer is in progress, R/W control cannot change
             if (oldVal & SSBM) {
@@ -501,8 +507,8 @@ IdeController::write(MemReqPtr &req, const uint8_t *data)
                     DPRINTF(IdeCtrl, "Stopping DMA transfer\n");
 
                     // clear the BMIDEA bit
-                    bmi_regs.chan[channel].bmis = letoh(
-                        letoh(bmi_regs.chan[channel].bmis) & ~BMIDEA);
+                    bmi_regs.chan[channel].bmis =
+                        bmi_regs.chan[channel].bmis & ~BMIDEA;
 
                     if (disks[disk] == NULL)
                         panic("DMA stop for disk %d which does not exist\n",
@@ -515,8 +521,8 @@ IdeController::write(MemReqPtr &req, const uint8_t *data)
                     DPRINTF(IdeCtrl, "Starting DMA transfer\n");
 
                     // set the BMIDEA bit
-                    bmi_regs.chan[channel].bmis = letoh(
-                        letoh(bmi_regs.chan[channel].bmis) | BMIDEA);
+                    bmi_regs.chan[channel].bmis =
+                        bmi_regs.chan[channel].bmis | BMIDEA;
 
                     if (disks[disk] == NULL)
                         panic("DMA start for disk %d which does not exist\n",
@@ -528,7 +534,7 @@ IdeController::write(MemReqPtr &req, const uint8_t *data)
             }
 
             // update the register value
-            bmi_regs.chan[channel].bmic = letoh(newVal);
+            bmi_regs.chan[channel].bmic = newVal;
             break;
 
             // Bus master IDE status register
@@ -537,8 +543,8 @@ IdeController::write(MemReqPtr &req, const uint8_t *data)
             if (req->size != sizeof(uint8_t))
                 panic("Invalid BMIS write size: %x\n", req->size);
 
-            oldVal = letoh(bmi_regs.chan[channel].bmis);
-            newVal = letoh(*data);
+            oldVal = bmi_regs.chan[channel].bmis;
+            newVal = *data;
 
             // the BMIDEA bit is RO
             newVal |= (oldVal & BMIDEA);
@@ -554,17 +560,20 @@ IdeController::write(MemReqPtr &req, const uint8_t *data)
             else
                 (oldVal & IDEDMAE) ? newVal |= IDEDMAE : newVal &= ~IDEDMAE;
 
-            bmi_regs.chan[channel].bmis = letoh(newVal);
+            bmi_regs.chan[channel].bmis = newVal;
             break;
 
             // Bus master IDE descriptor table pointer register
           case BMIDTP0:
           case BMIDTP1:
-            if (req->size != sizeof(uint32_t))
-                panic("Invalid BMIDTP write size: %x\n", req->size);
+            {
+                if (req->size != sizeof(uint32_t))
+                    panic("Invalid BMIDTP write size: %x\n", req->size);
 
-            bmi_regs.chan[channel].bmidtp = letoh(
-                letoh(*(uint32_t*)data) & ~0x3);
+                uint32_t host_data =  letoh(*(uint32_t*)data);
+                host_data &= ~0x3;
+                bmi_regs.chan[channel].bmidtp = htole(host_data);
+            }
             break;
 
           default:
@@ -619,7 +628,7 @@ IdeController::write(MemReqPtr &req, const uint8_t *data)
     DPRINTF(IdeCtrl, "write to offset: %#x size: %#x data: %#x\n",
             offset, req->size, *(uint32_t*)data);
 
-    return No_Fault;
+    return NoFault;
 }
 
 ////
@@ -645,14 +654,17 @@ IdeController::serialize(std::ostream &os)
     SERIALIZE_SCALAR(bmi_size);
 
     // Serialize registers
-    SERIALIZE_ARRAY(bmi_regs.data, sizeof(bmi_regs));
-    SERIALIZE_ARRAY(dev, sizeof(dev));
-    SERIALIZE_ARRAY(config_regs.data, sizeof(config_regs));
+    SERIALIZE_ARRAY(bmi_regs.data,
+                    sizeof(bmi_regs.data) / sizeof(bmi_regs.data[0]));
+    SERIALIZE_ARRAY(dev, sizeof(dev) / sizeof(dev[0]));
+    SERIALIZE_ARRAY(config_regs.data,
+                    sizeof(config_regs.data) / sizeof(config_regs.data[0]));
 
     // Serialize internal state
     SERIALIZE_SCALAR(io_enabled);
     SERIALIZE_SCALAR(bm_enabled);
-    SERIALIZE_ARRAY(cmd_in_progress, sizeof(cmd_in_progress));
+    SERIALIZE_ARRAY(cmd_in_progress,
+                    sizeof(cmd_in_progress) / sizeof(cmd_in_progress[0]));
 }
 
 void
@@ -674,14 +686,17 @@ IdeController::unserialize(Checkpoint *cp, const std::string &section)
     UNSERIALIZE_SCALAR(bmi_size);
 
     // Unserialize registers
-    UNSERIALIZE_ARRAY(bmi_regs.data, sizeof(bmi_regs));
-    UNSERIALIZE_ARRAY(dev, sizeof(dev));
-    UNSERIALIZE_ARRAY(config_regs.data, sizeof(config_regs));
+    UNSERIALIZE_ARRAY(bmi_regs.data,
+                      sizeof(bmi_regs.data) / sizeof(bmi_regs.data[0]));
+    UNSERIALIZE_ARRAY(dev, sizeof(dev) / sizeof(dev[0]));
+    UNSERIALIZE_ARRAY(config_regs.data,
+                      sizeof(config_regs.data) / sizeof(config_regs.data[0]));
 
     // Unserialize internal state
     UNSERIALIZE_SCALAR(io_enabled);
     UNSERIALIZE_SCALAR(bm_enabled);
-    UNSERIALIZE_ARRAY(cmd_in_progress, sizeof(cmd_in_progress));
+    UNSERIALIZE_ARRAY(cmd_in_progress,
+                      sizeof(cmd_in_progress) / sizeof(cmd_in_progress[0]));
 
     if (pioInterface) {
         pioInterface->addAddrRange(RangeSize(pri_cmd_addr, pri_cmd_size));
@@ -705,7 +720,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(IdeController)
     Param<uint32_t> pci_bus;
     Param<uint32_t> pci_dev;
     Param<uint32_t> pci_func;
-    SimObjectParam<Bus *> io_bus;
+    SimObjectParam<Bus *> pio_bus;
+    SimObjectParam<Bus *> dma_bus;
     Param<Tick> pio_latency;
     SimObjectParam<HierParams *> hier;
 
@@ -722,7 +738,8 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(IdeController)
     INIT_PARAM(pci_bus, "PCI bus ID"),
     INIT_PARAM(pci_dev, "PCI device number"),
     INIT_PARAM(pci_func, "PCI function code"),
-    INIT_PARAM_DFLT(io_bus, "Host bus to attach to", NULL),
+    INIT_PARAM(pio_bus, ""),
+    INIT_PARAM(dma_bus, ""),
     INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1),
     INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams)
 
@@ -741,7 +758,8 @@ CREATE_SIM_OBJECT(IdeController)
     params->functionNum = pci_func;
 
     params->disks = disks;
-    params->host_bus = io_bus;
+    params->pio_bus = pio_bus;
+    params->dma_bus = dma_bus;
     params->pio_latency = pio_latency;
     params->hier = hier;
     return new IdeController(params);