]> git.saurik.com Git - apple/xnu.git/blob - pexpert/ppc/pe_identify_machine.c
xnu-517.3.15.tar.gz
[apple/xnu.git] / pexpert / ppc / pe_identify_machine.c
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25 #include <pexpert/protos.h>
26 #include <pexpert/pexpert.h>
27 #include <pexpert/ppc/powermac.h>
28 #include <pexpert/device_tree.h>
29
30 /* pe_identify_machine:
31 *
32 * Sets up platform parameters.
33 * Returns: nothing
34 */
35 void pe_identify_machine(void)
36 {
37 DTEntry cpu, root;
38 unsigned long *value;
39 int size;
40
41 // Clear the gPEClockFrequencyInfo struct
42 bzero((void *)&gPEClockFrequencyInfo, sizeof(clock_frequency_info_t));
43
44 // Start with default values.
45 gPEClockFrequencyInfo.timebase_frequency_hz = 25000000;
46 gPEClockFrequencyInfo.bus_clock_rate_hz = 100000000;
47 gPEClockFrequencyInfo.cpu_clock_rate_hz = 300000000;
48
49 // Try to get the values from the device tree.
50 if (DTFindEntry("device_type", "cpu", &cpu) == kSuccess) {
51 // Find the time base frequency first.
52 if (DTGetProperty(cpu, "timebase-frequency", (void **)&value, &size) == kSuccess) {
53 // timebase_frequency_hz is only 32 bits, and the device tree should never provide 64 bits
54 // so this if should never be taken.
55 if (size == 8) gPEClockFrequencyInfo.timebase_frequency_hz = *(unsigned long long *)value;
56 else gPEClockFrequencyInfo.timebase_frequency_hz = *value;
57 }
58 gPEClockFrequencyInfo.dec_clock_rate_hz = gPEClockFrequencyInfo.timebase_frequency_hz;
59
60 // Find the bus frequency next. Try the cpu node, then the root.
61 if (DTGetProperty(cpu, "bus-frequency", (void **)&value, &size) == kSuccess) {
62 if (size == 8) gPEClockFrequencyInfo.bus_frequency_hz = *(unsigned long long *)value;
63 else gPEClockFrequencyInfo.bus_frequency_hz = *value;
64 } else {
65 if (DTLookupEntry(0, "/", &root) == kSuccess) {
66 if (DTGetProperty(root, "clock-frequency", (void **)&value, &size) == kSuccess) {
67 if (size == 8) gPEClockFrequencyInfo.bus_frequency_hz = *(unsigned long long *)value;
68 else gPEClockFrequencyInfo.bus_frequency_hz = *value;
69 }
70 }
71 }
72
73 gPEClockFrequencyInfo.bus_frequency_min_hz = gPEClockFrequencyInfo.bus_frequency_hz;
74 gPEClockFrequencyInfo.bus_frequency_max_hz = gPEClockFrequencyInfo.bus_frequency_hz;
75
76 if (gPEClockFrequencyInfo.bus_frequency_hz < 0x100000000ULL)
77 gPEClockFrequencyInfo.bus_clock_rate_hz = gPEClockFrequencyInfo.bus_frequency_hz;
78 else
79 gPEClockFrequencyInfo.bus_clock_rate_hz = 0xFFFFFFFF;
80
81 // Find the cpu frequency last.
82 if (DTGetProperty(cpu, "clock-frequency", (void **)&value, &size) == kSuccess) {
83 if (size == 8) gPEClockFrequencyInfo.cpu_frequency_hz = *(unsigned long long *)value;
84 else gPEClockFrequencyInfo.cpu_frequency_hz = *value;
85 }
86
87 gPEClockFrequencyInfo.cpu_frequency_min_hz = gPEClockFrequencyInfo.cpu_frequency_hz;
88 gPEClockFrequencyInfo.cpu_frequency_max_hz = gPEClockFrequencyInfo.cpu_frequency_hz;
89
90 if (gPEClockFrequencyInfo.cpu_frequency_hz < 0x100000000ULL)
91 gPEClockFrequencyInfo.cpu_clock_rate_hz = gPEClockFrequencyInfo.cpu_frequency_hz;
92 else
93 gPEClockFrequencyInfo.cpu_clock_rate_hz = 0xFFFFFFFF;
94 }
95
96 // Set the num / den pairs form the hz values.
97 gPEClockFrequencyInfo.timebase_frequency_num = gPEClockFrequencyInfo.timebase_frequency_hz;
98 gPEClockFrequencyInfo.timebase_frequency_den = 1;
99
100 gPEClockFrequencyInfo.bus_clock_rate_num = gPEClockFrequencyInfo.bus_clock_rate_hz;
101 gPEClockFrequencyInfo.bus_clock_rate_den = 1;
102
103 gPEClockFrequencyInfo.bus_to_cpu_rate_num =
104 (2 * gPEClockFrequencyInfo.cpu_clock_rate_hz) / gPEClockFrequencyInfo.bus_clock_rate_hz;
105 gPEClockFrequencyInfo.bus_to_cpu_rate_den = 2;
106
107 gPEClockFrequencyInfo.bus_to_dec_rate_num = 1;
108 gPEClockFrequencyInfo.bus_to_dec_rate_den =
109 gPEClockFrequencyInfo.bus_clock_rate_hz / gPEClockFrequencyInfo.dec_clock_rate_hz;
110 }
111
112 /* get_io_base_addr():
113 *
114 * Get the base address of the io controller.
115 */
116 vm_offset_t get_io_base_addr(void)
117 {
118 DTEntry entryP;
119 vm_offset_t *address;
120 int size;
121
122 if ((DTFindEntry("device_type", "dbdma", &entryP) == kSuccess)
123 || (DTFindEntry("device_type", "mac-io", &entryP) == kSuccess))
124 {
125 if (DTGetProperty(entryP, "AAPL,address", (void **)&address, &size) == kSuccess)
126 return *address;
127
128 if (DTGetProperty(entryP, "assigned-addresses", (void **)&address, &size) == kSuccess)
129 // address calculation not correct
130 return *(address+2);
131 }
132
133 panic("Can't find this machine's io base address\n");
134 return 0;
135 }
136
137 vm_offset_t PE_find_scc(void)
138 {
139 vm_offset_t io, sccadd;
140 DTEntry entryP;
141 vm_offset_t *sccregs;
142 unsigned int sccrsize;
143
144 if(!(io = get_io_base_addr())) { /* Get the I/O controller base address */
145 return (vm_offset_t)0; /* Hmmm, no I/O??? What gives??? How'd we even boot? */
146 }
147
148
149 /* Note: if we find a escc-legacy, we need to kind of hack because it can be either an offset
150 into the iobase or the actual address itself. ORint the two should provide the correct
151 for either */
152
153 sccadd = 0; /* Assume none for now */
154
155 if(DTFindEntry("name", "escc-legacy", &entryP) == kSuccess) { /* Find the old fashioned serial port */
156 if (DTGetProperty(entryP, "reg", (void **)&sccregs, &sccrsize) == kSuccess) { /* Do we have some registers? */
157 sccadd = ((vm_offset_t)*sccregs | io); /* Get the address */
158 }
159 }
160
161 if(DTFindEntry("name", "escc", &entryP) == kSuccess) { /* Well, see if we just have the new fangled one */
162 sccadd = io + 0x12000; /* Yeah, but still return the oldie goldie... */
163 }
164
165 return sccadd; /* Return it if you found it */
166 }
167
168 unsigned int PE_init_taproot(vm_offset_t *taddr)
169 {
170 DTEntry entryP;
171 vm_offset_t *tappdata;
172 unsigned int tappsize;
173
174
175 if(DTFindEntry("name", "memory-map", &entryP) != kSuccess) return 0; /* no memory map */
176
177 if (DTGetProperty(entryP, "TapRoot", (void **)&tappdata, &tappsize) != kSuccess) return 0; /* No TapRoot */
178
179 tappdata[1] = (tappdata[1] + 4095 ) & -4096; /* Make sure this is a whole page */
180
181 *taddr = io_map_spec(tappdata[0], tappdata[1]); /* Map it in and return the address */
182 tappdata[0] = *taddr; /* Also change property */
183 return tappdata[1]; /* And the size */
184 }