.
authorMiguel Serrano <mserrano@umich.edu>
Thu, 28 Jul 2005 15:49:01 +0000 (11:49 -0400)
committerMiguel Serrano <mserrano@umich.edu>
Thu, 28 Jul 2005 15:49:01 +0000 (11:49 -0400)
SConscript:
    add pcifake
dev/ide_ctrl.cc:
dev/ide_ctrl.hh:
dev/ide_disk.cc:
dev/ide_disk.hh:
    endianess
dev/tsunami_io.cc:
    rtc, date/time

--HG--
extra : convert_revision : 21ad27c780749cb6f6eef2b57798c0c292c3f14d

SConscript
dev/ide_ctrl.cc
dev/ide_ctrl.hh
dev/ide_disk.cc
dev/ide_disk.hh
dev/tsunami_io.cc

index 7b309fbfe554c372838800cfea7c698f538013e1..736135386dd0777a391c1c7784243e6110fc4a2d 100644 (file)
@@ -265,6 +265,7 @@ full_system_sources = Split('''
        dev/ns_gige.cc
        dev/pciconfigall.cc
        dev/pcidev.cc
+        dev/pcifake.cc
        dev/pktfifo.cc
         dev/platform.cc
        dev/sinic.cc
index 6636a5ff61f0d15b2f1cd27976c8538204994852..2c86d27c795cacce2eba8443a3062c3cc6c52a51 100644 (file)
@@ -75,13 +75,13 @@ IdeController::IdeController(Params *p)
     bmi_size = BARSize[4];
 
     // zero out all of the registers
-    memset(bmi_regs, 0, sizeof(bmi_regs));
+    memset(bmi_regs.data, 0, sizeof(bmi_regs));
     memset(pci_config_regs.data, 0, sizeof(pci_config_regs.data));
 
     // setup initial values
     pci_config_regs.idetim = htoa((uint32_t)0x80008000); // enable both channels
-    *(uint8_t *)&bmi_regs[BMIS0] = 0x60;
-    *(uint8_t *)&bmi_regs[BMIS1] = 0x60;
+    bmi_regs.bmis0 = DMA1CAP | DMA0CAP;
+    bmi_regs.bmis1 = DMA1CAP | DMA0CAP;
 
     // reset all internal variables
     io_enabled = false;
@@ -218,18 +218,18 @@ IdeController::setDmaComplete(IdeDisk *disk)
 
     if (diskNum < 2) {
         // clear the start/stop bit in the command register
-        bmi_regs[BMIC0] &= ~SSBM;
+        bmi_regs.bmic0 &= ~SSBM;
         // clear the bus master active bit in the status register
-        bmi_regs[BMIS0] &= ~BMIDEA;
+        bmi_regs.bmis0 &= ~BMIDEA;
         // set the interrupt bit
-        bmi_regs[BMIS0] |= IDEINTS;
+        bmi_regs.bmis0 |= IDEINTS;
     } else {
         // clear the start/stop bit in the command register
-        bmi_regs[BMIC1] &= ~SSBM;
+        bmi_regs.bmic1 &= ~SSBM;
         // clear the bus master active bit in the status register
-        bmi_regs[BMIS1] &= ~BMIDEA;
+        bmi_regs.bmis1 &= ~BMIDEA;
         // set the interrupt bit
-        bmi_regs[BMIS1] |= IDEINTS;
+        bmi_regs.bmis1 |= IDEINTS;
     }
 }
 
@@ -251,74 +251,78 @@ IdeController::cacheAccess(MemReqPtr &req)
 void
 IdeController::ReadConfig(int offset, int size, uint8_t *data)
 {
-    int config_offset;
+    union {
+        uint8_t byte;
+        uint16_t word;
+        uint32_t dword;
+    };
 
-#if TRACING_ON
-    Addr origOffset = offset;
-#endif
+    int config_offset;
 
     if (offset < PCI_DEVICE_SPECIFIC) {
         PciDev::ReadConfig(offset, size, data);
-    } else if (offset >= IDE_CTRL_CONFIG_START && (offset + size) <= IDE_CTRL_CONFIG_END) {
+    } else if (offset >= IDE_CTRL_CONFIG_START &&
+               (offset + size) <= IDE_CTRL_CONFIG_END) {
 
         config_offset = offset - IDE_CTRL_CONFIG_START;
+        dword = 0;
 
-        switch(size) {
-          case sizeof(uint32_t):
-            memcpy(data, &pci_config_regs.data[config_offset], sizeof(uint32_t));
-            *(uint32_t*)data = htoa(*(uint32_t*)data);
+        switch (size) {
+          case sizeof(uint8_t):
+            memcpy(&byte, &pci_config_regs.data[config_offset], size);
+            *data = byte;
             break;
-
           case sizeof(uint16_t):
-            memcpy(data, &pci_config_regs.data[config_offset], sizeof(uint16_t));
-            *(uint16_t*)data = htoa(*(uint16_t*)data);
+            memcpy(&byte, &pci_config_regs.data[config_offset], size);
+            *(uint16_t*)data = htoa(word);
             break;
-
-          case sizeof(uint8_t):
-            memcpy(data, &pci_config_regs.data[config_offset], sizeof(uint8_t));
+          case sizeof(uint32_t):
+            memcpy(&byte, &pci_config_regs.data[config_offset], size);
+            *(uint32_t*)data = htoa(dword);
             break;
-
           default:
             panic("Invalid PCI configuration read size!\n");
         }
+
+        DPRINTF(IdeCtrl, "PCI read offset: %#x size: %#x data: %#x\n",
+                offset, size, htoa(dword));
+
     } else {
         panic("Read of unimplemented PCI config. register: %x\n", offset);
     }
-
-    DPRINTF(IdeCtrl, "PCI read offset: %#x (%#x) size: %#x data: %#x\n",
-            origOffset, offset, size,
-            *(uint32_t *)data & (0xffffffff >> 8 * (4 - size)));
 }
 
 void
 IdeController::WriteConfig(int offset, int size, uint32_t data)
 {
     int config_offset;
+    uint32_t write_data;
 
     if (offset < PCI_DEVICE_SPECIFIC) {
         PciDev::WriteConfig(offset, size, data);
-    } else if (offset >= IDE_CTRL_CONFIG_START && (offset + size) <= IDE_CTRL_CONFIG_END) {
+    } else if (offset >= IDE_CTRL_CONFIG_START &&
+               (offset + size) <= IDE_CTRL_CONFIG_END) {
 
         config_offset = offset - IDE_CTRL_CONFIG_START;
 
+        write_data = htoa(data);
+
         switch(size) {
-          case sizeof(uint32_t):
-          case sizeof(uint16_t):
           case sizeof(uint8_t):
-            memcpy(&pci_config_regs.data[config_offset], &data, size);
+          case sizeof(uint16_t):
+          case sizeof(uint32_t):
+            memcpy(&pci_config_regs.data[config_offset], &write_data, size);
             break;
 
           default:
             panic("Invalid PCI configuration write size!\n");
         }
-
     } else {
         panic("Write of unimplemented PCI config. register: %x\n", offset);
     }
 
     DPRINTF(IdeCtrl, "PCI write offset: %#x size: %#x data: %#x\n",
-            offset, size, data & (0xffffffff >> 8 * (4 - size)));
-
+            offset, size, data);
 
     // Catch the writes to specific PCI registers that have side affects
     // (like updating the PIO ranges)
@@ -399,42 +403,89 @@ IdeController::read(MemReqPtr &req, uint8_t *data)
     RegType_t type;
     int disk;
 
+    /*   union
+     *   +--  --+--  --+--  --+--  --+
+     *   |  0   |  1   |  2   |  3   |
+     *   +--  --+--  --+--  --+--  --+
+     *   | byte |  ..  |  ..  |  ..  |
+     *   +--  --+--  --+--  --+--  --+
+     *   |    word0    |    word1    |
+     *   +--         --+--         --+
+     *   |           dword           |
+     *   +--                       --+
+     */
+    union {
+        uint8_t byte;
+        uint16_t word[2];
+        uint32_t dword;
+    };
+
+    dword = 0;
+
     parseAddr(req->paddr, offset, primary, type);
 
     if (!io_enabled)
         return No_Fault;
 
-    // sanity check the size (allows byte, word, or dword access)
-    switch (req->size) {
-      case sizeof(uint8_t):
-      case sizeof(uint16_t):
-      case sizeof(uint32_t):
+    switch (type) {
+      case BMI_BLOCK:
+        switch (req->size) {
+          case sizeof(uint8_t):
+            memcpy(&byte, &bmi_regs.data[offset], sizeof(uint8_t));
+            *data = byte;
+            break;
+          case sizeof(uint16_t):
+            memcpy(&byte, &bmi_regs.data[offset], sizeof(uint16_t));
+            *(uint16_t*)data = htoa(word[0]);
+            break;
+          case sizeof(uint32_t):
+            memcpy(&byte, &bmi_regs.data[offset], sizeof(uint32_t));
+            *(uint32_t*)data = htoa(dword);
+            break;
+          default:
+            panic("IDE read of BMI reg invalid size: %#x\n", req->size);
+        }
         break;
-      default:
-        panic("IDE controller read of invalid size: %#x\n", req->size);
-    }
-
-    if (type != BMI_BLOCK) {
 
+      case COMMAND_BLOCK:
+      case CONTROL_BLOCK:
         disk = getDisk(primary);
-        if (disks[disk])
-            if (req->size == sizeof(uint32_t) && offset == DATA_OFFSET) {
-                ((uint16_t*)data)[0] = disks[disk]->read(offset, type);
-                ((uint16_t*)data)[1] = disks[disk]->read(offset, type);
-            }
-            else if (req->size == sizeof(uint8_t) && offset == DATA_OFFSET) {
+
+        if (disks[disk] == NULL)
+            break;
+
+        switch (offset) {
+          case DATA_OFFSET:
+            switch (req->size) {
+              case sizeof(uint16_t):
+                disks[disk]->read(offset, type, (uint8_t*)&word[0]);
+                *(uint16_t*)data = htoa(word[0]);
+                break;
+
+              case sizeof(uint32_t):
+                disks[disk]->read(offset, type, (uint8_t*)&word[0]);
+                disks[disk]->read(offset, type, (uint8_t*)&word[1]);
+                *(uint32_t*)data = htoa(dword);
+                break;
+
+              default:
                 panic("IDE read of data reg invalid size: %#x\n", req->size);
             }
-            else {
-                *data = disks[disk]->read(offset, type);
-            }
-    } else {
-        memcpy((void *)data, &bmi_regs[offset], req->size);
+            break;
+          default:
+            if (req->size == sizeof(uint8_t)) {
+                disks[disk]->read(offset, type, &byte);
+                *data = byte;
+            } else
+                panic("IDE read of command reg of invalid size: %#x\n", req->size);
+        }
+        break;
+      default:
+        panic("IDE controller read of unknown register block type!\n");
     }
 
     DPRINTF(IdeCtrl, "read from offset: %#x size: %#x data: %#x\n",
-            offset, req->size,
-            (*(uint32_t *)data) & (0xffffffff >> 8 * (4 - req->size)));
+            offset, req->size, htoa(dword));
 
     return No_Fault;
 }
@@ -444,40 +495,29 @@ IdeController::write(MemReqPtr &req, const uint8_t *data)
 {
     Addr offset;
     bool primary;
-    bool byte;
-    bool cmdBlk;
     RegType_t type;
     int disk;
 
-    parseAddr(req->paddr, offset, primary, type);
-    byte = (req->size == sizeof(uint8_t)) ? true : false;
-    cmdBlk = (type == COMMAND_BLOCK) ? true : false;
+    union {
+        uint8_t byte;
+        uint16_t word[2];
+        uint32_t dword;
+    };
 
-    DPRINTF(IdeCtrl, "write from offset: %#x size: %#x data: %#x\n",
-            offset, req->size,
-            (*(uint32_t *)data) & (0xffffffff >> 8 * (4 - req->size)));
+    dword = 0;
+
+    parseAddr(req->paddr, offset, primary, type);
 
     uint8_t oldVal, newVal;
 
     if (!io_enabled)
         return No_Fault;
 
-    if (type == BMI_BLOCK && !bm_enabled)
-        return No_Fault;
+    switch (type) {
+      case BMI_BLOCK:
+        if (!bm_enabled)
+            return No_Fault;
 
-    if (type != BMI_BLOCK) {
-        // shadow the dev bit
-        if (type == COMMAND_BLOCK && offset == IDE_SELECT_OFFSET) {
-            uint8_t *devBit = (primary ? &dev[0] : &dev[1]);
-            *devBit = ((*data & IDE_SELECT_DEV_BIT) ? 1 : 0);
-        }
-
-        assert(req->size != sizeof(uint32_t));
-
-        disk = getDisk(primary);
-        if (disks[disk])
-            disks[disk]->write(offset, byte, cmdBlk, data);
-    } else {
         switch (offset) {
             // Bus master IDE command register
           case BMIC1:
@@ -488,8 +528,9 @@ IdeController::write(MemReqPtr &req, const uint8_t *data)
             // select the current disk based on DEV bit
             disk = getDisk(primary);
 
-            oldVal = bmi_regs[offset];
-            newVal = *data;
+            oldVal = bmi_regs.data[offset];
+            byte = *data;
+            newVal = byte;
 
             // if a DMA transfer is in progress, R/W control cannot change
             if (oldVal & SSBM) {
@@ -505,7 +546,7 @@ IdeController::write(MemReqPtr &req, const uint8_t *data)
                     DPRINTF(IdeCtrl, "Stopping DMA transfer\n");
 
                     // clear the BMIDEA bit
-                    bmi_regs[offset + 0x2] &= ~BMIDEA;
+                    bmi_regs.data[offset + 0x2] &= ~BMIDEA;
 
                     if (disks[disk] == NULL)
                         panic("DMA stop for disk %d which does not exist\n",
@@ -518,7 +559,7 @@ IdeController::write(MemReqPtr &req, const uint8_t *data)
                     DPRINTF(IdeCtrl, "Starting DMA transfer\n");
 
                     // set the BMIDEA bit
-                    bmi_regs[offset + 0x2] |= BMIDEA;
+                    bmi_regs.data[offset + 0x2] |= BMIDEA;
 
                     if (disks[disk] == NULL)
                         panic("DMA start for disk %d which does not exist\n",
@@ -526,14 +567,14 @@ IdeController::write(MemReqPtr &req, const uint8_t *data)
 
                     // inform the disk of the DMA transfer start
                     if (primary)
-                        disks[disk]->startDma(*(uint32_t *)&bmi_regs[BMIDTP0]);
+                        disks[disk]->startDma(bmi_regs.bmidtp0);
                     else
-                        disks[disk]->startDma(*(uint32_t *)&bmi_regs[BMIDTP1]);
+                        disks[disk]->startDma(bmi_regs.bmidtp1);
                 }
             }
 
             // update the register value
-            bmi_regs[offset] = newVal;
+            bmi_regs.data[offset] = newVal;
             break;
 
             // Bus master IDE status register
@@ -542,8 +583,9 @@ IdeController::write(MemReqPtr &req, const uint8_t *data)
             if (req->size != sizeof(uint8_t))
                 panic("Invalid BMIS write size: %x\n", req->size);
 
-            oldVal = bmi_regs[offset];
-            newVal = *data;
+            oldVal = bmi_regs.data[offset];
+            byte = *data;
+            newVal = byte;
 
             // the BMIDEA bit is RO
             newVal |= (oldVal & BMIDEA);
@@ -559,7 +601,7 @@ IdeController::write(MemReqPtr &req, const uint8_t *data)
             else
                 (oldVal & IDEDMAE) ? newVal |= IDEDMAE : newVal &= ~IDEDMAE;
 
-            bmi_regs[offset] = newVal;
+            bmi_regs.data[offset] = newVal;
             break;
 
             // Bus master IDE descriptor table pointer register
@@ -568,7 +610,8 @@ IdeController::write(MemReqPtr &req, const uint8_t *data)
             if (req->size != sizeof(uint32_t))
                 panic("Invalid BMIDTP write size: %x\n", req->size);
 
-            *(uint32_t *)&bmi_regs[offset] = *(uint32_t *)data & ~0x3;
+            dword = htoa(*(uint32_t *)data & ~0x3);
+            *(uint32_t *)&bmi_regs.data[offset] = dword;
             break;
 
           default:
@@ -579,10 +622,53 @@ IdeController::write(MemReqPtr &req, const uint8_t *data)
                       req->size);
 
             // do a default copy of data into the registers
-            memcpy((void *)&bmi_regs[offset], data, req->size);
+            memcpy((void *)&bmi_regs.data[offset], data, req->size);
+        }
+        break;
+      case COMMAND_BLOCK:
+        if (offset == IDE_SELECT_OFFSET) {
+            uint8_t *devBit = (primary ? &dev[0] : &dev[1]);
+            *devBit = ((*data & IDE_SELECT_DEV_BIT) ? 1 : 0);
         }
+        // fall-through ok!
+      case CONTROL_BLOCK:
+        disk = getDisk(primary);
+
+        if (disks[disk] == NULL)
+            break;
+
+        switch (offset) {
+          case DATA_OFFSET:
+            switch (req->size) {
+              case sizeof(uint16_t):
+                word[0] = htoa(*(uint16_t*)data);
+                disks[disk]->write(offset, type, (uint8_t*)&word[0]);
+                break;
+
+              case sizeof(uint32_t):
+                dword = htoa(*(uint32_t*)data);
+                disks[disk]->write(offset, type, (uint8_t*)&word[0]);
+                disks[disk]->write(offset, type, (uint8_t*)&word[1]);
+                break;
+              default:
+                panic("IDE write of data reg invalid size: %#x\n", req->size);
+            }
+            break;
+          default:
+            if (req->size == sizeof(uint8_t)) {
+                byte = *data;
+                disks[disk]->write(offset, type, &byte);
+            } else
+                panic("IDE write of command reg of invalid size: %#x\n", req->size);
+        }
+        break;
+      default:
+        panic("IDE controller write of unknown register block type!\n");
     }
 
+    DPRINTF(IdeCtrl, "write to offset: %#x size: %#x data: %#x\n",
+            offset, req->size, dword);
+
     return No_Fault;
 }
 
@@ -609,14 +695,14 @@ IdeController::serialize(std::ostream &os)
     SERIALIZE_SCALAR(bmi_size);
 
     // Serialize registers
-    SERIALIZE_ARRAY(bmi_regs, 16);
-    SERIALIZE_ARRAY(dev, 2);
-    SERIALIZE_ARRAY(pci_config_regs.data, 22);
+    SERIALIZE_ARRAY(bmi_regs.data, sizeof(bmi_regs));
+    SERIALIZE_ARRAY(dev, sizeof(dev));
+    SERIALIZE_ARRAY(pci_config_regs.data, sizeof(pci_config_regs));
 
     // Serialize internal state
     SERIALIZE_SCALAR(io_enabled);
     SERIALIZE_SCALAR(bm_enabled);
-    SERIALIZE_ARRAY(cmd_in_progress, 4);
+    SERIALIZE_ARRAY(cmd_in_progress, sizeof(cmd_in_progress));
 }
 
 void
@@ -638,14 +724,14 @@ IdeController::unserialize(Checkpoint *cp, const std::string &section)
     UNSERIALIZE_SCALAR(bmi_size);
 
     // Unserialize registers
-    UNSERIALIZE_ARRAY(bmi_regs, 16);
-    UNSERIALIZE_ARRAY(dev, 2);
-    UNSERIALIZE_ARRAY(pci_config_regs.data, 22);
+    UNSERIALIZE_ARRAY(bmi_regs.data, sizeof(bmi_regs));
+    UNSERIALIZE_ARRAY(dev, sizeof(dev));
+    UNSERIALIZE_ARRAY(pci_config_regs.data, sizeof(pci_config_regs));
 
     // Unserialize internal state
     UNSERIALIZE_SCALAR(io_enabled);
     UNSERIALIZE_SCALAR(bm_enabled);
-    UNSERIALIZE_ARRAY(cmd_in_progress, 4);
+    UNSERIALIZE_ARRAY(cmd_in_progress, sizeof(cmd_in_progress));
 
     if (pioInterface) {
         pioInterface->addAddrRange(RangeSize(pri_cmd_addr, pri_cmd_size));
index 2164f2f4a112e481ea9adc4a5944bf0aa12fdbdc..51bdd93b1c1125931651fa7beafa03b6b9471273 100644 (file)
@@ -110,7 +110,22 @@ class IdeController : public PciDev
 
   private:
     /** Registers used for bus master interface */
-    uint8_t bmi_regs[16];
+    union {
+        uint8_t data[16];
+
+        struct {
+            uint8_t bmic0;
+            uint8_t padding_0;
+            uint8_t bmis0;
+            uint8_t padding_1;
+            uint32_t bmidtp0;
+            uint8_t bmic1;
+            uint8_t padding_2;
+            uint8_t bmis1;
+            uint8_t padding_3;
+            uint32_t bmidtp1;
+        };
+    } bmi_regs;
     /** Shadows of the device select bit */
     uint8_t dev[2];
     /** Registers used in device specific PCI configuration */
index 0d553fb83045d2022ea518f27a5a8aa15d7171ad..39eb2e698a14635a5c9c507bb8d6c6d7984a109c 100644 (file)
@@ -116,6 +116,9 @@ IdeDisk::IdeDisk(const string &name, DiskImage *img, PhysicalMemory *phys,
     driveID.atap_udmamode_supp = 0x10;
     // Statically set hardware config word
     driveID.atap_hwreset_res = 0x4001;
+
+    //arbitrary for now...
+    driveID.atap_ata_major = WDC_VER_ATA7;
 }
 
 IdeDisk::~IdeDisk()
@@ -134,8 +137,6 @@ IdeDisk::reset(int id)
     memset(&cmdReg, 0, sizeof(CommandReg_t));
     memset(&curPrd.entry, 0, sizeof(PrdEntry_t));
 
-    cmdReg.error = 1;
-
     dmaInterfaceBytes = 0;
     curPrdAddr = 0;
     curSector = 0;
@@ -160,6 +161,8 @@ IdeDisk::reset(int id)
 
     // set the device ready bit
     status = STATUS_DRDY_BIT;
+
+    cmdReg.error = 0x1;
 }
 
 ////
@@ -208,134 +211,113 @@ IdeDisk::bytesInDmaPage(Addr curAddr, uint32_t bytesLeft)
 // Device registers read/write
 ////
 
-uint16_t
-IdeDisk::read(const Addr &offset, RegType_t type)
+void
+IdeDisk::read(const Addr &offset, RegType_t type, uint8_t *data)
 {
-    uint16_t data = 0;
     DevAction_t action = ACT_NONE;
 
-    if (type == COMMAND_BLOCK) {
-
-        if (offset == STATUS_OFFSET)
-            action = ACT_STAT_READ;
-        else if (offset == DATA_OFFSET)
-            action = ACT_DATA_READ_SHORT;
-
+    switch (type) {
+      case COMMAND_BLOCK:
         switch (offset) {
+          // Data transfers occur two bytes at a time
           case DATA_OFFSET:
-            data = cmdReg.data;
+            memcpy(data, &cmdReg.data, sizeof(uint16_t));
+            action = ACT_DATA_READ_SHORT;
             break;
           case ERROR_OFFSET:
-            data = cmdReg.error;
+            *data = cmdReg.error;
             break;
           case NSECTOR_OFFSET:
-            data = cmdReg.sec_count;
+            *data = cmdReg.sec_count;
             break;
           case SECTOR_OFFSET:
-            data = cmdReg.sec_num;
+            *data = cmdReg.sec_num;
             break;
           case LCYL_OFFSET:
-            data = cmdReg.cyl_low;
+            *data = cmdReg.cyl_low;
             break;
           case HCYL_OFFSET:
-            data = cmdReg.cyl_high;
+            *data = cmdReg.cyl_high;
             break;
-          case SELECT_OFFSET:
-            data = cmdReg.drive;
+          case DRIVE_OFFSET:
+            *data = cmdReg.drive;
             break;
           case STATUS_OFFSET:
-            data = status;
+            *data = status;
+            action = ACT_STAT_READ;
             break;
           default:
             panic("Invalid IDE command register offset: %#x\n", offset);
         }
-    }
-    else if (type == CONTROL_BLOCK) {
-        if (offset != ALTSTAT_OFFSET)
+        break;
+      case CONTROL_BLOCK:
+        if (offset == ALTSTAT_OFFSET)
+            *data = status;
+        else
             panic("Invalid IDE control register offset: %#x\n", offset);
-
-        data = status;
+        break;
+      default:
+        panic("Unknown register block!\n");
     }
 
     if (action != ACT_NONE)
         updateState(action);
-
-    return data;
 }
 
 void
-IdeDisk::write(const Addr &offset, bool byte, bool cmdBlk, const uint8_t *data)
+IdeDisk::write(const Addr &offset, RegType_t type, const uint8_t *data)
 {
     DevAction_t action = ACT_NONE;
 
-    if (cmdBlk) {
-        if (offset < 0 || offset > sizeof(CommandReg_t))
-            panic("Invalid disk command register offset: %#x\n", offset);
-
-        if (!byte && offset != DATA_OFFSET)
-            panic("Invalid 16-bit write, only allowed on data reg\n");
-
-        if (!byte)
-            *((uint16_t *)&cmdReg.data) = *(uint16_t *)data;
-        else {
-            switch (offset) {
-              case DATA_OFFSET:
-                cmdReg.data = *data;
-                break;
-              case FEATURES_OFFSET:
-                cmdReg.features = *data;
-                break;
-              case NSECTOR_OFFSET:
-                cmdReg.sec_count = *data;
-                break;
-              case SECTOR_OFFSET:
-                cmdReg.sec_num = *data;
-                break;
-              case LCYL_OFFSET:
-                cmdReg.cyl_low = *data;
-                break;
-              case HCYL_OFFSET:
-                cmdReg.cyl_high = *data;
-                break;
-              case SELECT_OFFSET:
-                cmdReg.drive = *data;
-                break;
-              case COMMAND_OFFSET:
-                cmdReg.command = *data;
-                break;
-              default:
-                panic("Invalid IDE command register offset: %#x\n", offset);
-            }
-        }
-
-        // determine if an action needs to be taken on the state machine
-        if (offset == COMMAND_OFFSET) {
-            action = ACT_CMD_WRITE;
-        } else if (offset == DATA_OFFSET) {
-            if (byte)
-                action = ACT_DATA_WRITE_BYTE;
-            else
-                action = ACT_DATA_WRITE_SHORT;
-        } else if (offset == SELECT_OFFSET) {
+    switch (type) {
+      case COMMAND_BLOCK:
+        switch (offset) {
+          case DATA_OFFSET:
+            memcpy(&cmdReg.data, data, sizeof(uint16_t));
+            action = ACT_DATA_WRITE_SHORT;
+            break;
+          case FEATURES_OFFSET:
+            break;
+          case NSECTOR_OFFSET:
+            cmdReg.sec_count = *data;
+            break;
+          case SECTOR_OFFSET:
+            cmdReg.sec_num = *data;
+            break;
+          case LCYL_OFFSET:
+            cmdReg.cyl_low = *data;
+            break;
+          case HCYL_OFFSET:
+            cmdReg.cyl_high = *data;
+            break;
+          case DRIVE_OFFSET:
+            cmdReg.drive = *data;
             action = ACT_SELECT_WRITE;
+            break;
+          case COMMAND_OFFSET:
+            cmdReg.command = *data;
+            action = ACT_CMD_WRITE;
+            break;
+          default:
+            panic("Invalid IDE command register offset: %#x\n", offset);
         }
-
-    } else {
-        if (offset != CONTROL_OFFSET)
-            panic("Invalid disk control register offset: %#x\n", offset);
-
-        if (!byte)
-            panic("Invalid 16-bit write to control block\n");
-
-        if (*data & CONTROL_RST_BIT) {
-            // force the device into the reset state
-            devState = Device_Srst;
-            action = ACT_SRST_SET;
-        } else if (devState == Device_Srst && !(*data & CONTROL_RST_BIT)) {
-            action = ACT_SRST_CLEAR;
+        break;
+      case CONTROL_BLOCK:
+        if (offset == CONTROL_OFFSET) {
+            if (*data & CONTROL_RST_BIT) {
+                // force the device into the reset state
+                devState = Device_Srst;
+                action = ACT_SRST_SET;
+            } else if (devState == Device_Srst && !(*data & CONTROL_RST_BIT))
+                action = ACT_SRST_CLEAR;
+
+            nIENBit = (*data & CONTROL_IEN_BIT) ? true : false;
         }
-
-        nIENBit = (*data & CONTROL_IEN_BIT) ? true : false;
+        else
+            panic("Invalid IDE control register offset: %#x\n", offset);
+        break;
+      default:
+        panic("Unknown register block!\n");
     }
 
     if (action != ACT_NONE)
@@ -787,8 +769,8 @@ IdeDisk::intrPost()
     intrPending = true;
 
     // talk to controller to set interrupt
-    if (ctrl){
-        ctrl->bmi_regs[BMIS0] |= IDEINTS;
+    if (ctrl) {
+        ctrl->bmi_regs.bmis0 |= IDEINTS;
         ctrl->intrPost();
     }
 }
index 0fcd863ecea9055fbe38db299cdf5f2f894b6514..ceec119255d8ac3b555e75aa1a2bd1c38302cb40 100644 (file)
@@ -84,6 +84,7 @@ class PrdTableEntry {
 #define LCYL_OFFSET     (4)
 #define HCYL_OFFSET     (5)
 #define SELECT_OFFSET   (6)
+#define DRIVE_OFFSET    (6)
 #define STATUS_OFFSET   (7)
 #define COMMAND_OFFSET  (7)
 
@@ -105,10 +106,7 @@ class PrdTableEntry {
 
 typedef struct CommandReg {
     uint16_t data;
-    union {
-        uint8_t error;
-        uint8_t features;
-    };
+    uint8_t error;
     uint8_t sec_count;
     uint8_t sec_num;
     uint8_t cyl_low;
@@ -272,8 +270,8 @@ class IdeDisk : public SimObject
     }
 
     // Device register read/write
-    uint16_t read(const Addr &offset, RegType_t type);
-    void write(const Addr &offset, bool byte, bool cmdBlk, const uint8_t *data);
+    void read(const Addr &offset, RegType_t type, uint8_t *data);
+    void write(const Addr &offset, RegType_t type, const uint8_t *data);
 
     // Start/abort functions
     void startDma(const uint32_t &prdTableBase);
index 3aef9b0518ff05a781963663ca1cccf4fbb519a4..f9dcbb8e0a93d423d77648bc9c20088aae20ecd4 100644 (file)
@@ -329,7 +329,7 @@ TsunamiIO::read(MemReqPtr &req, uint8_t *data)
                 *(uint8_t *)data = tm.tm_wday + 1;
                 return No_Fault;
               case RTC_DOM:
-                *(uint8_t *)data = tm.tm_mday + 1;
+                *(uint8_t *)data = tm.tm_mday;
                 return No_Fault;
               case RTC_MON:
                 *(uint8_t *)data = tm.tm_mon + 1;
@@ -340,15 +340,6 @@ TsunamiIO::read(MemReqPtr &req, uint8_t *data)
               default:
                 panic("Unknown RTC Address\n");
             }
-
-          /* Added for keyboard reads */
-          case TSDEV_KBD:
-            *(uint8_t *)data = 0x00;
-            return No_Fault;
-          /* Added for ATA PCI DMA */
-          case ATA_PCI_DMA:
-            *(uint8_t *)data = 0x00;
-            return No_Fault;
           default:
             panic("I/O Read - va%#x size %d\n", req->vaddr, req->size);
         }
@@ -542,7 +533,6 @@ TsunamiIO::write(MemReqPtr &req, const uint8_t *data)
               case RTC_YEAR:
                 tm.tm_year = *(uint8_t *)data;
                 return No_Fault;
-            //panic("RTC Write not implmented (rtc.o won't work)\n");
             }
           default:
             panic("I/O Write - va%#x size %d\n", req->vaddr, req->size);