Now skips the calibrate_delay loop in the kernel boot
authorAndrew Schultz <alschult@umich.edu>
Thu, 5 Feb 2004 23:23:16 +0000 (18:23 -0500)
committerAndrew Schultz <alschult@umich.edu>
Thu, 5 Feb 2004 23:23:16 +0000 (18:23 -0500)
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

dev/tsunami.cc
dev/tsunami_io.cc
dev/tsunami_io.hh
kern/linux/linux_system.cc
kern/linux/linux_system.hh
sim/system.hh

index 42281c5070670d463f93eefb6dfa0e592dcae3a7..04ab922b9680681133bba50b371a94dedcead4d5 100644 (file)
 
 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 &section)
 
 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);
 }
 
index 79fc4cb510610557d26488af3cadbb8f2a745276..25323ee14d1e15c255aa863324eab2a7b2c7c0e6 100644 (file)
@@ -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");
+            }
+            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;
             }
-        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_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);
     }
 
 
index 9ebf61481ee1ccd2679cbff4a16be68453316934..aa77645f34c44e8571ecb3fbb6ace9ec4de5a755 100644 (file)
@@ -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);
 
index db67c56195e568135f98a3473976cc612da81b99..798577ba5ca856e0c34e68a2d765a0e2f508201e 100644 (file)
 #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)
 {
index cfb20f6dc61125c37981d09f5c6023081e976453..6aa29249a58431a5eefc75312090bfa81da550d9 100644 (file)
@@ -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);
 
index 8348a144e5053d5c5d3435e7ceff261aeb74a4b9..e5d990e8618b7c795368eedd23c34f1bde8503d9 100644 (file)
@@ -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;