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
50unsigned char __res[sizeof(RESIDUAL)] = {0,};
51RESIDUAL *res = (RESIDUAL *)&__res;
52
53char * 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
69unsigned 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
126unsigned 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
244static 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
253static 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
264static 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
289static 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
356static 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
466static 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
478static 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
500void __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
569/* Returns the device index in the residual data,
570   any of the search items may be set as -1 for wildcard,
571   DevID number field (second halfword) is big endian !
572
573   Examples:
574   - search for the Interrupt controller (8259 type), 2 methods:
575     1) i8259 = residual_find_device(~0,
576                                     NULL,
577				     SystemPeripheral,
578				     ProgrammableInterruptController,
579				     ISA_PIC,
580				     0);
581     2) i8259 = residual_find_device(~0, "PNP0000", -1, -1, -1, 0)
582
583   - search for the first two serial devices, whatever their type)
584     iserial1 = residual_find_device(~0,NULL,
585                                     CommunicationsDevice,
586				     RS232Device,
587				     -1, 0)
588     iserial2 = residual_find_device(~0,NULL,
589                                     CommunicationsDevice,
590				     RS232Device,
591				     -1, 1)
592   - but search for typical COM1 and COM2 is not easy due to the
593     fact that the interface may be anything and the name "PNP0500" or
594     "PNP0501". Quite bad.
595
596*/
597
598/* devid are easier to uncompress than to compress, so to minimize bloat
599in this rarely used area we unencode and compare */
600
601/* in residual data number is big endian in the device table and
602little endian in the heap, so we use two parameters to avoid writing
603two very similar functions */
604
605static int __init same_DevID(unsigned short vendor,
606	       unsigned short Number,
607	       char * str)
608{
609	static unsigned const char hexdigit[]="0123456789ABCDEF";
610	if (strlen(str)!=7) return 0;
611	if ( ( ((vendor>>10)&0x1f)+'A'-1 == str[0])  &&
612	     ( ((vendor>>5)&0x1f)+'A'-1 == str[1])   &&
613	     ( (vendor&0x1f)+'A'-1 == str[2])        &&
614	     (hexdigit[(Number>>12)&0x0f] == str[3]) &&
615	     (hexdigit[(Number>>8)&0x0f] == str[4])  &&
616	     (hexdigit[(Number>>4)&0x0f] == str[5])  &&
617	     (hexdigit[Number&0x0f] == str[6]) ) return 1;
618	return 0;
619}
620
621PPC_DEVICE __init *residual_find_device(unsigned long BusMask,
622			 unsigned char * DevID,
623			 int BaseType,
624			 int SubType,
625			 int Interface,
626			 int n)
627{
628	int i;
629	if (!have_residual_data) return NULL;
630	for (i=0; i<res->ActualNumDevices; i++) {
631#define Dev res->Devices[i].DeviceId
632		if ( (Dev.BusId&BusMask)                                  &&
633		     (BaseType==-1 || Dev.BaseType==BaseType)             &&
634		     (SubType==-1 || Dev.SubType==SubType)                &&
635		     (Interface==-1 || Dev.Interface==Interface)          &&
636		     (DevID==NULL || same_DevID((Dev.DevId>>16)&0xffff,
637						Dev.DevId&0xffff, DevID)) &&
638		     !(n--) ) return res->Devices+i;
639#undef Dev
640	}
641	return NULL;
642}
643
644PPC_DEVICE __init *residual_find_device_id(unsigned long BusMask,
645			 unsigned short DevID,
646			 int BaseType,
647			 int SubType,
648			 int Interface,
649			 int n)
650{
651	int i;
652	if (!have_residual_data) return NULL;
653	for (i=0; i<res->ActualNumDevices; i++) {
654#define Dev res->Devices[i].DeviceId
655		if ( (Dev.BusId&BusMask)                                  &&
656		     (BaseType==-1 || Dev.BaseType==BaseType)             &&
657		     (SubType==-1 || Dev.SubType==SubType)                &&
658		     (Interface==-1 || Dev.Interface==Interface)          &&
659		     (DevID==0xffff || (Dev.DevId&0xffff) == DevID)	  &&
660		     !(n--) ) return res->Devices+i;
661#undef Dev
662	}
663	return NULL;
664}
665
666static int __init
667residual_scan_pcibridge(PnP_TAG_PACKET * pkt, struct pci_dev *dev)
668{
669	int irq = -1;
670
671#define data pkt->L4_Pack.L4_Data.L4_PPCPack.PPCData
672	if (dev->bus->number == data[16]) {
673		int i, size;
674
675		size = 3 + ld_le16((u_short *) (&pkt->L4_Pack.Count0));
676		for (i = 20; i < size - 4; i += 12) {
677			unsigned char pin;
678			int line_irq;
679
680			if (dev->devfn != data[i + 1])
681				continue;
682
683			pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
684			if (pin) {
685				line_irq = ld_le16((unsigned short *)
686						(&data[i + 4 + 2 * (pin - 1)]));
687				irq = (line_irq == 0xffff) ? 0
688							   : line_irq & 0x7fff;
689			} else
690				irq = 0;
691
692			break;
693		}
694	}
695#undef data
696
697	return irq;
698}
699
700int __init
701residual_pcidev_irq(struct pci_dev *dev)
702{
703	int i = 0;
704	int irq = -1;
705	PPC_DEVICE *bridge;
706
707	while ((bridge = residual_find_device
708	       (-1, NULL, BridgeController, PCIBridge, -1, i++))) {
709
710		PnP_TAG_PACKET *pkt;
711		if (bridge->AllocatedOffset) {
712			pkt = PnP_find_large_vendor_packet(res->DevicePnPHeap +
713					   bridge->AllocatedOffset, 3, 0);
714			if (!pkt)
715				continue;
716
717			irq = residual_scan_pcibridge(pkt, dev);
718			if (irq != -1)
719				break;
720		}
721	}
722
723	return (irq < 0) ? 0 : irq;
724}
725
726void __init residual_irq_mask(char *irq_edge_mask_lo, char *irq_edge_mask_hi)
727{
728	PPC_DEVICE *dev;
729	int i = 0;
730	unsigned short irq_mask = 0x000; /* default to edge */
731
732	while ((dev = residual_find_device(-1, NULL, -1, -1, -1, i++))) {
733		PnP_TAG_PACKET *pkt;
734		unsigned short mask;
735		int size;
736		int offset = dev->AllocatedOffset;
737
738		if (!offset)
739			continue;
740
741		pkt = PnP_find_packet(res->DevicePnPHeap + offset,
742					      IRQFormat, 0);
743		if (!pkt)
744			continue;
745
746		size = tag_small_count(pkt->S1_Pack.Tag) + 1;
747		mask = ld_le16((unsigned short *)pkt->S4_Pack.IRQMask);
748		if (size > 3 && (pkt->S4_Pack.IRQInfo & 0x0c))
749			irq_mask |= mask;
750	}
751
752	*irq_edge_mask_lo = irq_mask & 0xff;
753	*irq_edge_mask_hi = irq_mask >> 8;
754}
755
756unsigned int __init residual_isapic_addr(void)
757{
758	PPC_DEVICE *isapic;
759	PnP_TAG_PACKET *pkt;
760	unsigned int addr;
761
762	isapic = residual_find_device(~0, NULL, SystemPeripheral,
763				      ProgrammableInterruptController,
764				      ISA_PIC, 0);
765	if (!isapic)
766		goto unknown;
767
768	pkt = PnP_find_large_vendor_packet(res->DevicePnPHeap +
769						isapic->AllocatedOffset, 9, 0);
770	if (!pkt)
771		goto unknown;
772
773#define p pkt->L4_Pack.L4_Data.L4_PPCPack
774	/* Must be 32-bit system address */
775	if (!((p.PPCData[0] == 3) && (p.PPCData[1] == 32)))
776		goto unknown;
777
778	/* It doesn't seem to work where length != 1 (what can I say? :-/ ) */
779	if (ld_le32((unsigned int *)(p.PPCData + 12)) != 1)
780		goto unknown;
781
782	addr = ld_le32((unsigned int *) (p.PPCData + 4));
783#undef p
784	return addr;
785unknown:
786	return 0;
787}
788
789PnP_TAG_PACKET *PnP_find_packet(unsigned char *p,
790				unsigned packet_tag,
791				int n)
792{
793	unsigned mask, masked_tag, size;
794	if(!p) return NULL;
795	if (tag_type(packet_tag)) mask=0xff; else mask=0xF8;
796	masked_tag = packet_tag&mask;
797	for(; *p != END_TAG; p+=size) {
798		if ((*p & mask) == masked_tag && !(n--))
799			return (PnP_TAG_PACKET *) p;
800		if (tag_type(*p))
801			size=ld_le16((unsigned short *)(p+1))+3;
802		else
803			size=tag_small_count(*p)+1;
804	}
805	return NULL; /* not found */
806}
807
808PnP_TAG_PACKET __init *PnP_find_small_vendor_packet(unsigned char *p,
809					     unsigned packet_type,
810					     int n)
811{
812	int next=0;
813	while (p) {
814		p = (unsigned char *) PnP_find_packet(p, 0x70, next);
815		if (p && p[1]==packet_type && !(n--))
816			return (PnP_TAG_PACKET *) p;
817		next = 1;
818	};
819	return NULL; /* not found */
820}
821
822PnP_TAG_PACKET __init *PnP_find_large_vendor_packet(unsigned char *p,
823					   unsigned packet_type,
824					   int n)
825{
826	int next=0;
827	while (p) {
828		p = (unsigned char *) PnP_find_packet(p, 0x84, next);
829		if (p && p[3]==packet_type && !(n--))
830			return (PnP_TAG_PACKET *) p;
831		next = 1;
832	};
833	return NULL; /* not found */
834}
835
836#ifdef CONFIG_PROC_PREPRESIDUAL
837static int proc_prep_residual_read(char * buf, char ** start, off_t off,
838		int count, int *eof, void *data)
839{
840	int n;
841
842	n = res->ResidualLength - off;
843	if (n < 0) {
844		*eof = 1;
845		n = 0;
846	}
847	else {
848		if (n > count)
849			n = count;
850		else
851			*eof = 1;
852
853		memcpy(buf, (char *)res + off, n);
854		*start = buf;
855	}
856
857	return n;
858}
859
860int __init
861proc_prep_residual_init(void)
862{
863	if (have_residual_data)
864		create_proc_read_entry("residual", S_IRUGO, NULL,
865					proc_prep_residual_read, NULL);
866	return 0;
867}
868
869__initcall(proc_prep_residual_init);
870#endif
871