]>
git.saurik.com Git - apple/xnu.git/blob - pexpert/ppc/pe_identify_machine.c
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
28 #include <pexpert/protos.h>
29 #include <pexpert/pexpert.h>
30 #include <pexpert/ppc/powermac.h>
31 #include <pexpert/device_tree.h>
34 extern void panic(const char *str
, ...);
36 /* Local declarations */
37 void pe_identify_machine(void);
38 vm_offset_t
get_io_base_addr(void);
40 /* pe_identify_machine:
42 * Sets up platform parameters.
45 void pe_identify_machine(void)
51 // Clear the gPEClockFrequencyInfo struct
52 bzero((void *)&gPEClockFrequencyInfo
, sizeof(clock_frequency_info_t
));
54 // Start with default values.
55 gPEClockFrequencyInfo
.timebase_frequency_hz
= 25000000;
56 gPEClockFrequencyInfo
.bus_clock_rate_hz
= 100000000;
57 gPEClockFrequencyInfo
.cpu_clock_rate_hz
= 300000000;
59 // Try to get the values from the device tree.
60 if (DTFindEntry("device_type", "cpu", &cpu
) == kSuccess
) {
61 // Find the time base frequency first.
62 if (DTGetProperty(cpu
, "timebase-frequency", (void **)&value
, &size
) == kSuccess
) {
63 // timebase_frequency_hz is only 32 bits, and the device tree should never provide 64 bits
64 // so this if should never be taken.
65 if (size
== 8) gPEClockFrequencyInfo
.timebase_frequency_hz
= *(unsigned long long *)value
;
66 else gPEClockFrequencyInfo
.timebase_frequency_hz
= *value
;
68 gPEClockFrequencyInfo
.dec_clock_rate_hz
= gPEClockFrequencyInfo
.timebase_frequency_hz
;
70 // Find the bus frequency next. Try the cpu node, then the root.
71 if (DTGetProperty(cpu
, "bus-frequency", (void **)&value
, &size
) == kSuccess
) {
72 if (size
== 8) gPEClockFrequencyInfo
.bus_frequency_hz
= *(unsigned long long *)value
;
73 else gPEClockFrequencyInfo
.bus_frequency_hz
= *value
;
75 if (DTLookupEntry(0, "/", &root
) == kSuccess
) {
76 if (DTGetProperty(root
, "clock-frequency", (void **)&value
, &size
) == kSuccess
) {
77 if (size
== 8) gPEClockFrequencyInfo
.bus_frequency_hz
= *(unsigned long long *)value
;
78 else gPEClockFrequencyInfo
.bus_frequency_hz
= *value
;
83 gPEClockFrequencyInfo
.bus_frequency_min_hz
= gPEClockFrequencyInfo
.bus_frequency_hz
;
84 gPEClockFrequencyInfo
.bus_frequency_max_hz
= gPEClockFrequencyInfo
.bus_frequency_hz
;
86 if (gPEClockFrequencyInfo
.bus_frequency_hz
< 0x100000000ULL
)
87 gPEClockFrequencyInfo
.bus_clock_rate_hz
= gPEClockFrequencyInfo
.bus_frequency_hz
;
89 gPEClockFrequencyInfo
.bus_clock_rate_hz
= 0xFFFFFFFF;
91 // Find the cpu frequency last.
92 if (DTGetProperty(cpu
, "clock-frequency", (void **)&value
, &size
) == kSuccess
) {
93 if (size
== 8) gPEClockFrequencyInfo
.cpu_frequency_hz
= *(unsigned long long *)value
;
94 else gPEClockFrequencyInfo
.cpu_frequency_hz
= *value
;
97 gPEClockFrequencyInfo
.cpu_frequency_min_hz
= gPEClockFrequencyInfo
.cpu_frequency_hz
;
98 gPEClockFrequencyInfo
.cpu_frequency_max_hz
= gPEClockFrequencyInfo
.cpu_frequency_hz
;
100 if (gPEClockFrequencyInfo
.cpu_frequency_hz
< 0x100000000ULL
)
101 gPEClockFrequencyInfo
.cpu_clock_rate_hz
= gPEClockFrequencyInfo
.cpu_frequency_hz
;
103 gPEClockFrequencyInfo
.cpu_clock_rate_hz
= 0xFFFFFFFF;
106 // Set the num / den pairs form the hz values.
107 gPEClockFrequencyInfo
.timebase_frequency_num
= gPEClockFrequencyInfo
.timebase_frequency_hz
;
108 gPEClockFrequencyInfo
.timebase_frequency_den
= 1;
110 gPEClockFrequencyInfo
.bus_clock_rate_num
= gPEClockFrequencyInfo
.bus_clock_rate_hz
;
111 gPEClockFrequencyInfo
.bus_clock_rate_den
= 1;
113 gPEClockFrequencyInfo
.bus_to_cpu_rate_num
=
114 (2 * gPEClockFrequencyInfo
.cpu_clock_rate_hz
) / gPEClockFrequencyInfo
.bus_clock_rate_hz
;
115 gPEClockFrequencyInfo
.bus_to_cpu_rate_den
= 2;
117 gPEClockFrequencyInfo
.bus_to_dec_rate_num
= 1;
118 gPEClockFrequencyInfo
.bus_to_dec_rate_den
=
119 gPEClockFrequencyInfo
.bus_clock_rate_hz
/ gPEClockFrequencyInfo
.dec_clock_rate_hz
;
122 /* get_io_base_addr():
124 * Get the base address of the io controller.
126 vm_offset_t
get_io_base_addr(void)
129 vm_offset_t
*address
;
132 if ((DTFindEntry("device_type", "dbdma", &entryP
) == kSuccess
)
133 || (DTFindEntry("device_type", "mac-io", &entryP
) == kSuccess
))
135 if (DTGetProperty(entryP
, "AAPL,address", (void **)&address
, &size
) == kSuccess
)
138 if (DTGetProperty(entryP
, "assigned-addresses", (void **)&address
, &size
) == kSuccess
)
139 // address calculation not correct
143 panic("Can't find this machine's io base address\n");
147 vm_offset_t
PE_find_scc(void)
149 vm_offset_t io
, sccadd
;
151 vm_offset_t
*sccregs
;
152 unsigned int sccrsize
;
154 if(!(io
= get_io_base_addr())) { /* Get the I/O controller base address */
155 return (vm_offset_t
)0; /* Hmmm, no I/O??? What gives??? How'd we even boot? */
159 /* Note: if we find a escc-legacy, we need to kind of hack because it can be either an offset
160 into the iobase or the actual address itself. ORint the two should provide the correct
163 sccadd
= 0; /* Assume none for now */
165 if(DTFindEntry("name", "escc-legacy", &entryP
) == kSuccess
) { /* Find the old fashioned serial port */
166 if (DTGetProperty(entryP
, "reg", (void **)&sccregs
, &sccrsize
) == kSuccess
) { /* Do we have some registers? */
167 sccadd
= ((vm_offset_t
)*sccregs
| io
); /* Get the address */
171 if(DTFindEntry("name", "escc", &entryP
) == kSuccess
) { /* Well, see if we just have the new fangled one */
172 sccadd
= io
+ 0x12000; /* Yeah, but still return the oldie goldie... */
175 return sccadd
; /* Return it if you found it */
178 unsigned int PE_init_taproot(vm_offset_t
*taddr
)
181 vm_offset_t
*tappdata
;
182 unsigned int tappsize
;
185 if(DTFindEntry("name", "memory-map", &entryP
) != kSuccess
) return 0; /* no memory map */
187 if (DTGetProperty(entryP
, "TapRoot", (void **)&tappdata
, &tappsize
) != kSuccess
) return 0; /* No TapRoot */
189 tappdata
[1] = (tappdata
[1] + 4095 ) & -4096; /* Make sure this is a whole page */
191 *taddr
= io_map_spec(tappdata
[0], tappdata
[1], VM_WIMG_IO
); /* Map it in and return the address */
192 tappdata
[0] = *taddr
; /* Also change property */
193 return tappdata
[1]; /* And the size */