From 8b042182626b94ed6380f0ba6b99c0e862aa710f Mon Sep 17 00:00:00 2001 From: Benjamin Nash Date: Mon, 27 Jun 2005 18:08:42 -0400 Subject: [PATCH] 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 --- dev/ide_ctrl.cc | 16 ++++--- dev/ide_disk.cc | 120 ++++++++++++++++++++++++++++++++---------------- dev/ide_disk.hh | 6 +-- dev/ns_gige.cc | 2 +- 4 files changed, 95 insertions(+), 49 deletions(-) diff --git a/dev/ide_ctrl.cc b/dev/ide_ctrl.cc index 0037e06e0..964bd01c2 100644 --- a/dev/ide_ctrl.cc +++ b/dev/ide_ctrl.cc @@ -412,14 +412,10 @@ IdeController::read(MemReqPtr &req, 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; if (!io_enabled) 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); if (type != BMI_BLOCK) { - assert(req->size != sizeof(uint32_t)); disk = getDisk(primary); 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 { memcpy((void *)data, &bmi_regs[offset], req->size); } diff --git a/dev/ide_disk.cc b/dev/ide_disk.cc index ae394c69e..555eb023e 100644 --- a/dev/ide_disk.cc +++ b/dev/ide_disk.cc @@ -208,46 +208,61 @@ IdeDisk::bytesInDmaPage(Addr curAddr, uint32_t bytesLeft) // Device registers read/write //// -void -IdeDisk::read(const Addr &offset, bool byte, bool cmdBlk, uint8_t *data) +uint16_t +IdeDisk::read(const Addr &offset, RegType_t type) { + + uint16_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 (type == COMMAND_BLOCK) { - if (!byte && offset != DATA_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) { + if (offset == STATUS_OFFSET) action = ACT_STAT_READ; - *data = status; // status is in a shadow, explicity copy - } else if (offset == DATA_OFFSET) { - if (byte) - action = ACT_DATA_READ_BYTE; - else - action = ACT_DATA_READ_SHORT; - } + else if (offset == DATA_OFFSET) + 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) - panic("Invalid disk control register offset: %#x\n", offset); + panic("Invalid IDE control register offset: %#x\n", offset); - if (!byte) - panic("Invalid 16-bit read from control block\n"); - - *data = status; + data = status; } if (action != ACT_NONE) updateState(action); + + return data; + } 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"); if (!byte) - *((uint16_t *)&cmdReg.data0) = *(uint16_t *)data; - else - ((uint8_t *)&cmdReg)[offset] = *data; + *((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) { @@ -746,9 +789,10 @@ IdeDisk::intrPost() intrPending = true; // talk to controller to set interrupt - if (ctrl) + if (ctrl){ ctrl->bmi_regs[BMIS0] |= IDEINTS; ctrl->intrPost(); + } } void @@ -867,7 +911,7 @@ IdeDisk::updateState(DevAction_t action) } // put the first two bytes into the data register - memcpy((void *)&cmdReg.data0, (void *)dataBuffer, + memcpy((void *)&cmdReg.data, (void *)dataBuffer, sizeof(uint16_t)); if (!isIENSet()) { @@ -896,7 +940,7 @@ IdeDisk::updateState(DevAction_t action) // copy next short into data registers if (drqBytesLeft) - memcpy((void *)&cmdReg.data0, + memcpy((void *)&cmdReg.data, (void *)&dataBuffer[SectorSize - drqBytesLeft], sizeof(uint16_t)); } @@ -969,7 +1013,7 @@ IdeDisk::updateState(DevAction_t action) } else { // copy the latest short into the data buffer memcpy((void *)&dataBuffer[SectorSize - drqBytesLeft], - (void *)&cmdReg.data0, + (void *)&cmdReg.data, sizeof(uint16_t)); drqBytesLeft -= 2; @@ -1093,8 +1137,7 @@ IdeDisk::serialize(ostream &os) SERIALIZE_ENUM(event); // Serialize device registers - SERIALIZE_SCALAR(cmdReg.data0); - SERIALIZE_SCALAR(cmdReg.data1); + SERIALIZE_SCALAR(cmdReg.data); SERIALIZE_SCALAR(cmdReg.sec_count); SERIALIZE_SCALAR(cmdReg.sec_num); SERIALIZE_SCALAR(cmdReg.cyl_low); @@ -1146,8 +1189,7 @@ IdeDisk::unserialize(Checkpoint *cp, const string §ion) } // Unserialize device registers - UNSERIALIZE_SCALAR(cmdReg.data0); - UNSERIALIZE_SCALAR(cmdReg.data1); + UNSERIALIZE_SCALAR(cmdReg.data); UNSERIALIZE_SCALAR(cmdReg.sec_count); UNSERIALIZE_SCALAR(cmdReg.sec_num); UNSERIALIZE_SCALAR(cmdReg.cyl_low); diff --git a/dev/ide_disk.hh b/dev/ide_disk.hh index 506f0c7cb..0fcd863ec 100644 --- a/dev/ide_disk.hh +++ b/dev/ide_disk.hh @@ -35,6 +35,7 @@ #include "dev/disk_image.hh" #include "dev/ide_atareg.h" +#include "dev/ide_ctrl.hh" #include "dev/ide_wdcreg.h" #include "dev/io_device.hh" #include "sim/eventq.hh" @@ -103,9 +104,8 @@ class PrdTableEntry { #define DEV1 (1) typedef struct CommandReg { - uint8_t data0; + uint16_t data; union { - uint8_t data1; uint8_t error; uint8_t features; }; @@ -272,7 +272,7 @@ class IdeDisk : public SimObject } // 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); // Start/abort functions diff --git a/dev/ns_gige.cc b/dev/ns_gige.cc index 108f2616c..25dfc87a4 100644 --- a/dev/ns_gige.cc +++ b/dev/ns_gige.cc @@ -1359,7 +1359,7 @@ void NSGigE::regsReset() { memset(®s, 0, sizeof(regs)); - regs.config = CFGR_LNKSTS; + regs.config = (CFGR_LNKSTS | CFGR_TBI_EN | CFGR_MODE_1000); regs.mear = 0x22; regs.txcfg = 0x120; // set drain threshold to 1024 bytes and // fill threshold to 32 bytes