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