Module Name:    src
Committed By:   thorpej
Date:           Mon Jul 19 01:06:14 UTC 2021

Modified Files:
        src/sys/arch/alpha/pci: cia_dma.c ciavar.h tsp_dma.c tsvar.h

Log Message:
For CIA/Pyxis and Tsunami/Typhoon/Titan, save the firmware's idea of
the DMA window configuration, and restore it at shutdown time.  Make
sure that all assumptions we've made on the firmware's configuration
of DMA windows is correct.


To generate a diff of this commit:
cvs rdiff -u -r1.36 -r1.37 src/sys/arch/alpha/pci/cia_dma.c
cvs rdiff -u -r1.21 -r1.22 src/sys/arch/alpha/pci/ciavar.h \
    src/sys/arch/alpha/pci/tsp_dma.c
cvs rdiff -u -r1.16 -r1.17 src/sys/arch/alpha/pci/tsvar.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/alpha/pci/cia_dma.c
diff -u src/sys/arch/alpha/pci/cia_dma.c:1.36 src/sys/arch/alpha/pci/cia_dma.c:1.37
--- src/sys/arch/alpha/pci/cia_dma.c:1.36	Sun Jul 18 05:09:47 2021
+++ src/sys/arch/alpha/pci/cia_dma.c	Mon Jul 19 01:06:14 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: cia_dma.c,v 1.36 2021/07/18 05:09:47 thorpej Exp $ */
+/* $NetBSD: cia_dma.c,v 1.37 2021/07/19 01:06:14 thorpej Exp $ */
 
 /*-
  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
@@ -32,7 +32,7 @@
 
 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
 
-__KERNEL_RCSID(0, "$NetBSD: cia_dma.c,v 1.36 2021/07/18 05:09:47 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cia_dma.c,v 1.37 2021/07/19 01:06:14 thorpej Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -100,12 +100,49 @@ struct alpha_sgmap cia_pyxis_bug_sgmap;
 #define	CIA_PYXIS_BUG_BASE	(128UL*1024*1024)
 #define	CIA_PYXIS_BUG_SIZE	(2UL*1024*1024)
 
+static void
+cia_dma_shutdown(void *arg)
+{
+	struct cia_config *ccp = arg;
+	int i;
+
+	/*
+	 * Restore the original values, to make the firmware happy.
+	 */
+	for (i = 0; i < 4; i++) {
+		REGVAL(CIA_PCI_W0BASE + (i * 0x100)) =
+		    ccp->cc_saved_windows.wbase[i];
+		alpha_mb();
+		REGVAL(CIA_PCI_W0MASK + (i * 0x100)) =
+		    ccp->cc_saved_windows.wmask[i];
+		alpha_mb();
+		REGVAL(CIA_PCI_T0BASE + (i * 0x100)) =
+		    ccp->cc_saved_windows.tbase[i];
+		alpha_mb();
+	}
+}
+
 void
 cia_dma_init(struct cia_config *ccp)
 {
 	bus_addr_t tbase;
 	bus_dma_tag_t t;
 	bus_dma_tag_t t_sg_hi = NULL;
+	int i;
+
+	/*
+	 * Save our configuration to restore at shutdown, just
+	 * in case the firmware would get cranky with us.
+	 */
+	for (i = 0; i < 4; i++) {
+		ccp->cc_saved_windows.wbase[i] =
+		    REGVAL(CIA_PCI_W0BASE + (i * 0x100));
+		ccp->cc_saved_windows.wmask[i] =
+		    REGVAL(CIA_PCI_W0MASK + (i * 0x100));
+		ccp->cc_saved_windows.tbase[i] =
+		    REGVAL(CIA_PCI_T0BASE + (i * 0x100));
+	}
+	shutdownhook_establish(cia_dma_shutdown, ccp);
 
 	/*
 	 * If we have more than 1GB of RAM, then set up an sgmap-mapped
@@ -195,11 +232,17 @@ cia_dma_init(struct cia_config *ccp)
 	t->_dmamem_mmap = _bus_dmamem_mmap;
 
 	/*
-	 * The firmware has set up window 1 as a 1G direct-mapped DMA
-	 * window beginning at 1G.  We leave it alone.  Leave window
-	 * 0 alone until we reconfigure it for SGMAP-mapped DMA.
-	 * Windows 2 and 3 are already disabled.
+	 * The firmware will have set up window 1 as a 1G dirct-mapped
+	 * DMA window beginning at 1G.  While it's pretty safe to assume
+	 * this is the case, we'll go ahead and program the registers
+	 * as we expect as a belt-and-suspenders measure.
 	 */
+	REGVAL(CIA_PCI_W1BASE) = CIA_DIRECT_MAPPED_BASE | CIA_PCI_WnBASE_W_EN;
+	alpha_mb();
+	REGVAL(CIA_PCI_W1MASK) = CIA_PCI_WnMASK_1G;
+	alpha_mb();
+	REGVAL(CIA_PCI_T1BASE) = 0;
+	alpha_mb();
 
 	/*
 	 * Initialize the SGMAP(s).  Must align page table to at least 32k
@@ -248,6 +291,9 @@ cia_dma_init(struct cia_config *ccp)
 			panic("cia_dma_init: bad page table address");
 		REGVAL(CIA_PCI_T3BASE) = tbase;
 		alpha_mb();
+	} else {
+		REGVAL(CIA_PCI_W3BASE) = 0;
+		alpha_mb();
 	}
 
 	/*
@@ -261,7 +307,6 @@ cia_dma_init(struct cia_config *ccp)
 	 */
 	if ((ccp->cc_flags & CCF_ISPYXIS) != 0 && ccp->cc_rev <= 1) {
 		uint64_t *page_table;
-		int i;
 
 		cia_tlb_invalidate_fn =
 		    cia_broken_pyxis_tlb_invalidate;
@@ -296,8 +341,12 @@ cia_dma_init(struct cia_config *ccp)
 			    pci_sgmap_pte64_prefetch_spill_page_pte;
 		}
 		alpha_mb();
-	} else
+	} else {
+		REGVAL(CIA_PCI_W2BASE) = 0;
+		alpha_mb();
+
 		cia_tlb_invalidate_fn = cia_tlb_invalidate;
+	}
 
 	CIA_TLB_INVALIDATE();
 }

Index: src/sys/arch/alpha/pci/ciavar.h
diff -u src/sys/arch/alpha/pci/ciavar.h:1.21 src/sys/arch/alpha/pci/ciavar.h:1.22
--- src/sys/arch/alpha/pci/ciavar.h:1.21	Sat Jul 17 00:30:39 2021
+++ src/sys/arch/alpha/pci/ciavar.h	Mon Jul 19 01:06:14 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: ciavar.h,v 1.21 2021/07/17 00:30:39 thorpej Exp $ */
+/* $NetBSD: ciavar.h,v 1.22 2021/07/19 01:06:14 thorpej Exp $ */
 
 /*
  * Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -65,6 +65,12 @@ struct cia_config {
 
 	struct extent *cc_io_ex, *cc_d_mem_ex, *cc_s_mem_ex;
 	int	cc_mallocsafe;
+
+	struct {
+		uint32_t wbase[4];
+		uint32_t wmask[4];
+		uint32_t tbase[4];
+	} cc_saved_windows;
 };
 
 struct cia_softc {
Index: src/sys/arch/alpha/pci/tsp_dma.c
diff -u src/sys/arch/alpha/pci/tsp_dma.c:1.21 src/sys/arch/alpha/pci/tsp_dma.c:1.22
--- src/sys/arch/alpha/pci/tsp_dma.c:1.21	Sun Jul 18 19:58:34 2021
+++ src/sys/arch/alpha/pci/tsp_dma.c	Mon Jul 19 01:06:14 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: tsp_dma.c,v 1.21 2021/07/18 19:58:34 thorpej Exp $ */
+/* $NetBSD: tsp_dma.c,v 1.22 2021/07/19 01:06:14 thorpej Exp $ */
 
 /*-
  * Copyright (c) 1997, 1998, 2021 The NetBSD Foundation, Inc.
@@ -61,7 +61,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tsp_dma.c,v 1.21 2021/07/18 19:58:34 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tsp_dma.c,v 1.22 2021/07/19 01:06:14 thorpej Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -158,6 +158,26 @@ static void	tsp_tlb_invalidate(struct ts
  * dual address cycle.
  */
 
+static void
+tsp_dma_shutdown(void *arg)
+{
+	struct tsp_config *pcp = arg;
+	struct ts_pchip *pccsr = pcp->pc_csr;
+	int i;
+
+	/*
+	 * Restore the initial values, to make the firmware happy.
+	 */
+	for (i = 0; i < 4; i++) {
+		pccsr->tsp_wsba[i].tsg_r = pcp->pc_saved_windows.wsba[i];
+		pccsr->tsp_wsm[i].tsg_r = pcp->pc_saved_windows.wsm[i];
+		pccsr->tsp_tba[i].tsg_r = pcp->pc_saved_windows.tba[i];
+		alpha_mb();
+	}
+	pccsr->tsp_pctl.tsg_r = pcp->pc_saved_pctl;
+	alpha_mb();
+}
+
 void
 tsp_dma_init(struct tsp_config *pcp)
 {
@@ -165,6 +185,19 @@ tsp_dma_init(struct tsp_config *pcp)
 	bus_dma_tag_t t_sg_hi = NULL;
 	struct ts_pchip *pccsr = pcp->pc_csr;
 	bus_addr_t tbase;
+	int i;
+
+	/*
+	 * Save our configuration to restore at shutdown, just
+	 * in case the firmware would get cranky with us.
+	 */
+	for (i = 0; i < 4; i++) {
+		pcp->pc_saved_windows.wsba[i] = pccsr->tsp_wsba[i].tsg_r;
+		pcp->pc_saved_windows.wsm[i] = pccsr->tsp_wsm[i].tsg_r;
+		pcp->pc_saved_windows.tba[i] = pccsr->tsp_tba[i].tsg_r;
+	}
+	pcp->pc_saved_pctl = pccsr->tsp_pctl.tsg_r;
+	shutdownhook_establish(tsp_dma_shutdown, pcp);
 
 	/* Ensure the Monster Window is enabled. */
 	alpha_mb();

Index: src/sys/arch/alpha/pci/tsvar.h
diff -u src/sys/arch/alpha/pci/tsvar.h:1.16 src/sys/arch/alpha/pci/tsvar.h:1.17
--- src/sys/arch/alpha/pci/tsvar.h:1.16	Sun Jul 18 00:01:20 2021
+++ src/sys/arch/alpha/pci/tsvar.h	Mon Jul 19 01:06:14 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: tsvar.h,v 1.16 2021/07/18 00:01:20 thorpej Exp $ */
+/* $NetBSD: tsvar.h,v 1.17 2021/07/19 01:06:14 thorpej Exp $ */
 
 /*-
  * Copyright (c) 1999 by Ross Harvey.  All rights reserved.
@@ -66,6 +66,13 @@ struct tsp_config {
 	long	pc_mem_exstorage[_FSTORE];
 	struct	extent *pc_io_ex, *pc_mem_ex;
 	int	pc_mallocsafe;
+
+	struct {
+		uint64_t wsba[4];
+		uint64_t wsm[4];
+		uint64_t tba[4];
+	} pc_saved_windows;
+	uint64_t pc_saved_pctl;
 };
 
 struct tsp_attach_args {

Reply via email to