1 | /*␊ |
2 | Copyright (c) 2010, Intel Corporation␊ |
3 | All rights reserved.␊ |
4 | ␊ |
5 | Redistribution and use in source and binary forms, with or without␊ |
6 | modification, are permitted provided that the following conditions are met:␊ |
7 | ␊ |
8 | * Redistributions of source code must retain the above copyright notice,␊ |
9 | this list of conditions and the following disclaimer.␊ |
10 | * Redistributions in binary form must reproduce the above copyright notice,␊ |
11 | this list of conditions and the following disclaimer in the documentation␊ |
12 | and/or other materials provided with the distribution.␊ |
13 | * Neither the name of Intel Corporation nor the names of its contributors␊ |
14 | may be used to endorse or promote products derived from this software␊ |
15 | without specific prior written permission.␊ |
16 | ␊ |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND␊ |
18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED␊ |
19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE␊ |
20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR␊ |
21 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES␊ |
22 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;␊ |
23 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON␊ |
24 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT␊ |
25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS␊ |
26 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.␊ |
27 | */␊ |
28 | /*␊ |
29 | * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.␊ |
30 | *␊ |
31 | * @APPLE_LICENSE_HEADER_START@␊ |
32 | * ␊ |
33 | * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights␊ |
34 | * Reserved. This file contains Original Code and/or Modifications of␊ |
35 | * Original Code as defined in and that are subject to the Apple Public␊ |
36 | * Source License Version 2.0 (the 'License'). You may not use this file␊ |
37 | * except in compliance with the License. Please obtain a copy of the␊ |
38 | * License at http://www.apple.com/publicsource and read it before using␊ |
39 | * this file.␊ |
40 | * ␊ |
41 | * The Original Code and all software distributed under the License are␊ |
42 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER␊ |
43 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,␊ |
44 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,␊ |
45 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the␊ |
46 | * License for the specific language governing rights and limitations␊ |
47 | * under the License.␊ |
48 | * ␊ |
49 | * @APPLE_LICENSE_HEADER_END@␊ |
50 | */␊ |
51 | ␊ |
52 | ␊ |
53 | #import <Foundation/Foundation.h>␊ |
54 | #import <IOKit/IOReturn.h>␊ |
55 | ␊ |
56 | #include "Intel_Acpi/acpidecode.h"␊ |
57 | #include "Intel_Acpi/ppmsetup.h"␊ |
58 | ␊ |
59 | unsigned long uuid32;␊ |
60 | #define UUID_LEN␉16␊ |
61 | #define UUID_STR_LEN UUID_LEN*2 + 8␊ |
62 | typedef int8_t EFI_CHAR8;␊ |
63 | ␊ |
64 | unsigned long␊ |
65 | adler32( unsigned char * buffer, long length );␊ |
66 | U8 GetChecksum(void *mem_addr, U32 mem_size);␊ |
67 | void SetChecksum(struct acpi_table_header *header);␊ |
68 | const char * getStringFromUUID(const EFI_CHAR8* eUUID);␊ |
69 | ␊ |
70 | ␊ |
71 | unsigned long␊ |
72 | adler32( unsigned char * buffer, long length )␊ |
73 | {␊ |
74 | long cnt;␊ |
75 | unsigned long result, lowHalf, highHalf;␊ |
76 | ␊ |
77 | lowHalf = 1;␊ |
78 | highHalf = 0;␊ |
79 | ␉␊ |
80 | ␉for ( cnt = 0; cnt < length; cnt++ )␊ |
81 | {␊ |
82 | if ((cnt % 5000) == 0)␊ |
83 | {␊ |
84 | lowHalf %= 65521L;␊ |
85 | highHalf %= 65521L;␊ |
86 | }␊ |
87 | ␉␉␊ |
88 | lowHalf += buffer[cnt];␊ |
89 | highHalf += lowHalf;␊ |
90 | }␊ |
91 | ␉␊ |
92 | ␉lowHalf %= 65521L;␊ |
93 | ␉highHalf %= 65521L;␊ |
94 | ␉␊ |
95 | ␉result = (highHalf << 16) | lowHalf;␊ |
96 | ␉␊ |
97 | ␉return result;␊ |
98 | }␊ |
99 | ␊ |
100 | //-------------------------------------------------------------------------------␊ |
101 | //␊ |
102 | // Procedure: GetChecksum - Performs byte checksum␊ |
103 | //␊ |
104 | //-------------------------------------------------------------------------------␊ |
105 | U8 GetChecksum(void *mem_addr, U32 mem_size)␊ |
106 | {␊ |
107 | U8 *current = mem_addr;␊ |
108 | U8 *end = current + mem_size;␊ |
109 | U8 checksum = 0;␊ |
110 | ␊ |
111 | for (; current < end; current++)␊ |
112 | checksum = checksum + *current;␊ |
113 | ␊ |
114 | return (checksum);␊ |
115 | }␊ |
116 | ␊ |
117 | void SetChecksum(struct acpi_table_header *header)␊ |
118 | {␊ |
119 | header->Checksum = 0;␊ |
120 | header->Checksum = 0 - GetChecksum(header, header->Length);␊ |
121 | }␊ |
122 | ␊ |
123 | ␊ |
124 | /** Transform a 16 bytes hexadecimal value UUID to a string */␊ |
125 | /* getStringFromUUID : credit to Rekursor (see convert.c) */␊ |
126 | const char * getStringFromUUID(const EFI_CHAR8* eUUID)␊ |
127 | {␊ |
128 | ␉static char msg[UUID_STR_LEN] = "";␊ |
129 | ␉if (!eUUID) return "";␊ |
130 | ␉const unsigned char * uuid = (unsigned char*) eUUID;␊ |
131 | ␉sprintf(msg, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",␊ |
132 | ␉␉ uuid[0], uuid[1], uuid[2], uuid[3], ␊ |
133 | ␉␉ uuid[4], uuid[5], uuid[6], uuid[7],␊ |
134 | ␉␉ uuid[8], uuid[9], uuid[10],uuid[11],␊ |
135 | ␉␉ uuid[12],uuid[13],uuid[14],uuid[15]);␊ |
136 | ␉return msg ;␊ |
137 | }␊ |
138 | ␊ |
139 | int main (int argc, const char * argv[]) {␊ |
140 | NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];␊ |
141 | ␊ |
142 | mach_port_t masterPort;␊ |
143 | ␉␊ |
144 | ␉io_registry_entry_t entry,entry2;␊ |
145 | ␉␊ |
146 | ␉kern_return_t err;␊ |
147 | ␉␊ |
148 | ␉CFDataRef data;␊ |
149 | ␉␊ |
150 | ␉CFAllocatorRef allocator=kCFAllocatorDefault;␊ |
151 | ␉␊ |
152 | ␉const UInt8* rawdata = NULL;␊ |
153 | ␉␊ |
154 | ␉UInt32 uuid32 = 0;␊ |
155 | ␉UInt32 Model32 = 0;␊ |
156 | ␉const char *cfilename ;␊ |
157 | ␉NSString *filename, *fullfilename ;␊ |
158 | ␉NSArray *namechunks;␊ |
159 | ␉NSMutableArray *chunks;␉␊ |
160 | ␉char * input, *output, dirspec[512];␊ |
161 | ␉NSString *outStr, *inStr;␊ |
162 | ␊ |
163 | ␉if (argc > 3 || argc < 2) {␊ |
164 | ␉␉printf("Usage: amlsgn input(as a file) output(as a directory)\n");␊ |
165 | ␉␉return 1;␊ |
166 | } else if (argc == 2) {␉␊ |
167 | ␉␉␊ |
168 | ␉␉/* Creating output string */␊ |
169 | ␉␉inStr = [NSString stringWithUTF8String:argv[1]];␊ |
170 | ␉␉chunks = [[NSMutableArray alloc] init];␊ |
171 | ␉␉[chunks addObjectsFromArray:[inStr componentsSeparatedByString: @"/"]];␊ |
172 | ␉␉␊ |
173 | ␉␉fullfilename = [chunks lastObject];␊ |
174 | ␉␉namechunks = [fullfilename componentsSeparatedByString: @"."];␊ |
175 | ␉␉filename = [namechunks objectAtIndex:0];␊ |
176 | ␉␉cfilename = [filename UTF8String];␊ |
177 | ␉␉␊ |
178 | ␉␉[chunks removeLastObject];␊ |
179 | ␉␉outStr = [chunks componentsJoinedByString: @"/"];␊ |
180 | ␊ |
181 | ␉} else {␊ |
182 | ␉␉inStr = [NSString stringWithUTF8String:argv[1]];␊ |
183 | ␉␉BOOL isDirectory= FALSE;␊ |
184 | ␉␉if ([[NSFileManager defaultManager] fileExistsAtPath:outStr isDirectory:&isDirectory]) {␊ |
185 | ␉␉␉␊ |
186 | ␉␉␉if (isDirectory == FALSE) {␊ |
187 | ␉␉␉␉chunks = [[NSMutableArray alloc] init];␊ |
188 | ␉␉␉␉[chunks addObjectsFromArray:[inStr componentsSeparatedByString: @"/"]];␊ |
189 | ␉␉␉␉␊ |
190 | ␉␉␉␉[chunks removeLastObject];␊ |
191 | ␉␉␉␉outStr = [chunks componentsJoinedByString: @"/"];␊ |
192 | ␉␉␉} else {␊ |
193 | ␉␉␉␉outStr = [NSString stringWithUTF8String:argv[2]];␊ |
194 | ␊ |
195 | ␉␉␉}␉␉␉␊ |
196 | ␉␉} ␊ |
197 | ␊ |
198 | ␉}␊ |
199 | ␉␊ |
200 | ␉do {␊ |
201 | ␉␉BOOL isDirectory= FALSE;␊ |
202 | ␉␉if ([[NSFileManager defaultManager] fileExistsAtPath:outStr isDirectory:&isDirectory] && isDirectory) {␊ |
203 | ␉␉␊ |
204 | ␉␉␉if ([[NSFileManager defaultManager] isWritableFileAtPath:outStr])␊ |
205 | ␉␉␉␉break;␊ |
206 | ␉␉}␊ |
207 | ␉␉␊ |
208 | ␉␉outStr = [NSHomeDirectory() stringByAppendingPathComponent: @"Desktop"];␊ |
209 | ␊ |
210 | ␉} while (0);␊ |
211 | ␉␊ |
212 | ␉␊ |
213 | ␉err = IOMasterPort(MACH_PORT_NULL, &masterPort);␊ |
214 | ␉␊ |
215 | ␉if (err == KERN_SUCCESS){␉␉␊ |
216 | ␉␉␊ |
217 | ␉␉entry2=IORegistryEntryFromPath(masterPort, [@"IODeviceTree:/efi" UTF8String]);␊ |
218 | ␊ |
219 | ␉␉if (entry2!=MACH_PORT_NULL) {␉␉␉␊ |
220 | ␉␉␉␊ |
221 | ␉␉␉data = IORegistryEntrySearchCFProperty( entry2, kIOServicePlane, CFSTR("motherboard-name"), allocator, kIORegistryIterateRecursively);␊ |
222 | ␉␉␉␊ |
223 | ␉␉␉if (data != NULL) {␊ |
224 | ␉␉␉␉rawdata=CFDataGetBytePtr(data);␊ |
225 | ␉␉␉␉␊ |
226 | ␉␉␉␉int len = 0;␊ |
227 | ␉␉␉␉␊ |
228 | ␉␉␉␉char *ModelStr = ( char* )rawdata;␊ |
229 | ␉␉␉␉␊ |
230 | ␉␉␉␉if (len = strlen(ModelStr)) ␊ |
231 | ␉␉␉␉{␊ |
232 | ␉␉␉␉␉Model32 = OSSwapHostToBigInt32(adler32( (unsigned char *) ModelStr, len ));␊ |
233 | ␉␉␉␉␉␊ |
234 | ␉␉␉␉␉printf("uuid32 0x%lu uuidStr %s\n",(unsigned long)Model32,ModelStr);␊ |
235 | ␉␉␉␉␉␊ |
236 | ␉␉␉␉␉UInt8 mem[1024*1024];␊ |
237 | ␉␉␉␉␉␊ |
238 | ␉␉␉␉␉bzero(mem, sizeof(mem));␉␉␉␉␉␊ |
239 | ␉␉␉␉␉␊ |
240 | ␉␉␉␉␉int fdIn = open([inStr UTF8String], O_RDONLY, 0666);␊ |
241 | ␉␉␉␉␉␊ |
242 | ␉␉␉␉␉if (-1 == fdIn) {␊ |
243 | ␉␉␉␉␉␉printf("Error while opening the file \n");␊ |
244 | ␉␉␉␉␉␉return 1;␊ |
245 | ␉␉␉␉␉}␊ |
246 | ␉␉␉␉␉␊ |
247 | ␉␉␉␉␉size_t nbRead = read(fdIn, (void*)mem, sizeof(mem));␊ |
248 | ␉␉␉␉␉if (nbRead <= 0) {␊ |
249 | ␉␉␉␉␉␉printf("Error: Unable to read the file\n");␉␉␊ |
250 | ␉␉␉␉␉␉close(fdIn);␊ |
251 | ␉␉␉␉␉␉return 1; ␊ |
252 | ␉␉␉␉␉}␊ |
253 | ␉␉␉␉␉␊ |
254 | ␉␉␉␉␉ACPI_TABLE_HEADER * head = (ACPI_TABLE_HEADER *)mem;␊ |
255 | ␉␉␉␉␉␊ |
256 | ␉␉␉␉␉close(fdIn);␊ |
257 | ␉␉␉␉␉␊ |
258 | ␉␉␉␉␉head->OemRevision = Model32;␊ |
259 | ␉␉␉␉␉␊ |
260 | ␉␉␉␉␉SetChecksum(head);␊ |
261 | ␉␉␉␉␉␊ |
262 | ␉␉␉␉␉{␉␉␊ |
263 | ␉␉␉␉␉␉char dir[1024];␊ |
264 | ␉␉␉␉␉␉␊ |
265 | ␉␉␉␉␉␉sprintf(dir,"%s/%s.%s.aml",[outStr UTF8String],cfilename,ModelStr);␊ |
266 | ␊ |
267 | ␉␉␉␉␉␉int fdOut = open(dir, O_WRONLY | O_CREAT, 0666);␊ |
268 | ␉␉␉␉␉␉␊ |
269 | ␉␉␉␉␉␉if (-1 == fdOut) {␊ |
270 | ␉␉␉␉␉␉␉printf("Error: Can't save the file\n");␊ |
271 | ␉␉␉␉␉␉␉return 1;␊ |
272 | ␉␉␉␉␉␉}␊ |
273 | ␉␉␉␉␉␉write(fdOut, mem, head->Length);␊ |
274 | ␉␉␉␉␉␉␊ |
275 | ␉␉␉␉␉␉close(fdOut);␊ |
276 | ␉␉␉␉␉}␊ |
277 | ␉␉␉␉}␉␉␉␉␊ |
278 | ␉␉␉␉␊ |
279 | ␉␉␉␉IOObjectRelease(entry2);␊ |
280 | ␉␉␉␉␊ |
281 | ␉␉␉␉goto out;␊ |
282 | ␉␉␉}␉␉␉␊ |
283 | ␉␉␉␊ |
284 | ␉␉} ␉␉␊ |
285 | ␉␉␊ |
286 | ␉␉printf("No Model entry \n");␊ |
287 | ␉␉␉␊ |
288 | ␉␉entry=IORegistryEntryFromPath(masterPort, [@"IODeviceTree:/efi/platform" UTF8String]);␊ |
289 | ␊ |
290 | ␉␉if (entry!=MACH_PORT_NULL){␉␉␊ |
291 | ␉␉␉␊ |
292 | ␉␉␉␊ |
293 | ␉␉␉data = IORegistryEntrySearchCFProperty( entry, kIOServicePlane, CFSTR("system-id"), allocator, kIORegistryIterateRecursively);␊ |
294 | ␉␉␉␊ |
295 | ␉␉␉if (data != NULL) {␊ |
296 | ␉␉␉␉rawdata=CFDataGetBytePtr(data);␊ |
297 | ␉␉␉␉␊ |
298 | ␉␉␉␉␊ |
299 | ␉␉␉␉const char *uuidStr = getStringFromUUID(( EFI_CHAR8* )rawdata);␊ |
300 | ␉␉␉␉␊ |
301 | ␉␉␉␉if (strlen(uuidStr)) ␊ |
302 | ␉␉␉␉{␊ |
303 | ␉␉␉␉␉uuid32 = OSSwapHostToBigInt32(adler32( (unsigned char *) uuidStr, UUID_STR_LEN ));␊ |
304 | ␉␉␉␉␉␊ |
305 | ␉␉␉␉␉printf("uuid32 : 0x%lu\n",(unsigned long)uuid32);␊ |
306 | ␉␉␉␉␉printf("uuidStr : %s\n",uuidStr);␊ |
307 | ␊ |
308 | ␉␉␉␉␉UInt8 mem[1024*1024];␊ |
309 | ␉␉␉␉␉␊ |
310 | ␉␉␉␉␉bzero(mem, sizeof(mem));␊ |
311 | ␉␉␉␉␉␊ |
312 | ␉␉␉␉␉int fdIn = open([inStr UTF8String], O_RDONLY, 0666);␊ |
313 | ␉␉␉␉␉␊ |
314 | ␉␉␉␉␉if (-1 == fdIn) {␊ |
315 | ␉␉␉␉␉␉printf("Error while opening the file \n");␊ |
316 | ␉␉␉␉␉␉return 1;␊ |
317 | ␉␉␉␉␉}␊ |
318 | ␉␉␉␉␉␊ |
319 | ␉␉␉␉␉size_t nbRead = read(fdIn, (void*)mem, sizeof(mem));␊ |
320 | ␉␉␉␉␉if (nbRead <= 0) {␊ |
321 | ␉␉␉␉␉␉printf("Error: Unable to read the file\n");␉␉␊ |
322 | ␉␉␉␉␉␉close(fdIn);␊ |
323 | ␉␉␉␉␉␉return 1; ␊ |
324 | ␉␉␉␉␉}␊ |
325 | ␉␉␉␉␉␊ |
326 | ␉␉␉␉␉ACPI_TABLE_HEADER * head = (ACPI_TABLE_HEADER *)mem;␊ |
327 | ␉␉␉␉␉␊ |
328 | ␉␉␉␉␉close(fdIn);␊ |
329 | ␉␉␉␉␉␊ |
330 | ␉␉␉␉␉head->OemRevision = uuid32;␊ |
331 | ␉␉␉␉␉␊ |
332 | ␉␉␉␉␉SetChecksum(head);␊ |
333 | ␉␉␉␉␉␊ |
334 | ␉␉␉␉␉{␉␉␊ |
335 | ␉␉␉␉␉␉char dir[1024];␊ |
336 | ␉␉␉␉␉␉␊ |
337 | ␉␉␉␉␉␉sprintf(dir,"%s/%s.%lu.aml",[outStr UTF8String],cfilename,(unsigned long)uuid32);␊ |
338 | ␉␉␉␉␉␉␊ |
339 | ␉␉␉␉␉␉int fdOut = open(dir, O_WRONLY | O_CREAT, 0666);␊ |
340 | ␉␉␉␉␉␉␊ |
341 | ␉␉␉␉␉␉if (-1 == fdOut) {␊ |
342 | ␉␉␉␉␉␉␉printf("Error: Can't save the file\n");␊ |
343 | ␉␉␉␉␉␉␉return 1;␊ |
344 | ␉␉␉␉␉␉}␊ |
345 | ␉␉␉␉␉␉write(fdOut, mem, head->Length);␊ |
346 | ␉␉␉␉␉␉␊ |
347 | ␉␉␉␉␉␉close(fdOut);␊ |
348 | ␉␉␉␉␉}␊ |
349 | ␉␉␉␉}␊ |
350 | ␉␉␉␉␊ |
351 | ␉␉␉␉IOObjectRelease(entry);␊ |
352 | ␉␉␉␉␊ |
353 | ␉␉␉␉goto out;␊ |
354 | ␊ |
355 | ␉␉␉}␉␉␉␊ |
356 | ␉␉}␊ |
357 | ␉␉printf("No UUID entry\n");␊ |
358 | ␊ |
359 | ␉}␊ |
360 | out:␊ |
361 | [pool drain];␊ |
362 | return 0;␊ |
363 | }␊ |
364 | |