.
authorMiguel Serrano <mserrano@umich.edu>
Fri, 1 Jul 2005 19:10:18 +0000 (15:10 -0400)
committerMiguel Serrano <mserrano@umich.edu>
Fri, 1 Jul 2005 19:10:18 +0000 (15:10 -0400)
--HG--
extra : convert_revision : 1ed206b27498641b64d7f35c74ea1f0623398d4e

dev/ide_ctrl.cc
dev/ide_ctrl.hh
dev/ide_disk.cc
dev/pcidev.cc
dev/tsunami_io.cc
dev/tsunami_io.hh
kern/freebsd/freebsd_system.cc

index 964bd01c2d51c60c31c10e0ae4005d3c3df424dd..5e5f534a826facafb7c2535e6f9125a00c985d15 100644 (file)
@@ -76,10 +76,10 @@ IdeController::IdeController(Params *p)
 
     // zero out all of the registers
     memset(bmi_regs, 0, sizeof(bmi_regs));
-    memset(pci_regs, 0, sizeof(pci_regs));
+    memset(pci_config_regs.data, 0, sizeof(pci_config_regs.data));
 
     // setup initial values
-    *(uint32_t *)&pci_regs[IDETIM] = 0x80008000; // enable both channels
+    pci_config_regs.idetim = htoa((uint32_t)0x80008000); // enable both channels
     *(uint8_t *)&bmi_regs[BMIS0] = 0x60;
     *(uint8_t *)&bmi_regs[BMIS1] = 0x60;
 
@@ -249,6 +249,7 @@ IdeController::cacheAccess(MemReqPtr &req)
 void
 IdeController::ReadConfig(int offset, int size, uint8_t *data)
 {
+    int config_offset;
 
 #if TRACING_ON
     Addr origOffset = offset;
@@ -256,86 +257,67 @@ IdeController::ReadConfig(int offset, int size, uint8_t *data)
 
     if (offset < PCI_DEVICE_SPECIFIC) {
         PciDev::ReadConfig(offset, size, data);
-    } else {
-        if (offset >= PCI_IDE_TIMING && offset < (PCI_IDE_TIMING + 4)) {
-            offset -= PCI_IDE_TIMING;
-            offset += IDETIM;
-
-            if ((offset + size) > (IDETIM + 4))
-                panic("PCI read of IDETIM with invalid size\n");
-        } else if (offset == PCI_SLAVE_TIMING) {
-            offset -= PCI_SLAVE_TIMING;
-            offset += SIDETIM;
-
-            if ((offset + size) > (SIDETIM + 1))
-                panic("PCI read of SIDETIM with invalid size\n");
-        } else if (offset == PCI_UDMA33_CTRL) {
-            offset -= PCI_UDMA33_CTRL;
-            offset += UDMACTL;
-
-            if ((offset + size) > (UDMACTL + 1))
-                panic("PCI read of UDMACTL with invalid size\n");
-        } else if (offset >= PCI_UDMA33_TIMING &&
-                   offset < (PCI_UDMA33_TIMING + 2)) {
-            offset -= PCI_UDMA33_TIMING;
-            offset += UDMATIM;
-
-            if ((offset + size) > (UDMATIM + 2))
-                panic("PCI read of UDMATIM with invalid size\n");
-        } else {
-            panic("PCI read of unimplemented register: %x\n", offset);
-        }
+    } else if (offset >= IDE_CTRL_CONFIG_START && (offset + size) <= IDE_CTRL_CONFIG_END) {
+
+        config_offset = offset - IDE_CTRL_CONFIG_START;
+
+        switch(size) {
+          case sizeof(uint32_t):
+            memcpy(data, &pci_config_regs.data[config_offset], sizeof(uint32_t));
+            *(uint32_t*)data = htoa(*(uint32_t*)data);
+            break;
+
+          case sizeof(uint16_t):
+            memcpy(data, &pci_config_regs.data[config_offset], sizeof(uint16_t));
+            *(uint16_t*)data = htoa(*(uint16_t*)data);
+            break;
 
-        memcpy((void *)data, (void *)&pci_regs[offset], size);
+          case sizeof(uint8_t):
+            memcpy(data, &pci_config_regs.data[config_offset], sizeof(uint8_t));
+            break;
+
+          default:
+            panic("Invalid PCI configuration read size!\n");
+        }
+    } 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)));
+            *(uint32_t *)data & (0xffffffff >> 8 * (4 - size)));
 }
 
 void
 IdeController::WriteConfig(int offset, int size, uint32_t data)
 {
-    DPRINTF(IdeCtrl, "PCI write offset: %#x size: %#x data: %#x\n",
-            offset, size, data & (0xffffffff >> 8 * (4 - size)));
+    int config_offset;
 
-    // do standard write stuff if in standard PCI space
     if (offset < PCI_DEVICE_SPECIFIC) {
         PciDev::WriteConfig(offset, size, data);
-    } else {
-        if (offset >= PCI_IDE_TIMING && offset < (PCI_IDE_TIMING + 4)) {
-            offset -= PCI_IDE_TIMING;
-            offset += IDETIM;
-
-            if ((offset + size) > (IDETIM + 4))
-                panic("PCI write to IDETIM with invalid size\n");
-        } else if (offset == PCI_SLAVE_TIMING) {
-            offset -= PCI_SLAVE_TIMING;
-            offset += SIDETIM;
-
-            if ((offset + size) > (SIDETIM + 1))
-                panic("PCI write to SIDETIM with invalid size\n");
-        } else if (offset == PCI_UDMA33_CTRL) {
-            offset -= PCI_UDMA33_CTRL;
-            offset += UDMACTL;
-
-            if ((offset + size) > (UDMACTL + 1))
-                panic("PCI write to UDMACTL with invalid size\n");
-        } else if (offset >= PCI_UDMA33_TIMING &&
-                   offset < (PCI_UDMA33_TIMING + 2)) {
-            offset -= PCI_UDMA33_TIMING;
-            offset += UDMATIM;
-
-            if ((offset + size) > (UDMATIM + 2))
-                panic("PCI write to UDMATIM with invalid size\n");
-        } else {
-            panic("PCI write to unimplemented register: %x\n", offset);
+    } else if (offset >= IDE_CTRL_CONFIG_START && (offset + size) <= IDE_CTRL_CONFIG_END) {
+
+        config_offset = offset - IDE_CTRL_CONFIG_START;
+
+        switch(size) {
+          case sizeof(uint32_t):
+          case sizeof(uint16_t):
+          case sizeof(uint8_t):
+            memcpy(&pci_config_regs.data[config_offset], &data, size);
+            break;
+
+          default:
+            panic("Invalid PCI configuration write size!\n");
         }
 
-        memcpy((void *)&pci_regs[offset], (void *)&data, size);
+    } 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)));
+
+
     // Catch the writes to specific PCI registers that have side affects
     // (like updating the PIO ranges)
     switch (offset) {
@@ -421,17 +403,22 @@ IdeController::read(MemReqPtr &req, uint8_t *data)
         return No_Fault;
 
     // sanity check the size (allows byte, word, or dword access)
-    if (req->size != sizeof(uint8_t) && req->size != sizeof(uint16_t) &&
-        req->size != sizeof(uint32_t))
+    switch (req->size) {
+      case sizeof(uint8_t):
+      case sizeof(uint16_t):
+      case sizeof(uint32_t):
+        break;
+      default:
         panic("IDE controller read of invalid size: %#x\n", req->size);
+    }
 
     if (type != BMI_BLOCK) {
 
         disk = getDisk(primary);
         if (disks[disk])
             if (req->size == sizeof(uint32_t) && offset == DATA_OFFSET) {
-                *((uint16_t*)data) = disks[disk]->read(offset, type);
-                *((uint16_t*)data + 1) = disks[disk]->read(offset, type);
+                ((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) {
                 panic("IDE read of data reg invalid size: %#x\n", req->size);
@@ -622,7 +609,7 @@ IdeController::serialize(std::ostream &os)
     // Serialize registers
     SERIALIZE_ARRAY(bmi_regs, 16);
     SERIALIZE_ARRAY(dev, 2);
-    SERIALIZE_ARRAY(pci_regs, 8);
+    SERIALIZE_ARRAY(pci_config_regs.data, 22);
 
     // Serialize internal state
     SERIALIZE_SCALAR(io_enabled);
@@ -651,7 +638,7 @@ IdeController::unserialize(Checkpoint *cp, const std::string &section)
     // Unserialize registers
     UNSERIALIZE_ARRAY(bmi_regs, 16);
     UNSERIALIZE_ARRAY(dev, 2);
-    UNSERIALIZE_ARRAY(pci_regs, 8);
+    UNSERIALIZE_ARRAY(pci_config_regs.data, 22);
 
     // Unserialize internal state
     UNSERIALIZE_SCALAR(io_enabled);
index 4b54c3d57913309564c847f8d015b7288ad202fc..2164f2f4a112e481ea9adc4a5944bf0aa12fdbdc 100644 (file)
 #define IDE_COMMAND_OFFSET      IDE_STATUS_OFFSET
 
 // PCI device specific register byte offsets
-#define PCI_IDE_TIMING    0x40
-#define PCI_SLAVE_TIMING  0x44
-#define PCI_UDMA33_CTRL   0x48
-#define PCI_UDMA33_TIMING 0x4a
+#define IDE_CTRL_CONFIG_START 0x40
+#define IDE_CTRL_CONFIG_END ((IDE_CTRL_CONFIG_START) + sizeof(pci_config_regs))
 
-#define IDETIM  (0)
-#define SIDETIM (4)
-#define UDMACTL (5)
-#define UDMATIM (6)
 
 typedef enum RegType {
     COMMAND_BLOCK = 0,
@@ -119,8 +113,30 @@ class IdeController : public PciDev
     uint8_t bmi_regs[16];
     /** Shadows of the device select bit */
     uint8_t dev[2];
-    /** Registers used in PCI configuration */
-    uint8_t pci_regs[8];
+    /** Registers used in device specific PCI configuration */
+    union {
+        uint8_t data[22];
+
+        struct {
+            uint32_t idetim;
+            uint8_t sidetim;
+            uint8_t reserved_45;
+            uint8_t reserved_46;
+            uint8_t reserved_47;
+            uint8_t udmactl;
+            uint8_t reserved_49;
+            uint16_t udmatim;
+            uint8_t reserved_4c;
+            uint8_t reserved_4d;
+            uint8_t reserved_4e;
+            uint8_t reserved_4f;
+            uint8_t reserved_50;
+            uint8_t reserved_51;
+            uint8_t reserved_52;
+            uint8_t reserved_53;
+            uint16_t ideconfig;
+        };
+    } pci_config_regs;
 
     // Internal management variables
     bool io_enabled;
index 555eb023e93d9c0a2292e144baf5edf710372d3b..0d553fb83045d2022ea518f27a5a8aa15d7171ad 100644 (file)
@@ -211,8 +211,7 @@ IdeDisk::bytesInDmaPage(Addr curAddr, uint32_t bytesLeft)
 uint16_t
 IdeDisk::read(const Addr &offset, RegType_t type)
 {
-
-    uint16_t data;
+    uint16_t data = 0;
     DevAction_t action = ACT_NONE;
 
     if (type == COMMAND_BLOCK) {
@@ -222,34 +221,34 @@ IdeDisk::read(const Addr &offset, RegType_t type)
         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);
-            }
+        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)
@@ -262,7 +261,6 @@ IdeDisk::read(const Addr &offset, RegType_t type)
         updateState(action);
 
     return data;
-
 }
 
 void
index 93200a8c775ed982bd35c3046186060ca4bdd0dc..7f4acea1c37c05becf974a6c385e45ca3d3285f3 100644 (file)
@@ -78,33 +78,35 @@ PciDev::ReadConfig(int offset, int size, uint8_t *data)
 
     switch(size) {
       case sizeof(uint32_t):
-        memcpy((uint8_t*)data, config.data + offset, sizeof(uint32_t));
+        memcpy(data, &config.data[offset], sizeof(uint32_t));
         *(uint32_t*)data = htoa(*(uint32_t*)data);
+
         DPRINTF(PCIDEV,
                 "read device: %#x function: %#x register: %#x %d bytes: data: %#x\n",
                 params()->deviceNum, params()->functionNum, offset, size,
-                *(uint32_t*)(config.data + offset));
+                *(uint32_t*)data);
         break;
 
       case sizeof(uint16_t):
-        memcpy((uint8_t*)data, config.data + offset, sizeof(uint16_t));
+        memcpy(data, &config.data[offset], sizeof(uint16_t));
         *(uint16_t*)data = htoa(*(uint16_t*)data);
+
         DPRINTF(PCIDEV,
                 "read device: %#x function: %#x register: %#x %d bytes: data: %#x\n",
                 params()->deviceNum, params()->functionNum, offset, size,
-                *(uint16_t*)(config.data + offset));
+                *(uint16_t*)data);
         break;
 
       case sizeof(uint8_t):
-        memcpy((uint8_t*)data, config.data + offset, sizeof(uint8_t));
+        memcpy(data, &config.data[offset], sizeof(uint8_t));
         DPRINTF(PCIDEV,
                 "read device: %#x function: %#x register: %#x %d bytes: data: %#x\n",
                 params()->deviceNum, params()->functionNum, offset, size,
-                (uint16_t)(*(uint8_t*)(config.data + offset)));
+                *data);
         break;
 
       default:
-        panic("Invalid Read Size");
+        panic("Invalid PCI configuration read size!\n");
     }
 }
 
index 963bdc3215ef757a12f48a7af3bc28ad6f64c579..6e517d43108aaf9e131c5b74c90289b03ff5646f 100644 (file)
@@ -59,17 +59,18 @@ TsunamiIO::RTCEvent::RTCEvent(Tsunami* t, Tick i)
     : Event(&mainEventQueue), tsunami(t), interval(i)
 {
     DPRINTF(MC146818, "RTC Event Initilizing\n");
+    intr_count = 0;
     schedule(curTick + interval);
 }
 
 void
 TsunamiIO::RTCEvent::process()
 {
-    static int intr_count = 0;
     DPRINTF(MC146818, "RTC Timer Interrupt\n");
     schedule(curTick + interval);
     //Actually interrupt the processor here
     tsunami->cchip->postRTC();
+
     if (intr_count == 1023)
         tm.tm_sec = (tm.tm_sec + 1) % 60;
 
@@ -113,10 +114,10 @@ TsunamiIO::ClockEvent::ClockEvent()
     DPRINTF(Tsunami, "Clock Event Initilizing\n");
     mode = 0;
 
-    current_count.whole = 0;
-    latched_count.whole = 0;
+    current_count = 0;
+    latched_count = 0;
     latch_on = false;
-    read_msb = false;
+    read_byte = READ_LSB;
 }
 
 void
@@ -128,7 +129,7 @@ TsunamiIO::ClockEvent::process()
     else
         schedule(curTick + interval);
 
-     current_count.whole--; //decrement count
+    current_count--; //decrement count
 }
 
 void
@@ -138,7 +139,7 @@ TsunamiIO::ClockEvent::Program(int count)
     schedule(curTick + count * interval);
     status = 0;
 
-    current_count.whole = count;
+    current_count = (uint16_t)count;
 }
 
 const char *
@@ -162,32 +163,45 @@ TsunamiIO::ClockEvent::Status()
 void
 TsunamiIO::ClockEvent::LatchCount()
 {
+    // behave like a real latch
     if(!latch_on) {
         latch_on = true;
-        read_msb = false;
-        latched_count.whole = current_count.whole;
+        read_byte = READ_LSB;
+        latched_count = current_count;
     }
 }
 
 uint8_t
 TsunamiIO::ClockEvent::Read()
 {
+   uint8_t result = 0;
+
     if(latch_on) {
-        if(!read_msb) {
-            read_msb = true;
-            return latched_count.half.lsb;
-        } else {
+        switch (read_byte) {
+          case READ_LSB:
+            read_byte = READ_MSB;
+            result = (uint8_t)latched_count;
+            break;
+          case READ_MSB:
+            read_byte = READ_LSB;
             latch_on = false;
-            return latched_count.half.msb;
+            result = latched_count >> 8;
+            break;
         }
     } else {
-        if(!read_msb) {
-            read_msb = true;
-            return current_count.half.lsb;
-        } else {
-            return current_count.half.msb;
+        switch (read_byte) {
+          case READ_LSB:
+            read_byte = READ_MSB;
+            result = (uint8_t)current_count;
+            break;
+          case READ_MSB:
+            read_byte = READ_LSB;
+            result = current_count >> 8;
+            break;
         }
     }
+
+    return result;
 }
 
 
index dca651d4bbc211f634b52cec438bfddd43d15ab7..4b28635e86f1c855ce47c99ff810ce2d38bf27c3 100644 (file)
@@ -75,18 +75,14 @@ class TsunamiIO : public PioDevice
         uint8_t mode;
         /** The status of the PIT */
         uint8_t status;
-        /** The counts (current and latched) of the PIT */
-        union {
-            uint16_t whole;
-            struct {
-                uint8_t msb;
-                uint8_t lsb;
-            } half;
-        } current_count, latched_count;
-
-        /** Thse state of the output latch of the PIT */
+        /** The current count of the PIT */
+        uint16_t current_count;
+        /** The latched count of the PIT */
+        uint16_t latched_count;
+        /** The state of the output latch of the PIT */
         bool latch_on;
-        bool read_msb;
+        /** The next count half (byte) to read */
+        enum {READ_LSB, READ_MSB} read_byte;
 
       public:
         /**
@@ -158,6 +154,9 @@ class TsunamiIO : public PioDevice
         Tsunami* tsunami;
         Tick interval;
 
+        /** Count of the number of RTC interrupts that have occured */
+        uint32_t intr_count;
+
       public:
         /**
          * RTC Event initializes the RTC event by scheduling an event
index d7d32cc662f5ff652d3e8e20451fa103003ceb11..a902b07066052c495ae5b44ab1e3b2d69f9bfb45 100644 (file)
@@ -93,8 +93,8 @@ FreebsdSystem::doCalibrateClocks(ExecContext *xc)
     uint8_t *ppc = physmem->dma_addr(ppc_paddr, sizeof(uint32_t));
     uint8_t *timer = physmem->dma_addr(timer_paddr, sizeof(uint32_t));
 
-    *(uint32_t *)ppc = 2000000000;
-    *(uint32_t *)timer = 1193180;
+    *(uint32_t *)ppc = htoa((uint32_t)2000000000);
+    *(uint32_t *)timer = htoa((uint32_t)1193180);
 }