diff options
-rwxr-xr-x | src/build/simics/post_model_hook.simics | 3 | ||||
-rw-r--r-- | src/include/kernel/intmsghandler.H | 46 | ||||
-rw-r--r-- | src/include/sys/msg.h | 1 | ||||
-rw-r--r-- | src/kernel/intmsghandler.C | 15 | ||||
-rw-r--r-- | src/usr/intr/intrrp.C | 206 | ||||
-rw-r--r-- | src/usr/intr/intrrp.H | 36 | ||||
-rw-r--r-- | src/usr/intr/test/intrtest.H | 131 |
7 files changed, 291 insertions, 147 deletions
diff --git a/src/build/simics/post_model_hook.simics b/src/build/simics/post_model_hook.simics index 57dc9a117..f2705f615 100755 --- a/src/build/simics/post_model_hook.simics +++ b/src/build/simics/post_model_hook.simics @@ -42,7 +42,10 @@ phys-mem.load-file ./sysspd.dat 0x701000 #Setup the mailbox venice_cec_chip_cmp0.psi_hb->psihb_psihbcr=0x5f00000000000000 +# for mbox on core 0 use: venice_cec_chip_cmp0.psi_hb->psihb_xivr_fsi=0x0140000000 #02010917 +# for mbox on core 1 use: +#venice_cec_chip_cmp0.psi_hb->psihb_xivr_fsi=0x0000200140000000 venice_cec_chip_cmp0.psi_hb->psihb_irsn=0x00030000FFFF0000 #0201091b p8Proc0.proc_fsi2host_mbox->responder_enable=1 diff --git a/src/include/kernel/intmsghandler.H b/src/include/kernel/intmsghandler.H index 52eadde27..500961668 100644 --- a/src/include/kernel/intmsghandler.H +++ b/src/include/kernel/intmsghandler.H @@ -27,6 +27,7 @@ #include <kernel/types.h> #include <kernel/msghandler.H> #include <kernel/msg.H> +#include <builtins.h> /** * @class InterruptMsgHdlr @@ -41,6 +42,31 @@ class InterruptMsgHdlr : public MessageHandler { public: + /** + * Field values for P8 + * @note This is used to calculate the mmio address offset + * from the PIR for the interrupt presenter memory mapped registers. + * The masks isolate the node,chip,core, and thread id fields in the + * PIR. The LSL values tell how far left a PIR field needs to be + * shifted to create a proper mmio offset address. + * + */ + enum + { + P8_PIR_THREADID_MSK = 0x00000007, + P8_PIR_COREID_MSK = 0x00000078, + P8_PIR_CHIPID_MSK = 0x00000380, + P8_PIR_NODEID_MSK = 0x00001C00, + + // Logical Shift Left fields for mmio Base address from PIR. + // (IP addr bit pos - PIR bit pos) + P8_IP_THREADID_LSL = (12-0), + P8_IP_COREID_LSL = (15-3), + P8_IP_CHIPID_LSL = (20-7), + P8_IP_NODEID_LSL = (23-10), + XIRR_ADDR_OFFSET = 4, + }; + // Notes: // All external interrupts are routed to one cpu core // External Interrupts are only processed one at a time @@ -71,6 +97,26 @@ class InterruptMsgHdlr : public MessageHandler task_t* i_task,int i_rc); + ALWAYS_INLINE + static uint64_t mmio_offset(uint64_t i_pir) + { + uint64_t offset = 0; + + // The node and chip id fields are adjacent in both the PIR and + // the mmio offset - so they can be done in one shift operation + offset |= + (i_pir & (P8_PIR_NODEID_MSK | P8_PIR_CHIPID_MSK)) + << P8_IP_CHIPID_LSL; + + // The core and thread id field are adjacent in both the PIR and + // the mmio offset, so they can be done in one shift operation. + offset |= + (i_pir & (P8_PIR_COREID_MSK | P8_PIR_THREADID_MSK)) + << P8_IP_THREADID_LSL; + + return offset; + } + /** * Create the InterruptMsgHdlr to handle external interrupts * @param[in] i_msgQ The message queue diff --git a/src/include/sys/msg.h b/src/include/sys/msg.h index 4bbf0b265..91dd51ce9 100644 --- a/src/include/sys/msg.h +++ b/src/include/sys/msg.h @@ -61,6 +61,7 @@ enum msg_sys_types_t MSG_INTR_EXTERN, //!< Msg sent from kernel to user space on ext intr MSG_INTR_ADD_CPU, //!< Add cpu core, data[0] = cpuid (PIR) + MSG_INTR_REMOVE_CPU,//!< un-configure intrp on cpu core, data[0] = cpuid }; // System-defined root queue types diff --git a/src/kernel/intmsghandler.C b/src/kernel/intmsghandler.C index e5c86b796..7b994f006 100644 --- a/src/kernel/intmsghandler.C +++ b/src/kernel/intmsghandler.C @@ -31,6 +31,7 @@ #include <kernel/taskmgr.H> #include <kernel/cpu.H> #include <kernel/scheduler.H> +#include <arch/ppc.H> const char* INTR_MSGQ = "/msg/interrupt"; @@ -76,9 +77,12 @@ void InterruptMsgHdlr::handleInterrupt() // the message. task_t* t = TaskManager::getCurrentTask(); - // TODO will this always be processor 0 core 0 thread 0? - // Need a way to pass this addr down from user code? - uint64_t xirrAddress = (static_cast<uint64_t>(ICPBAR_VAL) << 20) + 4; + uint64_t pir = getPIR(); + + uint64_t xirrAddress = (static_cast<uint64_t>(ICPBAR_VAL) << 20); + + xirrAddress += mmio_offset(pir); // Add offset for this cpu + xirrAddress += XIRR_ADDR_OFFSET; // Add offset for XIRR register // Ignore HRMOR setting xirrAddress |= 0x8000000000000000ul; @@ -100,7 +104,7 @@ void InterruptMsgHdlr::handleInterrupt() { cv_instance->sendMessage(MSG_INTR_EXTERN, (void *)xirr, - NULL, + (void *)pir, NULL); } @@ -109,6 +113,8 @@ void InterruptMsgHdlr::handleInterrupt() // leave the interrupt presenter locked. // Does the code that sets up the IP registers need to check to see if // there is an interrupt sitting there and send an EOI? + // Story 41868 - Mask off all interrupts very early - might + // resolve this TODO. // Return the task to the scheduler queue if we did a context-switch. if (TaskManager::getCurrentTask() != t) @@ -118,6 +124,7 @@ void InterruptMsgHdlr::handleInterrupt() } +// TODO where does this get called from? (story 39878) void InterruptMsgHdlr::addCpuCore(uint64_t i_pir) { // Save the current task in case we context-switch away when sending diff --git a/src/usr/intr/intrrp.C b/src/usr/intr/intrrp.C index 5e6771e5b..d05c6c44e 100644 --- a/src/usr/intr/intrrp.C +++ b/src/usr/intr/intrrp.C @@ -38,11 +38,14 @@ #include <targeting/common/targetservice.H> #include <vmmconst.h> #include <targeting/common/attributes.H> +#include <devicefw/userif.H> + +#define INTR_TRACE_NAME INTR_COMP_NAME using namespace INTR; trace_desc_t * g_trac_intr = NULL; -TRAC_INIT(&g_trac_intr, INTR_COMP_NAME, 2 * 1024); +TRAC_INIT(&g_trac_intr, INTR_TRACE_NAME, 2 * 1024); /** @@ -84,67 +87,30 @@ errlHndl_t IntrRp::_init() { errlHndl_t err = NULL; - // TODO Temporaritly DISABLE in VBU until P8 support is confirmed - if( TARGETING::is_vpo() ) - { - iv_isVBU = true; - } - // get the PIR // Which ever cpu core this is running on is the MASTER cpu // Make master thread 0 uint32_t cpuid = task_getcpuid(); iv_masterCpu = cpuid; // If P7 or P7+ core -- need to tweak fields in PIR - if(cpu_core_type() < CORE_POWER8_MURANO) + if(cpu_core_type() == CORE_POWER7 || + cpu_core_type() == CORE_POWER7_PLUS) { iv_masterCpu = P7PIR_t(cpuid); } iv_masterCpu.threadId = 0; - TRACFCOMP(g_trac_intr,"node[%d], chip[%d], core[%d], thread[%d]", + TRACFCOMP(g_trac_intr,"Master cpu node[%d], chip[%d], core[%d], thread[%d]", iv_masterCpu.nodeId, iv_masterCpu.chipId, iv_masterCpu.coreId, iv_masterCpu.threadId); + // The base realAddr is the base address for the whole system. + // Therefore the realAddr must be based on the processor + // that would have the lowest BAR value in the system, + // whether it exists or not. In this case n0p0 - uint64_t realAddr = 0; - - // TODO Does the BAR scom reg need to be read here or set here?? - // Who sets the BAR? - //uint64_t size = sizeof(realAddr); - //TARGETING::TargetService& targetService = TARGETING::targetService(); - //TARGETING::Target* procTarget = NULL; - //targetService.masterProcChipTargetHandle( procTarget ); - // - // TODO What if this does not jive with with the PIR? - - // TODO Does this need to be read here? - //err = deviceRead(procTarget, - // &realAddr, - // size, - // DEVICE_SCOM_ADDRESS(ICPBAR_SCOM_ADDR)); - //if(err) return err; - - if(realAddr == 0) - { - realAddr = (static_cast<uint64_t>(ICPBAR_VAL)) << 34; - } - - // TODO Does this need to be set here? - // err = deviceWrite(procTarget, - // &realAddr, - // size, - // DEVICE_SCOM_ADDRESS(ICPBAR_SCOM_ADDR)); - - realAddr &= 0xFFFFFFFC00000000ul; //[0:29] is ICP_BAR - realAddr >>= 14; //[14:43] is BAR field in real address - - - // The realAddr is the base address for the whole system. - // Therefore the realAddr must be based on the processor with - // lowest BAR value in the system. (usually n0p0) - // TODO Adjust the realAddr if the BAR came from a processor other - // than cpuid 0 + // [14:43] is BAR field in address to shift by (34 - 14) + uint64_t realAddr = (static_cast<uint64_t>(ICPBAR_VAL)) << 20; TRACFCOMP(g_trac_intr,"INTR: realAddr = %lx",realAddr); @@ -154,7 +120,17 @@ errlHndl_t IntrRp::_init() TRACFCOMP(g_trac_intr,"INTR: vAddr = %lx",iv_baseAddr); - err = checkAddress(iv_baseAddr); + // Set the BAR scom reg + TARGETING::Target* procTarget = NULL; + TARGETING::targetService().masterProcChipTargetHandle( procTarget ); + + err = setBAR(procTarget,iv_masterCpu); + + if(!err) + { + err = checkAddress(iv_baseAddr); + } + if(!err) { @@ -188,9 +164,6 @@ errlHndl_t IntrRp::enableInterrupts() { errlHndl_t err = NULL; - // TODO Temporarily DISABLE in VBU until P8 support is confirmed - if(iv_isVBU) return err; - // Enable the interrupt on master processor core, thread 0 uint64_t baseAddr = iv_baseAddr + cpuOffsetAddr(iv_masterCpu); @@ -209,9 +182,6 @@ errlHndl_t IntrRp::disableInterrupts() errlHndl_t err = NULL; // Disable the interrupt on master processor core, thread 0 - // TODO Temporarily DISABLE in VBU until P8 support is confirmed - if(iv_isVBU) return err; - uint64_t baseAddr = iv_baseAddr + cpuOffsetAddr(iv_masterCpu); err = checkAddress(baseAddr); @@ -245,16 +215,20 @@ void IntrRp::msgHandler() { ext_intr_t type = NO_INTERRUPT; - // type = XISR = XIRR[8:31] - // priority = XIRR[0:7] - uint32_t * xirrAddress = - reinterpret_cast<uint32_t *>(iv_baseAddr+ XIRR_OFFSET+ - cpuOffsetAddr(iv_masterCpu)); - // xirr was read by interrupt message handler. // Passed in as data[0] uint32_t xirr = static_cast<uint32_t>(msg->data[0]); - type = static_cast<ext_intr_t>(xirr & 0x00FFFFFF); + PIR_t pir = static_cast<PIR_t>(msg->data[1]); + + // data[1] has the PIR + uint32_t * xirrAddress = + reinterpret_cast<uint32_t*>(iv_baseAddr + XIRR_OFFSET + + cpuOffsetAddr(pir)); + + // type = XISR = XIRR[8:31] + // priority = XIRR[0:7] + // Use the XISR as the type (for now) + type = static_cast<ext_intr_t>(xirr & XISR_MASK); TRACDCOMP(g_trac_intr,"External Interrupt recieved, Type=%x",type); @@ -354,8 +328,9 @@ void IntrRp::msgHandler() { PIR_t pir = msg->data[0]; // If P7 or P7+ core -- need to tweak fields in PIR - if(cpu_core_type() < CORE_POWER8_MURANO) - { + if(cpu_core_type() == CORE_POWER7 || + cpu_core_type() == CORE_POWER7_PLUS) + { pir = P7PIR_t(msg->data[0]); } @@ -364,6 +339,7 @@ void IntrRp::msgHandler() pir.nodeId, pir.chipId, pir.coreId, pir.threadId); + size_t threads = cpu_thread_count(); for(size_t thread = 0; thread < threads; ++thread) @@ -377,6 +353,33 @@ void IntrRp::msgHandler() } break; + case MSG_INTR_REMOVE_CPU: + { + PIR_t pir = msg->data[0]; + if(cpu_core_type() == CORE_POWER7 || + cpu_core_type() == CORE_POWER7_PLUS) + { + pir = P7PIR_t(msg->data[0]); + } + + TRACFCOMP(g_trac_intr,"Remove CPU node[%d], chip[%d]," + "core[%d], thread[%d]", + pir.nodeId, pir.chipId, pir.coreId, + pir.threadId); + + size_t threads = cpu_thread_count(); + + for(size_t thread = 0; thread < threads; ++thread) + { + pir.threadId = thread; + deconfigureInterruptPresenter(pir); + } + + msg->data[1] = 0; + msg_respond(iv_msgQ, msg); + } + break; + default: msg->data[1] = -EINVAL; msg_respond(iv_msgQ, msg); @@ -385,6 +388,36 @@ void IntrRp::msgHandler() } + +errlHndl_t IntrRp::setBAR(TARGETING::Target * i_target, + const PIR_t i_pir) +{ + errlHndl_t err = NULL; + + uint64_t barValue = static_cast<uint64_t>(ICPBAR_VAL) + + (8 * i_pir.nodeId) + i_pir.chipId; + barValue <<= 34; + + TRACFCOMP(g_trac_intr,"INTR: Target %p. ICPBAR value: 0x%016lx", + i_target,barValue); + + uint64_t size = sizeof(barValue); + + err = deviceWrite(i_target, + &barValue, + size, + DEVICE_SCOM_ADDRESS(ICPBAR_SCOM_ADDR)); + + if(err) + { + TRACFCOMP(g_trac_intr,ERR_MRK"Unable to set IPCBAR"); + } + + return err; +} + + + errlHndl_t IntrRp::registerInterrupt(msg_q_t i_msgQ, ext_intr_t i_type) { errlHndl_t err = NULL; @@ -424,9 +457,6 @@ errlHndl_t IntrRp::registerInterrupt(msg_q_t i_msgQ, ext_intr_t i_type) void IntrRp::initInterruptPresenter(const PIR_t i_pir) const { - // TODO Temporaritly DISABLE in VBU until P8 support is confirmed - if(iv_isVBU) return; - uint64_t baseAddr = iv_baseAddr + cpuOffsetAddr(i_pir); uint8_t * cppr = reinterpret_cast<uint8_t*>(baseAddr + CPPR_OFFSET); @@ -469,6 +499,44 @@ void IntrRp::initInterruptPresenter(const PIR_t i_pir) const } + +void IntrRp::deconfigureInterruptPresenter(const PIR_t i_pir) const +{ + uint64_t baseAddr = iv_baseAddr + cpuOffsetAddr(i_pir); + uint8_t * cppr = + reinterpret_cast<uint8_t*>(baseAddr + CPPR_OFFSET); + uint32_t * plinkReg = + reinterpret_cast<uint32_t *>(baseAddr + LINKA_OFFSET); + + // non- side effect xirr register + uint32_t * xirrAddr = + reinterpret_cast<uint32_t *>(baseAddr) + XIRR_RO_OFFSET; + + uint32_t xirr = *xirrAddr & 0x00FFFFFF; + + TRACDCOMP(g_trac_intr,"PIR 0x%x offset: 0x%lx", + i_pir.word, + cpuOffsetAddr(i_pir)); + + // Not sure if this will ever happen, but squawk alittle if it does + if(xirr) + { + TRACFCOMP(g_trac_intr, + ERR_MRK + "Pending interrupt found on shutdown. CpuId:0x%x XIRR:0x%x", + i_pir.word, + xirr); + } + + *cppr = 0; // Set priority to most favored (off) + + *plinkReg = 0; // Reset link registers - clear all forwarding + *(plinkReg + 1) = 0; + *(plinkReg + 2) = 0; +} + + + errlHndl_t IntrRp::checkAddress(uint64_t i_addr) { errlHndl_t err = NULL; @@ -498,6 +566,12 @@ errlHndl_t IntrRp::checkAddress(uint64_t i_addr) return err; } +// TODO rtc story 39878 +errlHndl_t IntrRp::shutDown() +{ + errlHndl_t err = NULL; + return err; +} // Register a message queue with a particular intr type errlHndl_t INTR::registerMsgQ(msg_q_t i_msgQ, ext_intr_t i_type) diff --git a/src/usr/intr/intrrp.H b/src/usr/intr/intrrp.H index 7078f823f..2900c5276 100644 --- a/src/usr/intr/intrrp.H +++ b/src/usr/intr/intrrp.H @@ -34,6 +34,11 @@ struct msg_t; +namespace TARGETING +{ + class Target; +}; + namespace INTR { class IntrRp @@ -46,6 +51,13 @@ namespace INTR */ static void init( errlHndl_t &io_rtaskRetErrl ); + /** + * This function is registered with init for shutdown + * processing of the interrupt presenter. + * TODO Story 39878 + */ + static errlHndl_t shutDown(); + protected: /** @@ -54,8 +66,7 @@ namespace INTR IntrRp() : iv_msgQ(NULL), iv_baseAddr(0), - iv_masterCpu(0), - iv_isVBU(false) {} + iv_masterCpu(0) {} /** * Destructor @@ -71,11 +82,13 @@ namespace INTR enum { + XIRR_RO_OFFSET = 0, //!< offset to XIRR (poll) CPPR_OFFSET = 4, //!< offset to CPPR (1 byte) XIRR_OFFSET = 4, //!< offset to XIRR (4 bytes) LINKA_OFFSET = 16, //!< offset to LINKA register LINKB_OFFSET = 20, //!< offset to LINKB register LINKC_OFFSET = 24, //!< offset to LINKC register + XISR_MASK = 0x00FFFFFF, //!< XISR MASK in XIRR register }; // If the interrupt can't be handled by the current chip there are @@ -184,7 +197,6 @@ namespace INTR Registry_t iv_registry; //!< registered interrupt type uint64_t iv_baseAddr; //!< Base address of hw INTR regs PIR_t iv_masterCpu; //!< Master cpu PIR - bool iv_isVBU; //!< TODO Don't run on VBU for now private: //functions @@ -220,13 +232,29 @@ namespace INTR void initInterruptPresenter(const PIR_t i_pir) const; /** + * Deconfigure the interrupt presenter registers + * @param[in] i_pir, the PIR value for the presenter + */ + void deconfigureInterruptPresenter(const PIR_t i_pir) const; + + /** + * Set the IPCBAR scom register + * @param[in] i_target, the Target. + * @param[in] i_pir, The pir for this processor + */ + errlHndl_t setBAR(TARGETING::Target * i_target, + const PIR_t i_pir); + + /** * Calculate the adress offset for the given cpu * @param[in] i_pir PIR value for the presenter * @return the offset */ - ALWAYS_INLINE + ALWAYS_INLINE uint64_t cpuOffsetAddr(const PIR_t i_pir) const { + // TODO when P7 support is removed then change this + // to use InterruptMsgHdlr::mmio_offset() uint64_t offset = (i_pir.nodeId * 8) + i_pir.chipId; offset <<= 20; switch (cpu_core_type()) diff --git a/src/usr/intr/test/intrtest.H b/src/usr/intr/test/intrtest.H index ae9ce135f..f7c6b37f4 100644 --- a/src/usr/intr/test/intrtest.H +++ b/src/usr/intr/test/intrtest.H @@ -32,6 +32,9 @@ #include <targeting/common/attributes.H> #include <sys/time.h> #include <sys/mmio.h> +#include <sys/task.h> +#include <sys/misc.h> +#include <kernel/intmsghandler.H> extern trace_desc_t * g_trac_intr; @@ -44,73 +47,41 @@ class IntrTest: public CxxTest::TestSuite */ void test_verifyState( void ) { - // TODO Temporaritly DISABLE in VBU until P8 support is verfied - if( TARGETING::is_vpo() ) + + uint32_t * addr = reinterpret_cast<uint32_t *>(iv_masterAddr); + + if(*addr != 0xFF000000) // XIRR ro reg { - return; + TS_FAIL + ("INTR:Master cpu not initialized-XIRR @ %p = 0x%08x", + addr,*addr); } - //// Add support for second chip (dummy) - ////uint32_t fake_pir = 0x00000001 << 5; // P7 - //uint32_t fake_pir = 0x00000001 << 7; // P8 - //msg_q_t intr_msgQ = msg_q_resolve(INTR_MSGQ); - //msg_t * msg = msg_allocate(); - //msg->type = INTR::MSG_INTR_ADD_CPU_USR; - //msg->data[0] = fake_pir; - - //msg_sendrecv(intr_msgQ, msg); - //msg_free(msg); + size_t threads = cpu_thread_count(); - // all the simics registers - for(uint64_t chip = 0; chip < 1; ++chip) + for(size_t thread = 0; thread < threads; ++thread) { - // simics P8 appears to support 8 threads on 1 core. - // simics P7 appears to support 4 threads on 2 cores. - // for P7, pretending to have 8 threads works because the - // bit fields for cores and threads are contiguous so we can - // let the thread count overflow into the core field. so this - // works for p7 as well. - for(uint64_t thread = 0; thread < 8; ++thread) + addr = reinterpret_cast<uint32_t *> + (iv_masterAddr + (thread << 12) + 16); // LINK A reg + + uint32_t linkVal = iv_masterPIR | 0x40000000; + + if((*addr != linkVal) || + (*(addr+1) != linkVal) || + (*(addr+2) != (linkVal | 0x80000000))) { - uint64_t offset = (chip << 20) | (thread << 12); - - uint32_t * addr = - reinterpret_cast<uint32_t *>(iv_baseAddr + offset); - - if(offset == 0) // Master cpu - { - if(*addr != 0xFF000000) - { - TS_FAIL - ("INTR:Master cpu not initialized-XIRR@%p=0x%08x", - addr,*addr); - } - } - - // TODO remove restriction when/if simics supports - // more than 2 chips and 4 threads each - if (chip < 2 && thread < 4) - { - if(offset != 0 && *addr != 0) - { - TS_FAIL("INTR:Chip %ld Thread %ld bad XIRR@%p=0x%08x", - chip,thread,addr,*addr); - } - - - - if(*(addr+4) != 0x40000000 || - *(addr+5) != 0x40000000 || - *(addr+6) != 0xC0000000) - { - TS_FAIL("INTR:Chip %ld Thread %ld bad LINKS" - " 0x%08x 0x%08x 0x%08x", - chip,thread, - *(addr+4),*(addr+5),*(addr+6)); - } - } + TS_FAIL("INTR:Bad LINKS on chipid 0x%08x " + "Links: 0x%08x 0x%08x 0x%08x", + ((uint32_t)iv_masterPIR + thread), + *addr, + *(addr + 1), + *(addr + 2) + ); } + } + + // Potentially could check all link registers on other chips } /** @@ -118,13 +89,8 @@ class IntrTest: public CxxTest::TestSuite */ void test_enableDisable( void ) { - // TODO Temporaritly DISABLE in VBU until P8 support is confirmed - if( TARGETING::is_vpo() ) - { - return; - } - uint32_t * addr = reinterpret_cast<uint32_t *>(iv_baseAddr); + uint32_t * addr = reinterpret_cast<uint32_t *>(iv_masterAddr); errlHndl_t err = INTR::disableExternalInterrupts(); @@ -162,7 +128,8 @@ class IntrTest: public CxxTest::TestSuite */ void test_intr( void ) { - // TODO Temporaritly DISABLE in VBU until P8 support is confirmed + + // DISABLE in VBU if( TARGETING::is_vpo() ) { return; @@ -182,7 +149,7 @@ class IntrTest: public CxxTest::TestSuite // Force an interrupt by writing to the MFFR on master volatile uint8_t * mfrr = - reinterpret_cast<uint8_t *>(iv_baseAddr+12); + reinterpret_cast<uint8_t *>(iv_masterAddr+12); *(mfrr) = 0x55; *(mfrr) = 0xff; @@ -206,12 +173,28 @@ class IntrTest: public CxxTest::TestSuite } - IntrTest() : CxxTest::TestSuite() - { - iv_baseAddr = reinterpret_cast<uint64_t> - (mmio_dev_map(reinterpret_cast<void*>(cv_realAddr),THIRTYTWO_MB)); - TRACDCOMP(g_trac_intr,"IntrTest()> iv_baseAddr=0x%.X",iv_baseAddr); - }; + IntrTest() : CxxTest::TestSuite() + { + iv_baseAddr = reinterpret_cast<uint64_t> + (mmio_dev_map(reinterpret_cast<void*>(cv_realAddr),THIRTYTWO_MB)); + + TRACDCOMP(g_trac_intr,"IntrTest()> iv_baseAddr=0x%.X",iv_baseAddr); + + task_affinity_pin(); // pin this task to current cpu + task_affinity_migrate_to_master(); // Move to the master cpu + + // Get the master cpu id, thread 0 + iv_masterPIR = task_getcpuid(); + + TRACDCOMP(g_trac_intr,"IntrTest()> iv_masterPIR=0x%.X",iv_masterPIR); + + iv_masterPIR &= 0xFFFFFFF8; + + task_affinity_unpin(); // unpin this task + + iv_masterAddr = InterruptMsgHdlr::mmio_offset(iv_masterPIR) + iv_baseAddr; + + }; ~IntrTest() @@ -222,6 +205,8 @@ class IntrTest: public CxxTest::TestSuite private: uint64_t iv_baseAddr; + uint64_t iv_masterAddr; + cpuid_t iv_masterPIR; static const uint64_t cv_realAddr; }; |