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