Chameleon

Chameleon Commit Details

Date:2010-01-21 07:41:42 (9 years 6 months ago)
Author:Rekursor
Commit:23
Parents: 22
Message:Merged modifications from my branch to trunk as requested by Zef. This includes asere patch with few modifications /bug fixes. Included JrCs coding standard name convention change. See CHANGES file for details.
Changes:
D/trunk/i386/libsaio/memory.c
D/trunk/i386/libsaio/freq_detect.c
D/trunk/i386/libsaio/freq_detect.h
C/branches/rekursor/coding_standards.txt → /trunk/coding_standards.txt
C/branches/rekursor/CHANGES → /trunk/CHANGES
C/branches/rekursor/i386/libsaio/mem.c → /trunk/i386/libsaio/mem.c
C/branches/rekursor/i386/libsaio/mem.h → /trunk/i386/libsaio/mem.h
C/branches/rekursor/i386/libsaio/allocate.c → /trunk/i386/libsaio/allocate.c
C/branches/rekursor/i386/libsaio/pci_root.c → /trunk/i386/libsaio/pci_root.c
C/branches/rekursor/i386/libsaio/pci_root.h → /trunk/i386/libsaio/pci_root.h
C/branches/rekursor/i386/libsaio/cpu.c → /trunk/i386/libsaio/cpu.c
C/branches/rekursor/i386/libsaio/cpu.h → /trunk/i386/libsaio/cpu.h
M/trunk/i386/libsaio/dsdt_patcher.c
M/trunk
M/trunk/i386/boot0/boot0.s
M/trunk/i386/libsa/efi_tables.c
M/trunk/i386/libsa/efi_tables.h
M/trunk/i386/libsaio/ntfs.c
M/trunk/i386/libsaio/ext2fs.c
M/trunk/i386/libsaio/pci.c
M/trunk/i386/libsaio/bootstruct.h
M/trunk/i386/libsaio/stringTable.c
M/trunk/i386/libsaio/load.c
M/trunk/i386/libsaio/ntfs.h
M/trunk/i386/libsaio/ext2fs.h
M/trunk/i386/libsaio/pci.h
M/trunk/i386/libsaio/acpi.h
M/trunk/i386/libsaio/platform.c
M/trunk/i386/boot2/gui.c
M/trunk/i386/libsaio/platform.h
M/trunk/i386/libsaio/disk.c
M/trunk/i386/libsaio/device_inject.c
M/trunk/i386/libsaio/Makefile
M/trunk/i386/boot2/gui.h
M/trunk/i386/boot2/ramdisk.c
M/trunk/i386/libsaio/device_inject.h
M/trunk/i386/libsaio/SMBIOS.h
M/trunk/i386/libsaio/smbios_patcher.c
M/trunk/i386/boot2/picopng.c
M/trunk/i386/boot2/ramdisk.h
M/trunk/i386/libsaio/console.c
M/trunk/i386/boot2/graphics.c
M/trunk/doc/BootHelp.txt
M/trunk/i386/libsaio/smbios_patcher.h
M/trunk/i386/boot2/picopng.h
M/trunk/i386/boot2/graphics.h
M/trunk/i386/util/machOconv.c
M/trunk/i386/libsaio/device_tree.c
M/trunk/i386/libsaio/hfs.c
M/trunk/i386/libsaio/device_tree.h
M/trunk/i386/libsaio/hfs.h
M/trunk/i386/libsaio/spd.c
M/trunk/i386/libsaio/fake_efi.c
M/trunk/i386/libsaio/spd.h
M/trunk/i386/libsaio/pci_setup.c
M/trunk/i386/libsaio/misc.c
M/trunk/i386/libsa/zalloc.c
M/trunk/i386/boot2/resume.c
M/trunk/i386/boot2/boot.c
M/trunk/i386/libsa/libsa.h
M/trunk/i386/libsaio/nvidia.c
M/trunk/i386/boot2/boot.h
M/trunk/i386/libsaio/msdos.c
M/trunk/i386/libsaio/usb.c
M/trunk/i386/libsaio/saio_internal.h
M/trunk/i386/boot2/options.c
M/trunk/i386/libsaio/ati.c
M/trunk/i386/libsaio/sys.c
M/trunk/i386/libsaio/biosfn.c
M/trunk/i386/boot2/drivers.c
M/trunk/i386/libsaio/ati.h
M/trunk/i386/boot2/mboot.c
M/trunk/i386/libsaio/saio_types.h
M/trunk/i386/libsa/strtol.c
M/trunk/i386/boot2/Makefile

File differences

trunk/coding_standards.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
Coding Standard rev. 0 (First Draft)
1. Indentation
having seen most indentation styles going from 2 to 8 spaces, I would suggest a indentation of 4 spaces.
2. Comments
I see here two main differents cases:
function description comments and one-line code quite comments
For functions documentation, I suggest to use this syntax
/**
*
*/
Note the use of /** that will make future html auto-documentation easier (i.e: Doxygen at least recognize this marker)
for punctual, short code comment, let's use:
//
3) #define at top of document
4) Global vars right below #include / #define (notation: gLobal)
Note that global vars and static vars should be avoided as much as possible in favor of local variables use, get/set functions (properties).
5) No curly brackets for single lines
6) else
{
....
}
instead of:
else {
....
}
7) if
{
....
}
instead of:
if {
....
}
8) fall through code (using indention) or bail out early (using returns)?
Using early bail out for preconditions early in the function code,
use common sense to avoid as an example more than 4 imbricated if() constructions.
In the later case, consider decomposing your function in more manageable primitives.
9) Spaces/readability i.e. not: if (fd<0)
but: if (fd < 0)
10. types, variables, functions, naming
non const variables should follow the (currently mostly used) CamelCase convention:
int myVariableIsFine;
instead of :
int my_variable_is_ok;
Functions should follow the same conventions except for standard c lib related functions.
Types should share the same convention but start with a Captial letter instead of lower case.
11. Please make sure you extensively initialize variables:
avoid as much as possible:
int myVar
...
myVar = 10;
but use instead:
int myVar = 10;
12. const values:
const int MY_CONST_VARIABLE=42; is also ok for me, depending on the context of use.
or
const int MyConstVariable = 42; (with a Capital first letter)
13. macro definitions should follow this convention:
#define MY_HANDY_MACROS_PSEUDO_FUNC() ...
14. Macros use should be limited to really special cases where they bring real value (like special optimization cases)
Most of the time inlining a function is much better than the use of macros
15. Don't optimize your code blindly, always favor readability when in doubt.
Very often, optimization is not necessary where you think it is, think about the bubble sort algorithm, where people would code it in assembly, where a heap or quick sort algorithm would be much more efficient (n log(n) instead of quadratic complexity), as an example when values count to be sorted get high.
trunk/doc/BootHelp.txt
5151
5252
5353
54
55
56
5457
5558
5659
"Hide Partition" Remove unwanted partition(s) from the boot menu.
=hd(x,y) [hd(m,n)]
"Rename Partition" Rename partition(s) for the boot menu.
=hd(x,y) <alias>[;hd(m,n) <alias2> ...]
GUI=No Disable the GUI (enabled by default).
"Boot Banner"=Yes|No Show boot banner in GUI mode (enabled by default).
"Legacy Logo"=Yes|No Use the legacy grey apple logo (disabled by default).
trunk/CHANGES
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- Added JrCs modified convention name change to coding_standards
- Now malloc (ex. MALLOC in Asere patch) is renamed malloc(size) and is an alias
to safe_malloc(size, file, line) with _FILE_ and _LINE_ prerocessor definitions
- Added a new 'Rename Partition Feature', now permitting to rename partition
like 'System reserved' to a more meaningful name
- Added SystemID option permitting to change the System UUID to a fixed value.
- Added the PciRoot autodetection feature imported from pcefi10.5
- Added automatic "system-id" injection from dmi bios, also compatible
with SystemID boot option and former SMUUID from smbios,plist
- Added "system-type' automatic injection (1=Desktop) plus override possibility
with the new system-type option in bootConfig
- Added SMserial and SMproductname new options for smbios.plist
- Merged with asere patch, while keeping my fake_efi.c changes, and adding a new
stringForKey() API, also changed the DT__XXXX() set of functions
to handle const char * values instead of char*.
trunk/i386/libsaio/memory.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/*
* Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* Portions Copyright (c) 2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
* Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
*
* The Original Code and all software distributed under the License are
* distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
* License for the specific language governing rights and limitations
* under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
#include "sl.h"
#include "saio_internal.h"
#include "bootstruct.h"
#include "device_tree.h"
static long gImageLastKernelAddr;
#define kPageSize 4096
#define RoundPage(x) ((((unsigned)(x)) + kPageSize - 1) & ~(kPageSize - 1))
long
AllocateMemoryRange(char * rangeName, long start, long length, long type)
{
char *nameBuf;
uint32_t *buffer;
nameBuf = malloc(strlen(rangeName) + 1);
if (nameBuf == 0) return -1;
strcpy(nameBuf, rangeName);
buffer = malloc(2 * sizeof(uint32_t));
if (buffer == 0) return -1;
buffer[0] = start;
buffer[1] = length;
DT__AddProperty(gMemoryMapNode, nameBuf, 2 * sizeof(uint32_t), (char *)buffer);
return 0;
}
#if 0
long
AllocateMemoryRange(char * rangeName, long start, long length, long type)
{
if ( bootArgs->numBootDrivers < NDRIVERS )
{
int num = bootArgs->numBootDrivers;
bootArgs->driverConfig[num].address = start;
bootArgs->driverConfig[num].size = length;
bootArgs->driverConfig[num].type = type;
bootArgs->numBootDrivers++;
}
else
{
stop( "AllocateMemoryRange error" );
}
return 0;
}
#endif
long
AllocateKernelMemory( long inSize )
{
long addr;
if (gImageLastKernelAddr == 0) {
gImageLastKernelAddr = RoundPage( bootArgs->kaddr +
bootArgs->ksize );
}
addr = gImageLastKernelAddr;
gImageLastKernelAddr += RoundPage(inSize);
if ( gImageLastKernelAddr >= (KERNEL_ADDR + KERNEL_LEN) ) {
stop ("AllocateKernelMemory error");
}
bootArgs->ksize = gImageLastKernelAddr - bootArgs->kaddr;
return addr;
}
trunk/i386/libsaio/freq_detect.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
/*
* Copyright 2008 Islam Ahmed Zaid. All rights reserved. <azismed@gmail.com>
*/
#include "libsaio.h"
#include "freq_detect.h"
// DFE: enable_PIT2 and disable_PIT2 come from older xnu
/*
* Enable or disable timer 2.
* Port 0x61 controls timer 2:
* bit 0 gates the clock,
* bit 1 gates output to speaker.
*/
inline static void
enable_PIT2(void)
{
/* Enable gate, disable speaker */
__asm__ volatile(
" inb $0x61,%%al \n\t"
" and $0xFC,%%al \n\t" /* & ~0x03 */
" or $1,%%al \n\t"
" outb %%al,$0x61 \n\t"
: : : "%al" );
}
inline static void
disable_PIT2(void)
{
/* Disable gate and output to speaker */
__asm__ volatile(
" inb $0x61,%%al \n\t"
" and $0xFC,%%al \n\t"/* & ~0x03 */
" outb %%al,$0x61 \n\t"
: : : "%al" );
}
// DFE: set_PIT2_mode0, poll_PIT2_gate, and measure_tsc_frequency are
// roughly based on Linux code
/* Set the 8254 channel 2 to mode 0 with the specified value.
In mode 0, the counter will initially set its gate low when the
timer expires. For this to be useful, you ought to set it high
before calling this function. The enable_PIT2 function does this.
*/
static inline void set_PIT2_mode0(uint16_t value)
{
__asm__ volatile(
" movb $0xB0,%%al \n\t"
" outb%%al,$0x43\n\t"
" movb%%dl,%%al\n\t"
" outb%%al,$0x42\n\t"
" movb%%dh,%%al\n\t"
" outb%%al,$0x42"
: : "d"(value) /*: no clobber */ );
}
/* Returns the number of times the loop ran before the PIT2 signaled */
static inline unsigned long poll_PIT2_gate(void)
{
unsigned long count = 0;
unsigned char nmi_sc_val;
do {
++count;
__asm__ volatile(
"inb$0x61,%0"
: "=q"(nmi_sc_val) /*:*/ /* no input */ /*:*/ /* no clobber */);
} while( (nmi_sc_val & 0x20) == 0);
return count;
}
/*
* DFE: Measures the TSC frequency in Hz (64-bit) using the ACPI PM timer
*/
uint64_t measure_tsc_frequency(void)
{
uint64_t tscStart;
uint64_t tscEnd;
uint64_t tscDelta = 0xffffffffffffffffULL;
unsigned long pollCount;
uint64_t retval = 0;
int i;
/* Time how many TSC ticks elapse in 30 msec using the 8254 PIT
* counter 2. We run this loop 3 times to make sure the cache
* is hot and we take the minimum delta from all of the runs.
* That is to say that we're biased towards measuring the minimum
* number of TSC ticks that occur while waiting for the timer to
* expire. That theoretically helps avoid inconsistencies when
* running under a VM if the TSC is not virtualized and the host
* steals time. The TSC is normally virtualized for VMware.
*/
for(i = 0; i < 3; ++i)
{
enable_PIT2();
set_PIT2_mode0(CALIBRATE_LATCH);
tscStart = rdtsc64();
pollCount = poll_PIT2_gate();
tscEnd = rdtsc64();
/* The poll loop must have run at least a few times for accuracy */
if(pollCount <= 1)
continue;
/* The TSC must increment at LEAST once every millisecond. We
* should have waited exactly 30 msec so the TSC delta should
* be >= 30. Anything less and the processor is way too slow.
*/
if((tscEnd - tscStart) <= CALIBRATE_TIME_MSEC)
continue;
// tscDelta = min(tscDelta, (tscEnd - tscStart))
if( (tscEnd - tscStart) < tscDelta )
tscDelta = tscEnd - tscStart;
}
/* tscDelta is now the least number of TSC ticks the processor made in
* a timespan of 0.03 s (e.g. 30 milliseconds)
* Linux thus divides by 30 which gives the answer in kiloHertz because
* 1 / ms = kHz. But we're xnu and most of the rest of the code uses
* Hz so we need to convert our milliseconds to seconds. Since we're
* dividing by the milliseconds, we simply multiply by 1000.
*/
/* Unlike linux, we're not limited to 32-bit, but we do need to take care
* that we're going to multiply by 1000 first so we do need at least some
* arithmetic headroom. For now, 32-bit should be enough.
* Also unlike Linux, our compiler can do 64-bit integer arithmetic.
*/
if(tscDelta > (1ULL<<32))
retval = 0;
else
{
retval = tscDelta * 1000 / 30;
}
disable_PIT2();
return retval;
}
uint64_t tscFrequency = 0;
uint64_t fsbFrequency = 0;
uint64_t cpuFrequency = 0;
/*
* Calculates the FSB and CPU frequencies using specific MSRs for each CPU
* - multi. is read from a specific MSR. In the case of Intel, there is:
* a max multi. (used to calculate the FSB freq.),
* and a current multi. (used to calculate the CPU freq.)
* - fsbFrequency = tscFrequency / multi
* - cpuFrequency = fsbFrequency * multi
*/
void calculate_freq(void)
{
uint32_tcpuid_reg[4], cpu_vendor;
uint8_tcpu_family, cpu_model, cpu_extfamily, cpu_extmodel;
uint64_tmsr, flex_ratio;
uint8_tmaxcoef, maxdiv, currcoef, currdiv;
do_cpuid(0, cpuid_reg);
cpu_vendor = cpuid_reg[1];
do_cpuid(1, cpuid_reg);
cpu_model = bitfield(cpuid_reg[0], 7, 4);
cpu_family = bitfield(cpuid_reg[0], 11, 8);
cpu_extmodel = bitfield(cpuid_reg[0], 19, 16);
cpu_extfamily = bitfield(cpuid_reg[0], 27, 20);
cpu_model += (cpu_extmodel << 4);
DBG("\nCPU Model: %d - CPU Family: %d - CPU Ext. Family: %d\n", cpu_model, cpu_family, cpu_extfamily);
DBG("The booter will now attempt to read the CPU Multiplier (using RDMSR).\n");
DBG("Press any key to continue..\n\n");
#if DEBUG_FREQ
getc();
#endif
tscFrequency = measure_tsc_frequency();
DBG("CPU Multiplier: ");
if((cpu_vendor == 0x756E6547 /* Intel */) && ((cpu_family == 0x06) || (cpu_family == 0x0f)))
{
if ((cpu_family == 0x06 && cpu_model >= 0x0c) ||
(cpu_family == 0x0f && cpu_model >= 0x03))
{
/* Nehalem CPU model */
if (cpu_family == 0x06 && (cpu_model == 0x1a || cpu_model == 0x1e))
{
msr = rdmsr64(MSR_PLATFORM_INFO);
currcoef = (msr >> 8) & 0xff;
msr = rdmsr64(MSR_FLEX_RATIO);
if ((msr >> 16) & 0x01)
{
flex_ratio = (msr >> 8) & 0xff;
if (currcoef > flex_ratio)
currcoef = flex_ratio;
}
if (currcoef)
{
DBG("%d\n", currcoef);
fsbFrequency = (tscFrequency / currcoef);
}
cpuFrequency = tscFrequency;
}
else
{
msr = rdmsr64(IA32_PERF_STATUS);
currcoef = (msr >> 8) & 0x1f;
/* Non-integer bus ratio for the max-multi*/
maxdiv = (msr >> 46) & 0x01;
/* Non-integer bus ratio for the current-multi (undocumented)*/
currdiv = (msr >> 14) & 0x01;
if ((cpu_family == 0x06 && cpu_model >= 0x0e) ||
(cpu_family == 0x0f)) // This will always be model >= 3
{
/* On these models, maxcoef defines TSC freq */
maxcoef = (msr >> 40) & 0x1f;
}
else
{
/* On lower models, currcoef defines TSC freq */
/* XXX */
maxcoef = currcoef;
}
if (maxcoef)
{
if (maxdiv)
fsbFrequency = ((tscFrequency * 2) / ((maxcoef * 2) + 1));
else
fsbFrequency = (tscFrequency / maxcoef);
if (currdiv)
cpuFrequency = (fsbFrequency * ((currcoef * 2) + 1) / 2);
else
cpuFrequency = (fsbFrequency * currcoef);
DBG("max: %d%s current: %d%s\n", maxcoef, maxdiv ? ".5" : "",currcoef, currdiv ? ".5" : "");
}
}
}
}
else if((cpu_vendor == 0x68747541 /* AMD */) && (cpu_family == 0x0f))
{
if(cpu_extfamily == 0x00 /* K8 */)
{
msr = rdmsr64(K8_FIDVID_STATUS);
currcoef = (msr & 0x3f) / 2 + 4;
currdiv = (msr & 0x01) * 2;
}
else if(cpu_extfamily >= 0x01 /* K10+ */)
{
msr = rdmsr64(K10_COFVID_STATUS);
if(cpu_extfamily == 0x01 /* K10 */)
currcoef = (msr & 0x3f) + 0x10;
else /* K11+ */
currcoef = (msr & 0x3f) + 0x08;
currdiv = (2 << ((msr >> 6) & 0x07));
}
if (currcoef)
{
if (currdiv)
{
fsbFrequency = ((tscFrequency * currdiv) / currcoef);
DBG("%d.%d\n", currcoef / currdiv, ((currcoef % currdiv) * 100) / currdiv);
}
else
{
fsbFrequency = (tscFrequency / currcoef);
DBG("%d\n", currcoef);
}
fsbFrequency = (tscFrequency / currcoef);
cpuFrequency = tscFrequency;
}
}
if (!fsbFrequency)
{
fsbFrequency = (DEFAULT_FSB * 1000);
cpuFrequency = tscFrequency;
DBG("0 ! using the default value for FSB !\n");
}
DBG("TSC Frequency: %dMHz\n", tscFrequency / 1000000);
DBG("CPU Frequency: %dMHz\n", cpuFrequency / 1000000);
DBG("FSB Frequency: %dMHz\n", fsbFrequency / 1000000);
DBG("Press [Enter] to continue..\n");
#if DEBUG_FREQ
while (getc() != 0x0d) ;
#endif
}
trunk/i386/libsaio/freq_detect.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/*
* Copyright 2008 Islam Ahmed Zaid. All rights reserved. <azismed@gmail.com>
*/
#ifndef __LIBSAIO_FREQ_DETECT_H
#define __LIBSAIO_FREQ_DETECT_H
#include "libsaio.h"
#ifndef DEBUG_FREQ
#define DEBUG_FREQ 0
#endif
#if DEBUG_FREQ
#define DBG(x...)printf(x)
#else
#define DBG(x...)
#endif
/* Decimal powers: */
#define kilo (1000ULL)
#define Mega (kilo * kilo)
#define Giga (kilo * Mega)
#define Tera (kilo * Giga)
#define Peta (kilo * Tera)
#define bit(n)(1ULL << (n))
#define bitmask(h,l)((bit(h)|(bit(h)-1)) & ~(bit(l)-1))
#define bitfield(x,h,l)(((x) & bitmask(h,l)) >> l)
#defineIA32_PERF_STATUS0x198
#define MSR_FLEX_RATIO0x194
#defineMSR_PLATFORM_INFO0xCE
#define K8_FIDVID_STATUS0xC0010042
#define K10_COFVID_STATUS0xC0010071
#define DEFAULT_FSB100000 /* for now, hardcoding 100MHz for old CPUs */
// DFE: This constant comes from older xnu:
#define CLKNUM1193182/* formerly 1193167 */
// DFE: These two constants come from Linux except CLOCK_TICK_RATE replaced with CLKNUM
#define CALIBRATE_TIME_MSEC 30 /* 30 msecs */
#define CALIBRATE_LATCH\
((CLKNUM * CALIBRATE_TIME_MSEC + 1000/2)/1000)
extern uint64_t tscFrequency;
extern uint64_t fsbFrequency;
extern uint64_t cpuFrequency;
void calculate_freq(void);
static inline uint64_t rdtsc64(void)
{
uint64_t ret;
__asm__ volatile("rdtsc" : "=A" (ret));
return ret;
}
static inline uint64_t rdmsr64(uint32_t msr)
{
uint64_t ret;
__asm__ volatile("rdmsr" : "=A" (ret) : "c" (msr));
return ret;
}
static inline void do_cpuid(uint32_t selector, uint32_t *data)
{
asm volatile ("cpuid"
: "=a" (data[0]),
"=b" (data[1]),
"=c" (data[2]),
"=d" (data[3])
: "a" (selector)
);
}
#endif /* !__LIBSAIO_FREQ_DETECT_H */
trunk/i386/libsaio/console.c
4949
5050
5151
52
53
52
53
5454
5555
5656
......
126126
127127
128128
129
129
130130
131131
132132
......
138138
139139
140140
141
142
143
144
145
141
142
143
144
145
146146
147
147
148148
149
149150
150
151
151
152
153
152154
extern intvprf(const char * fmt, va_list ap);
BOOL gVerboseMode;
BOOL gErrors;
bool gVerboseMode;
bool gErrors;
/*
* write one character to console
int error(const char * fmt, ...)
{
va_list ap;
gErrors = YES;
gErrors = true;
va_start(ap, fmt);
if (bootArgs->Video.v_display == VGA_TEXT_MODE)
prf(fmt, ap, putchar, 0);
void stop(const char * fmt, ...)
{
va_list ap;
printf("\n");
va_start(ap, fmt);
if (bootArgs->Video.v_display == VGA_TEXT_MODE)
va_list ap;
printf("\n");
va_start(ap, fmt);
if (bootArgs->Video.v_display == VGA_TEXT_MODE) {
prf(fmt, ap, putchar, 0);
else
} else {
vprf(fmt, ap);
}
va_end(ap);
printf("\n");
halt();
printf("\nThis is a non recoverable error! System HALTED!!!");
halt();
while (1);
}
trunk/i386/libsaio/ext2fs.c
1313
1414
1515
16
16
1717
1818
1919
20
2021
2122
2223
......
3839
3940
4041
41
42
#define EX2ProbeSize2048
BOOL EX2Probe (const void *buf)
bool EX2Probe (const void *buf)
{
return (OSReadLittleInt16(buf+0x438,0)==0xEF53);
}
void EX2GetDescription(CICell ih, char *str, long strMaxLen)
{
char * buf=malloc (EX2ProbeSize);
str[strMaxLen]=0;
strncpy (str, buf+0x478, min (strMaxLen, 16));
free (buf);
}
}
trunk/i386/libsaio/bootstruct.h
126126
127127
128128
129
130129
131130
132131
config_file_t bootConfig; // boot.plist
config_file_t overrideConfig; // additional boot.plist which can override bootConfig keys
config_file_t themeDefault; // default theme.plist
config_file_t themeConfig; // theme.plist
config_file_t smbiosConfig; // smbios.plist
config_file_t helperConfig; // boot helper partition's boot.plist
trunk/i386/libsaio/device_tree.c
6262
6363
6464
65
65
6666
6767
6868
......
112112
113113
114114
115
115
116116
117117
118118
......
150150
151151
152152
153
153
154154
155155
156156
......
308308
309309
310310
311
311
312312
313313
314314
static Property *freeProperties, *allocedProperties;
Property *
DT__AddProperty(Node *node, char *name, uint32_t length, void *value)
DT__AddProperty(Node *node, const char *name, uint32_t length, void *value)
{
Property *prop;
}
Node *
DT__AddChild(Node *parent, char *name)
DT__AddChild(Node *parent, const char *name)
{
Node *node;
parent->children = node;
}
DTInfo.numNodes++;
DT__AddProperty(node, "name", strlen(name) + 1, name);
DT__AddProperty(node, "name", strlen(name) + 1, (void *) name);
return node;
}
}
Node *
DT__FindNode(char *path, bool createIfMissing)
DT__FindNode(const char *path, bool createIfMissing)
{
Node *node, *child;
DTPropertyNameBuf nameBuf;
trunk/i386/libsaio/hfs.c
109109
110110
111111
112
113
112
114113
115114
116115
......
125124
126125
127126
128
129
127
130128
131129
132130
......
134132
135133
136134
137
135
138136
139137
140
141
138
139
142140
143141
144142
u_int16_t *uniStr2, u_int32_t len2);
static void
SwapFinderInfo(FndrFileInfo *dst, FndrFileInfo *src)
static void SwapFinderInfo(FndrFileInfo *dst, FndrFileInfo *src)
{
dst->fdType = SWAP_BE32(src->fdType);
dst->fdCreator = SWAP_BE32(src->fdCreator);
free(ih);
}
BOOL
HFSProbe (const void *buf)
bool HFSProbe (const void *buf)
{
const HFSMasterDirectoryBlock *mdb;
const HFSPlusVolumeHeader *header;
header=(const HFSPlusVolumeHeader *)(((const char*)buf)+kMDBBaseOffset);
if ( SWAP_BE16(mdb->drSigWord) == kHFSSigWord )
return TRUE;
return true;
if (SWAP_BE16(header->signature) != kHFSPlusSigWord &&
SWAP_BE16(header->signature) != kHFSXSigWord)
return FALSE;
return TRUE;
return false;
return true;
}
long HFSInitPartition(CICell ih)
trunk/i386/libsaio/ext2fs.h
77
88
99
10
10
1111
*
*/
extern BOOL EX2Probe (const void *buf);
extern bool EX2Probe (const void *buf);
extern void EX2GetDescription(CICell ih, char *str, long strMaxLen);
trunk/i386/libsaio/device_tree.h
99
1010
1111
12
12
1313
1414
1515
......
2727
2828
2929
30
30
3131
3232
33
33
3434
3535
36
36
3737
3838
3939
#include <stdint.h>
typedef struct _Property {
char * name;
const char * name;
uint32_t length;
void * value;
extern Property *
DT__AddProperty(Node *node, char *name, uint32_t length, void *value);
DT__AddProperty(Node *node, const char *name, uint32_t length, void *value);
extern Node *
DT__AddChild(Node *parent, char *name);
DT__AddChild(Node *parent, const char *name);
Node *
DT__FindNode(char *path, bool createIfMissing);
DT__FindNode(const char *path, bool createIfMissing);
extern void
DT__FreeProperty(Property *prop);
trunk/i386/libsaio/allocate.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/*
* Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* Portions Copyright (c) 2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
* Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
*
* The Original Code and all software distributed under the License are
* distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
* License for the specific language governing rights and limitations
* under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
#include "sl.h"
#include "saio_internal.h"
#include "bootstruct.h"
#include "device_tree.h"
static long gImageLastKernelAddr;
#define kPageSize 4096
#define RoundPage(x) ((((unsigned)(x)) + kPageSize - 1) & ~(kPageSize - 1))
long
AllocateMemoryRange(char * rangeName, long start, long length, long type)
{
char *nameBuf;
uint32_t *buffer;
nameBuf = malloc(strlen(rangeName) + 1);
if (nameBuf == 0) return -1;
strcpy(nameBuf, rangeName);
buffer = malloc(2 * sizeof(uint32_t));
if (buffer == 0) return -1;
buffer[0] = start;
buffer[1] = length;
DT__AddProperty(gMemoryMapNode, nameBuf, 2 * sizeof(uint32_t), (char *)buffer);
return 0;
}
long
AllocateKernelMemory( long inSize )
{
long addr;
if (gImageLastKernelAddr == 0) {
gImageLastKernelAddr = RoundPage( bootArgs->kaddr +
bootArgs->ksize );
}
addr = gImageLastKernelAddr;
gImageLastKernelAddr += RoundPage(inSize);
if ( gImageLastKernelAddr >= (KERNEL_ADDR + KERNEL_LEN) ) {
stop ("AllocateKernelMemory error");
}
bootArgs->ksize = gImageLastKernelAddr - bootArgs->kaddr;
return addr;
}
trunk/i386/libsaio/hfs.h
3030
3131
3232
33
33
extern long HFSGetFileBlock(CICell ih, char *str, unsigned long long *firstBlock);
extern long HFSGetUUID(CICell ih, char *uuidStr);
extern void HFSFree(CICell ih);
extern BOOL HFSProbe (const void *buf);
extern bool HFSProbe (const void *buf);
trunk/i386/libsaio/spd.c
11
2
23
3
4
45
56
67
......
1819
1920
2021
21
22
2223
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
24
7025
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/*
* Copyright 2010 AsereBLN. All rights reserved. <aserebln@googlemail.com>
*
*
* spd.c - obtain serial presene detect memory information
*/
#include "libsaio.h"
#define DBG(x...)
#endif
static const char *spd_memory_types[] =
void scan_spd(PlatformInfo_t *p)
{
"RAM", /* 00h Undefined */
"FPM", /* 01h FPM */
"EDO", /* 02h EDO */
"",/* 03h PIPELINE NIBBLE */
"SDRAM", /* 04h SDRAM */
"",/* 05h MULTIPLEXED ROM */
"DDR SGRAM",/* 06h SGRAM DDR */
"DDR SDRAM",/* 07h SDRAM DDR */
"DDR2 SDRAM", /* 08h SDRAM DDR 2 */
"",/* 09h Undefined */
"",/* 0Ah Undefined */
"DDR3 SDRAM", /* 0Bh SDRAM DDR 3 */
};
#define rdtsc(low,high) \
__asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high))
#define SMBHSTSTS 0
#define SMBHSTCNT 2
#define SMBHSTCMD 3
#define SMBHSTADD 4
#define SMBHSTDAT 5
unsigned char smb_read_byte_intel(uint32_t base, uint8_t adr, uint8_t cmd)
{
int l1, h1, l2, h2;
unsigned long long t;
outb(base + SMBHSTSTS, 0x1f);// reset SMBus Controller
outb(base + SMBHSTDAT, 0xff);
while( inb(base + SMBHSTSTS) & 0x01);// wait until ready
outb(base + SMBHSTCMD, cmd);
outb(base + SMBHSTADD, (adr << 1) | 0x01 );
outb(base + SMBHSTCNT, 0x48 );
rdtsc(l1, h1);
while (!( inb(base + SMBHSTSTS) & 0x02))// wait til command finished
{
rdtsc(l2, h2);
t = ((h2 - h1) * 0xffffffff + (l2 - l1)) / (Platform.CPU.TSCFrequency / 40);
if (t > 10)
break;// break after 10ms
}
return inb(base + SMBHSTDAT);
/* NYI */
}
static void read_smb_intel(pci_dt_t *smbus_dev)
{
int i, x;
uint8_tspd_size;
uint32_tbase;
RamSlotInfo_t*slot;
base = pci_config_read16(smbus_dev->dev.addr, 0x20) & 0xFFFE;
// Search MAX_RAM_SLOTS slots
for (i = 0; i < 6; i++)
{
slot = &Platform.RAM.DIMM[i];
spd_size = smb_read_byte_intel(base, 0x50 + i, 0);
// Check spd is present
if (spd_size != 0xff)
{
slot->InUse = YES;
slot->spd = malloc(spd_size);
if (slot->spd)
{
bzero(slot->spd, spd_size);
// Copy spd data into buffer
for (x = 0; x < spd_size; x++)
slot->spd[x] = smb_read_byte_intel(base, 0x50 + i, x);
switch (slot->spd[SPD_MEMORY_TYPE])
{
case SPD_MEMORY_TYPE_SDRAM_DDR2:
slot->ModuleSize = ((1 << (slot->spd[SPD_NUM_ROWS] & 0x0f) + (slot->spd[SPD_NUM_COLUMNS] & 0x0f) - 17) *
((slot->spd[SPD_NUM_DIMM_BANKS] & 0x7) + 1) * slot->spd[SPD_NUM_BANKS_PER_SDRAM]);
break;
case SPD_MEMORY_TYPE_SDRAM_DDR3:
slot->ModuleSize = ((slot->spd[4] & 0x0f) + 28 ) + ((slot->spd[8] & 0x7) + 3 );
slot->ModuleSize -= (slot->spd[7] & 0x7) + 25;
slot->ModuleSize = ((1 << slot->ModuleSize) * (((slot->spd[7] >> 3) & 0x1f) + 1));
break;
}
}
verbose(" slot %d - %dMB %s SPD %d bytes at %x\n", i, slot->ModuleSize,
spd_memory_types[(uint8_t)slot->spd[SPD_MEMORY_TYPE]],
spd_size, slot->spd);
}
}
}
static struct smbus_controllers_t smbus_controllers[] = {
{0x8086, 0x5032, "EP80579", read_smb_intel },
{0x8086, 0x269B, "ESB2", read_smb_intel },
{0x8086, 0x25A4, "6300ESB", read_smb_intel },
{0x8086, 0x24C3, "ICH4", read_smb_intel },
{0x8086, 0x24D3, "ICH5", read_smb_intel },
{0x8086, 0x266A, "ICH6", read_smb_intel },
{0x8086, 0x27DA, "ICH7", read_smb_intel },
{0x8086, 0x283E, "ICH8", read_smb_intel },
{0x8086, 0x2930, "ICH9", read_smb_intel },
{0x8086, 0x3A30, "ICH10R", read_smb_intel },
{0x8086, 0x3A60, "ICH10B", read_smb_intel },
{0x8086, 0x3B30, "P55", read_smb_intel },
};
void scan_smbus_controller(pci_dt_t *smbus_dev)
{
inti;
for( i = 1; i < sizeof(smbus_controllers) / sizeof(smbus_controllers[0]); i++ )
if (( smbus_controllers[i].vendor == smbus_dev->vendor_id)
&& ( smbus_controllers[i].device == smbus_dev->device_id))
{
verbose("%s%s SMBus Controller [%4x:%4x] at %02x:%02x.%x\n",
(smbus_dev->vendor_id == 0x8086) ? "Intel(R) " : "",
smbus_controllers[i].name,
smbus_dev->vendor_id, smbus_dev->device_id,
smbus_dev->dev.bits.bus, smbus_dev->dev.bits.dev, smbus_dev->dev.bits.func);
smbus_controllers[i].read_smb(smbus_dev);
}
}
trunk/i386/libsaio/spd.h
11
2
23
3
4
45
56
67
78
89
9
10
1011
11
12
1213
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
15614
/*
* Copyright 2010 AsereBLN. All rights reserved. <aserebln@googlemail.com>
*
*
* spd.h
*/
#ifndef __LIBSAIO_SPD_H
#define __LIBSAIO_SPD_H
#include "libsaio.h"
#include "platform.h"
void scan_smbus_controller(pci_dt_t *smbus_dev);
extern void scan_spd(PlatformInfo_t *p);
struct smbus_controllers_t {
uint32_tvendor;
uint32_tdevice;
char*name;
void (*read_smb)(pci_dt_t *smbus_dev);
};
/*
* Serial Presence Detect (SPD) data stored on SDRAM modules.
*
* Datasheet:
* - Name: PC SDRAM Serial Presence Detect (SPD) Specification
* Revision 1.2A, December, 1997
* - PDF: http://www.intel.com/design/chipsets/memory/spdsd12a.pdf
*
* Datasheet (alternative):
* - Name: SERIAL PRESENCE DETECT STANDARD, General Standard
* JEDEC Standard No. 21-C
* - PDF: http://www.jedec.org/download/search/4_01_02_00R9.PDF
*/
/* Byte numbers. */
#define SPD_NUM_MANUFACTURER_BYTES 0 /* Number of bytes used by module manufacturer */
#define SPD_TOTAL_SPD_MEMORY_SIZE 1 /* Total SPD memory size */
#define SPD_MEMORY_TYPE 2 /* (Fundamental) memory type */
#define SPD_NUM_ROWS 3 /* Number of row address bits */
#define SPD_NUM_COLUMNS 4 /* Number of column address bits */
#define SPD_NUM_DIMM_BANKS 5 /* Number of module rows (banks) */
#define SPD_MODULE_DATA_WIDTH_LSB 6 /* Module data width (LSB) */
#define SPD_MODULE_DATA_WIDTH_MSB 7 /* Module data width (MSB) */
#define SPD_MODULE_VOLTAGE 8 /* Module interface signal levels */
#define SPD_MIN_CYCLE_TIME_AT_CAS_MAX 9 /* SDRAM cycle time (highest CAS latency), RAS access time (tRAC) */
#define SPD_ACCESS_TIME_FROM_CLOCK 10 /* SDRAM access time from clock (highest CAS latency), CAS access time (Tac, tCAC) */
#define SPD_DIMM_CONFIG_TYPE 11 /* Module configuration type */
#define SPD_REFRESH 12 /* Refresh rate/type */
#define SPD_PRIMARY_SDRAM_WIDTH 13 /* SDRAM width (primary SDRAM) */
#define SPD_ERROR_CHECKING_SDRAM_WIDTH 14 /* Error checking SDRAM (data) width */
#define SPD_MIN_CLOCK_DELAY_B2B_RAND_COLUMN 15 /* SDRAM device attributes, minimum clock delay for back to back random column */
#define SPD_SUPPORTED_BURST_LENGTHS 16 /* SDRAM device attributes, burst lengths supported */
#define SPD_NUM_BANKS_PER_SDRAM 17 /* SDRAM device attributes, number of banks on SDRAM device */
#define SPD_ACCEPTABLE_CAS_LATENCIES 18 /* SDRAM device attributes, CAS latency */
#define SPD_CS_LATENCY 19 /* SDRAM device attributes, CS latency */
#define SPD_WE_LATENCY 20 /* SDRAM device attributes, WE latency */
#define SPD_MODULE_ATTRIBUTES 21 /* SDRAM module attributes */
#define SPD_DEVICE_ATTRIBUTES_GENERAL 22 /* SDRAM device attributes, general */
#define SPD_SDRAM_CYCLE_TIME_2ND 23 /* SDRAM cycle time (2nd highest CAS latency) */
#define SPD_ACCESS_TIME_FROM_CLOCK_2ND 24 /* SDRAM access from clock (2nd highest CAS latency) */
#define SPD_SDRAM_CYCLE_TIME_3RD 25 /* SDRAM cycle time (3rd highest CAS latency) */
#define SPD_ACCESS_TIME_FROM_CLOCK_3RD 26 /* SDRAM access from clock (3rd highest CAS latency) */
#define SPD_MIN_ROW_PRECHARGE_TIME 27 /* Minimum row precharge time (Trp) */
#define SPD_MIN_ROWACTIVE_TO_ROWACTIVE 28 /* Minimum row active to row active (Trrd) */
#define SPD_MIN_RAS_TO_CAS_DELAY 29 /* Minimum RAS to CAS delay (Trcd) */
#define SPD_MIN_ACTIVE_TO_PRECHARGE_DELAY 30 /* Minimum RAS pulse width (Tras) */
#define SPD_DENSITY_OF_EACH_ROW_ON_MODULE 31 /* Density of each row on module */
#define SPD_CMD_SIGNAL_INPUT_SETUP_TIME 32 /* Command and address signal input setup time */
#define SPD_CMD_SIGNAL_INPUT_HOLD_TIME 33 /* Command and address signal input hold time */
#define SPD_DATA_SIGNAL_INPUT_SETUP_TIME 34 /* Data signal input setup time */
#define SPD_DATA_SIGNAL_INPUT_HOLD_TIME 35 /* Data signal input hold time */
#define SPD_WRITE_RECOVERY_TIME 36 /* Write recovery time (tWR) */
#define SPD_INT_WRITE_TO_READ_DELAY 37 /* Internal write to read command delay (tWTR) */
#define SPD_INT_READ_TO_PRECHARGE_DELAY 38 /* Internal read to precharge command delay (tRTP) */
#define SPD_MEM_ANALYSIS_PROBE_PARAMS 39 /* Memory analysis probe characteristics */
#define SPD_BYTE_41_42_EXTENSION 40 /* Extension of byte 41 (tRC) and byte 42 (tRFC) */
#define SPD_MIN_ACT_TO_ACT_AUTO_REFRESH 41 /* Minimum active to active auto refresh (tRCmin) */
#define SPD_MIN_AUTO_REFRESH_TO_ACT 42 /* Minimum auto refresh to active/auto refresh (tRFC) */
#define SPD_MAX_DEVICE_CYCLE_TIME 43 /* Maximum device cycle time (tCKmax) */
#define SPD_MAX_DQS_DQ_SKEW 44 /* Maximum skew between DQS and DQ (tDQSQ) */
#define SPD_MAX_READ_DATAHOLD_SKEW 45 /* Maximum read data-hold skew factor (tQHS) */
#define SPD_PLL_RELOCK_TIME 46 /* PLL relock time */
#define SPD_SPD_DATA_REVISION_CODE 62 /* SPD data revision code */
#define SPD_CHECKSUM_FOR_BYTES_0_TO_62 63 /* Checksum for bytes 0-62 */
#define SPD_MANUFACTURER_JEDEC_ID_CODE 64 /* Manufacturer's JEDEC ID code, per EIA/JEP106 (bytes 64-71) */
#define SPD_MANUFACTURING_LOCATION 72 /* Manufacturing location */
#define SPD_MANUFACTURER_PART_NUMBER 73 /* Manufacturer's part number, in 6-bit ASCII (bytes 73-90) */
#define SPD_REVISION_CODE 91 /* Revision code (bytes 91-92) */
#define SPD_MANUFACTURING_DATE 93 /* Manufacturing date (byte 93: year, byte 94: week) */
#define SPD_ASSEMBLY_SERIAL_NUMBER 95 /* Assembly serial number (bytes 95-98) */
#define SPD_MANUFACTURER_SPECIFIC_DATA 99 /* Manufacturer specific data (bytes 99-125) */
#define SPD_INTEL_SPEC_FOR_FREQUENCY 126 /* Intel specification for frequency */
#define SPD_INTEL_SPEC_100_MHZ 127 /* Intel specification details for 100MHz support */
/* DRAM specifications use the following naming conventions for SPD locations */
#define SPD_tRP SPD_MIN_ROW_PRECHARGE_TIME
#define SPD_tRRD SPD_MIN_ROWACTIVE_TO_ROWACTIVE
#define SPD_tRCD SPD_MIN_RAS_TO_CAS_DELAY
#define SPD_tRAS SPD_MIN_ACTIVE_TO_PRECHARGE_DELAY
#define SPD_BANK_DENSITY SPD_DENSITY_OF_EACH_ROW_ON_MODULE
#define SPD_ADDRESS_CMD_HOLD SPD_CMD_SIGNAL_INPUT_HOLD_TIME
#define SPD_tRC41/* SDRAM Device Minimum Active to Active/Auto Refresh Time (tRC) */
#define SPD_tRFC42/* SDRAM Device Minimum Auto Refresh to Active/Auto Refresh (tRFC) */
/* SPD_MEMORY_TYPE values. */
#define SPD_MEMORY_TYPE_FPM_DRAM1
#define SPD_MEMORY_TYPE_EDO2
#define SPD_MEMORY_TYPE_PIPELINED_NIBBLE3
#define SPD_MEMORY_TYPE_SDRAM4
#define SPD_MEMORY_TYPE_MULTIPLEXED_ROM5
#define SPD_MEMORY_TYPE_SGRAM_DDR6
#define SPD_MEMORY_TYPE_SDRAM_DDR7
#define SPD_MEMORY_TYPE_SDRAM_DDR28
#define SPD_MEMORY_TYPE_SDRAM_DDR30xb
/* SPD_MODULE_VOLTAGE values. */
#define SPD_VOLTAGE_TTL0 /* 5.0 Volt/TTL */
#define SPD_VOLTAGE_LVTTL1 /* LVTTL */
#define SPD_VOLTAGE_HSTL2 /* HSTL 1.5 */
#define SPD_VOLTAGE_SSTL33 /* SSTL 3.3 */
#define SPD_VOLTAGE_SSTL24 /* SSTL 2.5 */
/* SPD_DIMM_CONFIG_TYPE values. */
#define ERROR_SCHEME_NONE0
#define ERROR_SCHEME_PARITY1
#define ERROR_SCHEME_ECC2
/* SPD_ACCEPTABLE_CAS_LATENCIES values. */
// TODO: Check values.
#define SPD_CAS_LATENCY_1_00x01
#define SPD_CAS_LATENCY_1_50x02
#define SPD_CAS_LATENCY_2_00x04
#define SPD_CAS_LATENCY_2_50x08
#define SPD_CAS_LATENCY_3_00x10
#define SPD_CAS_LATENCY_3_50x20
#define SPD_CAS_LATENCY_4_00x40
#define SPD_CAS_LATENCY_DDR2_3(1 << 3)
#define SPD_CAS_LATENCY_DDR2_4(1 << 4)
#define SPD_CAS_LATENCY_DDR2_5(1 << 5)
#define SPD_CAS_LATENCY_DDR2_6(1 << 6)
/* SPD_SUPPORTED_BURST_LENGTHS values. */
#define SPD_BURST_LENGTH_11
#define SPD_BURST_LENGTH_22
#define SPD_BURST_LENGTH_44
#define SPD_BURST_LENGTH_88
#define SPD_BURST_LENGTH_PAGE(1 << 7)
/* SPD_MODULE_ATTRIBUTES values. */
#define MODULE_BUFFERED1
#define MODULE_REGISTERED2
#endif /* !__LIBSAIO_SPD_H */
trunk/i386/libsaio/Makefile
44
55
66
7
78
89
910
1011
11
12
13
1214
1315
14
16
1517
1618
1719
1820
1921
2022
21
23
2224
2325
2426
......
3335
3436
3537
36
38
3739
3840
3941
40
42
4143
4244
43
45
4446
4547
4648
UTILDIR = ../util
LIBSADIR = ../libsa
BOOT2DIR = ../boot2
INSTALLDIR = $(DSTROOT)/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders/standalone
#SYMROOT=
OPTIM = -Os -Oz
DEBUG = NOTHING
DEBUG = -DNOTHING
#DEBUG = -DDEBUG_CPU=1 -DDEBUG_MEM=1 -DDEBUG_SPD=1 -DDEBUG_PCI=1 -DDEBUG_SMBIOS=1
CFLAGS= $(RC_CFLAGS) $(OPTIM) $(MORECPP) -arch i386 -g -Wmost \
-D__ARCHITECTURE__=\"i386\" -DSAIO_INTERNAL_USER \
-DRCZ_COMPRESSED_FILE_SUPPORT -D$(DEBUG) \
-DRCZ_COMPRESSED_FILE_SUPPORT $(DEBUG) \
-fno-builtin -static $(OMIT_FRAME_POINTER_CFLAG) \
-mpreferred-stack-boundary=2 -fno-align-functions -fno-stack-protector \
-march=pentium4 -msse2 -mfpmath=sse -msoft-float
DEFINES=
CONFIG = hd
INC = -I. -I$(SYMROOT) -I$(UTILDIR) -I$(LIBSADIR)
INC = -I. -I$(SYMROOT) -I$(UTILDIR) -I$(LIBSADIR) -I$(BOOT2DIR)
ifneq "" "$(wildcard /bin/mkdirs)"
MKDIRS = /bin/mkdirs
else
SAIO_OBJS = table.o asm.o bios.o biosfn.o \
disk.o sys.o cache.o bootstruct.o \
stringTable.o load.o pci.o memory.o misc.o \
stringTable.o load.o pci.o allocate.o misc.o \
ufs.o ufs_byteorder.o \
vbe.o nbp.o hfs.o hfs_compare.o \
xml.o ntfs.o msdos.o md5c.o device_tree.o \
freq_detect.o platform.o dsdt_patcher.o \
cpu.o platform.o dsdt_patcher.o \
smbios_patcher.o fake_efi.o ext2fs.o \
hpet.o spd.o usb.o pci_setup.o \
device_inject.o nvidia.o ati.o
device_inject.o nvidia.o ati.o pci_root.o mem.o
SAIO_EXTERN_OBJS = console.o
trunk/i386/libsaio/SMBIOS.h
3939
4040
4141
42
43
44
45
46
47
4248
4349
4450
typedef UInt32 SMBDWord;
typedef UInt64 SMBQWord;
struct DMIHeader{
SMBByte type;
SMBByte length;
SMBWord handle;
} __attribute__((packed));
struct DMIEntryPoint {
SMBByte anchor[5];
SMBByte checksum;
trunk/i386/libsaio/smbios_patcher.c
33
44
55
6
6
77
8
89
910
1011
......
2425
2526
2627
27
28
2829
29
30
31
32
33
34
35
36
30
31
32
33
34
35
36
37
3738
3839
3940
4041
4142
42
43
4344
44
45
46
47
48
49
50
51
45
46
47
48
49
50
51
52
5253
5354
5455
5556
5657
57
58
5859
59
60
61
62
63
64
65
66
60
61
62
63
64
65
66
67
6768
6869
6970
7071
7172
72
73
7374
74
75
76
77
78
79
80
81
75
76
77
78
79
80
81
82
8283
8384
8485
8586
8687
87
88
8889
89
90
91
92
93
94
95
96
90
91
92
93
94
95
96
97
9798
9899
99100
100101
101102
102
103
103
104
104105
105
106
107
106
107
108108
109109
110110
111111
112
113
114
115
116
117
112
113
114
115
116
118117
118
119119
120
121
120
121
122122
123
124
123125
124126
125127
......
127129
128130
129131
130
132
131133
132134
133135
134136
135137
136138
137
138
139
140139
141140
142141
143142
144143
145
146
147
144
148145
149
146
150147
151
148
152149
153
150
154151
152
155153
156154
157155
158156
159
160
161
162
157
158
159
160
161
162
163
163164
164165
165166
166167
167
168
169
170
168
169
170
171
171172
172173
173174
174
175
176
177
178
179
180
181
182
175183
176184
177185
178186
179187
188
189
190
191
192
193
194
180195
181196
182197
183198
184199
200
201
202
203
204
205
206
185207
186208
187209
......
198220
199221
200222
201
202
203
223
224
225
204226
205227
206
207
208
209
210
211
228
229
230
231
232
233
212234
213235
214
215
216
236
237
238
217239
218240
219241
......
227249
228250
229251
230
252
231253
232254
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
263282
264283
265284
266
267
285
268286
269
270
271
272
273
274
275
287
288
289
290
291
292
293
276294
277
295
278296
279
280
281
282
283
284
285
286
297
298
299
300
301
302
303
304
305
306
307
287308
288
289
290
291
292
293
294
295
296
297
298
309
310
311
312
313
314
315
316
317
318
319
320
299321
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
341345
342
343
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
344368
345
369
346370
347
371
372
348373
349374
350375
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
386408
387
388
409
410
411
389412
390
391
392
413
414
415
416
393417
394418
395419
......
397421
398422
399423
400
401
402
424
403425
404
426
405427
406
428
407429
408430
409431
410432
411433
412
434
413435
414
436
437
438
439
415440
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
446466
447
467
468
469
448470
449
450
471
472
473
451474
452
453
475
476
454477
455
456
457
458
459
460
461
462
463
464
465
466
467
478
479
480
481
482
483
484
485
486
487
468488
469
470
489
490
471491
472
473
474
475
492
493
494
495
496
497
498
499
500
501
502
476503
477
478
479
480
481
482
483
484
485
486
487504
488
505
489506
490
491
507
508
492509
493
494
495
496
510
511
512
513
497514
498
499
500
501
502
515
516
517
518
519
520
503521
504
522
523
505524
506
525
526
507527
508
509
510
528
529
530
511531
512
513
532
533
514534
515535
516536
517537
518
538
519539
520
521
522
523
524
525
540
541
542
543
544
545
546
526547
527
548
528549
529
530
531
532
533
534
550
551
552
553
554
555
556
535557
558
536559
537560
538
539
540
561
562
541563
542564
543
565
544566
545567
546568
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
565587
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
584603
585
586
604
605
587606
588
589
590
591
607
608
609
610
611
612
613
614
615
616
617
592618
593
594
595
596
597
598
599
600
601
602619
603
620
604621
605
606
622
623
607624
608
609
610
611
625
626
627
628
629
612630
613
614
615
616
617
631
632
633
634
635
636
618637
619
638
639
620640
621
641
642
622643
623
624
625
644
645
646
626647
627
628
648
649
629650
630651
631652
632653
633654
634655
635
636
637
638
639
640
656
657
658
659
660
661
662
641663
642664
643665
644
645
646
647
648
649
666
667
668
669
670
671
672
650673
674
651675
652676
653
654
655
677
678
656679
657680
658
681
659682
660683
661684
662685
663
664
665
666
667
686
687
688
689
690
668691
669692
670
671
693
672694
673
674
675
676695
677696
678
679697
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
698
700699
701700
702701
*/
#include "libsaio.h"
#include "acpi.h"
#include "boot.h"
#include "bootstruct.h"
#include "acpi.h"
#include "efi_tables.h"
#include "fake_efi.h"
#include "platform.h"
// defaults for a MacBook
static char sm_macbook_defaults[][2][40]={
{"SMbiosvendor","Apple Inc."},
{"SMbiosvendor","Apple Inc."},
{"SMbiosversion","MB41.88Z.0073.B00.0809221748"},
{"SMbiosdate","04/01/2008"},
{"SMmanufacter","Apple Inc."},
{"SMproductname","MacBook4,1"},
{"SMsystemversion","1.0"},
{"SMserial","SOMESRLNMBR"},
{"SMfamily","MacBook"},
{"SMboardmanufacter","Apple Inc."},
{"SMboardproduct","Mac-F42D89C8"},
{"SMbiosdate","04/01/2008"},
{"SMmanufacter","Apple Inc."},
{"SMproductname","MacBook4,1"},
{"SMsystemversion","1.0"},
{"SMserial","SOMESRLNMBR"},
{"SMfamily","MacBook"},
{"SMboardmanufacter","Apple Inc."},
{"SMboardproduct","Mac-F42D89C8"},
{ "",""}
};
// defaults for a MacBook Pro
static char sm_macbookpro_defaults[][2][40]={
{"SMbiosvendor","Apple Inc."},
{"SMbiosvendor","Apple Inc."},
{"SMbiosversion","MBP41.88Z.0073.B00.0809221748"},
{"SMbiosdate","04/01/2008"},
{"SMmanufacter","Apple Inc."},
{"SMproductname","MacBookPro4,1"},
{"SMsystemversion","1.0"},
{"SMserial","SOMESRLNMBR"},
{"SMfamily","MacBookPro"},
{"SMboardmanufacter","Apple Inc."},
{"SMboardproduct","Mac-F42D89C8"},
{"SMbiosdate","04/01/2008"},
{"SMmanufacter","Apple Inc."},
{"SMproductname","MacBookPro4,1"},
{"SMsystemversion","1.0"},
{"SMserial","SOMESRLNMBR"},
{"SMfamily","MacBookPro"},
{"SMboardmanufacter","Apple Inc."},
{"SMboardproduct","Mac-F42D89C8"},
{ "",""}
};
// defaults for a Mac mini
static char sm_macmini_defaults[][2][40]={
{"SMbiosvendor","Apple Inc."},
{"SMbiosvendor","Apple Inc."},
{"SMbiosversion","MM21.88Z.009A.B00.0706281359"},
{"SMbiosdate","04/01/2008"},
{"SMmanufacter","Apple Inc."},
{"SMproductname","Macmini2,1"},
{"SMsystemversion","1.0"},
{"SMserial","SOMESRLNMBR"},
{"SMfamily","Napa Mac"},
{"SMboardmanufacter","Apple Inc."},
{"SMboardproduct","Mac-F4208EAA"},
{"SMbiosdate","04/01/2008"},
{"SMmanufacter","Apple Inc."},
{"SMproductname","Macmini2,1"},
{"SMsystemversion","1.0"},
{"SMserial","SOMESRLNMBR"},
{"SMfamily","Napa Mac"},
{"SMboardmanufacter","Apple Inc."},
{"SMboardproduct","Mac-F4208EAA"},
{ "",""}
};
// defaults for an iMac
static char sm_imac_defaults[][2][40]={
{"SMbiosvendor","Apple Inc."},
{"SMbiosvendor","Apple Inc."},
{"SMbiosversion","IM81.88Z.00C1.B00.0802091538"},
{"SMbiosdate","04/01/2008"},
{"SMmanufacter","Apple Inc."},
{"SMproductname","iMac8,1"},
{"SMsystemversion","1.0"},
{"SMserial","SOMESRLNMBR"},
{"SMfamily","Mac"},
{"SMboardmanufacter","Apple Inc."},
{"SMboardproduct","Mac-F227BEC8"},
{"SMbiosdate","04/01/2008"},
{"SMmanufacter","Apple Inc."},
{"SMproductname","iMac8,1"},
{"SMsystemversion","1.0"},
{"SMserial","SOMESRLNMBR"},
{"SMfamily","Mac"},
{"SMboardmanufacter","Apple Inc."},
{"SMboardproduct","Mac-F227BEC8"},
{ "",""}
};
// defaults for a Mac Pro
static char sm_macpro_defaults[][2][40]={
{"SMbiosvendor","Apple Computer, Inc."},
{"SMbiosvendor","Apple Computer, Inc."},
{"SMbiosversion","MP31.88Z.006C.B05.0802291410"},
{"SMbiosdate","04/01/2008"},
{"SMmanufacter","Apple Computer, Inc."},
{"SMproductname","MacPro3,1"},
{"SMsystemversion","1.0"},
{"SMserial","SOMESRLNMBR"},
{"SMfamily","MacPro"},
{"SMboardmanufacter","Apple Computer, Inc."},
{"SMboardproduct","Mac-F4208DC8"},
{"SMbiosdate","04/01/2008"},
{"SMmanufacter","Apple Computer, Inc."},
{"SMproductname","MacPro3,1"},
{"SMsystemversion","1.0"},
{"SMserial","SOMESRLNMBR"},
{"SMfamily","MacPro"},
{"SMboardmanufacter","Apple Computer, Inc."},
{"SMboardproduct","Mac-F4208DC8"},
{ "",""}
};
static char *sm_get_defstr(char *name, int table_num)
{
int i;
char (*sm_defaults)[2][40];
inti;
char(*sm_defaults)[2][40];
if (Platform.CPU.Mobile)
if (Platform.CPU.NoCores > 1)
{
if (platformCPUFeature(CPU_FEATURE_MOBILE)) {
if (Platform.CPU.NoCores > 1) {
sm_defaults=sm_macbookpro_defaults;
} else {
sm_defaults=sm_macbook_defaults;
}
else
switch (Platform.CPU.NoCores)
{
case 1: sm_defaults=sm_macmini_defaults; break;
case 2: sm_defaults=sm_imac_defaults; break;
default: sm_defaults=sm_macpro_defaults; break;
} else {
switch (Platform.CPU.NoCores) {
case 1: sm_defaults=sm_macmini_defaults; break;
case 2: sm_defaults=sm_imac_defaults; break;
default: sm_defaults=sm_macpro_defaults; break;
}
}
for (i=0;sm_defaults[i][0][0];i++)
if (!strcmp (sm_defaults[i][0],name))
for (i=0;sm_defaults[i][0][0];i++) {
if (!strcmp (sm_defaults[i][0],name)) {
return sm_defaults[i][1];
}
}
// Shouldn't happen
printf ("Error: no default for '%s' known\n", name);
return "";
}
static int sm_get_fsb (char *name, int table_num)
static int sm_get_fsb(char *name, int table_num)
{
return Platform.CPU.FSBFrequency/1000000;
}
static int sm_get_cpu (char *name, int table_num)
{
/* round CPU frequency */
//return round2(Platform.CPU.CPUFrequency/1000000, 10);
//return roundup2(Platform.CPU.CPUFrequency/1000000, 100);
return Platform.CPU.CPUFrequency/1000000;
}
static int sm_get_cputype (char *name, int table_num)
{
int cores = Platform.CPU.NoCores;
if (cores == 1)
if (Platform.CPU.NoCores == 1) {
return 0x0101; // <01 01> Intel Core Solo?
else if (cores == 2)
} else if (Platform.CPU.NoCores == 2) {
return 0x0301; // <01 03> Intel Core 2 Duo
else if (cores >= 4)
} else if (Platform.CPU.NoCores >= 4) {
return 0x0501; // <01 05> Quad-Core Intel Xeon
else
} else {
return 0x0301; // Default to Core 2 Duo
}
}
static int sm_get_memtype (char *name, int table_num)
{
if(Platform.RAM.Type)
return Platform.RAM.Type;
else
return SMB_MEM_TYPE_DDR2;
if (table_num < MAX_RAM_SLOTS &&
Platform.RAM.DIMM[table_num].InUse &&
Platform.RAM.DIMM[table_num].Type != 0)
{
return Platform.RAM.DIMM[table_num].Type;
}
return SMB_MEM_TYPE_DDR2;
}
static int sm_get_memspeed (char *name, int table_num)
{
if(Platform.RAM.Type)
return round2( Platform.RAM.Frequency / 500000, 2);
else
return 667;
if (Platform.RAM.Frequency != 0) {
return Platform.RAM.Frequency/1000000;
}
return 667;
}
static char *sm_get_memvendor (char *name, int table_num)
{
{
if (table_num < MAX_RAM_SLOTS &&
Platform.RAM.DIMM[table_num].InUse &&
strlen(Platform.RAM.DIMM[table_num].Vendor) > 0)
{
DBG("Vendor[%d]='%s'\n", table_num, Platform.RAM.DIMM[table_num].Vendor);
return Platform.RAM.DIMM[table_num].Vendor;
}
return "N/A";
}
static char *sm_get_memserial (char *name, int table_num)
{
if (table_num < MAX_RAM_SLOTS &&
Platform.RAM.DIMM[table_num].InUse &&
strlen(Platform.RAM.DIMM[table_num].SerialNo) > 0)
{
DBG("SerialNo[%d]='%s'\n", table_num, Platform.RAM.DIMM[table_num].SerialNo);
return Platform.RAM.DIMM[table_num].SerialNo;
}
return "N/A";
}
static char *sm_get_mempartno (char *name, int table_num)
{
if (table_num < MAX_RAM_SLOTS &&
Platform.RAM.DIMM[table_num].InUse &&
strlen(Platform.RAM.DIMM[table_num].PartNo) > 0)
{
DBG("PartNo[%d]='%s'\n", table_num, Platform.RAM.DIMM[table_num].PartNo);
return Platform.RAM.DIMM[table_num].PartNo;
}
return "N/A";
}
{.name="SMmanufacter",.table_type= 1,.value_type=SMSTRING,.offset=0x04,.auto_str=sm_get_defstr},
{.name="SMproductname",.table_type= 1,.value_type=SMSTRING,.offset=0x05,.auto_str=sm_get_defstr},
{.name="SMsystemversion",.table_type= 1,.value_type=SMSTRING,.offset=0x06,.auto_str=sm_get_defstr},
{.name="SMserial",.table_type= 1,.value_type=SMSTRING,.offset=0x07,.auto_str=sm_get_defstr},
{.name="SMUUID",.table_type= 1, .value_type=SMOWORD,.offset=0x08,.auto_oword=0},
{.name="SMfamily",.table_type= 1,.value_type=SMSTRING,.offset=0x1a,.auto_str=sm_get_defstr},
{.name="SMserial",.table_type= 1,.value_type=SMSTRING,.offset=0x07,.auto_str=sm_get_defstr},
{.name="SMUUID",.table_type= 1, .value_type=SMOWORD,.offset=0x08,.auto_oword=0},
{.name="SMfamily",.table_type= 1,.value_type=SMSTRING,.offset=0x1a,.auto_str=sm_get_defstr},
{.name="SMboardmanufacter",.table_type= 2, .value_type=SMSTRING,.offset=0x04,.auto_str=sm_get_defstr},
{.name="SMboardproduct",.table_type= 2, .value_type=SMSTRING,.offset=0x05,.auto_str=sm_get_defstr},
{.name="SMexternalclock",.table_type= 4,.value_type=SMWORD,.offset=0x12,.auto_int=sm_get_fsb},
{.name="SMmaximalclock",.table_type= 4,.value_type=SMWORD,.offset=0x14,.auto_int=sm_get_cpu},
{.name="SMmemdevloc",.table_type=17,.value_type=SMSTRING,.offset=0x10,.auto_str=0},
{.name="SMmembankloc",.table_type=17,.value_type=SMSTRING,.offset=0x11,.auto_str=0},
{.name="SMmemtype",.table_type=17,.value_type=SMBYTE,.offset=0x12,.auto_int=sm_get_memtype},
{.name="SMmemspeed",.table_type=17,.value_type=SMWORD,.offset=0x15,.auto_int=sm_get_memspeed},
{.name="SMexternalclock",.table_type= 4,.value_type=SMWORD,.offset=0x12,.auto_int=sm_get_fsb},
{.name="SMmaximalclock",.table_type= 4,.value_type=SMWORD,.offset=0x14,.auto_int=sm_get_cpu},
{.name="SMmemdevloc",.table_type=17,.value_type=SMSTRING,.offset=0x10,.auto_str=0},
{.name="SMmembankloc",.table_type=17,.value_type=SMSTRING,.offset=0x11,.auto_str=0},
{.name="SMmemtype",.table_type=17,.value_type=SMBYTE,.offset=0x12,.auto_int=sm_get_memtype},
{.name="SMmemspeed",.table_type=17,.value_type=SMWORD,.offset=0x15,.auto_int=sm_get_memspeed},
{.name="SMmemmanufacter",.table_type=17,.value_type=SMSTRING,.offset=0x17,.auto_str=sm_get_memvendor},
{.name="SMmemserial",.table_type=17,.value_type=SMSTRING,.offset=0x18,.auto_str=sm_get_memserial},
{.name="SMmempart",.table_type=17,.value_type=SMSTRING,.offset=0x1A,.auto_str=sm_get_mempartno},
{.name="SMcputype",.table_type=131,.value_type=SMWORD,.offset=0x04,.auto_int=sm_get_cputype},
{.name="SMbusspeed",.table_type=132,.value_type=SMWORD,.offset=0x04,.auto_str=0}
{.name="SMmempart",.table_type=17,.value_type=SMSTRING,.offset=0x1A,.auto_str=sm_get_mempartno},
{.name="SMcputype",.table_type=131,.value_type=SMWORD,.offset=0x04,.auto_int=sm_get_cputype},
{.name="SMbusspeed",.table_type=132,.value_type=SMWORD,.offset=0x04,.auto_str=0}
};
struct smbios_table_description smbios_table_descriptions[]=
{.type=132,.len=0x06,.numfunc=sm_one}
};
static inline struct SMBEntryPoint * getAddressOfSmbiosTable()
struct SMBEntryPoint *getAddressOfSmbiosTable(void)
{
/* First see if we can even find the damn SMBIOS table
* The logic here is to start at 0xf0000 and end at 0xfffff iterating 16 bytes at a time looking
* for the SMBIOS entry-point structure anchor (literal ASCII "_SM_").
*/
void *smbios_addr = (void*)SMBIOS_RANGE_START;
for(; (smbios_addr <= (void*)SMBIOS_RANGE_END) && (*(uint32_t*)smbios_addr != SMBIOS_ANCHOR_UINT32_LE); smbios_addr += 16)
;
if(smbios_addr <= (void*)SMBIOS_RANGE_END)
{
/* NOTE: The specification does not specifically state what to do in the event of finding an
* SMBIOS anchor on an invalid table. It might be better to move this code into the for loop
* so that searching can continue.
*/
uint8_t csum = checksum8(smbios_addr, sizeof(struct SMBEntryPoint));
/* The table already contains the checksum so we merely need to see if its checksum is now zero. */
if(csum != 0)
{
printf("Found SMBIOS anchor but bad table checksum. Assuming no SMBIOS.\n");
sleep(5);
smbios_addr = 0;
}
}
else
{
/* If this happens, it's possible that a PnP BIOS call can be done to retrieve the address of the table.
* The latest versions of the spec state that modern programs should not even attempt to do this. */
printf("Unable to find SMBIOS table.\n");
sleep(5);
smbios_addr = 0;
}
return smbios_addr;
* The logic here is to start at 0xf0000 and end at 0xfffff iterating 16 bytes at a time looking
* for the SMBIOS entry-point structure anchor (literal ASCII "_SM_").
*/
void *smbios_addr = (void*)SMBIOS_RANGE_START;
for (; (smbios_addr<=(void*)SMBIOS_RANGE_END) && (*(uint32_t*)smbios_addr!=SMBIOS_ANCHOR_UINT32_LE); smbios_addr+=16) ;
if (smbios_addr <= (void*)SMBIOS_RANGE_END) {
/* NOTE: The specification does not specifically state what to do in the event of finding an
* SMBIOS anchor on an invalid table. It might be better to move this code into the for loop
* so that searching can continue.
*/
uint8_t csum = checksum8(smbios_addr, sizeof(struct SMBEntryPoint));
/* The table already contains the checksum so we merely need to see if its checksum is now zero. */
if (csum != 0) {
printf("Found SMBIOS anchor but bad table checksum. Assuming no SMBIOS.\n");
sleep(5);
smbios_addr = 0;
}
} else {
/* If this happens, it's possible that a PnP BIOS call can be done to retrieve the address of the table.
* The latest versions of the spec state that modern programs should not even attempt to do this.
*/
printf("Unable to find SMBIOS table.\n");
sleep(5);
smbios_addr = 0;
}
return smbios_addr;
}
/* Compute necessary space requirements for new smbios */
struct SMBEntryPoint *
smbios_dry_run (struct SMBEntryPoint * origsmbios)
struct SMBEntryPoint *smbios_dry_run(struct SMBEntryPoint *origsmbios)
{
struct SMBEntryPoint *ret;
char *smbiostables=0;
char *tablesptr;
int origsmbiosnum=0;
int i, j;
int tablespresent[256];
BOOL do_auto=1;
struct SMBEntryPoint*ret;
char*smbiostables;
char*tablesptr;
intorigsmbiosnum;
inti, j;
inttablespresent[256];
booldo_auto=true;
getBoolForKey("SMBIOSdefaults",&do_auto,&bootInfo->bootConfig);
bzero(tablespresent, sizeof(tablespresent));
for (i=0;i<256;i++)
tablespresent[i]=0;
ret=(struct SMBEntryPoint *)AllocateKernelMemory(sizeof (struct SMBEntryPoint));
if (origsmbios)
{
smbiostables=(char *)origsmbios->dmi.tableAddress;
origsmbiosnum=origsmbios->dmi.structureCount;
}
getBoolForKey(kSMBIOSdefaults, &do_auto, &bootInfo->bootConfig);
ret = (struct SMBEntryPoint *)AllocateKernelMemory(sizeof(struct SMBEntryPoint));
if (origsmbios) {
smbiostables = (char *)origsmbios->dmi.tableAddress;
origsmbiosnum = origsmbios->dmi.structureCount;
} else {
smbiostables = NULL;
origsmbiosnum = 0;
}
// _SM_
ret->anchor[0]=0x5f;
ret->anchor[1]=0x53;
ret->anchor[2]=0x4d;
ret->anchor[3]=0x5f;
ret->entryPointLength=sizeof (*ret);
ret->majorVersion=2;
ret->minorVersion=1;
ret->maxStructureSize=0;
ret->entryPointRevision=0;
for (i=0;i<5;i++)
ret->formattedArea[i]=0;
ret->anchor[0] = 0x5f;
ret->anchor[1] = 0x53;
ret->anchor[2] = 0x4d;
ret->anchor[3] = 0x5f;
ret->entryPointLength = sizeof(*ret);
ret->majorVersion = 2;
ret->minorVersion = 1;
ret->maxStructureSize = 0;
ret->entryPointRevision = 0;
for (i=0;i<5;i++) {
ret->formattedArea[i] = 0;
}
//_DMI_
ret->dmi.anchor[0]=0x5f;
ret->dmi.anchor[1]=0x44;
ret->dmi.anchor[2]=0x4d;
ret->dmi.anchor[3]=0x49;
ret->dmi.anchor[4]=0x5f;
ret->dmi.tableLength=0;
ret->dmi.tableAddress=0;
ret->dmi.structureCount=0;
ret->dmi.bcdRevision=0x21;
tablesptr=smbiostables;
if (smbiostables)
for (i=0;i<origsmbiosnum;i++)
{
struct smbios_table_header *cur
=(struct smbios_table_header *) tablesptr;
char *stringsptr;
int stringlen;
tablesptr+=cur->length;
stringsptr=tablesptr;
for (;tablesptr[0]!=0 || tablesptr[1]!=0;tablesptr++);
tablesptr+=2;
stringlen=tablesptr-stringsptr-1;
if (stringlen==1)
stringlen=0;
for (j=0;j<sizeof (smbios_properties)/sizeof(smbios_properties[0]);
j++)
{
const char *str;
int size;
char altname[40];
sprintf (altname, "%s_%d",smbios_properties[j].name,
tablespresent[cur->type]+1);
if (smbios_properties[j].table_type==cur->type
&& smbios_properties[j].value_type==SMSTRING
&& (getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig)
|| getValueForKey(altname,&str, &size, &bootInfo->smbiosConfig)))
stringlen+=size+1;
else if (smbios_properties[j].table_type==cur->type
&& smbios_properties[j].value_type==SMSTRING
&& do_auto && smbios_properties[j].auto_str)
stringlen+=strlen(smbios_properties[j].auto_str(smbios_properties[j].name,tablespresent[cur->type]))+1;
ret->dmi.anchor[0] = 0x5f;
ret->dmi.anchor[1] = 0x44;
ret->dmi.anchor[2] = 0x4d;
ret->dmi.anchor[3] = 0x49;
ret->dmi.anchor[4] = 0x5f;
ret->dmi.tableLength = 0;
ret->dmi.tableAddress = 0;
ret->dmi.structureCount = 0;
ret->dmi.bcdRevision = 0x21;
tablesptr = smbiostables;
if (smbiostables) {
for (i=0; i<origsmbiosnum; i++) {
struct smbios_table_header*cur = (struct smbios_table_header *)tablesptr;
char*stringsptr;
intstringlen;
tablesptr += cur->length;
stringsptr = tablesptr;
for (; tablesptr[0]!=0 || tablesptr[1]!=0; tablesptr++);
tablesptr += 2;
stringlen = tablesptr - stringsptr - 1;
if (stringlen == 1) {
stringlen = 0;
}
if (stringlen==0)
stringlen=1;
for (j=0; j<sizeof(smbios_properties)/sizeof(smbios_properties[0]); j++) {
const char*str;
intsize;
charaltname[40];
sprintf(altname, "%s_%d",smbios_properties[j].name, tablespresent[cur->type] + 1);
if (smbios_properties[j].table_type == cur->type &&
smbios_properties[j].value_type == SMSTRING &&
(getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig) ||
getValueForKey(altname,&str, &size, &bootInfo->smbiosConfig)))
{
stringlen += size + 1;
} else if (smbios_properties[j].table_type == cur->type &&
smbios_properties[j].value_type == SMSTRING &&
do_auto && smbios_properties[j].auto_str)
{
stringlen += strlen(smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[cur->type])) + 1;
}
}
if (stringlen == 0) {
stringlen = 1;
}
stringlen++;
if (ret->maxStructureSize<cur->length+stringlen)
if (ret->maxStructureSize < cur->length+stringlen) {
ret->maxStructureSize=cur->length+stringlen;
ret->dmi.tableLength+=cur->length+stringlen;
}
ret->dmi.tableLength += cur->length+stringlen;
ret->dmi.structureCount++;
tablespresent[cur->type]++;
}
for (i=0;i<sizeof (smbios_table_descriptions)
/sizeof(smbios_table_descriptions[0]);i++)
{
int numnec=-1;
char buffer[40];
sprintf (buffer, "SMtable%d", i);
if (!getIntForKey(buffer,&numnec,&bootInfo->smbiosConfig))
numnec=-1;
if (numnec==-1 && do_auto && smbios_table_descriptions[i].numfunc)
numnec=smbios_table_descriptions[i].numfunc (smbios_table_descriptions[i].type);
while (tablespresent[smbios_table_descriptions[i].type]<numnec)
{
int stringlen=0;
for (j=0;j<sizeof (smbios_properties)/sizeof(smbios_properties[0]);
j++)
{
const char *str;
int size;
char altname[40];
sprintf (altname, "%s_%d",smbios_properties[j].name,
tablespresent[smbios_table_descriptions[i].type]+1);
if (smbios_properties[j].table_type
==smbios_table_descriptions[i].type
&& smbios_properties[j].value_type==SMSTRING
&& (getValueForKey(altname,&str, &size, &bootInfo->smbiosConfig)
|| getValueForKey(smbios_properties[j].name,&str, &size, &bootInfo->smbiosConfig)))
stringlen+=size+1;
else if (smbios_properties[j].table_type
==smbios_table_descriptions[i].type
&& smbios_properties[j].value_type==SMSTRING
&& do_auto && smbios_properties[j].auto_str)
stringlen+=strlen(smbios_properties[j].auto_str
(smbios_properties[j].name,
tablespresent[smbios_table_descriptions[i].type]))+1;
}
for (i=0; i<sizeof(smbios_table_descriptions)/sizeof(smbios_table_descriptions[0]); i++) {
intnumnec=-1;
charbuffer[40];
sprintf(buffer, "SMtable%d", i);
if (!getIntForKey(buffer, &numnec, &bootInfo->smbiosConfig)) {
numnec = -1;
}
if (numnec==-1 && do_auto && smbios_table_descriptions[i].numfunc) {
numnec = smbios_table_descriptions[i].numfunc(smbios_table_descriptions[i].type);
}
while (tablespresent[smbios_table_descriptions[i].type] < numnec) {
intstringlen = 0;
for (j=0; j<sizeof(smbios_properties)/sizeof(smbios_properties[0]); j++) {
const char*str;
intsize;
charaltname[40];
sprintf(altname, "%s_%d",smbios_properties[j].name, tablespresent[smbios_table_descriptions[i].type] + 1);
if (smbios_properties[j].table_type == smbios_table_descriptions[i].type &&
smbios_properties[j].value_type == SMSTRING &&
(getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||
getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig)))
{
stringlen += size + 1;
} else if (smbios_properties[j].table_type == smbios_table_descriptions[i].type &&
smbios_properties[j].value_type==SMSTRING &&
do_auto && smbios_properties[j].auto_str)
{
stringlen += strlen(smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[smbios_table_descriptions[i].type])) + 1;
}
}
if (stringlen==0)
stringlen=1;
if (stringlen == 0) {
stringlen = 1;
}
stringlen++;
if (ret->maxStructureSize<smbios_table_descriptions[i].len+stringlen)
ret->maxStructureSize=smbios_table_descriptions[i].len+stringlen;
ret->dmi.tableLength+=smbios_table_descriptions[i].len+stringlen;
if (ret->maxStructureSize < smbios_table_descriptions[i].len+stringlen) {
ret->maxStructureSize = smbios_table_descriptions[i].len + stringlen;
}
ret->dmi.tableLength += smbios_table_descriptions[i].len + stringlen;
ret->dmi.structureCount++;
tablespresent[smbios_table_descriptions[i].type]++;
}
return ret;
}
void
smbios_real_run (struct SMBEntryPoint * origsmbios,
struct SMBEntryPoint * newsmbios)
void smbios_real_run(struct SMBEntryPoint * origsmbios, struct SMBEntryPoint * newsmbios)
{
char *smbiostables=0;
char *smbiostables;
char *tablesptr, *newtablesptr;
int origsmbiosnum=0;
int origsmbiosnum;
// bitmask of used handles
uint8_t handles[8192];
uint16_t nexthandle=0;
int i, j;
int tablespresent[256];
BOOL do_auto=1;
bool do_auto=true;
getBoolForKey("SMBIOSdefaults",&do_auto,&bootInfo->bootConfig);
bzero(tablespresent, sizeof(tablespresent));
bzero(handles, sizeof(handles));
getBoolForKey(kSMBIOSdefaults, &do_auto, &bootInfo->bootConfig);
for (i=0;i<256;i++)
tablespresent[i]=0;
memset (handles,0,8192);
newsmbios->dmi.tableAddress=(uint32_t)AllocateKernelMemory(newsmbios->dmi.tableLength);
if (origsmbios)
{
smbiostables=(char *) origsmbios->dmi.tableAddress;
origsmbiosnum=origsmbios->dmi.structureCount;
}
tablesptr=smbiostables;
newtablesptr=(char *) newsmbios->dmi.tableAddress;
if (smbiostables)
for (i=0;i<origsmbiosnum;i++)
{
struct smbios_table_header *oldcur
=(struct smbios_table_header *) tablesptr,
*newcur=(struct smbios_table_header *) newtablesptr;
char *stringsptr;
int nstrings=0;
handles[(oldcur->handle)/8]|=1<<((oldcur->handle)%8);
memcpy (newcur,oldcur, oldcur->length);
tablesptr+=oldcur->length;
stringsptr=tablesptr;
newtablesptr+=oldcur->length;
for (;tablesptr[0]!=0 || tablesptr[1]!=0;tablesptr++)
if (tablesptr[0]==0)
newsmbios->dmi.tableAddress = (uint32_t)AllocateKernelMemory(newsmbios->dmi.tableLength);
if (origsmbios) {
smbiostables = (char *)origsmbios->dmi.tableAddress;
origsmbiosnum = origsmbios->dmi.structureCount;
} else {
smbiostables = NULL;
origsmbiosnum = 0;
}
tablesptr = smbiostables;
newtablesptr = (char *)newsmbios->dmi.tableAddress;
if (smbiostables) {
for (i=0; i<origsmbiosnum; i++) {
struct smbios_table_header*oldcur = (struct smbios_table_header *) tablesptr;
struct smbios_table_header*newcur = (struct smbios_table_header *) newtablesptr;
char*stringsptr;
intnstrings = 0;
handles[(oldcur->handle) / 8] |= 1 << ((oldcur->handle) % 8);
memcpy(newcur,oldcur, oldcur->length);
tablesptr += oldcur->length;
stringsptr = tablesptr;
newtablesptr += oldcur->length;
for (;tablesptr[0]!=0 || tablesptr[1]!=0; tablesptr++) {
if (tablesptr[0] == 0) {
nstrings++;
if (tablesptr!=stringsptr)
}
}
if (tablesptr != stringsptr) {
nstrings++;
tablesptr+=2;
memcpy (newtablesptr,stringsptr,tablesptr-stringsptr);
}
tablesptr += 2;
memcpy(newtablesptr, stringsptr, tablesptr-stringsptr);
//point to next possible space for a string
newtablesptr+=tablesptr-stringsptr-1;
if (nstrings==0)
newtablesptr += tablesptr - stringsptr - 1;
if (nstrings == 0) {
newtablesptr--;
for (j=0;j<sizeof (smbios_properties)/sizeof(smbios_properties[0]);
j++)
{
const char *str;
int size;
int num;
char altname[40];
sprintf (altname, "%s_%d",smbios_properties[j].name,
tablespresent[newcur->type]+1);
if (smbios_properties[j].table_type==newcur->type)
switch (smbios_properties[j].value_type)
{
}
for (j=0; j<sizeof(smbios_properties)/sizeof(smbios_properties[0]); j++) {
const char*str;
intsize;
intnum;
charaltname[40];
sprintf(altname, "%s_%d", smbios_properties[j].name, tablespresent[newcur->type] + 1);
if (smbios_properties[j].table_type == newcur->type) {
switch (smbios_properties[j].value_type) {
case SMSTRING:
if (getValueForKey(altname,&str, &size, &bootInfo->smbiosConfig)
||getValueForKey(smbios_properties[j].name,&str, &size, &bootInfo->smbiosConfig))
if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||
getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig))
{
memcpy (newtablesptr, str,size);
newtablesptr[size]=0;
newtablesptr+=size+1;
*((uint8_t*)(((char*)newcur)+smbios_properties[j].offset))=++nstrings;
memcpy(newtablesptr, str, size);
newtablesptr[size] = 0;
newtablesptr += size + 1;
*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings;
} else if (do_auto && smbios_properties[j].auto_str) {
str = smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[newcur->type]);
size = strlen(str);
memcpy(newtablesptr, str, size);
newtablesptr[size] = 0;
newtablesptr += size + 1;
*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings;
}
else if (do_auto && smbios_properties[j].auto_str)
{
str=smbios_properties[j].auto_str(smbios_properties[j].name,tablespresent[newcur->type]);
size=strlen (str);
memcpy (newtablesptr, str,size);
newtablesptr[size]=0;
newtablesptr+=size+1;
*((uint8_t*)(((char*)newcur)+smbios_properties[j].offset))=++nstrings;
}
break;
case SMOWORD:
if (getValueForKey(altname,&str, &size, &bootInfo->smbiosConfig)
||getValueForKey(smbios_properties[j].name,&str, &size, &bootInfo->smbiosConfig))
if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||
getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig))
{
int k=0, t=0, kk=0;
const char *ptr=str;
memset(((char*)newcur)+smbios_properties[j].offset, 0, 16);
while (ptr-str<size && *ptr && (*ptr==' ' || *ptr=='\t' || *ptr=='\n'))
intk=0, t=0, kk=0;
const char*ptr = str;
memset(((char*)newcur) + smbios_properties[j].offset, 0, 16);
while (ptr-str<size && *ptr && (*ptr==' ' || *ptr=='\t' || *ptr=='\n')) {
ptr++;
if (size-(ptr-str)>=2 && ptr[0]=='0' && (ptr[1]=='x' || ptr[1]=='X'))
ptr+=2;
for (;ptr-str<size && *ptr && k<16;ptr++)
{
if (*ptr>='0' && *ptr<='9')
}
if (size-(ptr-str)>=2 && ptr[0]=='0' && (ptr[1]=='x' || ptr[1]=='X')) {
ptr += 2;
}
for (;ptr-str<size && *ptr && k<16;ptr++) {
if (*ptr>='0' && *ptr<='9') {
(t=(t<<4)|(*ptr-'0')),kk++;
if (*ptr>='a' && *ptr<='f')
}
if (*ptr>='a' && *ptr<='f') {
(t=(t<<4)|(*ptr-'a'+10)),kk++;
if (*ptr>='A' && *ptr<='F')
}
if (*ptr>='A' && *ptr<='F') {
(t=(t<<4)|(*ptr-'A'+10)),kk++;
if (kk==2)
{
*((uint8_t*)(((char*)newcur)+smbios_properties[j].offset+k))=t;
}
if (kk == 2) {
*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset + k)) = t;
k++;
kk=0;
t=0;
kk = 0;
t = 0;
}
}
}
break;
case SMBYTE:
if (getIntForKey(altname,&num,&bootInfo->smbiosConfig)
||getIntForKey(smbios_properties[j].name,&num,&bootInfo->smbiosConfig))
*((uint8_t*)(((char*)newcur)+smbios_properties[j].offset))=num;
else if (do_auto && smbios_properties[j].auto_int)
*((uint8_t*)(((char*)newcur)+smbios_properties[j].offset))
=smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) ||
getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig))
{
*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = num;
} else if (do_auto && smbios_properties[j].auto_int) {
*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
}
break;
case SMWORD:
if (getIntForKey(altname,&num,&bootInfo->smbiosConfig)
||getIntForKey(smbios_properties[j].name,&num,&bootInfo->smbiosConfig))
*((uint16_t*)(((char*)newcur)+smbios_properties[j].offset))=num;
else if (do_auto && smbios_properties[j].auto_int)
*((uint16_t*)(((char*)newcur)+smbios_properties[j].offset))
=smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) ||
getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig))
{
*((uint16_t*)(((char*)newcur) + smbios_properties[j].offset)) = num;
} else if (do_auto && smbios_properties[j].auto_int) {
*((uint16_t*)(((char*)newcur) + smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
}
break;
}
}
}
if (nstrings==0)
{
newtablesptr[0]=0;
if (nstrings == 0) {
newtablesptr[0] = 0;
newtablesptr++;
}
newtablesptr[0]=0;
newtablesptr[0] = 0;
newtablesptr++;
tablespresent[newcur->type]++;
}
for (i=0;i<sizeof (smbios_table_descriptions)
/sizeof(smbios_table_descriptions[0]);i++)
{
int numnec=-1;
char buffer[40];
sprintf (buffer, "SMtable%d", i);
if (!getIntForKey(buffer,&numnec,&bootInfo->smbiosConfig))
numnec=-1;
if (numnec==-1 && do_auto && smbios_table_descriptions[i].numfunc)
numnec=smbios_table_descriptions[i].numfunc (smbios_table_descriptions[i].type);
while (tablespresent[smbios_table_descriptions[i].type]<numnec)
{
struct smbios_table_header *newcur=(struct smbios_table_header *) newtablesptr;
int nstrings=0;
memset (newcur,0, smbios_table_descriptions[i].len);
while (handles[(nexthandle)/8]&(1<<((nexthandle)%8)))
}
for (i=0; i<sizeof(smbios_table_descriptions)/sizeof(smbios_table_descriptions[0]); i++) {
intnumnec = -1;
charbuffer[40];
sprintf(buffer, "SMtable%d", i);
if (!getIntForKey(buffer, &numnec, &bootInfo->smbiosConfig)) {
numnec = -1;
}
if (numnec == -1 && do_auto && smbios_table_descriptions[i].numfunc) {
numnec = smbios_table_descriptions[i].numfunc(smbios_table_descriptions[i].type);
}
while (tablespresent[smbios_table_descriptions[i].type] < numnec) {
struct smbios_table_header*newcur = (struct smbios_table_header *) newtablesptr;
intnstrings = 0;
memset(newcur,0, smbios_table_descriptions[i].len);
while (handles[(nexthandle)/8] & (1 << ((nexthandle) % 8))) {
nexthandle++;
newcur->handle=nexthandle;
handles[nexthandle/8]|=1<<(nexthandle%8);
newcur->type=smbios_table_descriptions[i].type;
newcur->length=smbios_table_descriptions[i].len;
newtablesptr+=smbios_table_descriptions[i].len;
for (j=0;j<sizeof (smbios_properties)/sizeof(smbios_properties[0]);
j++)
{
const char *str;
int size;
int num;
char altname[40];
sprintf (altname, "%s_%d",smbios_properties[j].name,
tablespresent[newcur->type]+1);
if (smbios_properties[j].table_type==newcur->type)
switch (smbios_properties[j].value_type)
{
}
newcur->handle = nexthandle;
handles[nexthandle / 8] |= 1 << (nexthandle % 8);
newcur->type = smbios_table_descriptions[i].type;
newcur->length = smbios_table_descriptions[i].len;
newtablesptr += smbios_table_descriptions[i].len;
for (j=0; j<sizeof(smbios_properties)/sizeof(smbios_properties[0]); j++) {
const char*str;
intsize;
intnum;
charaltname[40];
sprintf(altname, "%s_%d", smbios_properties[j].name, tablespresent[newcur->type] + 1);
if (smbios_properties[j].table_type == newcur->type) {
switch (smbios_properties[j].value_type) {
case SMSTRING:
if (getValueForKey(altname,&str, &size, &bootInfo->smbiosConfig)
||getValueForKey(smbios_properties[j].name,&str, &size, &bootInfo->smbiosConfig))
if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||
getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig))
{
memcpy (newtablesptr, str,size);
newtablesptr[size]=0;
newtablesptr+=size+1;
*((uint8_t*)(((char*)newcur)+smbios_properties[j].offset))=++nstrings;
memcpy(newtablesptr, str, size);
newtablesptr[size] = 0;
newtablesptr += size + 1;
*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings;
} else if (do_auto && smbios_properties[j].auto_str) {
str = smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[newcur->type]);
size = strlen(str);
memcpy(newtablesptr, str, size);
newtablesptr[size] = 0;
newtablesptr += size + 1;
*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings;
}
else if (do_auto && smbios_properties[j].auto_str)
{
str=smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[newcur->type]);
size=strlen (str);
memcpy (newtablesptr, str,size);
newtablesptr[size]=0;
newtablesptr+=size+1;
*((uint8_t*)(((char*)newcur)+smbios_properties[j].offset))=++nstrings;
}
break;
case SMOWORD:
if (getValueForKey(altname,&str, &size, &bootInfo->smbiosConfig)
||getValueForKey(smbios_properties[j].name,&str, &size, &bootInfo->smbiosConfig))
if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||
getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig))
{
int k=0, t=0, kk=0;
const char *ptr=str;
memset(((char*)newcur)+smbios_properties[j].offset, 0, 16);
while (ptr-str<size && *ptr && (*ptr==' ' || *ptr=='\t' || *ptr=='\n'))
intk=0, t=0, kk=0;
const char*ptr = str;
memset(((char*)newcur) + smbios_properties[j].offset, 0, 16);
while (ptr-str<size && *ptr && (*ptr==' ' || *ptr=='\t' || *ptr=='\n')) {
ptr++;
if (size-(ptr-str)>=2 && ptr[0]=='0' && (ptr[1]=='x' || ptr[1]=='X'))
ptr+=2;
for (;ptr-str<size && *ptr && k<16;ptr++)
{
if (*ptr>='0' && *ptr<='9')
}
if (size-(ptr-str)>=2 && ptr[0]=='0' && (ptr[1]=='x' || ptr[1]=='X')) {
ptr += 2;
}
for (;ptr-str<size && *ptr && k<16;ptr++) {
if (*ptr>='0' && *ptr<='9') {
(t=(t<<4)|(*ptr-'0')),kk++;
if (*ptr>='a' && *ptr<='f')
}
if (*ptr>='a' && *ptr<='f') {
(t=(t<<4)|(*ptr-'a'+10)),kk++;
if (*ptr>='A' && *ptr<='F')
}
if (*ptr>='A' && *ptr<='F') {
(t=(t<<4)|(*ptr-'A'+10)),kk++;
if (kk==2)
{
*((uint8_t*)(((char*)newcur)+smbios_properties[j].offset+k))=t;
}
if (kk == 2) {
*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset + k)) = t;
k++;
kk=0;
t=0;
kk = 0;
t = 0;
}
}
}
break;
case SMBYTE:
if (getIntForKey(altname,&num,&bootInfo->smbiosConfig)
||getIntForKey(smbios_properties[j].name,&num,&bootInfo->smbiosConfig))
*((uint8_t*)(((char*)newcur)+smbios_properties[j].offset))=num;
else if (do_auto && smbios_properties[j].auto_int)
*((uint8_t*)(((char*)newcur)+smbios_properties[j].offset))
=smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) ||
getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig))
{
*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = num;
} else if (do_auto && smbios_properties[j].auto_int) {
*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
}
break;
case SMWORD:
if (getIntForKey(altname,&num,&bootInfo->smbiosConfig)
||getIntForKey(smbios_properties[j].name,&num,&bootInfo->smbiosConfig))
*((uint16_t*)(((char*)newcur)+smbios_properties[j].offset))=num;
else if (do_auto && smbios_properties[j].auto_int)
*((uint16_t*)(((char*)newcur)+smbios_properties[j].offset))
=smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) ||
getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig))
{
*((uint16_t*)(((char*)newcur) + smbios_properties[j].offset)) = num;
} else if (do_auto && smbios_properties[j].auto_int) {
*((uint16_t*)(((char*)newcur)+smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
}
break;
}
}
}
if (nstrings==0)
{
newtablesptr[0]=0;
if (nstrings == 0) {
newtablesptr[0] = 0;
newtablesptr++;
}
newtablesptr[0]=0;
newtablesptr[0] = 0;
newtablesptr++;
tablespresent[smbios_table_descriptions[i].type]++;
}
}
newsmbios->dmi.checksum=0;
newsmbios->dmi.checksum=256-checksum8 (&newsmbios->dmi,sizeof (newsmbios->dmi));
newsmbios->checksum=0;
newsmbios->checksum=256-checksum8 (newsmbios,sizeof (*newsmbios));
verbose("Patched DMI Table.\n");
newsmbios->dmi.checksum = 0;
newsmbios->dmi.checksum = 256 - checksum8(&newsmbios->dmi, sizeof(newsmbios->dmi));
newsmbios->checksum = 0;
newsmbios->checksum = 256 - checksum8(newsmbios, sizeof(*newsmbios));
verbose("Patched DMI Table\n");
}
inline struct SMBEntryPoint *
getSmbios()
struct SMBEntryPoint *getSmbios(void)
{
const char *smbios_filename;
char dirSpec[512];
int len;
struct SMBEntryPoint *orig_address;
struct SMBEntryPoint *new_address;
orig_address=getAddressOfSmbiosTable();
if (!getValueForKey("SMBIOS", &smbios_filename, &len, &bootInfo->bootConfig))
smbios_filename = "smbios.plist";
sprintf(dirSpec, "%s", smbios_filename);
if (loadConfigFile(dirSpec, &bootInfo->smbiosConfig) == -1)
{
sprintf(dirSpec, "/Extra/%s", smbios_filename);
if (loadConfigFile(dirSpec, &bootInfo->smbiosConfig) == -1)
{
sprintf(dirSpec, "bt(0,0)/Extra/%s", smbios_filename);
if (loadConfigFile(dirSpec, &bootInfo->smbiosConfig) == -1)
{
verbose("No SMBIOS replacement found.\n");
}
}
}
//if( (loadConfigFile("/Extra/smbios.plist", &bootInfo->smbiosConfig)) == -1 )
//loadConfigFile("bt(0,0)/Extra/smbios.plist", &bootInfo->smbiosConfig); // TODO: do we need this ?
orig_address=getAddressOfSmbiosTable();
new_address = smbios_dry_run(orig_address);
smbios_real_run(orig_address, new_address);
return new_address;
trunk/i386/libsaio/smbios_patcher.h
66
77
88
9
910
1011
1112
......
5455
5556
5657
58
59
5760
#define __LIBSAIO_SMBIOS_PATCHER_H
#include "libsaio.h"
#include "SMBIOS.h"
extern EFI_GUID gEfiAcpiTableGuid;
extern EFI_GUID gEfiAcpi20TableGuid;
};
extern struct SMBEntryPoint *getAddressOfSmbiosTable(void);
extern struct SMBEntryPoint *getSmbios(void);
#endif /* !__LIBSAIO_SMBIOS_PATCHER_H */
trunk/i386/libsaio/mem.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/*
* Copyright 2010 AsereBLN. All rights reserved. <aserebln@googlemail.com>
*
* mem.c - obtain system memory information
*/
#include "libsaio.h"
#include "pci.h"
#include "platform.h"
#include "cpu.h"
#include "mem.h"
#ifndef DEBUG_MEM
#define DEBUG_MEM 0
#endif
#if DEBUG_MEM
#define DBG(x...)printf(x)
#else
#define DBG(x...)
#endif
void scan_memory(PlatformInfo_t *p)
{
/* NYI */
}
trunk/i386/libsaio/pci_root.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/*
* Copyright 2009 netkas
*/
#include "libsaio.h"
#include "boot.h"
#include "bootstruct.h"
#ifndef DEBUG_PCIROOT
#define DEBUG_PCIROOT 0
#endif
#if DEBUG_PCIROOT
#define DBG(x...) printf(x)
#else
#define DBG(x...)
#endif
static int rootuid = 10; //value means function wasnt ran yet
static unsigned int findrootuid(unsigned char * dsdt, int len)
{
int i;
for (i=0; i<64 && i<len-5; i++) //not far than 64 symbols from pci root
{
if(dsdt[i] == '_' && dsdt[i+1] == 'U' && dsdt[i+2] == 'I' && dsdt[i+3] == 'D' && dsdt[i+5] == 0x08)
{
return dsdt[i+4];
}
}
return 11;
}
static unsigned int findpciroot(unsigned char * dsdt,int len)
{
int i;
for (i=0; i<len-4; i++) {
if(dsdt[i] == 'P' && dsdt[i+1] == 'C' && dsdt[i+2] == 'I' && (dsdt[i+3] == 0x08 || dsdt [i+4] == 0x08)) {
return findrootuid(dsdt+i, len-i);
}
}
return 10;
}
int getPciRootUID(void)
{
void *new_dsdt;
const char *dsdt_filename;
const char *val;
int fd;
int dsdt_uid;
int len,fsize;
if (rootuid < 10) {
return rootuid;
}
rootuid = 0;/* default uid = 0 */
if (getValueForKey(kPCIRootUID, &val, &len, &bootInfo->bootConfig)) {
if (isdigit(val[0])) {
rootuid = val[0] - '0';
}
goto out;
}
#if 0
/* Chameleon compatibility */
if (getValueForKey("PciRoot", &val, &len, &bootInfo->bootConfig)) {
if (isdigit(val[0])) {
rootuid = val[0] - '0';
}
goto out;
}
/* PCEFI compatibility */
if (getValueForKey("-pci0", &val, &len, &bootInfo->bootConfig)) {
rootuid = 0;
goto out;
}
if (getValueForKey("-pci1", &val, &len, &bootInfo->bootConfig)) {
rootuid = 1;
goto out;
}
#endif
if (!getValueForKey(kDSDT, &dsdt_filename, &len, &bootInfo->bootConfig)) {
dsdt_filename="/Extra/DSDT.aml";
}
if ((fd = open_bvdev("bt(0,0)", dsdt_filename, 0)) < 0) {
verbose("[WARNING] %s not found\n", dsdt_filename);
goto out;
}
fsize = file_size(fd);
if ((new_dsdt = malloc(fsize)) == NULL) {
verbose("[ERROR] alloc DSDT memory failed\n");
close (fd);
goto out;
}
if (read (fd, new_dsdt, fsize) != fsize) {
verbose("[ERROR] read %s failed\n", dsdt_filename);
close (fd);
goto out;
}
close (fd);
dsdt_uid = findpciroot(new_dsdt, fsize);
free(new_dsdt);
if (dsdt_uid >= 0 && dsdt_uid <= 9) {
rootuid = dsdt_uid;
} else {
verbose("Could not determine PCI-Root-UID value from DSDT!\n");
}
out:
verbose("Using PCI-Root-UID value %d\n", rootuid);
return rootuid;
}
trunk/i386/libsaio/mem.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
* Copyright 2010 AsereBLN. All rights reserved. <aserebln@googlemail.com>
*
* mem.h
*/
#ifndef __LIBSAIO_MEM_H
#define __LIBSAIO_MEM_H
#include "platform.h"
extern void scan_memory(PlatformInfo_t *);
#endif/* __LIBSAIO_MEM_H */
trunk/i386/libsaio/pci_root.h
1
2
3
4
5
6
7
8
9
10
11
12
13
/*
* Copyright 2008 mackerintel
*/
#ifndef __LIBSAIO_PCI_ROOT_H
#define __LIBSAIO_PCI_ROOT_H
#include "libsaio.h"
extern int getPciRootUID(void);
#endif /* !__LIBSAIO_DSDT_PATCHER_H */
trunk/i386/libsaio/usb.c
88
99
1010
11
1112
1213
1314
......
2324
2425
2526
26
27
27
2828
2929
3030
31
32
33
31
32
3433
35
36
37
34
35
36
37
38
3839
3940
40
41
4142
4243
4344
......
4849
4950
5051
51
52
53
52
53
5454
5555
5656
......
5858
5959
6060
61
62
63
61
62
6463
65
64
6665
6766
6867
......
7170
7271
7372
74
75
73
7674
7775
7876
79
80
81
77
78
8279
83
80
81
8482
83
8584
8685
8786
88
87
8988
9089
91
90
9291
93
94
95
92
93
9694
95
9796
98
97
9998
99
100100
101101
102
103
102
103
104104
105
105106
106
107
107
108108
109109
110110
111
112111
113112
114113
115114
116115
117
118
119
116
117
120118
119
121120
122121
123
122
124123
124
125125
126126
127127
128
128
129129
130
130131
131
132
132
133
133134
135
134136
135137
136138
137139
138
139
140
140141
141142
142143
143
144
144145
145146
146147
*/
#include "libsaio.h"
#include "boot.h"
#include "bootstruct.h"
#include "pci.h"
int ehci_acquire (pci_dt_t *pci_dev)
{
int j,k;
intj, k;
uint32_tbase;
uint8_teecp;
uint8_tlegacy[8];
BOOL isOwnershipConflict;
BOOL alwaysHardBIOSReset;
boolisOwnershipConflict;
boolalwaysHardBIOSReset;
if (!getBoolForKey("EHCIhard", &alwaysHardBIOSReset, &bootInfo->bootConfig))
alwaysHardBIOSReset = 1;
alwaysHardBIOSReset = false;
if (!getBoolForKey(kEHCIhard, &alwaysHardBIOSReset, &bootInfo->bootConfig)) {
alwaysHardBIOSReset = true;
}
pci_config_write16(pci_dev->dev.addr, 0x04, 0x0002);
base = pci_config_read32(pci_dev->dev.addr, 0x10);
verbose("EHCI controller [%04x:%04x] at %02x:%2x.%x DMA @%x\n",
pci_dev->vendor_id, pci_dev->device_id,
pci_dev->dev.bits.bus, pci_dev->dev.bits.dev, pci_dev->dev.bits.func,
DBG("Config space too small: no legacy implementation\n");
return 1;
}
eecp=*((unsigned char*)(base + 9));
if (!eecp)
{
eecp = *((unsigned char*)(base + 9));
if (!eecp) {
DBG("No extended capabilities: no legacy implementation\n");
return 1;
}
DBG("eecp=%x\n",eecp);
// bad way to do it
//pci_conf_write(pci_dev->dev.addr, eecp, 4, 0x01000001);
for (j = 0; j < 8; j++)
{
// pci_conf_write(pci_dev->dev.addr, eecp, 4, 0x01000001);
for (j = 0; j < 8; j++) {
legacy[j] = pci_config_read8(pci_dev->dev.addr, eecp + j);
DBG("%02x ",legacy[j]);
DBG("%02x ", legacy[j]);
}
DBG("\n");
// Definitely needed during reboot on 10.4.6
isOwnershipConflict = ((legacy[3] & 1 != 0) && (legacy[2] & 1 != 0));
if (!alwaysHardBIOSReset && isOwnershipConflict)
{
if (!alwaysHardBIOSReset && isOwnershipConflict) {
DBG("EHCI - Ownership conflict - attempting soft reset ...\n");
DBG("EHCI - toggle OS Ownership to 0\n");
pci_config_write8(pci_dev->dev.addr, eecp + 3, 0);
for (k = 0; k < 25; k++)
{
for (j = 0; j < 8; j++)
for (k = 0; k < 25; k++) {
for (j = 0; j < 8; j++) {
legacy[j] = pci_config_read8(pci_dev->dev.addr, eecp + j);
if (legacy[3] == 0)
}
if (legacy[3] == 0) {
break;
}
delay(10);
}
}
DBG("Found USBLEGSUP_ID - value %x:%x - writing OSOwned\n", legacy[3],legacy[2]);
pci_config_write8(pci_dev->dev.addr, eecp + 3, 1);
// wait for kEHCI_USBLEGSUP_BIOSOwned bit to clear
for (k = 0; k < 25; k++)
{
for (j = 0;j < 8; j++)
for (k = 0; k < 25; k++) {
for (j = 0;j < 8; j++) {
legacy[j] = pci_config_read8(pci_dev->dev.addr, eecp + j);
}
DBG ("%x:%x,",legacy[3],legacy[2]);
if (legacy[2] == 0)
if (legacy[2] == 0) {
break;
}
delay(10);
}
for (j = 0;j < 8; j++)
for (j = 0;j < 8; j++) {
legacy[j] = pci_config_read8(pci_dev->dev.addr, eecp + j);
}
isOwnershipConflict = ((legacy[2]) != 0);
if (isOwnershipConflict)
{
if (isOwnershipConflict) {
// Soft reset has failed. Assume SMI being ignored
// Hard reset
// Force Clear BIOS BIT
DBG("EHCI - Ownership conflict - attempting hard reset ...\n");
DBG ("%x:%x\n",legacy[3],legacy[2]);
DBG("EHCI - Force BIOS Ownership to 0\n");
pci_config_write8(pci_dev->dev.addr, eecp + 2, 0);
for (k = 0; k < 25; k++)
{
for (j = 0; j < 8; j++)
for (k = 0; k < 25; k++) {
for (j = 0; j < 8; j++) {
legacy[j] = pci_config_read8(pci_dev->dev.addr, eecp + j);
}
DBG ("%x:%x,",legacy[3],legacy[2]);
if ((legacy[2]) == 0)
if ((legacy[2]) == 0) {
break;
}
delay(10);
}
// Disable further SMI events
for (j = 4; j < 8; j++)
for (j = 4; j < 8; j++) {
pci_config_write8(pci_dev->dev.addr, eecp + j, 0);
}
}
for (j = 0; j < 8; j++)
for (j = 0; j < 8; j++) {
legacy[j] = pci_config_read8(pci_dev->dev.addr, eecp + j);
}
DBG ("%x:%x\n",legacy[3],legacy[2]);
// Final Ownership Resolution Check...
if (legacy[2]&1)
{
if (legacy[2] & 1) {
DBG("EHCI controller unable to take control from BIOS\n");
return 0;
}
DBG("EHCI Acquire OS Ownership done\n");
return 1;
}
trunk/i386/libsaio/device_inject.c
66
77
88
9
910
1011
12
1113
1214
1315
......
2931
3032
3133
32
33
34
3435
3536
3637
37
38
3839
3940
4041
42
4143
4244
4345
......
129131
130132
131133
132
134
133135
134136
135137
......
170172
171173
172174
173
174
175
175
176
177
176178
177
178
179
180
179
181180
182181
182
183183
184
185
186
187
188
189
190
191
184
192185
193186
194187
195
188
196189
197
198
199
190
191
200192
201193
202194
203195
204
205
206
207
196
197
208198
209199
210200
*/
#include "libsaio.h"
#include "boot.h"
#include "bootstruct.h"
#include "pci.h"
#include "pci_root.h"
#include "device_inject.h"
char *efi_inject_get_devprop_string(uint32_t *len)
{
if(string)
{
if(string) {
*len = string->length;
return devprop_generate_string(string);
}
printf("efi_inject_get_devprop_string NULL trying stringdata\n");
verbose("efi_inject_get_devprop_string NULL trying stringdata\n");
return NULL;
}
/* XXX AsereBLN replace by strtoul */
uint32_t ascii_hex_to_int(char *buff)
{
uint32_tvalue = 0, i, digit;
/* Use the static "device-properties" boot config key contents if available,
* otheriwse use the generated one.
*/
if (!getValueForKey(DEVICE_PROPERTIES_PROP, &val, &cnt, &bootInfo->bootConfig) && string)
if (!getValueForKey(kDeviceProperties, &val, &cnt, &bootInfo->bootConfig) && string)
{
val = (const char*)string;
cnt = strlength * 2;
struct DevPropDevice *devprop_add_device(struct DevPropString *string, char *path)
{
uint32_t PciRootID = 0;
const char *val;
int len;
struct DevPropDevice*device;
const charpciroot_string[] = "PciRoot(0x";
const charpci_device_string[] = "Pci(0x";
struct DevPropDevice *device = (struct DevPropDevice*)malloc(sizeof(struct DevPropDevice));
if(!device || !string || !path) {
if(device)
free(device);
if (string == NULL || path == NULL) {
return NULL;
}
device = malloc(sizeof(struct DevPropDevice));
const char pciroot_string[]= "PciRoot(0x";
const char pci_device_string[]= "Pci(0x";
if (getValueForKey("PciRoot", &val, &len, &bootInfo->bootConfig))
PciRootID = atoi(val);
if(strncmp(path, pciroot_string, strlen(pciroot_string)))
{
if (strncmp(path, pciroot_string, strlen(pciroot_string))) {
printf("ERROR parsing device path\n");
return NULL;
}
memset(device, 0, sizeof(struct DevPropDevice));
device->acpi_dev_path._UID = PciRootID;
device->acpi_dev_path._UID = getPciRootUID();
int numpaths = 0;
intx, curr = 0;
charbuff[] = "00";
for(x = 0; x < strlen(path); x++)
{
if(!strncmp(&path[x], pci_device_string, strlen(pci_device_string)))
{
for (x = 0; x < strlen(path); x++) {
if (!strncmp(&path[x], pci_device_string, strlen(pci_device_string))) {
x+=strlen(pci_device_string);
curr=x;
while(path[++x] != ',');
trunk/i386/libsaio/device_inject.h
6363
6464
6565
66
67
68
69
70
66
67
7168
7269
73
74
75
70
71
72
7673
7774
struct DevPropDevice **entries;
};
voidsetupEfiDevices ();
char*efi_inject_get_devprop_string(uint32_t *len);
int devprop_add_nvidia_template(struct DevPropDevice *device);
int devprop_add_network_template(struct DevPropDevice *device, uint16_t vendor_id);
char*efi_inject_get_devprop_string(uint32_t *len);
intdevprop_add_network_template(struct DevPropDevice *device, uint16_t vendor_id);
struct DevPropString*devprop_create_string(void);
struct DevPropDevice*devprop_add_device(struct DevPropString *string, char *path);
int devprop_add_value(struct DevPropDevice *device, char *nm, uint8_t *vl, uint32_t len);
char*devprop_generate_string(struct DevPropString *string);
void devprop_free_string(struct DevPropString *string);
intdevprop_add_value(struct DevPropDevice *device, char *nm, uint8_t *vl, uint32_t len);
char*devprop_generate_string(struct DevPropString *string);
voiddevprop_free_string(struct DevPropString *string);
#endif /* !__LIBSAIO_DEVICE_INJECT_H */
trunk/i386/libsaio/dsdt_patcher.c
33
44
55
6
67
78
89
910
1011
12
1113
1214
1315
......
7779
7880
7981
82
8083
8184
8285
......
8588
8689
8790
88
91
8992
9093
9194
9295
93
9496
95
97
98
99
96100
97
101
102
103
98104
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
105
106
107
119108
120
109
121110
122
123
124
111
112
125113
114
126115
127116
128
129
117
130118
119
131120
132121
133
134
122
135123
136
137
138
139
124
125
126
127
128
129
130
131
140132
141
133
142134
143
144
135
145136
146137
147138
......
216207
217208
218209
219
220
210
211
212
213
214
215
216
217
221218
219
220
221
222
223
224
225
226
227
228
229
222230
223231
224232
......
307315
308316
309317
310
311
312318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
313339
314340
315341
......
377403
378404
379405
406
380407
381408
382409
383410
384411
412
385413
386414
387415
388416
389
417
418
390419
391
420
392421
393422
*/
#include "libsaio.h"
#include "boot.h"
#include "bootstruct.h"
#include "acpi.h"
#include "efi_tables.h"
#include "fake_efi.h"
#include "dsdt_patcher.h"
#include "platform.h"
#ifndef DEBUG_DSDT
#define DEBUG_DSDT 0
{
//addConfigurationTable(&gEfiAcpiTableGuid, getAddressOfAcpiTable(), "ACPI");
//addConfigurationTable(&gEfiAcpi20TableGuid, getAddressOfAcpi20Table(), "ACPI_20");
/* XXX aserebln why uint32 cast if pointer is uint64 ? */
acpi10_p = (uint32_t)getAddressOfAcpiTable();
acpi20_p = (uint32_t)getAddressOfAcpi20Table();
addConfigurationTable(&gEfiAcpiTableGuid, &acpi10_p, "ACPI");
}
/* Setup ACPI. Replace DSDT if DSDT.aml is found */
int setupAcpi()
int setupAcpi(void)
{
int fd, version;
void *new_dsdt;
const char *dsdt_filename;
char dirspec[512];
int len;
boolean_t drop_ssdt=NO;
bool tmp;
bool drop_ssdt;
bool fix_restart;
//DBG("Enter setupACPI\n");
if (!getValueForKey(kDSDT, &dsdt_filename, &len, &bootInfo->bootConfig)) {
dsdt_filename = "/Extra/DSDT.aml";
}
if (!getValueForKey("DSDT", &dsdt_filename, &len, &bootInfo->bootConfig))
dsdt_filename="DSDT.aml";
// Check booting partition
sprintf(dirspec,"%s",dsdt_filename);
fd=open (dirspec,0);
if (fd<0)
{// Check Extra on booting partition
sprintf(dirspec,"/Extra/%s",dsdt_filename);
fd=open (dirspec,0);
if (fd<0)
{// Fall back to booter partition
sprintf(dirspec,"bt(0,0)/Extra/%s",dsdt_filename);
fd=open (dirspec,0);
if (fd<0)
{
verbose("No DSDT replacement found. Leaving ACPI data as is\n");
return setupAcpiNoMod();
}
}
if ((fd = open_bvdev("bt(0,0)", dsdt_filename, 0)) < 0) {
verbose("No DSDT replacement found. Leaving ACPI data as is\n");
return setupAcpiNoMod();
}
// Load replacement DSDT
new_dsdt=(void*)AllocateKernelMemory(file_size (fd));
if (!new_dsdt)
{
new_dsdt = (void*)AllocateKernelMemory(file_size (fd));
if (!new_dsdt) {
printf("Couldn't allocate memory for DSDT\n");
close(fd);
return setupAcpiNoMod();
}
if (read (fd, new_dsdt, file_size (fd))!=file_size (fd))
{
if (read(fd, new_dsdt, file_size(fd)) != file_size(fd)) {
printf("Couldn't read file\n");
close(fd);
return setupAcpiNoMod();
}
close (fd);
close(fd);
DBG("New DSDT Loaded in memory\n");
{
BOOL tmp;
drop_ssdt=getBoolForKey("DropSSDT",&tmp, &bootInfo->bootConfig)&&tmp;
drop_ssdt = getBoolForKey(kDropSSDT, &tmp, &bootInfo->bootConfig) && tmp;
if (Platform.CPU.Vendor == 0x756E6547) {/* Intel */
fix_restart = true;
getBoolForKey(kRestartFix, &fix_restart, &bootInfo->bootConfig);
} else {
fix_restart = false;
}
// Do the same procedure for both versions of ACPI
for (version=0;version<2;version++)
{
for (version=0; version<2; version++) {
struct acpi_2_rsdp *rsdp, *rsdp_mod;
struct acpi_2_rsdt *rsdt, *rsdt_mod;
int rsdplength;
continue;
}
fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(fadt->Length);
memcpy(fadt_mod, fadt, fadt->Length);
if (fix_restart && fadt->Length < 0x81) {
fadt_mod = (struct acpi_2_fadt *)AllocateKernelMemory(0x81);
memcpy(fadt_mod, fadt, fadt->Length);
fadt_mod->Length = 0x81;
} else {
fadt_mod = (struct acpi_2_fadt *)AllocateKernelMemory(fadt->Length);
memcpy(fadt_mod, fadt, fadt->Length);
}
if (fix_restart) {
fadt_mod->Flags |= 0x400;
fadt_mod->Reset_SpaceID = 0x01;
fadt_mod->Reset_BitWidth = 0x08;
fadt_mod->Reset_BitOffset = 0x00;
fadt_mod->Reset_AccessWidth = 0x01;
fadt_mod->Reset_Address = 0x0cf9;
fadt_mod->Reset_Value = 0x06;
verbose("FACP: Restart Fix applied\n");
}
// Patch DSDT Address
DBG("Old DSDT @%x,%x\n",fadt_mod->DSDT,fadt_mod->X_DSDT);
printf("FADT incorrect or after 4GB. Dropping XSDT\n");
goto drop_xsdt;
}
fadt_mod=(struct acpi_2_fadt*)AllocateKernelMemory(fadt->Length);
memcpy(fadt_mod, fadt, fadt->Length);
if (fix_restart && fadt->Length < 0x81) {
fadt_mod = (struct acpi_2_fadt *)AllocateKernelMemory(0x81);
memcpy(fadt_mod, fadt, fadt->Length);
fadt_mod->Length = 0x81;
} else {
fadt_mod = (struct acpi_2_fadt*)AllocateKernelMemory(fadt->Length);
memcpy(fadt_mod, fadt, fadt->Length);
}
if (fix_restart) {
fadt_mod->Flags |= 0x400;
fadt_mod->Reset_SpaceID = 0x01;
fadt_mod->Reset_BitWidth = 0x08;
fadt_mod->Reset_BitOffset = 0x00;
fadt_mod->Reset_AccessWidth = 0x01;
fadt_mod->Reset_Address = 0x0cf9;
fadt_mod->Reset_Value = 0x06;
verbose("FACP: Restart Fix applied\n");
}
// Patch DSDT Address
DBG("Old DSDT @%x,%x\n",fadt_mod->DSDT,fadt_mod->X_DSDT);
verbose("Patched ACPI version %d DSDT\n", version+1);
if (version)
{
/* XXX aserebln why uint32 cast if pointer is uint64 ? */
acpi20_p = (uint32_t)rsdp_mod;
addConfigurationTable(&gEfiAcpi20TableGuid, &acpi20_p, "ACPI_20");
}
else
{
/* XXX aserebln why uint32 cast if pointer is uint64 ? */
acpi10_p = (uint32_t)rsdp_mod;
addConfigurationTable(&gEfiAcpiTableGuid, &acpi10_p, "ACPI");
}
}
#if DEBUG_DSDT
#if DEBUG_DSDT
printf("(Press a key to continue...)\n");
getc();
#endif
#endif
return 1;
}
trunk/i386/libsaio/ntfs.c
295295
296296
297297
298
298
299299
300
300
301301
302302
303303
304304
305305
306
306
307307
308308
309309
return;
}
BOOL NTFSProbe(const void * buffer)
bool NTFSProbe(const void * buffer)
{
BOOL result = FALSE;
bool result = false;
const struct bootfile* part_bootfile = buffer;// NTFS boot sector structure
// Looking for NTFS signature.
if (strncmp((const char *)part_bootfile->bf_sysid, NTFS_BBID, NTFS_BBIDLEN) == 0)
result = TRUE;
result = true;
return result;
}
trunk/i386/libsaio/nvidia.c
4949
5050
5151
52
5253
5354
5455
......
6566
6667
6768
69
6870
6971
7072
......
7476
7577
7678
77
78
79
80
81
82
83
84
79
80
81
82
83
84
85
86
8587
86
87
88
89
90
91
88
89
90
91
9292
9393
94
95
96
97
98
9994
10095
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
13496
13597
13698
......
141103
142104
143105
106
107
108
109
110
111
112
113
144114
145115
146116
......
175145
176146
177147
178
179
180
181
182
183
184
185
186
187
188
189
190
191
148
149
150
151
152
192153
193154
194155
......
201162
202163
203164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
204220
205221
206222
......
213229
214230
215231
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239232
240233
241234
......
267260
268261
269262
263
270264
271265
266
267
272268
273269
274270
......
282278
283279
284280
285
286281
287282
288283
289284
285
286
290287
291288
292289
293290
291
292
293
294
295
296
294297
295298
296299
......
303306
304307
305308
306
307
308
309
310
311
312
309
310
311
313312
314313
315
316
317
318
319
320
321
322
323
314
315
316
324317
325318
326
319
320
327321
328322
329323
330324
331325
332326
333
327
328
329
330
331
332
333
334
335
336
337
338
339
334340
335341
336342
......
338344
339345
340346
341
342
343
347
348
349
350
351
344352
345353
346354
......
515523
516524
517525
518
519
520
521
526
527
528
529
530
522531
532
523533
524534
525535
526536
527
537
528538
529
530
539
540
531541
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
542
543
548544
549
550
551
552
545
546
547
548
549
550
551
552
553553
554554
555
555
556556
557
558
559
557560
558561
559
562
560563
561564
562565
......
571574
572575
573576
574
575
576
577
577
578
578579
579
580
580581
581582
582583
583
584584
585585
586
587
588
589
590
591
592
593
594
595
596
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
597601
598602
599
600603
601604
602
605
603606
604607
605
606608
607609
608610
609
610
611
611
612
613
612614
613
615
616
617
618
619
620
621
622
623
614624
615
616
617
618
619
625
620626
621
622
623
624
625
626
627
628
629
630
631
632
633627
634628
635
629
636630
637631
638
639
632
640633
641634
642635
643636
644637
645
638
646639
647640
648641
649642
650643
651
652
644
653645
654
646
655647
656648
657
658
659
649
650
660651
661
662
663
664
652
653
654
655
656
665657
666
667
668
658
659
669660
670
671
672
673661
674
675
676
677662
678
679
680
681
682
663
664
683665
684666
685667
686
687668
688669
689670
690
691
671
672
692673
693674
694
695
675
676
677
678
696679
697
680
698681
699
700
701
702
703
704
705
706
707
708
709682
683
710684
711685
712
686
713687
714688
715
716
689
717690
718
691
719692
720693
721694
722
723695
724696
725697
726698
727699
728
729
730
731
732
733
700
701
702
734703
704
735705
736706
737
738
739
740
741
742
743
744707
745708
746709
*/
#include "libsaio.h"
#include "boot.h"
#include "bootstruct.h"
#include "pci.h"
#include "platform.h"
#define DBG(x...)
#endif
#define NVIDIA_ROM_SIZE 0x10000
#define PATCH_ROM_SUCCESS 1
#define PATCH_ROM_SUCCESS_HAS_LVDS 2
#define PATCH_ROM_FAILED 0
extern uint32_t devices_number;
const char *nvidia_compatible_0[]={ "@0,compatible","NVDA,NVMac"};
const char *nvidia_compatible_1[]={ "@1,compatible","NVDA,NVMac"};
const char *nvidia_device_type_0[]={ "@0,device_type","display"};
const char *nvidia_device_type_1[]={ "@1,device_type","display"};
const char *nvidia_device_type[]={ "device_type","NVDA,Parent"};
const char *nvidia_name_0[]={ "@0,name","NVDA,Display-A"};
const char *nvidia_name_1[]={ "@1,name","NVDA,Display-B"};
const char *nvidia_slot_name[]={ "AAPL,slot-name","Slot-1"};
const char *nvidia_compatible_0[]={ "@0,compatible","NVDA,NVMac" };
const char *nvidia_compatible_1[]={ "@1,compatible","NVDA,NVMac" };
const char *nvidia_device_type_0[]={ "@0,device_type","display" };
const char *nvidia_device_type_1[]={ "@1,device_type","display" };
const char *nvidia_device_type[]={ "device_type","NVDA,Parent" };
const char *nvidia_name_0[]={ "@0,name","NVDA,Display-A" };
const char *nvidia_name_1[]={ "@1,name","NVDA,Display-B" };
const char *nvidia_slot_name[]={ "AAPL,slot-name","Slot-1" };
uint8_t default_NVCAP[]= {
0x04, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0d, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0a,
0x00, 0x00, 0x00, 0x00
static uint8_t default_NVCAP[]= {
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a,
0x00, 0x00, 0x00, 0x00
};
uint16_t swap16(uint16_t toswap) {
return (((toswap & 0x00FF) << 8) | ((toswap & 0xFF00) >> 8));
}
// Known cards as of 2008/08/26
static struct nv_chipsets_t NVKnownChipsets[] = {
{ 0x00000000, "Unknown" },
{ 0x10DE0301, "GeForce FX 5800 Ultra" },
{ 0x10DE0302, "GeForce FX 5800" },
{ 0x10DE0308, "Quadro FX 2000" },
{ 0x10DE0309, "Quadro FX 1000" },
{ 0x10DE0311, "GeForce FX 5600 Ultra" },
{ 0x10DE0312, "GeForce FX 5600" },
{ 0x10DE0314, "GeForce FX 5600XT" },
{ 0x10DE031A, "GeForce FX Go5600" },
{ 0x10DE031B, "GeForce FX Go5650" },
{ 0x10DE031C, "Quadro FX Go700" },
{ 0x10DE0324, "GeForce FX Go5200" },
{ 0x10DE0325, "GeForce FX Go5250" },
{ 0x10DE0326, "GeForce FX 5500" },
{ 0x10DE0328, "GeForce FX Go5200 32M/64M" },
{ 0x10DE032A, "Quadro NVS 55/280 PCI" },
{ 0x10DE032B, "Quadro FX 500/600 PCI" },
{ 0x10DE032C, "GeForce FX Go53xx Series" },
{ 0x10DE032D, "GeForce FX Go5100" },
{ 0x10DE0330, "GeForce FX 5900 Ultra" },
{ 0x10DE0331, "GeForce FX 5900" },
{ 0x10DE0332, "GeForce FX 5900XT" },
{ 0x10DE0333, "GeForce FX 5950 Ultra" },
{ 0x10DE0334, "GeForce FX 5900ZT" },
{ 0x10DE0338, "Quadro FX 3000" },
{ 0x10DE033F, "Quadro FX 700" },
{ 0x10DE0341, "GeForce FX 5700 Ultra" },
{ 0x10DE0342, "GeForce FX 5700" },
{ 0x10DE0343, "GeForce FX 5700LE" },
{ 0x10DE0344, "GeForce FX 5700VE" },
{ 0x10DE0347, "GeForce FX Go5700" },
{ 0x10DE0348, "GeForce FX Go5700" },
{ 0x10DE034C, "Quadro FX Go1000" },
{ 0x10DE034E, "Quadro FX 1100" },
{ 0x10DE0040, "GeForce 6800 Ultra" },
{ 0x10DE0041, "GeForce 6800" },
{ 0x10DE0042, "GeForce 6800 LE" },
{ 0x10DE0047, "GeForce 6800 GS" },
{ 0x10DE0048, "GeForce 6800 XT" },
{ 0x10DE004E, "Quadro FX 4000" },
{ 0x10DE0090, "GeForce 7800 GTX" },
{ 0x10DE0091, "GeForce 7800 GTX" },
{ 0x10DE0092, "GeForce 7800 GT" },
{ 0x10DE0093, "GeForce 7800 GS" },
{ 0x10DE0095, "GeForce 7800 SLI" },
{ 0x10DE0098, "GeForce Go 7800" },
{ 0x10DE0099, "GeForce Go 7800 GTX" },
{ 0x10DE009D, "Quadro FX 4500" },
{ 0x10DE00C0, "GeForce 6800 GS" },
{ 0x10DE00C1, "GeForce 6800" },
{ 0x10DE00C2, "GeForce 6800 LE" },
{ 0x10DE0168, "GeForce Go 6400" },
{ 0x10DE0169, "GeForce 6250" },
{ 0x10DE016A, "GeForce 7100 GS" },
{ 0x10DE0211, "GeForce 6800" },
{ 0x10DE0212, "GeForce 6800 LE" },
{ 0x10DE0215, "GeForce 6800 GT" },
{ 0x10DE0218, "GeForce 6800 XT" },
{ 0x10DE0221, "GeForce 6200" },
{ 0x10DE0222, "GeForce 6200 A-LE" },
{ 0x10DE0090, "GeForce 7800 GTX" },
{ 0x10DE0091, "GeForce 7800 GTX" },
{ 0x10DE0092, "GeForce 7800 GT" },
{ 0x10DE0093, "GeForce 7800 GS" },
{ 0x10DE0095, "GeForce 7800 SLI" },
{ 0x10DE0098, "GeForce Go 7800" },
{ 0x10DE0099, "GeForce Go 7800 GTX" },
{ 0x10DE009D, "Quadro FX 4500" },
{ 0x10DE0191, "GeForce 8800 GTX" },
{ 0x10DE0193, "GeForce 8800 GTS" },
{ 0x10DE0194, "GeForce 8800 Ultra" },
{ 0x10DE019D, "Quadro FX 5600" },
{ 0x10DE019E, "Quadro FX 4600" },
{ 0x10DE01D1, "GeForce 7300 LE" },
{ 0x10DE01D3, "GeForce 7300 SE" },
{ 0x10DE01D6, "GeForce Go 7200" },
{ 0x10DE01DD, "GeForce 7500 LE" },
{ 0x10DE01DE, "Quadro FX 350" },
{ 0x10DE01DF, "GeForce 7300 GS" },
{ 0x10DE0211, "GeForce 6800" },
{ 0x10DE0212, "GeForce 6800 LE" },
{ 0x10DE0215, "GeForce 6800 GT" },
{ 0x10DE0218, "GeForce 6800 XT" },
{ 0x10DE0221, "GeForce 6200" },
{ 0x10DE0222, "GeForce 6200 A-LE" },
{ 0x10DE0240, "GeForce 6150" },
{ 0x10DE0241, "GeForce 6150 LE" },
{ 0x10DE0242, "GeForce 6100" },
{ 0x10DE0244, "GeForce Go 6150" },
{ 0x10DE0247, "GeForce Go 6100" },
{ 0x10DE0290, "GeForce 7900 GTX" },
{ 0x10DE0291, "GeForce 7900 GT" },
{ 0x10DE0292, "GeForce 7900 GS" },
{ 0x10DE0298, "GeForce Go 7900 GS" },
{ 0x10DE0299, "GeForce Go 7900 GTX" },
{ 0x10DE029A, "Quadro FX 2500M" },
{ 0x10DE029B, "Quadro FX 1500M" },
{ 0x10DE029C, "Quadro FX 5500" },
{ 0x10DE029D, "Quadro FX 3500" },
{ 0x10DE029E, "Quadro FX 1500" },
{ 0x10DE029F, "Quadro FX 4500 X2" },
{ 0x10DE0301, "GeForce FX 5800 Ultra" },
{ 0x10DE0302, "GeForce FX 5800" },
{ 0x10DE0308, "Quadro FX 2000" },
{ 0x10DE0309, "Quadro FX 1000" },
{ 0x10DE0311, "GeForce FX 5600 Ultra" },
{ 0x10DE0312, "GeForce FX 5600" },
{ 0x10DE0314, "GeForce FX 5600XT" },
{ 0x10DE031A, "GeForce FX Go5600" },
{ 0x10DE031B, "GeForce FX Go5650" },
{ 0x10DE031C, "Quadro FX Go700" },
{ 0x10DE0324, "GeForce FX Go5200" },
{ 0x10DE0325, "GeForce FX Go5250" },
{ 0x10DE0326, "GeForce FX 5500" },
{ 0x10DE0328, "GeForce FX Go5200 32M/64M" },
{ 0x10DE032A, "Quadro NVS 55/280 PCI" },
{ 0x10DE032B, "Quadro FX 500/600 PCI" },
{ 0x10DE032C, "GeForce FX Go53xx Series" },
{ 0x10DE032D, "GeForce FX Go5100" },
{ 0x10DE0330, "GeForce FX 5900 Ultra" },
{ 0x10DE0331, "GeForce FX 5900" },
{ 0x10DE0332, "GeForce FX 5900XT" },
{ 0x10DE0333, "GeForce FX 5950 Ultra" },
{ 0x10DE0334, "GeForce FX 5900ZT" },
{ 0x10DE0338, "Quadro FX 3000" },
{ 0x10DE033F, "Quadro FX 700" },
{ 0x10DE0341, "GeForce FX 5700 Ultra" },
{ 0x10DE0342, "GeForce FX 5700" },
{ 0x10DE0343, "GeForce FX 5700LE" },
{ 0x10DE0344, "GeForce FX 5700VE" },
{ 0x10DE0347, "GeForce FX Go5700" },
{ 0x10DE0348, "GeForce FX Go5700" },
{ 0x10DE034C, "Quadro FX Go1000" },
{ 0x10DE034E, "Quadro FX 1100" },
{ 0x10DE0391, "GeForce 7600 GT" },
{ 0x10DE0392, "GeForce 7600 GS" },
{ 0x10DE0393, "GeForce 7300 GT" },
{ 0x10DE039B, "GeForce Go 7900 SE" },
{ 0x10DE039C, "Quadro FX 550M" },
{ 0x10DE039E, "Quadro FX 560" },
{ 0x10DE0290, "GeForce 7900 GTX" },
{ 0x10DE0291, "GeForce 7900 GT" },
{ 0x10DE0292, "GeForce 7900 GS" },
{ 0x10DE0298, "GeForce Go 7900 GS" },
{ 0x10DE0299, "GeForce Go 7900 GTX" },
{ 0x10DE029A, "Quadro FX 2500M" },
{ 0x10DE029B, "Quadro FX 1500M" },
{ 0x10DE029C, "Quadro FX 5500" },
{ 0x10DE029D, "Quadro FX 3500" },
{ 0x10DE029E, "Quadro FX 1500" },
{ 0x10DE029F, "Quadro FX 4500 X2" },
{ 0x10DE0240, "GeForce 6150" },
{ 0x10DE0241, "GeForce 6150 LE" },
{ 0x10DE0242, "GeForce 6100" },
{ 0x10DE0244, "GeForce Go 6150" },
{ 0x10DE0247, "GeForce Go 6100" },
/*************** G8x ***************/
{ 0x10DE0191, "GeForce 8800 GTX" },
{ 0x10DE0193, "GeForce 8800 GTS" },
{ 0x10DE0194, "GeForce 8800 Ultra" },
{ 0x10DE019D, "Quadro FX 5600" },
{ 0x10DE019E, "Quadro FX 4600" },
{ 0x10DE0400, "GeForce 8600 GTS" },
{ 0x10DE0401, "GeForce 8600 GT" },
{ 0x10DE0402, "GeForce 8600 GT" },
{ 0x10DE042D, "Quadro FX 360M" },
{ 0x10DE042E, "GeForce 9300M G" },
{ 0x10DE042F, "Quadro NVS 290" },
{ 0x10DE05E0, "GeForce GTX 295" },
{ 0x10DE05E1, "GeForce GTX 280" },
{ 0x10DE05E2, "GeForce GTX 260" },
{ 0x10DE05E3, "GeForce GTX 285" },
{ 0x10DE05E6, "GeForce GTX 275" },
{ 0x10DE0600, "GeForce 8800 GTS 512" },
{ 0x10DE0602, "GeForce 8800 GT" },
{ 0x10DE0604, "GeForce 9800 GX2" },
{ 0x10DE0612, "GeForce 9800 GTX" },
{ 0x10DE0613, "GeForce 9800 GTX+" },
{ 0x10DE0614, "GeForce 9800 GT" },
{ 0x10DE0615, "GeForce 250 GTS" },
{ 0x10DE061A, "Quadro FX 3700" },
{ 0x10DE061C, "Quadro FX 3600M" },
{ 0x10DE0622, "GeForce 9600 GT" },
{ 0x10DE0623, "GeForce 9600 GS" },
{ 0x10DE0626, "GeForce GT 130" },
{ 0x10DE0627, "GeForce GT 140" },
{ 0x10DE0628, "GeForce 9800M GTS" },
{ 0x10DE062A, "GeForce 9700M GTS" },
{ 0x10DE062C, "GeForce 9800M GTS" },
{ 0x10DE0640, "GeForce 9500 GT" },
{ 0x10DE0641, "GeForce 9400 GT" },
{ 0x10DE0642, "GeForce 8400 GS" },
{ 0x10DE0643, "GeForce 9500 GT" },
{ 0x10DE0644, "GeForce 9500 GS" },
{ 0x10DE0645, "GeForce 9500 GS" },
{ 0x10DE0646, "GeForce GT 120" },
{ 0x10DE0647, "GeForce 9600M GT" },
{ 0x10DE0648, "GeForce 9600M GS" },
{ 0x10DE0649, "GeForce 9600M GT" },
{ 0x10DE06E9, "GeForce 9300M GS" },
{ 0x10DE06EA, "Quadro NVS 150M" },
{ 0x10DE06EB, "Quadro NVS 160M" },
/*************** GT2xx *************/
{ 0x10DE05E0, "GeForce GTX 295" },
{ 0x10DE05E1, "GeForce GTX 280" },
{ 0x10DE05E2, "GeForce GTX 260" },
{ 0x10DE05E3, "GeForce GTX 285" },
{ 0x10DE05E6, "GeForce GTX 275" },
{ 0x10DE0A20, "GeForce GT220" },
{ 0x10DE0A60, "GeForce G210" },
{ 0x10DE0A65, "GeForce 210" }
};
uint32_t swap32(uint32_t toswap) {
return ((toswap & 0x000000FF) << 24) |
((toswap & 0x0000FF00) << 8 ) |
((toswap & 0x00FF0000) >> 8 ) |
((toswap & 0xFF000000) >> 24);
}
uint8_t read8(uint8_t *ptr, uint16_t offset) {
return ptr[offset];
static uint16_t swap16(uint16_t x)
{
return (((x & 0x00FF) << 8) | ((x & 0xFF00) >> 8));
}
uint16_t read16(uint8_t *ptr, uint16_t offset) {
static uint16_t read16(uint8_t *ptr, uint16_t offset)
{
uint8_t ret[2];
ret[0] = ptr[offset+1];
ret[1] = ptr[offset];
return *((uint16_t*)&ret);
}
uint32_t read32(uint8_t *ptr, uint16_t offset) {
#if 0
static uint32_t swap32(uint32_t x)
{
return ((x & 0x000000FF) << 24) | ((x & 0x0000FF00) << 8 ) | ((x & 0x00FF0000) >> 8 ) | ((x & 0xFF000000) >> 24);
}
static uint8_t read8(uint8_t *ptr, uint16_t offset)
{
return ptr[offset];
}
static uint32_t read32(uint8_t *ptr, uint16_t offset)
{
uint8_t ret[4];
ret[0] = ptr[offset+3];
ret[1] = ptr[offset+2];
ret[3] = ptr[offset];
return *((uint32_t*)&ret);
}
int patch_nvidia_rom(uint8_t *rom) {
if(!rom || (rom[0] != 0x55 && rom[1] != 0xaa)) {
#endif
static int patch_nvidia_rom(uint8_t *rom)
{
if (!rom || (rom[0] != 0x55 && rom[1] != 0xaa)) {
printf("False ROM signature: 0x%02x%02x\n", rom[0], rom[1]);
return PATCH_ROM_FAILED;
}
return (has_lvds ? PATCH_ROM_SUCCESS_HAS_LVDS : PATCH_ROM_SUCCESS);
}
char *get_nvidia_model(uint32_t id) {
int i=0;
for(i = 0; i < (sizeof(NVKnownChipsets) / sizeof(NVKnownChipsets[0])); i++) {
if(NVKnownChipsets[i].device == id)
static char *get_nvidia_model(uint32_t id) {
inti;
for (i=1; i< (sizeof(NVKnownChipsets) / sizeof(NVKnownChipsets[0])); i++) {
if (NVKnownChipsets[i].device == id) {
return NVKnownChipsets[i].name;
}
}
return NVKnownChipsets[0].name;
}
uint32_t load_nvidia_bios_file(char *filename, char *buffer)
static uint32_t load_nvidia_bios_file(const char *filename, uint8_t *buf, int bufsize)
{
intfd, size;
chardirspec[128];
intfd;
intsize;
// Check booting partition
sprintf(dirspec, "%s", filename);
fd = open(dirspec, 0);
if (fd < 0)
{
// Check Extra on booting partition
sprintf(dirspec, "/Extra/%s", filename);
fd = open(dirspec, 0);
if (fd < 0)
{
// Fall back to booter partition
sprintf(dirspec, "bt(0,0)/Extra/%s", filename);
fd=open (dirspec, 0);
if (fd < 0)
return 0;
}
if ((fd = open_bvdev("bt(0,0)", filename, 0)) < 0) {
return 0;
}
size = read(fd, buffer, file_size (fd));
close (fd);
return size;
size = file_size(fd);
if (size > bufsize) {
printf("Filesize of %s is bigger than expected! Truncating to 0x%x Bytes!\n", filename, bufsize);
size = bufsize;
}
size = read(fd, (char *)buf, size);
close(fd);
return size;
}
int devprop_add_nvidia_template(struct DevPropDevice *device)
static int devprop_add_nvidia_template(struct DevPropDevice *device)
{
chartmp[16];
intlen;
if(!device)
return 0;
if(!DP_ADD_TEMP_VAL(device, nvidia_compatible_0))
return 0;
if(!DP_ADD_TEMP_VAL(device, nvidia_device_type_0))
return 0;
if(!DP_ADD_TEMP_VAL(device, nvidia_device_type))
return 0;
char tmp[10];
sprintf(tmp, "Slot-%x",devices_number);
devprop_add_value(device, "AAPL,slot-name", tmp, strlen(tmp));
len = sprintf(tmp, "Slot-%x", devices_number);
devprop_add_value(device, "AAPL,slot-name", (uint8_t *)tmp, len + 1);
devices_number++;
return 1;
}
bool setup_nvidia_devprop(pci_dt_t *nvda_dev)
{
intlen;
char*devicepath;
uint8_t*nvRom, *rom;
volatile uint8_t *regs;
uint32_tvideoRam, nvBiosOveride, nvBiosSize;
uint32_tbar[7];
uint8_tnvPatch = 0;
charbiosVersion[32];
char*model;
const char*nvFilename;
struct DevPropDevice*device;
char*devicepath;
struct pci_rom_pci_header_t*rom_pci_header;
volatile uint8_t*regs;
uint8_t*rom;
uint8_t*nvRom;
uint32_tvideoRam;
uint32_tnvBiosOveride;
uint32_tbar[7];
uint32_tboot_display;
intnvPatch;
charbiosVersion[32];
charnvFilename[32];
char*model;
booldoit;
devicepath = get_pci_dev_path(nvda_dev);
bar[0] = pci_config_read32(nvda_dev->dev.addr, 0x10 );
regs = (uint8_t *) (bar[0] & ~0x0f);
// Amount of VRAM in kilobytes
videoRam = (REG32(0x10020c) & 0xfff00000) >> 10;
model = get_nvidia_model((nvda_dev->vendor_id << 16) | nvda_dev->device_id);
verbose("nVidia %s %dMB NV%02x [%04x:%04x] :: %s\n",
model, (videoRam / 1024),
(REG32(0) >> 20) & 0x1ff, nvda_dev->vendor_id, nvda_dev->device_id,
devicepath);
model, (videoRam / 1024),
(REG32(0) >> 20) & 0x1ff, nvda_dev->vendor_id, nvda_dev->device_id,
devicepath);
rom = malloc(0x10000);
rom = malloc(NVIDIA_ROM_SIZE);
sprintf(nvFilename, "/Extra/%04x_%04x.rom", (uint16_t)nvda_dev->vendor_id, (uint16_t)nvda_dev->device_id);
if (getBoolForKey(kUseNvidiaROM, &doit, &bootInfo->bootConfig) && doit) {
verbose("Looking for nvidia video bios file %s\n", nvFilename);
nvBiosOveride = load_nvidia_bios_file(nvFilename, rom, NVIDIA_ROM_SIZE);
DBG("%s Signature 0x%02x%02x %d bytes\n", nvFilename, rom[0], rom[1], nvBiosOveride);
} else {
// Otherwise read bios from card
nvBiosOveride = 0;
if(!rom)
{
verbose(" ROM malloc failed.\n");
return 0;
}
// TODO: we should really check for the signature before copying the rom, i think.
if (!getValueForKey("VideoROM", &nvFilename, &len, &bootInfo->bootConfig))
nvFilename="NVIDIA.ROM";
// Load video bios overide
nvBiosOveride = nvBiosSize = load_nvidia_bios_file((char *)nvFilename, (char *)rom);
// Otherwise read bios from card
if (nvBiosOveride == 0)
{
// TODO: we should really check for the signature
// before copying the rom, i think.
// PRAMIN first
nvRom = (uint8_t*)&regs[NV_PRAMIN_OFFSET];
bcopy((uint32_t *)nvRom, rom, 0x10000);
bcopy((uint32_t *)nvRom, rom, NVIDIA_ROM_SIZE);
// Valid Signature ?
if(rom[0] != 0x55 && rom[1] != 0xaa)
{
if (rom[0] != 0x55 && rom[1] != 0xaa) {
// PROM next
// Enable PROM access
(REG32(NV_PBUS_PCI_NV_20)) = NV_PBUS_PCI_NV_20_ROM_SHADOW_DISABLED;
nvRom = (uint8_t*)&regs[NV_PROM_OFFSET];
bcopy((uint8_t *)nvRom, rom, 0x10000);
bcopy((uint8_t *)nvRom, rom, NVIDIA_ROM_SIZE);
// disable PROM access
(REG32(NV_PBUS_PCI_NV_20)) = NV_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED;
// Valid Signature ?
if(rom[0] != 0x55 && rom[1] != 0xaa)
{
if (rom[0] != 0x55 && rom[1] != 0xaa) {
// 0xC0000 last
bcopy((char *)0xc0000, rom, 0x10000);
bcopy((char *)0xc0000, rom, NVIDIA_ROM_SIZE);
// Valid Signature ?
if(rom[0] != 0x55 && rom[1] != 0xaa)
{
verbose(" Unable to locate video bios.\n");
if