Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/sparc/sparc Cleanup iommu_attach().
details: https://anonhg.NetBSD.org/src/rev/984f1375cf6f
branches: trunk
changeset: 486788:984f1375cf6f
user: pk <pk%NetBSD.org@localhost>
date: Sun May 28 20:55:54 2000 +0000
description:
Cleanup iommu_attach().
diffstat:
sys/arch/sparc/sparc/iommu.c | 129 +++++++++++++++++++++++++-----------------
1 files changed, 76 insertions(+), 53 deletions(-)
diffs (208 lines):
diff -r 5f5c6b9cb7fc -r 984f1375cf6f sys/arch/sparc/sparc/iommu.c
--- a/sys/arch/sparc/sparc/iommu.c Sun May 28 20:54:42 2000 +0000
+++ b/sys/arch/sparc/sparc/iommu.c Sun May 28 20:55:54 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: iommu.c,v 1.41 2000/05/23 11:39:58 pk Exp $ */
+/* $NetBSD: iommu.c,v 1.42 2000/05/28 20:55:54 pk Exp $ */
/*
* Copyright (c) 1996
@@ -84,6 +84,8 @@
void iommu_attach __P((struct device *, struct device *, void *));
int iommu_match __P((struct device *, struct cfdata *, void *));
+static void iommu_copy_prom_entries __P((struct iommu_softc *));
+
struct cfattach iommu_ca = {
sizeof(struct iommu_softc), iommu_match, iommu_attach
};
@@ -171,13 +173,10 @@
struct mainbus_attach_args *ma = aux;
int node;
bus_space_handle_t bh;
- u_int pbase, pa;
- int i, mmupcrsave, s;
- iopte_t *tpte_p;
+ int i, s;
extern u_int *kernel_iopte_table;
extern u_int kernel_iopte_table_pa;
-/*XXX-GCC!*/mmupcrsave=0;
iommu_sc = sc;
/*
* XXX there is only one iommu, for now -- do not know how to
@@ -221,21 +220,11 @@
has_iocache = sc->sc_hasiocache; /* Set global flag */
sc->sc_pagesize = getpropint(node, "page-size", NBPG),
- sc->sc_range = (1 << 24) <<
- ((sc->sc_reg->io_cr & IOMMU_CTL_RANGE) >> IOMMU_CTL_RANGESHFT);
-#if 0
- sc->sc_dvmabase = (0 - sc->sc_range);
-#endif
- pbase = (sc->sc_reg->io_bar & IOMMU_BAR_IBA) <<
- (14 - IOMMU_BAR_IBASHFT);
/*
* Now we build our own copy of the IOMMU page tables. We need to
* do this since we're going to change the range to give us 64M of
- * mappings, and thus we can move DVMA space down to 0xfd000000 to
- * give us lots of space and to avoid bumping into the PROM, etc.
- *
- * XXX Note that this is rather messy.
+ * DVMA space (starting at 0xfd000000).
*/
sc->sc_ptes = (iopte_t *) kernel_iopte_table;
@@ -247,33 +236,10 @@
(((0 - IOMMU_DVMA_BASE)/sc->sc_pagesize) * sizeof(iopte_t)) / NBPG);
/*
- * Ok. We've got to read in the original table using MMU bypass,
- * and copy all of its entries to the appropriate place in our
- * new table, even if the sizes are different.
- * This is pretty easy since we know DVMA ends at 0xffffffff.
- *
- * XXX: PGOFSET, NBPG assume same page size as SRMMU
+ * Copy entries from current IOMMU table.
+ * XXX - Why do we need to do this?
*/
- if (cpuinfo.cpu_impl == 4 && cpuinfo.mxcc) {
- /* set MMU AC bit */
- sta(SRMMU_PCR, ASI_SRMMU,
- ((mmupcrsave = lda(SRMMU_PCR, ASI_SRMMU)) | VIKING_PCR_AC));
- }
-
- for (tpte_p = &sc->sc_ptes[((0 - IOMMU_DVMA_BASE)/NBPG) - 1],
- pa = (u_int)pbase - sizeof(iopte_t) +
- ((u_int)sc->sc_range/NBPG)*sizeof(iopte_t);
- tpte_p >= &sc->sc_ptes[0] && pa >= (u_int)pbase;
- tpte_p--, pa -= sizeof(iopte_t)) {
-
- IOMMU_FLUSHPAGE(sc,
- (tpte_p - &sc->sc_ptes[0])*NBPG + IOMMU_DVMA_BASE);
- *tpte_p = lda(pa, ASI_BYPASS);
- }
- if (cpuinfo.cpu_impl == 4 && cpuinfo.mxcc) {
- /* restore mmu after bug-avoidance */
- sta(SRMMU_PCR, ASI_SRMMU, mmupcrsave);
- }
+ iommu_copy_prom_entries(sc);
/*
* Now we can install our new pagetable into the IOMMU
@@ -284,7 +250,7 @@
/* calculate log2(sc->sc_range/16MB) */
i = ffs(sc->sc_range/(1 << 24)) - 1;
if ((1 << i) != (sc->sc_range/(1 << 24)))
- panic("bad iommu range: %d\n",i);
+ panic("iommu: bad range: %d\n", i);
s = splhigh();
IOMMU_FLUSHALL(sc);
@@ -334,6 +300,63 @@
#endif
}
+static void
+iommu_copy_prom_entries(sc)
+ struct iommu_softc *sc;
+{
+ u_int pbase, pa;
+ u_int range;
+ iopte_t *tpte_p;
+ u_int pagesz = sc->sc_pagesize;
+ int use_ac = (cpuinfo.cpu_impl == 4 && cpuinfo.mxcc);
+ u_int mmupcr_save;
+
+ /*
+ * We read in the original table using MMU bypass and copy all
+ * of its entries to the appropriate place in our new table,
+ * even if the sizes are different.
+ * This is pretty easy since we know DVMA ends at 0xffffffff.
+ */
+
+ range = (1 << 24) <<
+ ((sc->sc_reg->io_cr & IOMMU_CTL_RANGE) >> IOMMU_CTL_RANGESHFT);
+
+ pbase = (sc->sc_reg->io_bar & IOMMU_BAR_IBA) <<
+ (14 - IOMMU_BAR_IBASHFT);
+
+ if (use_ac) {
+ /*
+ * Set MMU AC bit so we'll still read from the cache
+ * in by-pass mode.
+ */
+ mmupcr_save = lda(SRMMU_PCR, ASI_SRMMU);
+ sta(SRMMU_PCR, ASI_SRMMU, mmupcr_save | VIKING_PCR_AC);
+ } else
+ mmupcr_save = 0; /* XXX - avoid GCC `unintialized' warning */
+
+ /* Flush entire IOMMU TLB before messing with the in-memory tables */
+ IOMMU_FLUSHALL(sc);
+
+ /*
+ * tpte_p = top of our PTE table
+ * pa = top of current PTE table
+ * Then work downwards and copy entries until we hit the bottom
+ * of either table.
+ */
+ for (tpte_p = &sc->sc_ptes[((0 - IOMMU_DVMA_BASE)/pagesz) - 1],
+ pa = (u_int)pbase + (range/pagesz - 1)*sizeof(iopte_t);
+ tpte_p >= &sc->sc_ptes[0] && pa >= (u_int)pbase;
+ tpte_p--, pa -= sizeof(iopte_t)) {
+
+ *tpte_p = lda(pa, ASI_BYPASS);
+ }
+
+ if (use_ac) {
+ /* restore mmu after bug-avoidance */
+ sta(SRMMU_PCR, ASI_SRMMU, mmupcr_save);
+ }
+}
+
void
iommu_enter(dva, pa)
bus_addr_t dva;
@@ -360,8 +383,8 @@
* iommu_clear: clears mappings created by iommu_enter
*/
void
-iommu_remove(va, len)
- bus_addr_t va;
+iommu_remove(dva, len)
+ bus_addr_t dva;
bus_size_t len;
{
struct iommu_softc *sc = iommu_sc;
@@ -369,22 +392,22 @@
bus_addr_t base = sc->sc_dvmabase;
#ifdef DEBUG
- if (va < base)
- panic("iommu_enter: va 0x%lx not in DVMA space", (long)va);
+ if (dva < base)
+ panic("iommu_remove: va 0x%lx not in DVMA space", (long)va);
#endif
while ((long)len > 0) {
#ifdef notyet
#ifdef DEBUG
- if ((sc->sc_ptes[atop(va - base)] & IOPTE_V) == 0)
- panic("iommu_clear: clearing invalid pte at va 0x%lx",
- (long)va);
+ if ((sc->sc_ptes[atop(dva - base)] & IOPTE_V) == 0)
+ panic("iommu_remove: clearing invalid pte at dva 0x%lx",
+ (long)dva);
#endif
#endif
- sc->sc_ptes[atop(va - base)] = 0;
- IOMMU_FLUSHPAGE(sc, va);
+ sc->sc_ptes[atop(dva - base)] = 0;
+ IOMMU_FLUSHPAGE(sc, dva);
len -= pagesz;
- va += pagesz;
+ dva += pagesz;
}
}
Home |
Main Index |
Thread Index |
Old Index