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