diff options
-rw-r--r-- | SConscript | 2 | ||||
-rw-r--r-- | arch/alpha/isa_traits.hh | 1 | ||||
-rw-r--r-- | dev/ide_disk.cc | 3 | ||||
-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 | ||||
-rw-r--r-- | kern/freebsd/freebsd_system.cc | 166 | ||||
-rw-r--r-- | kern/freebsd/freebsd_system.hh | 53 | ||||
-rw-r--r-- | python/m5/objects/Tsunami.py | 1 |
11 files changed, 393 insertions, 9 deletions
diff --git a/SConscript b/SConscript index ddca8b057..7b309fbfe 100644 --- a/SConscript +++ b/SConscript @@ -280,6 +280,8 @@ full_system_sources = Split(''' kern/kernel_binning.cc kern/kernel_stats.cc kern/system_events.cc + kern/freebsd/freebsd_system.cc + kern/freebsd/freebsd_events.cc kern/linux/linux_events.cc kern/linux/linux_syscalls.cc kern/linux/linux_system.cc diff --git a/arch/alpha/isa_traits.hh b/arch/alpha/isa_traits.hh index 9c7709a60..6c0c09b7a 100644 --- a/arch/alpha/isa_traits.hh +++ b/arch/alpha/isa_traits.hh @@ -287,6 +287,7 @@ const int ReturnAddressReg = TheISA::ReturnAddressReg; const int ReturnValueReg = TheISA::ReturnValueReg; const int ArgumentReg0 = TheISA::ArgumentReg0; const int ArgumentReg1 = TheISA::ArgumentReg1; +const int ArgumentReg2 = TheISA::ArgumentReg2; const int BranchPredAddrShiftAmt = TheISA::BranchPredAddrShiftAmt; const int MaxAddr = (Addr)-1; diff --git a/dev/ide_disk.cc b/dev/ide_disk.cc index 23d04bb5e..ae394c69e 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; @@ -745,6 +747,7 @@ IdeDisk::intrPost() // talk to controller to set interrupt if (ctrl) + ctrl->bmi_regs[BMIS0] |= IDEINTS; ctrl->intrPost(); } diff --git a/dev/ns_gige.hh b/dev/ns_gige.hh index f39731493..9007ea6cf 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 diff --git a/kern/freebsd/freebsd_system.cc b/kern/freebsd/freebsd_system.cc new file mode 100644 index 000000000..d7d32cc66 --- /dev/null +++ b/kern/freebsd/freebsd_system.cc @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Modifications for the FreeBSD kernel. Based off of kern/linux/linux_system.cc. + * Currently only used to skip DELAY function. + * + */ + +#include "base/loader/symtab.hh" +#include "base/trace.hh" +#include "cpu/exec_context.hh" +#include "cpu/base.hh" +#include "kern/freebsd/freebsd_system.hh" +#include "kern/system_events.hh" +#include "mem/functional/memory_control.hh" +#include "mem/functional/physical.hh" +#include "sim/builder.hh" +#include "dev/platform.hh" +#include "targetarch/isa_traits.hh" +#include "targetarch/vtophys.hh" +#include "sim/debug.hh" + +using namespace std; + +FreebsdSystem::FreebsdSystem(Params *p) + : System(p) +{ + Addr addr = 0; + + /** + * Any time DELAY is called just skip the function. + * Replace calibrate_clocks with function below. + */ + skipDelayEvent = new SkipFuncEvent(&pcEventQueue, "DELAY"); + if (kernelSymtab->findAddress("DELAY", addr)) + skipDelayEvent->schedule(addr+sizeof(MachInst)); + + skipCalibrateClocks = new FreebsdSkipCalibrateClocksEvent(&pcEventQueue, "calibrate_clocks"); + if (kernelSymtab->findAddress("calibrate_clocks", addr)) + skipCalibrateClocks->schedule(addr + sizeof(MachInst) * 2); + +} + + +FreebsdSystem::~FreebsdSystem() +{ + delete skipDelayEvent; + delete skipCalibrateClocks; +} + + +void +FreebsdSystem::doCalibrateClocks(ExecContext *xc) +{ + Addr ppc_vaddr = 0; + Addr timer_vaddr = 0; + Addr ppc_paddr = 0; + Addr timer_paddr = 0; + + ppc_vaddr = (Addr)xc->regs.intRegFile[ArgumentReg1]; + timer_vaddr = (Addr)xc->regs.intRegFile[ArgumentReg2]; + + ppc_paddr = vtophys(physmem, ppc_vaddr); + timer_paddr = vtophys(physmem, timer_vaddr); + + uint8_t *ppc = physmem->dma_addr(ppc_paddr, sizeof(uint32_t)); + uint8_t *timer = physmem->dma_addr(timer_paddr, sizeof(uint32_t)); + + *(uint32_t *)ppc = 2000000000; + *(uint32_t *)timer = 1193180; +} + + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(FreebsdSystem) + + Param<Tick> boot_cpu_frequency; + SimObjectParam<MemoryController *> memctrl; + SimObjectParam<PhysicalMemory *> physmem; + + Param<string> kernel; + Param<string> console; + Param<string> pal; + + Param<string> boot_osflags; + Param<string> readfile; + Param<unsigned int> init_param; + + Param<uint64_t> system_type; + Param<uint64_t> system_rev; + + Param<bool> bin; + VectorParam<string> binned_fns; + Param<bool> bin_int; + +END_DECLARE_SIM_OBJECT_PARAMS(FreebsdSystem) + +BEGIN_INIT_SIM_OBJECT_PARAMS(FreebsdSystem) + + INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"), + INIT_PARAM(memctrl, "memory controller"), + INIT_PARAM(physmem, "phsyical memory"), + INIT_PARAM(kernel, "file that contains the kernel code"), + INIT_PARAM(console, "file that contains the console code"), + INIT_PARAM(pal, "file that contains palcode"), + INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot", + "a"), + INIT_PARAM_DFLT(readfile, "file to read startup script from", ""), + INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0), + INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 34), + INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10), + INIT_PARAM_DFLT(bin, "is this system to be binned", false), + INIT_PARAM(binned_fns, "functions to be broken down and binned"), + INIT_PARAM_DFLT(bin_int, "is interrupt code binned seperately?", true) + +END_INIT_SIM_OBJECT_PARAMS(FreebsdSystem) + +CREATE_SIM_OBJECT(FreebsdSystem) +{ + System::Params *p = new System::Params; + p->name = getInstanceName(); + p->boot_cpu_frequency = boot_cpu_frequency; + p->memctrl = memctrl; + p->physmem = physmem; + p->kernel_path = kernel; + p->console_path = console; + p->palcode = pal; + p->boot_osflags = boot_osflags; + p->init_param = init_param; + p->readfile = readfile; + p->system_type = system_type; + p->system_rev = system_rev; + p->bin = bin; + p->binned_fns = binned_fns; + p->bin_int = bin_int; + return new FreebsdSystem(p); +} + +REGISTER_SIM_OBJECT("FreebsdSystem", FreebsdSystem) + diff --git a/kern/freebsd/freebsd_system.hh b/kern/freebsd/freebsd_system.hh new file mode 100644 index 000000000..a3c5f8b92 --- /dev/null +++ b/kern/freebsd/freebsd_system.hh @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __KERN_FREEBSD_FREEBSD_SYSTEM_HH__ +#define __KERN_FREEBSD_FREEBSD_SYSTEM_HH__ + +#include "sim/host.hh" +#include "sim/system.hh" +#include "targetarch/isa_traits.hh" +#include "kern/freebsd/freebsd_events.hh" + + +class FreebsdSystem : public System +{ + private: + + SkipFuncEvent *skipDelayEvent; + + FreebsdSkipCalibrateClocksEvent *skipCalibrateClocks; + + public: + FreebsdSystem(Params *p); + ~FreebsdSystem(); + void doCalibrateClocks(ExecContext *xc); + +}; + +#endif // __KERN_FREEBSD_FREEBSD_SYSTEM_HH__ diff --git a/python/m5/objects/Tsunami.py b/python/m5/objects/Tsunami.py index c8fd94e2c..8e16d5d1e 100644 --- a/python/m5/objects/Tsunami.py +++ b/python/m5/objects/Tsunami.py @@ -13,6 +13,7 @@ class TsunamiCChip(FooPioDevice): class TsunamiFake(FooPioDevice): type = 'TsunamiFake' + size = Param.Addr("Size of address range") class TsunamiIO(FooPioDevice): type = 'TsunamiIO' |