diff options
Diffstat (limited to 'src/include/ipxe')
| -rw-r--r-- | src/include/ipxe/errfile.h | 1 | ||||
| -rw-r--r-- | src/include/ipxe/pcivpd.h | 165 |
2 files changed, 166 insertions, 0 deletions
diff --git a/src/include/ipxe/errfile.h b/src/include/ipxe/errfile.h index 17e5a4f8e..747241492 100644 --- a/src/include/ipxe/errfile.h +++ b/src/include/ipxe/errfile.h @@ -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 ) diff --git a/src/include/ipxe/pcivpd.h b/src/include/ipxe/pcivpd.h new file mode 100644 index 000000000..8b973ea1c --- /dev/null +++ b/src/include/ipxe/pcivpd.h @@ -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 */ |
