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...) msglog(x)␊ |
17 | #endif␊ |
18 | ␊ |
19 | static int rootuid = 10; //value means function wasn't 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 | ␉char dsdt_dirSpec[256];␊ |
49 | ␉const char *val = NULL;␊ |
50 | ␉int len = 0;␊ |
51 | ␉const char *dsdt_filename = NULL;␊ |
52 | ␉//extern int search_and_get_acpi_fd(const char *, const char **);␊ |
53 | ␉//extern void *loadACPITable (const char *filename);␊ |
54 | ␊ |
55 | ␉if (rootuid < 10)␊ |
56 | ␉{␊ |
57 | ␉␉return rootuid;␊ |
58 | ␉}␊ |
59 | ␊ |
60 | ␉rootuid = 0;␉/* default _UID = 0 */␊ |
61 | ␊ |
62 | ␉if (getValueForKey(kPCIRootUID, &val, &len, &bootInfo->chameleonConfig) && len)␊ |
63 | ␉{␊ |
64 | ␉␉if (isdigit(val[0]))␊ |
65 | ␉␉{␊ |
66 | ␉␉␉rootuid = val[0] - '0';␊ |
67 | ␉␉}␊ |
68 | ␊ |
69 | ␉␉goto out;␊ |
70 | ␉}␊ |
71 | ␉/* Chameleon compatibility */␊ |
72 | ␉else if (getValueForKey("PciRoot", &val, &len, &bootInfo->chameleonConfig) && len)␊ |
73 | ␉{␊ |
74 | ␉␉if (isdigit(val[0]))␊ |
75 | ␉␉{␊ |
76 | ␉␉␉rootuid = val[0] - '0';␊ |
77 | ␉␉}␊ |
78 | ␊ |
79 | ␉␉goto out;␊ |
80 | ␉}␊ |
81 | ␉/* PCEFI compatibility */␊ |
82 | ␉else if (getValueForKey("-pci0", &val, &len, &bootInfo->chameleonConfig) && len)␊ |
83 | ␉{␊ |
84 | ␉␉rootuid = 0;␊ |
85 | ␉␉goto out;␊ |
86 | ␉}␊ |
87 | ␉else if (getValueForKey("-pci1", &val, &len, &bootInfo->chameleonConfig) && len)␊ |
88 | ␉{␊ |
89 | ␉␉rootuid = 1;␊ |
90 | ␉␉goto out;␊ |
91 | ␉}␊ |
92 | ␊ |
93 | ␉if (new_dsdt != NULL)␊ |
94 | ␉{␊ |
95 | ␉␉len = *(int *)(new_dsdt + 4);␊ |
96 | ␉␉verbose("PCIrootUID: custom DSDT already loaded @%08X, length=%d.\n", new_dsdt, len);␊ |
97 | ␉}␊ |
98 | ␉else␊ |
99 | ␉{␊ |
100 | ␉␉// Try using the file specified with the DSDT option␊ |
101 | ␉␉if (getValueForKey(kDSDT, &dsdt_filename, &len, &bootInfo->chameleonConfig) && len)␊ |
102 | ␉␉{␊ |
103 | ␉␉␉snprintf(dsdt_dirSpec, sizeof(dsdt_dirSpec), dsdt_filename);␊ |
104 | ␉␉}␊ |
105 | ␉␉else␊ |
106 | ␉␉{␊ |
107 | ␉␉␉sprintf(dsdt_dirSpec, "DSDT.aml");␊ |
108 | ␉␉}␊ |
109 | ␊ |
110 | ␉␉verbose("PCIrootUID: attempting to load custom DSDT...\n");␊ |
111 | ␉␉if ((new_dsdt = loadACPITable(dsdt_dirSpec)))␊ |
112 | ␉␉{␊ |
113 | ␉␉␉len = *(int *)(new_dsdt + 4);␊ |
114 | ␉␉␉verbose("PCIrootUID: custom DSDT loaded @%08X, length=%d\n", new_dsdt, len);␊ |
115 | ␉␉}␊ |
116 | ␉␉else␊ |
117 | ␉␉{␊ |
118 | ␉␉␉//verbose("PCIrootUID: custom DSDT not found!.\n");␊ |
119 | ␉␉}␊ |
120 | ␉}␊ |
121 | /*␊ |
122 | ␉// Try using the file specified with the DSDT option␊ |
123 | ␉if (getValueForKey(kDSDT, &dsdt_filename, &len, &bootInfo->chameleonConfig) && len)␊ |
124 | ␉{␊ |
125 | ␉␉snprintf(dsdt_dirSpec, sizeof(dsdt_dirSpec), dsdt_filename);␊ |
126 | ␉}␊ |
127 | ␉else␊ |
128 | ␉{␊ |
129 | ␉␉sprintf(dsdt_dirSpec, "DSDT.aml");␊ |
130 | ␉}␊ |
131 | ␊ |
132 | ␉DBG("PCIrootUID: trying file DSDT.aml... ");␊ |
133 | ␊ |
134 | ␉int fd = search_and_get_acpi_fd(dsdt_dirSpec, &dsdt_filename);␊ |
135 | ␊ |
136 | ␉// Check booting partition␊ |
137 | ␉if (fd<0)␊ |
138 | ␉{␉ ␊ |
139 | ␉␉DBG("PCIrootUID: file '%s' not found, using default value.\n", dsdt_filename);␊ |
140 | ␉␉rootuid = 0;␊ |
141 | ␉␉goto out;␊ |
142 | ␉}␊ |
143 | ␊ |
144 | ␉fsize = file_size(fd);␊ |
145 | ␊ |
146 | ␉if (!(new_dsdt = malloc(fsize)))␊ |
147 | ␉{␊ |
148 | ␉␉DBG("PCIrootUID: ERROR: allocating DSDT memory failed.\n");␊ |
149 | ␉␉close (fd);␊ |
150 | ␉␉goto out;␊ |
151 | ␉}␊ |
152 | ␊ |
153 | ␉if (read (fd, new_dsdt, fsize) != fsize)␊ |
154 | ␉{␊ |
155 | ␉␉DBG("PCIrootUID: ERROR: failed reading DSDT from '%s'.\n", dsdt_filename);␊ |
156 | ␉␉free(new_dsdt);␊ |
157 | ␉␉close (fd);␊ |
158 | ␉␉goto out;␊ |
159 | ␉}␊ |
160 | ␊ |
161 | ␉close (fd);␊ |
162 | */␊ |
163 | ␉if (len)␊ |
164 | ␉{␊ |
165 | ␉␉rootuid = findpciroot(new_dsdt, len);␊ |
166 | ␉}␊ |
167 | /*␊ |
168 | ␉free(new_dsdt);␊ |
169 | */␊ |
170 | ␉// make sure it really works: ␊ |
171 | ␉if (rootuid == 11)␊ |
172 | ␉{␊ |
173 | ␉␉rootuid = 0; //usually when _UID isn't present, it means uid is zero␊ |
174 | ␉}␊ |
175 | ␉else if (rootuid < 0 || rootuid > 9) ␊ |
176 | ␉{␊ |
177 | ␉␉verbose("PCIrootUID: proper value wasn't found. Using default value (0).\n");␊ |
178 | ␉␉rootuid = 0;␊ |
179 | ␉␉return rootuid;␊ |
180 | ␉}␊ |
181 | ␊ |
182 | out:␊ |
183 | ␉verbose("PCIrootUID=0x%02X: using.\n", rootuid);␊ |
184 | ␉return rootuid;␊ |
185 | }␊ |
186 | |