?? sysmotvpdutil.c
字號:
/* sysMotVpdUtil.c - Vital Product Data Routines. *//* Copyright 1984-2000 Wind River Systems, Inc. *//* Copyright 1998-2000 Motorola, Inc., All Rights Reserved *//*modification history--------------------01c,18oct01,mil Fixed sysVpdPktParse() for vpdShow() error (SPR 35714) and cleaned up compiler warnings.01b,05dec00,rhk WRS code standards cleanup.01a,10aug99,rhk ported to the cpv3060 BSP (from mv2100 BSP).*//*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 "sysMotVpdCpv3060.h"/* defines */#define ENET_INSTANCE_SIZE 7 /* size of an extended ethernet packet *//******************************************************************************** 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]; 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.** SEE ALSO: sysVpdPktParse()*/STATUS sysVpdPktGet ( UCHAR vpdType, /* target packet type */ UINT32 vpdInstance, /* instance number of desired packet (0-based) */ VPD_PACKET ** pVpdPtr, /* address of the array of packet pointers */ VPD_PACKET ** pVpdPacket /* address of the return variable */ ) { UCHAR type; /* current packet type */ VPD_PACKET * p; /* pointer to current packet */ /* if the first pointer in the array is NULL, return an error indication. */ if (*pVpdPtr == NULL) return (ERROR); do { /* get the current packet pointer */ p = *pVpdPtr; /* if the packet type matches the caller's requested type */ if ( (type = p->type) == vpdType ) { /* * see if the type is an ethernet address and has a trailing * instance value. if it does, see of the instance number matches * the caller's requested instance. */ if ( (vpdType == VPD_PID_EA) && (p->size == ENET_INSTANCE_SIZE) && (vpdInstance == p->data[ENET_INSTANCE_SIZE-1]) ) { *pVpdPacket = p; return (OK); } else { /* * see if this is the instance the caller requested, if not * decrement the instance count and go around again. */ if (vpdInstance-- == 0) { *pVpdPacket = p; return (OK); } } } /* advance to the next packet. */ pVpdPtr++; /* terminate on reaching the term packet. */ } while ( type != VPD_PID_TERM); return (ERROR); }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -