1 /* $NetBSD: machdep.c,v 1.28 2009/11/26 00:19:16 matt Exp $ */
4 * Copyright (c) 2003 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Juergen Hannken-Illjes.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.28 2009/11/26 00:19:16 matt Exp $");
35 #include "opt_explora.h"
36 #include "opt_modular.h"
39 #include <sys/param.h>
40 #include <sys/systm.h>
42 #include <sys/msgbuf.h>
43 #include <sys/kernel.h>
44 #include <sys/mount.h>
46 #include <sys/reboot.h>
47 #include <sys/ksyms.h>
48 #include <sys/device.h>
50 #include <uvm/uvm_extern.h>
52 #include <prop/proplib.h>
54 #include <machine/explora.h>
55 #include <machine/bus.h>
56 #include <machine/powerpc.h>
57 #include <machine/tlb.h>
58 #include <machine/trap.h>
60 #include <powerpc/spr.h>
61 #include <powerpc/ibm4xx/dcr403cgx.h>
63 #if NKSYMS || defined(DDB) || defined(MODULAR)
64 #include <machine/db_machdep.h>
65 #include <ddb/db_extern.h>
69 #define TLB_PG_SIZE (16*1024*1024)
72 char machine
[] = MACHINE
; /* from <machine/param.h> */
73 char machine_arch
[] = MACHINE_ARCH
; /* from <machine/param.h> */
75 static const unsigned int cpuspeed
= 66000000;
77 prop_dictionary_t board_properties
;
78 struct vm_map
*phys_map
= NULL
;
79 struct vm_map
*mb_map
= NULL
;
80 char msgbuf
[MSGBUFSIZE
];
83 static struct mem_region phys_mem
[MEMREGIONS
];
84 static struct mem_region avail_mem
[MEMREGIONS
];
86 void bootstrap(u_int
, u_int
);
87 static void install_extint(void (*)(void));
93 extern int defaulttrap
, defaultsize
;
94 extern int sctrap
, scsize
;
95 extern int alitrap
, alisize
;
96 extern int dsitrap
, dsisize
;
97 extern int isitrap
, isisize
;
98 extern int mchktrap
, mchksize
;
99 extern int tlbimiss4xx
, tlbim4size
;
100 extern int tlbdmiss4xx
, tlbdm4size
;
101 extern int pitfitwdog
, pitfitwdogsize
;
102 extern int debugtrap
, debugsize
;
103 extern int errata51handler
, errata51size
;
105 extern int ddblow
, ddbsize
;
112 { EXC_SC
, &sctrap
, &scsize
},
113 { EXC_ALI
, &alitrap
, &alisize
},
114 { EXC_DSI
, &dsitrap
, &dsisize
},
115 { EXC_ISI
, &isitrap
, &isisize
},
116 { EXC_MCHK
, &mchktrap
, &mchksize
},
117 { EXC_ITMISS
, &tlbimiss4xx
, &tlbim4size
},
118 { EXC_DTMISS
, &tlbdmiss4xx
, &tlbdm4size
},
119 { EXC_PIT
, &pitfitwdog
, &pitfitwdogsize
},
120 { EXC_DEBUG
, &debugtrap
, &debugsize
},
121 { (EXC_DTMISS
|EXC_ALI
), &errata51handler
, &errata51size
},
123 { EXC_PGM
, &ddblow
, &ddbsize
},
128 * Install a trap vector. We cannot use memcpy because the
129 * destination may be zero.
132 trap_copy(void *src
, int dest
, size_t len
)
134 uint32_t *src_p
= src
;
135 uint32_t *dest_p
= (void *)dest
;
138 *dest_p
++ = *src_p
++;
139 len
-= sizeof(uint32_t);
144 bootstrap(u_int startkernel
, u_int endkernel
)
146 u_int i
, j
, t
, br
[4];
147 u_int maddr
, msize
, size
;
148 struct cpu_info
* const ci
= &cpu_info
[0];
150 br
[0] = mfdcr(DCR_BR4
);
151 br
[1] = mfdcr(DCR_BR5
);
152 br
[2] = mfdcr(DCR_BR6
);
153 br
[3] = mfdcr(DCR_BR7
);
155 for (i
= 0; i
< 4; i
++)
156 for (j
= i
+1; j
< 4; j
++)
158 t
= br
[j
], br
[j
] = br
[i
], br
[i
] = t
;
160 for (i
= 0, size
= 0; i
< 4; i
++) {
161 if (((br
[i
] >> 19) & 3) != 3)
163 maddr
= ((br
[i
] >> 24) & 0xff) << 20;
164 msize
= 1 << (20 + ((br
[i
] >> 21) & 7));
165 if (maddr
+msize
> size
)
169 phys_mem
[0].start
= 0;
170 phys_mem
[0].size
= size
& ~PGOFSET
;
171 avail_mem
[0].start
= startkernel
;
172 avail_mem
[0].size
= size
-startkernel
;
177 : : "r" (KERNEL_PID
) );
180 * Setup initial tlbs.
181 * Kernel memory and console device are
182 * mapped into the first (reserved) tlbs.
185 for (maddr
= 0; maddr
< endkernel
; maddr
+= TLB_PG_SIZE
)
186 ppc4xx_tlb_reserve(maddr
, maddr
, TLB_PG_SIZE
, TLB_EX
);
188 /* Map PCKBC, PCKBC2, COM, LPT. This is far beyond physmem. */
189 ppc4xx_tlb_reserve(BASE_ISA
, BASE_ISA
, TLB_PG_SIZE
, TLB_I
| TLB_G
);
191 #ifndef COM_IS_CONSOLE
192 ppc4xx_tlb_reserve(BASE_FB
, BASE_FB
, TLB_PG_SIZE
, TLB_I
| TLB_G
);
193 ppc4xx_tlb_reserve(BASE_FB2
, BASE_FB2
, TLB_PG_SIZE
, TLB_I
| TLB_G
);
198 /* Disable all external interrupts */
201 /* Disable all timer interrupts */
204 /* Initialize cache info for memcpy, etc. */
208 * Initialize lwp0 and current pcb and pmap pointers.
212 curpcb
= lwp_getpcb(&lwp0
);
213 memset(curpcb
, 0, sizeof(struct pcb
)); /* XXX why? */
214 curpcb
->pcb_pm
= pmap_kernel();
217 * Install trap vectors.
220 for (i
= EXC_RSVD
; i
<= EXC_LAST
; i
+= 0x100)
221 trap_copy(&defaulttrap
, i
, (size_t)&defaultsize
);
223 for (i
= 0; i
< sizeof(trap_table
)/sizeof(trap_table
[0]); i
++) {
224 trap_copy(trap_table
[i
].addr
, trap_table
[i
].vector
,
225 (size_t)trap_table
[i
].size
);
228 __syncicache((void *)EXC_RST
, EXC_LAST
- EXC_RST
+ 0x100);
231 * Set Exception vector base.
232 * Handle trap instruction as PGM exception.
237 t
= mfspr(SPR_DBCR0
);
242 * External interrupt handler install.
245 install_extint(ext_intr
);
248 * Now enable translation (and machine checks/recoverable interrupts).
255 : : "r" (0), "K" (PSL_IR
|PSL_DR
|PSL_ME
) );
260 * Initialize pmap module.
262 pmap_bootstrap(startkernel
, endkernel
);
267 install_extint(void (*handler
)(void))
269 extern int extint
, extsize
;
270 extern u_long extint_call
;
271 u_long offset
= (u_long
)handler
- (u_long
)&extint_call
;
275 if (offset
> 0x1ffffff)
276 panic("install_extint: too far away");
282 : "=r" (omsr
), "=r" (msr
) : "K" ((u_short
)~PSL_EE
) );
283 extint_call
= (extint_call
& 0xfc000003) | offset
;
284 memcpy((void *)EXC_EXI
, &extint
, (size_t)&extsize
);
285 __syncicache((void *)&extint_call
, sizeof extint_call
);
286 __syncicache((void *)EXC_EXI
, (int)&extsize
);
295 vaddr_t minaddr
, maxaddr
;
300 * Initialize error message buffer (before start of kernel)
302 initmsgbuf((void *)msgbuf
, round_page(MSGBUFSIZE
));
304 printf("%s%s", copyright
, version
);
305 printf("NCD Explora451\n");
307 format_bytes(pbuf
, sizeof(pbuf
), ctob(physmem
));
308 printf("total memory = %s\n", pbuf
);
312 * Allocate a submap for physio
314 phys_map
= uvm_km_suballoc(kernel_map
, &minaddr
, &maxaddr
,
315 VM_PHYS_SIZE
, 0, false, NULL
);
318 * No need to allocate an mbuf cluster submap. Mbuf clusters
319 * are allocated via the pool allocator, and we use direct-mapped
323 format_bytes(pbuf
, sizeof(pbuf
), ptoa(uvmexp
.free
));
324 printf("avail memory = %s\n", pbuf
);
327 * Set up the board properties database.
329 board_properties
= prop_dictionary_create();
330 KASSERT(board_properties
!= NULL
);
332 pn
= prop_number_create_integer(ctob(physmem
));
334 if (prop_dictionary_set(board_properties
, "mem-size", pn
) == false)
335 panic("setting mem-size");
336 prop_object_release(pn
);
338 pn
= prop_number_create_integer(cpuspeed
);
340 if (prop_dictionary_set(board_properties
, "processor-frequency",
342 panic("setting processor-frequency");
343 prop_object_release(pn
);
351 return spllower(ipl
); /*XXX*/
355 cpu_reboot(int howto
, char *what
)
357 static int syncing
= 0;
360 if (!cold
&& !(howto
& RB_NOSYNC
) && !syncing
) {
368 if (!cold
&& (howto
& RB_DUMP
))
373 pmf_system_shutdown(boothowto
);
375 if (howto
& RB_HALT
) {
376 printf("halted\n\n");
382 printf("rebooting\n\n");
384 /* flush cache for msgbuf */
385 __syncicache((void *)msgbuf_paddr
, round_page(MSGBUFSIZE
));
399 mem_regions(struct mem_region
**mem
, struct mem_region
**avail
)