switch contexts on palcode rather than kernel code
authorAli Saidi <saidi@eecs.umich.edu>
Thu, 16 Sep 2004 04:37:21 +0000 (00:37 -0400)
committerAli Saidi <saidi@eecs.umich.edu>
Thu, 16 Sep 2004 04:37:21 +0000 (00:37 -0400)
cpu/pc_event.cc:
    mask off lower three bits so we can have an event in palcode

--HG--
extra : convert_revision : 49fcdc5c359ca2bd9149f092f80f77abcd7b20ee

cpu/pc_event.cc
kern/linux/linux_system.cc
kern/linux/linux_system.hh

index a86c017d40844d0241713561e45cf9d0e1ac1d28..8f046a7a41e9a6447113eadff6e159149d4231ba 100644 (file)
@@ -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",
index 91ad45157bacb4f426a511b75778f628f6da63e5..539bac6494316e22ea95f1b2e1b4e8abddb75db7 100644 (file)
@@ -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;
 }
 
 
index f5fd2b06b18d82e4407c49762191dae518ac3908..5e3cba9b32be7aa433298d01a0971bb6fc632090 100644 (file)
@@ -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;