]>
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 * 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. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
23 #include <mach/std_types.h>
24 #include <ppc/proc_reg.h>
28 // The sophisticated BAT manager
30 unsigned int mappedSegments
= 0;
31 unsigned int availableBATs
= 0xE; // BAT0 used, 1-3 available
34 PEResidentAddress( vm_offset_t address
, vm_size_t length
)
36 if( mappedSegments
& (1 << (15 & (address
>> 28))))
43 PEMapSegment( vm_offset_t address
, vm_size_t length
)
45 vm_offset_t retAddress
;
49 retAddress
= PEResidentAddress( address
, length
);
53 if( length
< (256 * 1024))
55 if( availableBATs
== 0)
59 (0 == (availableBATs
& (1 << batNum
)));
62 bat
.upper
.word
= address
& 0xf0000000;
63 bat
.lower
.word
= bat
.upper
.word
;
65 bat
.upper
.bits
.bl
= 0x7ff; /* size = 256M */
66 bat
.upper
.bits
.vs
= 1;
67 bat
.upper
.bits
.vp
= 0; /* user disabled */
69 bat
.lower
.bits
.wimg
= PTE_WIMG_IO
;
70 bat
.lower
.bits
.pp
= 2; /* read/write access */
72 // Update the shadow bats.
73 shadow_BAT
.DBATs
[batNum
].upper
= bat
.upper
.word
;
74 shadow_BAT
.DBATs
[batNum
].lower
= bat
.lower
.word
;
77 switch( batNum
) { // !%$@!! mtdbat needs literal
79 mtdbatu( 0, BAT_INVALID
); /* invalidate old mapping */
80 mtdbatl( 0, bat
.lower
.word
);
81 mtdbatu( 0, bat
.upper
.word
);
84 mtdbatu( 1, BAT_INVALID
);
85 mtdbatl( 1, bat
.lower
.word
);
86 mtdbatu( 1, bat
.upper
.word
);
89 mtdbatu( 2, BAT_INVALID
);
90 mtdbatl( 2, bat
.lower
.word
);
91 mtdbatu( 2, bat
.upper
.word
);
94 mtdbatu( 3, BAT_INVALID
);
95 mtdbatl( 3, bat
.lower
.word
);
96 mtdbatu( 3, bat
.upper
.word
);
101 availableBATs
&= ~(1 << batNum
);
102 mappedSegments
|= (1 << (15 & (address
>> 28)));
107 void initialize_bats(boot_args
*args
)
111 /* Give ourselves the virtual map that we would like */
114 /* Make sure that the BATs map what we expect. Note
115 * that we assume BAT0 maps kernel text & data.
117 * Except, oops, none of the BATs have ever been set.
118 * Developer worked only by fluke.
122 bat
.upper
.bits
.bepi
= 0x0; /* start at logical addr 0M */
124 * We should be smarter here about picking an
127 bat
.upper
.bits
.bl
= 0x7ff; /* size = 256M */
128 bat
.upper
.bits
.vs
= 1;
129 bat
.upper
.bits
.vp
= 0;
132 bat
.lower
.bits
.brpn
= 0x0; /* start at physical addr 0 */
133 bat
.lower
.bits
.wimg
= PTE_WIMG_DEFAULT
;
134 bat
.lower
.bits
.pp
= 2; /* read/write access */
136 /* Mustn't cause any data traffic here,
137 * we're modifying our data BAT register!
141 mtdbatu(0, BAT_INVALID
); /* invalidate old mapping */
143 mtdbatl(0, bat
.lower
.word
);
145 mtdbatu(0, bat
.upper
.word
); /* update with new mapping */
147 mtibatl(0, bat
.lower
.word
);
149 mtibatu(0, bat
.upper
.word
); /* update with new mapping */
153 mtdbatu(1,BAT_INVALID
); mtdbatl(1,BAT_INVALID
);
154 mtibatu(1,BAT_INVALID
); mtibatl(1,BAT_INVALID
);
155 mtdbatu(2,BAT_INVALID
); mtdbatl(2,BAT_INVALID
);
156 mtibatu(2,BAT_INVALID
); mtibatl(2,BAT_INVALID
);
157 mtdbatu(3,BAT_INVALID
); mtdbatl(3,BAT_INVALID
);
158 mtibatu(3,BAT_INVALID
); mtibatl(3,BAT_INVALID
);
161 PEMapSegment( 0xf0000000, 0x10000000);
162 if( args
->Video
.v_baseAddr
)
163 PEMapSegment( args
->Video
.v_baseAddr
, 0x10000000);
165 /* Set up segment registers as VM through space 0 */
167 for (i
=0; i
<=15; i
++) {
168 mtsrin(KERNEL_SEG_REG0_VALUE
| i
, i
* 0x10000000);
174 * Adjust the size of the region mapped by a BAT
175 * to to be just large enough to include the specified
176 * offset, and return the offset of the new end of the region.
177 * Note that both 'offsets' are really *lengths*, i.e. the
178 * offset of the end of the mapped region from the beginning.
179 * Either the instruction or data BATs (or both) can be specified.
180 * If the new length is greater than the size mappable by a BAT,
181 * then that value is just returned and no changes are made.
185 vm_offset_t new_minimum
,
191 vm_offset_t new_limit
;
193 if (new_minimum
<= 256*1024*1024) {
196 new_limit
= 128*1024;
197 while (new_limit
< new_minimum
) {
205 if (dbat
) switch (batn
) {
248 if (ibat
) switch (batn
) {
293 new_limit
= new_minimum
;