]>
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 * 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.
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
20 * @APPLE_LICENSE_HEADER_END@
22 #include <mach/std_types.h>
23 #include <ppc/proc_reg.h>
27 // The sophisticated BAT manager
29 unsigned int mappedSegments
= 0;
30 unsigned int availableBATs
= 0xE; // BAT0 used, 1-3 available
33 PEResidentAddress( vm_offset_t address
, vm_size_t length
)
35 if( mappedSegments
& (1 << (15 & (address
>> 28))))
42 PEMapSegment( vm_offset_t address
, vm_size_t length
)
44 vm_offset_t retAddress
;
48 retAddress
= PEResidentAddress( address
, length
);
52 if( length
< (256 * 1024))
54 if( availableBATs
== 0)
58 (0 == (availableBATs
& (1 << batNum
)));
61 bat
.upper
.word
= address
& 0xf0000000;
62 bat
.lower
.word
= bat
.upper
.word
;
64 bat
.upper
.bits
.bl
= 0x7ff; /* size = 256M */
65 bat
.upper
.bits
.vs
= 1;
66 bat
.upper
.bits
.vp
= 0; /* user disabled */
68 bat
.lower
.bits
.wimg
= PTE_WIMG_IO
;
69 bat
.lower
.bits
.pp
= 2; /* read/write access */
71 // Update the shadow bats.
72 shadow_BAT
.DBATs
[batNum
].upper
= bat
.upper
.word
;
73 shadow_BAT
.DBATs
[batNum
].lower
= bat
.lower
.word
;
76 switch( batNum
) { // !%$@!! mtdbat needs literal
78 mtdbatu( 0, BAT_INVALID
); /* invalidate old mapping */
79 mtdbatl( 0, bat
.lower
.word
);
80 mtdbatu( 0, bat
.upper
.word
);
83 mtdbatu( 1, BAT_INVALID
);
84 mtdbatl( 1, bat
.lower
.word
);
85 mtdbatu( 1, bat
.upper
.word
);
88 mtdbatu( 2, BAT_INVALID
);
89 mtdbatl( 2, bat
.lower
.word
);
90 mtdbatu( 2, bat
.upper
.word
);
93 mtdbatu( 3, BAT_INVALID
);
94 mtdbatl( 3, bat
.lower
.word
);
95 mtdbatu( 3, bat
.upper
.word
);
100 availableBATs
&= ~(1 << batNum
);
101 mappedSegments
|= (1 << (15 & (address
>> 28)));
106 void initialize_bats(boot_args
*args
)
110 /* Give ourselves the virtual map that we would like */
113 /* Make sure that the BATs map what we expect. Note
114 * that we assume BAT0 maps kernel text & data.
116 * Except, oops, none of the BATs have ever been set.
117 * Developer worked only by fluke.
121 bat
.upper
.bits
.bepi
= 0x0; /* start at logical addr 0M */
123 * We should be smarter here about picking an
126 bat
.upper
.bits
.bl
= 0x7ff; /* size = 256M */
127 bat
.upper
.bits
.vs
= 1;
128 bat
.upper
.bits
.vp
= 0;
131 bat
.lower
.bits
.brpn
= 0x0; /* start at physical addr 0 */
132 bat
.lower
.bits
.wimg
= PTE_WIMG_DEFAULT
;
133 bat
.lower
.bits
.pp
= 2; /* read/write access */
135 /* Mustn't cause any data traffic here,
136 * we're modifying our data BAT register!
140 mtdbatu(0, BAT_INVALID
); /* invalidate old mapping */
142 mtdbatl(0, bat
.lower
.word
);
144 mtdbatu(0, bat
.upper
.word
); /* update with new mapping */
146 mtibatl(0, bat
.lower
.word
);
148 mtibatu(0, bat
.upper
.word
); /* update with new mapping */
152 mtdbatu(1,BAT_INVALID
); mtdbatl(1,BAT_INVALID
);
153 mtibatu(1,BAT_INVALID
); mtibatl(1,BAT_INVALID
);
154 mtdbatu(2,BAT_INVALID
); mtdbatl(2,BAT_INVALID
);
155 mtibatu(2,BAT_INVALID
); mtibatl(2,BAT_INVALID
);
156 mtdbatu(3,BAT_INVALID
); mtdbatl(3,BAT_INVALID
);
157 mtibatu(3,BAT_INVALID
); mtibatl(3,BAT_INVALID
);
160 PEMapSegment( 0xf0000000, 0x10000000);
161 if( args
->Video
.v_baseAddr
)
162 PEMapSegment( args
->Video
.v_baseAddr
, 0x10000000);
164 /* Set up segment registers as VM through space 0 */
166 for (i
=0; i
<=15; i
++) {
167 mtsrin(KERNEL_SEG_REG0_VALUE
| i
, i
* 0x10000000);
173 * Adjust the size of the region mapped by a BAT
174 * to to be just large enough to include the specified
175 * offset, and return the offset of the new end of the region.
176 * Note that both 'offsets' are really *lengths*, i.e. the
177 * offset of the end of the mapped region from the beginning.
178 * Either the instruction or data BATs (or both) can be specified.
179 * If the new length is greater than the size mappable by a BAT,
180 * then that value is just returned and no changes are made.
184 vm_offset_t new_minimum
,
190 vm_offset_t new_limit
;
192 if (new_minimum
<= 256*1024*1024) {
195 new_limit
= 128*1024;
196 while (new_limit
< new_minimum
) {
204 if (dbat
) switch (batn
) {
247 if (ibat
) switch (batn
) {
292 new_limit
= new_minimum
;