changeset 7f0c8006c3d7 in /z/repo/m5
details: http://repo.m5sim.org/m5?cmd=changeset;node=7f0c8006c3d7
description:
        X86: Make APICs communicate through the memory system.

diffstat:

7 files changed, 55 insertions(+), 4 deletions(-)
src/arch/x86/interrupts.cc |   10 ++++++++++
src/arch/x86/interrupts.hh |    2 +-
src/arch/x86/intmessage.hh |   42 ++++++++++++++++++++++++++++++++++++++++++
src/cpu/BaseCPU.py         |    1 -
src/dev/x86/i82094aa.cc    |    1 +
src/dev/x86/i8259.hh       |    2 --
src/dev/x86/intdev.hh      |    1 +

diffs (truncated from 519 to 300 lines):

diff -r d2782c951841 -r 7f0c8006c3d7 src/arch/x86/X86LocalApic.py
--- a/src/arch/x86/X86LocalApic.py      Sun Oct 12 12:08:51 2008 -0700
+++ b/src/arch/x86/X86LocalApic.py      Sun Oct 12 13:28:54 2008 -0700
@@ -33,3 +33,4 @@
     type = 'X86LocalApic'
     cxx_class = 'X86ISA::Interrupts'
     pio_latency = Param.Latency('1ns', 'Programmed IO latency in simticks')
+    int_port = Port("Port for sending and receiving interrupt messages")
diff -r d2782c951841 -r 7f0c8006c3d7 src/arch/x86/interrupts.cc
--- a/src/arch/x86/interrupts.cc        Sun Oct 12 12:08:51 2008 -0700
+++ b/src/arch/x86/interrupts.cc        Sun Oct 12 13:28:54 2008 -0700
@@ -239,6 +239,27 @@
     return latency;
 }
 
+Tick
+X86ISA::Interrupts::recvMessage(PacketPtr pkt)
+{
+    Addr offset = pkt->getAddr() - x86InterruptAddress(0, 0);
+    assert(pkt->cmd == MemCmd::MessageReq);
+    switch(offset)
+    {
+      case 0:
+        DPRINTF(LocalApic, "Got Trigger Interrupt message.\n");
+        break;
+      default:
+        panic("Local apic got unknown interrupt message at offset %#x.\n",
+                offset);
+        break;
+    }
+    delete pkt->req;
+    delete pkt;
+    return latency;
+}
+
+
 uint32_t
 X86ISA::Interrupts::readReg(ApicRegIndex reg)
 {
diff -r d2782c951841 -r 7f0c8006c3d7 src/arch/x86/interrupts.hh
--- a/src/arch/x86/interrupts.hh        Sun Oct 12 12:08:51 2008 -0700
+++ b/src/arch/x86/interrupts.hh        Sun Oct 12 13:28:54 2008 -0700
@@ -62,16 +62,16 @@
 #include "arch/x86/faults.hh"
 #include "cpu/thread_context.hh"
 #include "dev/io_device.hh"
+#include "dev/x86/intdev.hh"
 #include "params/X86LocalApic.hh"
 #include "sim/eventq.hh"
-#include "sim/sim_object.hh"
 
 class ThreadContext;
 
 namespace X86ISA
 {
 
-class Interrupts : public BasicPioDevice
+class Interrupts : public BasicPioDevice, IntDev
 {
   protected:
     uint32_t regs[NUM_APIC_REGS];
@@ -108,12 +108,20 @@
 
     Tick read(PacketPtr pkt);
     Tick write(PacketPtr pkt);
+    Tick recvMessage(PacketPtr pkt);
 
     void addressRanges(AddrRangeList &range_list)
     {
         range_list.clear();
         range_list.push_back(RangeEx(x86LocalAPICAddress(0, 0),
                                      x86LocalAPICAddress(0, 0) + PageBytes));
+    }
+
+    void getIntAddrRange(AddrRangeList &range_list)
+    {
+        range_list.clear();
+        range_list.push_back(RangeEx(x86InterruptAddress(0, 0),
+                    x86InterruptAddress(0, 0) + PhysAddrAPICRangeSize));
     }
 
     uint32_t readReg(ApicRegIndex miscReg);
@@ -123,7 +131,7 @@
         regs[reg] = val;
     }
 
-    Interrupts(Params * p) : BasicPioDevice(p),
+    Interrupts(Params * p) : BasicPioDevice(p), IntDev(this),
                              latency(p->pio_latency), clock(0)
     {
         pioSize = PageBytes;
@@ -131,6 +139,13 @@
         regs[APIC_DESTINATION_FORMAT] = (uint32_t)(-1);
         memset(regs, 0, sizeof(regs));
         clear_all();
+    }
+
+    Port *getPort(const std::string &if_name, int idx = -1)
+    {
+        if (if_name == "int_port")
+            return intPort;
+        return BasicPioDevice::getPort(if_name, idx);
     }
 
     int InterruptLevel(uint64_t softint)
diff -r d2782c951841 -r 7f0c8006c3d7 src/arch/x86/intmessage.hh
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/src/arch/x86/intmessage.hh        Sun Oct 12 13:28:54 2008 -0700
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2008 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.
+ *
+ * Authors: Gabe Black
+ */
+
+#ifndef __ARCH_X86_INTMESSAGE_HH__
+#define __ARCH_X86_INTMESSAGE_HH__
+
+#include "arch/x86/x86_traits.hh"
+#include "base/bitunion.hh"
+#include "mem/packet.hh"
+#include "mem/request.hh"
+#include "sim/host.hh"
+
+namespace X86ISA
+{
+    BitUnion32(TriggerIntMessage)
+        Bitfield<7, 0> destination;
+        Bitfield<15, 8> vector;
+        Bitfield<18, 16> deliveryMode;
+        Bitfield<19> destMode;
+    EndBitUnion(TriggerIntMessage)
+
+    static const Addr TriggerIntOffset = 0;
+
+    static inline PacketPtr
+    prepIntRequest(const uint8_t id, Addr offset, Addr size)
+    {
+        RequestPtr req = new Request(x86InterruptAddress(id, offset),
+                                     size, UNCACHEABLE);
+        PacketPtr pkt = new Packet(req, MemCmd::MessageReq, Packet::Broadcast);
+        pkt->allocate();
+        return pkt;
+    }
+
+    template<class T>
+    PacketPtr
+    buildIntRequest(const uint8_t id, T payload, Addr offset, Addr size)
+    {
+        PacketPtr pkt = prepIntRequest(id, offset, size);
+        pkt->set<T>(payload);
+        return pkt;
+    }
+
+    static inline PacketPtr
+    buildIntRequest(const uint8_t id, TriggerIntMessage payload)
+    {
+        return buildIntRequest(id, payload, TriggerIntOffset,
+                sizeof(TriggerIntMessage));
+    }
+
+    static inline PacketPtr
+    buildIntResponse()
+    {
+        panic("buildIntResponse not implemented.\n");
+    }
+}
+
+#endif
diff -r d2782c951841 -r 7f0c8006c3d7 src/arch/x86/x86_traits.hh
--- a/src/arch/x86/x86_traits.hh        Sun Oct 12 12:08:51 2008 -0700
+++ b/src/arch/x86/x86_traits.hh        Sun Oct 12 13:28:54 2008 -0700
@@ -93,6 +93,7 @@
     const Addr PhysAddrPrefixIO = ULL(0x8000000000000000);
     const Addr PhysAddrPrefixPciConfig = ULL(0xC000000000000000);
     const Addr PhysAddrPrefixLocalAPIC = ULL(0xA000000000000000);
+    const Addr PhysAddrPrefixInterrupts = ULL(0x2000000000000000);
     // Each APIC gets two pages. One page is used for local apics to field
     // accesses from the CPU, and the other is for all APICs to communicate.
     const Addr PhysAddrAPICRangeSize = 1 << 12;
@@ -115,6 +116,13 @@
         assert(addr < (1 << 12));
         return PhysAddrPrefixLocalAPIC | (id * (1 << 12)) | addr;
     }
+
+    static inline Addr
+    x86InterruptAddress(const uint8_t id, const uint16_t addr)
+    {
+        assert(addr < PhysAddrAPICRangeSize);
+        return PhysAddrPrefixInterrupts | (id * PhysAddrAPICRangeSize) | addr;
+    }
 }
 
 #endif //__ARCH_X86_X86TRAITS_HH__
diff -r d2782c951841 -r 7f0c8006c3d7 src/cpu/BaseCPU.py
--- a/src/cpu/BaseCPU.py        Sun Oct 12 12:08:51 2008 -0700
+++ b/src/cpu/BaseCPU.py        Sun Oct 12 13:28:54 2008 -0700
@@ -144,7 +144,8 @@
     if build_env['TARGET_ISA'] == 'x86' and build_env['FULL_SYSTEM']:
         _mem_ports = ["itb.walker.port",
                       "dtb.walker.port",
-                      "interrupts.pio"]
+                      "interrupts.pio",
+                      "interrupts.int_port"]
 
     def connectMemPorts(self, bus):
         for p in self._mem_ports:
diff -r d2782c951841 -r 7f0c8006c3d7 src/dev/x86/I82094AA.py
--- a/src/dev/x86/I82094AA.py   Sun Oct 12 12:08:51 2008 -0700
+++ b/src/dev/x86/I82094AA.py   Sun Oct 12 13:28:54 2008 -0700
@@ -36,6 +36,7 @@
     cxx_class = 'X86ISA::I82094AA'
     pio_latency = Param.Latency('1ns', "Programmed IO latency in simticks")
     pio_addr = Param.Addr("Device address")
+    int_port = Port("Port for sending and receiving interrupt messages")
 
     def pin(self, line):
         return X86IntPin(device=self, line=line)
diff -r d2782c951841 -r 7f0c8006c3d7 src/dev/x86/SouthBridge.py
--- a/src/dev/x86/SouthBridge.py        Sun Oct 12 12:08:51 2008 -0700
+++ b/src/dev/x86/SouthBridge.py        Sun Oct 12 13:28:54 2008 -0700
@@ -72,3 +72,4 @@
         self.pit.pio = bus.port
         self.speaker.pio = bus.port
         self.io_apic.pio = bus.port
+        self.io_apic.int_port = bus.port
diff -r d2782c951841 -r 7f0c8006c3d7 src/dev/x86/i82094aa.cc
--- a/src/dev/x86/i82094aa.cc   Sun Oct 12 12:08:51 2008 -0700
+++ b/src/dev/x86/i82094aa.cc   Sun Oct 12 13:28:54 2008 -0700
@@ -28,12 +28,13 @@
  * Authors: Gabe Black
  */
 
+#include "arch/x86/intmessage.hh"
 #include "dev/x86/i82094aa.hh"
 #include "mem/packet.hh"
 #include "mem/packet_access.hh"
 #include "sim/system.hh"
 
-X86ISA::I82094AA::I82094AA(Params *p) : PioDevice(p),
+X86ISA::I82094AA::I82094AA(Params *p) : PioDevice(p), IntDev(this),
    latency(p->pio_latency), pioAddr(p->pio_addr)
 {
     // This assumes there's only one I/O APIC in the system
@@ -140,11 +141,56 @@
         DPRINTF(I82094AA, "Entry was masked.\n");
         return;
     } else {
+        if (DTRACE(I82094AA)) {
+            switch(entry.deliveryMode) {
+              case 0:
+                DPRINTF(I82094AA, "Delivery mode is: Fixed.\n");
+                break;
+              case 1:
+                DPRINTF(I82094AA, "Delivery mode is: Lowest Priority.\n");
+                break;
+              case 2:
+                DPRINTF(I82094AA, "Delivery mode is: SMI.\n");
+                break;
+              case 3:
+                fatal("Tried to use reserved delivery mode "
+                        "for IO APIC entry %d.\n", line);
+                break;
+              case 4:
+                DPRINTF(I82094AA, "Delivery mode is: NMI.\n");
+                break;
+              case 5:
+                DPRINTF(I82094AA, "Delivery mode is: INIT.\n");
+                break;
+              case 6:
+                fatal("Tried to use reserved delivery mode "
+                        "for IO APIC entry %d.\n", line);
+                break;
+              case 7:
+                DPRINTF(I82094AA, "Delivery mode is: ExtINT.\n");
+                break;
_______________________________________________
m5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/m5-dev

Reply via email to