Chameleon

Chameleon Svn Source Tree

Root/branches/Bungo/i386/libsaio/pci_root.c

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
19static int rootuid = 10; //value means function wasn't ran yet
20
21static unsigned int findrootuid(unsigned char * dsdt, int len)
22{
23int i;
24for (i=0; i<64 && i<len-5; i++) //not far than 64 symbols from pci root
25{
26if(dsdt[i] == '_' && dsdt[i+1] == 'U' && dsdt[i+2] == 'I' && dsdt[i+3] == 'D' && dsdt[i+5] == 0x08)
27{
28return dsdt[i+4];
29}
30}
31return 11;
32}
33
34static unsigned int findpciroot(unsigned char * dsdt,int len)
35{
36int i;
37
38for (i=0; i<len-4; i++) {
39if(dsdt[i] == 'P' && dsdt[i+1] == 'C' && dsdt[i+2] == 'I' && (dsdt[i+3] == 0x08 || dsdt [i+4] == 0x08)) {
40return findrootuid(dsdt+i, len-i);
41}
42}
43return 10;
44}
45
46int getPciRootUID(void)
47{
48char dsdt_dirSpec[128];
49void *new_dsdt = NULL;
50const char *val = "";
51int len = 0,fsize = 0;
52const char * dsdt_filename = "";
53extern int search_and_get_acpi_fd(const char *, const char **);
54
55if (rootuid < 10) return rootuid;
56rootuid = 0;/* default _UID = 0 */
57
58if (getValueForKey(kPCIRootUID, &val, &len, &bootInfo->chameleonConfig) && len) {
59if (isdigit(val[0])) rootuid = val[0] - '0';
60goto out;
61}
62/* Chameleon compatibility */
63else if (getValueForKey("PciRoot", &val, &len, &bootInfo->chameleonConfig) && len) {
64if (isdigit(val[0])) rootuid = val[0] - '0';
65goto out;
66}
67/* PCEFI compatibility */
68else if (getValueForKey("-pci0", &val, &len, &bootInfo->chameleonConfig) && len) {
69rootuid = 0;
70goto out;
71}
72else if (getValueForKey("-pci1", &val, &len, &bootInfo->chameleonConfig) && len) {
73rootuid = 1;
74goto out;
75}
76
77// Try using the file specified with the DSDT option
78if (getValueForKey(kDSDT, &dsdt_filename, &len, &bootInfo->chameleonConfig) && len)
79{
80snprintf(dsdt_dirSpec, sizeof(dsdt_dirSpec), dsdt_filename);
81}
82else
83{
84sprintf(dsdt_dirSpec, "DSDT.aml");
85}
86
87 DBG("PCIrootUID: trying DSDT.aml... ");
88int fd = search_and_get_acpi_fd(dsdt_dirSpec, &dsdt_filename);
89
90// Check booting partition
91if (fd<0)
92{
93 DBG("PCIrootUID: file '%s' not found, using default value.\n", dsdt_filename);
94 rootuid = 0;
95 goto out;
96}
97
98fsize = file_size(fd);
99
100if (!(new_dsdt = malloc(fsize))) {
101DBG("PCIrootUID: ERROR: allocating DSDT memory failed.\n");
102close (fd);
103goto out;
104}
105
106if (read (fd, new_dsdt, fsize) != fsize) {
107DBG("PCIrootUID: ERROR: failed reading DSDT from '%s'.\n", dsdt_filename);
108free(new_dsdt);
109close (fd);
110goto out;
111}
112
113close (fd);
114
115rootuid = findpciroot(new_dsdt, fsize);
116free(new_dsdt);
117
118// make sure it really works:
119if (rootuid == 11) rootuid=0; //usually when _UID isnt present, it means uid is zero
120else if (rootuid < 0 || rootuid > 9)
121{
122DBG("PCIrootUID: proper value wasn't found. Using default value (0). Use -PciRootUID flag to force.\n");
123rootuid = 0;
124 return rootuid;
125}
126
127out:
128 DBG("PCIrootUID=0x%02X: using.\n", rootuid);
129return rootuid;
130}
131

Archive Download this file

Revision: 2469