xref: /netbsd-src/sys/arch/evbppc/explora/machdep.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 /*	$NetBSD: machdep.c,v 1.37 2012/07/27 22:13:58 matt Exp $	*/
2 
3 /*-
4  * Copyright (c) 2003 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Juergen Hannken-Illjes.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
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.
18  *
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.
30  */
31 
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.37 2012/07/27 22:13:58 matt Exp $");
34 
35 #include "opt_explora.h"
36 #include "opt_modular.h"
37 #include "ksyms.h"
38 
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/buf.h>
42 #include <sys/msgbuf.h>
43 #include <sys/kernel.h>
44 #include <sys/mount.h>
45 #include <sys/proc.h>
46 #include <sys/reboot.h>
47 #include <sys/ksyms.h>
48 #include <sys/device.h>
49 #include <sys/module.h>
50 #include <sys/bus.h>
51 #include <sys/cpu.h>
52 
53 #include <uvm/uvm_extern.h>
54 
55 #include <prop/proplib.h>
56 
57 #include <machine/explora.h>
58 #include <machine/powerpc.h>
59 #include <machine/tlb.h>
60 #include <machine/pcb.h>
61 #include <machine/trap.h>
62 
63 #include <powerpc/spr.h>
64 #include <powerpc/ibm4xx/spr.h>
65 
66 #include <powerpc/ibm4xx/cpu.h>
67 #include <powerpc/ibm4xx/dcr403cgx.h>
68 
69 #if NKSYMS || defined(DDB) || defined(MODULAR)
70 #include <machine/db_machdep.h>
71 #include <ddb/db_extern.h>
72 #endif
73 
74 #define MEMREGIONS	2
75 #define TLB_PG_SIZE	(16*1024*1024)
76 
77 char machine[] = MACHINE;		/* from <machine/param.h> */
78 char machine_arch[] = MACHINE_ARCH;	/* from <machine/param.h> */
79 
80 static const unsigned int cpuspeed = 66000000;
81 
82 prop_dictionary_t board_properties;
83 struct vm_map *phys_map = NULL;
84 
85 static struct mem_region phys_mem[MEMREGIONS];
86 static struct mem_region avail_mem[MEMREGIONS];
87 
88 void		initppc(vaddr_t, vaddr_t);
89 
90 void
91 initppc(vaddr_t startkernel, vaddr_t endkernel)
92 {
93 	u_int i, j, t, br[4];
94 	u_int maddr, msize, size;
95 
96 	br[0] = mfdcr(DCR_BR4);
97 	br[1] = mfdcr(DCR_BR5);
98 	br[2] = mfdcr(DCR_BR6);
99 	br[3] = mfdcr(DCR_BR7);
100 
101 	for (i = 0; i < 4; i++)
102 		for (j = i+1; j < 4; j++)
103 			if (br[j] < br[i])
104 				t = br[j], br[j] = br[i], br[i] = t;
105 
106 	for (i = 0, size = 0; i < 4; i++) {
107 		if (((br[i] >> 19) & 3) != 3)
108 			continue;
109 		maddr = ((br[i] >> 24) & 0xff) << 20;
110 		msize = 1 << (20 + ((br[i] >> 21) & 7));
111 		if (maddr+msize > size)
112 			size = maddr+msize;
113 	}
114 
115 	phys_mem[0].start = 0;
116 	phys_mem[0].size = size & ~PGOFSET;
117 	avail_mem[0].start = startkernel;
118 	avail_mem[0].size = size-startkernel;
119 
120 	__asm volatile(
121 	    "	mtpid %0	\n"
122 	    "	sync		\n"
123 	    : : "r" (KERNEL_PID) );
124 
125 	/*
126 	 * Setup initial tlbs.
127 	 * Kernel memory and console device are
128 	 * mapped into the first (reserved) tlbs.
129 	 */
130 
131 	for (maddr = 0; maddr < endkernel; maddr += TLB_PG_SIZE)
132 		ppc4xx_tlb_reserve(maddr, maddr, TLB_PG_SIZE, TLB_EX);
133 
134 	/* Map PCKBC, PCKBC2, COM, LPT. This is far beyond physmem. */
135 	ppc4xx_tlb_reserve(BASE_ISA, BASE_ISA, TLB_PG_SIZE, TLB_I | TLB_G);
136 
137 #ifndef COM_IS_CONSOLE
138 	ppc4xx_tlb_reserve(BASE_FB,  BASE_FB,  TLB_PG_SIZE, TLB_I | TLB_G);
139 	ppc4xx_tlb_reserve(BASE_FB2, BASE_FB2, TLB_PG_SIZE, TLB_I | TLB_G);
140 #endif
141 
142 	/* Disable all external interrupts */
143 	mtdcr(DCR_EXIER, 0);
144 
145 	/* Disable all timer interrupts */
146 	mtspr(SPR_TCR, 0);
147 
148 	ibm4xx_init(startkernel, endkernel, pic_ext_intr);
149 }
150 
151 void
152 cpu_startup(void)
153 {
154 	vaddr_t minaddr, maxaddr;
155 	prop_number_t pn;
156 	char pbuf[9];
157 
158 	/*
159 	 * Initialize error message buffer (before start of kernel)
160 	 */
161 	initmsgbuf((void *)msgbuf, round_page(MSGBUFSIZE));
162 
163 	printf("%s%s", copyright, version);
164 	printf("NCD Explora451\n");
165 
166 	format_bytes(pbuf, sizeof(pbuf), ctob(physmem));
167 	printf("total memory = %s\n", pbuf);
168 
169 	minaddr = 0;
170 	/*
171 	 * Allocate a submap for physio
172 	 */
173 	phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
174 				 VM_PHYS_SIZE, 0, false, NULL);
175 
176 	/*
177 	 * No need to allocate an mbuf cluster submap.  Mbuf clusters
178 	 * are allocated via the pool allocator, and we use direct-mapped
179 	 * pool pages.
180 	 */
181 
182 	format_bytes(pbuf, sizeof(pbuf), ptoa(uvmexp.free));
183 	printf("avail memory = %s\n", pbuf);
184 
185 	/*
186 	 * Set up the board properties database.
187 	 */
188 	board_properties = prop_dictionary_create();
189 	KASSERT(board_properties != NULL);
190 
191 	pn = prop_number_create_integer(ctob(physmem));
192 	KASSERT(pn != NULL);
193 	if (prop_dictionary_set(board_properties, "mem-size", pn) == false)
194 		panic("setting mem-size");
195 	prop_object_release(pn);
196 
197 	pn = prop_number_create_integer(cpuspeed);
198 	KASSERT(pn != NULL);
199 	if (prop_dictionary_set(board_properties, "processor-frequency",
200 				pn) == false)
201 		panic("setting processor-frequency");
202 	prop_object_release(pn);
203 
204 	intr_init();
205 
206 	/*
207 	 * Look for the ibm4xx modules in the right place.
208 	 */
209 	module_machine = module_machine_ibm4xx;
210 	fake_mapiodev = 0;
211 }
212 
213 void
214 cpu_reboot(int howto, char *what)
215 {
216 	static int syncing = 0;
217 
218 	boothowto = howto;
219 	if (!cold && !(howto & RB_NOSYNC) && !syncing) {
220 		syncing = 1;
221 		vfs_shutdown();
222 		resettodr();
223 	}
224 
225 	splhigh();
226 
227 	if (!cold && (howto & RB_DUMP))
228 		/*XXX dumpsys()*/;
229 
230 	doshutdownhooks();
231 
232 	pmf_system_shutdown(boothowto);
233 
234 	if (howto & RB_HALT) {
235 		printf("halted\n\n");
236 
237 		while (1)
238 			;
239 	}
240 
241 	printf("rebooting\n\n");
242 
243 	/* flush cache for msgbuf */
244 	__syncicache((void *)msgbuf_paddr, round_page(MSGBUFSIZE));
245 
246 	ppc4xx_reset();
247 
248 #ifdef DDB
249 	while (1)
250 		Debugger();
251 #else
252 	while (1)
253 		;
254 #endif
255 }
256 
257 void
258 mem_regions(struct mem_region **mem, struct mem_region **avail)
259 {
260 	*mem = phys_mem;
261 	*avail = avail_mem;
262 }
263