/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jeremy Cooper and Gordon Ross
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Standalone functions specific to the Sun3X.
*/
/* This points to the end of the free DVMA space. */
u_int dvma3x_end = MON_DVMA_BASE + MON_DVMA_MAPLEN;
static void
dvma3x_init(void)
{
u_int va, pa;
pa = SA_MIN_VA;
va = MON_DVMA_BASE;
while (pa < SA_MAX_VA) {
sun3x_set_pte(va, pa | MMU_DT_PAGE | MMU_SHORT_PTE_CI);
set_iommupte(va, pa | IOMMU_PDE_DT_VALID | IOMMU_PDE_CI);
va += NBPG;
pa += NBPG;
}
}
/* Convert a local address to a DVMA address. */
char *
dvma3x_mapin(char *addr, int len)
{
int va = (int)addr;
/* Make sure the address is in the DVMA map. */
if ((va < SA_MIN_VA) || (va >= SA_MAX_VA))
panic("dvma3x_mapin");
va -= SA_MIN_VA;
va += MON_DVMA_BASE;
return ((char *) va);
}
/* Convert a DVMA address to a local address. */
static void
dvma3x_mapout(char *addr, int len)
{
int va = (int)addr;
/* Make sure the address is in the DVMA map. */
if ((va < MON_DVMA_BASE) ||
(va >= (MON_DVMA_BASE + MON_DVMA_MAPLEN)))
panic("dvma3x_mapout");
}
if (va >= MON_LOMEM_BASE && va < MON_LOMEM_END) {
tbl = (mmu_short_pte_t *) *romVectorPtr->lomemptaddr;
} else if (va >= MON_KDB_BASE && va < MON_KDB_END) {
va -= MON_KDB_BASE;
tbl = (mmu_short_pte_t *) *romVectorPtr->monptaddr;
} else if (va >= MON_DVMA_BASE) {
va -= MON_DVMA_BASE;
tbl = (mmu_short_pte_t *) *romVectorPtr->shadowpteaddr;
} else {
return 0;
}
/* Calculate the page number within the selected table. */
pn = (va >> MMU_PAGE_SHIFT);
/* Extract the PTE from the table. */
return tbl[pn].attr.raw;
}
#endif
if (va >= MON_LOMEM_BASE && va < (MON_LOMEM_BASE + MON_LOMEM_SIZE)) {
/*
* Main memory range.
*/
tbl = (mmu_short_pte_t *) *romVectorPtr->lomemptaddr;
} else if (va >= MON_KDB_BASE && va < (MON_KDB_BASE + MON_KDB_SIZE)) {
/*
* Kernel Debugger range.
*/
va -= MON_KDB_BASE;
tbl = (mmu_short_pte_t *) *romVectorPtr->monptaddr;
} else if (va >= MON_DVMA_BASE) {
/*
* DVMA range.
*/
va -= MON_DVMA_BASE;
tbl = (mmu_short_pte_t *) *romVectorPtr->shadowpteaddr;
} else {
/* invalid range */
return;
}
/* Calculate the page number within the selected table. */
pn = (va >> MMU_PAGE_SHIFT);
/* Enter the PTE into the table. */
tbl[pn].attr.raw = pa;
/* Flush the ATC of any cached entries for the va. */
mmu_atc_flush(va);
}
static void
mmu_atc_flush(vaddr_t va)
{
__asm volatile ("pflush #0,#0,%0@" : : "a" (va));
}
static void
set_iommupte(vaddr_t va, paddr_t pa)
{
iommu_pde_t *iommu_va;
int pn;