]>
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_OSREFERENCE_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. 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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
28 #include <mach/std_types.h>
29 #include <ppc/proc_reg.h>
33 // The sophisticated BAT manager
35 unsigned int mappedSegments
= 0;
36 unsigned int availableBATs
= 0xE; // BAT0 used, 1-3 available
39 PEResidentAddress( vm_offset_t address
, vm_size_t length
)
41 if( mappedSegments
& (1 << (15 & (address
>> 28))))
48 PEMapSegment( vm_offset_t address
, vm_size_t length
)
50 vm_offset_t retAddress
;
54 retAddress
= PEResidentAddress( address
, length
);
58 if( length
< (256 * 1024))
60 if( availableBATs
== 0)
64 (0 == (availableBATs
& (1 << batNum
)));
67 bat
.upper
.word
= address
& 0xf0000000;
68 bat
.lower
.word
= bat
.upper
.word
;
70 bat
.upper
.bits
.bl
= 0x7ff; /* size = 256M */
71 bat
.upper
.bits
.vs
= 1;
72 bat
.upper
.bits
.vp
= 0; /* user disabled */
74 bat
.lower
.bits
.wimg
= PTE_WIMG_IO
;
75 bat
.lower
.bits
.pp
= 2; /* read/write access */
77 // Update the shadow bats.
78 shadow_BAT
.DBATs
[batNum
].upper
= bat
.upper
.word
;
79 shadow_BAT
.DBATs
[batNum
].lower
= bat
.lower
.word
;
82 switch( batNum
) { // !%$@!! mtdbat needs literal
84 mtdbatu( 0, BAT_INVALID
); /* invalidate old mapping */
85 mtdbatl( 0, bat
.lower
.word
);
86 mtdbatu( 0, bat
.upper
.word
);
89 mtdbatu( 1, BAT_INVALID
);
90 mtdbatl( 1, bat
.lower
.word
);
91 mtdbatu( 1, bat
.upper
.word
);
94 mtdbatu( 2, BAT_INVALID
);
95 mtdbatl( 2, bat
.lower
.word
);
96 mtdbatu( 2, bat
.upper
.word
);
99 mtdbatu( 3, BAT_INVALID
);
100 mtdbatl( 3, bat
.lower
.word
);
101 mtdbatu( 3, bat
.upper
.word
);
106 availableBATs
&= ~(1 << batNum
);
107 mappedSegments
|= (1 << (15 & (address
>> 28)));
112 void initialize_bats(boot_args
*args
)
116 /* Give ourselves the virtual map that we would like */
119 /* Make sure that the BATs map what we expect. Note
120 * that we assume BAT0 maps kernel text & data.
122 * Except, oops, none of the BATs have ever been set.
123 * Developer worked only by fluke.
127 bat
.upper
.bits
.bepi
= 0x0; /* start at logical addr 0M */
129 * We should be smarter here about picking an
132 bat
.upper
.bits
.bl
= 0x7ff; /* size = 256M */
133 bat
.upper
.bits
.vs
= 1;
134 bat
.upper
.bits
.vp
= 0;
137 bat
.lower
.bits
.brpn
= 0x0; /* start at physical addr 0 */
138 bat
.lower
.bits
.wimg
= PTE_WIMG_DEFAULT
;
139 bat
.lower
.bits
.pp
= 2; /* read/write access */
141 /* Mustn't cause any data traffic here,
142 * we're modifying our data BAT register!
146 mtdbatu(0, BAT_INVALID
); /* invalidate old mapping */
148 mtdbatl(0, bat
.lower
.word
);
150 mtdbatu(0, bat
.upper
.word
); /* update with new mapping */
152 mtibatl(0, bat
.lower
.word
);
154 mtibatu(0, bat
.upper
.word
); /* update with new mapping */
158 mtdbatu(1,BAT_INVALID
); mtdbatl(1,BAT_INVALID
);
159 mtibatu(1,BAT_INVALID
); mtibatl(1,BAT_INVALID
);
160 mtdbatu(2,BAT_INVALID
); mtdbatl(2,BAT_INVALID
);
161 mtibatu(2,BAT_INVALID
); mtibatl(2,BAT_INVALID
);
162 mtdbatu(3,BAT_INVALID
); mtdbatl(3,BAT_INVALID
);
163 mtibatu(3,BAT_INVALID
); mtibatl(3,BAT_INVALID
);
166 PEMapSegment( 0xf0000000, 0x10000000);
167 if( args
->Video
.v_baseAddr
)
168 PEMapSegment( args
->Video
.v_baseAddr
, 0x10000000);
170 /* Set up segment registers as VM through space 0 */
172 for (i
=0; i
<=15; i
++) {
173 mtsrin(KERNEL_SEG_REG0_VALUE
| i
, i
* 0x10000000);
179 * Adjust the size of the region mapped by a BAT
180 * to to be just large enough to include the specified
181 * offset, and return the offset of the new end of the region.
182 * Note that both 'offsets' are really *lengths*, i.e. the
183 * offset of the end of the mapped region from the beginning.
184 * Either the instruction or data BATs (or both) can be specified.
185 * If the new length is greater than the size mappable by a BAT,
186 * then that value is just returned and no changes are made.
190 vm_offset_t new_minimum
,
196 vm_offset_t new_limit
;
198 if (new_minimum
<= 256*1024*1024) {
201 new_limit
= 128*1024;
202 while (new_limit
< new_minimum
) {
210 if (dbat
) switch (batn
) {
253 if (ibat
) switch (batn
) {
298 new_limit
= new_minimum
;