residual.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:25k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * BK Id: SCCS/s.residual.c 1.13 09/11/01 16:54:34 trini
  3.  */
  4. /*
  5.  * Code to deal with the PReP residual data.
  6.  *
  7.  * Written by: Cort Dougan (cort@cs.nmt.edu)
  8.  * Improved _greatly_ and rewritten by Gabriel Paubert (paubert@iram.es)
  9.  *
  10.  *  This file is based on the following documentation:
  11.  *
  12.  * IBM Power Personal Systems Architecture
  13.  * Residual Data
  14.  *  Document Number: PPS-AR-FW0001
  15.  *
  16.  *  This file is subject to the terms and conditions of the GNU General Public
  17.  *  License.  See the file COPYING in the main directory of this archive
  18.  *  for more details.
  19.  *
  20.  */
  21. #include <linux/string.h>
  22. #include <asm/residual.h>
  23. #include <asm/pnp.h>
  24. #include <asm/byteorder.h>
  25. #include <linux/errno.h>
  26. #include <linux/sched.h>
  27. #include <linux/kernel.h>
  28. #include <linux/mm.h>
  29. #include <linux/stddef.h>
  30. #include <linux/unistd.h>
  31. #include <linux/ptrace.h>
  32. #include <linux/slab.h>
  33. #include <linux/user.h>
  34. #include <linux/a.out.h>
  35. #include <linux/tty.h>
  36. #include <linux/major.h>
  37. #include <linux/interrupt.h>
  38. #include <linux/reboot.h>
  39. #include <linux/init.h>
  40. #include <linux/blk.h>
  41. #include <linux/ioport.h>
  42. #include <linux/pci.h>
  43. #include <linux/ide.h>
  44. #include <asm/sections.h>
  45. #include <asm/mmu.h>
  46. #include <asm/processor.h>
  47. #include <asm/io.h>
  48. #include <asm/pgtable.h>
  49. #include <asm/ide.h>
  50. unsigned char __res[sizeof(RESIDUAL)] __prepdata = {0,};
  51. RESIDUAL *res = (RESIDUAL *)&__res;
  52. char * PnP_BASE_TYPES[] __initdata = {
  53.   "Reserved",
  54.   "MassStorageDevice",
  55.   "NetworkInterfaceController",
  56.   "DisplayController",
  57.   "MultimediaController",
  58.   "MemoryController",
  59.   "BridgeController",
  60.   "CommunicationsDevice",
  61.   "SystemPeripheral",
  62.   "InputDevice",
  63.   "ServiceProcessor"
  64.   };
  65. /* Device Sub Type Codes */
  66. unsigned char * PnP_SUB_TYPES[] __initdata = {
  67.   "0100SCSIController",
  68.   "0101IDEController",
  69.   "0102FloppyController",
  70.   "0103IPIController",
  71.   "01200OtherMassStorageController",
  72.   "0200EthernetController",
  73.   "0201TokenRingController",
  74.   "0202FDDIController",
  75.   "02x80OtherNetworkController",
  76.   "0300VGAController",
  77.   "0301SVGAController",
  78.   "0302XGAController",
  79.   "03200OtherDisplayController",
  80.   "0400VideoController",
  81.   "0401AudioController",
  82.   "04200OtherMultimediaController",
  83.   "0500RAM",
  84.   "0501FLASH",
  85.   "05200OtherMemoryDevice",
  86.   "0600HostProcessorBridge",
  87.   "0601ISABridge",
  88.   "0602EISABridge",
  89.   "0603MicroChannelBridge",
  90.   "0604PCIBridge",
  91.   "0605PCMCIABridge",
  92.   "0606VMEBridge",
  93.   "06200OtherBridgeDevice",
  94.   "0700RS232Device",
  95.   "0701ATCompatibleParallelPort",
  96.   "07200OtherCommunicationsDevice",
  97.   "1000ProgrammableInterruptController",
  98.   "1001DMAController",
  99.   "1002SystemTimer",
  100.   "1003RealTimeClock",
  101.   "1004L2Cache",
  102.   "1005NVRAM",
  103.   "1006PowerManagement",
  104.   "1007CMOS",
  105.   "1010OperatorPanel",
  106.   "1011ServiceProcessorClass1",
  107.   "1012ServiceProcessorClass2",
  108.   "1013ServiceProcessorClass3",
  109.   "1014GraphicAssist",
  110.   "1017SystemPlanar",
  111.   "10200OtherSystemPeripheral",
  112.   "1100KeyboardController",
  113.   "1101Digitizer",
  114.   "1102MouseController",
  115.   "1103TabletController",
  116.   "11x80OtherInputController",
  117.   "1200GeneralMemoryController",
  118.   NULL
  119. };
  120. /* Device Interface Type Codes */
  121. unsigned char * PnP_INTERFACES[] __initdata = {
  122.   "000000General",
  123.   "010000GeneralSCSI",
  124.   "010100GeneralIDE",
  125.   "010101ATACompatible",
  126.   "010200GeneralFloppy",
  127.   "010201Compatible765",
  128.   "010202NS398_Floppy",         /* NS Super I/O wired to use index
  129.                                          register at port 398 and data
  130.                                          register at port 399               */
  131.   "010203NS26E_Floppy",         /* Ports 26E and 26F                  */
  132.   "010204NS15C_Floppy",         /* Ports 15C and 15D                  */
  133.   "010205NS2E_Floppy",          /* Ports 2E and 2F                    */
  134.   "010206CHRP_Floppy",          /* CHRP Floppy in PR*P system         */
  135.   "010300GeneralIPI",
  136.   
  137.   "020000GeneralEther",
  138.   "020100GeneralToken",
  139.   "020200GeneralFDDI",
  140.   
  141.   "030000GeneralVGA",
  142.   "030100GeneralSVGA",
  143.   "030200GeneralXGA",
  144.   
  145.   "040000GeneralVideo",
  146.   "040100GeneralAudio",
  147.   "040101CS4232Audio",            /* CS 4232 Plug 'n Play Configured    */
  148.   "050000GeneralRAM",
  149.   /* This one is obviously wrong ! */
  150.   "050000PCIMemoryController",    /* PCI Config Method                  */
  151.   "050001RS6KMemoryController",   /* RS6K Config Method                 */
  152.   "050100GeneralFLASH",
  153.   
  154.   "060000GeneralHostBridge",
  155.   "060100GeneralISABridge",
  156.   "060200GeneralEISABridge",
  157.   "060300GeneralMCABridge",
  158.   /* GeneralPCIBridge = 0, */
  159.   "060400PCIBridgeDirect",
  160.   "060401PCIBridgeIndirect",
  161.   "060402PCIBridgeRS6K",
  162.   "060500GeneralPCMCIABridge",
  163.   "060600GeneralVMEBridge",
  164.   
  165.   "070000GeneralRS232",
  166.   "070001COMx",
  167.   "070002Compatible16450",
  168.   "070003Compatible16550",
  169.   "070004NS398SerPort",         /* NS Super I/O wired to use index
  170.                                          register at port 398 and data
  171.                                          register at port 399               */
  172.   "070005NS26ESerPort",         /* Ports 26E and 26F                  */
  173.   "070006NS15CSerPort",         /* Ports 15C and 15D                  */
  174.   "070007NS2ESerPort",          /* Ports 2E and 2F                    */
  175.   "070100GeneralParPort",
  176.   "070101LPTx",
  177.   "070102NS398ParPort",         /* NS Super I/O wired to use index
  178.                                          register at port 398 and data
  179.                                          register at port 399               */
  180.   "070103NS26EParPort",         /* Ports 26E and 26F                  */
  181.   "070104NS15CParPort",         /* Ports 15C and 15D                  */
  182.   "070105NS2EParPort",          /* Ports 2E and 2F                    */
  183.   
  184.   "100000GeneralPIC",
  185.   "100001ISA_PIC",
  186.   "100002EISA_PIC",
  187.   "100003MPIC",
  188.   "100004RS6K_PIC",
  189.   "100100GeneralDMA",
  190.   "100101ISA_DMA",
  191.   "100102EISA_DMA",
  192.   "100200GeneralTimer",
  193.   "100201ISA_Timer",
  194.   "100202EISA_Timer",
  195.   "100300GeneralRTC",
  196.   "100301ISA_RTC",
  197.   
  198.   "100401StoreThruOnly",
  199.   "100402StoreInEnabled",
  200.   "100403RS6KL2Cache",
  201.   "100500IndirectNVRAM",        /* Indirectly addressed               */
  202.   "100501DirectNVRAM",          /* Memory Mapped                      */
  203.   "100502IndirectNVRAM24",      /* Indirectly addressed - 24 bit      */
  204.   "100600GeneralPowerManagement",
  205.   "100601EPOWPowerManagement",
  206.   "100602PowerControl",         // d1378
  207.   
  208.   "100700GeneralCMOS",
  209.   "101000GeneralOPPanel",
  210.   "101001HarddiskLight",
  211.   "101002CDROMLight",
  212.   "101003PowerLight",
  213.   "101004KeyLock",
  214.   "101005ANDisplay",            /* AlphaNumeric Display               */
  215.   "101006SystemStatusLED",      /* 3 digit 7 segment LED              */
  216.   "101007CHRP_SystemStatusLED", /* CHRP LEDs in PR*P system           */
  217.   "101100GeneralServiceProcessor",
  218.   "101200GeneralServiceProcessor",
  219.   "101300GeneralServiceProcessor",
  220.   
  221.   "101401TransferData",
  222.   "101402IGMC32",
  223.   "101403IGMC64",
  224.   
  225.   "101700GeneralSystemPlanar",   /* 10/5/95                            */
  226.   NULL
  227.   };
  228. static const unsigned char __init *PnP_SUB_TYPE_STR(unsigned char BaseType, 
  229.      unsigned char SubType) {
  230. unsigned char ** s=PnP_SUB_TYPES;
  231. while (*s && !((*s)[0]==BaseType 
  232.        && (*s)[1]==SubType)) s++;
  233. if (*s) return *s+2;
  234. else return("Unknown !");
  235. };
  236. static const unsigned char __init *PnP_INTERFACE_STR(unsigned char BaseType, 
  237.       unsigned char SubType,
  238.       unsigned char Interface) {
  239. unsigned char ** s=PnP_INTERFACES;
  240. while (*s && !((*s)[0]==BaseType 
  241.        && (*s)[1]==SubType 
  242.        && (*s)[2]==Interface)) s++;
  243. if (*s) return *s+3;
  244. else return NULL;
  245. };
  246. static void __init printsmallvendor(PnP_TAG_PACKET *pkt, int size) {
  247. int i, c;
  248. char decomp[4];
  249. #define p pkt->S14_Pack.S14_Data.S14_PPCPack
  250. switch(p.Type) {
  251. case 1:
  252.   /* Decompress first 3 chars */
  253.   c = *(unsigned short *)p.PPCData;
  254.   decomp[0]='A'-1+((c>>10)&0x1F);
  255.   decomp[1]='A'-1+((c>>5)&0x1F);
  256.   decomp[2]='A'-1+(c&0x1F);
  257.   decomp[3]=0;
  258.   printk("    Chip identification: %s%4.4Xn",
  259.  decomp, ld_le16((unsigned short *)(p.PPCData+2)));
  260.   break;
  261. default:
  262.   printk("    Small vendor item type 0x%2.2x, data (hex): ",
  263.  p.Type);
  264.   for(i=0; i<size-2; i++) printk("%2.2x ", p.PPCData[i]);
  265.   printk("n");
  266.   break;
  267. }
  268. #undef p
  269. }
  270. static void __init printsmallpacket(PnP_TAG_PACKET * pkt, int size) {
  271. static const unsigned char * intlevel[] = {"high", "low"};
  272. static const unsigned char * intsense[] = {"edge", "level"};
  273. switch (tag_small_item_name(pkt->S1_Pack.Tag)) {
  274. case PnPVersion:
  275.   printk("    PnPversion 0x%x.%xn", 
  276.  pkt->S1_Pack.Version[0], /* How to interpret version ? */
  277.  pkt->S1_Pack.Version[1]);
  278.   break;
  279. // case Logicaldevice:
  280.   break;
  281. // case CompatibleDevice:
  282.   break;
  283. case IRQFormat:
  284. #define p pkt->S4_Pack
  285.   printk("    IRQ Mask 0x%4.4x, %s %s sensitiven", 
  286.  ld_le16((unsigned short *)p.IRQMask),
  287.  intlevel[(size>3) ? !(p.IRQInfo&0x05) : 0],
  288.  intsense[(size>3) ? !(p.IRQInfo&0x03) : 0]);
  289. #undef p
  290.   break;
  291. case DMAFormat:
  292. #define p pkt->S5_Pack
  293.   printk("    DMA channel mask 0x%2.2x, info 0x%2.2xn",
  294.  p.DMAMask, p.DMAInfo);
  295. #undef p
  296.   break;
  297. case StartDepFunc:
  298.   printk("Start dependent function:n");
  299.   break;
  300. case EndDepFunc:
  301.   printk("End dependent functionn");
  302.   break;
  303. case IOPort:
  304. #define p pkt->S8_Pack
  305.   printk("    Variable (%d decoded bits) I/O portn"
  306.  "      from 0x%4.4x to 0x%4.4x, alignment %d, %d portsn",
  307.  p.IOInfo&ISAAddr16bit?16:10,
  308.  ld_le16((unsigned short *)p.RangeMin),
  309.    ld_le16((unsigned short *)p.RangeMax),
  310.  p.IOAlign, p.IONum); 
  311. #undef p
  312.   break;
  313. case FixedIOPort:
  314. #define p pkt->S9_Pack
  315.   printk("    Fixed (10 decoded bits) I/O port from %3.3x to %3.3xn",
  316.  (p.Range[1]<<8)|p.Range[0],
  317.  ((p.Range[1]<<8)|p.Range[0])+p.IONum-1);
  318. #undef p  
  319.   break;
  320. case Res1:
  321. case Res2:
  322. case Res3:
  323.   printk("    Undefined packet type %d!n", 
  324.  tag_small_item_name(pkt->S1_Pack.Tag));
  325.   break;
  326. case SmallVendorItem:
  327.   printsmallvendor(pkt,size);
  328.   break;
  329. default:
  330.   printk("    Type 0x2.2x%d, size=%dn", 
  331.  pkt->S1_Pack.Tag, size);    
  332.   break;
  333. }
  334. }
  335. static void __init printlargevendor(PnP_TAG_PACKET * pkt, int size) {
  336. static const unsigned char * addrtype[] = {"I/O", "Memory", "System"};
  337. static const unsigned char * inttype[] = {"8259", "MPIC", "RS6k BUID %d"};
  338. static const unsigned char * convtype[] = {"Bus Memory", "Bus I/O", "DMA"};
  339. static const unsigned char * transtype[] = {"direct", "mapped", "direct-store segment"};
  340. static const unsigned char * L2type[] = {"WriteThru", "CopyBack"};
  341. static const unsigned char * L2assoc[] = {"DirectMapped", "2-way set"};
  342. int i;
  343. char tmpstr[30], *t;
  344. #define p pkt->L4_Pack.L4_Data.L4_PPCPack
  345. switch(p.Type) {
  346. case 2:
  347.   printk("    %d K %s %s L2 cache, %d/%d bytes line/sector sizen",
  348.  ld_le32((unsigned int *)p.PPCData),
  349.  L2type[p.PPCData[10]-1],
  350.  L2assoc[p.PPCData[4]-1],
  351.  ld_le16((unsigned short *)p.PPCData+3),
  352.  ld_le16((unsigned short *)p.PPCData+4));
  353.   break;
  354. case 3:
  355.   printk("    PCI Bridge parametersn"
  356.  "      ConfigBaseAddress %0xn"
  357.  "      ConfigBaseData %0xn"
  358.  "      Bus number %dn",
  359.  ld_le32((unsigned int *)p.PPCData),
  360.  ld_le32((unsigned int *)(p.PPCData+8)),
  361.  p.PPCData[16]);
  362.   for(i=20; i<size-4; i+=12) {
  363.    int j, first;
  364.    if(p.PPCData[i]) printk("      PCI Slot %d", p.PPCData[i]);
  365. else printk ("      Integrated PCI device");
  366. for(j=0, first=1, t=tmpstr; j<4; j++) {
  367. int line=ld_le16((unsigned short *)(p.PPCData+i+4)+j);
  368. if(line!=0xffff){
  369.         if(first) first=0; else *t++='/';
  370. *t++='A'+j;
  371. }
  372. }
  373. *t='';
  374. printk(" DevFunc 0x%x interrupt line(s) %s routed to",
  375.        p.PPCData[i+1],tmpstr);
  376. sprintf(tmpstr,
  377. inttype[p.PPCData[i+2]-1],
  378. p.PPCData[i+3]);
  379. printk(" %s line(s) ",
  380.        tmpstr);
  381. for(j=0, first=1, t=tmpstr; j<4; j++) {
  382. int line=ld_le16((unsigned short *)(p.PPCData+i+4)+j);
  383. if(line!=0xffff){
  384. if(first) first=0; else *t++='/';
  385. t+=sprintf(t,"%d(%c)",
  386.    line&0x7fff,
  387.    line&0x8000?'E':'L');
  388. }
  389. }
  390. printk("%sn",tmpstr);
  391.   }
  392.   break;
  393. case 5:
  394.   printk("    Bridge address translation, %s decoding:n"
  395.  "      Processor  Bus        Size       Conversion Translationn"
  396.  "      0x%8.8x 0x%8.8x 0x%8.8x %s %sn",
  397.  p.PPCData[0]&1 ? "positive" : "subtractive",
  398.  ld_le32((unsigned int *)p.PPCData+1),
  399.  ld_le32((unsigned int *)p.PPCData+3),
  400.  ld_le32((unsigned int *)p.PPCData+5),
  401.  convtype[p.PPCData[2]-1],
  402.  transtype[p.PPCData[1]-1]);
  403.   break;
  404. case 6:
  405.   printk("    Bus speed %d Hz, %d slot(s)n",
  406.  ld_le32((unsigned int *)p.PPCData),
  407.  p.PPCData[4]);
  408.   break;
  409. case 7:
  410.   printk("    SCSI buses: %d, id(s):", p.PPCData[0]);
  411.   for(i=1; i<=p.PPCData[0]; i++) 
  412.     printk(" %d%c", p.PPCData[i], i==p.PPCData[0] ? 'n' : ',');
  413.   break;
  414. case 9:
  415.   printk("    %s address (%d bits), at 0x%x size 0x%x bytesn",
  416.  addrtype[p.PPCData[0]-1],
  417.  p.PPCData[1],
  418.  ld_le32((unsigned int *)(p.PPCData+4)),
  419.  ld_le32((unsigned int *)(p.PPCData+12)));
  420.   break;
  421. case 10:
  422.   sprintf(tmpstr,
  423.   inttype[p.PPCData[0]-1],
  424.   p.PPCData[1]);
  425.   printk("    ISA interrupts routed to %sn"
  426.  "      lines", 
  427.  tmpstr);
  428.   for(i=0; i<16; i++) {
  429.    int line=ld_le16((unsigned short *)p.PPCData+i+1);
  430. if (line!=0xffff) printk(" %d(IRQ%d)", line, i); 
  431.   }
  432.   printk("n");
  433.   break;
  434. default:
  435.   printk("    Large vendor item type 0x%2.2xn      Data (hex):",
  436.  p.Type);
  437.   for(i=0; i<size-4; i++) printk(" %2.2x", p.PPCData[i]);
  438.   printk("n");
  439. #undef p
  440. }
  441. }
  442. static void __init printlargepacket(PnP_TAG_PACKET * pkt, int size) {
  443. switch (tag_large_item_name(pkt->S1_Pack.Tag)) {
  444. case LargeVendorItem:
  445.   printlargevendor(pkt, size);
  446.   break;
  447. default:
  448.   printk("    Type 0x2.2x%d, size=%dn", 
  449.  pkt->S1_Pack.Tag, size);    
  450.   break;
  451. }
  452. }
  453. static void __init printpackets(PnP_TAG_PACKET * pkt, const char * cat) {
  454. if (pkt->S1_Pack.Tag== END_TAG) {
  455. printk("  No packets describing %s resources.n", cat);
  456. return;
  457. }
  458. printk(  "  Packets describing %s resources:n",cat);
  459. do {
  460. int size;
  461. if (tag_type(pkt->S1_Pack.Tag)) {
  462.    size= 3 +
  463.   pkt->L1_Pack.Count0 + 
  464.   pkt->L1_Pack.Count1*256;
  465. printlargepacket(pkt, size);
  466. } else {
  467. size=tag_small_count(pkt->S1_Pack.Tag)+1;
  468. printsmallpacket(pkt, size);
  469. }
  470. (unsigned char *) pkt+=size;
  471. } while (pkt->S1_Pack.Tag != END_TAG);
  472. }
  473. void __init print_residual_device_info(void)
  474. {
  475. int i;
  476. PPC_DEVICE *dev;
  477. #define did dev->DeviceId
  478. /* make sure we have residual data first */
  479. if ( res->ResidualLength == 0 )
  480. return;
  481. printk("Residual: %ld devicesn", res->ActualNumDevices);
  482. for ( i = 0;
  483.       i < res->ActualNumDevices ;
  484.       i++)
  485. {
  486.    char decomp[4], sn[20];
  487. const char * s;
  488. dev = &res->Devices[i];
  489. s = PnP_INTERFACE_STR(did.BaseType, did.SubType, 
  490.       did.Interface);
  491. if(!s) {
  492. sprintf(sn, "interface %d", did.Interface);
  493. s=sn;
  494. }
  495. if ( did.BusId & PCIDEVICE ) 
  496.   printk("PCI Device, Bus %d, DevFunc 0x%x:",
  497.  dev->BusAccess.PCIAccess.BusNumber,
  498.  dev->BusAccess.PCIAccess.DevFuncNumber);
  499.         if ( did.BusId & PNPISADEVICE ) printk("PNPISA Device:");
  500. if ( did.BusId & ISADEVICE ) 
  501.   printk("ISA Device, Slot %d, LogicalDev %d:",
  502.  dev->BusAccess.ISAAccess.SlotNumber,
  503.  dev->BusAccess.ISAAccess.LogicalDevNumber);
  504. if ( did.BusId & EISADEVICE ) printk("EISA Device:");
  505. if ( did.BusId & PROCESSORDEVICE ) 
  506.   printk("ProcBus Device, Bus %d, BUID %d: ",
  507.  dev->BusAccess.ProcBusAccess.BusNumber,
  508.  dev->BusAccess.ProcBusAccess.BUID);
  509. if ( did.BusId & PCMCIADEVICE ) printk("PCMCIA ");
  510. if ( did.BusId & VMEDEVICE ) printk("VME ");
  511. if ( did.BusId & MCADEVICE ) printk("MCA ");
  512. if ( did.BusId & MXDEVICE ) printk("MX ");
  513. /* Decompress first 3 chars */
  514. decomp[0]='A'-1+((did.DevId>>26)&0x1F);
  515. decomp[1]='A'-1+((did.DevId>>21)&0x1F);
  516. decomp[2]='A'-1+((did.DevId>>16)&0x1F);
  517. decomp[3]=0;
  518. printk(" %s%4.4lX, %s, %s, %sn", 
  519.        decomp, did.DevId&0xffff,
  520.        PnP_BASE_TYPES[did.BaseType],
  521.        PnP_SUB_TYPE_STR(did.BaseType,did.SubType),
  522.        s);
  523. if ( dev->AllocatedOffset )
  524. printpackets( (union _PnP_TAG_PACKET *)
  525.       &res->DevicePnPHeap[dev->AllocatedOffset],
  526.       "allocated");
  527. if ( dev->PossibleOffset )
  528. printpackets( (union _PnP_TAG_PACKET *)
  529.       &res->DevicePnPHeap[dev->PossibleOffset],
  530.       "possible");
  531. if ( dev->CompatibleOffset )
  532. printpackets( (union _PnP_TAG_PACKET *)
  533.       &res->DevicePnPHeap[dev->CompatibleOffset],
  534.       "compatible");
  535. }
  536. }
  537. #if 0
  538. static void __init printVPD(void) {
  539. #define vpd res->VitalProductData
  540. int ps=vpd.PageSize, i, j;
  541. static const char* Usage[]={
  542.   "FirmwareStack",  "FirmwareHeap",  "FirmwareCode", "BootImage",
  543.   "Free", "Unpopulated", "ISAAddr", "PCIConfig",
  544.   "IOMemory", "SystemIO", "SystemRegs", "PCIAddr", 
  545.   "UnPopSystemRom", "SystemROM", "ResumeBlock", "Other" 
  546. };
  547. static const unsigned char *FWMan[]={
  548.   "IBM", "Motorola", "FirmWorks", "Bull"
  549. };
  550. static const unsigned char *FWFlags[]={
  551.   "Conventional", "OpenFirmware", "Diagnostics", "LowDebug",
  552.   "MultiBoot", "LowClient", "Hex41", "FAT", 
  553.   "ISO9660", "SCSI_ID_Override", "Tape_Boot", "FW_Boot_Path"
  554. };
  555. static const unsigned char *ESM[]={
  556.   "Port92", "PCIConfigA8", "FF001030", "????????"
  557. };
  558. static const unsigned char *SIOM[]={
  559.   "Port850", "????????", "PCIConfigA8", "????????"
  560. };
  561. printk("Model: %sn",vpd.PrintableModel);
  562. printk("Serial: %sn", vpd.Serial);
  563. printk("FirmwareSupplier: %sn", FWMan[vpd.FirmwareSupplier]);
  564. printk("FirmwareFlags:");
  565. for(j=0; j<12; j++) {
  566.    if (vpd.FirmwareSupports & (1<<j)) {
  567. printk(" %s%c", FWFlags[j], 
  568.        vpd.FirmwareSupports&(-2<<j) ? ',' : 'n');
  569. }
  570. }
  571. printk("NVRamSize: %ldn", vpd.NvramSize);
  572. printk("SIMMslots: %ldn", vpd.NumSIMMSlots);
  573. printk("EndianSwitchMethod: %sn", 
  574.        ESM[vpd.EndianSwitchMethod>2 ? 2 : vpd.EndianSwitchMethod]);
  575. printk("SpreadIOMethod: %sn", 
  576.        SIOM[vpd.SpreadIOMethod>3 ? 3 : vpd.SpreadIOMethod]);
  577. printk("Processor/Bus frequencies (Hz): %ld/%ldn",
  578.        vpd.ProcessorHz, vpd.ProcessorBusHz);
  579. printk("Time Base Divisor: %ldn", vpd.TimeBaseDivisor);
  580. printk("WordWidth, PageSize: %ld, %dn", vpd.WordWidth, ps);
  581. printk("Cache sector size, Lock granularity: %ld, %ldn",
  582.        vpd.CoherenceBlockSize, vpd.GranuleSize);
  583. for (i=0; i<res->ActualNumMemSegs; i++) {
  584. int mask=res->Segs[i].Usage, first, j;
  585. printk("%8.8lx-%8.8lx ", 
  586.        res->Segs[i].BasePage*ps,
  587.        (res->Segs[i].PageCount+res->Segs[i].BasePage)*ps-1);
  588. for(j=15, first=1; j>=0; j--) {
  589. if (mask&(1<<j)) {
  590. if (first) first=0;
  591. else printk(", ");
  592. printk("%s", Usage[j]);
  593. }
  594. }
  595. printk("n");
  596. }
  597. }
  598. /*
  599.  * Spit out some info about residual data
  600.  */
  601. void print_residual_device_info(void)
  602. {
  603. int i;
  604. union _PnP_TAG_PACKET *pkt;
  605. PPC_DEVICE *dev;
  606. #define did dev->DeviceId
  607. /* make sure we have residual data first */
  608. if ( res->ResidualLength == 0 )
  609. return;
  610. printk("Residual: %ld devicesn", res->ActualNumDevices);
  611. for ( i = 0;
  612.       i < res->ActualNumDevices ;
  613.       i++)
  614. {
  615. dev = &res->Devices[i];
  616. /*
  617.  * pci devices
  618.  */
  619. if ( did.BusId & PCIDEVICE )
  620. {
  621. printk("PCI Device:");
  622. /* unknown vendor */
  623. if ( !strncmp( "Unknown", pci_strvendor(did.DevId>>16), 7) )
  624. printk(" id %08lx types %d/%d", did.DevId,
  625.        did.BaseType, did.SubType);
  626. /* known vendor */
  627. else
  628. printk(" %s %s",
  629.        pci_strvendor(did.DevId>>16),
  630.        pci_strdev(did.DevId>>16,
  631.   did.DevId&0xffff)
  632. );
  633. if ( did.BusId & PNPISADEVICE )
  634. {
  635. printk(" pnp:");
  636. /* get pnp info on the device */
  637. pkt = (union _PnP_TAG_PACKET *)
  638. &res->DevicePnPHeap[dev->AllocatedOffset];
  639. for (; pkt->S1_Pack.Tag != DF_END_TAG;
  640.      pkt++ )
  641. {
  642. if ( (pkt->S1_Pack.Tag == S4_Packet) ||
  643.      (pkt->S1_Pack.Tag == S4_Packet_flags) )
  644. printk(" irq %02x%02x",
  645.        pkt->S4_Pack.IRQMask[0],
  646.        pkt->S4_Pack.IRQMask[1]);
  647. }
  648. }
  649. printk("n");
  650. continue;
  651. }
  652. /*
  653.  * isa devices
  654.  */
  655. if ( did.BusId & ISADEVICE )
  656. {
  657. printk("ISA Device: basetype: %d subtype: %d",
  658.        did.BaseType, did.SubType);
  659. printk("n");
  660. continue;
  661. }
  662. /*
  663.  * eisa devices
  664.  */
  665. if ( did.BusId & EISADEVICE )
  666. {
  667. printk("EISA Device: basetype: %d subtype: %d",
  668.        did.BaseType, did.SubType);
  669. printk("n");
  670. continue;
  671. }
  672. /*
  673.  * proc bus devices
  674.  */
  675. if ( did.BusId & PROCESSORDEVICE )
  676. {
  677. printk("ProcBus Device: basetype: %d subtype: %d",
  678.        did.BaseType, did.SubType);
  679. printk("n");
  680. continue;
  681. }
  682. /*
  683.  * pcmcia devices
  684.  */
  685. if ( did.BusId & PCMCIADEVICE )
  686. {
  687. printk("PCMCIA Device: basetype: %d subtype: %d",
  688.        did.BaseType, did.SubType);
  689. printk("n");
  690. continue;
  691. }
  692. printk("Unknown bus access device: busid %lxn",
  693.        did.BusId);
  694. }
  695. }
  696. #endif
  697. /* Returns the device index in the residual data, 
  698.    any of the search items may be set as -1 for wildcard,
  699.    DevID number field (second halfword) is big endian ! 
  700.    Examples:
  701.    - search for the Interrupt controller (8259 type), 2 methods:
  702.      1) i8259 = residual_find_device(~0, 
  703.                                      NULL, 
  704.      SystemPeripheral, 
  705.      ProgrammableInterruptController, 
  706.      ISA_PIC, 
  707.      0);
  708.      2) i8259 = residual_find_device(~0, "PNP0000", -1, -1, -1, 0) 
  709.    - search for the first two serial devices, whatever their type)
  710.      iserial1 = residual_find_device(~0,NULL,
  711.                                      CommunicationsDevice,
  712.      RS232Device,
  713.      -1, 0)
  714.      iserial2 = residual_find_device(~0,NULL,
  715.                                      CommunicationsDevice,
  716.      RS232Device,
  717.      -1, 1)
  718.    - but search for typical COM1 and COM2 is not easy due to the
  719.      fact that the interface may be anything and the name "PNP0500" or 
  720.      "PNP0501". Quite bad. 
  721. */
  722. /* devid are easier to uncompress than to compress, so to minimize bloat
  723. in this rarely used area we unencode and compare */
  724. /* in residual data number is big endian in the device table and
  725. little endian in the heap, so we use two parameters to avoid writing
  726. two very similar functions */
  727. static int __init same_DevID(unsigned short vendor,
  728.        unsigned short Number,
  729.        char * str) 
  730. {
  731. static unsigned const char hexdigit[]="0123456789ABCDEF";
  732. if (strlen(str)!=7) return 0;
  733. if ( ( ((vendor>>10)&0x1f)+'A'-1 == str[0])  &&
  734.      ( ((vendor>>5)&0x1f)+'A'-1 == str[1])   &&
  735.      ( (vendor&0x1f)+'A'-1 == str[2])        &&
  736.      (hexdigit[(Number>>12)&0x0f] == str[3]) &&
  737.      (hexdigit[(Number>>8)&0x0f] == str[4])  &&
  738.      (hexdigit[(Number>>4)&0x0f] == str[5])  &&
  739.      (hexdigit[Number&0x0f] == str[6]) ) return 1;
  740. return 0;
  741. }
  742. PPC_DEVICE __init *residual_find_device(unsigned long BusMask,
  743.  unsigned char * DevID,
  744.  int BaseType,
  745.  int SubType,
  746.  int Interface,
  747.  int n)
  748. {
  749. int i;
  750. if ( !res->ResidualLength ) return NULL;
  751. for (i=0; i<res->ActualNumDevices; i++) {
  752. #define Dev res->Devices[i].DeviceId
  753. if ( (Dev.BusId&BusMask)                                  &&
  754.      (BaseType==-1 || Dev.BaseType==BaseType)             &&
  755.      (SubType==-1 || Dev.SubType==SubType)                &&
  756.      (Interface==-1 || Dev.Interface==Interface)          &&
  757.      (DevID==NULL || same_DevID((Dev.DevId>>16)&0xffff,
  758. Dev.DevId&0xffff, DevID)) &&
  759.      !(n--) ) return res->Devices+i;
  760. #undef Dev
  761. }
  762. return 0;
  763. }
  764. PPC_DEVICE __init *residual_find_device_id(unsigned long BusMask,
  765.  unsigned short DevID,
  766.  int BaseType,
  767.  int SubType,
  768.  int Interface,
  769.  int n)
  770. {
  771. int i;
  772. if ( !res->ResidualLength ) return NULL;
  773. for (i=0; i<res->ActualNumDevices; i++) {
  774. #define Dev res->Devices[i].DeviceId
  775. if ( (Dev.BusId&BusMask)                                  &&
  776.      (BaseType==-1 || Dev.BaseType==BaseType)             &&
  777.      (SubType==-1 || Dev.SubType==SubType)                &&
  778.      (Interface==-1 || Dev.Interface==Interface)          &&
  779.      (DevID==0xffff || (Dev.DevId&0xffff) == DevID)   &&
  780.      !(n--) ) return res->Devices+i;
  781. #undef Dev
  782. }
  783. return 0;
  784. }
  785. PnP_TAG_PACKET *PnP_find_packet(unsigned char *p,
  786. unsigned packet_tag,
  787. int n)
  788. {
  789. unsigned mask, masked_tag, size;
  790. if(!p) return 0;
  791. if (tag_type(packet_tag)) mask=0xff; else mask=0xF8;
  792. masked_tag = packet_tag&mask;
  793. for(; *p != END_TAG; p+=size) {
  794. if ((*p & mask) == masked_tag && !(n--)) 
  795. return (PnP_TAG_PACKET *) p;
  796. if (tag_type(*p))
  797. size=ld_le16((unsigned short *)(p+1))+3;
  798. else 
  799. size=tag_small_count(*p)+1;
  800. }
  801. return 0; /* not found */
  802. }
  803. PnP_TAG_PACKET __init *PnP_find_small_vendor_packet(unsigned char *p,
  804.      unsigned packet_type,
  805.      int n)
  806. {
  807. int next=0;
  808. while (p) {
  809. p = (unsigned char *) PnP_find_packet(p, 0x70, next);
  810. if (p && p[1]==packet_type && !(n--)) 
  811. return (PnP_TAG_PACKET *) p;
  812. next = 1;
  813. };
  814. return 0; /* not found */
  815. }
  816. PnP_TAG_PACKET __init *PnP_find_large_vendor_packet(unsigned char *p,
  817.    unsigned packet_type,
  818.    int n)
  819. {
  820. int next=0;
  821. while (p) {
  822. p = (unsigned char *) PnP_find_packet(p, 0x84, next);
  823. if (p && p[3]==packet_type && !(n--)) 
  824. return (PnP_TAG_PACKET *) p;
  825. next = 1;
  826. };
  827. return 0; /* not found */
  828. }