Home | History | Annotate | Line # | Download | only in libsa
sun3.c revision 1.1
      1 /*	$NetBSD: sun3.c,v 1.1 2001/06/14 12:57:15 fredette 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 #include <sys/param.h>
     52 #include <machine/idprom.h>
     53 #include <machine/mon.h>
     54 
     55 #include <arch/sun3/include/pte3.h>
     56 #include <arch/sun3/sun3/control.h>
     57 #include <arch/sun3/sun3/vme.h>
     58 
     59 #include <stand.h>
     60 
     61 #include "libsa.h"
     62 #include "dvma.h"
     63 #include "saio.h"	/* enum MAPTYPES */
     64 
     65 #define OBIO_MASK 0xFFFFFF
     66 
     67 u_int	get_pte __P((vm_offset_t va));
     68 void	set_pte __P((vm_offset_t va, u_int pte));
     69 char *	dvma3_alloc  __P((int len));
     70 void	dvma3_free  __P((char *dvma, int len));
     71 char *	dvma3_mapin  __P((char *pkt, int len));
     72 void	dvma3_mapout  __P((char *dmabuf, int len));
     73 char *	dev3_mapin  __P((int type, u_long addr, int len));
     74 
     75 struct mapinfo {
     76 	int maptype;
     77 	int pgtype;
     78 	u_int base;
     79 	u_int mask;
     80 };
     81 
     82 struct mapinfo
     83 sun3_mapinfo[MAP__NTYPES] = {
     84 	/* On-board memory, I/O */
     85 	{ MAP_MAINMEM,   PGT_OBMEM,   0,          ~0 },
     86 	{ MAP_OBIO,      PGT_OBIO,    0,          OBIO_MASK },
     87 	/* Multibus adapter (A24,A16) */
     88 	{ MAP_MBMEM,     PGT_VME_D16, VME24_BASE, VME24_MASK },
     89 	{ MAP_MBIO,      PGT_VME_D16, VME16_BASE, VME16_MASK },
     90 	/* VME A16 */
     91 	{ MAP_VME16A16D, PGT_VME_D16, VME16_BASE, VME16_MASK },
     92 	{ MAP_VME16A32D, PGT_VME_D32, VME16_BASE, VME16_MASK },
     93 	/* VME A24 */
     94 	{ MAP_VME24A16D, PGT_VME_D16, VME24_BASE, VME24_MASK },
     95 	{ MAP_VME24A32D, PGT_VME_D32, VME24_BASE, VME24_MASK },
     96 	/* VME A32 */
     97 	{ MAP_VME32A16D, PGT_VME_D16, VME32_BASE, VME32_MASK },
     98 	{ MAP_VME32A32D, PGT_VME_D32, VME32_BASE, VME32_MASK },
     99 };
    100 
    101 /* The virtual address we will use for PROM device mappings. */
    102 int sun3_devmap = SUN3_MONSHORTSEG;
    103 
    104 char *
    105 dev3_mapin(maptype, physaddr, length)
    106 	int maptype;
    107 	u_long physaddr;
    108 	int length;
    109 {
    110 	u_int i, pa, pte, pgva, va;
    111 
    112 	if ((sun3_devmap + length) > SUN3_MONSHORTPAGE)
    113 		panic("dev3_mapin: length=%d\n", length);
    114 
    115 	for (i = 0; i < MAP__NTYPES; i++)
    116 		if (sun3_mapinfo[i].maptype == maptype)
    117 			goto found;
    118 	panic("dev3_mapin: bad maptype");
    119 found:
    120 
    121 	if (physaddr & ~(sun3_mapinfo[i].mask))
    122 		panic("dev3_mapin: bad address");
    123 	pa = sun3_mapinfo[i].base += physaddr;
    124 
    125 	pte = PA_PGNUM(pa) | PG_PERM |
    126 		sun3_mapinfo[i].pgtype;
    127 
    128 	va = pgva = sun3_devmap;
    129 	do {
    130 		set_pte(pgva, pte);
    131 		pgva += NBPG;
    132 		pte += 1;
    133 		length -= NBPG;
    134 	} while (length > 0);
    135 	sun3_devmap = pgva;
    136 	va += (physaddr & PGOFSET);
    137 
    138 #ifdef	DEBUG_PROM
    139 	if (debug)
    140 		printf("dev3_mapin: va=0x%x pte=0x%x\n",
    141 			   va, get_pte(va));
    142 #endif
    143 	return ((char*)va);
    144 }
    145 
    146 /*****************************************************************
    147  * DVMA support
    148  */
    149 
    150 /*
    151  * The easiest way to deal with the need for DVMA mappings is to
    152  * create a DVMA alias mapping of the entire address range used by
    153  * the boot program.  That way, dvma_mapin can just compute the
    154  * DVMA alias address, and dvma_mapout does nothing.
    155  *
    156  * Note that this assumes that standalone programs will do I/O
    157  * operations only within range (SA_MIN_VA .. SA_MAX_VA) checked.
    158  */
    159 
    160 #define	DVMA_BASE 0xFFf00000
    161 #define DVMA_MAPLEN  0xE0000	/* 1 MB - 128K (save MONSHORTSEG) */
    162 
    163 #define SA_MIN_VA	0x200000
    164 #define SA_MAX_VA	(SA_MIN_VA + DVMA_MAPLEN)
    165 
    166 /* This points to the end of the free DVMA space. */
    167 u_int dvma3_end = DVMA_BASE + DVMA_MAPLEN;
    168 
    169 void
    170 dvma3_init()
    171 {
    172 	int segva, dmava, sme;
    173 
    174 	segva = SA_MIN_VA;
    175 	dmava = DVMA_BASE;
    176 
    177 	while (segva < SA_MAX_VA) {
    178 		sme = get_segmap(segva);
    179 		set_segmap(dmava, sme);
    180 		segva += NBSG;
    181 		dmava += NBSG;
    182 	}
    183 }
    184 
    185 /* Convert a local address to a DVMA address. */
    186 char *
    187 dvma3_mapin(char *addr, int len)
    188 {
    189 	int va = (int)addr;
    190 
    191 	/* Make sure the address is in the DVMA map. */
    192 	if ((va < SA_MIN_VA) || (va >= SA_MAX_VA))
    193 		panic("dvma3_mapin");
    194 
    195 	va -= SA_MIN_VA;
    196 	va += DVMA_BASE;
    197 
    198 	return ((char *) va);
    199 }
    200 
    201 /* Destroy a DVMA address alias. */
    202 void
    203 dvma3_mapout(char *addr, int len)
    204 {
    205 	int va = (int)addr;
    206 
    207 	/* Make sure the address is in the DVMA map. */
    208 	if ((va < DVMA_BASE) || (va >= (DVMA_BASE + DVMA_MAPLEN)))
    209 		panic("dvma3_mapout");
    210 }
    211 
    212 char *
    213 dvma3_alloc(int len)
    214 {
    215 	len = m68k_round_page(len);
    216 	dvma3_end -= len;
    217 	return((char*)dvma3_end);
    218 }
    219 
    220 void
    221 dvma3_free(char *dvma, int len)
    222 {
    223 	/* not worth the trouble */
    224 }
    225 
    226 /*****************************************************************
    227  * Control space stuff...
    228  */
    229 
    230 u_int
    231 get_pte(va)
    232 	vm_offset_t va;
    233 {
    234 	va = CONTROL_ADDR_BUILD(PGMAP_BASE, va);
    235 	return (get_control_word(va));
    236 }
    237 
    238 void
    239 set_pte(va, pte)
    240 	vm_offset_t va;
    241 	u_int pte;
    242 {
    243 	va = CONTROL_ADDR_BUILD(PGMAP_BASE, va);
    244 	set_control_word(va, pte);
    245 }
    246 
    247 int
    248 get_segmap(va)
    249 	vm_offset_t va;
    250 {
    251 	va = CONTROL_ADDR_BUILD(SEGMAP_BASE, va);
    252 	return (get_control_byte(va));
    253 }
    254 
    255 void
    256 set_segmap(va, sme)
    257 	vm_offset_t va;
    258 	int sme;
    259 {
    260 	va = CONTROL_ADDR_BUILD(SEGMAP_BASE, va);
    261 	set_control_byte(va, sme);
    262 }
    263 
    264 /*
    265  * Copy the IDPROM contents into the passed buffer.
    266  * The caller (idprom.c) will do the checksum.
    267  */
    268 void
    269 sun3_getidprom(u_char *dst)
    270 {
    271 	vm_offset_t src;	/* control space address */
    272 	int len, x;
    273 
    274 	src = IDPROM_BASE;
    275 	len = sizeof(struct idprom);
    276 	do {
    277 		x = get_control_byte(src++);
    278 		*dst++ = x;
    279 	} while (--len > 0);
    280 }
    281 
    282 /*****************************************************************
    283  * Init our function pointers, etc.
    284  */
    285 
    286 void
    287 sun3_init()
    288 {
    289 
    290 	/* Set the function pointers. */
    291 	dev_mapin_p   = dev3_mapin;
    292 	dvma_alloc_p  = dvma3_alloc;
    293 	dvma_free_p   = dvma3_free;
    294 	dvma_mapin_p  = dvma3_mapin;
    295 	dvma_mapout_p = dvma3_mapout;
    296 
    297 	/* Prepare DVMA segment. */
    298 	dvma3_init();
    299 }
    300