From 32b52fe7126091692c0a76314bb3692fa3f70d27 Mon Sep 17 00:00:00 2001 From: Benjamin Nash Date: Wed, 13 Jul 2005 12:30:13 -0400 Subject: Various changes to m5/dev files to work with FreeBSD. dev/ide_ctrl.cc: dev/ide_disk.cc: dev/pcidev.cc: Made endian-independent. dev/ide_disk.hh: fixed. dev/pciconfigall.cc: The data to write is contained in a 32-bit unsigned int now. The union method would not have worked on big-endian machines. dev/pcidev.hh: Fixed typo. dev/tsunami_io.cc: Return zero on RTC alarm reads. dev/uart8250.cc: Fix uart interrupt handling. --HG-- extra : convert_revision : b5c08e8e77644c399c20888666406805ff1b6649 --- dev/ide_ctrl.cc | 124 +++++++++++++++++++++++++++++++++++----------------- dev/ide_disk.cc | 63 +++++++++++++------------- dev/ide_disk.hh | 8 ++-- dev/pciconfigall.cc | 10 ++--- dev/pcidev.cc | 72 +++++++++++++++--------------- dev/pcidev.hh | 2 +- dev/tsunami_io.cc | 10 ++++- dev/uart8250.cc | 9 ++-- 8 files changed, 174 insertions(+), 124 deletions(-) (limited to 'dev') diff --git a/dev/ide_ctrl.cc b/dev/ide_ctrl.cc index 6636a5ff6..171f59a33 100644 --- a/dev/ide_ctrl.cc +++ b/dev/ide_ctrl.cc @@ -251,49 +251,57 @@ IdeController::cacheAccess(MemReqPtr &req) void IdeController::ReadConfig(int offset, int size, uint8_t *data) { - int config_offset; + union { + uint8_t byte; + uint16_t word; + uint32_t dword; + }; -#if TRACING_ON - Addr origOffset = offset; -#endif + int config_offset; if (offset < PCI_DEVICE_SPECIFIC) { PciDev::ReadConfig(offset, size, data); } else if (offset >= IDE_CTRL_CONFIG_START && (offset + size) <= IDE_CTRL_CONFIG_END) { config_offset = offset - IDE_CTRL_CONFIG_START; + dword = 0; - switch(size) { + switch (size) { + case sizeof(uint8_t): + case sizeof(uint16_t): case sizeof(uint32_t): - memcpy(data, &pci_config_regs.data[config_offset], sizeof(uint32_t)); - *(uint32_t*)data = htoa(*(uint32_t*)data); + memcpy(&byte, &pci_config_regs.data[config_offset], size); break; - case sizeof(uint16_t): - memcpy(data, &pci_config_regs.data[config_offset], sizeof(uint16_t)); - *(uint16_t*)data = htoa(*(uint16_t*)data); - break; + default: + panic("Invalid PCI configuration read size!\n"); + } + switch (size) { case sizeof(uint8_t): - memcpy(data, &pci_config_regs.data[config_offset], sizeof(uint8_t)); + *data = byte; + break; + case sizeof(uint16_t): + *(uint16_t*)data = htoa(word); + break; + case sizeof(uint32_t): + *(uint32_t*)data = htoa(dword); break; - - default: - panic("Invalid PCI configuration read size!\n"); } + + DPRINTF(IdeCtrl, "PCI read offset: %#x size: %#x data: %#x\n", + offset, size, htoa(dword)); + } 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))); } void IdeController::WriteConfig(int offset, int size, uint32_t data) { int config_offset; + uint32_t write_data; if (offset < PCI_DEVICE_SPECIFIC) { PciDev::WriteConfig(offset, size, data); @@ -301,24 +309,24 @@ IdeController::WriteConfig(int offset, int size, uint32_t data) config_offset = offset - IDE_CTRL_CONFIG_START; + write_data = htoa(data); + switch(size) { - case sizeof(uint32_t): - case sizeof(uint16_t): case sizeof(uint8_t): - memcpy(&pci_config_regs.data[config_offset], &data, size); + case sizeof(uint16_t): + case sizeof(uint32_t): + memcpy(&pci_config_regs.data[config_offset], &write_data, size); break; default: panic("Invalid PCI configuration write size!\n"); } - } 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))); - + offset, size, data); // Catch the writes to specific PCI registers that have side affects // (like updating the PIO ranges) @@ -399,6 +407,12 @@ IdeController::read(MemReqPtr &req, uint8_t *data) RegType_t type; int disk; + union { + uint8_t byte; + uint16_t word[2]; + uint32_t dword; + }; + parseAddr(req->paddr, offset, primary, type); if (!io_enabled) @@ -414,27 +428,59 @@ IdeController::read(MemReqPtr &req, uint8_t *data) panic("IDE controller read of invalid size: %#x\n", req->size); } - if (type != BMI_BLOCK) { + switch (type) { + case BMI_BLOCK: + memcpy(&byte, &bmi_regs[offset], req->size); + switch (req->size) { + case sizeof(uint8_t): + *data = byte; + break; + case sizeof(uint16_t): + *(uint16_t*)data = htoa(word[0]); + break; + case sizeof(uint32_t): + *(uint32_t*)data = htoa(dword); + break; + } + break; + case COMMAND_BLOCK: + case CONTROL_BLOCK: disk = getDisk(primary); - if (disks[disk]) - 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) { + + if (disks[disk] == NULL) + break; + + switch (offset) { + case DATA_OFFSET: + switch (req->size) { + case sizeof(uint16_t): + disks[disk]->read(offset, type, (uint8_t*)&word[0]); + *(uint16_t*)data = htoa(word[0]); + break; + + case sizeof(uint32_t): + disks[disk]->read(offset, type, (uint8_t*)&word[0]); + disks[disk]->read(offset, type, (uint8_t*)&word[1]); + *(uint32_t*)data = htoa(dword); + break; + + default: 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); + break; + default: + if (req->size == sizeof(uint8_t)) { + disks[disk]->read(offset, type, &byte); + *data = byte; + } else + panic("IDE read of command reg of invalid size: %#x\n", req->size); + } + break; } DPRINTF(IdeCtrl, "read from offset: %#x size: %#x data: %#x\n", - offset, req->size, - (*(uint32_t *)data) & (0xffffffff >> 8 * (4 - req->size))); + offset, req->size, htoa(dword)); return No_Fault; } diff --git a/dev/ide_disk.cc b/dev/ide_disk.cc index 3d7bd19c0..98f2ee7d5 100644 --- a/dev/ide_disk.cc +++ b/dev/ide_disk.cc @@ -116,6 +116,9 @@ IdeDisk::IdeDisk(const string &name, DiskImage *img, PhysicalMemory *phys, driveID.atap_udmamode_supp = 0x10; // Statically set hardware config word driveID.atap_hwreset_res = 0x4001; + + //arbitrary for now... + driveID.atap_ata_major = WDC_VER_ATA7; } IdeDisk::~IdeDisk() @@ -134,7 +137,6 @@ 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; @@ -159,6 +161,8 @@ IdeDisk::reset(int id) // set the device ready bit status = STATUS_DRDY_BIT; + + cmdReg.error = 0x1; } //// @@ -207,62 +211,63 @@ IdeDisk::bytesInDmaPage(Addr curAddr, uint32_t bytesLeft) // Device registers read/write //// -uint16_t -IdeDisk::read(const Addr &offset, RegType_t type) +void +IdeDisk::read(const Addr &offset, RegType_t type, uint8_t *data) { - uint16_t data; DevAction_t action = ACT_NONE; - if (type == COMMAND_BLOCK) { - + switch (type) { + case COMMAND_BLOCK: if (offset == STATUS_OFFSET) action = ACT_STAT_READ; else if (offset == DATA_OFFSET) action = ACT_DATA_READ_SHORT; switch (offset) { + // Data transfers occur 16 bits at a time case DATA_OFFSET: - data = cmdReg.data; + // use memcpy to preserve little-endianess + memcpy(data, &cmdReg.data, sizeof(uint16_t)); break; + // All other transfers are 8 bit case ERROR_OFFSET: - data = cmdReg.error; + *data = cmdReg.error; break; case NSECTOR_OFFSET: - data = cmdReg.sec_count; + *data = cmdReg.sec_count; break; case SECTOR_OFFSET: - data = cmdReg.sec_num; + *data = cmdReg.sec_num; break; case LCYL_OFFSET: - data = cmdReg.cyl_low; + *data = cmdReg.cyl_low; break; case HCYL_OFFSET: - data = cmdReg.cyl_high; + *data = cmdReg.cyl_high; break; - case SELECT_OFFSET: - data = cmdReg.drive; + case DRIVE_OFFSET: + *data = cmdReg.drive; break; case STATUS_OFFSET: - data = status; + *data = status; break; default: panic("Invalid IDE command register offset: %#x\n", offset); } - } - else if (type == CONTROL_BLOCK) { - if (offset != ALTSTAT_OFFSET) + break; + case CONTROL_BLOCK: + if (offset == ALTSTAT_OFFSET) + *data = status; + else panic("Invalid IDE control register offset: %#x\n", offset); + break; - data = status; - } - else { - panic("Invalid IDE register type: %#x\n", type); + default: + panic("Unknown register block!\n"); } if (action != ACT_NONE) updateState(action); - - return data; } void @@ -271,8 +276,6 @@ IdeDisk::write(const Addr &offset, bool byte, bool cmdBlk, const uint8_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 (!byte && offset != DATA_OFFSET) panic("Invalid 16-bit write, only allowed on data reg\n"); @@ -282,10 +285,10 @@ IdeDisk::write(const Addr &offset, bool byte, bool cmdBlk, const uint8_t *data) else { switch (offset) { case DATA_OFFSET: - cmdReg.data = *data; + memcpy(&cmdReg.data, data, sizeof(uint16_t)); break; case FEATURES_OFFSET: - cmdReg.features = *data; + //cmdReg.features = *data; break; case NSECTOR_OFFSET: cmdReg.sec_count = *data; @@ -299,7 +302,7 @@ IdeDisk::write(const Addr &offset, bool byte, bool cmdBlk, const uint8_t *data) case HCYL_OFFSET: cmdReg.cyl_high = *data; break; - case SELECT_OFFSET: + case DRIVE_OFFSET: cmdReg.drive = *data; break; case COMMAND_OFFSET: @@ -318,7 +321,7 @@ IdeDisk::write(const Addr &offset, bool byte, bool cmdBlk, const uint8_t *data) action = ACT_DATA_WRITE_BYTE; else action = ACT_DATA_WRITE_SHORT; - } else if (offset == SELECT_OFFSET) { + } else if (offset == DRIVE_OFFSET) { action = ACT_SELECT_WRITE; } diff --git a/dev/ide_disk.hh b/dev/ide_disk.hh index 0fcd863ec..9799e2d38 100644 --- a/dev/ide_disk.hh +++ b/dev/ide_disk.hh @@ -84,6 +84,7 @@ class PrdTableEntry { #define LCYL_OFFSET (4) #define HCYL_OFFSET (5) #define SELECT_OFFSET (6) +#define DRIVE_OFFSET (6) #define STATUS_OFFSET (7) #define COMMAND_OFFSET (7) @@ -105,10 +106,7 @@ class PrdTableEntry { typedef struct CommandReg { uint16_t data; - union { - uint8_t error; - uint8_t features; - }; + uint8_t error; uint8_t sec_count; uint8_t sec_num; uint8_t cyl_low; @@ -272,7 +270,7 @@ class IdeDisk : public SimObject } // Device register read/write - uint16_t read(const Addr &offset, RegType_t type); + void read(const Addr &offset, RegType_t type, uint8_t *data); void write(const Addr &offset, bool byte, bool cmdBlk, const uint8_t *data); // Start/abort functions diff --git a/dev/pciconfigall.cc b/dev/pciconfigall.cc index 7d86c3e1b..6a4d60d1b 100644 --- a/dev/pciconfigall.cc +++ b/dev/pciconfigall.cc @@ -152,21 +152,17 @@ PciConfigAll::write(MemReqPtr &req, const uint8_t *data) int func = (daddr >> 8) & 0x7; int reg = daddr & 0xFF; - union { - uint8_t byte_value; - uint16_t half_value; - uint32_t word_value; - }; + uint32_t word_value = 0; if (devices[device][func] == NULL) panic("Attempting to write to config space on non-existant device\n"); else { switch (req->size) { case sizeof(uint8_t): - byte_value = *(uint8_t*)data; + word_value = *(uint8_t*)data & 0x000000FF; break; case sizeof(uint16_t): - half_value = *(uint16_t*)data; + word_value = *(uint16_t*)data & 0x0000FFFF; break; case sizeof(uint32_t): word_value = *(uint32_t*)data; diff --git a/dev/pcidev.cc b/dev/pcidev.cc index 7f4acea1c..b003d3987 100644 --- a/dev/pcidev.cc +++ b/dev/pcidev.cc @@ -73,41 +73,44 @@ PciDev::PciDev(Params *p) void PciDev::ReadConfig(int offset, int size, uint8_t *data) { + union { + uint8_t byte; + uint16_t word; + uint32_t dword; + }; + + dword = 0; + if (offset >= PCI_DEVICE_SPECIFIC) panic("Device specific PCI config space not implemented!\n"); switch(size) { + case sizeof(uint8_t): + case sizeof(uint16_t): case 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*)data); + memcpy(&byte, &config.data[offset], size); break; - case 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*)data); - break; + default: + panic("Invalid PCI configuration read size!\n"); + } + switch(size) { case 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, - *data); + *data = byte; + break; + case sizeof(uint16_t): + *(uint16_t*)data = htoa(word); + break; + case sizeof(uint32_t): + *(uint32_t*)data = htoa(dword); break; - - default: - panic("Invalid PCI configuration read size!\n"); } + + DPRINTF(PCIDEV, + "read device: %#x function: %#x register: %#x %d bytes: data: %#x\n", + params()->deviceNum, params()->functionNum, offset, size, + htoa(dword)); } void @@ -118,17 +121,14 @@ PciDev::WriteConfig(int offset, int size, uint32_t data) uint32_t barnum; - union { - uint8_t byte_value; - uint16_t half_value; - uint32_t word_value; - }; - word_value = data; + uint8_t byte_value = data; + uint16_t half_value = data; + uint32_t word_value = data; DPRINTF(PCIDEV, "write device: %#x function: %#x reg: %#x size: %d data: %#x\n", params()->deviceNum, params()->functionNum, offset, size, - word_value); + data); barnum = (offset - PCI0_BASE_ADDR0) >> 2; @@ -165,9 +165,6 @@ PciDev::WriteConfig(int offset, int size, uint32_t data) } break; - case sizeof(uint16_t)+1: // 3-byte access - panic("invalid access size"); - case sizeof(uint32_t): // 4-byte access switch (offset) { case PCI0_BASE_ADDR0: @@ -183,12 +180,12 @@ PciDev::WriteConfig(int offset, int size, uint32_t data) // This is I/O Space, bottom two bits are read only if (htoa(config.data[offset]) & 0x1) { *(uint32_t *)&config.data[offset] = htoa( - ~(BARSize[barnum] - 1) | + (~(BARSize[barnum] - 1) & ~0x3) | (htoa(config.data[offset]) & 0x3)); } else { // This is memory space, bottom four bits are read only *(uint32_t *)&config.data[offset] = htoa( - ~(BARSize[barnum] - 1) | + (~(BARSize[barnum] - 1) & ~0xF) | (htoa(config.data[offset]) & 0xF)); } } else { @@ -263,6 +260,9 @@ PciDev::WriteConfig(int offset, int size, uint32_t data) DPRINTF(PCIDEV, "Writing to a read only register"); } break; + + default: + panic("invalid access size"); } } diff --git a/dev/pcidev.hh b/dev/pcidev.hh index 091a365e3..31b0cab16 100644 --- a/dev/pcidev.hh +++ b/dev/pcidev.hh @@ -115,7 +115,7 @@ class PciDev : public DmaDevice protected: /** The current config space. Unlike the PciConfigData this is - * updated during simulation while continues to refelect what was + * updated during simulation while continues to reflect what was * in the config file. */ PCIConfig config; diff --git a/dev/tsunami_io.cc b/dev/tsunami_io.cc index 6e517d431..6a704f7ac 100644 --- a/dev/tsunami_io.cc +++ b/dev/tsunami_io.cc @@ -270,7 +270,7 @@ 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)) + 0x20; + Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)); switch(req->size) { @@ -319,6 +319,12 @@ TsunamiIO::read(MemReqPtr &req, uint8_t *data) case RTC_SEC: *(uint8_t *)data = tm.tm_sec; return No_Fault; + case RTC_SEC_ALRM: + case RTC_MIN_ALRM: + case RTC_HR_ALRM: + // RTC alarm functionality is not currently implemented + *(uint8_t *)data = 0x00; + return No_Fault; case RTC_MIN: *(uint8_t *)data = tm.tm_min; return No_Fault; @@ -391,7 +397,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)) + 0x20; + Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)); switch(req->size) { case sizeof(uint8_t): diff --git a/dev/uart8250.cc b/dev/uart8250.cc index 99e3bd017..63756042a 100644 --- a/dev/uart8250.cc +++ b/dev/uart8250.cc @@ -88,7 +88,7 @@ Uart8250::IntrEvent::process() void Uart8250::IntrEvent::scheduleIntr() { - static const Tick interval = (Tick)((Clock::Float::s / 2e9) * 450); + static const Tick interval = (Tick)((Clock::Float::s / 2e9) * 600); DPRINTF(Uart, "Scheduling IER interrupt for %#x, at cycle %lld\n", intrBit, curTick + interval); if (!scheduled()) @@ -146,10 +146,11 @@ Uart8250::read(MemReqPtr &req, uint8_t *data) break; case 0x2: // Intr Identification Register (IIR) DPRINTF(Uart, "IIR Read, status = %#x\n", (uint32_t)status); - if (status) - *(uint8_t*)data = 0; + status &= ~TX_INT; + if (status & RX_INT) + *(uint8_t*)data = 0x4; else - *(uint8_t*)data = 1; + *(uint8_t*)data = 0x1; break; case 0x3: // Line Control Register (LCR) *(uint8_t*)data = LCR; -- cgit v1.2.3