1 /* $NetBSD: sun3x.c,v 1.11 2009/01/12 07:00:59 tsutsui Exp $ */
4 * Copyright (c) 1998 The NetBSD Foundation, Inc.
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
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.
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>
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>
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);
84 sun3x_mapinfo
[MAP__NTYPES
] = {
85 /* On-board memory, I/O */
86 { MAP_MAINMEM
, 0, ~0 },
88 /* Multibus adapter (A24,A16) */
89 { MAP_MBMEM
, VME24D16_BASE
, VME24_MASK
},
90 { MAP_MBIO
, VME16D16_BASE
, VME16_MASK
},
92 { MAP_VME16A16D
, VME16D16_BASE
, VME16_MASK
},
93 { MAP_VME16A32D
, VME16D32_BASE
, VME16_MASK
},
95 { MAP_VME24A16D
, VME24D16_BASE
, VME24_MASK
},
96 { MAP_VME24A32D
, VME24D32_BASE
, VME24_MASK
},
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
;
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
)
116 panic("dev3x_mapin: bad maptype");
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
;
131 } while (length
> 0);
133 va
+= (physaddr
& PGOFSET
);
137 printf("dev3x_mapin: va=0x%x pte=0x%x\n",
143 /*****************************************************************
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
;
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
);
171 /* Convert a local address to a DVMA address. */
173 dvma3x_mapin(char *addr
, int len
)
177 /* Make sure the address is in the DVMA map. */
178 if ((va
< SA_MIN_VA
) || (va
>= SA_MAX_VA
))
179 panic("dvma3x_mapin");
184 return ((char *) va
);
187 /* Convert a DVMA address to a local address. */
189 dvma3x_mapout(char *addr
, int len
)
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");
200 dvma3x_alloc(int len
)
202 len
= m68k_round_page(len
);
204 return((char *)dvma3x_end
);
208 dvma3x_free(char *dvma
, int len
)
210 /* not worth the trouble */
213 /*****************************************************************
214 * MMU (and I/O MMU) support
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
) {
227 tbl
= (mmu_short_pte_t
*) *romVectorPtr
->monptaddr
;
228 } else if (va
>= MON_DVMA_BASE
) {
230 tbl
= (mmu_short_pte_t
*) *romVectorPtr
->shadowpteaddr
;
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
;
242 set_pte(vaddr_t va
, paddr_t pa
)
245 mmu_short_pte_t
*tbl
;
247 if (va
>= MON_LOMEM_BASE
&& va
< (MON_LOMEM_BASE
+ MON_LOMEM_SIZE
)) {
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.
257 tbl
= (mmu_short_pte_t
*) *romVectorPtr
->monptaddr
;
258 } else if (va
>= MON_DVMA_BASE
) {
263 tbl
= (mmu_short_pte_t
*) *romVectorPtr
->shadowpteaddr
;
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. */
278 mmu_atc_flush(vaddr_t va
)
281 __asm
volatile ("pflush #0,#0,%0@" : : "a" (va
));
285 set_iommupte(vaddr_t va
, paddr_t pa
)
287 iommu_pde_t
*iommu_va
;
290 iommu_va
= (iommu_pde_t
*) *romVectorPtr
->dvmaptaddr
;
292 /* Adjust the virtual address into an offset within the DVMA map. */
295 /* Convert the slave address into a page index. */
298 iommu_va
[pn
].addr
.raw
= pa
;
301 /*****************************************************************
302 * Init our function pointers, etc.
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
;