diff options
author | Doug Gilbert <dgilbert@us.ibm.com> | 2011-11-04 12:12:01 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2012-01-05 11:06:04 -0600 |
commit | 7de0708eac63bb81786c2a5e794c5d6fbef069c4 (patch) | |
tree | b47aeb4c9827851d61b44d5cb922704f73257693 /src/usr/intr/test/intrtest.H | |
parent | 048789fdce6b406de3b7149f8171afd63eea1829 (diff) | |
download | talos-hostboot-7de0708eac63bb81786c2a5e794c5d6fbef069c4.tar.gz talos-hostboot-7de0708eac63bb81786c2a5e794c5d6fbef069c4.zip |
Interrupt presenter implementation
Change-Id: If6b499d819b71298b8a64e096e1eb83c639ad645
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/517
Tested-by: Jenkins Server
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/intr/test/intrtest.H')
-rw-r--r-- | src/usr/intr/test/intrtest.H | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/src/usr/intr/test/intrtest.H b/src/usr/intr/test/intrtest.H new file mode 100644 index 000000000..9c0d4e412 --- /dev/null +++ b/src/usr/intr/test/intrtest.H @@ -0,0 +1,221 @@ +// IBM_PROLOG_BEGIN_TAG +// This is an automatically generated prolog. +// +// $Source: src/usr/intr/test/intrtest.H $ +// +// IBM CONFIDENTIAL +// +// COPYRIGHT International Business Machines Corp. 2011 +// +// p1 +// +// Object Code Only (OCO) source materials +// Licensed Internal Code Source Materials +// IBM HostBoot Licensed Internal Code +// +// The source code for this program is not published or other- +// wise divested of its trade secrets, irrespective of what has +// been deposited with the U.S. Copyright Office. +// +// Origin: 30 +// +// IBM_PROLOG_END +#ifndef __INTRTEST_H +#define __INTRTEST_H + +#include <cxxtest/TestSuite.H> +#include <intr/interrupt.H> +#include <errl/errlentry.H> +#include <errl/errlmanager.H> +#include <kernel/console.H> +#include <targeting/targetservice.H> + + +class IntrTest: public CxxTest::TestSuite +{ + public: + /** + * @brief INTR test setup values + */ + void test_verifyState( void ) + { + + // TODO Temporaritly DISABLE in VBU until P8 support is added + TARGETING::EntityPath syspath(TARGETING::EntityPath::PATH_PHYSICAL); + syspath.addLast(TARGETING::TYPE_SYS,0); + TARGETING::Target* sys = TARGETING::targetService().toTarget(syspath); + uint8_t vpo_mode = 0; + if( sys + && sys->tryGetAttr<TARGETING::ATTR_IS_SIMULATION>(vpo_mode) + && (vpo_mode == 1) ) + { + return; + } + + // Add support for second chip (dummy) + uint32_t fake_pir = 0x00000001 << 5; // P7 chip 1 TODO 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); + + // all the simics registers + for(uint64_t chip = 0; chip < 4; ++chip) + { + // simics P7 only supports 4 threads per core + // and 2 cores - let the thread field overflow + // into the core field -> 2 cores x 4 threads = 8 threads + for(uint64_t thread = 0; thread < 8; ++thread) + { + uint64_t offset = (chip << 20) | (thread << 12); + + uint32_t * addr = + reinterpret_cast<uint32_t *>(cv_baseAddr + offset); + + if(offset == 0) // Master cpu + { + if(*addr != 0xFF000000) + { + TS_FAIL + ("INTR:Master cpu not initialized-XIRR=0x%08x", + *addr); + } + } + + if (chip < 2 && thread < 4) // TODO Change when all threads supported + { + if(offset != 0 && *addr != 0) + { + TS_FAIL("INTR:Chip %ld Thread %ld bad XIRR=0x%08x", + chip,thread,*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)); + } + } + } + } + } + + /** + * @brief Disable then Enable interrupt handling + */ + void test_enableDisable( void ) + { + // TODO Temporaritly DISABLE in VBU until P8 support is added + TARGETING::EntityPath syspath(TARGETING::EntityPath::PATH_PHYSICAL); + syspath.addLast(TARGETING::TYPE_SYS,0); + TARGETING::Target* sys = TARGETING::targetService().toTarget(syspath); + uint8_t vpo_mode = 0; + if( sys + && sys->tryGetAttr<TARGETING::ATTR_IS_SIMULATION>(vpo_mode) + && (vpo_mode == 1) ) + { + return; + } + + uint32_t * addr = reinterpret_cast<uint32_t *>(cv_baseAddr); + + errlHndl_t err = INTR::disableExternalInterrupts(); + + if(err) + { + TS_FAIL("INTR::disableExternalInterrupts returned error log"); + delete err; + err = NULL; + } + + if((*addr & 0xFF000000) != 0) + { + TS_FAIL("INTR not disabled"); + } + + err = INTR::enableExternalInterrupts(); + + if(err) + { + TS_FAIL("INTR::enableExternalInterrupts returned error log"); + delete err; + err = NULL; + } + + + if((*addr & 0xFF000000) != 0xFF000000) + { + TS_FAIL("INTR not enabled"); + } + } + + /** + * @brief Register an interrupt message queue, force an interrupt, + * then handle the interrupt. + */ + void test_intr( void ) + { + // Injecting interproc interrupt seems to work sometimes and not others + // TODO need to investigate. +#ifdef __NOT_NOW__ + // TODO Temporaritly DISABLE in VBU until P8 support is added + TARGETING::EntityPath syspath(TARGETING::EntityPath::PATH_PHYSICAL); + syspath.addLast(TARGETING::TYPE_SYS,0); + TARGETING::Target* sys = TARGETING::targetService().toTarget(syspath); + uint8_t vpo_mode = 0; + if( sys + && sys->tryGetAttr<TARGETING::ATTR_IS_SIMULATION>(vpo_mode) + && (vpo_mode == 1) ) + { + return; + } + + extern trace_desc_t * g_trac_intr; + + errlHndl_t err = NULL; + + // Need to register a msgq + msg_q_t msgQ = msg_q_create(); + err = INTR::registerMsgQ(msgQ,INTR::INTERPROC); + if(err) + { + TS_FAIL("Errl from INTR::registerMsgQ()"); + delete err; + err = NULL; + } + + // Force an interrupt by writing to the MFFR on master + volatile uint8_t * mfrr = + reinterpret_cast<uint8_t *>(cv_baseAddr+12); + *(mfrr) = 0x55; + *(mfrr) = 0xff; + + msg_t* msg = msg_wait(msgQ); // wait for interrupt msg + TRACFCOMP(g_trac_intr,"Interrupt handled! Type=%lx",msg->type); + if(msg->type != INTR::INTERPROC) + { + TS_FAIL("INTR::unexpected interrupt type %lx",msg->type); + } + msg_respond(msgQ,msg); +#endif + } + + + private: + + static uint64_t cv_baseAddr; +}; + +uint64_t IntrTest::cv_baseAddr = 0x20000000000ul; + + +#endif + |