Пример #1
0
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;
	}
}
Пример #2
0
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;
}
Пример #3
0
 virtual int_type underflow()
 {
    if (_ispb)
    {
       return _pb;
    }
    else
    {
       int_type c = readFromDevice();
       if (c != char_traits::eof())
       {
          _ispb = true;
          _pb   = c;
       }
       return c;
    }
 }
Пример #4
0
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;
}
Пример #5
0
/**
 * @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" );
}
Пример #6
0
/**
 * @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();
}
Пример #8
0
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;
}
Пример #9
0
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;
}
Пример #10
0
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;
}