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