diff options
Diffstat (limited to 'dev')
-rw-r--r-- | dev/ide_ctrl.cc | 16 | ||||
-rw-r--r-- | dev/ide_disk.cc | 125 | ||||
-rw-r--r-- | dev/ide_disk.hh | 6 | ||||
-rw-r--r-- | dev/ns_gige.cc | 2 | ||||
-rw-r--r-- | dev/ns_gige.hh | 2 | ||||
-rw-r--r-- | dev/pcidev.cc | 10 | ||||
-rw-r--r-- | dev/tsunami_io.cc | 127 | ||||
-rw-r--r-- | dev/tsunami_io.hh | 25 | ||||
-rw-r--r-- | dev/tsunamireg.h | 12 |
9 files changed, 266 insertions, 59 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 23d04bb5e..555eb023e 100644 --- a/dev/ide_disk.cc +++ b/dev/ide_disk.cc @@ -134,6 +134,8 @@ 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; @@ -206,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) { - 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 read, only allowed on data reg\n"); + uint16_t data; + DevAction_t action = ACT_NONE; - if (!byte) - *(uint16_t *)data = *(uint16_t *)&cmdReg.data0; - else - *data = ((uint8_t *)&cmdReg)[offset]; + if (type == COMMAND_BLOCK) { - // 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 { + else if (offset == DATA_OFFSET) + action = ACT_DATA_READ_SHORT; + + 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); - - if (!byte) - panic("Invalid 16-bit read from control block\n"); + panic("Invalid IDE control register offset: %#x\n", offset); - *data = status; + data = status; } if (action != ACT_NONE) updateState(action); + + return data; + } void @@ -261,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) { @@ -744,8 +789,10 @@ IdeDisk::intrPost() intrPending = true; // talk to controller to set interrupt - if (ctrl) + if (ctrl){ + ctrl->bmi_regs[BMIS0] |= IDEINTS; ctrl->intrPost(); + } } void @@ -864,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()) { @@ -893,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)); } @@ -966,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; @@ -1090,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); @@ -1143,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 4e7deba90..0d446214d 100644 --- a/dev/ns_gige.cc +++ b/dev/ns_gige.cc @@ -1360,7 +1360,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 diff --git a/dev/ns_gige.hh b/dev/ns_gige.hh index 143460b64..67f1b7ef5 100644 --- a/dev/ns_gige.hh +++ b/dev/ns_gige.hh @@ -99,7 +99,7 @@ class Bus; class PciConfigAll; /** - * NS DP82830 Ethernet device model + * NS DP83820 Ethernet device model */ class NSGigE : public PciDev { diff --git a/dev/pcidev.cc b/dev/pcidev.cc index f2bce33ca..93200a8c7 100644 --- a/dev/pcidev.cc +++ b/dev/pcidev.cc @@ -138,7 +138,13 @@ PciDev::WriteConfig(int offset, int size, uint32_t data) case PCI_LATENCY_TIMER: *(uint8_t *)&config.data[offset] = htoa(byte_value); break; - + /* Do nothing for these read-only registers */ + case PCI0_INTERRUPT_PIN: + case PCI0_MINIMUM_GRANT: + case PCI0_MAXIMUM_LATENCY: + case PCI_CLASS_CODE: + case PCI_REVISION_ID: + break; default: panic("writing to a read only register"); } @@ -192,7 +198,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]; diff --git a/dev/tsunami_io.cc b/dev/tsunami_io.cc index da1062237..963bdc321 100644 --- a/dev/tsunami_io.cc +++ b/dev/tsunami_io.cc @@ -52,6 +52,8 @@ 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) @@ -63,10 +65,16 @@ TsunamiIO::RTCEvent::RTCEvent(Tsunami* t, Tick i) void TsunamiIO::RTCEvent::process() { + static int intr_count = 0; DPRINTF(MC146818, "RTC Timer Interrupt\n"); 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 * @@ -104,6 +112,11 @@ TsunamiIO::ClockEvent::ClockEvent() DPRINTF(Tsunami, "Clock Event Initilizing\n"); mode = 0; + + current_count.whole = 0; + latched_count.whole = 0; + latch_on = false; + read_msb = false; } void @@ -114,6 +127,8 @@ TsunamiIO::ClockEvent::process() status = 0x20; // set bit that linux is looking for else schedule(curTick + interval); + + current_count.whole--; //decrement count } void @@ -122,6 +137,8 @@ TsunamiIO::ClockEvent::Program(int count) DPRINTF(Tsunami, "Timer set to curTick + %d\n", count * interval); schedule(curTick + count * interval); status = 0; + + current_count.whole = count; } const char * @@ -143,6 +160,38 @@ TsunamiIO::ClockEvent::Status() } void +TsunamiIO::ClockEvent::LatchCount() +{ + if(!latch_on) { + latch_on = true; + read_msb = false; + latched_count.whole = current_count.whole; + } +} + +uint8_t +TsunamiIO::ClockEvent::Read() +{ + if(latch_on) { + if(!read_msb) { + read_msb = true; + return latched_count.half.lsb; + } else { + latch_on = false; + return latched_count.half.msb; + } + } else { + if(!read_msb) { + read_msb = true; + return current_count.half.lsb; + } else { + return current_count.half.msb; + } + } +} + + +void TsunamiIO::ClockEvent::serialize(std::ostream &os) { Tick time = scheduled() ? when() : 0; @@ -207,12 +256,19 @@ TsunamiIO::read(MemReqPtr &req, uint8_t *data) DPRINTF(Tsunami, "io read va=%#x size=%d IOPorrt=%#x\n", req->vaddr, req->size, req->vaddr & 0xfff); - Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)); + Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)) + 0x20; switch(req->size) { case sizeof(uint8_t): switch(daddr) { + // PIC1 mask read + case TSDEV_PIC1_MASK: + *(uint8_t*)data = ~mask1; + return No_Fault; + case TSDEV_PIC2_MASK: + *(uint8_t*)data = ~mask2; + return No_Fault; case TSDEV_PIC1_ISR: // !!! If this is modified 64bit case needs to be too // Pal code has to do a 64 bit physical read because there is @@ -226,6 +282,9 @@ TsunamiIO::read(MemReqPtr &req, uint8_t *data) case TSDEV_TMR_CTL: *(uint8_t*)data = timer2.Status(); return No_Fault; + case TSDEV_TMR0_DATA: + *(uint8_t *)data = timer0.Read(); + return No_Fault; case TSDEV_RTC_DATA: switch(RTCAddress) { case RTC_CNTRL_REGA: @@ -257,6 +316,7 @@ TsunamiIO::read(MemReqPtr &req, uint8_t *data) return No_Fault; case RTC_DOM: *(uint8_t *)data = tm.tm_mday; + return No_Fault; case RTC_MON: *(uint8_t *)data = tm.tm_mon + 1; return No_Fault; @@ -267,6 +327,14 @@ TsunamiIO::read(MemReqPtr &req, uint8_t *data) 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); } @@ -309,7 +377,7 @@ TsunamiIO::write(MemReqPtr &req, const uint8_t *data) DPRINTF(Tsunami, "io write - va=%#x size=%d IOPort=%#x Data=%#x\n", req->vaddr, req->size, req->vaddr & 0xfff, dt64); - Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)); + Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)) + 0x20; switch(req->size) { case sizeof(uint8_t): @@ -355,8 +423,24 @@ TsunamiIO::write(MemReqPtr &req, const uint8_t *data) case TSDEV_TMR_CTL: return No_Fault; case TSDEV_TMR2_CTL: - if ((*(uint8_t*)data & 0x30) != 0x30) - panic("Only L/M write supported\n"); + switch((*(uint8_t*)data >> 4) & 0x3) { + case 0x0: + switch(*(uint8_t*)data >> 6) { + case 0: + timer0.LatchCount(); + break; + case 2: + timer2.LatchCount(); + break; + default: + panic("Read Back Command not implemented\n"); + } + break; + case 0x3: + break; + default: + panic("Only L/M write and Counter-Latch read supported\n"); + } switch(*(uint8_t*)data >> 6) { case 0: @@ -396,8 +480,41 @@ TsunamiIO::write(MemReqPtr &req, const uint8_t *data) case TSDEV_RTC_ADDR: RTCAddress = *(uint8_t*)data; return No_Fault; + case TSDEV_KBD: + return No_Fault; case TSDEV_RTC_DATA: - panic("RTC Write not implmented (rtc.o won't work)\n"); + switch(RTCAddress) { + case RTC_CNTRL_REGA: + return No_Fault; + case RTC_CNTRL_REGB: + return No_Fault; + case RTC_CNTRL_REGC: + return No_Fault; + case RTC_CNTRL_REGD: + return No_Fault; + case RTC_SEC: + tm.tm_sec = *(uint8_t *)data; + return No_Fault; + case RTC_MIN: + tm.tm_min = *(uint8_t *)data; + return No_Fault; + case RTC_HR: + tm.tm_hour = *(uint8_t *)data; + return No_Fault; + case RTC_DOW: + tm.tm_wday = *(uint8_t *)data; + return No_Fault; + case RTC_DOM: + tm.tm_mday = *(uint8_t *)data; + return No_Fault; + case RTC_MON: + tm.tm_mon = *(uint8_t *)data - 1; + return No_Fault; + case RTC_YEAR: + tm.tm_year = *(uint8_t *)data + UNIX_YEAR_OFFSET; + 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); } diff --git a/dev/tsunami_io.hh b/dev/tsunami_io.hh index d5d106db3..dca651d4b 100644 --- a/dev/tsunami_io.hh +++ b/dev/tsunami_io.hh @@ -51,7 +51,7 @@ class TsunamiIO : public PioDevice /** The size of mappad from the above address */ static const Addr size = 0xff; - struct tm tm; + static struct tm tm; /** * In Tsunami RTC only has two i/o ports one for data and one for @@ -75,6 +75,18 @@ class TsunamiIO : public PioDevice uint8_t mode; /** The status of the PIT */ uint8_t status; + /** The counts (current and latched) of the PIT */ + union { + uint16_t whole; + struct { + uint8_t msb; + uint8_t lsb; + } half; + } current_count, latched_count; + + /** Thse state of the output latch of the PIT */ + bool latch_on; + bool read_msb; public: /** @@ -111,6 +123,17 @@ class TsunamiIO : public PioDevice uint8_t Status(); /** + * Latch the count of the PIT. + */ + void LatchCount(); + + /** + * The current PIT count. + * @return the count of the PIT + */ + uint8_t Read(); + + /** * Serialize this object to the given output stream. * @param os The stream to serialize to. */ diff --git a/dev/tsunamireg.h b/dev/tsunamireg.h index 5fbfd5c31..8b290deb1 100644 --- a/dev/tsunamireg.h +++ b/dev/tsunamireg.h @@ -123,6 +123,18 @@ #define TSDEV_TMR2_DATA 0x42 #define TSDEV_TMR0_DATA 0x40 +/* Added for keyboard accesses */ +#define TSDEV_KBD 0x64 + +/* Added for ATA PCI DMA */ +#define ATA_PCI_DMA 0x00 +#define ATA_PCI_DMA2 0x02 +#define ATA_PCI_DMA3 0x16 +#define ATA_PCI_DMA4 0x17 +#define ATA_PCI_DMA5 0x1a +#define ATA_PCI_DMA6 0x11 +#define ATA_PCI_DMA7 0x14 + #define TSDEV_RTC_ADDR 0x70 #define TSDEV_RTC_DATA 0x71 |