Now skips the calibrate_delay loop in the kernel boot
dev/tsunami.cc: Changed so Tsunami has a pointer to the System to which it belongs. Now it is derived from generic base class Platform so platform stuff can be accessed based on the system dev/tsunami_io.cc: dev/tsunami_io.hh: Cleanup and added copyright kern/linux/linux_system.cc: kern/linux/linux_system.hh: Added event to skip the "calibrate_delay" function, now calculate loops_per_jiffy based on frequency, interrupt frequency, and constant sim/system.hh: Added pointer to generic Platform base class --HG-- extra : convert_revision : 5bd925eec220a2ca48eb6164d2ecfdec96922c2c
This commit is contained in:
parent
77a30ed48d
commit
c76675be58
6 changed files with 242 additions and 177 deletions
|
@ -43,11 +43,13 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
Tsunami::Tsunami(const string &name, EtherDev *e, SimConsole *con,
|
||||
Tsunami::Tsunami(const string &name, System *s, SimConsole *con,
|
||||
IntrControl *ic, int intr_freq)
|
||||
: SimObject(name), intrctrl(ic), cons(con), ethernet(e),
|
||||
interrupt_frequency(intr_freq)
|
||||
: Platform(name, con, ic, intr_freq), system(s)
|
||||
{
|
||||
// set the back pointer from the system to myself
|
||||
system->platform = this;
|
||||
|
||||
for (int i = 0; i < Tsunami::Max_CPUs; i++)
|
||||
intr_sum_type[i] = 0;
|
||||
}
|
||||
|
@ -66,7 +68,7 @@ Tsunami::unserialize(Checkpoint *cp, const std::string §ion)
|
|||
|
||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(Tsunami)
|
||||
|
||||
SimObjectParam<EtherDev *> ethernet;
|
||||
SimObjectParam<System *> system;
|
||||
SimObjectParam<SimConsole *> cons;
|
||||
SimObjectParam<IntrControl *> intrctrl;
|
||||
Param<int> interrupt_frequency;
|
||||
|
@ -75,7 +77,7 @@ END_DECLARE_SIM_OBJECT_PARAMS(Tsunami)
|
|||
|
||||
BEGIN_INIT_SIM_OBJECT_PARAMS(Tsunami)
|
||||
|
||||
INIT_PARAM(ethernet, "ethernet controller"),
|
||||
INIT_PARAM(system, "system"),
|
||||
INIT_PARAM(cons, "system console"),
|
||||
INIT_PARAM(intrctrl, "interrupt controller"),
|
||||
INIT_PARAM_DFLT(interrupt_frequency, "frequency of interrupts", 1024)
|
||||
|
@ -84,7 +86,7 @@ END_INIT_SIM_OBJECT_PARAMS(Tsunami)
|
|||
|
||||
CREATE_SIM_OBJECT(Tsunami)
|
||||
{
|
||||
return new Tsunami(getInstanceName(), ethernet, cons, intrctrl,
|
||||
return new Tsunami(getInstanceName(), system, cons, intrctrl,
|
||||
interrupt_frequency);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,30 @@
|
|||
/* $Id$ */
|
||||
/*
|
||||
* Copyright (c) 2003 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
|
||||
* Tsunami I/O including PIC, PIT, RTC, DMA
|
||||
|
@ -25,7 +51,6 @@ using namespace std;
|
|||
|
||||
#define UNIX_YEAR_OFFSET 52
|
||||
|
||||
|
||||
// Timer Event for Periodic interrupt of RTC
|
||||
TsunamiIO::RTCEvent::RTCEvent(Tsunami* t)
|
||||
: Event(&mainEventQueue), tsunami(t)
|
||||
|
@ -66,7 +91,7 @@ TsunamiIO::ClockEvent::process()
|
|||
{
|
||||
DPRINTF(Tsunami, "Timer Interrupt\n");
|
||||
if (mode == 0)
|
||||
status = 0x20; // set bit that linux is looking for
|
||||
status = 0x20; // set bit that linux is looking for
|
||||
else
|
||||
schedule(curTick + interval);
|
||||
}
|
||||
|
@ -99,13 +124,13 @@ TsunamiIO::ClockEvent::Status()
|
|||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
TsunamiIO::TsunamiIO(const string &name, Tsunami *t, time_t init_time,
|
||||
Addr addr, Addr mask, MemoryController *mmu)
|
||||
Addr addr, Addr mask, MemoryController *mmu)
|
||||
: MmapDevice(name, addr, mask, mmu), tsunami(t), rtc(t)
|
||||
{
|
||||
// set the back pointer from tsunami to myself
|
||||
tsunami->io = this;
|
||||
|
||||
timerData = 0;
|
||||
set_time(init_time == 0 ? time(NULL) : init_time);
|
||||
uip = 1;
|
||||
|
@ -131,62 +156,63 @@ TsunamiIO::read(MemReqPtr &req, uint8_t *data)
|
|||
// int cpuid = xc->cpu_id;
|
||||
|
||||
switch(req->size) {
|
||||
case sizeof(uint8_t):
|
||||
switch(daddr) {
|
||||
case TSDEV_TMR_CTL:
|
||||
*(uint8_t*)data = timer2.Status();
|
||||
return No_Fault;
|
||||
case TSDEV_RTC_DATA:
|
||||
switch(RTCAddress) {
|
||||
case RTC_CONTROL_REGISTERA:
|
||||
*(uint8_t*)data = uip << 7 | 0x26;
|
||||
uip = !uip;
|
||||
return No_Fault;
|
||||
case RTC_CONTROL_REGISTERB:
|
||||
// DM and 24/12 and UIE
|
||||
*(uint8_t*)data = 0x46;
|
||||
return No_Fault;
|
||||
case RTC_CONTROL_REGISTERC:
|
||||
// If we want to support RTC user access in linux
|
||||
// This won't work, but for now it's fine
|
||||
*(uint8_t*)data = 0x00;
|
||||
return No_Fault;
|
||||
case RTC_CONTROL_REGISTERD:
|
||||
panic("RTC Control Register D not implemented");
|
||||
case RTC_SECOND:
|
||||
*(uint8_t *)data = tm.tm_sec;
|
||||
return No_Fault;
|
||||
case RTC_MINUTE:
|
||||
*(uint8_t *)data = tm.tm_min;
|
||||
return No_Fault;
|
||||
case RTC_HOUR:
|
||||
*(uint8_t *)data = tm.tm_hour;
|
||||
return No_Fault;
|
||||
case RTC_DAY_OF_WEEK:
|
||||
*(uint8_t *)data = tm.tm_wday;
|
||||
return No_Fault;
|
||||
case RTC_DAY_OF_MONTH:
|
||||
*(uint8_t *)data = tm.tm_mday;
|
||||
case RTC_MONTH:
|
||||
*(uint8_t *)data = tm.tm_mon + 1;
|
||||
return No_Fault;
|
||||
case RTC_YEAR:
|
||||
*(uint8_t *)data = tm.tm_year - UNIX_YEAR_OFFSET;
|
||||
return No_Fault;
|
||||
default:
|
||||
panic("Unknown RTC Address\n");
|
||||
}
|
||||
|
||||
default:
|
||||
panic("I/O Read - va%#x size %d\n", req->vaddr, req->size);
|
||||
case sizeof(uint8_t):
|
||||
switch(daddr) {
|
||||
case TSDEV_TMR_CTL:
|
||||
*(uint8_t*)data = timer2.Status();
|
||||
return No_Fault;
|
||||
case TSDEV_RTC_DATA:
|
||||
switch(RTCAddress) {
|
||||
case RTC_CONTROL_REGISTERA:
|
||||
*(uint8_t*)data = uip << 7 | 0x26;
|
||||
uip = !uip;
|
||||
return No_Fault;
|
||||
case RTC_CONTROL_REGISTERB:
|
||||
// DM and 24/12 and UIE
|
||||
*(uint8_t*)data = 0x46;
|
||||
return No_Fault;
|
||||
case RTC_CONTROL_REGISTERC:
|
||||
// If we want to support RTC user access in linux
|
||||
// This won't work, but for now it's fine
|
||||
*(uint8_t*)data = 0x00;
|
||||
return No_Fault;
|
||||
case RTC_CONTROL_REGISTERD:
|
||||
panic("RTC Control Register D not implemented");
|
||||
case RTC_SECOND:
|
||||
*(uint8_t *)data = tm.tm_sec;
|
||||
return No_Fault;
|
||||
case RTC_MINUTE:
|
||||
*(uint8_t *)data = tm.tm_min;
|
||||
return No_Fault;
|
||||
case RTC_HOUR:
|
||||
*(uint8_t *)data = tm.tm_hour;
|
||||
return No_Fault;
|
||||
case RTC_DAY_OF_WEEK:
|
||||
*(uint8_t *)data = tm.tm_wday;
|
||||
return No_Fault;
|
||||
case RTC_DAY_OF_MONTH:
|
||||
*(uint8_t *)data = tm.tm_mday;
|
||||
case RTC_MONTH:
|
||||
*(uint8_t *)data = tm.tm_mon + 1;
|
||||
return No_Fault;
|
||||
case RTC_YEAR:
|
||||
*(uint8_t *)data = tm.tm_year - UNIX_YEAR_OFFSET;
|
||||
return No_Fault;
|
||||
default:
|
||||
panic("Unknown RTC Address\n");
|
||||
}
|
||||
case sizeof(uint16_t):
|
||||
case sizeof(uint32_t):
|
||||
case sizeof(uint64_t):
|
||||
default:
|
||||
panic("I/O Read - invalid size - va %#x size %d\n", req->vaddr, req->size);
|
||||
|
||||
default:
|
||||
panic("I/O Read - va%#x size %d\n", req->vaddr, req->size);
|
||||
}
|
||||
case sizeof(uint16_t):
|
||||
case sizeof(uint32_t):
|
||||
case sizeof(uint64_t):
|
||||
default:
|
||||
panic("I/O Read - invalid size - va %#x size %d\n",
|
||||
req->vaddr, req->size);
|
||||
}
|
||||
panic("I/O Read - va%#x size %d\n", req->vaddr, req->size);
|
||||
panic("I/O Read - va%#x size %d\n", req->vaddr, req->size);
|
||||
|
||||
return No_Fault;
|
||||
}
|
||||
|
@ -203,87 +229,88 @@ TsunamiIO::write(MemReqPtr &req, const uint8_t *data)
|
|||
Addr daddr = (req->paddr & addr_mask);
|
||||
|
||||
switch(req->size) {
|
||||
case sizeof(uint8_t):
|
||||
switch(daddr) {
|
||||
case TSDEV_PIC1_MASK:
|
||||
mask1 = *(uint8_t*)data;
|
||||
if ((picr & mask1) && !picInterrupting) {
|
||||
picInterrupting = true;
|
||||
tsunami->cchip->postDRIR(uint64_t(1) << 55);
|
||||
DPRINTF(Tsunami, "posting pic interrupt to cchip\n");
|
||||
}
|
||||
return No_Fault;
|
||||
case TSDEV_PIC2_MASK:
|
||||
mask2 = *(uint8_t*)data;
|
||||
//PIC2 Not implemented to interrupt
|
||||
return No_Fault;
|
||||
case TSDEV_DMA1_RESET:
|
||||
return No_Fault;
|
||||
case TSDEV_DMA2_RESET:
|
||||
return No_Fault;
|
||||
case TSDEV_DMA1_MODE:
|
||||
mode1 = *(uint8_t*)data;
|
||||
return No_Fault;
|
||||
case TSDEV_DMA2_MODE:
|
||||
mode2 = *(uint8_t*)data;
|
||||
return No_Fault;
|
||||
case TSDEV_DMA1_MASK:
|
||||
case TSDEV_DMA2_MASK:
|
||||
return No_Fault;
|
||||
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 >> 6) {
|
||||
case 0:
|
||||
timer0.ChangeMode((*(uint8_t*)data & 0xF) >> 1);
|
||||
break;
|
||||
case 2:
|
||||
timer2.ChangeMode((*(uint8_t*)data & 0xF) >> 1);
|
||||
break;
|
||||
default:
|
||||
panic("Read Back Command not implemented\n");
|
||||
}
|
||||
return No_Fault;
|
||||
case TSDEV_TMR2_DATA:
|
||||
/* two writes before we actually start the Timer
|
||||
so I set a flag in the timerData */
|
||||
if(timerData & 0x1000) {
|
||||
timerData &= 0x1000;
|
||||
timerData += *(uint8_t*)data << 8;
|
||||
timer2.Program(timerData);
|
||||
} else {
|
||||
timerData = *(uint8_t*)data;
|
||||
timerData |= 0x1000;
|
||||
}
|
||||
return No_Fault;
|
||||
case TSDEV_TMR0_DATA:
|
||||
/* two writes before we actually start the Timer
|
||||
so I set a flag in the timerData */
|
||||
if(timerData & 0x1000) {
|
||||
timerData &= 0x1000;
|
||||
timerData += *(uint8_t*)data << 8;
|
||||
timer0.Program(timerData);
|
||||
} else {
|
||||
timerData = *(uint8_t*)data;
|
||||
timerData |= 0x1000;
|
||||
}
|
||||
return No_Fault;
|
||||
case TSDEV_RTC_ADDR:
|
||||
RTCAddress = *(uint8_t*)data;
|
||||
return No_Fault;
|
||||
case TSDEV_RTC_DATA:
|
||||
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);
|
||||
case sizeof(uint8_t):
|
||||
switch(daddr) {
|
||||
case TSDEV_PIC1_MASK:
|
||||
mask1 = *(uint8_t*)data;
|
||||
if ((picr & mask1) && !picInterrupting) {
|
||||
picInterrupting = true;
|
||||
tsunami->cchip->postDRIR(uint64_t(1) << 55);
|
||||
DPRINTF(Tsunami, "posting pic interrupt to cchip\n");
|
||||
}
|
||||
case sizeof(uint16_t):
|
||||
case sizeof(uint32_t):
|
||||
case sizeof(uint64_t):
|
||||
default:
|
||||
panic("I/O Write - invalid size - va %#x size %d\n", req->vaddr, req->size);
|
||||
return No_Fault;
|
||||
case TSDEV_PIC2_MASK:
|
||||
mask2 = *(uint8_t*)data;
|
||||
//PIC2 Not implemented to interrupt
|
||||
return No_Fault;
|
||||
case TSDEV_DMA1_RESET:
|
||||
return No_Fault;
|
||||
case TSDEV_DMA2_RESET:
|
||||
return No_Fault;
|
||||
case TSDEV_DMA1_MODE:
|
||||
mode1 = *(uint8_t*)data;
|
||||
return No_Fault;
|
||||
case TSDEV_DMA2_MODE:
|
||||
mode2 = *(uint8_t*)data;
|
||||
return No_Fault;
|
||||
case TSDEV_DMA1_MASK:
|
||||
case TSDEV_DMA2_MASK:
|
||||
return No_Fault;
|
||||
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 >> 6) {
|
||||
case 0:
|
||||
timer0.ChangeMode((*(uint8_t*)data & 0xF) >> 1);
|
||||
break;
|
||||
case 2:
|
||||
timer2.ChangeMode((*(uint8_t*)data & 0xF) >> 1);
|
||||
break;
|
||||
default:
|
||||
panic("Read Back Command not implemented\n");
|
||||
}
|
||||
return No_Fault;
|
||||
case TSDEV_TMR2_DATA:
|
||||
/* two writes before we actually start the Timer
|
||||
so I set a flag in the timerData */
|
||||
if(timerData & 0x1000) {
|
||||
timerData &= 0x1000;
|
||||
timerData += *(uint8_t*)data << 8;
|
||||
timer2.Program(timerData);
|
||||
} else {
|
||||
timerData = *(uint8_t*)data;
|
||||
timerData |= 0x1000;
|
||||
}
|
||||
return No_Fault;
|
||||
case TSDEV_TMR0_DATA:
|
||||
/* two writes before we actually start the Timer
|
||||
so I set a flag in the timerData */
|
||||
if(timerData & 0x1000) {
|
||||
timerData &= 0x1000;
|
||||
timerData += *(uint8_t*)data << 8;
|
||||
timer0.Program(timerData);
|
||||
} else {
|
||||
timerData = *(uint8_t*)data;
|
||||
timerData |= 0x1000;
|
||||
}
|
||||
return No_Fault;
|
||||
case TSDEV_RTC_ADDR:
|
||||
RTCAddress = *(uint8_t*)data;
|
||||
return No_Fault;
|
||||
case TSDEV_RTC_DATA:
|
||||
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);
|
||||
}
|
||||
case sizeof(uint16_t):
|
||||
case sizeof(uint32_t):
|
||||
case sizeof(uint64_t):
|
||||
default:
|
||||
panic("I/O Write - invalid size - va %#x size %d\n",
|
||||
req->vaddr, req->size);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -56,19 +56,19 @@ class TsunamiIO : public MmapDevice
|
|||
|
||||
class ClockEvent : public Event
|
||||
{
|
||||
protected:
|
||||
Tick interval;
|
||||
uint8_t mode;
|
||||
uint8_t status;
|
||||
protected:
|
||||
Tick interval;
|
||||
uint8_t mode;
|
||||
uint8_t status;
|
||||
|
||||
public:
|
||||
ClockEvent();
|
||||
public:
|
||||
ClockEvent();
|
||||
|
||||
virtual void process();
|
||||
virtual const char *description();
|
||||
void Program(int count);
|
||||
void ChangeMode(uint8_t mode);
|
||||
uint8_t Status();
|
||||
virtual void process();
|
||||
virtual const char *description();
|
||||
void Program(int count);
|
||||
void ChangeMode(uint8_t mode);
|
||||
uint8_t Status();
|
||||
|
||||
};
|
||||
|
||||
|
@ -83,41 +83,45 @@ class TsunamiIO : public MmapDevice
|
|||
virtual const char *description();
|
||||
};
|
||||
|
||||
uint8_t uip;
|
||||
uint8_t uip;
|
||||
|
||||
uint8_t mask1;
|
||||
uint8_t mask2;
|
||||
uint8_t mode1;
|
||||
uint8_t mode2;
|
||||
uint8_t mask1;
|
||||
uint8_t mask2;
|
||||
uint8_t mode1;
|
||||
uint8_t mode2;
|
||||
|
||||
uint8_t picr; //Raw PIC interrput register, before masking
|
||||
bool picInterrupting;
|
||||
|
||||
Tsunami *tsunami;
|
||||
|
||||
/* This timer is initilized, but after I wrote the code
|
||||
it doesn't seem to be used again, and best I can tell
|
||||
it too is not connected to any interrupt port */
|
||||
ClockEvent timer0;
|
||||
/*
|
||||
* This timer is initilized, but after I wrote the code
|
||||
* it doesn't seem to be used again, and best I can tell
|
||||
* it too is not connected to any interrupt port
|
||||
*/
|
||||
ClockEvent timer0;
|
||||
|
||||
/* This timer is used to control the speaker, which
|
||||
we normally could care less about, however it is
|
||||
also used to calculated the clockspeed and hense
|
||||
bogomips which is kinda important to the scheduler
|
||||
so we need to implemnt it although after boot I can't
|
||||
imagine we would be playing with the PC speaker much */
|
||||
ClockEvent timer2;
|
||||
/*
|
||||
* This timer is used to control the speaker, which
|
||||
* we normally could care less about, however it is
|
||||
* also used to calculated the clockspeed and hense
|
||||
* bogomips which is kinda important to the scheduler
|
||||
* so we need to implemnt it although after boot I can't
|
||||
* imagine we would be playing with the PC speaker much
|
||||
*/
|
||||
ClockEvent timer2;
|
||||
|
||||
RTCEvent rtc;
|
||||
RTCEvent rtc;
|
||||
|
||||
uint32_t timerData;
|
||||
uint32_t timerData;
|
||||
|
||||
|
||||
public:
|
||||
uint32_t frequency() const { return RTC_RATE; }
|
||||
|
||||
TsunamiIO(const std::string &name, Tsunami *t, time_t init_time,
|
||||
Addr addr, Addr mask, MemoryController *mmu);
|
||||
Addr addr, Addr mask, MemoryController *mmu);
|
||||
|
||||
void set_time(time_t t);
|
||||
|
||||
|
|
|
@ -33,11 +33,13 @@
|
|||
#include "base/remote_gdb.hh"
|
||||
#include "base/trace.hh"
|
||||
#include "cpu/exec_context.hh"
|
||||
#include "cpu/base_cpu.hh"
|
||||
#include "kern/linux/linux_events.hh"
|
||||
#include "kern/linux/linux_system.hh"
|
||||
#include "mem/functional_mem/memory_control.hh"
|
||||
#include "mem/functional_mem/physical_memory.hh"
|
||||
#include "sim/builder.hh"
|
||||
#include "dev/platform.hh"
|
||||
#include "targetarch/isa_traits.hh"
|
||||
#include "targetarch/vtophys.hh"
|
||||
|
||||
|
@ -220,6 +222,10 @@ LinuxSystem::LinuxSystem(const string _name, const uint64_t _init_param,
|
|||
skipScavengeBootEvent = new LinuxSkipFuncEvent(&pcEventQueue,
|
||||
"pmap_scavenge_boot");
|
||||
printfEvent = new LinuxPrintfEvent(&pcEventQueue, "printf");
|
||||
|
||||
skipDelayLoopEvent = new LinuxSkipDelayLoopEvent(&pcEventQueue,
|
||||
"calibrate_delay");
|
||||
|
||||
/* debugPrintfEvent = new DebugPrintfEvent(&pcEventQueue,
|
||||
"debug_printf", false);
|
||||
debugPrintfrEvent = new DebugPrintfEvent(&pcEventQueue,
|
||||
|
@ -301,6 +307,9 @@ LinuxSystem::LinuxSystem(const string _name, const uint64_t _init_param,
|
|||
if (kernelSymtab->findAddress("pmap_scavenge_boot", addr))
|
||||
skipScavengeBootEvent->schedule(addr);
|
||||
|
||||
if (kernelSymtab->findAddress("calibrate_delay", addr))
|
||||
skipDelayLoopEvent->schedule(addr+8);
|
||||
|
||||
#if TRACING_ON
|
||||
if (kernelSymtab->findAddress("printk", addr))
|
||||
printfEvent->schedule(addr);
|
||||
|
@ -581,6 +590,23 @@ LinuxSystem::~LinuxSystem()
|
|||
#endif //FS_MEASURE
|
||||
}
|
||||
|
||||
void
|
||||
LinuxSystem::setDelayLoop(ExecContext *xc)
|
||||
{
|
||||
Addr addr = 0;
|
||||
if (kernelSymtab->findAddress("loops_per_jiffy", addr)) {
|
||||
Addr paddr = vtophys(physmem, addr);
|
||||
|
||||
uint8_t *loops_per_jiffy =
|
||||
physmem->dma_addr(paddr, sizeof(uint32_t));
|
||||
|
||||
Tick cpuFreq = xc->cpu->getFreq();
|
||||
Tick intrFreq = platform->interrupt_frequency;
|
||||
*(uint32_t *)loops_per_jiffy =
|
||||
(uint32_t)((cpuFreq / intrFreq) * 0.9988);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
LinuxSystem::registerExecContext(ExecContext *xc)
|
||||
{
|
||||
|
|
|
@ -45,6 +45,7 @@ class SymbolTable;
|
|||
class BreakPCEvent;
|
||||
class LinuxBadAddrEvent;
|
||||
class LinuxSkipFuncEvent;
|
||||
class LinuxSkipDelayLoopEvent;
|
||||
class LinuxPrintfEvent;
|
||||
class LinuxDebugPrintfEvent;
|
||||
class LinuxDumpMbufEvent;
|
||||
|
@ -105,6 +106,7 @@ class LinuxSystem : public System
|
|||
LinuxBadAddrEvent *badaddrEvent;
|
||||
LinuxSkipFuncEvent *skipPowerStateEvent;
|
||||
LinuxSkipFuncEvent *skipScavengeBootEvent;
|
||||
LinuxSkipDelayLoopEvent *skipDelayLoopEvent;
|
||||
LinuxPrintfEvent *printfEvent;
|
||||
LinuxDebugPrintfEvent *debugPrintfEvent;
|
||||
LinuxDebugPrintfEvent *debugPrintfrEvent;
|
||||
|
@ -174,6 +176,8 @@ class LinuxSystem : public System
|
|||
const bool _bin);
|
||||
~LinuxSystem();
|
||||
|
||||
void setDelayLoop(ExecContext *xc);
|
||||
|
||||
int registerExecContext(ExecContext *xc);
|
||||
void replaceExecContext(ExecContext *xc, int xcIndex);
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
|
||||
class MemoryController;
|
||||
class PhysicalMemory;
|
||||
class Platform;
|
||||
class RemoteGDB;
|
||||
class GDBListener;
|
||||
|
||||
|
@ -60,6 +61,7 @@ class System : public SimObject
|
|||
const uint64_t init_param;
|
||||
MemoryController *memCtrl;
|
||||
PhysicalMemory *physmem;
|
||||
Platform *platform;
|
||||
bool bin;
|
||||
|
||||
PCEventQueue pcEventQueue;
|
||||
|
|
Loading…
Reference in a new issue