summaryrefslogtreecommitdiff
path: root/dev
diff options
context:
space:
mode:
Diffstat (limited to 'dev')
-rw-r--r--dev/ide_ctrl.cc129
-rw-r--r--dev/ide_ctrl.hh36
-rw-r--r--dev/pcidev.cc16
-rw-r--r--dev/tsunami_io.cc50
-rw-r--r--dev/tsunami_io.hh21
5 files changed, 135 insertions, 117 deletions
diff --git a/dev/ide_ctrl.cc b/dev/ide_ctrl.cc
index defeb641b..6636a5ff6 100644
--- a/dev/ide_ctrl.cc
+++ b/dev/ide_ctrl.cc
@@ -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;
@@ -251,6 +251,7 @@ IdeController::cacheAccess(MemReqPtr &req)
void
IdeController::ReadConfig(int offset, int size, uint8_t *data)
{
+ int config_offset;
#if TRACING_ON
Addr origOffset = offset;
@@ -258,86 +259,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) {
@@ -423,17 +405,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);
@@ -624,7 +611,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);
@@ -653,7 +640,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);
diff --git a/dev/ide_ctrl.hh b/dev/ide_ctrl.hh
index 4b54c3d57..2164f2f4a 100644
--- a/dev/ide_ctrl.hh
+++ b/dev/ide_ctrl.hh
@@ -64,15 +64,9 @@
#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;
diff --git a/dev/pcidev.cc b/dev/pcidev.cc
index 93200a8c7..7f4acea1c 100644
--- a/dev/pcidev.cc
+++ b/dev/pcidev.cc
@@ -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");
}
}
diff --git a/dev/tsunami_io.cc b/dev/tsunami_io.cc
index 963bdc321..6e517d431 100644
--- a/dev/tsunami_io.cc
+++ b/dev/tsunami_io.cc
@@ -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;
}
diff --git a/dev/tsunami_io.hh b/dev/tsunami_io.hh
index dca651d4b..4b28635e8 100644
--- a/dev/tsunami_io.hh
+++ b/dev/tsunami_io.hh
@@ -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