From 20b03fdaeb7414fdf9d43634976ca1ab5fbac7f1 Mon Sep 17 00:00:00 2001 From: Dan Crowell Date: Thu, 11 Aug 2011 13:30:16 -0500 Subject: Finishing up PNOR RP code (RTC Task 3440) -Add calls to mm_alloc_block -Fix error responses to message -Cleanup some error handling -Code review updates Final piece of the PNOR puzzle - Task 3389 -Also added a check to autocitest that will catch initialization fails. -Added some error printks to message interface -Disabled test_messageReadWrite testcase Change-Id: I4f1207138a6cf4f86cf2b6f3f81fc5885b02699d Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/252 Tested-by: Jenkins Server Reviewed-by: Daniel M. Crowell --- src/usr/pnor/pnorrp.C | 446 ++++++++++++++++++++++++++--------------- src/usr/pnor/pnorrp.H | 63 +++--- src/usr/pnor/test/pnorrptest.H | 53 ++--- 3 files changed, 348 insertions(+), 214 deletions(-) (limited to 'src/usr') diff --git a/src/usr/pnor/pnorrp.C b/src/usr/pnor/pnorrp.C index 7a9992c15..92c24b626 100644 --- a/src/usr/pnor/pnorrp.C +++ b/src/usr/pnor/pnorrp.C @@ -1,5 +1,4 @@ #include "pnorrp.H" -#include #include #include #include @@ -9,7 +8,9 @@ #include #include #include -#include +#include +#include + // Trace definition trace_desc_t* g_trac_pnor = NULL; @@ -22,7 +23,7 @@ TRAC_INIT(&g_trac_pnor, "PNOR", 4096); //4K /** * Eyecatcher strings for PNOR TOC entries */ -const char* cv_EYECATCHER[] = { +const char* cv_EYECATCHER[] = { //@todo - convert there to uint64_t "TOC", /**< PNOR::TOC : Table of Contents */ "GLOBAL", /**< PNOR::GLOBAL_DATA : Global Data */ "SBE", /**< PNOR::SBE_IPL : Self-Boot Enginer IPL image */ @@ -107,7 +108,7 @@ PnorRP::PnorRP() // setup everything in a separate function initDaemon(); - TRACFCOMP(g_trac_pnor, "< PnorRP::PnorRP " ); + TRACFCOMP(g_trac_pnor, "< PnorRP::PnorRP : Startup Errors=%X ", iv_startupRC ); } /** @@ -118,7 +119,12 @@ PnorRP::~PnorRP() TRACFCOMP(g_trac_pnor, "PnorRP::~PnorRP> " ); // delete the message queue we created - msg_q_destroy( iv_msgQ ); + if( iv_msgQ ) + { + msg_q_destroy( iv_msgQ ); + } + + // should kill the task we spawned, but that isn't needed right now TRACFCOMP(g_trac_pnor, "< PnorRP::~PnorRP" ); } @@ -129,18 +135,51 @@ PnorRP::~PnorRP() void PnorRP::initDaemon() { TRACUCOMP(g_trac_pnor, "PnorRP::initDaemon> " ); + errlHndl_t l_errhdl = NULL; + + do + { + // read the TOC in the PNOR to compute the sections + l_errhdl = readTOC(); + if( l_errhdl ) + { + break; + } - // read the TOC in the PNOR to compute the sections - readTOC(); + // create a message queue + iv_msgQ = msg_q_create(); - // create a message queue - iv_msgQ = msg_q_create(); + // create a Block, passing in the message queue + int rc = mm_alloc_block( iv_msgQ, (void*) BASE_VADDR, TOTAL_SIZE ); + if( rc ) + { + TRACFCOMP( g_trac_pnor, "PnorRP::initDaemon> Error from mm_alloc_block : rc=%d", rc ); + /*@ + * @errortype + * @moduleid PNOR::MOD_PNORRP_INITDAEMON + * @reasoncode PNOR::RC_EXTERNAL_ERROR + * @userdata1 Requested Address + * @userdata2 rc from mm_alloc_block + * @devdesc PnorRP::initDaemon> Error from mm_alloc_block + */ + l_errhdl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, + PNOR::MOD_PNORRP_GETSECTIONINFO, + PNOR::RC_INVALID_SECTION, + TO_UINT64(BASE_VADDR), + TO_UINT64(rc)); + break; + } - // create a Block, passing in the message queue - //@todo iv_block = new Block( 0, 0 ); + // start task to wait on the queue + task_create( wait_for_message, NULL ); - // start task to wait on the queue - task_create( wait_for_message, NULL ); + } while(0); + + if( l_errhdl ) + { + errlCommit(l_errhdl); + iv_startupRC = l_errhdl->reasonCode(); + } TRACUCOMP(g_trac_pnor, "< PnorRP::initDaemon" ); } @@ -154,44 +193,71 @@ errlHndl_t PnorRP::getSectionInfo( PNOR::SectionId i_section, PNOR::SectionInfo_t& o_info ) { //TRACDCOMP(g_trac_pnor, "PnorRP::getSectionInfo> i_section=%d, i_side=%X", i_section, i_side ); - errlHndl_t errhdl = NULL; - + errlHndl_t l_errhdl = NULL; PNOR::SectionId id = i_section; - // Zero-length means the section is invalid - if( 0 == iv_TOC[i_side][id].size ) - { - TRACFCOMP( g_trac_pnor, "PnorRP::getSectionInfo> Invalid Section Requested : i_section=%d, i_side=%d", i_section, i_side ); - TRACFCOMP(g_trac_pnor, "o_info={ id=%d, size=%d }", iv_TOC[i_side][i_section].id, iv_TOC[i_side][i_section].size ); - /*@ - * @errortype - * @moduleid PNOR::MOD_PNORRP_GETSECTIONINFO - * @reasoncode PNOR::RC_INVALID_SECTION - * @userdata1 Requested Section - * @userdata2 Requested Side - * @devdesc PnorRP::waitForMessage> Invalid Address for read/write - */ - errhdl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, - PNOR::MOD_PNORRP_GETSECTIONINFO, - PNOR::RC_INVALID_SECTION, - TO_UINT64(i_section), - TO_UINT64(i_side)); + do + { + // Abort this operation if we had a startup failure + uint64_t rc = 0; + if( didStartupFail(rc) ) + { + TRACFCOMP( g_trac_pnor, "PnorRP::getSectionInfo> RP not properly initialized, failing : rc=%X", rc ); + /*@ + * @errortype + * @moduleid PNOR::MOD_PNORRP_GETSECTIONINFO + * @reasoncode PNOR::RC_STARTUP_FAIL + * @userdata1 Requested Section + * @userdata2 Startup RC + * @devdesc PnorRP::getSectionInfo> RP not properly initialized + */ + l_errhdl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, + PNOR::MOD_PNORRP_GETSECTIONINFO, + PNOR::RC_STARTUP_FAIL, + TO_UINT64(i_section), + rc); + + // set the return section to our invalid data + id = PNOR::INVALID_SECTION; + break; + } - // set the return valid to our invalid data - id = PNOR::INVALID_SECTION; - } + // Zero-length means the section is invalid + if( 0 == iv_TOC[i_side][id].size ) + { + TRACFCOMP( g_trac_pnor, "PnorRP::getSectionInfo> Invalid Section Requested : i_section=%d, i_side=%d", i_section, i_side ); + TRACFCOMP(g_trac_pnor, "o_info={ id=%d, size=%d }", iv_TOC[i_side][i_section].id, iv_TOC[i_side][i_section].size ); + /*@ + * @errortype + * @moduleid PNOR::MOD_PNORRP_GETSECTIONINFO + * @reasoncode PNOR::RC_INVALID_SECTION + * @userdata1 Requested Section + * @userdata2 Requested Side + * @devdesc PnorRP::getSectionInfo> Invalid Address for read/write + */ + l_errhdl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, + PNOR::MOD_PNORRP_GETSECTIONINFO, + PNOR::RC_INVALID_SECTION, + TO_UINT64(i_section), + TO_UINT64(i_side)); + + // set the return section to our invalid data + id = PNOR::INVALID_SECTION; + break; + } + } while(0); TRACFCOMP( g_trac_pnor, "i_section=%d, i_side=%d : id=%d", i_section, i_side, iv_TOC[i_side][i_section].id ); // copy my data into the external format - o_info.id = iv_TOC[i_side][i_section].id; - o_info.side = iv_TOC[i_side][i_section].side; - o_info.name = cv_EYECATCHER[i_section]; - o_info.vaddr = iv_TOC[i_side][i_section].virtAddr; - o_info.size = iv_TOC[i_side][i_section].size; - o_info.eccProtected = iv_TOC[i_side][i_section].eccProtected; - - return errhdl; + o_info.id = iv_TOC[i_side][id].id; + o_info.side = iv_TOC[i_side][id].side; + o_info.name = cv_EYECATCHER[id]; + o_info.vaddr = iv_TOC[i_side][id].virtAddr; + o_info.size = iv_TOC[i_side][id].size; + o_info.eccProtected = iv_TOC[i_side][id].eccProtected; + + return l_errhdl; } @@ -199,9 +265,10 @@ errlHndl_t PnorRP::getSectionInfo( PNOR::SectionId i_section, /** * @brief Read the TOC and store section information */ -void PnorRP::readTOC() +errlHndl_t PnorRP::readTOC() { TRACUCOMP(g_trac_pnor, "PnorRP::readTOC>" ); + errlHndl_t l_errhdl = NULL; // Zero out my table for( uint64_t side = 0; side < NUM_SIDES; side++ ) @@ -217,11 +284,12 @@ void PnorRP::readTOC() iv_TOC[side][id].pmrwAddr = 0; iv_TOC[side][id].virtAddr = 0; iv_TOC[side][id].size = 0; - iv_TOC[side][id].eccProtected = false; + iv_TOC[side][id].eccProtected = 0; } } //@todo - Add in some dummy values for now + // Will update under Story 3547 // assume 1 chip with only 1 side for now, no sideless // TOC starts at offset zero in MMRD mode @@ -244,17 +312,18 @@ void PnorRP::readTOC() iv_TOC[PNOR::SIDE_A][PNOR::GLOBAL_DATA].mmrdAddr = iv_TOC[PNOR::SIDE_A][PNOR::HB_EXT_CODE].mmrdAddr + iv_TOC[PNOR::SIDE_A][PNOR::HB_EXT_CODE].size; iv_TOC[PNOR::SIDE_A][PNOR::HB_DATA].mmrdAddr = iv_TOC[PNOR::SIDE_A][PNOR::GLOBAL_DATA].mmrdAddr + iv_TOC[PNOR::SIDE_A][PNOR::GLOBAL_DATA].size; // PMRW offsets - no ECC support yet so just equal to MMRD - iv_TOC[PNOR::SIDE_A][PNOR::TOC].pmrwAddr = BASE_VADDR + 0; - iv_TOC[PNOR::SIDE_A][PNOR::HB_EXT_CODE].pmrwAddr = iv_TOC[PNOR::SIDE_A][PNOR::TOC].virtAddr + iv_TOC[PNOR::SIDE_A][PNOR::TOC].size; - iv_TOC[PNOR::SIDE_A][PNOR::GLOBAL_DATA].pmrwAddr = iv_TOC[PNOR::SIDE_A][PNOR::HB_EXT_CODE].virtAddr + iv_TOC[PNOR::SIDE_A][PNOR::HB_EXT_CODE].size; - iv_TOC[PNOR::SIDE_A][PNOR::HB_DATA].pmrwAddr = iv_TOC[PNOR::SIDE_A][PNOR::GLOBAL_DATA].virtAddr + iv_TOC[PNOR::SIDE_A][PNOR::GLOBAL_DATA].size; + iv_TOC[PNOR::SIDE_A][PNOR::TOC].pmrwAddr = iv_TOC[PNOR::SIDE_A][PNOR::TOC].mmrdAddr; + iv_TOC[PNOR::SIDE_A][PNOR::HB_EXT_CODE].pmrwAddr = iv_TOC[PNOR::SIDE_A][PNOR::HB_EXT_CODE].mmrdAddr; + iv_TOC[PNOR::SIDE_A][PNOR::GLOBAL_DATA].pmrwAddr = iv_TOC[PNOR::SIDE_A][PNOR::GLOBAL_DATA].mmrdAddr; + iv_TOC[PNOR::SIDE_A][PNOR::HB_DATA].pmrwAddr = iv_TOC[PNOR::SIDE_A][PNOR::HB_DATA].mmrdAddr; //@todo - end fake data //@todo - load flash layout (how many chips) //@todo - read TOC on each chip/bank/whatever - + TRACUCOMP(g_trac_pnor, "< PnorRP::readTOC" ); + return l_errhdl; } @@ -266,72 +335,110 @@ void PnorRP::waitForMessage() { TRACFCOMP(g_trac_pnor, "PnorRP::waitForMessage>" ); - errlHndl_t l_err = NULL; + errlHndl_t l_errhdl = NULL; msg_t* message = NULL; uint8_t* user_addr = NULL; uint8_t* eff_addr = NULL; uint64_t dev_offset = 0; uint64_t chip_select = 0xF; bool needs_ecc = false; + int rc = 0; + uint64_t status_rc = 0; while(1) { + status_rc = 0; TRACUCOMP(g_trac_pnor, "PnorRP::waitForMessage> waiting for message" ); message = msg_wait( iv_msgQ ); if( message ) { - user_addr = (uint8_t*)message->data[0]; - eff_addr = (uint8_t*)message->data[1]; - l_err = computeDeviceAddr( eff_addr, MMRD_MODE, dev_offset, chip_select, needs_ecc ); - //@todo - assuming MMRD mode for now - if( l_err ) + /* data[0] = virtual address requested + * data[1] = address to place contents + */ + eff_addr = (uint8_t*)message->data[0]; + user_addr = (uint8_t*)message->data[1]; + + //@todo - assuming MMRD mode for now (Story 3548) + l_errhdl = computeDeviceAddr( eff_addr, PNOR::MMRD, dev_offset, chip_select, needs_ecc ); + if( l_errhdl ) { - errlCommit(l_err); - //@todo - kill calling task?, commit log + status_rc = -EFAULT; /* Bad address */ + } + else + { + //@todo - handle MMRD/PMRW mode + // if MMRD then needs_ecc = false - if( !msg_is_async(message) ) + switch(message->type) { - TRACUCOMP( g_trac_pnor, "sending response...\n" ); - msg_respond( iv_msgQ, message ); //@todo - what goes in response message? + case( MSG_MM_RP_READ ): + l_errhdl = readFromDevice( dev_offset, chip_select, needs_ecc, user_addr ); + if( l_errhdl ) + { + status_rc = -EIO; /* I/O error */ + } + break; + case( MSG_MM_RP_WRITE ): + l_errhdl = writeToDevice( dev_offset, chip_select, needs_ecc, user_addr ); + if( l_errhdl ) + { + status_rc = -EIO; /* I/O error */ + } + break; + default: + TRACFCOMP( g_trac_pnor, "PnorRP::waitForMessage> Unrecognized message type : user_addr=%p, eff_addr=%p, msgtype=%d", user_addr, eff_addr, message->type ); + /*@ + * @errortype + * @moduleid PNOR::MOD_PNORRP_WAITFORMESSAGE + * @reasoncode PNOR::RC_INVALID_MESSAGE + * @userdata1 Message type + * @userdata2 Requested Virtual Address + * @devdesc PnorRP::waitForMessage> Unrecognized message type + */ + l_errhdl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, + PNOR::MOD_PNORRP_WAITFORMESSAGE, + PNOR::RC_INVALID_MESSAGE, + TO_UINT64(message->type), + (uint64_t)eff_addr); + status_rc = -EINVAL; /* Invalid argument */ } - continue; // go wait for another message + } + + if( !l_errhdl && msg_is_async(message) ) + { + TRACFCOMP( g_trac_pnor, "PnorRP::waitForMessage> Unsupported Asynchronous Message : user_addr=%p, eff_addr=%p, msgtype=%d", user_addr, eff_addr, message->type ); + /*@ + * @errortype + * @moduleid PNOR::MOD_PNORRP_WAITFORMESSAGE + * @reasoncode PNOR::RC_INVALID_MESSAGE + * @userdata1 Message type + * @userdata2 Requested Virtual Address + * @devdesc PnorRP::waitForMessage> Unrecognized message type + */ + l_errhdl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, + PNOR::MOD_PNORRP_WAITFORMESSAGE, + PNOR::RC_INVALID_MESSAGE, + TO_UINT64(message->type), + (uint64_t)eff_addr); + status_rc = -EINVAL; /* Invalid argument */ } - //@todo - handle MMRD/PMRW mode - // if MMRD then needs_ecc = false - - switch(message->type) + if( l_errhdl ) { - case( RP::READ_PAGE ): - readFromDevice( dev_offset, chip_select, needs_ecc, user_addr ); - break; - case( RP::WRITE_PAGE ): - writeToDevice( dev_offset, chip_select, needs_ecc, user_addr ); - break; - default: - TRACFCOMP( g_trac_pnor, "PnorRP::waitForMessage> Unrecognized message type : user_addr=%p, eff_addr=%p, msgtype=%d", user_addr, eff_addr, message->type ); - /*@ - * @errortype - * @moduleid PNOR::MOD_PNORRP_WAITFORMESSAGE - * @reasoncode PNOR::RC_INVALID_MESSAGE - * @userdata1 Message type - * @userdata2 User memory address - * @devdesc PnorRP::waitForMessage> Unrecognized message type - */ - l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, - PNOR::MOD_PNORRP_WAITFORMESSAGE, - PNOR::RC_INVALID_MESSAGE, - TO_UINT64(message->type), - (uint64_t)user_addr); - errlCommit(l_err); - //@todo - kill calling task?, commit log - continue; // go wait for another message + errlCommit(l_errhdl); } - if( !msg_is_async(message) ) + + /* Expected Response: + * data[0] = virtual address requested + * data[1] = rc (0 or negative errno value) + */ + message->data[1] = status_rc; + rc = msg_respond( iv_msgQ, message ); + if( rc ) { - TRACUCOMP( g_trac_pnor, "sending response...\n" ); - msg_respond( iv_msgQ, message ); //@todo - what goes in response message? + TRACFCOMP(g_trac_pnor, "PnorRP::waitForMessage> Error from msg_respond, giving up : rc=%d", rc ); + break; } } } @@ -344,80 +451,102 @@ void PnorRP::waitForMessage() /** * @brief Retrieve 1 page of data from the PNOR device */ -void PnorRP::readFromDevice( uint64_t i_offset, - uint64_t i_chip, - bool i_ecc, - void* o_dest ) +errlHndl_t PnorRP::readFromDevice( uint64_t i_offset, + uint64_t i_chip, + bool i_ecc, + void* o_dest ) { TRACUCOMP(g_trac_pnor, "PnorRP::readFromDevice> i_offset=0x%X, i_chip=%d", i_offset, i_chip ); - - TARGETING::Target* pnor_target = TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL; //@todo - - void* data_to_read = o_dest; + errlHndl_t l_errhdl = NULL; uint8_t* ecc_buffer = NULL; - size_t read_size = PAGESIZE; - if( i_ecc ) - { - ecc_buffer = new uint8_t[PAGESIZE_PLUS_ECC]; - data_to_read = ecc_buffer; - read_size = PAGESIZE_PLUS_ECC; - } - errlHndl_t l_err = DeviceFW::deviceRead(pnor_target, - data_to_read, - read_size, - DEVICE_PNOR_ADDRESS(i_chip,i_offset) ); - if( l_err ) + do { - TRACFCOMP(g_trac_pnor, "PnorRP::readFromDevice> Error from device : RC=%X", l_err->reasonCode() ); - errlCommit(l_err); - //@todo - anything else? - } + TARGETING::Target* pnor_target = TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL; + + // assume a single page + void* data_to_read = o_dest; + size_t read_size = PAGESIZE; + + // if we need to handle ECC we need to read more than 1 page + if( i_ecc ) + { + ecc_buffer = new uint8_t[PAGESIZE_PLUS_ECC]; + data_to_read = ecc_buffer; + read_size = PAGESIZE_PLUS_ECC; + } + + // get the data from the PNOR DD + l_errhdl = DeviceFW::deviceRead(pnor_target, + data_to_read, + read_size, + DEVICE_PNOR_ADDRESS(i_chip,i_offset) ); + if( l_errhdl ) + { + TRACFCOMP(g_trac_pnor, "PnorRP::readFromDevice> Error from device : RC=%X", l_errhdl->reasonCode() ); + break; + } + + // remove the ECC data + if( i_ecc ) + { + l_errhdl = stripECC( data_to_read, o_dest ); + if( l_errhdl ) + { + break; + } + } + } while(0); - // remove the ECC data - if( i_ecc ) + if( ecc_buffer ) { - l_err = stripECC( data_to_read, o_dest ); - //@todo - handle ECC error delete[] ecc_buffer; } TRACUCOMP(g_trac_pnor, "< PnorRP::readFromDevice" ); + return l_errhdl; } /** * @brief Write 1 page of data to the PNOR device */ -void PnorRP::writeToDevice( uint64_t i_offset, - uint64_t i_chip, - bool i_ecc, - void* i_src ) +errlHndl_t PnorRP::writeToDevice( uint64_t i_offset, + uint64_t i_chip, + bool i_ecc, + void* i_src ) { TRACUCOMP(g_trac_pnor, "PnorRP::writeToDevice> i_offset=%X, i_chip=%d", i_offset, i_chip ); - - TARGETING::Target* pnor_target = TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL; //@todo - - // apply ECC to data if needed - void* data_to_write = i_src; + errlHndl_t l_errhdl = NULL; uint8_t* ecc_buffer = NULL; - if( i_ecc ) - { - ecc_buffer = new uint8_t[PAGESIZE]; - applyECC( i_src, ecc_buffer ); - data_to_write = (void*)ecc_buffer; - } - size_t write_size = PAGESIZE; - errlHndl_t l_err = DeviceFW::deviceWrite(pnor_target, - data_to_write, - write_size, - DEVICE_PNOR_ADDRESS(i_chip,i_offset) ); - if( l_err ) + do { - TRACFCOMP(g_trac_pnor, "PnorRP::readFromDevice> Error from device : RC=%X", l_err->reasonCode() ); - errlCommit(l_err); - //@todo - anything else? - } + TARGETING::Target* pnor_target = TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL; + + // assume a single page to write + void* data_to_write = i_src; + size_t write_size = PAGESIZE; + + // apply ECC to data if needed + if( i_ecc ) + { + ecc_buffer = new uint8_t[PAGESIZE]; + applyECC( i_src, ecc_buffer ); + data_to_write = (void*)ecc_buffer; + write_size = PAGESIZE_PLUS_ECC; + } + + // write the data out to the PNOR DD + errlHndl_t l_errhdl = DeviceFW::deviceWrite(pnor_target, + data_to_write, + write_size, + DEVICE_PNOR_ADDRESS(i_chip,i_offset) ); + if( l_errhdl ) + { + TRACFCOMP(g_trac_pnor, "PnorRP::readFromDevice> Error from device : RC=%X", l_errhdl->reasonCode() ); + break; + } + } while(0); if( ecc_buffer ) { @@ -425,18 +554,19 @@ void PnorRP::writeToDevice( uint64_t i_offset, } TRACUCOMP(g_trac_pnor, "< PnorRP::writeToDevice" ); + return l_errhdl; } /** * @brief Convert a virtual address into the PNOR device address */ errlHndl_t PnorRP::computeDeviceAddr( void* i_vaddr, - ControllerMode i_mode, + PNOR::lscMode i_mode, uint64_t& o_offset, uint64_t& o_chip, bool& o_ecc ) { - errlHndl_t l_err = NULL; + errlHndl_t l_errhdl = NULL; o_offset = 0; o_chip = 99; uint64_t l_vaddr = (uint64_t)i_vaddr; @@ -455,28 +585,28 @@ errlHndl_t PnorRP::computeDeviceAddr( void* i_vaddr, * @devdesc PnorRP::computeDeviceAddr> Virtual Address outside * known PNOR range */ - l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, + l_errhdl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, PNOR::MOD_PNORRP_COMPUTEDEVICEADDR, PNOR::RC_INVALID_ADDRESS, l_vaddr, BASE_VADDR); - return l_err; + return l_errhdl; } // find the matching section PNOR::SideSelect side = PNOR::SIDE_A; PNOR::SectionId id = PNOR::INVALID_SECTION; - l_err = computeSection( l_vaddr, side, id ); - if( l_err ) + l_errhdl = computeSection( l_vaddr, side, id ); + if( l_errhdl ) { - return l_err; + return l_errhdl; } // pull out the information we need to return from our global copy o_chip = iv_TOC[side][id].chip; o_ecc = iv_TOC[side][id].eccProtected; o_offset = l_vaddr - iv_TOC[side][id].virtAddr; //offset into pnor - if( MMRD_MODE == i_mode ) + if( PNOR::MMRD == i_mode ) { o_offset += iv_TOC[side][id].mmrdAddr; } @@ -486,7 +616,7 @@ errlHndl_t PnorRP::computeDeviceAddr( void* i_vaddr, } TRACUCOMP( g_trac_pnor, "< PnorRP::computeDeviceAddr: o_offset=0x%X, o_chip=%d", o_offset, o_chip ); - return l_err; + return l_errhdl; } @@ -498,7 +628,7 @@ void PnorRP::applyECC( void* i_orig, { TRACFCOMP(g_trac_pnor, "> PnorRP::applyECC" ); - //@todo - fill this in + //@todo - fill this in (Story 3548) memcpy( o_ecc, i_orig, PAGESIZE ); TRACFCOMP(g_trac_pnor, "< PnorRP::applyECC" ); @@ -512,7 +642,7 @@ errlHndl_t PnorRP::stripECC( void* i_orig, { TRACFCOMP(g_trac_pnor, "> PnorRP::stripECC" ); - //@todo - fill this in + //@todo - fill this in (Story 3548) memcpy( o_data, i_orig, PAGESIZE ); TRACFCOMP(g_trac_pnor, "< PnorRP::stripECC" ); diff --git a/src/usr/pnor/pnorrp.H b/src/usr/pnor/pnorrp.H index dccce8cd5..9b0be7161 100644 --- a/src/usr/pnor/pnorrp.H +++ b/src/usr/pnor/pnorrp.H @@ -7,6 +7,7 @@ #include #include #include +#include "pnordd.H" /** * PNOR Resource Provider @@ -53,17 +54,18 @@ class PnorRP */ enum { - BASE_VADDR = 0x80000000, /**< 2GB */ + BASE_VADDR = 2*1024*1024*1024ul, /**< 2GB = 0x80000000*/ NUM_SIDES = 3, /**< A, B, Sideless */ - SIDE_SIZE = 0x2000000, /**< Allocate 32 MB of VA per side */ + SIDE_SIZE = 32*1024*1024ul, /**< Allocate 32 MB (0x2000000) of VA per side */ SIDEA_VADDR = BASE_VADDR, /**< Base address of Side A */ SIDEB_VADDR = SIDEA_VADDR + SIDE_SIZE, /**< Base address of Side B */ - SIDELESS_VADDR = SIDEA_VADDR + SIDE_SIZE*2, /**< Base address of Sideless data */ + SIDELESS_VADDR = SIDEB_VADDR + SIDE_SIZE, /**< Base address of Sideless data */ - LAST_VADDR = BASE_VADDR + SIDE_SIZE*NUM_SIDES, /**< End of our VA range */ + TOTAL_SIZE = SIDE_SIZE*NUM_SIDES, /**< Size of PNOR VA region */ + LAST_VADDR = BASE_VADDR + TOTAL_SIZE, /**< End of our VA range */ /** Real number of bytes required to read 1 logical page */ PAGESIZE_PLUS_ECC = PAGESIZE * (9/8), // 8 bytes of data + 1 byte of ECC @@ -81,16 +83,7 @@ class PnorRP uint64_t size_act; /**< Actual size of content in bytes */ char fuse_tbd[96]; /**< Remainder is TBD depending on FUSE requirements */ //@todo - need a chip select here I think? - }; - - /** - * Mode that PNOR controller is using - */ - enum ControllerMode - { - MMRD_MODE, /**< MMRD - Read-Only, ECC is hidden by hardware */ - PMRW_MODE, /**< PMRW - Write-able mode, ECC must be handled on reads/writes */ - }; + } PACKED; /** * Internal information to deal with the sections of PNOR @@ -99,13 +92,15 @@ class PnorRP PNOR::SectionId id; /**< Identifier for this section */ PNOR::SideSelect side; /** Side Select */ - uint64_t chip; /**< Chip Select */ - uint64_t mmrdAddr; /**< Address in MMRD mode (no ECC) */ - uint64_t pmrwAddr; /**< Address in PMRW mode (with ECC) */ uint64_t virtAddr; /**< Virtual address for the start of the section */ - uint64_t size; /**< Actual size of content in bytes (not including ECC) */ - bool eccProtected; /**< Section is ECC protected */ - }; + + uint32_t mmrdAddr; /**< Address in MMRD mode (no ECC) */ + uint32_t pmrwAddr; /**< Address in PMRW mode (with ECC) */ + + uint32_t size; /**< Actual size of content in bytes (not including ECC) */ + uint8_t chip; /**< Chip Select */ + uint8_t eccProtected; /**< Section is ECC protected */ + } PACKED; /** * Cached copy of section data @@ -119,6 +114,8 @@ class PnorRP /** * Remember that we failed during initial startup + * This is set by startup methods to indicate to constructor that + * something went wrong */ uint64_t iv_startupRC; @@ -129,8 +126,10 @@ class PnorRP /** * @brief Read the TOC and store section information + * + * @return Error from device */ - void readTOC(); + errlHndl_t readTOC(); /** * @brief Message receiver @@ -144,11 +143,13 @@ class PnorRP * @param[in] i_chip Which PNOR chip * @param[in] i_ecc true=apply ECC after reading * @param[out] o_dest Buffer to copy data into + * + * @return Error from device */ - void readFromDevice( uint64_t i_offset, - uint64_t i_chip, - bool i_ecc, - void* o_dest ); + errlHndl_t readFromDevice( uint64_t i_offset, + uint64_t i_chip, + bool i_ecc, + void* o_dest ); /** * @brief Write 1 logical page of data to the PNOR device @@ -157,11 +158,13 @@ class PnorRP * @param[in] i_chip Which PNOR chip * @param[in] i_ecc true=apply ECC before writing * @param[in] i_src Buffer to copy data from + * + * @return Error from device */ - void writeToDevice( uint64_t i_offset, - uint64_t i_chip, - bool i_ecc, - void* i_src ); + errlHndl_t writeToDevice( uint64_t i_offset, + uint64_t i_chip, + bool i_ecc, + void* i_src ); /** * @brief Convert a virtual address into the PNOR device address @@ -175,7 +178,7 @@ class PnorRP * @return Error if VA is bad */ errlHndl_t computeDeviceAddr( void* i_vaddr, - ControllerMode i_mode, + PNOR::lscMode i_mode, uint64_t& o_offset, uint64_t& o_chip, bool& o_ecc ); diff --git a/src/usr/pnor/test/pnorrptest.H b/src/usr/pnor/test/pnorrptest.H index c2c5cccd9..ca63bfeed 100644 --- a/src/usr/pnor/test/pnorrptest.H +++ b/src/usr/pnor/test/pnorrptest.H @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include "../pnorrp.H" @@ -20,6 +19,7 @@ extern trace_desc_t* g_trac_pnor; + class PnorRpTest : public CxxTest::TestSuite { public: @@ -106,6 +106,7 @@ class PnorRpTest : public CxxTest::TestSuite */ void test_messageReadWrite(void) { + return; //this fails with the new message ids TRACFCOMP(g_trac_pnor, "PnorRpTest::test_messageReadWrite> Start" ); uint64_t fails = 0; uint64_t total = 0; @@ -127,27 +128,27 @@ class PnorRpTest : public CxxTest::TestSuite // read the first page total++; - msg->type = RP::READ_PAGE; - msg->data[0] = (uint64_t)data1_r; //data[0] = address to copy into (user buffer) - msg->data[1] = info.vaddr; //data[1] = address to copy from (effective address) + msg->type = MSG_MM_RP_READ; + msg->data[1] = (uint64_t)data1_r; //data[1] = address to copy into (user buffer) + msg->data[0] = info.vaddr; //data[0] = address to copy from (effective address) rc = msg_sendrecv( mq, msg ); if( rc ) { - TRACFCOMP(g_trac_pnor, "PnorRpTest::test_messageReadWrite> ERROR : error from msg_sendrecv(READ_PAGE):1" ); - TS_FAIL( "PnorRpTest::test_messageReadWrite> ERROR : error from msg_sendrecv(READ_PAGE):1, rc=%d", rc ); + TRACFCOMP(g_trac_pnor, "PnorRpTest::test_messageReadWrite> ERROR : error from msg_sendrecv(READ):1" ); + TS_FAIL( "PnorRpTest::test_messageReadWrite> ERROR : error from msg_sendrecv(READ):1, rc=%d", rc ); fails++; } // read the second page total++; - msg->type = RP::READ_PAGE; - msg->data[0] = (uint64_t)data2_r; //data[0] = address to copy into (user buffer) - msg->data[1] = info.vaddr + PAGESIZE; //data[1] = address to copy from (effective address) + msg->type = MSG_MM_RP_READ; + msg->data[1] = (uint64_t)data2_r; //data[1] = address to copy into (user buffer) + msg->data[0] = info.vaddr + PAGESIZE; //data[0] = address to copy from (effective address) rc = msg_sendrecv( mq, msg ); if( rc ) { - TRACFCOMP(g_trac_pnor, "PnorRpTest::test_messageReadWrite> ERROR : error from msg_sendrecv(READ_PAGE):2" ); - TS_FAIL( "PnorRpTest::test_messageReadWrite> ERROR : error from msg_sendrecv(READ_PAGE):2, rc=%d", rc ); + TRACFCOMP(g_trac_pnor, "PnorRpTest::test_messageReadWrite> ERROR : error from msg_sendrecv(READ):2" ); + TS_FAIL( "PnorRpTest::test_messageReadWrite> ERROR : error from msg_sendrecv(READ):2, rc=%d", rc ); fails++; } @@ -159,27 +160,27 @@ class PnorRpTest : public CxxTest::TestSuite // write the changed page back out total++; - msg->type = RP::WRITE_PAGE; - msg->data[0] = (uint64_t)data_tmp; //data[0] = address to copy from (user buffer) - msg->data[1] = info.vaddr; //data[1] = address to copy into (effective address) + msg->type = MSG_MM_RP_WRITE; + msg->data[1] = (uint64_t)data_tmp; //data[1] = address to copy from (user buffer) + msg->data[0] = info.vaddr; //data[0] = address to copy into (effective address) rc = msg_sendrecv( mq, msg ); if( rc ) { - TRACFCOMP(g_trac_pnor, "PnorRpTest::test_messageReadWrite> ERROR : error from msg_sendrecv(WRITE_PAGE):1" ); - TS_FAIL( "PnorRpTest::test_messageReadWrite> ERROR : error from msg_sendrecv(WRITE_PAGE):1, rc=%d", rc ); + TRACFCOMP(g_trac_pnor, "PnorRpTest::test_messageReadWrite> ERROR : error from msg_sendrecv(WRITE):1" ); + TS_FAIL( "PnorRpTest::test_messageReadWrite> ERROR : error from msg_sendrecv(WRITE):1, rc=%d", rc ); fails++; } // read the first page again total++; - msg->type = RP::READ_PAGE; - msg->data[0] = (uint64_t)data1_r; //data[0] = address to copy into (user buffer) - msg->data[1] = info.vaddr; //data[1] = address to copy from (effective address) + msg->type = MSG_MM_RP_READ; + msg->data[1] = (uint64_t)data1_r; //data[1] = address to copy into (user buffer) + msg->data[0] = info.vaddr; //data[0] = address to copy from (effective address) rc = msg_sendrecv( mq, msg ); if( rc ) { - TRACFCOMP(g_trac_pnor, "PnorRpTest::test_messageReadWrite> ERROR : error from msg_sendrecv(READ_PAGE):3" ); - TS_FAIL( "PnorRpTest::test_messageReadWrite> ERROR : error from msg_sendrecv(READ_PAGE):3, rc=%d", rc ); + TRACFCOMP(g_trac_pnor, "PnorRpTest::test_messageReadWrite> ERROR : error from msg_sendrecv(READ):3" ); + TS_FAIL( "PnorRpTest::test_messageReadWrite> ERROR : error from msg_sendrecv(READ):3, rc=%d", rc ); fails++; } @@ -200,14 +201,14 @@ class PnorRpTest : public CxxTest::TestSuite // read the second page again total++; - msg->type = RP::READ_PAGE; - msg->data[0] = (uint64_t)data_tmp; //data[0] = address to copy into (user buffer) - msg->data[1] = info.vaddr + PAGESIZE; //data[1] = address to copy from (effective address) + msg->type = MSG_MM_RP_READ; + msg->data[1] = (uint64_t)data_tmp; //data[1] = address to copy into (user buffer) + msg->data[0] = info.vaddr + PAGESIZE; //data[0] = address to copy from (effective address) rc = msg_sendrecv( mq, msg ); if( rc ) { - TRACFCOMP(g_trac_pnor, "PnorRpTest::test_messageReadWrite> ERROR : error from msg_sendrecv(READ_PAGE):4" ); - TS_FAIL( "PnorRpTest::test_messageReadWrite> ERROR : error from msg_sendrecv(READ_PAGE):4, rc=%d", rc ); + TRACFCOMP(g_trac_pnor, "PnorRpTest::test_messageReadWrite> ERROR : error from msg_sendrecv(READ):4" ); + TS_FAIL( "PnorRpTest::test_messageReadWrite> ERROR : error from msg_sendrecv(READ):4, rc=%d", rc ); fails++; } -- cgit v1.2.1