From 6a8ae7a6a040876e697dfa8b837e1ba1bd7e1fd5 Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Thu, 28 Jul 2005 11:47:06 -0400 Subject: ghgfsdf dev/pciconfigall.cc: removed union. dev/pcidev.cc: . dev/rtcreg.h: more macros to avoid magic numbers. dev/tsunami_io.cc: replaced magic numbers, no more advancing RTC as it isn't reaaly necessary. dev/tsunami_io.hh: removed declarations of things that go unused. dev/uart8250.cc: reading the Interrupt ID register should clear TX interrupt flag. dev/uart8250.hh: useful #defines. kern/freebsd/freebsd_system.cc: kern/freebsd/freebsd_system.hh: nothing. python/m5/objects/Pci.py: new PciFake. --HG-- extra : convert_revision : 88259704f5b215591d1416360180810fcda14d26 --- dev/pciconfigall.cc | 10 +++----- dev/pcidev.cc | 69 ++++++++++++++++++++++++----------------------------- dev/rtcreg.h | 14 +++++++++++ dev/tsunami_io.cc | 65 ++++++++++++++++++++++++++++++------------------- dev/tsunami_io.hh | 11 ++++----- dev/uart8250.cc | 7 +++--- dev/uart8250.hh | 3 +++ 7 files changed, 100 insertions(+), 79 deletions(-) (limited to 'dev') diff --git a/dev/pciconfigall.cc b/dev/pciconfigall.cc index 7d86c3e1b..8c6657ceb 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; break; case sizeof(uint16_t): - half_value = *(uint16_t*)data; + word_value = *(uint16_t*)data; break; case sizeof(uint32_t): word_value = *(uint32_t*)data; diff --git a/dev/pcidev.cc b/dev/pcidev.cc index 7f4acea1c..c74fb035c 100644 --- a/dev/pcidev.cc +++ b/dev/pcidev.cc @@ -73,41 +73,38 @@ PciDev::PciDev(Params *p) void PciDev::ReadConfig(int offset, int size, uint8_t *data) { + union { + uint8_t byte; + uint16_t word; + uint32_t dword; + }; + if (offset >= PCI_DEVICE_SPECIFIC) panic("Device specific PCI config space not implemented!\n"); - switch(size) { - case sizeof(uint32_t): - memcpy(data, &config.data[offset], sizeof(uint32_t)); - *(uint32_t*)data = htoa(*(uint32_t*)data); + dword = 0; - DPRINTF(PCIDEV, - "read device: %#x function: %#x register: %#x %d bytes: data: %#x\n", - params()->deviceNum, params()->functionNum, offset, size, - *(uint32_t*)data); + switch(size) { + case sizeof(uint8_t): + memcpy(&byte, &config.data[offset], size); + *data = byte; 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); + memcpy(&byte, &config.data[offset], size); + *(uint16_t*)data = htoa(word); break; - - 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); + case sizeof(uint32_t): + memcpy(&byte, &config.data[offset], size); + *(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,22 +115,16 @@ 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; - 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; switch (size) { case sizeof(uint8_t): // 1-byte access + uint8_t byte_value = data; switch (offset) { case PCI0_INTERRUPT_LINE: case PCI_CACHE_LINE_SIZE: @@ -153,6 +144,7 @@ PciDev::WriteConfig(int offset, int size, uint32_t data) break; case sizeof(uint16_t): // 2-byte access + uint16_t half_value = data; switch (offset) { case PCI_COMMAND: case PCI_STATUS: @@ -165,10 +157,8 @@ 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 + uint32_t word_value = data; switch (offset) { case PCI0_BASE_ADDR0: case PCI0_BASE_ADDR1: @@ -183,12 +173,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 { @@ -200,7 +190,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]; @@ -263,6 +253,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/rtcreg.h b/dev/rtcreg.h index 0b33c25b2..032e22ab5 100644 --- a/dev/rtcreg.h +++ b/dev/rtcreg.h @@ -36,8 +36,22 @@ #define RTC_DOM 0x07 #define RTC_MON 0x08 #define RTC_YEAR 0x09 + #define RTC_CNTRL_REGA 0x0A +#define RTCA_1024HZ 0x06 /* 1024Hz periodic interrupt frequency */ +#define RTCA_32768HZ 0x20 /* 22-stage divider, 32.768KHz timebase */ +#define RTCA_UIP 0x80 /* 1 = date and time update in progress */ + #define RTC_CNTRL_REGB 0x0B +#define RTCB_DST 0x01 /* USA Daylight Savings Time enable */ +#define RTCB_24HR 0x02 /* 0 = 12 hours, 1 = 24 hours */ +#define RTCB_BIN 0x04 /* 0 = BCD, 1 = Binary coded time */ +#define RTCB_SQWE 0x08 /* 1 = output sqare wave at SQW pin */ +#define RTCB_UPDT_IE 0x10 /* 1 = enable update-ended interrupt */ +#define RTCB_ALRM_IE 0x20 /* 1 = enable alarm interrupt */ +#define RTCB_PRDC_IE 0x40 /* 1 = enable periodic clock interrupt */ +#define RTCB_NO_UPDT 0x80 /* stop clock updates */ + #define RTC_CNTRL_REGC 0x0C #define RTC_CNTRL_REGD 0x0D diff --git a/dev/tsunami_io.cc b/dev/tsunami_io.cc index 6e517d431..3aef9b051 100644 --- a/dev/tsunami_io.cc +++ b/dev/tsunami_io.cc @@ -52,14 +52,11 @@ 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); } @@ -70,12 +67,6 @@ 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 * @@ -99,6 +90,11 @@ TsunamiIO::RTCEvent::unserialize(Checkpoint *cp, const std::string §ion) reschedule(time); } +void +TsunamiIO::RTCEvent::scheduleIntr() +{ + schedule(curTick + interval); +} // Timer Event for PIT Timers TsunamiIO::ClockEvent::ClockEvent() @@ -126,10 +122,8 @@ TsunamiIO::ClockEvent::process() DPRINTF(Tsunami, "Timer Interrupt\n"); if (mode == 0) status = 0x20; // set bit that linux is looking for - else - schedule(curTick + interval); - - current_count--; //decrement count + else if (mode == 2) + schedule(curTick + current_count*interval); } void @@ -270,7 +264,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) { @@ -302,12 +296,12 @@ TsunamiIO::read(MemReqPtr &req, uint8_t *data) case TSDEV_RTC_DATA: switch(RTCAddress) { case RTC_CNTRL_REGA: - *(uint8_t*)data = uip << 7 | 0x26; + *(uint8_t*)data = uip << 7 | RTCA_32768HZ | RTCA_1024HZ; uip = !uip; return No_Fault; case RTC_CNTRL_REGB: // DM and 24/12 and UIE - *(uint8_t*)data = 0x46; + *(uint8_t*)data = RTCB_PRDC_IE | RTCB_BIN | RTCB_24HR; return No_Fault; case RTC_CNTRL_REGC: // If we want to support RTC user access in linux @@ -316,6 +310,12 @@ TsunamiIO::read(MemReqPtr &req, uint8_t *data) return No_Fault; case RTC_CNTRL_REGD: panic("RTC Control Register D not implemented"); + 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_SEC: *(uint8_t *)data = tm.tm_sec; return No_Fault; @@ -326,16 +326,16 @@ TsunamiIO::read(MemReqPtr &req, uint8_t *data) *(uint8_t *)data = tm.tm_hour; return No_Fault; case RTC_DOW: - *(uint8_t *)data = tm.tm_wday; + *(uint8_t *)data = tm.tm_wday + 1; return No_Fault; case RTC_DOM: - *(uint8_t *)data = tm.tm_mday; + *(uint8_t *)data = tm.tm_mday + 1; return No_Fault; case RTC_MON: *(uint8_t *)data = tm.tm_mon + 1; return No_Fault; case RTC_YEAR: - *(uint8_t *)data = tm.tm_year - UNIX_YEAR_OFFSET; + *(uint8_t *)data = tm.tm_year; return No_Fault; default: panic("Unknown RTC Address\n"); @@ -391,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)) + 0x20; + Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)); switch(req->size) { case sizeof(uint8_t): @@ -442,10 +442,10 @@ TsunamiIO::write(MemReqPtr &req, const uint8_t *data) switch(*(uint8_t*)data >> 6) { case 0: timer0.LatchCount(); - break; + return No_Fault; case 2: timer2.LatchCount(); - break; + return No_Fault; default: panic("Read Back Command not implemented\n"); } @@ -483,9 +483,10 @@ TsunamiIO::write(MemReqPtr &req, const uint8_t *data) /* two writes before we actually start the Timer so I set a flag in the timerData */ if(timerData & 0x1000) { - timerData &= 0x1000; + timerData &= ~0x1000; timerData += *(uint8_t*)data << 8; timer0.Program(timerData); + timerData = 0; } else { timerData = *(uint8_t*)data; timerData |= 0x1000; @@ -499,12 +500,26 @@ TsunamiIO::write(MemReqPtr &req, const uint8_t *data) case TSDEV_RTC_DATA: switch(RTCAddress) { case RTC_CNTRL_REGA: + if (*data != (RTCA_32768HZ | RTCA_1024HZ)) + panic("Unimplemented RTC register A value write!\n"); return No_Fault; case RTC_CNTRL_REGB: + if ((*data & ~(RTCB_PRDC_IE | RTCB_SQWE)) != (RTCB_BIN | RTCB_24HR)) + panic("Write to RTC reg B bits that are not implemented!\n"); + + if (*data & RTCB_PRDC_IE) { + if (!rtc.scheduled()) + rtc.scheduleIntr(); + } else { + if (rtc.scheduled()) + rtc.deschedule(); + } return No_Fault; case RTC_CNTRL_REGC: + panic("Write to RTC reg C not implemented!\n"); return No_Fault; case RTC_CNTRL_REGD: + panic("Write to RTC reg D not implemented!\n"); return No_Fault; case RTC_SEC: tm.tm_sec = *(uint8_t *)data; @@ -522,10 +537,10 @@ TsunamiIO::write(MemReqPtr &req, const uint8_t *data) tm.tm_mday = *(uint8_t *)data; return No_Fault; case RTC_MON: - tm.tm_mon = *(uint8_t *)data - 1; + tm.tm_mon = *(uint8_t *)data; return No_Fault; case RTC_YEAR: - tm.tm_year = *(uint8_t *)data + UNIX_YEAR_OFFSET; + tm.tm_year = *(uint8_t *)data; return No_Fault; //panic("RTC Write not implmented (rtc.o won't work)\n"); } diff --git a/dev/tsunami_io.hh b/dev/tsunami_io.hh index 4b28635e8..7054b4ff4 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; - static struct tm tm; + struct tm tm; /** * In Tsunami RTC only has two i/o ports one for data and one for @@ -154,9 +154,6 @@ 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 @@ -165,7 +162,7 @@ class TsunamiIO : public PioDevice RTCEvent(Tsunami* t, Tick i); /** - * Interrupth the processor and reschedule the event. + * Interrupt the processor and reschedule the event. */ virtual void process(); @@ -187,6 +184,8 @@ class TsunamiIO : public PioDevice * @param section The section name of this object */ virtual void unserialize(Checkpoint *cp, const std::string §ion); + + void scheduleIntr(); }; /** uip UpdateInProgess says that the rtc is updating, but we just fake it @@ -243,7 +242,7 @@ class TsunamiIO : public PioDevice * This variable contains a flag as to how many writes have happened, and * the time so far. */ - uint32_t timerData; + uint16_t timerData; public: /** diff --git a/dev/uart8250.cc b/dev/uart8250.cc index 99e3bd017..013cbfd00 100644 --- a/dev/uart8250.cc +++ b/dev/uart8250.cc @@ -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 = IIR_RXID; else - *(uint8_t*)data = 1; + *(uint8_t*)data = IIR_NOPEND; break; case 0x3: // Line Control Register (LCR) *(uint8_t*)data = LCR; diff --git a/dev/uart8250.hh b/dev/uart8250.hh index 06a798e26..e85ad72c8 100644 --- a/dev/uart8250.hh +++ b/dev/uart8250.hh @@ -38,6 +38,9 @@ #include "dev/io_device.hh" #include "dev/uart.hh" +#define IIR_NOPEND 0x1 +#define IIR_RXID 0x4 + class SimConsole; class Platform; -- cgit v1.2.3