residual.c 28 KB

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