residual.c 28 KB

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