home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection 1998 Fall: Game Toolkit / Disc.iso / SDKs / PCI Driver Development Kit / • Tools / Utility / DisplayNameRegistry 950412 / Src / FormatThisProperty.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-27  |  9.7 KB  |  376 lines  |  [TEXT/MPCC]

  1. /*                                FormatThisProperty.c                                */
  2. /*
  3.  * FormatThisProperty.c
  4.  *
  5.  * Store the Name Registry value into the Twist-Down list.
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include "DisplayNameRegistry.h"
  10. #include <ctype.h>
  11. #include <string.h>
  12.  
  13. Boolean            gDisplayContent;
  14. Boolean            gDisplayDrivers;
  15. /*
  16.  * To test for a driver (executable code), look at the first 7 bytes of the property.
  17.  */
  18. #define kDriverProperty        "driver,"
  19. #define kAddressProperty    "assigned-addresses"
  20. #define kRegPropery            "reg"
  21. #define IsDriverProperty(property) \
  22.     (strncmp((property), kDriverProperty, 7) == 0)
  23. #define IsAddressProperty(property) (strcmp((property), kAddressProperty) == 0)
  24. #define IsRegProperty(property) (strcmp((property), kRegPropery) == 0)
  25.  
  26. /*
  27.  * The PhysAddressProperty structure from IEEE 1275 is used for "reg" and
  28.  * "assigned-address" properties.
  29.  */
  30. typedef struct PhysAddressProperty {
  31.     UInt32            physHi;
  32.     UInt32            physMid;
  33.     UInt32            physLo;
  34.     UInt32            sizeHi;
  35.     UInt32            sizeLo;
  36. } PhysAddressProperty, *PhysAddressPropertyPtr;
  37. /*
  38.  * These masks and values decode the physHi word. The format is
  39.  * npt000ss bbbbbbbb dddddfff rrrrrrrr
  40.  *
  41.  * n        1 = Relocatable, 0 = Absolute
  42.  * p        1 = Prefetchable
  43.  * t        1 = Alias
  44.  * ss        Space code (Config, I/O, Mem, 64-bit Mem)    2 bits
  45.  * bbbbbbbb    Bus number                                    8 bits
  46.  * ddddd    Device number                                5 bits
  47.  * fff        Function number                                3 bits
  48.  * rrrrrrrr    Register number                             8 bits
  49.  */
  50. #define kPhysAbsolute        0x80000000    /* 0 if relocatable, 1 if not                */
  51. #define kPhysPrefetch        0x40000000    /* 1 if "prefetchable", 0 if not            */
  52. #define kPhysAlias            0x20000000    /* 1 if alised (for I/O) or below 1MB (Mem)    */
  53. #define kPhysSpaceMask        0x03000000    /* Config, Mem, I/O, or 64-bit Mem            */
  54. #define kPhysSpaceShift        24
  55. #define kPhysBusNumberMask    0x00FF0000
  56. #define kPhysBusNumberShift    16
  57. #define kPhysDeviceMask        0x0000F800
  58. #define kPhysDeviceShift    11
  59. #define kPhysFunctionMask    0x00000700
  60. #define kPhysFunctionShift    8
  61. #define kPhysRegisterMask    0x000000FF
  62. #define kPhysRegisterShift    0
  63.  
  64. TwistDownHdl                EnumeratePropertiesForThisName(
  65.         RegEntryID                *entryID
  66.     );
  67. Boolean                        FormatOneLineProperty(
  68.         RegPropertyValueSize    propertySize,
  69.         const void                *propertyValue,
  70.         char                    *result
  71.     );
  72. void                        FormatPhysAddressProperty(
  73.         PhysAddressPropertyPtr    physAddressPropertyPtr,
  74.         short                    nPhysAddress,
  75.         TwistDownSiblingSet        *twistDownSiblingSetPtr
  76.     );
  77. Boolean                        FormatStringProperty(
  78.         RegPropertyValueSize    propertySize,
  79.         const void                *propertyValue,
  80.         char                    *result
  81.     );
  82. Boolean                        FormatSmallProperty(
  83.         RegPropertyValueSize    propertySize,
  84.         const void                *propertyValue,
  85.         char                    *result
  86.     );
  87. TwistDownHdl                FormatLargeProperty(
  88.         const RegPropertyNameBuf foundProperty,
  89.         RegPropertyValueSize    propertySize,
  90.         const void                *propertyValue
  91.     );
  92.  
  93.  
  94. /*
  95.  * Called for all property values.
  96.  */
  97. TwistDownHdl
  98. FormatThisProperty(
  99.         const RegPropertyNameBuf foundProperty,
  100.         RegPropertyValueSize    propertySize,
  101.         const void                *propertyValue
  102.     )
  103. {
  104.         TwistDownHdl            propertyHdl;
  105.         Boolean                    oneLiner;
  106.         char                    work[kOneLineFormatLength + 1];
  107.  
  108.         oneLiner = FormatOneLineProperty(propertySize, propertyValue, work);
  109.         if (oneLiner) {
  110.             (void)  MakeTwistDownElement(
  111.                     NULL,
  112.                     kValueIndentLevel,
  113.                     strlen(work),
  114.                     (Ptr) work,
  115.                     &propertyHdl
  116.                 );
  117.         }
  118.         else {
  119.             propertyHdl = FormatLargeProperty(
  120.                         foundProperty,
  121.                         propertySize,
  122.                         propertyValue
  123.                     );
  124.         }
  125.         return (propertyHdl);
  126. }
  127.  
  128. /*
  129.  * FormatOneLineProperty tries to format the property value into a single line.
  130.  * It returns TRUE if it succeeds.
  131.  */
  132. Boolean
  133. FormatOneLineProperty(
  134.         RegPropertyValueSize    propertySize,
  135.         const void                *propertyValue,
  136.         char                    *result
  137.     )
  138. {
  139.         Boolean                    oneLiner;
  140.         
  141.         oneLiner = FormatStringProperty(
  142.                     propertySize,
  143.                     propertyValue,
  144.                     result
  145.                 );
  146.         if (oneLiner == FALSE)
  147.             oneLiner = FormatSmallProperty(propertySize, propertyValue, result);
  148.         return (oneLiner);
  149. }
  150.  
  151. Boolean
  152. FormatStringProperty(
  153.         RegPropertyValueSize    propertySize,
  154.         const void                *propertyValue,
  155.         char                    *result
  156.     )
  157. {
  158.         Boolean                    isStringProperty;
  159.         Boolean                    isAscii;
  160.         int                        i;
  161.         register char            *cp;
  162.         
  163.         isStringProperty = FALSE;
  164.         if (propertySize < (kOneLineFormatLength - 3)) {
  165.             isAscii = TRUE;
  166.             cp = ((char *) propertyValue);
  167.             for (i = 0; isAscii && i < (propertySize - 1); i++)
  168.                 isAscii = IS_ASCII_PRINT(cp[i]);
  169.             if (isAscii && cp[i] == '\0') {
  170.                 sprintf(result, "\"%s\"", cp);
  171.                 isStringProperty = TRUE;
  172.             }
  173.         }
  174.         return (isStringProperty);
  175. }
  176.  
  177. Boolean
  178. FormatSmallProperty(
  179.         RegPropertyValueSize    propertySize,
  180.         const void                *propertyValue,
  181.         char                    *result
  182.     )
  183. {
  184.         Boolean                    isSmallProperty;
  185.         long                    *lp;
  186.         short                    *sp;
  187.         
  188.         isSmallProperty = FALSE;
  189.         if (propertySize == sizeof (short)) {
  190.             sp = (short *) propertyValue;
  191.             sprintf(result, "[%04x = %d]", ((int) *sp) & 0xFFFF, (int) *sp);
  192.             isSmallProperty = TRUE;
  193.         }
  194.         if (propertySize == sizeof (long)) {
  195.             lp = (long *) propertyValue;
  196.             sprintf(result, "[%08x = %ld]",
  197.                 lp[0], lp[0]
  198.             );
  199.             isSmallProperty = TRUE;
  200.         }
  201.         else if (propertySize == (sizeof (long) * 2)) {
  202.             lp = (long *) propertyValue;
  203.             sprintf(result, "[%08x = %ld], [%08x = %ld]",
  204.                 lp[0], lp[0], lp[1], lp[1]);
  205.             isSmallProperty = TRUE;
  206.         }
  207.         return (isSmallProperty);
  208. }
  209.  
  210. TwistDownHdl
  211. FormatLargeProperty(
  212.         const RegPropertyNameBuf foundProperty,
  213.         RegPropertyValueSize    propertySize,
  214.         const void                *propertyValue
  215.     )
  216. {
  217.         TwistDownSiblingSet        twistDownSiblingSet;
  218.         OSErr                    status;
  219.         short                    i;
  220.         short                    offset;
  221.         short                    nBytesToDraw;
  222.         unsigned char            c;
  223.         unsigned char            *cp;
  224.         char                    work[256];
  225.         char                    thisValue[80];
  226. #define kBytesPerLine    16
  227.  
  228.         NewTwistDownSiblingSet(&twistDownSiblingSet);
  229.         if (IsAddressProperty(foundProperty) || IsRegProperty(foundProperty)) {
  230.             FormatPhysAddressProperty(
  231.                 (PhysAddressPropertyPtr) propertyValue,
  232.                 propertySize / sizeof (PhysAddressProperty),
  233.                 &twistDownSiblingSet
  234.             );
  235.         }
  236.         /*
  237.          * Even if it's a known property ("assigned-address"), format
  238.          * the raw hex data.
  239.          */
  240.         cp = (unsigned char *) propertyValue;
  241.         for (offset = 0; offset < propertySize; offset += kBytesPerLine) {
  242.             if ((offset + kBytesPerLine) <= propertySize)
  243.                 nBytesToDraw = kBytesPerLine;
  244.             else {
  245.                 nBytesToDraw = propertySize - offset;
  246.             }
  247.             sprintf(work, "%04lx:", offset);
  248.             for (i = 0; i < nBytesToDraw; i++) {
  249.                 sprintf(thisValue, " %02x", cp[offset + i] & 0xFF);
  250.                 strcat(work, thisValue);
  251.             }
  252.             for (; i < kBytesPerLine; i++)
  253.                 strcat(work, "   ");
  254.             strcat(work, " ");
  255.             for (i = 0; i < nBytesToDraw; i++) {
  256.                 c = cp[offset + i];
  257.                 if (c < ' ' || c > '~')
  258.                     c = '.';
  259.                 thisValue[0] = c;
  260.                 thisValue[1] = 0;
  261.                 strcat(work, thisValue);
  262.             }
  263.             status = MakeTwistDownSibling(
  264.                         &twistDownSiblingSet,
  265.                         kValueIndentLevel,
  266.                         strlen(work),
  267.                         (Ptr) work
  268.                     );
  269.         }
  270.         return (twistDownSiblingSet.firstElement);
  271. }
  272.  
  273.  
  274. /*
  275.  * FormatPhysAddressProperty formats a vector of "reg" and/or "assigned-address"
  276.  * descriptor values, as described in IEEE 1275-1994. The caller has checked that this is,
  277.  * indeed, a "reg" or "assigned-address" property. The "reg" property is the primary
  278.  * mechanism that PCI uses to describe a device's physical memory requirements. The
  279.  * "assigned-address" property binds physical addresses to the actual hardware
  280.  * configuration.
  281.  */
  282. void
  283. FormatPhysAddressProperty(
  284.         PhysAddressPropertyPtr    physAddressPropertyPtr,
  285.         short                    nPhysAddress,
  286.         TwistDownSiblingSet        *twistDownSiblingSetPtr
  287.     )
  288. {
  289.         short                    i;
  290.         unsigned int            busNumber;
  291.         unsigned int            deviceNumber;
  292.         unsigned int            functionNumber;
  293.         unsigned int            registerNumber;
  294.         OSErr                    status;
  295.         char                    *addressType;
  296.         char                    *isPrefetch;
  297.         char                    *isAlias;
  298.         char                    *isAbsolute;
  299.         char                    work[256];
  300.         UInt32                    cellHi;
  301.         
  302.         for (status = noErr, i = 0; status == noErr && i < nPhysAddress; i++) {
  303.             cellHi = physAddressPropertyPtr[i].physHi;
  304.             busNumber = (cellHi & kPhysBusNumberMask) >> kPhysBusNumberShift;
  305.             deviceNumber = (cellHi & kPhysDeviceMask) >> kPhysDeviceShift;
  306.             functionNumber = (cellHi & kPhysFunctionMask) >> kPhysFunctionShift;
  307.             registerNumber = (cellHi & kPhysRegisterMask) >> kPhysRegisterShift;
  308.             isAbsolute = ((cellHi & kPhysAbsolute) != 0) ? "abs" : "rel";
  309.             isPrefetch = ((cellHi & kPhysPrefetch) != 0) ? ", prefetch" : "";
  310.             isAlias    = ((cellHi & kPhysAlias)    != 0) ? ", alias" : "";
  311.             switch ((cellHi & kPhysSpaceMask) >> kPhysSpaceShift) {
  312.             case 0:    addressType = "Config";        break;
  313.             case 1:    addressType = "I/O";        break;
  314.             case 2:    addressType = "Mem";        break;
  315.             case 3:    addressType = "64-bit";        break;
  316.             }
  317.             sprintf(
  318.                 work,
  319.                 "bus %u, dev %u, func %u, reg %u (%s) %s%s%s, %08lx %08lx %08lx",
  320.                 busNumber,
  321.                 deviceNumber,
  322.                 functionNumber,
  323.                 registerNumber,
  324.                 addressType,
  325.                 isAbsolute,
  326.                 isPrefetch,
  327.                 isAlias,
  328.                 physAddressPropertyPtr[i].physHi,
  329.                 physAddressPropertyPtr[i].physLo,
  330.                 physAddressPropertyPtr[i].sizeLo
  331.             );
  332.             status = MakeTwistDownSibling(
  333.                         twistDownSiblingSetPtr,
  334.                         kValueIndentLevel,
  335.                         strlen(work),
  336.                         (Ptr) work
  337.                     );
  338.         }
  339. }
  340.  
  341. /*
  342.  * OneLineProperty is called by the display list creator to format
  343.  * "property : value" or "path : value" where the entire text fits
  344.  * on a single display line.
  345.  */
  346. Boolean
  347. OneLineProperty(
  348.         const char                *labelText,
  349.         const TwistDownHdl        valueElement,
  350.         char                    *oneLineWork
  351.     )
  352. {
  353.         int                        length;
  354.         Boolean                    oneLiner;
  355. #define VAL    (**valueElement)
  356.  
  357.         if (valueElement == NULL || VAL.nextElement != NULL)
  358.             oneLiner = FALSE;
  359.         else {
  360.             length = strlen(labelText) + strlen(" = ") + VAL.dataLength;
  361.             if (length > kOneLineFormatLength)
  362.                 oneLiner = FALSE;
  363.             else {
  364.                 oneLiner = TRUE;
  365.                 sprintf(
  366.                     oneLineWork,
  367.                     "%s = %.*s",
  368.                     (char *) labelText,
  369.                     (int) VAL.dataLength,
  370.                     (char *) VAL.data
  371.                 );
  372.             }
  373.         }
  374.         return (oneLiner);
  375. }
  376.