1 | /*␊ |
2 | * Copyright 2009 netkas␊ |
3 | */␊ |
4 | ␊ |
5 | #include "libsaio.h"␊ |
6 | #include "bootstruct.h"␊ |
7 | ␊ |
8 | #ifndef DEBUG_PCIROOT␊ |
9 | #define DEBUG_PCIROOT 0␊ |
10 | #endif␊ |
11 | ␊ |
12 | #if DEBUG_PCIROOT==1␊ |
13 | #define DBG(x...) printf(x)␊ |
14 | #else␊ |
15 | #define DBG(x...)␊ |
16 | #endif␊ |
17 | ␊ |
18 | int rootuid = 10; //value means function wasnt ran yet␊ |
19 | ␊ |
20 | unsigned int findrootuid(unsigned char * dsdt)␊ |
21 | {␊ |
22 | ␉int i;␊ |
23 | ␉for (i=0; i<64; i++) //not far than 64 symbols from pci root ␊ |
24 | ␉{␊ |
25 | ␉␉if(dsdt[i] == '_' && dsdt[i+1] == 'U' && dsdt[i+2] == 'I' && dsdt[i+3] == 'D' && dsdt[i+5] == 0x08)␊ |
26 | ␉␉{␊ |
27 | ␉␉␉return dsdt[i+4];␊ |
28 | ␉␉}␊ |
29 | ␉}␊ |
30 | ␉printf("pci root uid not found\n");␊ |
31 | ␉return 11;␊ |
32 | }␊ |
33 | ␊ |
34 | unsigned int findpciroot(unsigned char * dsdt,int size)␊ |
35 | {␊ |
36 | ␉int i;␊ |
37 | ␉for (i=0; i<size; i++)␊ |
38 | ␉{␊ |
39 | ␉␉if(dsdt[i] == 'P' && dsdt[i+1] == 'C' && dsdt[i+2] == 'I' && (dsdt[i+3] == 0x08 || dsdt [i+4] == 0x08))␊ |
40 | ␉␉{␊ |
41 | ␉␉␉return findrootuid(dsdt+i);␊ |
42 | ␉␉}␊ |
43 | ␉}␊ |
44 | ␉␊ |
45 | ␉printf("pci root not found\n");␊ |
46 | ␉return 10;␊ |
47 | }␊ |
48 | ␊ |
49 | ␊ |
50 | /* Setup ACPI. Replace DSDT if DSDT.aml is found */␊ |
51 | int getPciRootUID()␊ |
52 | {␊ |
53 | ␉int fd, version;␊ |
54 | ␉void *new_dsdt;␊ |
55 | ␉const char *dsdt_filename;␊ |
56 | ␉const char *val;␊ |
57 | ␉int user_uid_value;␊ |
58 | ␉char dirspec[512];␊ |
59 | ␉int len,fsize;␊ |
60 | ␊ |
61 | ␉if(rootuid < 10) return rootuid;␊ |
62 | ␉␊ |
63 | ␉if (!getValueForKey("DSDT", &dsdt_filename, &len, &bootInfo->bootConfig))␊ |
64 | ␉␉dsdt_filename="DSDT.aml";␊ |
65 | ␉␊ |
66 | ␉if (getValueForKey("-pci1", &val, &len, &bootInfo->bootConfig)) //fallback␊ |
67 | ␉{␊ |
68 | ␉␉user_uid_value = 1;␊ |
69 | ␉␉rootuid = user_uid_value;␊ |
70 | ␉␉return rootuid;␊ |
71 | ␉}␊ |
72 | ␉ else user_uid_value = 0;␊ |
73 | ␉␉␊ |
74 | ␉␉␊ |
75 | ␉// Check booting partition␊ |
76 | ␉sprintf(dirspec,"%s",dsdt_filename);␊ |
77 | ␉fd=open (dirspec,0);␊ |
78 | ␉if (fd<0)␊ |
79 | ␉{␉// Check Extra on booting partition␊ |
80 | ␉␉sprintf(dirspec,"/Extra/%s",dsdt_filename);␊ |
81 | ␉␉fd=open (dirspec,0);␊ |
82 | ␉␉if (fd<0)␊ |
83 | ␉␉{␉// Fall back to booter partition␊ |
84 | ␉␉␉sprintf(dirspec,"bt(0,0)/Extra/%s",dsdt_filename);␊ |
85 | ␉␉␉fd=open (dirspec,0);␊ |
86 | ␉␉␉if (fd<0)␊ |
87 | ␉␉␉{␊ |
88 | ␉␉␉␉verbose("No DSDT found, using 0 as uid value.\n");␊ |
89 | ␉␉␉␉rootuid = user_uid_value;␊ |
90 | ␉␉␉␉return rootuid;␊ |
91 | ␉␉␉}␊ |
92 | ␉␉}␊ |
93 | ␉}␊ |
94 | ␉␊ |
95 | ␉// Load replacement DSDT␊ |
96 | ␉new_dsdt=(void*)MALLOC(file_size (fd));␊ |
97 | ␉if (!new_dsdt)␊ |
98 | ␉{␊ |
99 | ␉␉printf("Couldn't allocate memory for DSDT\n");␊ |
100 | ␉␉rootuid = user_uid_value;␊ |
101 | ␉␉return rootuid;␊ |
102 | ␉}␊ |
103 | ␉fsize = file_size(fd);␊ |
104 | ␉if (read (fd, new_dsdt, file_size (fd))!=file_size (fd))␊ |
105 | ␉{␊ |
106 | ␉␉printf("Couldn't read file\n");␊ |
107 | ␉␉rootuid = user_uid_value;␊ |
108 | ␉␉return rootuid;␊ |
109 | ␉}␊ |
110 | ␉close (fd);␊ |
111 | ␉rootuid=findpciroot(new_dsdt, fsize);␊ |
112 | ␉if(rootuid == 11)rootuid=0; //usualy when _UID isnt present, it means uid is zero␊ |
113 | ␉if(rootuid == 10) //algo failed, PCI0 wasnt found;␊ |
114 | ␉{␊ |
115 | ␉␉printf("pci root uid value wasnt found, using zero, if you want it to be 1, use -pci1 flag");␊ |
116 | ␉␉rootuid = user_uid_value;␊ |
117 | ␉}␊ |
118 | ␉free(new_dsdt);␊ |
119 | ␉return rootuid;␊ |
120 | }␊ |
121 | ␊ |
122 | |