diff options
Diffstat (limited to 'dev')
-rw-r--r-- | dev/ide_ctrl.cc | 141 | ||||
-rw-r--r-- | dev/ide_ctrl.hh | 36 | ||||
-rw-r--r-- | dev/ide_disk.cc | 121 | ||||
-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 | 26 | ||||
-rw-r--r-- | dev/tsunami_io.cc | 141 | ||||
-rw-r--r-- | dev/tsunami_io.hh | 24 | ||||
-rw-r--r-- | dev/tsunamireg.h | 12 |
10 files changed, 367 insertions, 144 deletions
diff --git a/dev/ide_ctrl.cc b/dev/ide_ctrl.cc index 785f18ae8..6636a5ff6 100644 --- a/dev/ide_ctrl.cc +++ b/dev/ide_ctrl.cc @@ -76,10 +76,10 @@ IdeController::IdeController(Params *p) // zero out all of the registers memset(bmi_regs, 0, sizeof(bmi_regs)); - memset(pci_regs, 0, sizeof(pci_regs)); + memset(pci_config_regs.data, 0, sizeof(pci_config_regs.data)); // setup initial values - *(uint32_t *)&pci_regs[IDETIM] = 0x80008000; // enable both channels + pci_config_regs.idetim = htoa((uint32_t)0x80008000); // enable both channels *(uint8_t *)&bmi_regs[BMIS0] = 0x60; *(uint8_t *)&bmi_regs[BMIS1] = 0x60; @@ -251,6 +251,7 @@ IdeController::cacheAccess(MemReqPtr &req) void IdeController::ReadConfig(int offset, int size, uint8_t *data) { + int config_offset; #if TRACING_ON Addr origOffset = offset; @@ -258,86 +259,67 @@ IdeController::ReadConfig(int offset, int size, uint8_t *data) if (offset < PCI_DEVICE_SPECIFIC) { PciDev::ReadConfig(offset, size, data); - } else { - if (offset >= PCI_IDE_TIMING && offset < (PCI_IDE_TIMING + 4)) { - offset -= PCI_IDE_TIMING; - offset += IDETIM; - - if ((offset + size) > (IDETIM + 4)) - panic("PCI read of IDETIM with invalid size\n"); - } else if (offset == PCI_SLAVE_TIMING) { - offset -= PCI_SLAVE_TIMING; - offset += SIDETIM; - - if ((offset + size) > (SIDETIM + 1)) - panic("PCI read of SIDETIM with invalid size\n"); - } else if (offset == PCI_UDMA33_CTRL) { - offset -= PCI_UDMA33_CTRL; - offset += UDMACTL; - - if ((offset + size) > (UDMACTL + 1)) - panic("PCI read of UDMACTL with invalid size\n"); - } else if (offset >= PCI_UDMA33_TIMING && - offset < (PCI_UDMA33_TIMING + 2)) { - offset -= PCI_UDMA33_TIMING; - offset += UDMATIM; - - if ((offset + size) > (UDMATIM + 2)) - panic("PCI read of UDMATIM with invalid size\n"); - } else { - panic("PCI read of unimplemented register: %x\n", offset); - } + } else if (offset >= IDE_CTRL_CONFIG_START && (offset + size) <= IDE_CTRL_CONFIG_END) { + + config_offset = offset - IDE_CTRL_CONFIG_START; + + switch(size) { + case sizeof(uint32_t): + memcpy(data, &pci_config_regs.data[config_offset], sizeof(uint32_t)); + *(uint32_t*)data = htoa(*(uint32_t*)data); + break; + + case sizeof(uint16_t): + memcpy(data, &pci_config_regs.data[config_offset], sizeof(uint16_t)); + *(uint16_t*)data = htoa(*(uint16_t*)data); + break; + + case sizeof(uint8_t): + memcpy(data, &pci_config_regs.data[config_offset], sizeof(uint8_t)); + break; - memcpy((void *)data, (void *)&pci_regs[offset], size); + default: + panic("Invalid PCI configuration read size!\n"); + } + } else { + panic("Read of unimplemented PCI config. register: %x\n", offset); } DPRINTF(IdeCtrl, "PCI read offset: %#x (%#x) size: %#x data: %#x\n", origOffset, offset, size, - (*(uint32_t *)data) & (0xffffffff >> 8 * (4 - size))); + *(uint32_t *)data & (0xffffffff >> 8 * (4 - size))); } void IdeController::WriteConfig(int offset, int size, uint32_t data) { - DPRINTF(IdeCtrl, "PCI write offset: %#x size: %#x data: %#x\n", - offset, size, data & (0xffffffff >> 8 * (4 - size))); + int config_offset; - // do standard write stuff if in standard PCI space if (offset < PCI_DEVICE_SPECIFIC) { PciDev::WriteConfig(offset, size, data); - } else { - if (offset >= PCI_IDE_TIMING && offset < (PCI_IDE_TIMING + 4)) { - offset -= PCI_IDE_TIMING; - offset += IDETIM; - - if ((offset + size) > (IDETIM + 4)) - panic("PCI write to IDETIM with invalid size\n"); - } else if (offset == PCI_SLAVE_TIMING) { - offset -= PCI_SLAVE_TIMING; - offset += SIDETIM; - - if ((offset + size) > (SIDETIM + 1)) - panic("PCI write to SIDETIM with invalid size\n"); - } else if (offset == PCI_UDMA33_CTRL) { - offset -= PCI_UDMA33_CTRL; - offset += UDMACTL; - - if ((offset + size) > (UDMACTL + 1)) - panic("PCI write to UDMACTL with invalid size\n"); - } else if (offset >= PCI_UDMA33_TIMING && - offset < (PCI_UDMA33_TIMING + 2)) { - offset -= PCI_UDMA33_TIMING; - offset += UDMATIM; - - if ((offset + size) > (UDMATIM + 2)) - panic("PCI write to UDMATIM with invalid size\n"); - } else { - panic("PCI write to unimplemented register: %x\n", offset); + } else if (offset >= IDE_CTRL_CONFIG_START && (offset + size) <= IDE_CTRL_CONFIG_END) { + + config_offset = offset - IDE_CTRL_CONFIG_START; + + switch(size) { + case sizeof(uint32_t): + case sizeof(uint16_t): + case sizeof(uint8_t): + memcpy(&pci_config_regs.data[config_offset], &data, size); + break; + + default: + panic("Invalid PCI configuration write size!\n"); } - memcpy((void *)&pci_regs[offset], (void *)&data, size); + } else { + panic("Write of unimplemented PCI config. register: %x\n", offset); } + DPRINTF(IdeCtrl, "PCI write offset: %#x size: %#x data: %#x\n", + offset, size, data & (0xffffffff >> 8 * (4 - size))); + + // Catch the writes to specific PCI registers that have side affects // (like updating the PIO ranges) switch (offset) { @@ -414,29 +396,38 @@ 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; // sanity check the size (allows byte, word, or dword access) - if (req->size != sizeof(uint8_t) && req->size != sizeof(uint16_t) && - req->size != sizeof(uint32_t)) + switch (req->size) { + case sizeof(uint8_t): + case sizeof(uint16_t): + case sizeof(uint32_t): + break; + default: 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)[0] = 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); } @@ -620,7 +611,7 @@ IdeController::serialize(std::ostream &os) // Serialize registers SERIALIZE_ARRAY(bmi_regs, 16); SERIALIZE_ARRAY(dev, 2); - SERIALIZE_ARRAY(pci_regs, 8); + SERIALIZE_ARRAY(pci_config_regs.data, 22); // Serialize internal state SERIALIZE_SCALAR(io_enabled); @@ -649,7 +640,7 @@ IdeController::unserialize(Checkpoint *cp, const std::string §ion) // Unserialize registers UNSERIALIZE_ARRAY(bmi_regs, 16); UNSERIALIZE_ARRAY(dev, 2); - UNSERIALIZE_ARRAY(pci_regs, 8); + UNSERIALIZE_ARRAY(pci_config_regs.data, 22); // Unserialize internal state UNSERIALIZE_SCALAR(io_enabled); diff --git a/dev/ide_ctrl.hh b/dev/ide_ctrl.hh index 4b54c3d57..2164f2f4a 100644 --- a/dev/ide_ctrl.hh +++ b/dev/ide_ctrl.hh @@ -64,15 +64,9 @@ #define IDE_COMMAND_OFFSET IDE_STATUS_OFFSET // PCI device specific register byte offsets -#define PCI_IDE_TIMING 0x40 -#define PCI_SLAVE_TIMING 0x44 -#define PCI_UDMA33_CTRL 0x48 -#define PCI_UDMA33_TIMING 0x4a +#define IDE_CTRL_CONFIG_START 0x40 +#define IDE_CTRL_CONFIG_END ((IDE_CTRL_CONFIG_START) + sizeof(pci_config_regs)) -#define IDETIM (0) -#define SIDETIM (4) -#define UDMACTL (5) -#define UDMATIM (6) typedef enum RegType { COMMAND_BLOCK = 0, @@ -119,8 +113,30 @@ class IdeController : public PciDev uint8_t bmi_regs[16]; /** Shadows of the device select bit */ uint8_t dev[2]; - /** Registers used in PCI configuration */ - uint8_t pci_regs[8]; + /** Registers used in device specific PCI configuration */ + union { + uint8_t data[22]; + + struct { + uint32_t idetim; + uint8_t sidetim; + uint8_t reserved_45; + uint8_t reserved_46; + uint8_t reserved_47; + uint8_t udmactl; + uint8_t reserved_49; + uint16_t udmatim; + uint8_t reserved_4c; + uint8_t reserved_4d; + uint8_t reserved_4e; + uint8_t reserved_4f; + uint8_t reserved_50; + uint8_t reserved_51; + uint8_t reserved_52; + uint8_t reserved_53; + uint16_t ideconfig; + }; + } pci_config_regs; // Internal management variables bool io_enabled; diff --git a/dev/ide_disk.cc b/dev/ide_disk.cc index 23d04bb5e..0d553fb83 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,59 @@ 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 = 0; 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"); + if (type == COMMAND_BLOCK) { - 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; + + 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 { + } + 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 +276,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 +787,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 +909,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 +938,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 +1011,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 +1135,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 +1187,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..7f4acea1c 100644 --- a/dev/pcidev.cc +++ b/dev/pcidev.cc @@ -78,33 +78,35 @@ PciDev::ReadConfig(int offset, int size, uint8_t *data) switch(size) { case sizeof(uint32_t): - memcpy((uint8_t*)data, config.data + offset, sizeof(uint32_t)); + memcpy(data, &config.data[offset], sizeof(uint32_t)); *(uint32_t*)data = htoa(*(uint32_t*)data); + DPRINTF(PCIDEV, "read device: %#x function: %#x register: %#x %d bytes: data: %#x\n", params()->deviceNum, params()->functionNum, offset, size, - *(uint32_t*)(config.data + offset)); + *(uint32_t*)data); break; case sizeof(uint16_t): - memcpy((uint8_t*)data, config.data + offset, sizeof(uint16_t)); + memcpy(data, &config.data[offset], sizeof(uint16_t)); *(uint16_t*)data = htoa(*(uint16_t*)data); + DPRINTF(PCIDEV, "read device: %#x function: %#x register: %#x %d bytes: data: %#x\n", params()->deviceNum, params()->functionNum, offset, size, - *(uint16_t*)(config.data + offset)); + *(uint16_t*)data); break; case sizeof(uint8_t): - memcpy((uint8_t*)data, config.data + offset, sizeof(uint8_t)); + memcpy(data, &config.data[offset], sizeof(uint8_t)); DPRINTF(PCIDEV, "read device: %#x function: %#x register: %#x %d bytes: data: %#x\n", params()->deviceNum, params()->functionNum, offset, size, - (uint16_t)(*(uint8_t*)(config.data + offset))); + *data); break; default: - panic("Invalid Read Size"); + panic("Invalid PCI configuration read size!\n"); } } @@ -138,7 +140,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 +200,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..6e517d431 100644 --- a/dev/tsunami_io.cc +++ b/dev/tsunami_io.cc @@ -52,11 +52,14 @@ 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); } @@ -67,6 +70,12 @@ 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 * @@ -104,6 +113,11 @@ TsunamiIO::ClockEvent::ClockEvent() DPRINTF(Tsunami, "Clock Event Initilizing\n"); mode = 0; + + current_count = 0; + latched_count = 0; + latch_on = false; + read_byte = READ_LSB; } void @@ -114,6 +128,8 @@ TsunamiIO::ClockEvent::process() status = 0x20; // set bit that linux is looking for else schedule(curTick + interval); + + current_count--; //decrement count } void @@ -122,6 +138,8 @@ TsunamiIO::ClockEvent::Program(int count) DPRINTF(Tsunami, "Timer set to curTick + %d\n", count * interval); schedule(curTick + count * interval); status = 0; + + current_count = (uint16_t)count; } const char * @@ -143,6 +161,51 @@ TsunamiIO::ClockEvent::Status() } void +TsunamiIO::ClockEvent::LatchCount() +{ + // behave like a real latch + if(!latch_on) { + latch_on = true; + read_byte = READ_LSB; + latched_count = current_count; + } +} + +uint8_t +TsunamiIO::ClockEvent::Read() +{ + uint8_t result = 0; + + if(latch_on) { + switch (read_byte) { + case READ_LSB: + read_byte = READ_MSB; + result = (uint8_t)latched_count; + break; + case READ_MSB: + read_byte = READ_LSB; + latch_on = false; + result = latched_count >> 8; + break; + } + } else { + switch (read_byte) { + case READ_LSB: + read_byte = READ_MSB; + result = (uint8_t)current_count; + break; + case READ_MSB: + read_byte = READ_LSB; + result = current_count >> 8; + break; + } + } + + return result; +} + + +void TsunamiIO::ClockEvent::serialize(std::ostream &os) { Tick time = scheduled() ? when() : 0; @@ -207,12 +270,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 +296,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 +330,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 +341,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 +391,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 +437,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 +494,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..4b28635e8 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,14 @@ class TsunamiIO : public PioDevice uint8_t mode; /** The status of the PIT */ uint8_t status; + /** The current count of the PIT */ + uint16_t current_count; + /** The latched count of the PIT */ + uint16_t latched_count; + /** The state of the output latch of the PIT */ + bool latch_on; + /** The next count half (byte) to read */ + enum {READ_LSB, READ_MSB} read_byte; public: /** @@ -111,6 +119,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. */ @@ -135,6 +154,9 @@ 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 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 |