⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sysmotvpdutil.c

📁 LoPEC Early Access VxWorks BSP
💻 C
📖 第 1 页 / 共 2 页
字号:
/* sysMotVpdUtil.c - Vital Product Data Routines. *//* Copyright 1998, 1999, 2000 Motorola, Inc., All Rights Reserved *//*modification history--------------------01d,30mar01,scb  removed #ifdef DEBUG_VPD .. debugVpdProgram() .. #endif01c,04jan01,scb  sysCalcBusSpd() handles 0 baud-out when debug mode turned on.01b,08dec00,djs  changes for VPD and i2c support01a,02nov00,djs  created based on 01f,28may99,dmw mv2100*//*DESCRIPTIONThis file contains the Vital Product Data utility routines. These routines areused to read the contents of the VPD serial EEPROM and provide access to thevarious VPD data packets. These routines operate using caller-supplied buffers.This permits their use in environments where multiple VPD EEPROMS are supported(as in the Sitka).CAVEATSThis code executes very early in the startup sequence (called from romInit.s),before the image has been copied to RAM (assuming a non-ROM image). As such,this file must be added to the BOOT_EXTRA list in the Makefile to prevent itfrom being compressed during keernel generation. Additionally, extreme cautionmust be exercised when modifying these routines to prevent the use of absolutememory addresses which reference locations in the RAM-relocated image. Theselocations are invalid and references to them will cause unpredictable behavior.Absolute memory addresses are generated by the compiler when referencing tables,static data structures and global variables. All of these must be avoided. Insome places in the code, nested if-else constructs are used to avoid the jumptable created when a simple switch contruct is used. The jump table address wasloaded using an absolute address and the code broke because the execution imagehad not been copied to the RAM address produced by the compiler.*/#include "vxWorks.h"#include "config.h"#include "sysMotVpd.h"#include "drv/sio/i8250Sio.h"/* defines */#define ENET_INSTANCE_SIZE  7   /* size of an extended ethernet packet */#ifndef I2C_BYTE_READIMPORT int i2cRead(UINT32, unsigned int , unsigned int , char *);#define I2C_BYTE_READ(devAddr, startBlk, pBuf) \    i2cRead(devAddr, startBlk, 1, pBuf)#endif#ifndef I2C_BYTE_WRITEIMPORT int i2cWrite (UINT32, unsigned int, unsigned int, char *);#define I2C_BYTE_WRITE(devAddr, startBlk, bfr) \    i2cWrite(devAddr, startBlk, 1, bfr)#endif#ifndef I2C_BYTE_RANGE_READ#define I2C_BYTE_RANGE_READ(devAddr, startBlk, count, pBuf) \    i2cRead(devAddr, startBlk, count, pBuf)#endif#ifndef I2C_BYTE_RANGE_WRITE#define I2C_BYTE_RANGE_WRITE(devAddr, startBlk, count, pBuf) \    i2cWrite(devAddr, startBlk, count, pBuf)#endif#define FAIL_LED_BAUDOUT    0x1     /* Failure code for no BAUD out  */IMPORT UINT32 sysTimeEdges (UINT32);IMPORT void   flashFailLed (BOOL, UINT32, int);UINT32 sysCalcBusSpd (void);/******************************************************************************** sysI2cSromRangeRead - reads a range of bytes from an I2C serial eeprom (SROM)** This routine simply calls the I2C byte read routine for each requested byte.* The I2C byte read call is written using a macro to accommodate alternate* read routines.** RETURNS: OK, or ERROR if the I2C byte read fails.** SEE ALSO: sysI2cSromRangeWrite**/STATUS sysI2cSromRangeRead     (    UCHAR    devAdrs,    /* i2c address of the serial eeprom */    UCHAR    devOffset,  /* starting offset within the serial eeprom to read */    UINT16   byteCount,  /* number of bytes to read (one-based) */    UCHAR *  pBfr        /* destination buffer */    )    {    for ( ; byteCount != 0; ++devOffset, ++pBfr, --byteCount)        {        if (I2C_BYTE_READ(devAdrs, devOffset, pBfr) != OK)            return (ERROR);        }    return (OK);    }/******************************************************************************** sysI2cSromRangeWrite - writes a range of bytes to an I2C serial eeprom (SROM)** This routine simply calls the I2C byte write routine for each requested byte.* The I2C byte write call is written using a macro to accommodate alternate* I2C byte write routines.** RETURNS: OK, or ERROR if the I2C byte write fails.** SEE ALSO: sysI2cSromRangeRead**/STATUS sysI2cSromRangeWrite     (    UCHAR    devAdrs,    /* i2c address of the serial eeprom */    UCHAR    devOffset,  /* starting offset within the serial eeprom to write */    UINT16   byteCount,  /* number of bytes to write (one-based) */    UCHAR *  pBfr        /* source buffer */    )    {    for ( ; byteCount != 0; ++devOffset, ++pBfr, --byteCount)        {        if (I2C_BYTE_WRITE(devAdrs, devOffset, pBfr) != OK)            return (ERROR);        }    return (OK);    }/******************************************************************************** sysVpdHdrVld - validate a vital product data header** This routine validates the header of a vital product data structure. The* validation is performed by checking the contents of the "eyecatcher" and size* fields.** RETURNS: OK, or ERROR if vpd header contents are invalid.**/STATUS sysVpdHdrVld     (    VPD * pVpd   /* pointer to vpd structure */    )    {    UINT32 * pEyecatcher;    /*     * verify that the contents of the eyecatcher are correct. this must be     * done numerically because the string addresses generated by the     * compiler reference the program data area which is not valid until after     * the code has been copied to ram.     */    pEyecatcher = (UINT32 *)&pVpd->header.eyeCatcher[0];    if ((*pEyecatcher != 0x4d4f544f) ||     /* MOTO */        (*(pEyecatcher+1) != 0x524f4c41))   /* ROLA */        {            return (ERROR);        }    /*     * make sure the eeprom contents will fit into our vpd structure     * and that the eeprom size is at least large enough to hold the header and     * a termination packet.     */    if ( (pVpd->header.size > sizeof(VPD)) ||         (pVpd->header.size < (sizeof(VPD_HEADER) + 1)) )        return (ERROR);    return (OK);    }/******************************************************************************** sysVpdPktParse - parse the vital product data packets** This routine parses a raw VPD data array into an array of VPD packet pointers.* The parser walks through the data area of the vital product data structure and* saves the starting address of each packet it finds into an array of packet* pointers. When a desired packet is needed at a later time, the packet pointer* array can be scanned without having to re-parse the packets for each search.** RETURNS: OK, or ERROR and NULLs the first pointer in the array if an error*          is encountered while parsing or the size of the pointer array is*          exceeded. ** SEE ALSO: sysVpdPktGet()*/STATUS sysVpdPktParse    (    VPD *         pVpd,        /* pointer to vpd structure */    VPD_PACKET ** pVpdPtr,     /* packet ptr array */    UINT32        vpdPktLimit  /* number of pointers in the array */    )    {    VPD_PACKET ** p;           /* address of first array element */    UCHAR type;                /* type of current packet */    UINT32 limit;              /* end of valid packet data */    UINT32 index = 0;          /* current position in packet data */    UINT32 pkt = 0;            /* number of packets found */    /* verify that the header is correct */    if (sysVpdHdrVld (pVpd) != OK)        {        *pVpdPtr = NULL;        return (ERROR);        }    /* save the address of the first element in the pointer array */    p = pVpdPtr;    /* calculate the size of the data array */    limit = (UINT32)pVpd->header.size - sizeof(VPD_HEADER);    /* walk through the vpd data area parsing each packet */    do        {        /* save the packet type */        type =  pVpd->packets[index];        /*         * save the address of the current packet in the packet pointer array         * and advance the packet pointer to the next array entry.         */        *pVpdPtr++ = (VPD_PACKET *)&pVpd->packets[index++];        /* increment the packet count and advance to the next packet */        ++pkt;        index += pVpd->packets[index++];        /*         * check the packet type and bail out of the loop if: 1) the termination         * packet has been found, 2) the packet type is illegal, or 3) if we've         * reached or exceeded the end of the data array or the packet pointer         * array.         */        if ( (type == VPD_PID_TERM) ||             (type == VPD_PID_GI)   ||             (index >= limit)       ||             (pkt >= vpdPktLimit) )            break;        /* continue until termination packet is found */        } while (type != VPD_PID_TERM);     /*     * if we didn't stop due to finding a termination packet, invalidate the     * first entry in the pointer array and return an error indication.     */    if (type != VPD_PID_TERM)        {        *p = NULL;        return (ERROR);        }    else        return (OK);    }/******************************************************************************** sysVpdPktGet - search the vital product data for a specific packet** This routine searches the a caller-supplied array of vpd packet pointers* looking for the specified instance of a specific packet type. Instances are* numbered starting at 0.** NOTE: There are two types of ethernet address packets defined: The base type* has 6 data bytes and no trailing instance number. The alternate type contains* 6 bytes of ethernet address plus a trailing instance byte. Instances are* numbered starting at zero. This routine will handle both packet types. It will* also handle multiple instances of the other packet types (except only one* termination packet is allowed).** RETURNS: A pointer to the desired packet and OK if the packet was found,*          otherwise it returns ERROR.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -