Merge ../linux-2.6 by hand
[sfrench/cifs-2.6.git] / arch / ppc / platforms / residual.c
1 /*
2  * Code to deal with the PReP residual data.
3  *
4  * Written by: Cort Dougan (cort@cs.nmt.edu)
5  * Improved _greatly_ and rewritten by Gabriel Paubert (paubert@iram.es)
6  *
7  *  This file is based on the following documentation:
8  *
9  *      IBM Power Personal Systems Architecture
10  *      Residual Data
11  *      Document Number: PPS-AR-FW0001
12  *
13  *  This file is subject to the terms and conditions of the GNU General Public
14  *  License.  See the file COPYING in the main directory of this archive
15  *  for more details.
16  *
17  */
18
19 #include <linux/string.h>
20 #include <asm/residual.h>
21 #include <asm/pnp.h>
22 #include <asm/byteorder.h>
23
24 #include <linux/errno.h>
25 #include <linux/sched.h>
26 #include <linux/kernel.h>
27 #include <linux/mm.h>
28 #include <linux/stddef.h>
29 #include <linux/unistd.h>
30 #include <linux/ptrace.h>
31 #include <linux/slab.h>
32 #include <linux/user.h>
33 #include <linux/a.out.h>
34 #include <linux/tty.h>
35 #include <linux/major.h>
36 #include <linux/interrupt.h>
37 #include <linux/reboot.h>
38 #include <linux/init.h>
39 #include <linux/ioport.h>
40 #include <linux/pci.h>
41 #include <linux/ide.h>
42
43 #include <asm/sections.h>
44 #include <asm/mmu.h>
45 #include <asm/io.h>
46 #include <asm/pgtable.h>
47 #include <asm/ide.h>
48
49
50 unsigned char __res[sizeof(RESIDUAL)] = {0,};
51 RESIDUAL *res = (RESIDUAL *)&__res;
52
53 char * PnP_BASE_TYPES[] __initdata = {
54   "Reserved",
55   "MassStorageDevice",
56   "NetworkInterfaceController",
57   "DisplayController",
58   "MultimediaController",
59   "MemoryController",
60   "BridgeController",
61   "CommunicationsDevice",
62   "SystemPeripheral",
63   "InputDevice",
64   "ServiceProcessor"
65   };
66
67 /* Device Sub Type Codes */
68
69 unsigned char * PnP_SUB_TYPES[] __initdata = {
70   "\001\000SCSIController",
71   "\001\001IDEController",
72   "\001\002FloppyController",
73   "\001\003IPIController",
74   "\001\200OtherMassStorageController",
75   "\002\000EthernetController",
76   "\002\001TokenRingController",
77   "\002\002FDDIController",
78   "\002\0x80OtherNetworkController",
79   "\003\000VGAController",
80   "\003\001SVGAController",
81   "\003\002XGAController",
82   "\003\200OtherDisplayController",
83   "\004\000VideoController",
84   "\004\001AudioController",
85   "\004\200OtherMultimediaController",
86   "\005\000RAM",
87   "\005\001FLASH",
88   "\005\200OtherMemoryDevice",
89   "\006\000HostProcessorBridge",
90   "\006\001ISABridge",
91   "\006\002EISABridge",
92   "\006\003MicroChannelBridge",
93   "\006\004PCIBridge",
94   "\006\005PCMCIABridge",
95   "\006\006VMEBridge",
96   "\006\200OtherBridgeDevice",
97   "\007\000RS232Device",
98   "\007\001ATCompatibleParallelPort",
99   "\007\200OtherCommunicationsDevice",
100   "\010\000ProgrammableInterruptController",
101   "\010\001DMAController",
102   "\010\002SystemTimer",
103   "\010\003RealTimeClock",
104   "\010\004L2Cache",
105   "\010\005NVRAM",
106   "\010\006PowerManagement",
107   "\010\007CMOS",
108   "\010\010OperatorPanel",
109   "\010\011ServiceProcessorClass1",
110   "\010\012ServiceProcessorClass2",
111   "\010\013ServiceProcessorClass3",
112   "\010\014GraphicAssist",
113   "\010\017SystemPlanar",
114   "\010\200OtherSystemPeripheral",
115   "\011\000KeyboardController",
116   "\011\001Digitizer",
117   "\011\002MouseController",
118   "\011\003TabletController",
119   "\011\0x80OtherInputController",
120   "\012\000GeneralMemoryController",
121   NULL
122 };
123
124 /* Device Interface Type Codes */
125
126 unsigned char * PnP_INTERFACES[] __initdata = {
127   "\000\000\000General",
128   "\001\000\000GeneralSCSI",
129   "\001\001\000GeneralIDE",
130   "\001\001\001ATACompatible",
131
132   "\001\002\000GeneralFloppy",
133   "\001\002\001Compatible765",
134   "\001\002\002NS398_Floppy",         /* NS Super I/O wired to use index
135                                          register at port 398 and data
136                                          register at port 399               */
137   "\001\002\003NS26E_Floppy",         /* Ports 26E and 26F                  */
138   "\001\002\004NS15C_Floppy",         /* Ports 15C and 15D                  */
139   "\001\002\005NS2E_Floppy",          /* Ports 2E and 2F                    */
140   "\001\002\006CHRP_Floppy",          /* CHRP Floppy in PR*P system         */
141
142   "\001\003\000GeneralIPI",
143
144   "\002\000\000GeneralEther",
145   "\002\001\000GeneralToken",
146   "\002\002\000GeneralFDDI",
147
148   "\003\000\000GeneralVGA",
149   "\003\001\000GeneralSVGA",
150   "\003\002\000GeneralXGA",
151
152   "\004\000\000GeneralVideo",
153   "\004\001\000GeneralAudio",
154   "\004\001\001CS4232Audio",            /* CS 4232 Plug 'n Play Configured    */
155
156   "\005\000\000GeneralRAM",
157   /* This one is obviously wrong ! */
158   "\005\000\000PCIMemoryController",    /* PCI Config Method                  */
159   "\005\000\001RS6KMemoryController",   /* RS6K Config Method                 */
160   "\005\001\000GeneralFLASH",
161
162   "\006\000\000GeneralHostBridge",
163   "\006\001\000GeneralISABridge",
164   "\006\002\000GeneralEISABridge",
165   "\006\003\000GeneralMCABridge",
166   /* GeneralPCIBridge = 0, */
167   "\006\004\000PCIBridgeDirect",
168   "\006\004\001PCIBridgeIndirect",
169   "\006\004\002PCIBridgeRS6K",
170   "\006\005\000GeneralPCMCIABridge",
171   "\006\006\000GeneralVMEBridge",
172
173   "\007\000\000GeneralRS232",
174   "\007\000\001COMx",
175   "\007\000\002Compatible16450",
176   "\007\000\003Compatible16550",
177   "\007\000\004NS398SerPort",         /* NS Super I/O wired to use index
178                                          register at port 398 and data
179                                          register at port 399               */
180   "\007\000\005NS26ESerPort",         /* Ports 26E and 26F                  */
181   "\007\000\006NS15CSerPort",         /* Ports 15C and 15D                  */
182   "\007\000\007NS2ESerPort",          /* Ports 2E and 2F                    */
183
184   "\007\001\000GeneralParPort",
185   "\007\001\001LPTx",
186   "\007\001\002NS398ParPort",         /* NS Super I/O wired to use index
187                                          register at port 398 and data
188                                          register at port 399               */
189   "\007\001\003NS26EParPort",         /* Ports 26E and 26F                  */
190   "\007\001\004NS15CParPort",         /* Ports 15C and 15D                  */
191   "\007\001\005NS2EParPort",          /* Ports 2E and 2F                    */
192
193   "\010\000\000GeneralPIC",
194   "\010\000\001ISA_PIC",
195   "\010\000\002EISA_PIC",
196   "\010\000\003MPIC",
197   "\010\000\004RS6K_PIC",
198
199   "\010\001\000GeneralDMA",
200   "\010\001\001ISA_DMA",
201   "\010\001\002EISA_DMA",
202
203   "\010\002\000GeneralTimer",
204   "\010\002\001ISA_Timer",
205   "\010\002\002EISA_Timer",
206   "\010\003\000GeneralRTC",
207   "\010\003\001ISA_RTC",
208
209   "\010\004\001StoreThruOnly",
210   "\010\004\002StoreInEnabled",
211   "\010\004\003RS6KL2Cache",
212
213   "\010\005\000IndirectNVRAM",        /* Indirectly addressed               */
214   "\010\005\001DirectNVRAM",          /* Memory Mapped                      */
215   "\010\005\002IndirectNVRAM24",      /* Indirectly addressed - 24 bit      */
216
217   "\010\006\000GeneralPowerManagement",
218   "\010\006\001EPOWPowerManagement",
219   "\010\006\002PowerControl",         // d1378
220
221   "\010\007\000GeneralCMOS",
222
223   "\010\010\000GeneralOPPanel",
224   "\010\010\001HarddiskLight",
225   "\010\010\002CDROMLight",
226   "\010\010\003PowerLight",
227   "\010\010\004KeyLock",
228   "\010\010\005ANDisplay",            /* AlphaNumeric Display               */
229   "\010\010\006SystemStatusLED",      /* 3 digit 7 segment LED              */
230   "\010\010\007CHRP_SystemStatusLED", /* CHRP LEDs in PR*P system           */
231
232   "\010\011\000GeneralServiceProcessor",
233   "\010\012\000GeneralServiceProcessor",
234   "\010\013\000GeneralServiceProcessor",
235
236   "\010\014\001TransferData",
237   "\010\014\002IGMC32",
238   "\010\014\003IGMC64",
239
240   "\010\017\000GeneralSystemPlanar",   /* 10/5/95                            */
241   NULL
242   };
243
244 static const unsigned char __init *PnP_SUB_TYPE_STR(unsigned char BaseType,
245                                              unsigned char SubType) {
246         unsigned char ** s=PnP_SUB_TYPES;
247         while (*s && !((*s)[0]==BaseType
248                        && (*s)[1]==SubType)) s++;
249         if (*s) return *s+2;
250         else return("Unknown !");
251 };
252
253 static const unsigned char __init *PnP_INTERFACE_STR(unsigned char BaseType,
254                                               unsigned char SubType,
255                                               unsigned char Interface) {
256         unsigned char ** s=PnP_INTERFACES;
257         while (*s && !((*s)[0]==BaseType
258                        && (*s)[1]==SubType
259                        && (*s)[2]==Interface)) s++;
260         if (*s) return *s+3;
261         else return NULL;
262 };
263
264 static void __init printsmallvendor(PnP_TAG_PACKET *pkt, int size) {
265         int i, c;
266         char decomp[4];
267 #define p pkt->S14_Pack.S14_Data.S14_PPCPack
268         switch(p.Type) {
269         case 1:
270           /* Decompress first 3 chars */
271           c = *(unsigned short *)p.PPCData;
272           decomp[0]='A'-1+((c>>10)&0x1F);
273           decomp[1]='A'-1+((c>>5)&0x1F);
274           decomp[2]='A'-1+(c&0x1F);
275           decomp[3]=0;
276           printk("    Chip identification: %s%4.4X\n",
277                  decomp, ld_le16((unsigned short *)(p.PPCData+2)));
278           break;
279         default:
280           printk("    Small vendor item type 0x%2.2x, data (hex): ",
281                  p.Type);
282           for(i=0; i<size-2; i++) printk("%2.2x ", p.PPCData[i]);
283           printk("\n");
284           break;
285         }
286 #undef p
287 }
288
289 static void __init printsmallpacket(PnP_TAG_PACKET * pkt, int size) {
290         static const unsigned char * intlevel[] = {"high", "low"};
291         static const unsigned char * intsense[] = {"edge", "level"};
292
293         switch (tag_small_item_name(pkt->S1_Pack.Tag)) {
294         case PnPVersion:
295           printk("    PnPversion 0x%x.%x\n",
296                  pkt->S1_Pack.Version[0], /* How to interpret version ? */
297                  pkt->S1_Pack.Version[1]);
298           break;
299 //      case Logicaldevice:
300           break;
301 //      case CompatibleDevice:
302           break;
303         case IRQFormat:
304 #define p pkt->S4_Pack
305           printk("    IRQ Mask 0x%4.4x, %s %s sensitive\n",
306                  ld_le16((unsigned short *)p.IRQMask),
307                  intlevel[(size>3) ? !(p.IRQInfo&0x05) : 0],
308                  intsense[(size>3) ? !(p.IRQInfo&0x03) : 0]);
309 #undef p
310           break;
311         case DMAFormat:
312 #define p pkt->S5_Pack
313           printk("    DMA channel mask 0x%2.2x, info 0x%2.2x\n",
314                  p.DMAMask, p.DMAInfo);
315 #undef p
316           break;
317         case StartDepFunc:
318           printk("Start dependent function:\n");
319           break;
320         case EndDepFunc:
321           printk("End dependent function\n");
322           break;
323         case IOPort:
324 #define p pkt->S8_Pack
325           printk("    Variable (%d decoded bits) I/O port\n"
326                  "      from 0x%4.4x to 0x%4.4x, alignment %d, %d ports\n",
327                  p.IOInfo&ISAAddr16bit?16:10,
328                  ld_le16((unsigned short *)p.RangeMin),
329                  ld_le16((unsigned short *)p.RangeMax),
330                  p.IOAlign, p.IONum);
331 #undef p
332           break;
333         case FixedIOPort:
334 #define p pkt->S9_Pack
335           printk("    Fixed (10 decoded bits) I/O port from %3.3x to %3.3x\n",
336                  (p.Range[1]<<8)|p.Range[0],
337                  ((p.Range[1]<<8)|p.Range[0])+p.IONum-1);
338 #undef p
339           break;
340         case Res1:
341         case Res2:
342         case Res3:
343           printk("    Undefined packet type %d!\n",
344                  tag_small_item_name(pkt->S1_Pack.Tag));
345           break;
346         case SmallVendorItem:
347           printsmallvendor(pkt,size);
348           break;
349         default:
350           printk("    Type 0x2.2x%d, size=%d\n",
351                  pkt->S1_Pack.Tag, size);
352           break;
353         }
354 }
355
356 static void __init printlargevendor(PnP_TAG_PACKET * pkt, int size) {
357         static const unsigned char * addrtype[] = {"I/O", "Memory", "System"};
358         static const unsigned char * inttype[] = {"8259", "MPIC", "RS6k BUID %d"};
359         static const unsigned char * convtype[] = {"Bus Memory", "Bus I/O", "DMA"};
360         static const unsigned char * transtype[] = {"direct", "mapped", "direct-store segment"};
361         static const unsigned char * L2type[] = {"WriteThru", "CopyBack"};
362         static const unsigned char * L2assoc[] = {"DirectMapped", "2-way set"};
363
364         int i;
365         char tmpstr[30], *t;
366 #define p pkt->L4_Pack.L4_Data.L4_PPCPack
367         switch(p.Type) {
368         case 2:
369           printk("    %d K %s %s L2 cache, %d/%d bytes line/sector size\n",
370                  ld_le32((unsigned int *)p.PPCData),
371                  L2type[p.PPCData[10]-1],
372                  L2assoc[p.PPCData[4]-1],
373                  ld_le16((unsigned short *)p.PPCData+3),
374                  ld_le16((unsigned short *)p.PPCData+4));
375           break;
376         case 3:
377           printk("    PCI Bridge parameters\n"
378                  "      ConfigBaseAddress %0x\n"
379                  "      ConfigBaseData %0x\n"
380                  "      Bus number %d\n",
381                  ld_le32((unsigned int *)p.PPCData),
382                  ld_le32((unsigned int *)(p.PPCData+8)),
383                  p.PPCData[16]);
384           for(i=20; i<size-4; i+=12) {
385                 int j, first;
386                 if(p.PPCData[i]) printk("      PCI Slot %d", p.PPCData[i]);
387                 else printk ("      Integrated PCI device");
388                 for(j=0, first=1, t=tmpstr; j<4; j++) {
389                         int line=ld_le16((unsigned short *)(p.PPCData+i+4)+j);
390                         if(line!=0xffff){
391                                 if(first) first=0; else *t++='/';
392                                 *t++='A'+j;
393                         }
394                 }
395                 *t='\0';
396                 printk(" DevFunc 0x%x interrupt line(s) %s routed to",
397                        p.PPCData[i+1],tmpstr);
398                 sprintf(tmpstr,
399                         inttype[p.PPCData[i+2]-1],
400                         p.PPCData[i+3]);
401                 printk(" %s line(s) ",
402                        tmpstr);
403                 for(j=0, first=1, t=tmpstr; j<4; j++) {
404                         int line=ld_le16((unsigned short *)(p.PPCData+i+4)+j);
405                         if(line!=0xffff){
406                                 if(first) first=0; else *t++='/';
407                                 t+=sprintf(t,"%d(%c)",
408                                            line&0x7fff,
409                                            line&0x8000?'E':'L');
410                         }
411                 }
412                 printk("%s\n",tmpstr);
413           }
414           break;
415         case 5:
416           printk("    Bridge address translation, %s decoding:\n"
417                  "      Processor  Bus        Size       Conversion Translation\n"
418                  "      0x%8.8x 0x%8.8x 0x%8.8x %s %s\n",
419                  p.PPCData[0]&1 ? "positive" : "subtractive",
420                  ld_le32((unsigned int *)p.PPCData+1),
421                  ld_le32((unsigned int *)p.PPCData+3),
422                  ld_le32((unsigned int *)p.PPCData+5),
423                  convtype[p.PPCData[2]-1],
424                  transtype[p.PPCData[1]-1]);
425           break;
426         case 6:
427           printk("    Bus speed %d Hz, %d slot(s)\n",
428                  ld_le32((unsigned int *)p.PPCData),
429                  p.PPCData[4]);
430           break;
431         case 7:
432           printk("    SCSI buses: %d, id(s):", p.PPCData[0]);
433           for(i=1; i<=p.PPCData[0]; i++)
434             printk(" %d%c", p.PPCData[i], i==p.PPCData[0] ? '\n' : ',');
435           break;
436         case 9:
437           printk("    %s address (%d bits), at 0x%x size 0x%x bytes\n",
438                  addrtype[p.PPCData[0]-1],
439                  p.PPCData[1],
440                  ld_le32((unsigned int *)(p.PPCData+4)),
441                  ld_le32((unsigned int *)(p.PPCData+12)));
442           break;
443         case 10:
444           sprintf(tmpstr,
445                   inttype[p.PPCData[0]-1],
446                   p.PPCData[1]);
447
448           printk("    ISA interrupts routed to %s\n"
449                  "      lines",
450                  tmpstr);
451           for(i=0; i<16; i++) {
452                 int line=ld_le16((unsigned short *)p.PPCData+i+1);
453                 if (line!=0xffff) printk(" %d(IRQ%d)", line, i);
454           }
455           printk("\n");
456           break;
457         default:
458           printk("    Large vendor item type 0x%2.2x\n      Data (hex):",
459                  p.Type);
460           for(i=0; i<size-4; i++) printk(" %2.2x", p.PPCData[i]);
461           printk("\n");
462 #undef p
463         }
464 }
465
466 static void __init printlargepacket(PnP_TAG_PACKET * pkt, int size) {
467         switch (tag_large_item_name(pkt->S1_Pack.Tag)) {
468         case LargeVendorItem:
469           printlargevendor(pkt, size);
470           break;
471         default:
472           printk("    Type 0x2.2x%d, size=%d\n",
473                  pkt->S1_Pack.Tag, size);
474           break;
475         }
476 }
477
478 static void __init printpackets(PnP_TAG_PACKET * pkt, const char * cat)
479 {
480         if (pkt->S1_Pack.Tag== END_TAG) {
481                 printk("  No packets describing %s resources.\n", cat);
482                 return;
483         }
484         printk(  "  Packets describing %s resources:\n",cat);
485         do {
486                 int size;
487                 if (tag_type(pkt->S1_Pack.Tag)) {
488                         size= 3 +
489                           pkt->L1_Pack.Count0 +
490                           pkt->L1_Pack.Count1*256;
491                         printlargepacket(pkt, size);
492                 } else {
493                         size=tag_small_count(pkt->S1_Pack.Tag)+1;
494                         printsmallpacket(pkt, size);
495                 }
496                 pkt = (PnP_TAG_PACKET *)((unsigned char *) pkt + size);
497         } while (pkt->S1_Pack.Tag != END_TAG);
498 }
499
500 void __init print_residual_device_info(void)
501 {
502         int i;
503         PPC_DEVICE *dev;
504 #define did dev->DeviceId
505
506         /* make sure we have residual data first */
507         if (!have_residual_data)
508                 return;
509
510         printk("Residual: %ld devices\n", res->ActualNumDevices);
511         for ( i = 0;
512               i < res->ActualNumDevices ;
513               i++)
514         {
515                 char decomp[4], sn[20];
516                 const char * s;
517                 dev = &res->Devices[i];
518                 s = PnP_INTERFACE_STR(did.BaseType, did.SubType,
519                                       did.Interface);
520                 if(!s) {
521                         sprintf(sn, "interface %d", did.Interface);
522                         s=sn;
523                 }
524                 if ( did.BusId & PCIDEVICE )
525                   printk("PCI Device, Bus %d, DevFunc 0x%x:",
526                          dev->BusAccess.PCIAccess.BusNumber,
527                          dev->BusAccess.PCIAccess.DevFuncNumber);
528                 if ( did.BusId & PNPISADEVICE ) printk("PNPISA Device:");
529                 if ( did.BusId & ISADEVICE )
530                   printk("ISA Device, Slot %d, LogicalDev %d:",
531                          dev->BusAccess.ISAAccess.SlotNumber,
532                          dev->BusAccess.ISAAccess.LogicalDevNumber);
533                 if ( did.BusId & EISADEVICE ) printk("EISA Device:");
534                 if ( did.BusId & PROCESSORDEVICE )
535                   printk("ProcBus Device, Bus %d, BUID %d: ",
536                          dev->BusAccess.ProcBusAccess.BusNumber,
537                          dev->BusAccess.ProcBusAccess.BUID);
538                 if ( did.BusId & PCMCIADEVICE ) printk("PCMCIA ");
539                 if ( did.BusId & VMEDEVICE ) printk("VME ");
540                 if ( did.BusId & MCADEVICE ) printk("MCA ");
541                 if ( did.BusId & MXDEVICE ) printk("MX ");
542                 /* Decompress first 3 chars */
543                 decomp[0]='A'-1+((did.DevId>>26)&0x1F);
544                 decomp[1]='A'-1+((did.DevId>>21)&0x1F);
545                 decomp[2]='A'-1+((did.DevId>>16)&0x1F);
546                 decomp[3]=0;
547                 printk(" %s%4.4lX, %s, %s, %s\n",
548                        decomp, did.DevId&0xffff,
549                        PnP_BASE_TYPES[did.BaseType],
550                        PnP_SUB_TYPE_STR(did.BaseType,did.SubType),
551                        s);
552                 if ( dev->AllocatedOffset )
553                         printpackets( (union _PnP_TAG_PACKET *)
554                                       &res->DevicePnPHeap[dev->AllocatedOffset],
555                                       "allocated");
556                 if ( dev->PossibleOffset )
557                         printpackets( (union _PnP_TAG_PACKET *)
558                                       &res->DevicePnPHeap[dev->PossibleOffset],
559                                       "possible");
560                 if ( dev->CompatibleOffset )
561                         printpackets( (union _PnP_TAG_PACKET *)
562                                       &res->DevicePnPHeap[dev->CompatibleOffset],
563                                       "compatible");
564         }
565 }
566
567
568 #if 0
569 static void __init printVPD(void) {
570 #define vpd res->VitalProductData
571         int ps=vpd.PageSize, i, j;
572         static const char* Usage[]={
573           "FirmwareStack",  "FirmwareHeap",  "FirmwareCode", "BootImage",
574           "Free", "Unpopulated", "ISAAddr", "PCIConfig",
575           "IOMemory", "SystemIO", "SystemRegs", "PCIAddr",
576           "UnPopSystemRom", "SystemROM", "ResumeBlock", "Other"
577         };
578         static const unsigned char *FWMan[]={
579           "IBM", "Motorola", "FirmWorks", "Bull"
580         };
581         static const unsigned char *FWFlags[]={
582           "Conventional", "OpenFirmware", "Diagnostics", "LowDebug",
583           "MultiBoot", "LowClient", "Hex41", "FAT",
584           "ISO9660", "SCSI_ID_Override", "Tape_Boot", "FW_Boot_Path"
585         };
586         static const unsigned char *ESM[]={
587           "Port92", "PCIConfigA8", "FF001030", "????????"
588         };
589         static const unsigned char *SIOM[]={
590           "Port850", "????????", "PCIConfigA8", "????????"
591         };
592
593         printk("Model: %s\n",vpd.PrintableModel);
594         printk("Serial: %s\n", vpd.Serial);
595         printk("FirmwareSupplier: %s\n", FWMan[vpd.FirmwareSupplier]);
596         printk("FirmwareFlags:");
597         for(j=0; j<12; j++) {
598                 if (vpd.FirmwareSupports & (1<<j)) {
599                         printk(" %s%c", FWFlags[j],
600                                vpd.FirmwareSupports&(-2<<j) ? ',' : '\n');
601                 }
602         }
603         printk("NVRamSize: %ld\n", vpd.NvramSize);
604         printk("SIMMslots: %ld\n", vpd.NumSIMMSlots);
605         printk("EndianSwitchMethod: %s\n",
606                ESM[vpd.EndianSwitchMethod>2 ? 2 : vpd.EndianSwitchMethod]);
607         printk("SpreadIOMethod: %s\n",
608                SIOM[vpd.SpreadIOMethod>3 ? 3 : vpd.SpreadIOMethod]);
609         printk("Processor/Bus frequencies (Hz): %ld/%ld\n",
610                vpd.ProcessorHz, vpd.ProcessorBusHz);
611         printk("Time Base Divisor: %ld\n", vpd.TimeBaseDivisor);
612         printk("WordWidth, PageSize: %ld, %d\n", vpd.WordWidth, ps);
613         printk("Cache sector size, Lock granularity: %ld, %ld\n",
614                vpd.CoherenceBlockSize, vpd.GranuleSize);
615         for (i=0; i<res->ActualNumMemSegs; i++) {
616                 int mask=res->Segs[i].Usage, first, j;
617                 printk("%8.8lx-%8.8lx ",
618                        res->Segs[i].BasePage*ps,
619                        (res->Segs[i].PageCount+res->Segs[i].BasePage)*ps-1);
620                 for(j=15, first=1; j>=0; j--) {
621                         if (mask&(1<<j)) {
622                                 if (first) first=0;
623                                 else printk(", ");
624                                 printk("%s", Usage[j]);
625                         }
626                 }
627                 printk("\n");
628         }
629 }
630
631 /*
632  * Spit out some info about residual data
633  */
634 void print_residual_device_info(void)
635 {
636         int i;
637         union _PnP_TAG_PACKET *pkt;
638         PPC_DEVICE *dev;
639 #define did dev->DeviceId
640
641         /* make sure we have residual data first */
642         if (!have_residual_data)
643                 return;
644         printk("Residual: %ld devices\n", res->ActualNumDevices);
645         for ( i = 0;
646               i < res->ActualNumDevices ;
647               i++)
648         {
649                 dev = &res->Devices[i];
650                 /*
651                  * pci devices
652                  */
653                 if ( did.BusId & PCIDEVICE )
654                 {
655                         printk("PCI Device:");
656                         /* unknown vendor */
657                         if ( !strncmp( "Unknown", pci_strvendor(did.DevId>>16), 7) )
658                                 printk(" id %08lx types %d/%d", did.DevId,
659                                        did.BaseType, did.SubType);
660                         /* known vendor */
661                         else
662                                 printk(" %s %s",
663                                        pci_strvendor(did.DevId>>16),
664                                        pci_strdev(did.DevId>>16,
665                                                   did.DevId&0xffff)
666                                         );
667
668                         if ( did.BusId & PNPISADEVICE )
669                         {
670                                 printk(" pnp:");
671                                 /* get pnp info on the device */
672                                 pkt = (union _PnP_TAG_PACKET *)
673                                         &res->DevicePnPHeap[dev->AllocatedOffset];
674                                 for (; pkt->S1_Pack.Tag != DF_END_TAG;
675                                      pkt++ )
676                                 {
677                                         if ( (pkt->S1_Pack.Tag == S4_Packet) ||
678                                              (pkt->S1_Pack.Tag == S4_Packet_flags) )
679                                                 printk(" irq %02x%02x",
680                                                        pkt->S4_Pack.IRQMask[0],
681                                                        pkt->S4_Pack.IRQMask[1]);
682                                 }
683                         }
684                         printk("\n");
685                         continue;
686                 }
687                 /*
688                  * isa devices
689                  */
690                 if ( did.BusId & ISADEVICE )
691                 {
692                         printk("ISA Device: basetype: %d subtype: %d",
693                                did.BaseType, did.SubType);
694                         printk("\n");
695                         continue;
696                 }
697                 /*
698                  * eisa devices
699                  */
700                 if ( did.BusId & EISADEVICE )
701                 {
702                         printk("EISA Device: basetype: %d subtype: %d",
703                                did.BaseType, did.SubType);
704                         printk("\n");
705                         continue;
706                 }
707                 /*
708                  * proc bus devices
709                  */
710                 if ( did.BusId & PROCESSORDEVICE )
711                 {
712                         printk("ProcBus Device: basetype: %d subtype: %d",
713                                did.BaseType, did.SubType);
714                         printk("\n");
715                         continue;
716                 }
717                 /*
718                  * pcmcia devices
719                  */
720                 if ( did.BusId & PCMCIADEVICE )
721                 {
722                         printk("PCMCIA Device: basetype: %d subtype: %d",
723                                did.BaseType, did.SubType);
724                         printk("\n");
725                         continue;
726                 }
727                 printk("Unknown bus access device: busid %lx\n",
728                        did.BusId);
729         }
730 }
731 #endif
732
733 /* Returns the device index in the residual data,
734    any of the search items may be set as -1 for wildcard,
735    DevID number field (second halfword) is big endian !
736
737    Examples:
738    - search for the Interrupt controller (8259 type), 2 methods:
739      1) i8259 = residual_find_device(~0,
740                                      NULL,
741                                      SystemPeripheral,
742                                      ProgrammableInterruptController,
743                                      ISA_PIC,
744                                      0);
745      2) i8259 = residual_find_device(~0, "PNP0000", -1, -1, -1, 0)
746
747    - search for the first two serial devices, whatever their type)
748      iserial1 = residual_find_device(~0,NULL,
749                                      CommunicationsDevice,
750                                      RS232Device,
751                                      -1, 0)
752      iserial2 = residual_find_device(~0,NULL,
753                                      CommunicationsDevice,
754                                      RS232Device,
755                                      -1, 1)
756    - but search for typical COM1 and COM2 is not easy due to the
757      fact that the interface may be anything and the name "PNP0500" or
758      "PNP0501". Quite bad.
759
760 */
761
762 /* devid are easier to uncompress than to compress, so to minimize bloat
763 in this rarely used area we unencode and compare */
764
765 /* in residual data number is big endian in the device table and
766 little endian in the heap, so we use two parameters to avoid writing
767 two very similar functions */
768
769 static int __init same_DevID(unsigned short vendor,
770                unsigned short Number,
771                char * str)
772 {
773         static unsigned const char hexdigit[]="0123456789ABCDEF";
774         if (strlen(str)!=7) return 0;
775         if ( ( ((vendor>>10)&0x1f)+'A'-1 == str[0])  &&
776              ( ((vendor>>5)&0x1f)+'A'-1 == str[1])   &&
777              ( (vendor&0x1f)+'A'-1 == str[2])        &&
778              (hexdigit[(Number>>12)&0x0f] == str[3]) &&
779              (hexdigit[(Number>>8)&0x0f] == str[4])  &&
780              (hexdigit[(Number>>4)&0x0f] == str[5])  &&
781              (hexdigit[Number&0x0f] == str[6]) ) return 1;
782         return 0;
783 }
784
785 PPC_DEVICE __init *residual_find_device(unsigned long BusMask,
786                          unsigned char * DevID,
787                          int BaseType,
788                          int SubType,
789                          int Interface,
790                          int n)
791 {
792         int i;
793         if (!have_residual_data) return NULL;
794         for (i=0; i<res->ActualNumDevices; i++) {
795 #define Dev res->Devices[i].DeviceId
796                 if ( (Dev.BusId&BusMask)                                  &&
797                      (BaseType==-1 || Dev.BaseType==BaseType)             &&
798                      (SubType==-1 || Dev.SubType==SubType)                &&
799                      (Interface==-1 || Dev.Interface==Interface)          &&
800                      (DevID==NULL || same_DevID((Dev.DevId>>16)&0xffff,
801                                                 Dev.DevId&0xffff, DevID)) &&
802                      !(n--) ) return res->Devices+i;
803 #undef Dev
804         }
805         return NULL;
806 }
807
808 PPC_DEVICE __init *residual_find_device_id(unsigned long BusMask,
809                          unsigned short DevID,
810                          int BaseType,
811                          int SubType,
812                          int Interface,
813                          int n)
814 {
815         int i;
816         if (!have_residual_data) return NULL;
817         for (i=0; i<res->ActualNumDevices; i++) {
818 #define Dev res->Devices[i].DeviceId
819                 if ( (Dev.BusId&BusMask)                                  &&
820                      (BaseType==-1 || Dev.BaseType==BaseType)             &&
821                      (SubType==-1 || Dev.SubType==SubType)                &&
822                      (Interface==-1 || Dev.Interface==Interface)          &&
823                      (DevID==0xffff || (Dev.DevId&0xffff) == DevID)       &&
824                      !(n--) ) return res->Devices+i;
825 #undef Dev
826         }
827         return NULL;
828 }
829
830 static int __init
831 residual_scan_pcibridge(PnP_TAG_PACKET * pkt, struct pci_dev *dev)
832 {
833         int irq = -1;
834
835 #define data pkt->L4_Pack.L4_Data.L4_PPCPack.PPCData
836         if (dev->bus->number == data[16]) {
837                 int i, size;
838
839                 size = 3 + ld_le16((u_short *) (&pkt->L4_Pack.Count0));
840                 for (i = 20; i < size - 4; i += 12) {
841                         unsigned char pin;
842                         int line_irq;
843
844                         if (dev->devfn != data[i + 1])
845                                 continue;
846
847                         pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
848                         if (pin) {
849                                 line_irq = ld_le16((unsigned short *)
850                                                 (&data[i + 4 + 2 * (pin - 1)]));
851                                 irq = (line_irq == 0xffff) ? 0
852                                                            : line_irq & 0x7fff;
853                         } else
854                                 irq = 0;
855
856                         break;
857                 }
858         }
859 #undef data
860
861         return irq;
862 }
863
864 int __init
865 residual_pcidev_irq(struct pci_dev *dev)
866 {
867         int i = 0;
868         int irq = -1;
869         PPC_DEVICE *bridge;
870
871         while ((bridge = residual_find_device
872                (-1, NULL, BridgeController, PCIBridge, -1, i++))) {
873
874                 PnP_TAG_PACKET *pkt;
875                 if (bridge->AllocatedOffset) {
876                         pkt = PnP_find_large_vendor_packet(res->DevicePnPHeap +
877                                            bridge->AllocatedOffset, 3, 0);
878                         if (!pkt)
879                                 continue;
880
881                         irq = residual_scan_pcibridge(pkt, dev);
882                         if (irq != -1)
883                                 break;
884                 }
885         }
886
887         return (irq < 0) ? 0 : irq;
888 }
889
890 void __init residual_irq_mask(char *irq_edge_mask_lo, char *irq_edge_mask_hi)
891 {
892         PPC_DEVICE *dev;
893         int i = 0;
894         unsigned short irq_mask = 0x000; /* default to edge */
895
896         while ((dev = residual_find_device(-1, NULL, -1, -1, -1, i++))) {
897                 PnP_TAG_PACKET *pkt;
898                 unsigned short mask;
899                 int size;
900                 int offset = dev->AllocatedOffset;
901
902                 if (!offset)
903                         continue;
904
905                 pkt = PnP_find_packet(res->DevicePnPHeap + offset,
906                                               IRQFormat, 0);
907                 if (!pkt)
908                         continue;
909
910                 size = tag_small_count(pkt->S1_Pack.Tag) + 1;
911                 mask = ld_le16((unsigned short *)pkt->S4_Pack.IRQMask);
912                 if (size > 3 && (pkt->S4_Pack.IRQInfo & 0x0c))
913                         irq_mask |= mask;
914         }
915
916         *irq_edge_mask_lo = irq_mask & 0xff;
917         *irq_edge_mask_hi = irq_mask >> 8;
918 }
919
920 unsigned int __init residual_isapic_addr(void)
921 {
922         PPC_DEVICE *isapic;
923         PnP_TAG_PACKET *pkt;
924         unsigned int addr;
925
926         isapic = residual_find_device(~0, NULL, SystemPeripheral,
927                                       ProgrammableInterruptController,
928                                       ISA_PIC, 0);
929         if (!isapic)
930                 goto unknown;
931
932         pkt = PnP_find_large_vendor_packet(res->DevicePnPHeap +
933                                                 isapic->AllocatedOffset, 9, 0);
934         if (!pkt)
935                 goto unknown;
936
937 #define p pkt->L4_Pack.L4_Data.L4_PPCPack
938         /* Must be 32-bit system address */
939         if (!((p.PPCData[0] == 3) && (p.PPCData[1] == 32)))
940                 goto unknown;
941
942         /* It doesn't seem to work where length != 1 (what can I say? :-/ ) */
943         if (ld_le32((unsigned int *)(p.PPCData + 12)) != 1)
944                 goto unknown;
945
946         addr = ld_le32((unsigned int *) (p.PPCData + 4));
947 #undef p
948         return addr;
949 unknown:
950         return 0;
951 }
952
953 PnP_TAG_PACKET *PnP_find_packet(unsigned char *p,
954                                 unsigned packet_tag,
955                                 int n)
956 {
957         unsigned mask, masked_tag, size;
958         if(!p) return NULL;
959         if (tag_type(packet_tag)) mask=0xff; else mask=0xF8;
960         masked_tag = packet_tag&mask;
961         for(; *p != END_TAG; p+=size) {
962                 if ((*p & mask) == masked_tag && !(n--))
963                         return (PnP_TAG_PACKET *) p;
964                 if (tag_type(*p))
965                         size=ld_le16((unsigned short *)(p+1))+3;
966                 else
967                         size=tag_small_count(*p)+1;
968         }
969         return NULL; /* not found */
970 }
971
972 PnP_TAG_PACKET __init *PnP_find_small_vendor_packet(unsigned char *p,
973                                              unsigned packet_type,
974                                              int n)
975 {
976         int next=0;
977         while (p) {
978                 p = (unsigned char *) PnP_find_packet(p, 0x70, next);
979                 if (p && p[1]==packet_type && !(n--))
980                         return (PnP_TAG_PACKET *) p;
981                 next = 1;
982         };
983         return NULL; /* not found */
984 }
985
986 PnP_TAG_PACKET __init *PnP_find_large_vendor_packet(unsigned char *p,
987                                            unsigned packet_type,
988                                            int n)
989 {
990         int next=0;
991         while (p) {
992                 p = (unsigned char *) PnP_find_packet(p, 0x84, next);
993                 if (p && p[3]==packet_type && !(n--))
994                         return (PnP_TAG_PACKET *) p;
995                 next = 1;
996         };
997         return NULL; /* not found */
998 }
999
1000 #ifdef CONFIG_PROC_PREPRESIDUAL
1001 static int proc_prep_residual_read(char * buf, char ** start, off_t off,
1002                 int count, int *eof, void *data)
1003 {
1004         int n;
1005
1006         n = res->ResidualLength - off;
1007         if (n < 0) {
1008                 *eof = 1;
1009                 n = 0;
1010         }
1011         else {
1012                 if (n > count)
1013                         n = count;
1014                 else
1015                         *eof = 1;
1016
1017                 memcpy(buf, (char *)res + off, n);
1018                 *start = buf;
1019         }
1020
1021         return n;
1022 }
1023
1024 int __init
1025 proc_prep_residual_init(void)
1026 {
1027         if (have_residual_data)
1028                 create_proc_read_entry("residual", S_IRUGO, NULL,
1029                                         proc_prep_residual_read, NULL);
1030         return 0;
1031 }
1032
1033 __initcall(proc_prep_residual_init);
1034 #endif