1 | /*␊ |
2 | * Copyright 2009 netkas␊ |
3 | */␊ |
4 | ␊ |
5 | #include "libsaio.h"␊ |
6 | #include "boot.h"␊ |
7 | #include "bootstruct.h"␊ |
8 | ␊ |
9 | #ifndef DEBUG_PCIROOT␊ |
10 | #define DEBUG_PCIROOT 0␊ |
11 | #endif␊ |
12 | ␊ |
13 | #if DEBUG_PCIROOT␊ |
14 | #define DBG(x...) printf(x)␊ |
15 | #else␊ |
16 | #define DBG(x...)␊ |
17 | #endif␊ |
18 | ␊ |
19 | static int rootuid = 10; //value means function wasnt ran yet␊ |
20 | ␊ |
21 | static unsigned int findrootuid(unsigned char * dsdt, int len)␊ |
22 | {␊ |
23 | ␉int i;␊ |
24 | ␉for (i=0; i<64 && i<len-5; i++) //not far than 64 symbols from pci root ␊ |
25 | ␉{␊ |
26 | ␉␉if(dsdt[i] == '_' && dsdt[i+1] == 'U' && dsdt[i+2] == 'I' && dsdt[i+3] == 'D' && dsdt[i+5] == 0x08)␊ |
27 | ␉␉{␊ |
28 | ␉␉␉return dsdt[i+4];␊ |
29 | ␉␉}␊ |
30 | ␉}␊ |
31 | ␉return 11;␊ |
32 | }␊ |
33 | ␊ |
34 | static unsigned int findpciroot(unsigned char * dsdt,int len)␊ |
35 | {␊ |
36 | ␉int i;␊ |
37 | ␊ |
38 | ␉for (i=0; i<len-4; i++) {␊ |
39 | ␉␉if(dsdt[i] == 'P' && dsdt[i+1] == 'C' && dsdt[i+2] == 'I' && (dsdt[i+3] == 0x08 || dsdt [i+4] == 0x08)) {␊ |
40 | ␉␉␉return findrootuid(dsdt+i, len-i);␊ |
41 | ␉␉}␊ |
42 | ␉}␊ |
43 | ␉return 10;␊ |
44 | }␊ |
45 | ␊ |
46 | int getPciRootUID(void)␊ |
47 | {␊ |
48 | ␉void *new_dsdt;␊ |
49 | ␉const char *dsdt_filename;␊ |
50 | ␉const char *val;␊ |
51 | ␉int fd;␊ |
52 | ␉int dsdt_uid;␊ |
53 | ␉int len,fsize;␊ |
54 | ␊ |
55 | ␉if (rootuid < 10) {␊ |
56 | ␉␉return rootuid;␊ |
57 | ␉}␊ |
58 | ␉rootuid = 0;␉/* default uid = 0 */␊ |
59 | ␊ |
60 | ␉if (getValueForKey(kPCIRootUID, &val, &len, &bootInfo->bootConfig)) {␊ |
61 | ␉␉if (isdigit(val[0])) {␊ |
62 | ␉␉␉rootuid = val[0] - '0';␊ |
63 | ␉␉}␊ |
64 | ␉␉goto out;␊ |
65 | ␉}␊ |
66 | #if 0␊ |
67 | ␉/* Chameleon compatibility */␊ |
68 | ␉if (getValueForKey("PciRoot", &val, &len, &bootInfo->bootConfig)) {␊ |
69 | ␉␉if (isdigit(val[0])) {␊ |
70 | ␉␉␉rootuid = val[0] - '0';␊ |
71 | ␉␉}␊ |
72 | ␉␉goto out;␊ |
73 | ␉}␊ |
74 | ␊ |
75 | ␉/* PCEFI compatibility */␊ |
76 | ␉if (getValueForKey("-pci0", &val, &len, &bootInfo->bootConfig)) {␊ |
77 | ␉␉rootuid = 0;␊ |
78 | ␉␉goto out;␊ |
79 | ␉}␊ |
80 | ␉if (getValueForKey("-pci1", &val, &len, &bootInfo->bootConfig)) {␊ |
81 | ␉␉rootuid = 1;␊ |
82 | ␉␉goto out;␊ |
83 | ␉}␊ |
84 | #endif␊ |
85 | ␉if (!getValueForKey(kDSDT, &dsdt_filename, &len, &bootInfo->bootConfig)) {␊ |
86 | ␉␉dsdt_filename="/Extra/DSDT.aml";␊ |
87 | ␉}␊ |
88 | ␊ |
89 | ␉if ((fd = open_bvdev("bt(0,0)", dsdt_filename, 0)) < 0) {␊ |
90 | ␉␉verbose("[WARNING] %s not found\n", dsdt_filename);␊ |
91 | ␉␉goto out;␊ |
92 | ␉}␊ |
93 | ␉fsize = file_size(fd);␊ |
94 | ␊ |
95 | ␉if ((new_dsdt = malloc(fsize)) == NULL) {␊ |
96 | ␉␉verbose("[ERROR] alloc DSDT memory failed\n");␊ |
97 | ␉␉close (fd);␊ |
98 | ␉␉goto out;␊ |
99 | ␉}␊ |
100 | ␉if (read (fd, new_dsdt, fsize) != fsize) {␊ |
101 | ␉␉verbose("[ERROR] read %s failed\n", dsdt_filename);␊ |
102 | ␉␉close (fd);␊ |
103 | ␉␉goto out;␊ |
104 | ␉}␊ |
105 | ␉close (fd);␊ |
106 | ␊ |
107 | ␉dsdt_uid = findpciroot(new_dsdt, fsize);␊ |
108 | ␉free(new_dsdt);␊ |
109 | ␊ |
110 | ␉if (dsdt_uid >= 0 && dsdt_uid <= 9) {␊ |
111 | ␉␉rootuid = dsdt_uid;␊ |
112 | ␉} else {␊ |
113 | ␉␉verbose("Could not determine PCI-Root-UID value from DSDT!\n");␊ |
114 | ␉}␊ |
115 | out:␊ |
116 | ␉verbose("Using PCI-Root-UID value %d\n", rootuid);␊ |
117 | ␉return rootuid;␊ |
118 | }␊ |
119 | |