Merge zed.eecs.umich.edu:/.automount/fox/y/mserrano/m5_new/m5
into zed.eecs.umich.edu:/z/benash/bk/m5 SConscript: dev/ide_disk.hh: Formatting. dev/ide_ctrl.cc: Endianness dev/ide_disk.cc: dev/pcidev.cc: dev/tsunami_io.cc: dev/uart8250.cc: Clean up code. --HG-- extra : convert_revision : cb554f0e3a701371d2106cd7e11a4a22f773acc2
This commit is contained in:
commit
a115249eb0
12 changed files with 222 additions and 183 deletions
154
dev/ide_ctrl.cc
154
dev/ide_ctrl.cc
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -261,7 +261,8 @@ IdeController::ReadConfig(int offset, int size, uint8_t *data)
|
|||
|
||||
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;
|
||||
|
@ -299,7 +300,8 @@ IdeController::WriteConfig(int offset, int size, uint32_t 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;
|
||||
|
||||
|
@ -401,7 +403,6 @@ IdeController::read(MemReqPtr &req, uint8_t *data)
|
|||
RegType_t type;
|
||||
int disk;
|
||||
|
||||
|
||||
/* union
|
||||
* +-- --+-- --+-- --+-- --+
|
||||
* | 0 | 1 | 2 | 3 |
|
||||
|
@ -430,15 +431,15 @@ IdeController::read(MemReqPtr &req, uint8_t *data)
|
|||
case BMI_BLOCK:
|
||||
switch (req->size) {
|
||||
case sizeof(uint8_t):
|
||||
memcpy(&byte, &bmi_regs[offset], sizeof(uint8_t));
|
||||
memcpy(&byte, &bmi_regs.data[offset], sizeof(uint8_t));
|
||||
*data = byte;
|
||||
break;
|
||||
case sizeof(uint16_t):
|
||||
memcpy(&byte, &bmi_regs[offset], 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[offset], sizeof(uint32_t));
|
||||
memcpy(&byte, &bmi_regs.data[offset], sizeof(uint32_t));
|
||||
*(uint32_t*)data = htoa(dword);
|
||||
break;
|
||||
default:
|
||||
|
@ -479,6 +480,8 @@ IdeController::read(MemReqPtr &req, uint8_t *data)
|
|||
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",
|
||||
|
@ -492,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 to 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:
|
||||
|
@ -536,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) {
|
||||
|
@ -553,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",
|
||||
|
@ -566,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",
|
||||
|
@ -574,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
|
||||
|
@ -590,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);
|
||||
|
@ -607,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
|
||||
|
@ -616,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:
|
||||
|
@ -627,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;
|
||||
}
|
||||
|
||||
|
@ -657,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
|
||||
|
@ -686,14 +724,14 @@ IdeController::unserialize(Checkpoint *cp, const std::string §ion)
|
|||
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));
|
||||
|
|
|
@ -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 */
|
||||
|
|
123
dev/ide_disk.cc
123
dev/ide_disk.cc
|
@ -218,18 +218,12 @@ IdeDisk::read(const Addr &offset, RegType_t type, uint8_t *data)
|
|||
|
||||
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
|
||||
// Data transfers occur two bytes at a time
|
||||
case DATA_OFFSET:
|
||||
// use memcpy to preserve IDE's little-endianess
|
||||
memcpy(data, &cmdReg.data, sizeof(uint16_t));
|
||||
action = ACT_DATA_READ_SHORT;
|
||||
break;
|
||||
// All other transfers are 8-bit
|
||||
case ERROR_OFFSET:
|
||||
*data = cmdReg.error;
|
||||
break;
|
||||
|
@ -250,6 +244,7 @@ IdeDisk::read(const Addr &offset, RegType_t type, uint8_t *data)
|
|||
break;
|
||||
case STATUS_OFFSET:
|
||||
*data = status;
|
||||
action = ACT_STAT_READ;
|
||||
break;
|
||||
default:
|
||||
panic("Invalid IDE command register offset: %#x\n", offset);
|
||||
|
@ -261,7 +256,6 @@ IdeDisk::read(const Addr &offset, RegType_t type, uint8_t *data)
|
|||
else
|
||||
panic("Invalid IDE control register offset: %#x\n", offset);
|
||||
break;
|
||||
|
||||
default:
|
||||
panic("Unknown register block!\n");
|
||||
}
|
||||
|
@ -271,76 +265,59 @@ IdeDisk::read(const Addr &offset, RegType_t type, uint8_t *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 (!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:
|
||||
memcpy(&cmdReg.data, data, sizeof(uint16_t));
|
||||
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 DRIVE_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 == DRIVE_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)
|
||||
|
@ -793,7 +770,7 @@ IdeDisk::intrPost()
|
|||
|
||||
// talk to controller to set interrupt
|
||||
if (ctrl) {
|
||||
ctrl->bmi_regs[BMIS0] |= IDEINTS;
|
||||
ctrl->bmi_regs.bmis0 |= IDEINTS;
|
||||
ctrl->intrPost();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -271,7 +271,7 @@ class IdeDisk : public SimObject
|
|||
|
||||
// Device register read/write
|
||||
void read(const Addr &offset, RegType_t type, uint8_t *data);
|
||||
void write(const Addr &offset, bool byte, bool cmdBlk, const uint8_t *data);
|
||||
void write(const Addr &offset, RegType_t type, const uint8_t *data);
|
||||
|
||||
// Start/abort functions
|
||||
void startDma(const uint32_t &prdTableBase);
|
||||
|
|
|
@ -115,10 +115,6 @@ PciDev::WriteConfig(int offset, int size, uint32_t data)
|
|||
|
||||
uint32_t barnum;
|
||||
|
||||
uint8_t byte_value;
|
||||
uint16_t half_value;
|
||||
uint32_t word_value;
|
||||
|
||||
DPRINTF(PCIDEV,
|
||||
"write device: %#x function: %#x reg: %#x size: %d data: %#x\n",
|
||||
params()->deviceNum, params()->functionNum, offset, size,
|
||||
|
@ -128,7 +124,7 @@ PciDev::WriteConfig(int offset, int size, uint32_t data)
|
|||
|
||||
switch (size) {
|
||||
case sizeof(uint8_t): // 1-byte access
|
||||
byte_value = data;
|
||||
uint8_t byte_value = data;
|
||||
switch (offset) {
|
||||
case PCI0_INTERRUPT_LINE:
|
||||
case PCI_CACHE_LINE_SIZE:
|
||||
|
@ -148,7 +144,7 @@ PciDev::WriteConfig(int offset, int size, uint32_t data)
|
|||
break;
|
||||
|
||||
case sizeof(uint16_t): // 2-byte access
|
||||
half_value = data;
|
||||
uint16_t half_value = data;
|
||||
switch (offset) {
|
||||
case PCI_COMMAND:
|
||||
case PCI_STATUS:
|
||||
|
@ -162,7 +158,7 @@ PciDev::WriteConfig(int offset, int size, uint32_t data)
|
|||
break;
|
||||
|
||||
case sizeof(uint32_t): // 4-byte access
|
||||
word_value = data;
|
||||
uint32_t word_value = data;
|
||||
switch (offset) {
|
||||
case PCI0_BASE_ADDR0:
|
||||
case PCI0_BASE_ADDR1:
|
||||
|
@ -194,7 +190,7 @@ PciDev::WriteConfig(int offset, int size, uint32_t data)
|
|||
htoa((word_value & ~0x3) |
|
||||
(htoa(config.data[offset]) & 0x3));
|
||||
|
||||
if (word_value != 0x1) {
|
||||
if (word_value &= ~0x1) {
|
||||
Addr base_addr = (word_value & ~0x1) + TSUNAMI_PCI0_IO;
|
||||
Addr base_size = BARSize[barnum];
|
||||
|
||||
|
|
14
dev/rtcreg.h
14
dev/rtcreg.h
|
@ -36,8 +36,22 @@
|
|||
#define RTC_DOM 0x07
|
||||
#define RTC_MON 0x08
|
||||
#define RTC_YEAR 0x09
|
||||
|
||||
#define RTC_CNTRL_REGA 0x0A
|
||||
#define RTCA_1024HZ 0x06 /* 1024Hz periodic interrupt frequency */
|
||||
#define RTCA_32768HZ 0x20 /* 22-stage divider, 32.768KHz timebase */
|
||||
#define RTCA_UIP 0x80 /* 1 = date and time update in progress */
|
||||
|
||||
#define RTC_CNTRL_REGB 0x0B
|
||||
#define RTCB_DST 0x01 /* USA Daylight Savings Time enable */
|
||||
#define RTCB_24HR 0x02 /* 0 = 12 hours, 1 = 24 hours */
|
||||
#define RTCB_BIN 0x04 /* 0 = BCD, 1 = Binary coded time */
|
||||
#define RTCB_SQWE 0x08 /* 1 = output sqare wave at SQW pin */
|
||||
#define RTCB_UPDT_IE 0x10 /* 1 = enable update-ended interrupt */
|
||||
#define RTCB_ALRM_IE 0x20 /* 1 = enable alarm interrupt */
|
||||
#define RTCB_PRDC_IE 0x40 /* 1 = enable periodic clock interrupt */
|
||||
#define RTCB_NO_UPDT 0x80 /* stop clock updates */
|
||||
|
||||
#define RTC_CNTRL_REGC 0x0C
|
||||
#define RTC_CNTRL_REGD 0x0D
|
||||
|
||||
|
|
|
@ -52,14 +52,11 @@ using namespace std;
|
|||
|
||||
#define UNIX_YEAR_OFFSET 52
|
||||
|
||||
struct tm TsunamiIO::tm = { 0 };
|
||||
|
||||
// Timer Event for Periodic interrupt of RTC
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -70,11 +67,6 @@ TsunamiIO::RTCEvent::process()
|
|||
schedule(curTick + interval);
|
||||
//Actually interrupt the processor here
|
||||
tsunami->cchip->postRTC();
|
||||
|
||||
if (intr_count == 1023)
|
||||
tm.tm_sec = (tm.tm_sec + 1) % 60;
|
||||
|
||||
intr_count = (intr_count + 1) % 1024;
|
||||
}
|
||||
|
||||
const char *
|
||||
|
@ -98,6 +90,11 @@ TsunamiIO::RTCEvent::unserialize(Checkpoint *cp, const std::string §ion)
|
|||
reschedule(time);
|
||||
}
|
||||
|
||||
void
|
||||
TsunamiIO::RTCEvent::scheduleIntr()
|
||||
{
|
||||
schedule(curTick + interval);
|
||||
}
|
||||
|
||||
// Timer Event for PIT Timers
|
||||
TsunamiIO::ClockEvent::ClockEvent()
|
||||
|
@ -125,10 +122,8 @@ TsunamiIO::ClockEvent::process()
|
|||
DPRINTF(Tsunami, "Timer Interrupt\n");
|
||||
if (mode == 0)
|
||||
status = 0x20; // set bit that linux is looking for
|
||||
else
|
||||
schedule(curTick + interval);
|
||||
|
||||
current_count--; //decrement count
|
||||
else if (mode == 2)
|
||||
schedule(curTick + current_count*interval);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -301,12 +296,12 @@ TsunamiIO::read(MemReqPtr &req, uint8_t *data)
|
|||
case TSDEV_RTC_DATA:
|
||||
switch(RTCAddress) {
|
||||
case RTC_CNTRL_REGA:
|
||||
*(uint8_t*)data = uip << 7 | 0x26;
|
||||
*(uint8_t*)data = uip << 7 | RTCA_32768HZ | RTCA_1024HZ;
|
||||
uip = !uip;
|
||||
return No_Fault;
|
||||
case RTC_CNTRL_REGB:
|
||||
// DM and 24/12 and UIE
|
||||
*(uint8_t*)data = 0x46;
|
||||
*(uint8_t*)data = RTCB_PRDC_IE | RTCB_BIN | RTCB_24HR;
|
||||
return No_Fault;
|
||||
case RTC_CNTRL_REGC:
|
||||
// If we want to support RTC user access in linux
|
||||
|
@ -331,7 +326,7 @@ TsunamiIO::read(MemReqPtr &req, uint8_t *data)
|
|||
*(uint8_t *)data = tm.tm_hour;
|
||||
return No_Fault;
|
||||
case RTC_DOW:
|
||||
*(uint8_t *)data = tm.tm_wday;
|
||||
*(uint8_t *)data = tm.tm_wday + 1;
|
||||
return No_Fault;
|
||||
case RTC_DOM:
|
||||
*(uint8_t *)data = tm.tm_mday;
|
||||
|
@ -340,20 +335,11 @@ TsunamiIO::read(MemReqPtr &req, uint8_t *data)
|
|||
*(uint8_t *)data = tm.tm_mon + 1;
|
||||
return No_Fault;
|
||||
case RTC_YEAR:
|
||||
*(uint8_t *)data = tm.tm_year - UNIX_YEAR_OFFSET;
|
||||
*(uint8_t *)data = tm.tm_year;
|
||||
return No_Fault;
|
||||
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);
|
||||
}
|
||||
|
@ -447,10 +433,10 @@ TsunamiIO::write(MemReqPtr &req, const uint8_t *data)
|
|||
switch(*(uint8_t*)data >> 6) {
|
||||
case 0:
|
||||
timer0.LatchCount();
|
||||
break;
|
||||
return No_Fault;
|
||||
case 2:
|
||||
timer2.LatchCount();
|
||||
break;
|
||||
return No_Fault;
|
||||
default:
|
||||
panic("Read Back Command not implemented\n");
|
||||
}
|
||||
|
@ -488,9 +474,10 @@ TsunamiIO::write(MemReqPtr &req, const uint8_t *data)
|
|||
/* two writes before we actually start the Timer
|
||||
so I set a flag in the timerData */
|
||||
if(timerData & 0x1000) {
|
||||
timerData &= 0x1000;
|
||||
timerData &= ~0x1000;
|
||||
timerData += *(uint8_t*)data << 8;
|
||||
timer0.Program(timerData);
|
||||
timerData = 0;
|
||||
} else {
|
||||
timerData = *(uint8_t*)data;
|
||||
timerData |= 0x1000;
|
||||
|
@ -504,12 +491,26 @@ TsunamiIO::write(MemReqPtr &req, const uint8_t *data)
|
|||
case TSDEV_RTC_DATA:
|
||||
switch(RTCAddress) {
|
||||
case RTC_CNTRL_REGA:
|
||||
if (*data != (RTCA_32768HZ | RTCA_1024HZ))
|
||||
panic("Unimplemented RTC register A value write!\n");
|
||||
return No_Fault;
|
||||
case RTC_CNTRL_REGB:
|
||||
if ((*data & ~(RTCB_PRDC_IE | RTCB_SQWE)) != (RTCB_BIN | RTCB_24HR))
|
||||
panic("Write to RTC reg B bits that are not implemented!\n");
|
||||
|
||||
if (*data & RTCB_PRDC_IE) {
|
||||
if (!rtc.scheduled())
|
||||
rtc.scheduleIntr();
|
||||
} else {
|
||||
if (rtc.scheduled())
|
||||
rtc.deschedule();
|
||||
}
|
||||
return No_Fault;
|
||||
case RTC_CNTRL_REGC:
|
||||
panic("Write to RTC reg C not implemented!\n");
|
||||
return No_Fault;
|
||||
case RTC_CNTRL_REGD:
|
||||
panic("Write to RTC reg D not implemented!\n");
|
||||
return No_Fault;
|
||||
case RTC_SEC:
|
||||
tm.tm_sec = *(uint8_t *)data;
|
||||
|
@ -527,12 +528,11 @@ TsunamiIO::write(MemReqPtr &req, const uint8_t *data)
|
|||
tm.tm_mday = *(uint8_t *)data;
|
||||
return No_Fault;
|
||||
case RTC_MON:
|
||||
tm.tm_mon = *(uint8_t *)data - 1;
|
||||
tm.tm_mon = *(uint8_t *)data;
|
||||
return No_Fault;
|
||||
case RTC_YEAR:
|
||||
tm.tm_year = *(uint8_t *)data + UNIX_YEAR_OFFSET;
|
||||
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);
|
||||
|
|
|
@ -51,7 +51,7 @@ class TsunamiIO : public PioDevice
|
|||
/** The size of mappad from the above address */
|
||||
static const Addr size = 0xff;
|
||||
|
||||
static struct tm tm;
|
||||
struct tm tm;
|
||||
|
||||
/**
|
||||
* In Tsunami RTC only has two i/o ports one for data and one for
|
||||
|
@ -154,9 +154,6 @@ 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
|
||||
|
@ -165,7 +162,7 @@ class TsunamiIO : public PioDevice
|
|||
RTCEvent(Tsunami* t, Tick i);
|
||||
|
||||
/**
|
||||
* Interrupth the processor and reschedule the event.
|
||||
* Interrupt the processor and reschedule the event.
|
||||
*/
|
||||
virtual void process();
|
||||
|
||||
|
@ -187,6 +184,8 @@ class TsunamiIO : public PioDevice
|
|||
* @param section The section name of this object
|
||||
*/
|
||||
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
|
||||
void scheduleIntr();
|
||||
};
|
||||
|
||||
/** uip UpdateInProgess says that the rtc is updating, but we just fake it
|
||||
|
@ -243,7 +242,7 @@ class TsunamiIO : public PioDevice
|
|||
* This variable contains a flag as to how many writes have happened, and
|
||||
* the time so far.
|
||||
*/
|
||||
uint32_t timerData;
|
||||
uint16_t timerData;
|
||||
|
||||
public:
|
||||
/**
|
||||
|
|
|
@ -148,9 +148,9 @@ Uart8250::read(MemReqPtr &req, uint8_t *data)
|
|||
DPRINTF(Uart, "IIR Read, status = %#x\n", (uint32_t)status);
|
||||
status &= ~TX_INT;
|
||||
if (status & RX_INT)
|
||||
*(uint8_t*)data = 0x4;
|
||||
*(uint8_t*)data = IIR_RXID;
|
||||
else
|
||||
*(uint8_t*)data = 0x1;
|
||||
*(uint8_t*)data = IIR_NOPEND;
|
||||
break;
|
||||
case 0x3: // Line Control Register (LCR)
|
||||
*(uint8_t*)data = LCR;
|
||||
|
|
|
@ -38,6 +38,9 @@
|
|||
#include "dev/io_device.hh"
|
||||
#include "dev/uart.hh"
|
||||
|
||||
#define IIR_NOPEND 0x1
|
||||
#define IIR_RXID 0x4
|
||||
|
||||
class SimConsole;
|
||||
class Platform;
|
||||
|
||||
|
|
|
@ -60,7 +60,6 @@ FreebsdSystem::FreebsdSystem(Params *p)
|
|||
skipCalibrateClocks = new FreebsdSkipCalibrateClocksEvent(&pcEventQueue, "calibrate_clocks");
|
||||
if (kernelSymtab->findAddress("calibrate_clocks", addr))
|
||||
skipCalibrateClocks->schedule(addr + sizeof(MachInst) * 2);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -34,9 +34,7 @@
|
|||
class FreebsdSystem : public System
|
||||
{
|
||||
private:
|
||||
|
||||
SkipFuncEvent *skipDelayEvent;
|
||||
|
||||
FreebsdSkipCalibrateClocksEvent *skipCalibrateClocks;
|
||||
|
||||
public:
|
||||
|
|
Loading…
Reference in a new issue