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:
parent
0460a78829
commit
8b04218262
4 changed files with 95 additions and 49 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
120
dev/ide_disk.cc
120
dev/ide_disk.cc
|
@ -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 §ion)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -1359,7 +1359,7 @@ void
|
||||||
NSGigE::regsReset()
|
NSGigE::regsReset()
|
||||||
{
|
{
|
||||||
memset(®s, 0, sizeof(regs));
|
memset(®s, 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
|
||||||
|
|
Loading…
Reference in a new issue