Change IDE disk and ethernet device to work better with FreeBSD.

dev/ide_ctrl.cc:
dev/ide_disk.cc:
dev/ide_disk.hh:
    Add support for 32-bit accesses.
dev/ns_gige.cc:
    Change default configuration register value to work with FreeBSD driver.

--HG--
extra : convert_revision : c9dd125338a97ffa8cd95293e6b7877068652387
This commit is contained in:
Benjamin Nash 2005-06-27 18:08:42 -04:00
parent 0460a78829
commit 8b04218262
4 changed files with 95 additions and 49 deletions

View file

@ -412,14 +412,10 @@ IdeController::read(MemReqPtr &req, uint8_t *data)
{ {
Addr offset; Addr offset;
bool primary; bool primary;
bool byte;
bool cmdBlk;
RegType_t type; RegType_t type;
int disk; int disk;
parseAddr(req->paddr, offset, primary, type); parseAddr(req->paddr, offset, primary, type);
byte = (req->size == sizeof(uint8_t)) ? true : false;
cmdBlk = (type == COMMAND_BLOCK) ? true : false;
if (!io_enabled) if (!io_enabled)
return No_Fault; return No_Fault;
@ -430,11 +426,19 @@ IdeController::read(MemReqPtr &req, uint8_t *data)
panic("IDE controller read of invalid size: %#x\n", req->size); panic("IDE controller read of invalid size: %#x\n", req->size);
if (type != BMI_BLOCK) { if (type != BMI_BLOCK) {
assert(req->size != sizeof(uint32_t));
disk = getDisk(primary); disk = getDisk(primary);
if (disks[disk]) if (disks[disk])
disks[disk]->read(offset, byte, cmdBlk, data); 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);
}
else if (req->size == sizeof(uint8_t) && offset == DATA_OFFSET) {
panic("IDE read of data reg invalid size: %#x\n", req->size);
}
else {
*data = disks[disk]->read(offset, type);
}
} else { } else {
memcpy((void *)data, &bmi_regs[offset], req->size); memcpy((void *)data, &bmi_regs[offset], req->size);
} }

View file

@ -208,46 +208,61 @@ IdeDisk::bytesInDmaPage(Addr curAddr, uint32_t bytesLeft)
// Device registers read/write // Device registers read/write
//// ////
void uint16_t
IdeDisk::read(const Addr &offset, bool byte, bool cmdBlk, uint8_t *data) IdeDisk::read(const Addr &offset, RegType_t type)
{ {
uint16_t data;
DevAction_t action = ACT_NONE; DevAction_t action = ACT_NONE;
if (cmdBlk) { if (type == COMMAND_BLOCK) {
if (offset < 0 || offset > sizeof(CommandReg_t))
panic("Invalid disk command register offset: %#x\n", offset);
if (!byte && offset != DATA_OFFSET) if (offset == STATUS_OFFSET)
panic("Invalid 16-bit read, only allowed on data reg\n");
if (!byte)
*(uint16_t *)data = *(uint16_t *)&cmdReg.data0;
else
*data = ((uint8_t *)&cmdReg)[offset];
// determine if an action needs to be taken on the state machine
if (offset == STATUS_OFFSET) {
action = ACT_STAT_READ; action = ACT_STAT_READ;
*data = status; // status is in a shadow, explicity copy else if (offset == DATA_OFFSET)
} else if (offset == DATA_OFFSET) { action = ACT_DATA_READ_SHORT;
if (byte)
action = ACT_DATA_READ_BYTE;
else
action = ACT_DATA_READ_SHORT;
}
} else { 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) if (offset != ALTSTAT_OFFSET)
panic("Invalid disk control register offset: %#x\n", offset); panic("Invalid IDE control register offset: %#x\n", offset);
if (!byte) data = status;
panic("Invalid 16-bit read from control block\n");
*data = status;
} }
if (action != ACT_NONE) if (action != ACT_NONE)
updateState(action); updateState(action);
return data;
} }
void void
@ -263,9 +278,37 @@ IdeDisk::write(const Addr &offset, bool byte, bool cmdBlk, const uint8_t *data)
panic("Invalid 16-bit write, only allowed on data reg\n"); panic("Invalid 16-bit write, only allowed on data reg\n");
if (!byte) if (!byte)
*((uint16_t *)&cmdReg.data0) = *(uint16_t *)data; *((uint16_t *)&cmdReg.data) = *(uint16_t *)data;
else else {
((uint8_t *)&cmdReg)[offset] = *data; 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 // determine if an action needs to be taken on the state machine
if (offset == COMMAND_OFFSET) { if (offset == COMMAND_OFFSET) {
@ -746,9 +789,10 @@ IdeDisk::intrPost()
intrPending = true; intrPending = true;
// talk to controller to set interrupt // talk to controller to set interrupt
if (ctrl) if (ctrl){
ctrl->bmi_regs[BMIS0] |= IDEINTS; ctrl->bmi_regs[BMIS0] |= IDEINTS;
ctrl->intrPost(); ctrl->intrPost();
}
} }
void void
@ -867,7 +911,7 @@ IdeDisk::updateState(DevAction_t action)
} }
// put the first two bytes into the data register // put the first two bytes into the data register
memcpy((void *)&cmdReg.data0, (void *)dataBuffer, memcpy((void *)&cmdReg.data, (void *)dataBuffer,
sizeof(uint16_t)); sizeof(uint16_t));
if (!isIENSet()) { if (!isIENSet()) {
@ -896,7 +940,7 @@ IdeDisk::updateState(DevAction_t action)
// copy next short into data registers // copy next short into data registers
if (drqBytesLeft) if (drqBytesLeft)
memcpy((void *)&cmdReg.data0, memcpy((void *)&cmdReg.data,
(void *)&dataBuffer[SectorSize - drqBytesLeft], (void *)&dataBuffer[SectorSize - drqBytesLeft],
sizeof(uint16_t)); sizeof(uint16_t));
} }
@ -969,7 +1013,7 @@ IdeDisk::updateState(DevAction_t action)
} else { } else {
// copy the latest short into the data buffer // copy the latest short into the data buffer
memcpy((void *)&dataBuffer[SectorSize - drqBytesLeft], memcpy((void *)&dataBuffer[SectorSize - drqBytesLeft],
(void *)&cmdReg.data0, (void *)&cmdReg.data,
sizeof(uint16_t)); sizeof(uint16_t));
drqBytesLeft -= 2; drqBytesLeft -= 2;
@ -1093,8 +1137,7 @@ IdeDisk::serialize(ostream &os)
SERIALIZE_ENUM(event); SERIALIZE_ENUM(event);
// Serialize device registers // Serialize device registers
SERIALIZE_SCALAR(cmdReg.data0); SERIALIZE_SCALAR(cmdReg.data);
SERIALIZE_SCALAR(cmdReg.data1);
SERIALIZE_SCALAR(cmdReg.sec_count); SERIALIZE_SCALAR(cmdReg.sec_count);
SERIALIZE_SCALAR(cmdReg.sec_num); SERIALIZE_SCALAR(cmdReg.sec_num);
SERIALIZE_SCALAR(cmdReg.cyl_low); SERIALIZE_SCALAR(cmdReg.cyl_low);
@ -1146,8 +1189,7 @@ IdeDisk::unserialize(Checkpoint *cp, const string &section)
} }
// Unserialize device registers // Unserialize device registers
UNSERIALIZE_SCALAR(cmdReg.data0); UNSERIALIZE_SCALAR(cmdReg.data);
UNSERIALIZE_SCALAR(cmdReg.data1);
UNSERIALIZE_SCALAR(cmdReg.sec_count); UNSERIALIZE_SCALAR(cmdReg.sec_count);
UNSERIALIZE_SCALAR(cmdReg.sec_num); UNSERIALIZE_SCALAR(cmdReg.sec_num);
UNSERIALIZE_SCALAR(cmdReg.cyl_low); UNSERIALIZE_SCALAR(cmdReg.cyl_low);

View file

@ -35,6 +35,7 @@
#include "dev/disk_image.hh" #include "dev/disk_image.hh"
#include "dev/ide_atareg.h" #include "dev/ide_atareg.h"
#include "dev/ide_ctrl.hh"
#include "dev/ide_wdcreg.h" #include "dev/ide_wdcreg.h"
#include "dev/io_device.hh" #include "dev/io_device.hh"
#include "sim/eventq.hh" #include "sim/eventq.hh"
@ -103,9 +104,8 @@ class PrdTableEntry {
#define DEV1 (1) #define DEV1 (1)
typedef struct CommandReg { typedef struct CommandReg {
uint8_t data0; uint16_t data;
union { union {
uint8_t data1;
uint8_t error; uint8_t error;
uint8_t features; uint8_t features;
}; };
@ -272,7 +272,7 @@ class IdeDisk : public SimObject
} }
// Device register read/write // Device register read/write
void read(const Addr &offset, bool byte, bool cmdBlk, uint8_t *data); uint16_t read(const Addr &offset, RegType_t type);
void write(const Addr &offset, bool byte, bool cmdBlk, const uint8_t *data); void write(const Addr &offset, bool byte, bool cmdBlk, const uint8_t *data);
// Start/abort functions // Start/abort functions

View file

@ -1359,7 +1359,7 @@ void
NSGigE::regsReset() NSGigE::regsReset()
{ {
memset(&regs, 0, sizeof(regs)); memset(&regs, 0, sizeof(regs));
regs.config = CFGR_LNKSTS; regs.config = (CFGR_LNKSTS | CFGR_TBI_EN | CFGR_MODE_1000);
regs.mear = 0x22; regs.mear = 0x22;
regs.txcfg = 0x120; // set drain threshold to 1024 bytes and regs.txcfg = 0x120; // set drain threshold to 1024 bytes and
// fill threshold to 32 bytes // fill threshold to 32 bytes