You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. #ifndef _IPXE_PCIVPD_H
  2. #define _IPXE_PCIVPD_H
  3. /**
  4. * @file
  5. *
  6. * PCI Vital Product Data
  7. *
  8. */
  9. FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  10. #include <stdint.h>
  11. #include <byteswap.h>
  12. #include <ipxe/isapnp.h>
  13. #include <ipxe/pci.h>
  14. /** PCI VPD address register */
  15. #define PCI_VPD_ADDRESS 0x02
  16. /** PCI VPD write flag */
  17. #define PCI_VPD_FLAG 0x8000
  18. /** PCI VPD data register */
  19. #define PCI_VPD_DATA 0x04
  20. /** A PCI VPD field */
  21. struct pci_vpd_field {
  22. /** Keyword */
  23. uint16_t keyword;
  24. /** Length */
  25. uint8_t len;
  26. } __attribute__ (( packed ));
  27. /** Maximum PCI VPD field length */
  28. #define PCI_VPD_MAX_LEN 0xff
  29. /** Construct PCI VPD field descriptor
  30. *
  31. * @v tag ISAPnP tag
  32. * @v keyword1 First character of keyword
  33. * @v keyword2 Second character of keyword
  34. * @ret field VPD field descriptor
  35. */
  36. #define PCI_VPD_FIELD( tag, keyword1, keyword2 ) \
  37. ( ( (tag) << 16 ) | ( (keyword2) << 8 ) | ( (keyword1) << 0 ) )
  38. /** Construct PCI VPD whole-tag field descriptor
  39. *
  40. * @v tag ISAPnP tag
  41. * @ret field VPD field descriptor
  42. */
  43. #define PCI_VPD_WHOLE_TAG_FIELD( tag ) PCI_VPD_FIELD ( (tag), '\0', '\0' )
  44. /** Extract PCI VPD ISAPnP tag
  45. *
  46. * @v field VPD field descriptor
  47. * @ret tag ISAPnP tag
  48. */
  49. #define PCI_VPD_TAG( field ) ( (field) >> 16 )
  50. /** Extract PCI VPD keyword
  51. *
  52. * @v field VPD field descriptor
  53. * @ret keyword Keyword
  54. */
  55. #define PCI_VPD_KEYWORD( field ) ( cpu_to_le16 ( (field) & 0xffff ) )
  56. /** PCI VPD field debug message format */
  57. #define PCI_VPD_FIELD_FMT "%c%c"
  58. /** PCI VPD field debug message arguments */
  59. #define PCI_VPD_FIELD_ARGS( field ) \
  60. ( (field) >> 0 ), ( (field) >> 8 )
  61. /** PCI VPD Read-Only field tag */
  62. #define PCI_VPD_TAG_RO 0x90
  63. /** PCI VPD Read-Write field tag */
  64. #define PCI_VPD_TAG_RW 0x91
  65. /** PCI VPD Card Name field descriptor */
  66. #define PCI_VPD_FIELD_NAME PCI_VPD_WHOLE_TAG_FIELD ( ISAPNP_TAG_ANSISTR )
  67. /** PCI VPD Part Number field descriptor */
  68. #define PCI_VPD_FIELD_PN PCI_VPD_FIELD ( PCI_VPD_TAG_RO, 'P', 'N' )
  69. /** PCI VPD Engineering Change Level field descriptor */
  70. #define PCI_VPD_FIELD_EC PCI_VPD_FIELD ( PCI_VPD_TAG_RO, 'E', 'C' )
  71. /** PCI VPD Fabric Geography field descriptor */
  72. #define PCI_VPD_FIELD_FG PCI_VPD_FIELD ( PCI_VPD_TAG_RO, 'F', 'G' )
  73. /** PCI VPD Location field descriptor */
  74. #define PCI_VPD_FIELD_LC PCI_VPD_FIELD ( PCI_VPD_TAG_RO, 'L', 'C' )
  75. /** PCI VPD Manufacturer ID field descriptor */
  76. #define PCI_VPD_FIELD_MN PCI_VPD_FIELD ( PCI_VPD_TAG_RO, 'M', 'N' )
  77. /** PCI VPD PCI Geography field descriptor */
  78. #define PCI_VPD_FIELD_PG PCI_VPD_FIELD ( PCI_VPD_TAG_RO, 'P', 'G' )
  79. /** PCI VPD Serial Number field descriptor */
  80. #define PCI_VPD_FIELD_SN PCI_VPD_FIELD ( PCI_VPD_TAG_RO, 'S', 'N' )
  81. /** PCI VPD Extended Capability field descriptor */
  82. #define PCI_VPD_FIELD_CP PCI_VPD_FIELD ( PCI_VPD_TAG_RO, 'C', 'P' )
  83. /** PCI VPD Checksum and Reserved field descriptor */
  84. #define PCI_VPD_FIELD_RV PCI_VPD_FIELD ( PCI_VPD_TAG_RO, 'R', 'V' )
  85. /** PCI VPD Asset Tag field descriptor */
  86. #define PCI_VPD_FIELD_YA PCI_VPD_FIELD ( PCI_VPD_TAG_RW, 'Y', 'A' )
  87. /** PCI VPD Remaining Read/Write Area field descriptor */
  88. #define PCI_VPD_FIELD_RW PCI_VPD_FIELD ( PCI_VPD_TAG_RW, 'R', 'W' )
  89. /** Maximum wait for PCI VPD (in ms) */
  90. #define PCI_VPD_MAX_WAIT_MS 100
  91. /** PCI VPD cache */
  92. struct pci_vpd_cache {
  93. /** Address */
  94. int address;
  95. /** Data */
  96. uint32_t data;
  97. };
  98. /** PCI VPD */
  99. struct pci_vpd {
  100. /** PCI device */
  101. struct pci_device *pci;
  102. /** VPD capability offset */
  103. int cap;
  104. /** Read cache */
  105. struct pci_vpd_cache cache;
  106. };
  107. /**
  108. * Check for presence of PCI VPD
  109. *
  110. * @v vpd PCI VPD
  111. * @ret is_present VPD is present
  112. */
  113. static inline __attribute__ (( always_inline )) int
  114. pci_vpd_is_present ( struct pci_vpd *vpd ) {
  115. return ( vpd->cap != 0 );
  116. }
  117. /**
  118. * Check if PCI VPD read cache is valid
  119. *
  120. * @v vpd PCI VPD
  121. * @ret is_valid Read cache is valid
  122. */
  123. static inline __attribute__ (( always_inline )) int
  124. pci_vpd_cache_is_valid ( struct pci_vpd *vpd ) {
  125. return ( vpd->cache.address >= 0 );
  126. }
  127. /**
  128. * Invalidate PCI VPD read cache
  129. *
  130. * @v vpd PCI VPD
  131. */
  132. static inline __attribute__ (( always_inline )) void
  133. pci_vpd_invalidate_cache ( struct pci_vpd *vpd ) {
  134. vpd->cache.address = -1;
  135. }
  136. extern int pci_vpd_init ( struct pci_vpd *vpd, struct pci_device *pci );
  137. extern int pci_vpd_read ( struct pci_vpd *vpd, unsigned int address,
  138. void *buf, size_t len );
  139. extern int pci_vpd_write ( struct pci_vpd *vpd, unsigned int address,
  140. const void *buf, size_t len );
  141. extern int pci_vpd_find ( struct pci_vpd *vpd, unsigned int field,
  142. unsigned int *address, size_t *len );
  143. extern int pci_vpd_resize ( struct pci_vpd *vpd, unsigned int field,
  144. size_t len, unsigned int *address );
  145. #endif /* _IPXE_PCIVPD_H */