Various changes to m5/dev files to work with FreeBSD.
authorBenjamin Nash <benash@umich.edu>
Wed, 13 Jul 2005 16:30:13 +0000 (12:30 -0400)
committerBenjamin Nash <benash@umich.edu>
Wed, 13 Jul 2005 16:30:13 +0000 (12:30 -0400)
dev/ide_ctrl.cc:
dev/ide_disk.cc:
dev/pcidev.cc:
    Made endian-independent.
dev/ide_disk.hh:
    fixed.
dev/pciconfigall.cc:
    The data to write is contained in a 32-bit unsigned int now. The union method would not have worked on big-endian machines.
dev/pcidev.hh:
    Fixed typo.
dev/tsunami_io.cc:
    Return zero on RTC alarm reads.
dev/uart8250.cc:
    Fix uart interrupt handling.

--HG--
extra : convert_revision : b5c08e8e77644c399c20888666406805ff1b6649

dev/ide_ctrl.cc
dev/ide_disk.cc
dev/ide_disk.hh
dev/pciconfigall.cc
dev/pcidev.cc
dev/pcidev.hh
dev/tsunami_io.cc
dev/uart8250.cc

index 6636a5ff61f0d15b2f1cd27976c8538204994852..171f59a33d2b0e18674304c4aaa60705a27b860b 100644 (file)
@@ -251,49 +251,57 @@ 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) {
 
         config_offset = offset - IDE_CTRL_CONFIG_START;
+        dword = 0;
 
-        switch(size) {
+        switch (size) {
+          case sizeof(uint8_t):
+          case sizeof(uint16_t):
           case sizeof(uint32_t):
-            memcpy(data, &pci_config_regs.data[config_offset], sizeof(uint32_t));
-            *(uint32_t*)data = htoa(*(uint32_t*)data);
+            memcpy(&byte, &pci_config_regs.data[config_offset], size);
             break;
 
-          case sizeof(uint16_t):
-            memcpy(data, &pci_config_regs.data[config_offset], sizeof(uint16_t));
-            *(uint16_t*)data = htoa(*(uint16_t*)data);
-            break;
+          default:
+            panic("Invalid PCI configuration read size!\n");
+        }
 
+        switch (size) {
           case sizeof(uint8_t):
-            memcpy(data, &pci_config_regs.data[config_offset], sizeof(uint8_t));
+            *data = byte;
+            break;
+          case sizeof(uint16_t):
+            *(uint16_t*)data = htoa(word);
+            break;
+          case sizeof(uint32_t):
+            *(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);
@@ -301,24 +309,24 @@ IdeController::WriteConfig(int offset, int size, uint32_t data)
 
         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,6 +407,12 @@ IdeController::read(MemReqPtr &req, uint8_t *data)
     RegType_t type;
     int disk;
 
+    union {
+        uint8_t byte;
+        uint16_t word[2];
+        uint32_t dword;
+    };
+
     parseAddr(req->paddr, offset, primary, type);
 
     if (!io_enabled)
@@ -414,27 +428,59 @@ IdeController::read(MemReqPtr &req, uint8_t *data)
         panic("IDE controller read of invalid size: %#x\n", req->size);
     }
 
-    if (type != BMI_BLOCK) {
+    switch (type) {
+      case BMI_BLOCK:
+        memcpy(&byte, &bmi_regs[offset], req->size);
+        switch (req->size) {
+          case sizeof(uint8_t):
+            *data = byte;
+            break;
+          case sizeof(uint16_t):
+            *(uint16_t*)data = htoa(word[0]);
+            break;
+          case sizeof(uint32_t):
+            *(uint32_t*)data = htoa(dword);
+            break;
+        }
+        break;
 
+      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;
     }
 
     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;
 }
index 3d7bd19c0e3ef9a550979507576d9680a96f59b1..98f2ee7d51fc662d3a968dfb04d4dd7294fecf33 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,7 +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;
@@ -159,6 +161,8 @@ IdeDisk::reset(int id)
 
     // set the device ready bit
     status = STATUS_DRDY_BIT;
+
+    cmdReg.error = 0x1;
 }
 
 ////
@@ -207,62 +211,63 @@ 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;
     DevAction_t action = ACT_NONE;
 
-    if (type == COMMAND_BLOCK) {
-
+    switch (type) {
+      case COMMAND_BLOCK:
         if (offset == STATUS_OFFSET)
             action = ACT_STAT_READ;
         else if (offset == DATA_OFFSET)
             action = ACT_DATA_READ_SHORT;
 
         switch (offset) {
+          // Data transfers occur 16 bits at a time
           case DATA_OFFSET:
-            data = cmdReg.data;
+            // use memcpy to preserve little-endianess
+            memcpy(data, &cmdReg.data, sizeof(uint16_t));
             break;
+          // All other transfers are 8 bit
           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;
             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);
+        break;
 
-        data = status;
-    }
-    else {
-        panic("Invalid IDE register type: %#x\n", type);
+      default:
+        panic("Unknown register block!\n");
     }
 
     if (action != ACT_NONE)
         updateState(action);
-
-    return data;
 }
 
 void
@@ -271,8 +276,6 @@ IdeDisk::write(const Addr &offset, bool byte, bool cmdBlk, 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");
@@ -282,10 +285,10 @@ IdeDisk::write(const Addr &offset, bool byte, bool cmdBlk, const uint8_t *data)
         else {
             switch (offset) {
               case DATA_OFFSET:
-                cmdReg.data = *data;
+                memcpy(&cmdReg.data, data, sizeof(uint16_t));
                 break;
               case FEATURES_OFFSET:
-                cmdReg.features = *data;
+                //cmdReg.features = *data;
                 break;
               case NSECTOR_OFFSET:
                 cmdReg.sec_count = *data;
@@ -299,7 +302,7 @@ IdeDisk::write(const Addr &offset, bool byte, bool cmdBlk, const uint8_t *data)
               case HCYL_OFFSET:
                 cmdReg.cyl_high = *data;
                 break;
-              case SELECT_OFFSET:
+              case DRIVE_OFFSET:
                 cmdReg.drive = *data;
                 break;
               case COMMAND_OFFSET:
@@ -318,7 +321,7 @@ IdeDisk::write(const Addr &offset, bool byte, bool cmdBlk, const uint8_t *data)
                 action = ACT_DATA_WRITE_BYTE;
             else
                 action = ACT_DATA_WRITE_SHORT;
-        } else if (offset == SELECT_OFFSET) {
+        } else if (offset == DRIVE_OFFSET) {
             action = ACT_SELECT_WRITE;
         }
 
index 0fcd863ecea9055fbe38db299cdf5f2f894b6514..9799e2d380ec3d8b146ba08f96b8369eccdd7532 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,7 +270,7 @@ class IdeDisk : public SimObject
     }
 
     // Device register read/write
-    uint16_t read(const Addr &offset, RegType_t type);
+    void read(const Addr &offset, RegType_t type, uint8_t *data);
     void write(const Addr &offset, bool byte, bool cmdBlk, const uint8_t *data);
 
     // Start/abort functions
index 7d86c3e1b88b8c52f9f914901d60dde92ae7996b..6a4d60d1b90bfebc2708ce473eebf729ac54b7ad 100644 (file)
@@ -152,21 +152,17 @@ PciConfigAll::write(MemReqPtr &req, const uint8_t *data)
     int func = (daddr >> 8) & 0x7;
     int reg = daddr & 0xFF;
 
-    union {
-        uint8_t byte_value;
-        uint16_t half_value;
-        uint32_t word_value;
-    };
+    uint32_t word_value = 0;
 
     if (devices[device][func] == NULL)
         panic("Attempting to write to config space on non-existant device\n");
     else {
             switch (req->size) {
             case sizeof(uint8_t):
-                byte_value = *(uint8_t*)data;
+                word_value = *(uint8_t*)data & 0x000000FF;
                 break;
             case sizeof(uint16_t):
-                half_value = *(uint16_t*)data;
+                word_value = *(uint16_t*)data & 0x0000FFFF;
                 break;
             case sizeof(uint32_t):
                 word_value = *(uint32_t*)data;
index 7f4acea1c37c05becf974a6c385e45ca3d3285f3..b003d3987d707664c20dcd0111df145357d71967 100644 (file)
@@ -73,41 +73,44 @@ PciDev::PciDev(Params *p)
 void
 PciDev::ReadConfig(int offset, int size, uint8_t *data)
 {
+    union {
+      uint8_t byte;
+      uint16_t word;
+      uint32_t dword;
+    };
+
+    dword = 0;
+
     if (offset >= PCI_DEVICE_SPECIFIC)
         panic("Device specific PCI config space not implemented!\n");
 
     switch(size) {
+      case sizeof(uint8_t):
+      case sizeof(uint16_t):
       case 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*)data);
+        memcpy(&byte, &config.data[offset], size);
         break;
 
-      case 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*)data);
-        break;
+      default:
+        panic("Invalid PCI configuration read size!\n");
+    }
 
+    switch(size) {
       case 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,
-                *data);
+        *data = byte;
+        break;
+      case sizeof(uint16_t):
+        *(uint16_t*)data = htoa(word);
+        break;
+      case sizeof(uint32_t):
+        *(uint32_t*)data = htoa(dword);
         break;
-
-      default:
-        panic("Invalid PCI configuration read size!\n");
     }
+
+    DPRINTF(PCIDEV,
+            "read device: %#x function: %#x register: %#x %d bytes: data: %#x\n",
+            params()->deviceNum, params()->functionNum, offset, size,
+            htoa(dword));
 }
 
 void
@@ -118,17 +121,14 @@ PciDev::WriteConfig(int offset, int size, uint32_t data)
 
     uint32_t barnum;
 
-    union {
-        uint8_t byte_value;
-        uint16_t half_value;
-        uint32_t word_value;
-    };
-    word_value = data;
+    uint8_t byte_value = data;
+    uint16_t half_value = data;
+    uint32_t word_value = data;
 
     DPRINTF(PCIDEV,
             "write device: %#x function: %#x reg: %#x size: %d data: %#x\n",
             params()->deviceNum, params()->functionNum, offset, size,
-            word_value);
+            data);
 
     barnum = (offset - PCI0_BASE_ADDR0) >> 2;
 
@@ -165,9 +165,6 @@ PciDev::WriteConfig(int offset, int size, uint32_t data)
         }
         break;
 
-      case sizeof(uint16_t)+1: // 3-byte access
-        panic("invalid access size");
-
       case sizeof(uint32_t): // 4-byte access
         switch (offset) {
           case PCI0_BASE_ADDR0:
@@ -183,12 +180,12 @@ PciDev::WriteConfig(int offset, int size, uint32_t data)
                 // This is I/O Space, bottom two bits are read only
                 if (htoa(config.data[offset]) & 0x1) {
                     *(uint32_t *)&config.data[offset] = htoa(
-                        ~(BARSize[barnum] - 1) |
+                        (~(BARSize[barnum] - 1) & ~0x3) |
                         (htoa(config.data[offset]) & 0x3));
                 } else {
                     // This is memory space, bottom four bits are read only
                     *(uint32_t *)&config.data[offset] = htoa(
-                        ~(BARSize[barnum] - 1) |
+                        (~(BARSize[barnum] - 1) & ~0xF) |
                         (htoa(config.data[offset]) & 0xF));
                 }
             } else {
@@ -263,6 +260,9 @@ PciDev::WriteConfig(int offset, int size, uint32_t data)
             DPRINTF(PCIDEV, "Writing to a read only register");
         }
         break;
+
+      default:
+        panic("invalid access size");
     }
 }
 
index 091a365e393ea61d8aa3b865c4f7b883b94a2379..31b0cab16943cb7f3aa55a7e75caf6465895fd54 100644 (file)
@@ -115,7 +115,7 @@ class PciDev : public DmaDevice
 
   protected:
     /** The current config space. Unlike the PciConfigData this is
-     * updated during simulation while continues to refelect what was
+     * updated during simulation while continues to reflect what was
      * in the config file.
      */
     PCIConfig config;
index 6e517d43108aaf9e131c5b74c90289b03ff5646f..6a704f7ac9ca37b91a86cd45c31c0f36b93e8159 100644 (file)
@@ -270,7 +270,7 @@ TsunamiIO::read(MemReqPtr &req, uint8_t *data)
     DPRINTF(Tsunami, "io read  va=%#x size=%d IOPorrt=%#x\n",
             req->vaddr, req->size, req->vaddr & 0xfff);
 
-    Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)) + 0x20;
+    Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask));
 
 
     switch(req->size) {
@@ -319,6 +319,12 @@ TsunamiIO::read(MemReqPtr &req, uint8_t *data)
               case RTC_SEC:
                 *(uint8_t *)data = tm.tm_sec;
                 return No_Fault;
+              case RTC_SEC_ALRM:
+              case RTC_MIN_ALRM:
+              case RTC_HR_ALRM:
+                // RTC alarm functionality is not currently implemented
+                *(uint8_t *)data = 0x00;
+                return No_Fault;
               case RTC_MIN:
                 *(uint8_t *)data = tm.tm_min;
                 return No_Fault;
@@ -391,7 +397,7 @@ TsunamiIO::write(MemReqPtr &req, const uint8_t *data)
     DPRINTF(Tsunami, "io write - va=%#x size=%d IOPort=%#x Data=%#x\n",
             req->vaddr, req->size, req->vaddr & 0xfff, dt64);
 
-    Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)) + 0x20;
+    Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask));
 
     switch(req->size) {
       case sizeof(uint8_t):
index 99e3bd01711507fa268b8084570b10f89205389a..63756042a151a6defd6c671f647e5157ce3b3457 100644 (file)
@@ -88,7 +88,7 @@ Uart8250::IntrEvent::process()
 void
 Uart8250::IntrEvent::scheduleIntr()
 {
-    static const Tick interval = (Tick)((Clock::Float::s / 2e9) * 450);
+    static const Tick interval = (Tick)((Clock::Float::s / 2e9) * 600);
     DPRINTF(Uart, "Scheduling IER interrupt for %#x, at cycle %lld\n", intrBit,
             curTick + interval);
     if (!scheduled())
@@ -146,10 +146,11 @@ Uart8250::read(MemReqPtr &req, uint8_t *data)
             break;
         case 0x2: // Intr Identification Register (IIR)
             DPRINTF(Uart, "IIR Read, status = %#x\n", (uint32_t)status);
-            if (status)
-                *(uint8_t*)data = 0;
+            status &= ~TX_INT;
+            if (status & RX_INT)
+                *(uint8_t*)data = 0x4;
             else
-                *(uint8_t*)data = 1;
+                *(uint8_t*)data = 0x1;
             break;
         case 0x3: // Line Control Register (LCR)
             *(uint8_t*)data = LCR;