From 8b042182626b94ed6380f0ba6b99c0e862aa710f Mon Sep 17 00:00:00 2001
From: Benjamin Nash <benash@umich.edu>
Date: Mon, 27 Jun 2005 18:08:42 -0400
Subject: Change IDE disk and ethernet device to work better with FreeBSD.

dev/ide_ctrl.cc:
dev/ide_disk.cc:
dev/ide_disk.hh:
    Add support for 32-bit accesses.
dev/ns_gige.cc:
    Change default configuration register value to work with FreeBSD driver.

--HG--
extra : convert_revision : c9dd125338a97ffa8cd95293e6b7877068652387
---
 dev/ide_disk.cc | 122 +++++++++++++++++++++++++++++++++++++-------------------
 1 file changed, 82 insertions(+), 40 deletions(-)

(limited to 'dev/ide_disk.cc')

diff --git a/dev/ide_disk.cc b/dev/ide_disk.cc
index ae394c69e..555eb023e 100644
--- a/dev/ide_disk.cc
+++ b/dev/ide_disk.cc
@@ -208,46 +208,61 @@ IdeDisk::bytesInDmaPage(Addr curAddr, uint32_t bytesLeft)
 // Device registers read/write
 ////
 
-void
-IdeDisk::read(const Addr &offset, bool byte, bool cmdBlk, uint8_t *data)
+uint16_t
+IdeDisk::read(const Addr &offset, RegType_t type)
 {
-    DevAction_t action = ACT_NONE;
 
-    if (cmdBlk) {
-        if (offset < 0 || offset > sizeof(CommandReg_t))
-            panic("Invalid disk command register offset: %#x\n", offset);
+    uint16_t data;
+    DevAction_t action = ACT_NONE;
 
-        if (!byte && offset != DATA_OFFSET)
-            panic("Invalid 16-bit read, only allowed on data reg\n");
+    if (type == COMMAND_BLOCK) {
 
-        if (!byte)
-            *(uint16_t *)data = *(uint16_t *)&cmdReg.data0;
-        else
-            *data = ((uint8_t *)&cmdReg)[offset];
-
-        // determine if an action needs to be taken on the state machine
-        if (offset == STATUS_OFFSET) {
+        if (offset == STATUS_OFFSET)
             action = ACT_STAT_READ;
-            *data = status; // status is in a shadow, explicity copy
-        } else if (offset == DATA_OFFSET) {
-            if (byte)
-                action = ACT_DATA_READ_BYTE;
-            else
-                action = ACT_DATA_READ_SHORT;
-        }
-
-    } else {
+        else if (offset == DATA_OFFSET)
+            action = ACT_DATA_READ_SHORT;
+
+            switch (offset) {
+              case DATA_OFFSET:
+                data = cmdReg.data;
+                break;
+              case ERROR_OFFSET:
+                data = cmdReg.error;
+                break;
+              case NSECTOR_OFFSET:
+                data = cmdReg.sec_count;
+                break;
+              case SECTOR_OFFSET:
+                data = cmdReg.sec_num;
+                break;
+              case LCYL_OFFSET:
+                data = cmdReg.cyl_low;
+                break;
+              case HCYL_OFFSET:
+                data = cmdReg.cyl_high;
+                break;
+              case SELECT_OFFSET:
+                data = cmdReg.drive;
+                break;
+              case STATUS_OFFSET:
+                data = status;
+                break;
+              default:
+                panic("Invalid IDE command register offset: %#x\n", offset);
+            }
+    }
+    else if (type == CONTROL_BLOCK) {
         if (offset != ALTSTAT_OFFSET)
-            panic("Invalid disk control register offset: %#x\n", offset);
-
-        if (!byte)
-            panic("Invalid 16-bit read from control block\n");
+            panic("Invalid IDE control register offset: %#x\n", offset);
 
-        *data = status;
+        data = status;
     }
 
     if (action != ACT_NONE)
         updateState(action);
+
+    return data;
+
 }
 
 void
@@ -263,9 +278,37 @@ IdeDisk::write(const Addr &offset, bool byte, bool cmdBlk, const uint8_t *data)
             panic("Invalid 16-bit write, only allowed on data reg\n");
 
         if (!byte)
-            *((uint16_t *)&cmdReg.data0) = *(uint16_t *)data;
-        else
-            ((uint8_t *)&cmdReg)[offset] = *data;
+            *((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) {
@@ -746,9 +789,10 @@ IdeDisk::intrPost()
     intrPending = true;
 
     // talk to controller to set interrupt
-    if (ctrl)
+    if (ctrl){
         ctrl->bmi_regs[BMIS0] |= IDEINTS;
         ctrl->intrPost();
+    }
 }
 
 void
@@ -867,7 +911,7 @@ IdeDisk::updateState(DevAction_t action)
             }
 
             // put the first two bytes into the data register
-            memcpy((void *)&cmdReg.data0, (void *)dataBuffer,
+            memcpy((void *)&cmdReg.data, (void *)dataBuffer,
                    sizeof(uint16_t));
 
             if (!isIENSet()) {
@@ -896,7 +940,7 @@ IdeDisk::updateState(DevAction_t action)
 
                 // copy next short into data registers
                 if (drqBytesLeft)
-                    memcpy((void *)&cmdReg.data0,
+                    memcpy((void *)&cmdReg.data,
                            (void *)&dataBuffer[SectorSize - drqBytesLeft],
                            sizeof(uint16_t));
             }
@@ -969,7 +1013,7 @@ IdeDisk::updateState(DevAction_t action)
             } else {
                 // copy the latest short into the data buffer
                 memcpy((void *)&dataBuffer[SectorSize - drqBytesLeft],
-                       (void *)&cmdReg.data0,
+                       (void *)&cmdReg.data,
                        sizeof(uint16_t));
 
                 drqBytesLeft -= 2;
@@ -1093,8 +1137,7 @@ IdeDisk::serialize(ostream &os)
     SERIALIZE_ENUM(event);
 
     // Serialize device registers
-    SERIALIZE_SCALAR(cmdReg.data0);
-    SERIALIZE_SCALAR(cmdReg.data1);
+    SERIALIZE_SCALAR(cmdReg.data);
     SERIALIZE_SCALAR(cmdReg.sec_count);
     SERIALIZE_SCALAR(cmdReg.sec_num);
     SERIALIZE_SCALAR(cmdReg.cyl_low);
@@ -1146,8 +1189,7 @@ IdeDisk::unserialize(Checkpoint *cp, const string &section)
     }
 
     // Unserialize device registers
-    UNSERIALIZE_SCALAR(cmdReg.data0);
-    UNSERIALIZE_SCALAR(cmdReg.data1);
+    UNSERIALIZE_SCALAR(cmdReg.data);
     UNSERIALIZE_SCALAR(cmdReg.sec_count);
     UNSERIALIZE_SCALAR(cmdReg.sec_num);
     UNSERIALIZE_SCALAR(cmdReg.cyl_low);
-- 
cgit v1.2.3