void process(void* data) { sensor_msgs::Imu *msg = (sensor_msgs::Imu*) data; char buffer[64]; //write header msg->header.seq = count++; struct timespec clock; clock_gettime(CLOCK_REALTIME,&clock); msg->header.stamp.sec = clock.tv_sec; msg->header.stamp.nsec = clock.tv_nsec; msg->header.frame_id = "/imu"; //get orientation if (readFromDevice(":0\n",buffer)) { char *byte = buffer; double x = strtod(byte,&byte); byte++; double y = strtod(byte,&byte); byte++; double z = strtod(byte,&byte); byte++; double w = strtod(byte,&byte); msg->orientation.x = x; msg->orientation.y = y; msg->orientation.z = z; msg->orientation.w = w; } //get gyro data if (readFromDevice(":38\n",buffer)) { char *byte = buffer; double x = strtod(byte,&byte); byte++; double y = strtod(byte,&byte); byte++; double z = strtod(byte,&byte); msg->angular_velocity.x = x; msg->angular_velocity.y = y; msg->angular_velocity.z = z; } //get accelerometer data if (readFromDevice(":39\n",buffer)) { char *byte = buffer; double x = strtod(byte,&byte) * GRAVITY; byte++; double y = strtod(byte,&byte) * GRAVITY; byte++; double z = strtod(byte,&byte) * GRAVITY; msg->linear_acceleration.x = x; msg->linear_acceleration.y = y; msg->linear_acceleration.z = z; } }
errlHndl_t RtPnor::readTOC () { TRACFCOMP(g_trac_pnor, ENTER_MRK"RtPnor::readTOC" ); errlHndl_t l_err = NULL; uint8_t* l_toc0Buffer = new uint8_t[PNOR::TOC_SIZE]; do { if (g_hostInterfaces && g_hostInterfaces->pnor_read) { //find proc id uint64_t l_procId; TARGETING::Target* l_masterProc = NULL; TARGETING::targetService().masterProcChipTargetHandle(l_masterProc); l_err = RT_TARG::getRtTarget (l_masterProc, l_procId); if (l_err) { TRACFCOMP(g_trac_pnor, "RtPnor::readTOC: getRtTarget failed"); break; } // offset = 0 means read the entire PNOR::TOC partition // This offset is offset into the partition, not offset from the // beginning of the flash l_err = readFromDevice (l_procId, PNOR::TOC, 0, PNOR::TOC_SIZE, false, l_toc0Buffer); if (l_err) { TRACFCOMP(g_trac_pnor,"RtPnor::readTOC:readFromDevice failed" " for TOC0"); break; } // When we ask for TOC partition, Opal returns a valid TOC. // So, we don't need to verify the second TOC in parseTOC // Therefore, sending invalid value for second toc PNOR::TOCS l_tocUsed; l_err = PNOR::parseTOC(l_toc0Buffer, 0, l_tocUsed, iv_TOC, 0); if (l_err) { TRACFCOMP(g_trac_pnor, "RtPnor::readTOC: parseTOC failed"); break; } } } while (0); if(l_toc0Buffer != NULL) { delete[] l_toc0Buffer; } TRACFCOMP(g_trac_pnor, EXIT_MRK"RtPnor::readTOC" ); return l_err; }
virtual int_type underflow() { if (_ispb) { return _pb; } else { int_type c = readFromDevice(); if (c != char_traits::eof()) { _ispb = true; _pb = c; } return c; } }
errlHndl_t RtPnor::readTOC () { TRACFCOMP(g_trac_pnor, ENTER_MRK"RtPnor::readTOC" ); errlHndl_t l_err = nullptr; uint8_t* l_toc0Buffer = new uint8_t[PNOR::TOC_SIZE]; do { if (g_hostInterfaces && g_hostInterfaces->pnor_read) { // offset = 0 means read the entire PNOR::TOC partition // This offset is offset into the partition, not offset from the // beginning of the flash l_err = readFromDevice (iv_masterProcId, PNOR::TOC, 0, PNOR::TOC_SIZE, false, l_toc0Buffer); if (l_err) { TRACFCOMP(g_trac_pnor,"RtPnor::readTOC:readFromDevice failed" " for TOC0"); break; } //Pass along TOC buffer to be parsed, parseTOC will parse through // the buffer and store needed information in iv_TOC // Note: that Opal should always return a valid TOC l_err = PNOR::parseTOC(l_toc0Buffer, iv_TOC, iv_initialized); if (l_err) { TRACFCOMP(g_trac_pnor, "RtPnor::readTOC: parseTOC failed"); break; } } } while (0); if(l_toc0Buffer != nullptr) { delete[] l_toc0Buffer; } TRACFCOMP(g_trac_pnor, EXIT_MRK"RtPnor::readTOC" ); return l_err; }
/** * @brief Message receiver */ void PnorRP::waitForMessage() { TRACFCOMP(g_trac_pnor, "PnorRP::waitForMessage>" ); 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; uint64_t fatal_error = 0; while(1) { status_rc = 0; TRACUCOMP(g_trac_pnor, "PnorRP::waitForMessage> waiting for message" ); message = msg_wait( iv_msgQ ); if( message ) { /* 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]; //figure out the real pnor offset l_errhdl = computeDeviceAddr( eff_addr, dev_offset, chip_select, needs_ecc ); if( l_errhdl ) { status_rc = -EFAULT; /* Bad address */ } else { switch(message->type) { case( MSG_MM_RP_READ ): l_errhdl = readFromDevice( dev_offset, chip_select, needs_ecc, user_addr, fatal_error ); if( l_errhdl || ( 0 != fatal_error ) ) { 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_TYPE * @userdata1 Message type * @userdata2 Requested Virtual Address * @devdesc PnorRP::waitForMessage> Unrecognized * message type * @custdesc A problem occurred while accessing * the boot flash. */ l_errhdl = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE, PNOR::MOD_PNORRP_WAITFORMESSAGE, PNOR::RC_INVALID_MESSAGE_TYPE, TO_UINT64(message->type), (uint64_t)eff_addr, true /*Add HB SW Callout*/); l_errhdl->collectTrace(PNOR_COMP_NAME); status_rc = -EINVAL; /* Invalid argument */ } } 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_ASYNC_MESSAGE * @userdata1 Message type * @userdata2 Requested Virtual Address * @devdesc PnorRP::waitForMessage> Unrecognized message * type * @custdesc A problem occurred while accessing the boot * flash. */ l_errhdl = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE, PNOR::MOD_PNORRP_WAITFORMESSAGE, PNOR::RC_INVALID_ASYNC_MESSAGE, TO_UINT64(message->type), (uint64_t)eff_addr, true /*Add HB SW Callout*/); l_errhdl->collectTrace(PNOR_COMP_NAME); status_rc = -EINVAL; /* Invalid argument */ } if( l_errhdl ) { errlCommit(l_errhdl,PNOR_COMP_ID); } /* Expected Response: * data[0] = virtual address requested * data[1] = rc (0 or negative errno value) * extra_data = Specific reason code. */ message->data[1] = status_rc; message->extra_data = reinterpret_cast<void*>(fatal_error); rc = msg_respond( iv_msgQ, message ); if( rc ) { TRACFCOMP(g_trac_pnor, "PnorRP::waitForMessage> Error from msg_respond, giving up : rc=%d", rc ); break; } } } TRACFCOMP(g_trac_pnor, "< PnorRP::waitForMessage" ); }
/** * @brief Read the TOC and store section information */ errlHndl_t PnorRP::readTOC() { TRACUCOMP(g_trac_pnor, "PnorRP::readTOC>" ); errlHndl_t l_errhdl = NULL; uint8_t* tocBuffer = NULL; uint64_t fatal_error = 0; bool TOC_0_failed = false; do{ iv_TOC_used = 0; for (uint32_t cur_TOC = 0; cur_TOC < NUM_TOCS; ++cur_TOC) { TRACFCOMP(g_trac_pnor, "PnorRP::readTOC verifying TOC: %d",cur_TOC); uint64_t nextVAddr = BASE_VADDR; // Zero out my table for( size_t id = PNOR::FIRST_SECTION; id <= PNOR::NUM_SECTIONS; //include extra entry for error paths ++id ) { iv_TOC[id].id = (PNOR::SectionId)id; //everything else should default to zero } // Read TOC information from TOC 0 and then TOC 1 tocBuffer = new uint8_t[PAGESIZE]; if (cur_TOC == 0) { l_errhdl = readFromDevice( TOC_0_OFFSET, 0, false, tocBuffer, fatal_error ); } else if (cur_TOC == 1) { l_errhdl = readFromDevice( TOC_1_OFFSET, 0, false, tocBuffer, fatal_error ); } if( l_errhdl ) { TRACFCOMP(g_trac_pnor, "PnorRP::readTOC readFromDevice Failed."); break; } ffs_hdr* l_ffs_hdr = (ffs_hdr*) tocBuffer; // ffs entry check, 0 if checksums match if( PNOR::pnor_ffs_checksum(l_ffs_hdr, FFS_HDR_SIZE) != 0) { //@TODO - RTC:90780 - May need to handle this differently in SP-less config TRACFCOMP(g_trac_pnor, "PnorRP::readTOC pnor_ffs_checksum header checksums do not match."); if (cur_TOC == 0) { TRACFCOMP(g_trac_pnor, "PnorRP::readTOC TOC 0 failed header checksum"); TOC_0_failed = true; iv_TOC_used = 1; continue; } else if (cur_TOC == 1 && TOC_0_failed) { // Both TOC's failed TRACFCOMP(g_trac_pnor, "PnorRP::readTOC both TOC's are corrupted"); INITSERVICE::doShutdown( PNOR::RC_PARTITION_TABLE_INVALID); } else { // TOC 1 failed TRACFCOMP(g_trac_pnor, "PnorRP::readTOC TOC 1 failed header checksum"); break; } } // Only check header if on first TOC or the first TOC failed if (cur_TOC == 0 || TOC_0_failed) { TRACFCOMP(g_trac_pnor, "PnorRP::readTOC: FFS Block size = 0x%.8X, Partition Table Size = 0x%.8x, entry_count=%d", l_ffs_hdr->block_size, l_ffs_hdr->size, l_ffs_hdr->entry_count); uint64_t spaceUsed = (sizeof(ffs_entry))*l_ffs_hdr->entry_count; /* Checking FFS Header to make sure it looks valid */ bool header_good = true; if(l_ffs_hdr->magic != FFS_MAGIC) { TRACFCOMP(g_trac_pnor, "E>PnorRP::readTOC: Invalid magic number in FFS header: 0x%.4X", l_ffs_hdr->magic); header_good = false; } else if(l_ffs_hdr->version != SUPPORTED_FFS_VERSION) { TRACFCOMP(g_trac_pnor, "E>PnorRP::readTOC: Unsupported FFS Header version: 0x%.4X", l_ffs_hdr->version); header_good = false; } else if(l_ffs_hdr->entry_size != sizeof(ffs_entry)) { TRACFCOMP(g_trac_pnor, "E>PnorRP::readTOC: Unexpected entry_size(0x%.8x) in FFS header: 0x%.4X", l_ffs_hdr->entry_size); header_good = false; } else if(l_ffs_hdr->entries == NULL) { TRACFCOMP(g_trac_pnor, "E>PnorRP::readTOC: FFS Header pointer to entries is NULL."); header_good = false; } else if(l_ffs_hdr->block_size != PAGESIZE) { TRACFCOMP(g_trac_pnor, "E>PnorRP::readTOC: Unsupported Block Size(0x%.4X). PNOR Blocks must be 4k", l_ffs_hdr->block_size); header_good = false; } else if(l_ffs_hdr->block_count == 0) { TRACFCOMP(g_trac_pnor, "E>PnorRP::readTOC: Unsupported BLock COunt(0x%.4X). Device cannot be zero blocks in length.", l_ffs_hdr->block_count); header_good = false; } //Make sure all the entries fit in specified partition table size. else if(spaceUsed > ((l_ffs_hdr->block_size * l_ffs_hdr->size) - sizeof(ffs_hdr))) { TRACFCOMP(g_trac_pnor, "E>PnorRP::readTOC: FFS Entries (0x%.16X) go past end of FFS Table.", spaceUsed); header_good = false; } if(!header_good) { //Shutdown if we detected a partition table issue for any reason if (TOC_0_failed) { INITSERVICE::doShutdown( PNOR::RC_PARTITION_TABLE_INVALID); } else { TOC_0_failed = true; } //Try TOC1 continue; } } ffs_hb_user_t* ffsUserData = NULL; //Walk through all the entries in the table and parse the data. for(uint32_t i=0; i<l_ffs_hdr->entry_count; i++) { ffs_entry* cur_entry = (&l_ffs_hdr->entries[i]); TRACUCOMP(g_trac_pnor, "PnorRP::readTOC: Entry %d, name=%s, pointer=0x%X", i, cur_entry->name, (uint64_t)cur_entry); uint32_t secId = PNOR::INVALID_SECTION; // ffs entry check, 0 if checksums match if( PNOR::pnor_ffs_checksum(cur_entry, FFS_ENTRY_SIZE) != 0) { //@TODO - RTC:90780 - May need to handle this differently in SP-less config TRACFCOMP(g_trac_pnor, "PnorRP::readTOC pnor_ffs_checksum entry checksums do not match."); if (cur_TOC == 0) { TRACFCOMP(g_trac_pnor, "PnorRP::readTOC TOC 0 entry checksum failed"); TOC_0_failed = true; iv_TOC_used = 1; break; } else if (cur_TOC == 1 && TOC_0_failed) { // Both TOC's failed TRACFCOMP(g_trac_pnor, "PnorRP::readTOC both TOC's are corrupted"); INITSERVICE::doShutdown( PNOR::RC_PARTITION_TABLE_INVALID); } else { // TOC 1 failed TRACFCOMP(g_trac_pnor, "PnorRP::readTOC TOC 1 entry checksum failed"); break; } } // Only set data if on first TOC or the first TOC failed if (cur_TOC == 0 || TOC_0_failed) { //Figure out section enum for(uint32_t eyeIndex=PNOR::TOC; eyeIndex < PNOR::NUM_SECTIONS; eyeIndex++) { if(strcmp(cv_EYECATCHER[eyeIndex], cur_entry->name) == 0) { secId = eyeIndex; TRACUCOMP(g_trac_pnor, "PnorRP::readTOC: sectionId=%d", secId); break; } } if(secId == PNOR::INVALID_SECTION) { TRACFCOMP(g_trac_pnor, "PnorRP::readTOC: Unrecognized Section name(%s), skipping", cur_entry->name); continue; } ffsUserData = (ffs_hb_user_t*)&(cur_entry->user); //size iv_TOC[secId].size = ((uint64_t)cur_entry->size)*PAGESIZE; //virtAddr iv_TOC[secId].virtAddr = nextVAddr; nextVAddr += iv_TOC[secId].size; //flashAddr iv_TOC[secId].flashAddr = ((uint64_t)cur_entry->base)*PAGESIZE; //chipSelect iv_TOC[secId].chip = ffsUserData->chip; //user data iv_TOC[secId].integrity = ffsUserData->dataInteg; iv_TOC[secId].version = ffsUserData->verCheck; iv_TOC[secId].misc = ffsUserData->miscFlags; TRACFCOMP(g_trac_pnor, "PnorRp::readTOC: User Data %s", cur_entry->name); if (iv_TOC[secId].integrity == FFS_INTEG_ECC_PROTECT) { TRACFCOMP(g_trac_pnor, "PnorRP::readTOC: ECC enabled for %s", cur_entry->name); iv_TOC[secId].size = ALIGN_PAGE_DOWN((iv_TOC[secId].size * 8 ) / 9); } // TODO RTC:96009 handle version header w/secureboot if (iv_TOC[secId].version == FFS_VERS_SHA512) { TRACFCOMP(g_trac_pnor, "PnorRP::readTOC: Incrementing Flash Address for SHA Header"); if (iv_TOC[secId].integrity == FFS_INTEG_ECC_PROTECT) { iv_TOC[secId].flashAddr += PAGESIZE_PLUS_ECC; } else { iv_TOC[secId].flashAddr += PAGESIZE; } } if((iv_TOC[secId].flashAddr + iv_TOC[secId].size) > (l_ffs_hdr->block_count*PAGESIZE)) { TRACFCOMP(g_trac_pnor, "E>PnorRP::readTOC: Partition(%s) at base address (0x%.8x) extends past end of flash device", cur_entry->name, iv_TOC[secId].flashAddr); INITSERVICE::doShutdown( PNOR::RC_PARTITION_TABLE_INVALID); } } } //keep these traces here until PNOR is rock-solid for(PNOR::SectionId tmpId = PNOR::FIRST_SECTION; tmpId < PNOR::NUM_SECTIONS; tmpId = (PNOR::SectionId) (tmpId + 1) ) { TRACFCOMP(g_trac_pnor, "%s: size=0x%.8X flash=0x%.8X virt=0x%.16X", cv_EYECATCHER[tmpId], iv_TOC[tmpId].size, iv_TOC[tmpId].flashAddr, iv_TOC[tmpId].virtAddr ); } } }while(0); if(tocBuffer != NULL) { TRACUCOMP(g_trac_pnor, "Deleting tocBuffer"); delete[] tocBuffer; } TRACUCOMP(g_trac_pnor, "< PnorRP::readTOC" ); return l_errhdl; }
void accelerometerWindow::Update() { //readFromExtDevice(); readFromDevice(); }
errlHndl_t RtPnor::getSectionInfo(PNOR::SectionId i_section, PNOR::SectionInfo_t& o_info) { TRACFCOMP(g_trac_pnor, ENTER_MRK"RtPnor::getSectionInfo %d, initialized = %d", i_section, iv_initialized?1:0); errlHndl_t l_err = nullptr; do { // Check if Section is invalid or inhibited from loading at runtime. bool l_inhibited = false; bool l_secure = PNOR::isEnforcedSecureSection(i_section); bool l_preVerified = RUNTIME::isPreVerifiedSection(i_section); #ifdef CONFIG_SECUREBOOT l_inhibited = PNOR::isInhibitedSection(i_section); #endif if (i_section == PNOR::INVALID_SECTION || l_inhibited || l_secure || l_preVerified) { TRACFCOMP(g_trac_pnor, "RtPnor::getSectionInfo: Invalid Section %d", static_cast<int>(i_section)); if (l_preVerified) { TRACFCOMP(g_trac_pnor, ERR_MRK"RtPnor::getSectionInfo: pre-verified sections should be loaded via Hostboot Reserved Memory "); } #ifdef CONFIG_SECUREBOOT else if (l_inhibited) { TRACFCOMP(g_trac_pnor, ERR_MRK"RtPnor::getSectionInfo: attribute overrides inhibited by secureboot"); } else if (l_secure) { TRACFCOMP(g_trac_pnor, ERR_MRK"RtPnor::getSectionInfo: secure sections should be loaded via Hostboot Reserved Memory"); } #endif /*@ * @errortype * @moduleid PNOR::MOD_RTPNOR_GETSECTIONINFO * @reasoncode PNOR::RC_RTPNOR_INVALID_SECTION * @userdata1 PNOR::SectionId * @userdata2[0:15] Inhibited by secureboot * @userdata2[16:31] Indication of a secure section * @userdata2[32:47] Indication of a pre-verified section * @userdata2[48:63] 0 * @devdesc invalid section passed to getSectionInfo or * section prohibited by secureboot */ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, PNOR::MOD_RTPNOR_GETSECTIONINFO, PNOR::RC_RTPNOR_INVALID_SECTION, i_section, FOUR_UINT16_TO_UINT64(l_inhibited, l_secure, l_preVerified, 0), true); break; } //size of the section uint64_t l_sizeBytes = iv_TOC[i_section].size; if (l_sizeBytes == 0) { TRACFCOMP(g_trac_pnor,"RtPnor::getSectionInfo: Section %d" " size is 0", static_cast<int>(i_section)); // prevent hang between ErrlManager and rt_pnor assert(iv_initialized, "RtPnor::getSectionInfo: Section size 0 returned" " before completing PNOR initialization"); /*@ * @errortype * @moduleid PNOR::MOD_RTPNOR_GETSECTIONINFO * @reasoncode PNOR::RC_SECTION_SIZE_IS_ZERO * @userdata1 PNOR::SectionId * @devdesc section size is zero */ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, PNOR::MOD_RTPNOR_GETSECTIONINFO, PNOR::RC_SECTION_SIZE_IS_ZERO, i_section, 0,true); break; } //ecc bool l_ecc = (iv_TOC[i_section].integrity&FFS_INTEG_ECC_PROTECT) ? true : false; void* l_pWorking = nullptr; void* l_pClean = nullptr; //find the section in the map first if(iv_pnorMap.find(i_section) != iv_pnorMap.end()) { //get the addresses from the map PnorAddrPair_t l_addrPair = iv_pnorMap[i_section]; l_pWorking = l_addrPair.first; l_pClean = l_addrPair.second; } else { //malloc twice -- one working copy and one clean copy //So, we can diff and write only the dirty bytes l_pWorking = malloc(l_sizeBytes); l_pClean = malloc(l_sizeBytes); //offset = 0 : read the entire section l_err = readFromDevice(iv_masterProcId, i_section, 0, l_sizeBytes, l_ecc, l_pWorking); if(l_err) { TRACFCOMP(g_trac_pnor, "RtPnor::getSectionInfo:readFromDevice" " failed"); break; } //copy data to another pointer to save a clean copy of data memcpy(l_pClean, l_pWorking, l_sizeBytes); //save it in the map iv_pnorMap [i_section] = PnorAddrPair_t(l_pWorking, l_pClean); } //return the data in the struct o_info.id = i_section; o_info.name = SectionIdToString(i_section); o_info.vaddr = reinterpret_cast<uint64_t>(l_pWorking); o_info.flashAddr = iv_TOC[i_section].flashAddr; o_info.size = l_sizeBytes; o_info.eccProtected = l_ecc; o_info.sha512Version= (iv_TOC[i_section].version & FFS_VERS_SHA512) ? true : false; o_info.sha512perEC = (iv_TOC[i_section].version & FFS_VERS_SHA512_PER_EC) ? true : false; o_info.secure = iv_TOC[i_section].secure; } while (0); TRACFCOMP(g_trac_pnor, EXIT_MRK"RtPnor::getSectionInfo %d", i_section); return l_err; }
errlHndl_t RtPnor::getSectionInfo(PNOR::SectionId i_section, PNOR::SectionInfo_t& o_info) { TRACFCOMP(g_trac_pnor, ENTER_MRK"RtPnor::getSectionInfo"); errlHndl_t l_err = NULL; do { if (i_section == PNOR::INVALID_SECTION) { TRACFCOMP(g_trac_pnor, "RtPnor::getSectionInfo: Invalid Section" " %d", (int)i_section); /*@ * @errortype * @moduleid PNOR::MOD_RTPNOR_GETSECTIONINFO * @reasoncode PNOR::RC_RTPNOR_INVALID_SECTION * @userdata1 PNOR::SectionId * @devdesc invalid section passed to getSectionInfo */ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, PNOR::MOD_RTPNOR_GETSECTIONINFO, PNOR::RC_RTPNOR_INVALID_SECTION, i_section, 0,true); break; } //size of the section uint64_t l_sizeBytes = iv_TOC[i_section].size; if (l_sizeBytes == 0) { TRACFCOMP(g_trac_pnor,"RtPnor::getSectionInfo: Section %d" " size is 0", (int)i_section); /*@ * @errortype * @moduleid PNOR::MOD_RTPNOR_GETSECTIONINFO * @reasoncode PNOR::RC_SECTION_SIZE_IS_ZERO * @userdata1 PNOR::SectionId * @devdesc section size is zero */ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, PNOR::MOD_RTPNOR_GETSECTIONINFO, PNOR::RC_SECTION_SIZE_IS_ZERO, i_section, 0,true); break; } //find proc id uint64_t l_procId; TARGETING::Target* l_masterProc = NULL; TARGETING::targetService().masterProcChipTargetHandle( l_masterProc ); l_err = RT_TARG::getRtTarget (l_masterProc, l_procId); if (l_err) { TRACFCOMP(g_trac_pnor, "RtPnor::getSectionInfo: getRtTarget failed"); break; } //ecc bool l_ecc = (iv_TOC[i_section].integrity&FFS_INTEG_ECC_PROTECT) ? true : false; void* l_pWorking = NULL; void* l_pClean = NULL; //find the section in the map first if(iv_pnorMap.find(i_section) != iv_pnorMap.end()) { //get the addresses from the map PnorAddrPair_t l_addrPair = iv_pnorMap[i_section]; l_pWorking = l_addrPair.first; l_pClean = l_addrPair.second; } else { //malloc twice -- one working copy and one clean copy //So, we can diff and write only the dirty bytes l_pWorking = malloc(l_sizeBytes); l_pClean = malloc(l_sizeBytes); //offset = 0 : read the entire section l_err = readFromDevice(l_procId, i_section, 0, l_sizeBytes, l_ecc, l_pWorking); if(l_err) { TRACFCOMP(g_trac_pnor, "RtPnor::getSectionInfo:readFromDevice" " failed"); break; } //copy data to another pointer to save a clean copy of data memcpy(l_pClean, l_pWorking, l_sizeBytes); //save it in the map iv_pnorMap [i_section] = PnorAddrPair_t(l_pWorking, l_pClean); } //return the data in the struct o_info.id = i_section; o_info.name = cv_EYECATCHER[i_section]; o_info.vaddr = (uint64_t)l_pWorking; o_info.flashAddr = iv_TOC[i_section].flashAddr; o_info.size = l_sizeBytes; o_info.eccProtected = l_ecc; o_info.sha512Version= (iv_TOC[i_section].version & FFS_VERS_SHA512) ? true : false; o_info.sha512perEC = (iv_TOC[i_section].version & FFS_VERS_SHA512_PER_EC) ? true : false; } while (0); TRACFCOMP(g_trac_pnor, EXIT_MRK"RtPnor::getSectionInfo"); return l_err; }
errlHndl_t RtPnor::getSectionInfo(PNOR::SectionId i_section, PNOR::SectionInfo_t& o_info) { TRACFCOMP(g_trac_pnor, ENTER_MRK"RtPnor::getSectionInfo"); errlHndl_t l_err = nullptr; do { // TODO: RTC:180063 change this to error out on secure sections as it // did previously in HB commit cefc4c // Check if Section is invalid or inhibited from loading at runtime. bool l_inhibited = false; #ifdef CONFIG_SECUREBOOT l_inhibited = PNOR::isInhibitedSection(i_section); #endif if (i_section == PNOR::INVALID_SECTION || l_inhibited) { TRACFCOMP(g_trac_pnor, "RtPnor::getSectionInfo: Invalid Section %d", static_cast<int>(i_section)); #ifdef CONFIG_SECUREBOOT if (l_inhibited) { TRACFCOMP(g_trac_pnor, ERR_MRK"RtPnor::getSectionInfo: attribute overrides inhibited by secureboot"); } #endif /*@ * @errortype * @moduleid PNOR::MOD_RTPNOR_GETSECTIONINFO * @reasoncode PNOR::RC_RTPNOR_INVALID_SECTION * @userdata1 PNOR::SectionId * @userdata2[0:63] Inhibited by secureboot * @devdesc invalid section passed to getSectionInfo or * section prohibited by secureboot */ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, PNOR::MOD_RTPNOR_GETSECTIONINFO, PNOR::RC_RTPNOR_INVALID_SECTION, i_section, l_inhibited, true); break; } //size of the section uint64_t l_sizeBytes = iv_TOC[i_section].size; if (l_sizeBytes == 0) { TRACFCOMP(g_trac_pnor,"RtPnor::getSectionInfo: Section %d" " size is 0", static_cast<int>(i_section)); /*@ * @errortype * @moduleid PNOR::MOD_RTPNOR_GETSECTIONINFO * @reasoncode PNOR::RC_SECTION_SIZE_IS_ZERO * @userdata1 PNOR::SectionId * @devdesc section size is zero */ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, PNOR::MOD_RTPNOR_GETSECTIONINFO, PNOR::RC_SECTION_SIZE_IS_ZERO, i_section, 0,true); break; } //ecc bool l_ecc = (iv_TOC[i_section].integrity&FFS_INTEG_ECC_PROTECT) ? true : false; // TODO: RTC:180063 change this to error out on secure sections as it // did previously in HB commit cefc4c // Only do mapping and read from device to set vaddr if not a secure // section. Secure sections should load from HB resv memory and will set // vaddr to 0 if (iv_TOC[i_section].secure) { TRACFCOMP(g_trac_pnor,"RtPnor::getSectionInfo: Warning> Section is secure, so must be loaded from Hb resv memory. vaddr will be set to 0"); o_info.vaddr = 0; } else { void* l_pWorking = nullptr; void* l_pClean = nullptr; //find the section in the map first if(iv_pnorMap.find(i_section) != iv_pnorMap.end()) { //get the addresses from the map PnorAddrPair_t l_addrPair = iv_pnorMap[i_section]; l_pWorking = l_addrPair.first; l_pClean = l_addrPair.second; } else { //malloc twice -- one working copy and one clean copy //So, we can diff and write only the dirty bytes l_pWorking = malloc(l_sizeBytes); l_pClean = malloc(l_sizeBytes); //offset = 0 : read the entire section l_err = readFromDevice(iv_masterProcId, i_section, 0, l_sizeBytes, l_ecc, l_pWorking); if(l_err) { TRACFCOMP(g_trac_pnor, "RtPnor::getSectionInfo:readFromDevice" " failed"); break; } //copy data to another pointer to save a clean copy of data memcpy(l_pClean, l_pWorking, l_sizeBytes); //save it in the map iv_pnorMap [i_section] = PnorAddrPair_t(l_pWorking, l_pClean); } o_info.vaddr = reinterpret_cast<uint64_t>(l_pWorking); } //return the data in the struct o_info.id = i_section; o_info.name = SectionIdToString(i_section); o_info.flashAddr = iv_TOC[i_section].flashAddr; o_info.size = l_sizeBytes; o_info.eccProtected = l_ecc; o_info.sha512Version= (iv_TOC[i_section].version & FFS_VERS_SHA512) ? true : false; o_info.sha512perEC = (iv_TOC[i_section].version & FFS_VERS_SHA512_PER_EC) ? true : false; o_info.secure = iv_TOC[i_section].secure; } while (0); TRACFCOMP(g_trac_pnor, EXIT_MRK"RtPnor::getSectionInfo"); return l_err; }