iPXE
pcivpd.h
Go to the documentation of this file.
00001 #ifndef _IPXE_PCIVPD_H
00002 #define _IPXE_PCIVPD_H
00003 
00004 /**
00005  * @file
00006  *
00007  * PCI Vital Product Data
00008  *
00009  */
00010 
00011 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
00012 
00013 #include <stdint.h>
00014 #include <byteswap.h>
00015 #include <ipxe/isapnp.h>
00016 #include <ipxe/pci.h>
00017 
00018 /** PCI VPD address register */
00019 #define PCI_VPD_ADDRESS 0x02
00020 
00021 /** PCI VPD write flag */
00022 #define PCI_VPD_FLAG 0x8000
00023 
00024 /** PCI VPD data register */
00025 #define PCI_VPD_DATA 0x04
00026 
00027 /** A PCI VPD field */
00028 struct pci_vpd_field {
00029         /** Keyword */
00030         uint16_t keyword;
00031         /** Length */
00032         uint8_t len;
00033 } __attribute__ (( packed ));
00034 
00035 /** Maximum PCI VPD field length */
00036 #define PCI_VPD_MAX_LEN 0xff
00037 
00038 /** Construct PCI VPD field descriptor
00039  *
00040  * @v tag               ISAPnP tag
00041  * @v keyword1          First character of keyword
00042  * @v keyword2          Second character of keyword
00043  * @ret field           VPD field descriptor
00044  */
00045 #define PCI_VPD_FIELD( tag, keyword1, keyword2 ) \
00046         ( ( (tag) << 16 ) | ( (keyword2) << 8 ) | ( (keyword1) << 0 ) )
00047 
00048 /** Construct PCI VPD whole-tag field descriptor
00049  *
00050  * @v tag               ISAPnP tag
00051  * @ret field           VPD field descriptor
00052  */
00053 #define PCI_VPD_WHOLE_TAG_FIELD( tag ) PCI_VPD_FIELD ( (tag), '\0', '\0' )
00054 
00055 /** Extract PCI VPD ISAPnP tag
00056  *
00057  * @v field             VPD field descriptor
00058  * @ret tag             ISAPnP tag
00059  */
00060 #define PCI_VPD_TAG( field ) ( (field) >> 16 )
00061 
00062 /** Extract PCI VPD keyword
00063  *
00064  * @v field             VPD field descriptor
00065  * @ret keyword         Keyword
00066  */
00067 #define PCI_VPD_KEYWORD( field ) ( cpu_to_le16 ( (field) & 0xffff ) )
00068 
00069 /** PCI VPD field debug message format */
00070 #define PCI_VPD_FIELD_FMT "%c%c"
00071 
00072 /** PCI VPD field debug message arguments */
00073 #define PCI_VPD_FIELD_ARGS( field ) \
00074         ( (field) >> 0 ), ( (field) >> 8 )
00075 
00076 /** PCI VPD Read-Only field tag */
00077 #define PCI_VPD_TAG_RO 0x90
00078 
00079 /** PCI VPD Read-Write field tag */
00080 #define PCI_VPD_TAG_RW 0x91
00081 
00082 /** PCI VPD Card Name field descriptor */
00083 #define PCI_VPD_FIELD_NAME PCI_VPD_WHOLE_TAG_FIELD ( ISAPNP_TAG_ANSISTR )
00084 
00085 /** PCI VPD Part Number field descriptor */
00086 #define PCI_VPD_FIELD_PN PCI_VPD_FIELD ( PCI_VPD_TAG_RO, 'P', 'N' )
00087 
00088 /** PCI VPD Engineering Change Level field descriptor */
00089 #define PCI_VPD_FIELD_EC PCI_VPD_FIELD ( PCI_VPD_TAG_RO, 'E', 'C' )
00090 
00091 /** PCI VPD Fabric Geography field descriptor */
00092 #define PCI_VPD_FIELD_FG PCI_VPD_FIELD ( PCI_VPD_TAG_RO, 'F', 'G' )
00093 
00094 /** PCI VPD Location field descriptor */
00095 #define PCI_VPD_FIELD_LC PCI_VPD_FIELD ( PCI_VPD_TAG_RO, 'L', 'C' )
00096 
00097 /** PCI VPD Manufacturer ID field descriptor */
00098 #define PCI_VPD_FIELD_MN PCI_VPD_FIELD ( PCI_VPD_TAG_RO, 'M', 'N' )
00099 
00100 /** PCI VPD PCI Geography field descriptor */
00101 #define PCI_VPD_FIELD_PG PCI_VPD_FIELD ( PCI_VPD_TAG_RO, 'P', 'G' )
00102 
00103 /** PCI VPD Serial Number field descriptor */
00104 #define PCI_VPD_FIELD_SN PCI_VPD_FIELD ( PCI_VPD_TAG_RO, 'S', 'N' )
00105 
00106 /** PCI VPD Extended Capability field descriptor */
00107 #define PCI_VPD_FIELD_CP PCI_VPD_FIELD ( PCI_VPD_TAG_RO, 'C', 'P' )
00108 
00109 /** PCI VPD Checksum and Reserved field descriptor */
00110 #define PCI_VPD_FIELD_RV PCI_VPD_FIELD ( PCI_VPD_TAG_RO, 'R', 'V' )
00111 
00112 /** PCI VPD Asset Tag field descriptor */
00113 #define PCI_VPD_FIELD_YA PCI_VPD_FIELD ( PCI_VPD_TAG_RW, 'Y', 'A' )
00114 
00115 /** PCI VPD Remaining Read/Write Area field descriptor */
00116 #define PCI_VPD_FIELD_RW PCI_VPD_FIELD ( PCI_VPD_TAG_RW, 'R', 'W' )
00117 
00118 /** Maximum wait for PCI VPD (in ms) */
00119 #define PCI_VPD_MAX_WAIT_MS 100
00120 
00121 /** PCI VPD cache */
00122 struct pci_vpd_cache {
00123         /** Address */
00124         int address;
00125         /** Data */
00126         uint32_t data;
00127 };
00128 
00129 /** PCI VPD */
00130 struct pci_vpd {
00131         /** PCI device */
00132         struct pci_device *pci;
00133         /** VPD capability offset */
00134         int cap;
00135         /** Read cache */
00136         struct pci_vpd_cache cache;
00137 };
00138 
00139 /**
00140  * Check for presence of PCI VPD
00141  *
00142  * @v vpd               PCI VPD
00143  * @ret is_present      VPD is present
00144  */
00145 static inline __attribute__ (( always_inline )) int
00146 pci_vpd_is_present ( struct pci_vpd *vpd ) {
00147         return ( vpd->cap != 0 );
00148 }
00149 
00150 /**
00151  * Check if PCI VPD read cache is valid
00152  *
00153  * @v vpd               PCI VPD
00154  * @ret is_valid        Read cache is valid
00155  */
00156 static inline __attribute__ (( always_inline )) int
00157 pci_vpd_cache_is_valid ( struct pci_vpd *vpd ) {
00158         return ( vpd->cache.address >= 0 );
00159 }
00160 
00161 /**
00162  * Invalidate PCI VPD read cache
00163  *
00164  * @v vpd               PCI VPD
00165  */
00166 static inline __attribute__ (( always_inline )) void
00167 pci_vpd_invalidate_cache ( struct pci_vpd *vpd ) {
00168         vpd->cache.address = -1;
00169 }
00170 
00171 extern int pci_vpd_init ( struct pci_vpd *vpd, struct pci_device *pci );
00172 extern int pci_vpd_read ( struct pci_vpd *vpd, unsigned int address,
00173                           void *buf, size_t len );
00174 extern int pci_vpd_write ( struct pci_vpd *vpd, unsigned int address,
00175                            const void *buf, size_t len );
00176 extern int pci_vpd_find ( struct pci_vpd *vpd, unsigned int field,
00177                           unsigned int *address, size_t *len );
00178 extern int pci_vpd_resize ( struct pci_vpd *vpd, unsigned int field,
00179                             size_t len, unsigned int *address );
00180 
00181 #endif /* _IPXE_PCIVPD_H */