1 /*
2 * Mach Operating System
3 * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University
4 * Copyright (c) 1991 IBM Corporation
5 * All Rights Reserved.
6 *
7 * Permission to use, copy, modify and distribute this software and its
8 * documentation is hereby granted, provided that both the copyright
9 * notice and this permission notice appear in all copies of the
10 * software, derivative works or modified versions, and any portions
11 * thereof, and that both notices appear in supporting documentation,
12 * and that the name IBM not be used in advertising or publicity
13 * pertaining to distribution of the software without specific, written
14 * prior permission.
15 *
16 * CARNEGIE MELLON AND IBM ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
17 * CONDITION. CARNEGIE MELLON AND IBM DISCLAIM ANY LIABILITY OF ANY KIND FOR
18 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
19 *
20 * Carnegie Mellon requests users of this software to return to
21 *
22 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
23 * School of Computer Science
24 * Carnegie Mellon University
25 * Pittsburgh PA 15213-3890
26 *
27 * any improvements or extensions that they make and grant Carnegie Mellon
28 * the rights to redistribute these changes.
29 */
30
31 /*
32 * COMPONENT_NAME: (I386) Mach port to i386 platform
33 *
34 * FUNCTIONS:
35 *
36 * ORIGINS: 6, 27
37 */
38 /*
39 * HISTORY
40 * $Log: model_dep.c,v $
41 * Revision 2.2 93/02/04 08:01:21 danner
42 * Initialize NMI here.
43 * [92/03/30 dbg@ibm]
44 *
45 * Add io_space_offset_to_addr - first step in IO space object
46 * [92/03/22 dbg@ibm]
47 *
48 * PS2 version
49 * [92/02/24 dbg@ibm]
50 *
51 * Revision 2.7 92/01/03 20:11:49 dbg
52 * Fixed so that mem_size can be patched to limit physical memory
53 * use.
54 * [91/09/29 dbg]
55 *
56 * Rename kdb_init to ddb_init. Remove esym.
57 * [91/09/11 dbg]
58 *
59 * Revision 2.6 91/07/31 17:42:41 dbg
60 * Remove call to pcb_module_init (in machine-independent code).
61 * [91/07/26 dbg]
62 *
63 * Revision 2.5 91/06/19 11:55:48 rvb
64 * cputypes.h->platforms.h
65 * [91/06/12 13:45:37 rvb]
66 *
67 * Revision 2.4 91/05/18 14:30:38 rpd
68 * Changed pmap_bootstrap arguments.
69 * Moved pmap_free_pages and pmap_next_page here.
70 * [91/05/15 rpd]
71 *
72 * Revision 2.3 91/05/14 16:29:13 mrt
73 * Correcting copyright
74 *
75 * Revision 2.2 91/05/08 12:44:52 dbg
76 * Initialization for i386 AT bus machines only.
77 * Combine code that was in i386/init.c and i386/i386_init.c.
78 * [91/04/26 14:40:43 dbg]
79 *
80 * Revision 2.3 90/09/23 17:45:10 jsb
81 * Added support for iPSC2.
82 * [90/09/21 16:39:41 jsb]
83 *
84 * Revision 2.2 90/05/03 15:27:39 dbg
85 * Alter for pure kernel.
86 * [90/02/15 dbg]
87 *
88 * Revision 1.5.1.4 90/02/01 13:36:37 rvb
89 * esym must always be defined. This is as good a place as any.
90 * [90/01/31 rvb]
91 *
92 * Revision 1.5.1.3 89/12/28 12:43:10 rvb
93 * Fix av_start & esym initialization, esp for MACH_KDB.
94 * [89/12/26 rvb]
95 *
96 * Revision 1.5.1.2 89/12/21 17:59:49 rvb
97 * enable esym processing.
98 *
99 *
100 * Revision 1.5.1.1 89/10/22 11:30:41 rvb
101 * Setup of rootdevice should not be here. And it was wrong.
102 * [89/10/17 rvb]
103 *
104 * Scary! We've changed sbss to edata. AND the coff loader
105 * following the vuifile spec was actually aligning the bss
106 * on 4k boundaries.
107 * [89/10/16 rvb]
108 *
109 * Revision 1.5 89/04/05 12:57:39 rvb
110 * Move extern out of function scope for gcc.
111 * [89/03/04 rvb]
112 *
113 * Revision 1.4 89/02/26 12:31:25 gm0w
114 * Changes for cleanup.
115 *
116 * 31-Dec-88 Robert Baron (rvb) at Carnegie-Mellon University
117 * Derived from MACH2.0 vax release.
118 *
119 */
120
121 /*
122 * File: model_dep.c
123 * Author: Avadis Tevanian, Jr., Michael Wayne Young
124 *
125 * Copyright (C) 1986, Avadis Tevanian, Jr., Michael Wayne Young
126 *
127 * Basic initialization for I386 - PS2 (MCA bus) machines.
128 */
129
130 #include <platforms.h>
131 #include <mach_kdb.h>
132
133 #include <mach/i386/vm_param.h>
134
135 #include <mach/vm_param.h>
136 #include <mach/vm_prot.h>
137 #include <mach/machine.h>
138 #include <kern/time_out.h>
139 #include <sys/time.h>
140 #include <vm/vm_page.h>
141
142 #if MACH_KDB
143 #include <sys/reboot.h>
144 #endif MACH_KDB
145
146 int loadpt;
147
148 vm_size_t mem_size = 0;
149 vm_size_t rawmem_size;
150 vm_offset_t first_addr = 0; /* set by start.s - keep out of bss */
151 vm_offset_t first_avail = 0;/* first after page tables */
152 vm_offset_t last_addr;
153
154 vm_offset_t avail_start, avail_end;
155 vm_offset_t virtual_avail, virtual_end;
156 vm_offset_t hole_start, hole_end;
157 vm_offset_t avail_next;
158 unsigned int avail_remaining;
159
160 /* parameters passed from bootstrap loader */
161 int cnvmem = 0; /* must be in .data section */
162 int extmem = 0;
163 int boottype = 0;
164
165 extern char edata, end;
166
167 extern char version[];
168
169 extern void setup_main();
170
171 void inittodr(); /* forward */
172
173 int rebootflag = 0; /* exported to kdintr */
174
175 /*
176 * Cpu initialization. Running virtual, but without MACH VM
177 * set up. First C routine called.
178 */
179 void machine_startup()
180 {
181 /*
182 * Do basic VM initialization
183 */
184 i386_init();
185
186 /*
187 * Initialize the console so we can print.
188 */
189 cninit();
190 #if MACH_KDB
191
192 /*
193 * Initialize the kernel debugger.
194 */
195 ddb_init();
196
197 /*
198 * Cause a breakpoint trap to the debugger before proceeding
199 * any further if the proper option bit was specified in
200 * the boot flags.
201 *
202 * XXX use -a switch to invoke kdb, since there's no
203 * boot-program switch to turn on RB_HALT!
204 */
205 if (boothowto & RB_ASKNAME)
206 Debugger();
207 #endif MACH_KDB
208
209 pos_init(); /* get POS registers */
210 abios_init(); /* set up ABIOS */
211
212 #if MACH_RDB
213 printf("entering db_kdb\n");
214 db_kdb(-1,0,0);
215 #endif /* MACH_RDB */
216
217 printf(version);
218
219 machine_slot[0].is_cpu = TRUE;
220 machine_slot[0].running = TRUE;
221 machine_slot[0].cpu_type = CPU_TYPE_I386;
222 machine_slot[0].cpu_subtype = CPU_SUBTYPE_PS2;
223
224 /*
225 * Start the system.
226 */
227 setup_main();
228 }
229
230 /*
231 * Find devices. The system is alive.
232 */
233 void machine_init()
234 {
235 /*
236 * Set up to use floating point.
237 */
238 init_fpu();
239
240 /*
241 * Find the devices
242 */
243 probeio();
244
245 /*
246 * Find the root device
247 */
248 get_root_device();
249
250 /*
251 * Get the time
252 */
253 inittodr();
254
255 /*
256 * Enable NMI interrupts.
257 */
258 nmi_enable();
259 }
260
261 /*
262 * Halt a cpu.
263 */
264 void
265 halt_cpu()
266 {
267 printf("\n*** HALTED ***\n");
268 (void) spl0();
269 for (;;)
270 continue;
271 }
272
273 /*
274 * Halt the system or reboot.
275 */
276 halt_all_cpus(reboot)
277 boolean_t reboot;
278 {
279 if (reboot) {
280 /*
281 * Tell the BIOS not to clear and test memory.
282 */
283 *(unsigned short *)phystokv(0x472) = 0x1234;
284
285 kdreboot();
286 }
287 else {
288 rebootflag = 1;
289 printf("In tight loop: hit ctl-alt-del to reboot\n");
290 (void) spl0();
291 }
292 for (;;)
293 continue;
294 }
295
296 /*
297 * Basic VM initialization.
298 */
299 i386_init()
300 {
301 /*
302 * Zero the BSS.
303 */
304 bzero((char *)&edata,(unsigned)(&end - &edata));
305
306 /*
307 * Initialize the pic prior to any possible call to an spl.
308 */
309 picinit();
310
311 vm_set_page_size();
312
313 /*
314 * Compute the memory size.
315 */
316 first_addr = 0x1000;
317 /* BIOS leaves data in low memory */
318 last_addr = 1024*1024 + extmem*1024;
319 /* extended memory starts at 1MB */
320 if (mem_size != 0) {
321 if (mem_size < last_addr - loadpt)
322 last_addr = loadpt + mem_size;
323 }
324 mem_size = last_addr - loadpt;
325
326 first_addr = round_page(first_addr);
327 last_addr = trunc_page(last_addr);
328
329 /*
330 * Initialize kernel physical map, mapping the
331 * region from loadpt to avail_start.
332 * Kernel virtual address starts at VM_KERNEL_MIN_ADDRESS.
333 */
334
335 avail_start = first_addr;
336 avail_end = last_addr;
337 printf("PS2 boot: memory from 0x%x to 0x%x\n", avail_start,
338 avail_end);
339
340 pmap_bootstrap(loadpt);
341
342 /*
343 * Initialize for pmap_free_pages and pmap_next_page.
344 * These guys should be page-aligned.
345 */
346
347 hole_start = trunc_page((vm_offset_t)(1024 * cnvmem));
348 hole_end = round_page((vm_offset_t)first_avail);
349
350 avail_remaining = atop((avail_end - avail_start) -
351 (hole_end - hole_start));
352 avail_next = avail_start;
353
354 printf("PS2_init: virtual_avail = %x, virtual_end = %x\n",
355 virtual_avail, virtual_end);
356
357 }
358
359 #include <mach/vm_prot.h>
360 #include <vm/pmap.h>
361 #include <mach/time_value.h>
362
363 timemmap(dev,off,prot)
364 vm_prot_t prot;
365 {
366 extern time_value_t *mtime;
367
368 #ifdef lint
369 dev++; off++;
370 #endif lint
371
372 if (prot & VM_PROT_WRITE) return (-1);
373
374 return (i386_btop(pmap_extract(pmap_kernel(), (vm_offset_t) mtime)));
375 }
376
377 startrtclock()
378 {
379 clkstart();
380 }
381
382 void
383 inittodr()
384 {
385 time_value_t new_time;
386
387 new_time.seconds = 0;
388 new_time.microseconds = 0;
389
390 (void) readtodc(&new_time.seconds);
391
392 {
393 int s = splhigh();
394 time = new_time;
395 splx(s);
396 }
397 }
398
399 void
400 resettodr()
401 {
402 writetodc();
403 }
404
405 unsigned int pmap_free_pages()
406 {
407 return avail_remaining;
408 }
409
410 boolean_t pmap_next_page(addrp)
411 vm_offset_t *addrp;
412 {
413 if (avail_next == avail_end)
414 return FALSE;
415
416 /* skip the hole */
417
418 if (avail_next == hole_start)
419 avail_next = hole_end;
420
421 *addrp = avail_next;
422 avail_next += PAGE_SIZE;
423 avail_remaining--;
424 return TRUE;
425 }
426
427 boolean_t pmap_valid_page(x)
428 vm_offset_t x;
429 {
430 return (((avail_start <= x) && (x < avail_end)) &&
431 !((hole_start <= x) && (x < hole_end)));
432 }
433
434 /*
435 * Given an offset into the IO space object:
436 * return (TRUE, phys_addr) if the offset is valid,
437 * return (FALSE, *) if the offset is invalid.
438 */
439 boolean_t
440 io_space_offset_to_addr(offset, phys_addr)
441 vm_offset_t offset;
442 vm_offset_t *phys_addr; /* OUT */
443 {
444 /*
445 * Include:
446 * BIOS vectors: 0..3ff
447 * BIOS data: 400..5ff
448 * ABIOS data: hole_start..9ffff
449 * IO space: a0000..fffff
450 *
451 * and eventually the rest of the 24-bit and
452 * 32-bit IO spaces...
453 */
454 if (offset <= 0x1000 ||
455 (offset >= hole_start && offset < 0x100000))
456 {
457 *phys_addr = offset;
458 return TRUE;
459 }
460 return FALSE;
461 }
462
Cache object: e6cd9440c64f4bc67dedff5980f946e8
|