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