switch contexts on palcode rather than kernel code
cpu/pc_event.cc:
mask off lower three bits so we can have an event in palcode
--HG--
extra : convert_revision : 49fcdc5c359ca2bd9149f092f80f77abcd7b20ee
This commit is contained in:
@@ -77,7 +77,7 @@ PCEventQueue::schedule(PCEvent *event)
|
||||
bool
|
||||
PCEventQueue::doService(ExecContext *xc)
|
||||
{
|
||||
Addr pc = xc->regs.pc;
|
||||
Addr pc = xc->regs.pc & ~0x3;
|
||||
int serviced = 0;
|
||||
range_t range = equal_range(pc);
|
||||
for (iterator i = range.first; i != range.second; ++i) {
|
||||
@@ -85,7 +85,7 @@ PCEventQueue::doService(ExecContext *xc)
|
||||
// another event. This for example, prevents two invocations
|
||||
// of the SkipFuncEvent. Maybe we should have separate PC
|
||||
// event queues for each processor?
|
||||
if (pc != xc->regs.pc)
|
||||
if (pc != (xc->regs.pc & ~0x3))
|
||||
continue;
|
||||
|
||||
DPRINTF(PCEvent, "PC based event serviced at %#x: %s\n",
|
||||
|
||||
@@ -145,14 +145,29 @@ LinuxSystem::LinuxSystem(Params *p)
|
||||
printThreadEvent->schedule(addr + sizeof(MachInst) * 6);
|
||||
|
||||
intStartEvent = new InterruptStartEvent(&pcEventQueue, "intStartEvent");
|
||||
if (kernelSymtab->findAddress("do_entInt", addr))
|
||||
if (palSymtab->findAddress("sys_int_21", addr))
|
||||
intStartEvent->schedule(addr + sizeof(MachInst) * 2);
|
||||
else
|
||||
panic("could not find symbol\n");
|
||||
|
||||
intEndEvent = new InterruptEndEvent(&pcEventQueue, "intStartEvent");
|
||||
if (palSymtab->findAddress("Call_Pal_Rti", addr))
|
||||
intEndEvent = new InterruptEndEvent(&pcEventQueue, "intEndEvent");
|
||||
if (palSymtab->findAddress("rti_to_kern", addr))
|
||||
intEndEvent->schedule(addr + sizeof(MachInst));
|
||||
else
|
||||
panic("could not find symbol\n");
|
||||
|
||||
intEndEvent2 = new InterruptEndEvent(&pcEventQueue, "intEndEvent2");
|
||||
if (palSymtab->findAddress("rti_to_user", addr))
|
||||
intEndEvent2->schedule(addr + sizeof(MachInst));
|
||||
else
|
||||
panic("could not find symbol\n");
|
||||
|
||||
|
||||
intEndEvent3 = new InterruptEndEvent(&pcEventQueue, "intEndEvent3");
|
||||
if (kernelSymtab->findAddress("do_softirq", addr))
|
||||
intEndEvent3->schedule(addr + sizeof(MachInst));
|
||||
else
|
||||
panic("could not find symbol\n");
|
||||
}
|
||||
|
||||
LinuxSystem::~LinuxSystem()
|
||||
@@ -167,6 +182,8 @@ LinuxSystem::~LinuxSystem()
|
||||
delete idleStartEvent;
|
||||
delete printThreadEvent;
|
||||
delete intStartEvent;
|
||||
delete intEndEvent;
|
||||
delete intEndEvent2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -98,6 +98,8 @@ class LinuxSystem : public System
|
||||
* Event to bin Interrupts seperately from kernel code
|
||||
*/
|
||||
InterruptEndEvent *intEndEvent;
|
||||
InterruptEndEvent *intEndEvent2;
|
||||
InterruptEndEvent *intEndEvent3;
|
||||
|
||||
/** Grab the PCBB of the idle process when it starts */
|
||||
IdleStartEvent *idleStartEvent;
|
||||
|
||||
Reference in New Issue
Block a user