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 1␊ |
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; // _UID isnt present on ACPI data.␊ |
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 | ␉{␊ |
40 | ␉␉if(dsdt[i] == 'P' && dsdt[i+1] == 'C' && dsdt[i+2] == 'I' && (dsdt[i+3] == 0x08 || dsdt [i+4] == 0x08))␊ |
41 | ␉␉{␊ |
42 | ␉␉␉return findrootuid(dsdt+i, len-i);␊ |
43 | ␉␉}␊ |
44 | ␉}␊ |
45 | ␉return 10;␊ |
46 | }␊ |
47 | ␊ |
48 | int getPciRootUID(void)␊ |
49 | {␊ |
50 | ␉const char *val;␊ |
51 | ␉const char * dsdt_filename = NULL; //Azi:dsdt␊ |
52 | ␉int len, fd, fsize;␊ |
53 | ␉void *new_dsdt;␊ |
54 | ␉//Azi: warning: implicit declaration of function ‘search_and_get_acpi_fd’, if removed... hum... but works fine!␊ |
55 | ␉extern int search_and_get_acpi_fd(const char *, const char **);␊ |
56 | ␉␊ |
57 | ␉if (rootuid < 10) return rootuid;␊ |
58 | ␉␊ |
59 | ␉// If user supplied a key...␊ |
60 | ␉if (getValueForKey(kPCIRootUIDKey, &val, &len, &bootInfo->bootConfig))␊ |
61 | ␉{␊ |
62 | ␉␉if (isdigit(val[0]))␊ |
63 | ␉␉␉rootuid = val[0] - '0';␊ |
64 | ␉␉// ... use the value in it.␊ |
65 | ␉␉verbose("Using PCI-Root-UID value from PciRoot key: %d\n", rootuid);␊ |
66 | ␉␉goto out_out;␊ |
67 | ␉}␊ |
68 | ␉␊ |
69 | ␉// Search for a user supplied ACPI Table, to fetch the value from.␊ |
70 | ␉fd = search_and_get_acpi_fd("DSDT.aml", &dsdt_filename); //Azi:dsdt call 1␊ |
71 | ␉␊ |
72 | ␉// If no ACPI Table is supplied by user...␊ |
73 | ␉if (fd < 0)␊ |
74 | ␉{␊ |
75 | ␉␉verbose("No ACPI Table supplied by user.\n");␊ |
76 | ␉␉rootuid = 0; // default uid to 0.␊ |
77 | ␉␉goto out;␊ |
78 | ␉}␊ |
79 | ␉␊ |
80 | ␉// Found ACPI Table supplied by user, check size...␊ |
81 | ␉fsize = file_size(fd);␊ |
82 | ␉␊ |
83 | ␉// ... try to allocate memory...␊ |
84 | ␉if ((new_dsdt = malloc(fsize)) == NULL)␊ |
85 | ␉{␊ |
86 | ␉␉verbose("[ERROR] DSDT memory allocation failed.\n");␊ |
87 | ␉␉close (fd); // ... if allocation fails close file.␊ |
88 | ␉␉rootuid = 0; // Default uid to 0.␊ |
89 | ␉␉goto out;␊ |
90 | ␉}␊ |
91 | ␉␊ |
92 | ␉// Try to read file...␊ |
93 | ␉if (read(fd, new_dsdt, fsize) != fsize)␊ |
94 | ␉{␊ |
95 | ␉␉verbose("[ERROR] read %s failed.\n", dsdt_filename);␊ |
96 | ␉␉close (fd); // ... if reading fails close file.␊ |
97 | ␉␉rootuid = 0; // Default uid to 0.␊ |
98 | ␉␉goto out;␊ |
99 | ␉}␊ |
100 | ␉// else new_dsdt = supplied ACPI Table data.␊ |
101 | ␉close (fd); // Supplied Table can be closed.␊ |
102 | ␉␊ |
103 | ␉// Find value on supplied data.␊ |
104 | ␉rootuid = findpciroot(new_dsdt, fsize);␊ |
105 | ␉free(new_dsdt); // Free allocated data.␊ |
106 | ␉␊ |
107 | ␉// If _UID isn't present on ACPI data (value 11)...␊ |
108 | ␉if (rootuid < 0 || rootuid > 9) // ... it's negative or bigger than 9...␊ |
109 | ␉{␊ |
110 | ␉␉rootuid = 0; // ... default uid to 0.␊ |
111 | ␉}␊ |
112 | ␉else␊ |
113 | ␉␉printf("Found UID value on ACPI Table provided by user...\n");␊ |
114 | out:␊ |
115 | ␉verbose("Using PCI-Root-UID value: %d\n", rootuid);␊ |
116 | out_out:␊ |
117 | ␉return rootuid;␊ |
118 | }␊ |
119 | |