📄 residual.c
字号:
default: printk(" Large vendor item type 0x%2.2x\n Data (hex):", p.Type); for(i=0; i<size-4; i++) printk(" %2.2x", p.PPCData[i]); printk("\n");#undef p }}static void __init printlargepacket(PnP_TAG_PACKET * pkt, int size) { switch (tag_large_item_name(pkt->S1_Pack.Tag)) { case LargeVendorItem: printlargevendor(pkt, size); break; default: printk(" Type 0x2.2x%d, size=%d\n", pkt->S1_Pack.Tag, size); break; }}static void __init printpackets(PnP_TAG_PACKET * pkt, const char * cat){ if (pkt->S1_Pack.Tag== END_TAG) { printk(" No packets describing %s resources.\n", cat); return; } printk( " Packets describing %s resources:\n",cat); do { int size; if (tag_type(pkt->S1_Pack.Tag)) { size= 3 + pkt->L1_Pack.Count0 + pkt->L1_Pack.Count1*256; printlargepacket(pkt, size); } else { size=tag_small_count(pkt->S1_Pack.Tag)+1; printsmallpacket(pkt, size); } pkt = (PnP_TAG_PACKET *)((unsigned char *) pkt + size); } while (pkt->S1_Pack.Tag != END_TAG);}void __init print_residual_device_info(void){ int i; PPC_DEVICE *dev;#define did dev->DeviceId /* make sure we have residual data first */ if ( res->ResidualLength == 0 ) return; printk("Residual: %ld devices\n", res->ActualNumDevices); for ( i = 0; i < res->ActualNumDevices ; i++) { char decomp[4], sn[20]; const char * s; dev = &res->Devices[i]; s = PnP_INTERFACE_STR(did.BaseType, did.SubType, did.Interface); if(!s) { sprintf(sn, "interface %d", did.Interface); s=sn; } if ( did.BusId & PCIDEVICE ) printk("PCI Device, Bus %d, DevFunc 0x%x:", dev->BusAccess.PCIAccess.BusNumber, dev->BusAccess.PCIAccess.DevFuncNumber); if ( did.BusId & PNPISADEVICE ) printk("PNPISA Device:"); if ( did.BusId & ISADEVICE ) printk("ISA Device, Slot %d, LogicalDev %d:", dev->BusAccess.ISAAccess.SlotNumber, dev->BusAccess.ISAAccess.LogicalDevNumber); if ( did.BusId & EISADEVICE ) printk("EISA Device:"); if ( did.BusId & PROCESSORDEVICE ) printk("ProcBus Device, Bus %d, BUID %d: ", dev->BusAccess.ProcBusAccess.BusNumber, dev->BusAccess.ProcBusAccess.BUID); if ( did.BusId & PCMCIADEVICE ) printk("PCMCIA "); if ( did.BusId & VMEDEVICE ) printk("VME "); if ( did.BusId & MCADEVICE ) printk("MCA "); if ( did.BusId & MXDEVICE ) printk("MX "); /* Decompress first 3 chars */ decomp[0]='A'-1+((did.DevId>>26)&0x1F); decomp[1]='A'-1+((did.DevId>>21)&0x1F); decomp[2]='A'-1+((did.DevId>>16)&0x1F); decomp[3]=0; printk(" %s%4.4lX, %s, %s, %s\n", decomp, did.DevId&0xffff, PnP_BASE_TYPES[did.BaseType], PnP_SUB_TYPE_STR(did.BaseType,did.SubType), s); if ( dev->AllocatedOffset ) printpackets( (union _PnP_TAG_PACKET *) &res->DevicePnPHeap[dev->AllocatedOffset], "allocated"); if ( dev->PossibleOffset ) printpackets( (union _PnP_TAG_PACKET *) &res->DevicePnPHeap[dev->PossibleOffset], "possible"); if ( dev->CompatibleOffset ) printpackets( (union _PnP_TAG_PACKET *) &res->DevicePnPHeap[dev->CompatibleOffset], "compatible"); }}#if 0static void __init printVPD(void) {#define vpd res->VitalProductData int ps=vpd.PageSize, i, j; static const char* Usage[]={ "FirmwareStack", "FirmwareHeap", "FirmwareCode", "BootImage", "Free", "Unpopulated", "ISAAddr", "PCIConfig", "IOMemory", "SystemIO", "SystemRegs", "PCIAddr", "UnPopSystemRom", "SystemROM", "ResumeBlock", "Other" }; static const unsigned char *FWMan[]={ "IBM", "Motorola", "FirmWorks", "Bull" }; static const unsigned char *FWFlags[]={ "Conventional", "OpenFirmware", "Diagnostics", "LowDebug", "MultiBoot", "LowClient", "Hex41", "FAT", "ISO9660", "SCSI_ID_Override", "Tape_Boot", "FW_Boot_Path" }; static const unsigned char *ESM[]={ "Port92", "PCIConfigA8", "FF001030", "????????" }; static const unsigned char *SIOM[]={ "Port850", "????????", "PCIConfigA8", "????????" }; printk("Model: %s\n",vpd.PrintableModel); printk("Serial: %s\n", vpd.Serial); printk("FirmwareSupplier: %s\n", FWMan[vpd.FirmwareSupplier]); printk("FirmwareFlags:"); for(j=0; j<12; j++) { if (vpd.FirmwareSupports & (1<<j)) { printk(" %s%c", FWFlags[j], vpd.FirmwareSupports&(-2<<j) ? ',' : '\n'); } } printk("NVRamSize: %ld\n", vpd.NvramSize); printk("SIMMslots: %ld\n", vpd.NumSIMMSlots); printk("EndianSwitchMethod: %s\n", ESM[vpd.EndianSwitchMethod>2 ? 2 : vpd.EndianSwitchMethod]); printk("SpreadIOMethod: %s\n", SIOM[vpd.SpreadIOMethod>3 ? 3 : vpd.SpreadIOMethod]); printk("Processor/Bus frequencies (Hz): %ld/%ld\n", vpd.ProcessorHz, vpd.ProcessorBusHz); printk("Time Base Divisor: %ld\n", vpd.TimeBaseDivisor); printk("WordWidth, PageSize: %ld, %d\n", vpd.WordWidth, ps); printk("Cache sector size, Lock granularity: %ld, %ld\n", vpd.CoherenceBlockSize, vpd.GranuleSize); for (i=0; i<res->ActualNumMemSegs; i++) { int mask=res->Segs[i].Usage, first, j; printk("%8.8lx-%8.8lx ", res->Segs[i].BasePage*ps, (res->Segs[i].PageCount+res->Segs[i].BasePage)*ps-1); for(j=15, first=1; j>=0; j--) { if (mask&(1<<j)) { if (first) first=0; else printk(", "); printk("%s", Usage[j]); } } printk("\n"); }}/* * Spit out some info about residual data */void print_residual_device_info(void){ int i; union _PnP_TAG_PACKET *pkt; PPC_DEVICE *dev;#define did dev->DeviceId /* make sure we have residual data first */ if ( res->ResidualLength == 0 ) return; printk("Residual: %ld devices\n", res->ActualNumDevices); for ( i = 0; i < res->ActualNumDevices ; i++) { dev = &res->Devices[i]; /* * pci devices */ if ( did.BusId & PCIDEVICE ) { printk("PCI Device:"); /* unknown vendor */ if ( !strncmp( "Unknown", pci_strvendor(did.DevId>>16), 7) ) printk(" id %08lx types %d/%d", did.DevId, did.BaseType, did.SubType); /* known vendor */ else printk(" %s %s", pci_strvendor(did.DevId>>16), pci_strdev(did.DevId>>16, did.DevId&0xffff) ); if ( did.BusId & PNPISADEVICE ) { printk(" pnp:"); /* get pnp info on the device */ pkt = (union _PnP_TAG_PACKET *) &res->DevicePnPHeap[dev->AllocatedOffset]; for (; pkt->S1_Pack.Tag != DF_END_TAG; pkt++ ) { if ( (pkt->S1_Pack.Tag == S4_Packet) || (pkt->S1_Pack.Tag == S4_Packet_flags) ) printk(" irq %02x%02x", pkt->S4_Pack.IRQMask[0], pkt->S4_Pack.IRQMask[1]); } } printk("\n"); continue; } /* * isa devices */ if ( did.BusId & ISADEVICE ) { printk("ISA Device: basetype: %d subtype: %d", did.BaseType, did.SubType); printk("\n"); continue; } /* * eisa devices */ if ( did.BusId & EISADEVICE ) { printk("EISA Device: basetype: %d subtype: %d", did.BaseType, did.SubType); printk("\n"); continue; } /* * proc bus devices */ if ( did.BusId & PROCESSORDEVICE ) { printk("ProcBus Device: basetype: %d subtype: %d", did.BaseType, did.SubType); printk("\n"); continue; } /* * pcmcia devices */ if ( did.BusId & PCMCIADEVICE ) { printk("PCMCIA Device: basetype: %d subtype: %d", did.BaseType, did.SubType); printk("\n"); continue; } printk("Unknown bus access device: busid %lx\n", did.BusId); }}#endif/* Returns the device index in the residual data, any of the search items may be set as -1 for wildcard, DevID number field (second halfword) is big endian ! Examples: - search for the Interrupt controller (8259 type), 2 methods: 1) i8259 = residual_find_device(~0, NULL, SystemPeripheral, ProgrammableInterruptController, ISA_PIC, 0); 2) i8259 = residual_find_device(~0, "PNP0000", -1, -1, -1, 0) - search for the first two serial devices, whatever their type) iserial1 = residual_find_device(~0,NULL, CommunicationsDevice, RS232Device, -1, 0) iserial2 = residual_find_device(~0,NULL, CommunicationsDevice, RS232Device, -1, 1) - but search for typical COM1 and COM2 is not easy due to the fact that the interface may be anything and the name "PNP0500" or "PNP0501". Quite bad.*//* devid are easier to uncompress than to compress, so to minimize bloatin this rarely used area we unencode and compare *//* in residual data number is big endian in the device table andlittle endian in the heap, so we use two parameters to avoid writingtwo very similar functions */static int __init same_DevID(unsigned short vendor, unsigned short Number, char * str){ static unsigned const char hexdigit[]="0123456789ABCDEF"; if (strlen(str)!=7) return 0; if ( ( ((vendor>>10)&0x1f)+'A'-1 == str[0]) && ( ((vendor>>5)&0x1f)+'A'-1 == str[1]) && ( (vendor&0x1f)+'A'-1 == str[2]) && (hexdigit[(Number>>12)&0x0f] == str[3]) && (hexdigit[(Number>>8)&0x0f] == str[4]) && (hexdigit[(Number>>4)&0x0f] == str[5]) && (hexdigit[Number&0x0f] == str[6]) ) return 1; return 0;}PPC_DEVICE __init *residual_find_device(unsigned long BusMask, unsigned char * DevID, int BaseType, int SubType, int Interface, int n){ int i; if ( !res->ResidualLength ) return NULL; for (i=0; i<res->ActualNumDevices; i++) {#define Dev res->Devices[i].DeviceId if ( (Dev.BusId&BusMask) && (BaseType==-1 || Dev.BaseType==BaseType) && (SubType==-1 || Dev.SubType==SubType) && (Interface==-1 || Dev.Interface==Interface) && (DevID==NULL || same_DevID((Dev.DevId>>16)&0xffff, Dev.DevId&0xffff, DevID)) && !(n--) ) return res->Devices+i;#undef Dev } return NULL;}PPC_DEVICE __init *residual_find_device_id(unsigned long BusMask, unsigned short DevID, int BaseType, int SubType, int Interface, int n){ int i; if ( !res->ResidualLength ) return NULL; for (i=0; i<res->ActualNumDevices; i++) {#define Dev res->Devices[i].DeviceId if ( (Dev.BusId&BusMask) && (BaseType==-1 || Dev.BaseType==BaseType) && (SubType==-1 || Dev.SubType==SubType) && (Interface==-1 || Dev.Interface==Interface) && (DevID==0xffff || (Dev.DevId&0xffff) == DevID) && !(n--) ) return res->Devices+i;#undef Dev } return NULL;}PnP_TAG_PACKET *PnP_find_packet(unsigned char *p, unsigned packet_tag, int n){ unsigned mask, masked_tag, size; if(!p) return NULL; if (tag_type(packet_tag)) mask=0xff; else mask=0xF8; masked_tag = packet_tag&mask; for(; *p != END_TAG; p+=size) { if ((*p & mask) == masked_tag && !(n--)) return (PnP_TAG_PACKET *) p; if (tag_type(*p)) size=ld_le16((unsigned short *)(p+1))+3; else size=tag_small_count(*p)+1; } return NULL; /* not found */}PnP_TAG_PACKET __init *PnP_find_small_vendor_packet(unsigned char *p, unsigned packet_type, int n){ int next=0; while (p) { p = (unsigned char *) PnP_find_packet(p, 0x70, next); if (p && p[1]==packet_type && !(n--)) return (PnP_TAG_PACKET *) p; next = 1; }; return NULL; /* not found */}PnP_TAG_PACKET __init *PnP_find_large_vendor_packet(unsigned char *p, unsigned packet_type, int n){ int next=0; while (p) { p = (unsigned char *) PnP_find_packet(p, 0x84, next); if (p && p[3]==packet_type && !(n--)) return (PnP_TAG_PACKET *) p; next = 1; }; return NULL; /* not found */}#ifdef CONFIG_PROC_PREPRESIDUALstatic int proc_prep_residual_read(char * buf, char ** start, off_t off, int count, int *eof, void *data){ int n; n = res->ResidualLength - off; if (n < 0) { *eof = 1; n = 0; } else { if (n > count) n = count; else *eof = 1; memcpy(buf, (char *)res + off, n); *start = buf; } return n;}int __initproc_prep_residual_init(void){ if (res->ResidualLength) create_proc_read_entry("residual", S_IRUGO, NULL, proc_prep_residual_read, NULL); return 0;}__initcall(proc_prep_residual_init);#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -