1/*
2 * Copyright (c) 2005-2007 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23/*
24 *  BLGetPreBootEnvironmentType.c
25 *  bless
26 *
27 *  Created by Shantonu Sen on 7/12/05.
28 *  Copyright 2005-2007 Apple Inc. All Rights Reserved.
29 *
30 */
31
32#include <stdlib.h>
33#include <unistd.h>
34#include <sys/param.h>
35
36#include <mach/mach_error.h>
37
38#include <IOKit/IOKitLib.h>
39#include <IOKit/IOKitKeys.h>
40
41#include <CoreFoundation/CoreFoundation.h>
42
43#include "bless.h"
44#include "bless_private.h"
45
46#define kBootRomPath "/openprom"
47#define kEFIPath "/efi"
48#define kiBootPath "/chosen/iBoot"
49
50int BLGetPreBootEnvironmentType(BLContextPtr context,
51				BLPreBootEnvType *pbType) {
52    const char *path = NULL;
53    kern_return_t ret;
54    io_registry_entry_t entry = 0;
55    CFMutableDictionaryRef props = NULL;
56    CFDataRef model = NULL;
57    mach_port_t	masterPort;
58
59#if 0
60    *pbType = kBLPreBootEnvType_EFI;
61    return 0;
62#endif
63
64    ret = IOMasterPort( MACH_PORT_NULL, &masterPort );
65    if(ret) return 0;
66
67    path = kIODeviceTreePlane ":" kBootRomPath;
68
69    entry = IORegistryEntryFromPath(masterPort, path);
70
71    if(entry == 0) {
72		path = kIODeviceTreePlane ":" kEFIPath;
73
74		entry = IORegistryEntryFromPath(masterPort, path);
75
76		if(entry == 0) {
77			path = kIODeviceTreePlane ":" kiBootPath;
78
79			entry = IORegistryEntryFromPath(masterPort, path);
80
81			if(entry == 0) {
82				*pbType = kBLPreBootEnvType_Unknown;
83				contextprintf(context, kBLLogLevelVerbose,  "No OpenFirmware or EFI.\n");
84			} else {
85				*pbType = kBLPreBootEnvType_iBoot;
86				IOObjectRelease(entry);
87				contextprintf(context, kBLLogLevelVerbose,  "iBoot found at %s\n", path);
88			}
89		} else {
90			*pbType = kBLPreBootEnvType_EFI;
91			IOObjectRelease(entry);
92			contextprintf(context, kBLLogLevelVerbose,  "EFI found at %s\n", path);
93		}
94
95		return 0;
96    }
97
98	// for OF
99    ret = IORegistryEntryCreateCFProperties(entry, &props,
100											kCFAllocatorDefault, 0);
101
102    if(ret) {
103		contextprintf(context, kBLLogLevelError, "Could not get entry properties\n");
104		CFRelease(props);
105		IOObjectRelease(entry);
106		// unknown
107		return 0;
108    }
109
110    model = CFDictionaryGetValue(props, CFSTR("model"));
111    if(model == NULL) {
112		contextprintf(context, kBLLogLevelVerbose,  "No 'model' property for %s\n", path);
113		CFRelease(props);
114		IOObjectRelease(entry);
115		return 0;
116    }
117
118	*pbType = kBLPreBootEnvType_OpenFirmware;
119    contextprintf(context, kBLLogLevelVerbose, "OpenFirmware found at %s\n", path);
120    contextprintf(context, kBLLogLevelVerbose, "OpenFirmware model is \"%*s\"\n", (int)CFDataGetLength(model), CFDataGetBytePtr(model));
121
122    CFRelease(props);
123    IOObjectRelease(entry);
124
125    return 0;
126}
127