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
This commit is contained in:
Miguel Serrano
2005-07-28 11:49:01 -04:00
parent 6a8ae7a6a0
commit 74fd4f68c5
6 changed files with 289 additions and 217 deletions

View 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

View 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);
break;
case sizeof(uint16_t):
memcpy(data, &pci_config_regs.data[config_offset], sizeof(uint16_t));
*(uint16_t*)data = htoa(*(uint16_t*)data);
break;
switch (size) {
case sizeof(uint8_t):
memcpy(data, &pci_config_regs.data[config_offset], sizeof(uint8_t));
memcpy(&byte, &pci_config_regs.data[config_offset], size);
*data = byte;
break;
case sizeof(uint16_t):
memcpy(&byte, &pci_config_regs.data[config_offset], size);
*(uint16_t*)data = htoa(word);
break;
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));

View 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 */

View 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);
}
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;
} 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;
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();
}
}

View 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);

View 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);