📄 sysmotvpdutil.c
字号:
** 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); }/******************************************************************************** sysVpdPktRead - read a packet vital product data structure.** This routine searches the vpd in I2C looking for the specified * instance of a specific packet type. The routine takes the number* of data bytes to read in an effort to reduce I2C cycles.** RETURNS: OK, if successful or ERROR if unsuccessful.**/STATUS sysVpdPktRead ( UCHAR devAdrs, /* i2c address of the serial eeprom */ UCHAR devOffset, /* offset to vpd within the serial eeprom */ UCHAR vpdType, /* target packet type */ UINT32 vpdInstance, /* instance number of desired packet (0-based) */ VPD_PACKET *packet, /* pointer to packet to fill out */ UINT32 numBytes /* number of data bytes to read */ ) { UINT32 currentOffset; currentOffset = 0; do { /* Read the next vpd packet. Add the type and size to numBytes. */ if (I2C_BYTE_RANGE_READ (devAdrs, devOffset + sizeof(VPD_HEADER) + currentOffset, numBytes + 2, (UCHAR *)packet) != OK) return (ERROR); /* * Compare the type of this vpd packet. */ if (packet->type == vpdType) return (OK); currentOffset += packet->size + 2; } while ((currentOffset < VPD_EEPROM_SIZE) && (packet->type != VPD_PID_TERM)); return (ERROR); }/******************************************************************************** sysVpdPktInit - initialize a vital product data structure.** This routine reads the vital product data header from a serial eeprom and* validates it. If the header is valid, the remainder of the vpd data* is read from the serial eeprom and parsed into vpd packets for general* purpose use. If the board type is LoPEC, the packets are read one* packet at a time rather than the whole 256 bytes.** RETURNS: OK, if successful or ERROR if unsuccessful.** SEE ALSO: sysVpdPktParse(), sysVpdPktGet() */STATUS sysVpdPktInit ( UCHAR devAdrs, /* i2c address of the serial eeprom */ UCHAR devOffset, /* offset to vpd within the serial eeprom */ VPD * pVpd, /* address of vpd structure */ VPD_PACKET ** pVpdPtr, /* address of packet ptr array */ UINT32 PktLimit, /* number of entries in the packet ptr array */ UINT32 parseFlag /* flag indicating to read all bytes or not */ ) { UINT32 currentOffset; UCHAR * currentPacketOffset; UCHAR size; /* mark vpd packet pointer contents invalid. */ *pVpdPtr = NULL; /* read just the header from serial eeprom. */ if (I2C_BYTE_RANGE_READ (devAdrs, devOffset, sizeof(VPD_HEADER), (UCHAR *)pVpd) != OK) return (ERROR); /* check for a valid header */ if (sysVpdHdrVld (pVpd) != OK) return (ERROR); if (!parseFlag) return (OK); /* read the rest of the vpd from the serial eeprom. */ currentOffset = 0; currentPacketOffset = (UCHAR *)&pVpd->packets[0]; do { /* Read next packet type. */ if (I2C_BYTE_READ (devAdrs, devOffset + sizeof(VPD_HEADER) + currentOffset++, currentPacketOffset) != OK) return (ERROR); if ((*currentPacketOffset == VPD_PID_TERM) || (*currentPacketOffset == VPD_PID_GI)) break; currentPacketOffset++; /* Read the packet size. */ if (I2C_BYTE_READ (devAdrs, devOffset + sizeof(VPD_HEADER) + currentOffset++, &size) != OK) return (ERROR); *currentPacketOffset++ = size; /* Read the next vpd packet. Add the type and size to numBytes. */ if (I2C_BYTE_RANGE_READ (devAdrs, devOffset + sizeof(VPD_HEADER) + currentOffset, size, currentPacketOffset) != OK) return (ERROR); currentOffset += size; /* Add size to pointer */ currentPacketOffset += size; } while (currentOffset < VPD_EEPROM_SIZE); /* parse the raw vpd data into vpd packets. */ return (sysVpdPktParse (pVpd, pVpdPtr, PktLimit) ); }/******************************************************************************** sysCalcBusSpd - routine to calculate the speed of the 60x processor bus** This routine calculates the 60x processor bus frequency using the UART's* crystal and baud rate generator as a reference. The UART is configured* for 9600 baud, which produces a (9600 x 16) Hz frequency reference on the* UART's BAUDOUT pin, this signal is visible as bit 1 in the board status* register. The processor's bus frequency can be determined by noting the* number of elapsed "ticks" required for a given number of BAUDOUT edges and* applying for formula below. The constants are: 2 = number edge per period.* 16 = the baud rate to BAUDOUT multiplier. 4 = The processor's time base* registers are driven by a clock which is 1/4 the bus frequency.**.CS* edges counted elapsed ticks* T = ---------------------- = --------------------* 2 * baud rate * 16 bus frequency / 4**** 2 * baud rate * 16 bus frequency / 4* F = ---------------------- = ----------------------* edges counted elapsed ticks*** 2 * baud rate * 16 * ticks * 4* F = ---------------------------------- = bus Frequency* edges counted*.CE** To keep everything in 32 bits, the number of ticks must be below 3495. At* 100 MHz, 3495 time base ticks is only 140 uSecs or 43 BAUDOUT edges. At* these numbers, each time base tick is worth 29.25 KHz. By setting the number* of edges equal to the baud rate, (baud rate / edges counted) = 1 the * equation reduces to:**.CS* F = 2 * 16 * ticks * 4 = Bus Frequency.*.CE** Using this equation, the sampling interval is increased to about 31 mSecs,* each time base tick is only worth 128 Hz and there is no danger of overflowing* 32 bits.** RETURNS: The bus speed (in Hz).** NOTE: This routine must be called before interrupts are enabled and before* the serial port baud rate has been configured. Since it is usually called* very early in the start up sequence, this should not be a problem.*/#define BAUD_RATE 9600#define BAUD_RATE_CODE 12#define EDGES_PER_PERIOD 2 /* one rising, one falling = 2 */#define BAUD_CLOCK_RATIO 16 /* UART's BAUDOUT is 16x baud rate */#define TIME_BASE_RATIO 4 /* time base clock is 1/4 bus frequency */#define MULTIPLIER (EDGES_PER_PERIOD * BAUD_CLOCK_RATIO * TIME_BASE_RATIO)#ifndef EIEIO_SYNC# define EIEIO_SYNC __asm__ volatile ("eieio;sync")#endif /* EIEIO_SYNC */UINT32 sysCalcBusSpd (void) { UCHAR * pUart = (UCHAR *) COM1_BASE_ADR; UINT32 edgeTime; /* configure the uart for 9600 baud */ pUart[UART_LCR * UART_REG_ADDR_INTERVAL] |= I8250_LCR_DLAB; pUart[UART_BRDL * UART_REG_ADDR_INTERVAL] = BAUD_RATE_CODE; pUart[UART_BRDH * UART_REG_ADDR_INTERVAL] = 0; pUart[UART_LCR * UART_REG_ADDR_INTERVAL] &= ~I8250_LCR_DLAB; EIEIO_SYNC; edgeTime = sysTimeEdges (BAUD_RATE) * MULTIPLIER; if (edgeTime == 0) flashFailLed (TRUE, FAIL_LED_BAUDOUT, 4); return (edgeTime); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -