]>
git.saurik.com Git - apple/xnu.git/blob - osfmk/ppc/bat_init.c
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
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
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.
23 * @APPLE_LICENSE_HEADER_END@
25 #include <mach/std_types.h>
26 #include <ppc/proc_reg.h>
30 // The sophisticated BAT manager
32 unsigned int mappedSegments
= 0;
33 unsigned int availableBATs
= 0xE; // BAT0 used, 1-3 available
36 PEResidentAddress( vm_offset_t address
, vm_size_t length
)
38 if( mappedSegments
& (1 << (15 & (address
>> 28))))
45 PEMapSegment( vm_offset_t address
, vm_size_t length
)
47 vm_offset_t retAddress
;
51 retAddress
= PEResidentAddress( address
, length
);
55 if( length
< (256 * 1024))
57 if( availableBATs
== 0)
61 (0 == (availableBATs
& (1 << batNum
)));
64 bat
.upper
.word
= address
& 0xf0000000;
65 bat
.lower
.word
= bat
.upper
.word
;
67 bat
.upper
.bits
.bl
= 0x7ff; /* size = 256M */
68 bat
.upper
.bits
.vs
= 1;
69 bat
.upper
.bits
.vp
= 0; /* user disabled */
71 bat
.lower
.bits
.wimg
= PTE_WIMG_IO
;
72 bat
.lower
.bits
.pp
= 2; /* read/write access */
74 // Update the shadow bats.
75 shadow_BAT
.DBATs
[batNum
].upper
= bat
.upper
.word
;
76 shadow_BAT
.DBATs
[batNum
].lower
= bat
.lower
.word
;
79 switch( batNum
) { // !%$@!! mtdbat needs literal
81 mtdbatu( 0, BAT_INVALID
); /* invalidate old mapping */
82 mtdbatl( 0, bat
.lower
.word
);
83 mtdbatu( 0, bat
.upper
.word
);
86 mtdbatu( 1, BAT_INVALID
);
87 mtdbatl( 1, bat
.lower
.word
);
88 mtdbatu( 1, bat
.upper
.word
);
91 mtdbatu( 2, BAT_INVALID
);
92 mtdbatl( 2, bat
.lower
.word
);
93 mtdbatu( 2, bat
.upper
.word
);
96 mtdbatu( 3, BAT_INVALID
);
97 mtdbatl( 3, bat
.lower
.word
);
98 mtdbatu( 3, bat
.upper
.word
);
103 availableBATs
&= ~(1 << batNum
);
104 mappedSegments
|= (1 << (15 & (address
>> 28)));
109 void initialize_bats(boot_args
*args
)
113 /* Give ourselves the virtual map that we would like */
116 /* Make sure that the BATs map what we expect. Note
117 * that we assume BAT0 maps kernel text & data.
119 * Except, oops, none of the BATs have ever been set.
120 * Developer worked only by fluke.
124 bat
.upper
.bits
.bepi
= 0x0; /* start at logical addr 0M */
126 * We should be smarter here about picking an
129 bat
.upper
.bits
.bl
= 0x7ff; /* size = 256M */
130 bat
.upper
.bits
.vs
= 1;
131 bat
.upper
.bits
.vp
= 0;
134 bat
.lower
.bits
.brpn
= 0x0; /* start at physical addr 0 */
135 bat
.lower
.bits
.wimg
= PTE_WIMG_DEFAULT
;
136 bat
.lower
.bits
.pp
= 2; /* read/write access */
138 /* Mustn't cause any data traffic here,
139 * we're modifying our data BAT register!
143 mtdbatu(0, BAT_INVALID
); /* invalidate old mapping */
145 mtdbatl(0, bat
.lower
.word
);
147 mtdbatu(0, bat
.upper
.word
); /* update with new mapping */
149 mtibatl(0, bat
.lower
.word
);
151 mtibatu(0, bat
.upper
.word
); /* update with new mapping */
155 mtdbatu(1,BAT_INVALID
); mtdbatl(1,BAT_INVALID
);
156 mtibatu(1,BAT_INVALID
); mtibatl(1,BAT_INVALID
);
157 mtdbatu(2,BAT_INVALID
); mtdbatl(2,BAT_INVALID
);
158 mtibatu(2,BAT_INVALID
); mtibatl(2,BAT_INVALID
);
159 mtdbatu(3,BAT_INVALID
); mtdbatl(3,BAT_INVALID
);
160 mtibatu(3,BAT_INVALID
); mtibatl(3,BAT_INVALID
);
163 PEMapSegment( 0xf0000000, 0x10000000);
164 if( args
->Video
.v_baseAddr
)
165 PEMapSegment( args
->Video
.v_baseAddr
, 0x10000000);
167 /* Set up segment registers as VM through space 0 */
169 for (i
=0; i
<=15; i
++) {
170 mtsrin(KERNEL_SEG_REG0_VALUE
| i
, i
* 0x10000000);
176 * Adjust the size of the region mapped by a BAT
177 * to to be just large enough to include the specified
178 * offset, and return the offset of the new end of the region.
179 * Note that both 'offsets' are really *lengths*, i.e. the
180 * offset of the end of the mapped region from the beginning.
181 * Either the instruction or data BATs (or both) can be specified.
182 * If the new length is greater than the size mappable by a BAT,
183 * then that value is just returned and no changes are made.
187 vm_offset_t new_minimum
,
193 vm_offset_t new_limit
;
195 if (new_minimum
<= 256*1024*1024) {
198 new_limit
= 128*1024;
199 while (new_limit
< new_minimum
) {
207 if (dbat
) switch (batn
) {
250 if (ibat
) switch (batn
) {
295 new_limit
= new_minimum
;