Expand PMF_FN_* macros.
[netbsd-mini2440.git] / sys / arch / sun68k / stand / libsa / sun3x.c
blob0005deec8f426d03230fcb143385d3912d1f5dac
1 /* $NetBSD: sun3x.c,v 1.11 2009/01/12 07:00:59 tsutsui Exp $ */
3 /*-
4 * Copyright (c) 1998 The NetBSD Foundation, Inc.
5 * All rights reserved.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jeremy Cooper and Gordon Ross
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.
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.
33 * Standalone functions specific to the Sun3X.
36 #define _SUN3X_ XXX
38 /* Avoid conflicts on these: */
39 #define get_pte sun3x_get_pte
40 #define set_pte sun3x_set_pte
42 #include <sys/param.h>
43 #include <machine/mon.h>
45 #include <stand.h>
47 #include "libsa.h"
48 #include "dvma.h"
49 #include "saio.h" /* enum MAPTYPES */
51 #include <arch/sun3/include/pte3x.h>
52 #include <arch/sun3/sun3x/iommu.h>
53 #include <arch/sun3/sun3x/vme.h>
55 /* Names, names... */
56 #define MON_LOMEM_BASE 0
57 #define MON_LOMEM_SIZE 0x400000
58 #define MON_LOMEM_END (MON_LOMEM_BASE+MON_LOMEM_SIZE)
59 #define MON_KDB_BASE SUN3X_MON_KDB_BASE
60 #define MON_KDB_SIZE SUN3X_MON_KDB_SIZE
61 #define MON_KDB_END (MON_KDB_BASE+MON_KDB_SIZE)
62 #define MON_DVMA_BASE SUN3X_MON_DVMA_BASE
63 #define MON_DVMA_SIZE SUN3X_MON_DVMA_SIZE
65 void mmu_atc_flush(vaddr_t);
66 void set_iommupte(vaddr_t, paddr_t);
68 u_int get_pte(vaddr_t);
69 void set_pte(vaddr_t, paddr_t);
70 void dvma3x_init(void);
71 char * dvma3x_alloc(int);
72 void dvma3x_free(char *, int);
73 char * dvma3x_mapin(char *, int);
74 void dvma3x_mapout(char *, int);
75 char * dev3x_mapin(int, u_long, int);
77 struct mapinfo {
78 int maptype;
79 u_int base;
80 u_int mask;
83 struct mapinfo
84 sun3x_mapinfo[MAP__NTYPES] = {
85 /* On-board memory, I/O */
86 { MAP_MAINMEM, 0, ~0 },
87 { MAP_OBIO, 0, ~0 },
88 /* Multibus adapter (A24,A16) */
89 { MAP_MBMEM, VME24D16_BASE, VME24_MASK },
90 { MAP_MBIO, VME16D16_BASE, VME16_MASK },
91 /* VME A16 */
92 { MAP_VME16A16D, VME16D16_BASE, VME16_MASK },
93 { MAP_VME16A32D, VME16D32_BASE, VME16_MASK },
94 /* VME A24 */
95 { MAP_VME24A16D, VME24D16_BASE, VME24_MASK },
96 { MAP_VME24A32D, VME24D32_BASE, VME24_MASK },
97 /* VME A32 */
98 { MAP_VME32A16D, VME32D16_BASE, VME32_MASK },
99 { MAP_VME32A32D, VME32D32_BASE, VME32_MASK },
102 /* The virtual address we will use for PROM device mappings. */
103 u_int sun3x_devmap = MON_KDB_BASE;
105 char *
106 dev3x_mapin(int maptype, u_long physaddr, int length)
108 u_int i, pa, pte, pgva, va;
110 if ((sun3x_devmap + length) > (MON_KDB_BASE + MON_KDB_SIZE))
111 panic("dev3x_mapin: length=%d", length);
113 for (i = 0; i < MAP__NTYPES; i++)
114 if (sun3x_mapinfo[i].maptype == maptype)
115 goto found;
116 panic("dev3x_mapin: bad maptype");
117 found:
119 if (physaddr & ~(sun3x_mapinfo[i].mask))
120 panic("dev3x_mapin: bad address");
121 pa = sun3x_mapinfo[i].base + physaddr;
123 pte = pa | MMU_DT_PAGE | MMU_SHORT_PTE_CI;
125 va = pgva = sun3x_devmap;
126 do {
127 set_pte(pgva, pte);
128 pgva += NBPG;
129 pte += NBPG;
130 length -= NBPG;
131 } while (length > 0);
132 sun3x_devmap = pgva;
133 va += (physaddr & PGOFSET);
135 #ifdef DEBUG_PROM
136 if (debug)
137 printf("dev3x_mapin: va=0x%x pte=0x%x\n",
138 va, get_pte(va));
139 #endif
140 return ((char*)va);
143 /*****************************************************************
144 * DVMA support
147 #define SA_MIN_VA 0x200000
148 #define SA_MAX_VA (SA_MIN_VA + MON_DVMA_SIZE - (8 * NBPG))
150 #define MON_DVMA_MAPLEN (MON_DVMA_SIZE - NBPG)
152 /* This points to the end of the free DVMA space. */
153 u_int dvma3x_end = MON_DVMA_BASE + MON_DVMA_MAPLEN;
155 void
156 dvma3x_init(void)
158 u_int va, pa;
160 pa = SA_MIN_VA;
161 va = MON_DVMA_BASE;
163 while (pa < SA_MAX_VA) {
164 set_pte(va, pa | MMU_DT_PAGE | MMU_SHORT_PTE_CI);
165 set_iommupte(va, pa | IOMMU_PDE_DT_VALID | IOMMU_PDE_CI);
166 va += NBPG;
167 pa += NBPG;
171 /* Convert a local address to a DVMA address. */
172 char *
173 dvma3x_mapin(char *addr, int len)
175 int va = (int)addr;
177 /* Make sure the address is in the DVMA map. */
178 if ((va < SA_MIN_VA) || (va >= SA_MAX_VA))
179 panic("dvma3x_mapin");
181 va -= SA_MIN_VA;
182 va += MON_DVMA_BASE;
184 return ((char *) va);
187 /* Convert a DVMA address to a local address. */
188 void
189 dvma3x_mapout(char *addr, int len)
191 int va = (int)addr;
193 /* Make sure the address is in the DVMA map. */
194 if ((va < MON_DVMA_BASE) ||
195 (va >= (MON_DVMA_BASE + MON_DVMA_MAPLEN)))
196 panic("dvma3x_mapout");
199 char *
200 dvma3x_alloc(int len)
202 len = m68k_round_page(len);
203 dvma3x_end -= len;
204 return((char *)dvma3x_end);
207 void
208 dvma3x_free(char *dvma, int len)
210 /* not worth the trouble */
213 /*****************************************************************
214 * MMU (and I/O MMU) support
217 u_int
218 get_pte(vaddr_t va)
220 u_int pn;
221 mmu_short_pte_t *tbl;
223 if (va >= MON_LOMEM_BASE && va < MON_LOMEM_END) {
224 tbl = (mmu_short_pte_t *) *romVectorPtr->lomemptaddr;
225 } else if (va >= MON_KDB_BASE && va < MON_KDB_END) {
226 va -= MON_KDB_BASE;
227 tbl = (mmu_short_pte_t *) *romVectorPtr->monptaddr;
228 } else if (va >= MON_DVMA_BASE) {
229 va -= MON_DVMA_BASE;
230 tbl = (mmu_short_pte_t *) *romVectorPtr->shadowpteaddr;
231 } else {
232 return 0;
235 /* Calculate the page number within the selected table. */
236 pn = (va >> MMU_PAGE_SHIFT);
237 /* Extract the PTE from the table. */
238 return tbl[pn].attr.raw;
241 void
242 set_pte(vaddr_t va, paddr_t pa)
244 u_int pn;
245 mmu_short_pte_t *tbl;
247 if (va >= MON_LOMEM_BASE && va < (MON_LOMEM_BASE + MON_LOMEM_SIZE)) {
249 * Main memory range.
251 tbl = (mmu_short_pte_t *) *romVectorPtr->lomemptaddr;
252 } else if (va >= MON_KDB_BASE && va < (MON_KDB_BASE + MON_KDB_SIZE)) {
254 * Kernel Debugger range.
256 va -= MON_KDB_BASE;
257 tbl = (mmu_short_pte_t *) *romVectorPtr->monptaddr;
258 } else if (va >= MON_DVMA_BASE) {
260 * DVMA range.
262 va -= MON_DVMA_BASE;
263 tbl = (mmu_short_pte_t *) *romVectorPtr->shadowpteaddr;
264 } else {
265 /* invalid range */
266 return;
269 /* Calculate the page number within the selected table. */
270 pn = (va >> MMU_PAGE_SHIFT);
271 /* Enter the PTE into the table. */
272 tbl[pn].attr.raw = pa;
273 /* Flush the ATC of any cached entries for the va. */
274 mmu_atc_flush(va);
277 void
278 mmu_atc_flush(vaddr_t va)
281 __asm volatile ("pflush #0,#0,%0@" : : "a" (va));
284 void
285 set_iommupte(vaddr_t va, paddr_t pa)
287 iommu_pde_t *iommu_va;
288 int pn;
290 iommu_va = (iommu_pde_t *) *romVectorPtr->dvmaptaddr;
292 /* Adjust the virtual address into an offset within the DVMA map. */
293 va -= MON_DVMA_BASE;
295 /* Convert the slave address into a page index. */
296 pn = IOMMU_BTOP(va);
298 iommu_va[pn].addr.raw = pa;
301 /*****************************************************************
302 * Init our function pointers, etc.
305 void
306 sun3x_init(void)
309 /* Set the function pointers. */
310 dev_mapin_p = dev3x_mapin;
311 dvma_alloc_p = dvma3x_alloc;
312 dvma_free_p = dvma3x_free;
313 dvma_mapin_p = dvma3x_mapin;
314 dvma_mapout_p = dvma3x_mapout;
316 dvma3x_init();