xref: /netbsd-src/sys/arch/sun68k/stand/libsa/sun3.c (revision 8b0f9554ff8762542c4defc4f70e1eb76fb508fa)
1 /*	$NetBSD: sun3.c,v 1.6 2005/12/11 12:19:29 christos Exp $	*/
2 
3 /*-
4  * Copyright (c) 1998 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Gordon W. Ross.
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  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *        This product includes software developed by the NetBSD
21  *        Foundation, Inc. and its contributors.
22  * 4. Neither the name of The NetBSD Foundation nor the names of its
23  *    contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  */
38 
39 /*
40  * Standalone functions specific to the Sun3.
41  */
42 
43 #define _SUN3_ XXX
44 
45 /* Need to avoid conflicts on these: */
46 #define get_pte sun3_get_pte
47 #define set_pte sun3_set_pte
48 #define get_segmap sun3_get_segmap
49 #define set_segmap sun3_set_segmap
50 
51 /*
52  * We need to get the sun3 NBSG definition, even if we're
53  * building this with a different sun68k target.
54  */
55 #include <arch/sun3/include/param.h>
56 
57 #include <sys/param.h>
58 #include <machine/idprom.h>
59 #include <machine/mon.h>
60 
61 #include <arch/sun3/include/pte3.h>
62 #include <arch/sun3/sun3/control.h>
63 #include <arch/sun3/sun3/vme.h>
64 
65 #include <stand.h>
66 
67 #include "libsa.h"
68 #include "dvma.h"
69 #include "saio.h"	/* enum MAPTYPES */
70 
71 #define OBIO_MASK 0xFFFFFF
72 
73 u_int	get_pte(vaddr_t);
74 void	set_pte(vaddr_t, u_int);
75 char *	dvma3_alloc(int);
76 void	dvma3_free(char *, int);
77 char *	dvma3_mapin(char *, int);
78 void	dvma3_mapout(char *, int);
79 char *	dev3_mapin(int, u_long, int);
80 
81 struct mapinfo {
82 	int maptype;
83 	int pgtype;
84 	u_int base;
85 	u_int mask;
86 };
87 
88 struct mapinfo
89 sun3_mapinfo[MAP__NTYPES] = {
90 	/* On-board memory, I/O */
91 	{ MAP_MAINMEM,   PGT_OBMEM,   0,          ~0 },
92 	{ MAP_OBIO,      PGT_OBIO,    0,          OBIO_MASK },
93 	/* Multibus adapter (A24,A16) */
94 	{ MAP_MBMEM,     PGT_VME_D16, VME24_BASE, VME24_MASK },
95 	{ MAP_MBIO,      PGT_VME_D16, VME16_BASE, VME16_MASK },
96 	/* VME A16 */
97 	{ MAP_VME16A16D, PGT_VME_D16, VME16_BASE, VME16_MASK },
98 	{ MAP_VME16A32D, PGT_VME_D32, VME16_BASE, VME16_MASK },
99 	/* VME A24 */
100 	{ MAP_VME24A16D, PGT_VME_D16, VME24_BASE, VME24_MASK },
101 	{ MAP_VME24A32D, PGT_VME_D32, VME24_BASE, VME24_MASK },
102 	/* VME A32 */
103 	{ MAP_VME32A16D, PGT_VME_D16, VME32_BASE, VME32_MASK },
104 	{ MAP_VME32A32D, PGT_VME_D32, VME32_BASE, VME32_MASK },
105 };
106 
107 /* The virtual address we will use for PROM device mappings. */
108 int sun3_devmap = SUN3_MONSHORTSEG;
109 
110 char *
111 dev3_mapin(int maptype, u_long physaddr, int length)
112 {
113 	u_int i, pa, pte, pgva, va;
114 
115 	if ((sun3_devmap + length) > SUN3_MONSHORTPAGE)
116 		panic("dev3_mapin: length=%d", length);
117 
118 	for (i = 0; i < MAP__NTYPES; i++)
119 		if (sun3_mapinfo[i].maptype == maptype)
120 			goto found;
121 	panic("dev3_mapin: bad maptype");
122 found:
123 
124 	if (physaddr & ~(sun3_mapinfo[i].mask))
125 		panic("dev3_mapin: bad address");
126 	pa = sun3_mapinfo[i].base += physaddr;
127 
128 	pte = PA_PGNUM(pa) | PG_PERM | sun3_mapinfo[i].pgtype;
129 
130 	va = pgva = sun3_devmap;
131 	do {
132 		set_pte(pgva, pte);
133 		pgva += NBPG;
134 		pte += 1;
135 		length -= NBPG;
136 	} while (length > 0);
137 	sun3_devmap = pgva;
138 	va += (physaddr & PGOFSET);
139 
140 #ifdef	DEBUG_PROM
141 	if (debug)
142 		printf("dev3_mapin: va=0x%x pte=0x%x\n",
143 			   va, get_pte(va));
144 #endif
145 	return ((char*)va);
146 }
147 
148 /*****************************************************************
149  * DVMA support
150  */
151 
152 /*
153  * The easiest way to deal with the need for DVMA mappings is to
154  * create a DVMA alias mapping of the entire address range used by
155  * the boot program.  That way, dvma_mapin can just compute the
156  * DVMA alias address, and dvma_mapout does nothing.
157  *
158  * Note that this assumes that standalone programs will do I/O
159  * operations only within range (SA_MIN_VA .. SA_MAX_VA) checked.
160  */
161 
162 #define	DVMA_BASE 0xFFf00000
163 #define DVMA_MAPLEN  0xE0000	/* 1 MB - 128K (save MONSHORTSEG) */
164 
165 #define SA_MIN_VA	0x200000
166 #define SA_MAX_VA	(SA_MIN_VA + DVMA_MAPLEN)
167 
168 /* This points to the end of the free DVMA space. */
169 u_int dvma3_end = DVMA_BASE + DVMA_MAPLEN;
170 
171 void
172 dvma3_init(void)
173 {
174 	int segva, dmava, sme;
175 
176 	segva = SA_MIN_VA;
177 	dmava = DVMA_BASE;
178 
179 	while (segva < SA_MAX_VA) {
180 		sme = get_segmap(segva);
181 		set_segmap(dmava, sme);
182 		segva += NBSG;
183 		dmava += NBSG;
184 	}
185 }
186 
187 /* Convert a local address to a DVMA address. */
188 char *
189 dvma3_mapin(char *addr, int len)
190 {
191 	int va = (int)addr;
192 
193 	/* Make sure the address is in the DVMA map. */
194 	if ((va < SA_MIN_VA) || (va >= SA_MAX_VA))
195 		panic("dvma3_mapin");
196 
197 	va -= SA_MIN_VA;
198 	va += DVMA_BASE;
199 
200 	return ((char *) va);
201 }
202 
203 /* Destroy a DVMA address alias. */
204 void
205 dvma3_mapout(char *addr, int len)
206 {
207 	int va = (int)addr;
208 
209 	/* Make sure the address is in the DVMA map. */
210 	if ((va < DVMA_BASE) || (va >= (DVMA_BASE + DVMA_MAPLEN)))
211 		panic("dvma3_mapout");
212 }
213 
214 char *
215 dvma3_alloc(int len)
216 {
217 	len = m68k_round_page(len);
218 	dvma3_end -= len;
219 	return((char*)dvma3_end);
220 }
221 
222 void
223 dvma3_free(char *dvma, int len)
224 {
225 	/* not worth the trouble */
226 }
227 
228 /*****************************************************************
229  * Control space stuff...
230  */
231 
232 u_int
233 get_pte(vaddr_t va)
234 {
235 	va = CONTROL_ADDR_BUILD(PGMAP_BASE, va);
236 	return (get_control_word(va));
237 }
238 
239 void
240 set_pte(vaddr_t va, u_int pte)
241 {
242 	va = CONTROL_ADDR_BUILD(PGMAP_BASE, va);
243 	set_control_word(va, pte);
244 }
245 
246 int
247 get_segmap(vaddr_t va)
248 {
249 	va = CONTROL_ADDR_BUILD(SEGMAP_BASE, va);
250 	return (get_control_byte(va));
251 }
252 
253 void
254 set_segmap(vaddr_t va, int sme)
255 {
256 	va = CONTROL_ADDR_BUILD(SEGMAP_BASE, va);
257 	set_control_byte(va, sme);
258 }
259 
260 /*
261  * Copy the IDPROM contents into the passed buffer.
262  * The caller (idprom.c) will do the checksum.
263  */
264 void
265 sun3_getidprom(u_char *dst)
266 {
267 	vaddr_t src;	/* control space address */
268 	int len, x;
269 
270 	src = IDPROM_BASE;
271 	len = sizeof(struct idprom);
272 	do {
273 		x = get_control_byte(src++);
274 		*dst++ = x;
275 	} while (--len > 0);
276 }
277 
278 /*****************************************************************
279  * Init our function pointers, etc.
280  */
281 
282 void
283 sun3_init(void)
284 {
285 
286 	/* Set the function pointers. */
287 	dev_mapin_p   = dev3_mapin;
288 	dvma_alloc_p  = dvma3_alloc;
289 	dvma_free_p   = dvma3_free;
290 	dvma_mapin_p  = dvma3_mapin;
291 	dvma_mapout_p = dvma3_mapout;
292 
293 	/* Prepare DVMA segment. */
294 	dvma3_init();
295 }
296