mirror of
https://github.com/ipxe/ipxe
synced 2025-12-22 21:11:03 +03:00
[pci] Add support for reading and writing PCI Vital Product Data (VPD)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
@@ -67,6 +67,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
||||
#define ERRFILE_mca ( ERRFILE_DRIVER | 0x00030000 )
|
||||
#define ERRFILE_pci ( ERRFILE_DRIVER | 0x00040000 )
|
||||
#define ERRFILE_linux ( ERRFILE_DRIVER | 0x00050000 )
|
||||
#define ERRFILE_pcivpd ( ERRFILE_DRIVER | 0x00060000 )
|
||||
|
||||
#define ERRFILE_nvs ( ERRFILE_DRIVER | 0x00100000 )
|
||||
#define ERRFILE_spi ( ERRFILE_DRIVER | 0x00110000 )
|
||||
|
||||
165
src/include/ipxe/pcivpd.h
Normal file
165
src/include/ipxe/pcivpd.h
Normal file
@@ -0,0 +1,165 @@
|
||||
#ifndef _IPXE_PCIVPD_H
|
||||
#define _IPXE_PCIVPD_H
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* PCI Vital Product Data
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER );
|
||||
|
||||
#include <stdint.h>
|
||||
#include <byteswap.h>
|
||||
#include <ipxe/isapnp.h>
|
||||
#include <ipxe/pci.h>
|
||||
|
||||
/** PCI VPD address register */
|
||||
#define PCI_VPD_ADDRESS 0x02
|
||||
|
||||
/** PCI VPD write flag */
|
||||
#define PCI_VPD_FLAG 0x8000
|
||||
|
||||
/** PCI VPD data register */
|
||||
#define PCI_VPD_DATA 0x04
|
||||
|
||||
/** A PCI VPD field */
|
||||
struct pci_vpd_field {
|
||||
/** Keyword */
|
||||
uint16_t keyword;
|
||||
/** Length */
|
||||
uint8_t len;
|
||||
} __attribute__ (( packed ));
|
||||
|
||||
/** Construct PCI VPD field descriptor
|
||||
*
|
||||
* @v tag ISAPnP tag
|
||||
* @v keyword1 First character of keyword
|
||||
* @v keyword2 Second character of keyword
|
||||
* @ret field VPD field descriptor
|
||||
*/
|
||||
#define PCI_VPD_FIELD( tag, keyword1, keyword2 ) \
|
||||
( ( (tag) << 16 ) | ( (keyword2) << 8 ) | ( (keyword1) << 0 ) )
|
||||
|
||||
/** Construct PCI VPD whole-tag field descriptor
|
||||
*
|
||||
* @v tag ISAPnP tag
|
||||
* @ret field VPD field descriptor
|
||||
*/
|
||||
#define PCI_VPD_WHOLE_TAG_FIELD( tag ) PCI_VPD_FIELD ( (tag), '\0', '\0' )
|
||||
|
||||
/** Extract PCI VPD ISAPnP tag
|
||||
*
|
||||
* @v field VPD field descriptor
|
||||
* @ret tag ISAPnP tag
|
||||
*/
|
||||
#define PCI_VPD_TAG( field ) ( (field) >> 16 )
|
||||
|
||||
/** Extract PCI VPD keyword
|
||||
*
|
||||
* @v field VPD field descriptor
|
||||
* @ret keyword Keyword
|
||||
*/
|
||||
#define PCI_VPD_KEYWORD( field ) ( cpu_to_le16 ( (field) & 0xffff ) )
|
||||
|
||||
/** PCI VPD field debug message format */
|
||||
#define PCI_VPD_FIELD_FMT "%c%c"
|
||||
|
||||
/** PCI VPD field debug message arguments */
|
||||
#define PCI_VPD_FIELD_ARGS( field ) \
|
||||
( (field) >> 0 ), ( (field) >> 8 )
|
||||
|
||||
/** PCI VPD Read-Only field tag */
|
||||
#define PCI_VPD_TAG_RO 0x90
|
||||
|
||||
/** PCI VPD Read-Write field tag */
|
||||
#define PCI_VPD_TAG_RW 0x91
|
||||
|
||||
/** PCI VPD Card Name field descriptor */
|
||||
#define PCI_VPD_FIELD_NAME PCI_VPD_WHOLE_TAG_FIELD ( ISAPNP_TAG_ANSISTR )
|
||||
|
||||
/** PCI VPD Part Number field descriptor */
|
||||
#define PCI_VPD_FIELD_PN PCI_VPD_FIELD ( PCI_VPD_TAG_RO, 'P', 'N' )
|
||||
|
||||
/** PCI VPD Engineering Change Level field descriptor */
|
||||
#define PCI_VPD_FIELD_EC PCI_VPD_FIELD ( PCI_VPD_TAG_RO, 'E', 'C' )
|
||||
|
||||
/** PCI VPD Fabric Geography field descriptor */
|
||||
#define PCI_VPD_FIELD_FG PCI_VPD_FIELD ( PCI_VPD_TAG_RO, 'F', 'G' )
|
||||
|
||||
/** PCI VPD Location field descriptor */
|
||||
#define PCI_VPD_FIELD_LC PCI_VPD_FIELD ( PCI_VPD_TAG_RO, 'L', 'C' )
|
||||
|
||||
/** PCI VPD Manufacturer ID field descriptor */
|
||||
#define PCI_VPD_FIELD_MN PCI_VPD_FIELD ( PCI_VPD_TAG_RO, 'M', 'N' )
|
||||
|
||||
/** PCI VPD PCI Geography field descriptor */
|
||||
#define PCI_VPD_FIELD_PG PCI_VPD_FIELD ( PCI_VPD_TAG_RO, 'P', 'G' )
|
||||
|
||||
/** PCI VPD Serial Number field descriptor */
|
||||
#define PCI_VPD_FIELD_SN PCI_VPD_FIELD ( PCI_VPD_TAG_RO, 'S', 'N' )
|
||||
|
||||
/** PCI VPD Extended Capability field descriptor */
|
||||
#define PCI_VPD_FIELD_CP PCI_VPD_FIELD ( PCI_VPD_TAG_RO, 'C', 'P' )
|
||||
|
||||
/** PCI VPD Checksum and Reserved field descriptor */
|
||||
#define PCI_VPD_FIELD_RV PCI_VPD_FIELD ( PCI_VPD_TAG_RO, 'R', 'V' )
|
||||
|
||||
/** PCI VPD Asset Tag field descriptor */
|
||||
#define PCI_VPD_FIELD_YA PCI_VPD_FIELD ( PCI_VPD_TAG_RW, 'Y', 'A' )
|
||||
|
||||
/** PCI VPD Remaining Read/Write Area field descriptor */
|
||||
#define PCI_VPD_FIELD_RW PCI_VPD_FIELD ( PCI_VPD_TAG_RW, 'R', 'W' )
|
||||
|
||||
/** Maximum wait for PCI VPD (in ms) */
|
||||
#define PCI_VPD_MAX_WAIT_MS 100
|
||||
|
||||
/** PCI VPD cache */
|
||||
struct pci_vpd_cache {
|
||||
/** Address */
|
||||
int address;
|
||||
/** Data */
|
||||
uint32_t data;
|
||||
};
|
||||
|
||||
/** PCI VPD */
|
||||
struct pci_vpd {
|
||||
/** PCI device */
|
||||
struct pci_device *pci;
|
||||
/** VPD capability offset */
|
||||
int cap;
|
||||
/** Read cache */
|
||||
struct pci_vpd_cache cache;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if PCI VPD read cache is valid
|
||||
*
|
||||
* @v vpd PCI VPD
|
||||
* @ret is_valid Read cache is valid
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) int
|
||||
pci_vpd_cache_is_valid ( struct pci_vpd *vpd ) {
|
||||
return ( vpd->cache.address >= 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate PCI VPD read cache
|
||||
*
|
||||
* @v vpd PCI VPD
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
pci_vpd_invalidate_cache ( struct pci_vpd *vpd ) {
|
||||
vpd->cache.address = -1;
|
||||
}
|
||||
|
||||
extern int pci_vpd_init ( struct pci_vpd *vpd, struct pci_device *pci );
|
||||
extern int pci_vpd_read ( struct pci_vpd *vpd, unsigned int address,
|
||||
void *buf, size_t len );
|
||||
extern int pci_vpd_write ( struct pci_vpd *vpd, unsigned int address,
|
||||
const void *buf, size_t len );
|
||||
extern int pci_vpd_find ( struct pci_vpd *vpd, unsigned int field,
|
||||
unsigned int *address, size_t *len );
|
||||
|
||||
#endif /* _IPXE_PCIVPD_H */
|
||||
Reference in New Issue
Block a user