summaryrefslogtreecommitdiff
path: root/sys/arch/amd64/pci
diff options
context:
space:
mode:
authorAriane van der Steldt <ariane@cvs.openbsd.org>2009-05-07 11:30:28 +0000
committerAriane van der Steldt <ariane@cvs.openbsd.org>2009-05-07 11:30:28 +0000
commitfafe38bd094e3a643eaeee0713da3672120f6a7c (patch)
treeee6da62c994498f28d5a4adcab1dd67174c0e5fe /sys/arch/amd64/pci
parentcaafa8002519442d0d9a9929c9dcce73c0576c5f (diff)
Move amas device from arch/amd64 to dev/pci and enable it in i386 as well.
amas defaults to disabled on both amd64 and i386. "Go for it!" kettenis@
Diffstat (limited to 'sys/arch/amd64/pci')
-rw-r--r--sys/arch/amd64/pci/amas.c284
1 files changed, 0 insertions, 284 deletions
diff --git a/sys/arch/amd64/pci/amas.c b/sys/arch/amd64/pci/amas.c
deleted file mode 100644
index 0dc07848d04..00000000000
--- a/sys/arch/amd64/pci/amas.c
+++ /dev/null
@@ -1,284 +0,0 @@
-/* $OpenBSD: amas.c,v 1.2 2009/04/20 20:29:11 ariane Exp $ */
-
-/*
- * Copyright (c) 2009 Ariane van der Steldt <ariane@stack.nl>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * Device: amas (AMD memory access/address switch).
- *
- * Driver for the amd athlon/opteron 64 address map.
- * This device is integrated in 64-bit Athlon and Opteron cpus
- * and contains mappings for memory to processor nodes.
- */
-
-#include <machine/amas.h>
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/device.h>
-
-#include <dev/pci/pcivar.h>
-#include <dev/pci/pcireg.h>
-#include <dev/pci/pcidevs.h>
-
-int amas_match(struct device*, void*, void*);
-void amas_attach(struct device*, struct device*, void*);
-
-/*
- * Amas device layout:
- *
- * - base/limit registers (on 0x0f, 0x10, 0x11)
- * - extended base/limit registers (on 0x10)
- *
- * 0x0f, 0x10 support up to 8 nodes
- * 0x11 supports up to 1 nodes
- *
- * base/limit registers use bits [31..16] to indicate address [39..24]
- * extended base/limit registers use bits [7..0] to indicate address [47..40]
- * base/limit addresses need to be shifted <<24 for memory address
- * extended base/limit addresses need to be shifted <<40 for memory address
- */
-
-#define AMAS_REG_BASE(node) (0x0040 + 0x08 * (node))
-#define AMAS_REG_LIMIT(node) (0x0044 + 0x08 * (node))
-#define AMAS_REG_EXTBASE(node) (0x0140 + 0x08 * (node))
-#define AMAS_REG_EXTLIMIT(node) (0x0144 + 0x08 * (node))
-
-#define AMAS_REG_BL_ADDR(reg) (((reg) >> 16) & 0xffff)
-#define AMAS_REG_EBL_ADDR(ereg) ((ereg) & 0xff)
-
-#define AMAS_REG_BL_SHIFT (24)
-#define AMAS_REG_EBL_SHIFT (40)
-
-#define AMAS_REG_BL_PGSHIFT (AMAS_REG_BL_SHIFT - PAGE_SHIFT)
-#define AMAS_REG_EBL_PGSHIFT (AMAS_REG_EBL_SHIFT - PAGE_SHIFT)
-
-/*
- * Convert an address in amas to a page number.
- *
- * The device uses an inclusive mapping, where the upper bound address
- * must be all 1's after shifting.
- * The device driver uses C-style array indices, hence the +1 in the _LIMIT
- * macro.
- */
-#define AMAS_ADDR2PAGE_BASE(base, ebase) \
- (((base) << AMAS_REG_BL_PGSHIFT) | ((ebase) << AMAS_REG_EBL_PGSHIFT))
-#define AMAS_ADDR2PAGE_LIMIT(base, ebase) \
- (((base + 1) << AMAS_REG_BL_PGSHIFT) | ((ebase) << AMAS_REG_EBL_PGSHIFT))
-
-/*
- * Node and interleave description.
- * - base contains node selection [10..8] (on 0x0f, 0x10)
- * - limit contains node selection bitmask [10..8] (on 0x0f, 0x10)
- * - limit contains destination node [2..0] (on 0x0f, 0x10)
- */
-#define AMAS_DST_NODE(base, limit) ((limit) & 0x07)
-#define AMAS_INTL_ENABLE(base, limit) (((base) >> 8) & 0x07)
-#define AMAS_INTL_SELECTOR(base, limit) (((limit) >> 8) & 0x07)
-
-/*
- * Defines for family.
- * Corresponds to the amas_feature[] constant below.
- */
-#define AMAS_FAM_0Fh (0)
-#define AMAS_FAM_10h (1)
-#define AMAS_FAM_11h (2)
-
-/*
- * Feature tests.
- *
- * 0x11 supports at max 1 node, 0x0f and 0x10 support up to 8 nodes.
- * 0x11 has extended address registers.
- * 0x0f, 0x10 can interleave memory.
- */
-struct amas_feature_t {
- int maxnodes;
- int can_intl;
- int has_extended_bl;
-};
-static const struct amas_feature_t amas_feature[] = {
- /* Family 0x0f */
- { 8, 1, 0 },
- /* Family 0x10 */
- { 8, 1, 1 },
- /* Family 0x11 */
- { 1, 0, 0 },
-};
-
-/* Probe code. */
-struct cfattach amas_ca = {
- sizeof(struct amas_softc),
- amas_match,
- amas_attach
-};
-
-struct cfdriver amas_cd = {
- NULL,
- "amas",
- DV_DULL
-};
-
-const struct pci_matchid amas_devices[] = {
- { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_AMD64_0F_ADDR },
- { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_AMD64_10_ADDR },
- { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_AMD64_11_ADDR },
-};
-
-int
-amas_match(struct device *parent, void *match, void *aux)
-{
- struct pci_attach_args* pa = aux;
-
- if (pci_matchbyid(pa, amas_devices, nitems(amas_devices)))
- return 2; /* override pchb */
- return 0;
-}
-
-void
-amas_attach(struct device *parent, struct device *self, void *aux)
-{
- struct pci_attach_args *pa = aux;
- struct amas_softc *amas = (struct amas_softc*)self;
-#ifdef DEBUG
- paddr_t start_pg, end_pg;
- int nodes, i;
-#endif /* DEBUG */
-
- amas->pa_tag = pa->pa_tag;
- amas->pa_pc = pa->pa_pc;
-
- switch (PCI_PRODUCT(pa->pa_id)) {
- case PCI_PRODUCT_AMD_AMD64_0F_ADDR:
- amas->family = AMAS_FAM_0Fh;
- break;
- case PCI_PRODUCT_AMD_AMD64_10_ADDR:
- amas->family = AMAS_FAM_10h;
- break;
- case PCI_PRODUCT_AMD_AMD64_11_ADDR:
- amas->family = AMAS_FAM_11h;
- break;
- }
-
-#ifdef DEBUG
- nodes = amas_intl_nodes(amas);
-
- printf(":");
- if (nodes != 0) {
- printf(" interleaved across %d nodes", nodes);
- } else {
- for (i = 0; i < AMAS_MAX_NODES; i++) {
- amas_get_pagerange(amas, i, &start_pg, &end_pg);
-
- if (start_pg == 0 && end_pg == 0)
- printf(" []");
- else
- printf(" [%p, %p]", start_pg, end_pg);
- }
- }
-#endif /* DEBUG */
- printf("\n");
-
- return;
-}
-
-/*
- * Returns the number of nodes across which the memory is interleaved.
- * Returns 0 if the memory is not interleaved.
- */
-int
-amas_intl_nodes(struct amas_softc *amas)
-{
- pcireg_t base_reg, limit_reg;
- int mask;
-
- if (!amas_feature[amas->family].can_intl)
- return 0;
-
- /*
- * Use node 0 on amas device to find interleave information.
- * Node 0 is always present.
- */
-
- base_reg = pci_conf_read(amas->pa_pc, amas->pa_tag, AMAS_REG_BASE(0));
- limit_reg = pci_conf_read(amas->pa_pc, amas->pa_tag, AMAS_REG_LIMIT(0));
- mask = AMAS_INTL_ENABLE(base_reg, limit_reg);
-
- return mask == 0 ? 0 : mask + 1;
-}
-
-/*
- * Returns the range of memory that is contained on the given node.
- * If the memory is interleaved, the result is undefined.
- *
- * The range is written in {start,end}_pg_idx.
- * Note that these are page numbers and that these use array indices:
- * pages are in this range if start <= pg_no < end.
- *
- * This device supports at most 8 nodes.
- */
-void
-amas_get_pagerange(struct amas_softc *amas, int node,
- paddr_t *start_pg_idx, paddr_t *end_pg_idx)
-{
- pcireg_t base, ebase, limit, elimit;
- paddr_t base_addr, ebase_addr, limit_addr, elimit_addr;
-
- /* Sanity check: max AMAS_MAX_NODES supported. */
- KASSERT(node >= 0 && node < AMAS_MAX_NODES);
-
- if (node >= amas_feature[amas->family].maxnodes) {
- /* Unsupported node: bail out early. */
- *start_pg_idx = 0;
- *end_pg_idx = 0;
- return;
- }
-
- base = pci_conf_read(amas->pa_pc, amas->pa_tag,
- AMAS_REG_BASE(node));
- limit = pci_conf_read(amas->pa_pc, amas->pa_tag,
- AMAS_REG_LIMIT(node));
- base_addr = AMAS_REG_BL_ADDR(base);
- limit_addr = AMAS_REG_BL_ADDR(limit);
-
- ebase = 0;
- elimit = 0;
- ebase_addr = 0;
- elimit_addr = 0;
-#if 0 /* Needs extended pci registers. */
- if (amas_feature[amas->family].has_extended_bl) {
- ebase = pci_conf_read(amas->pa_pc, amas->pa_tag,
- AMAS_REG_EXTBASE(node));
- elimit = pci_conf_read(amas->pa_pc, amas->pa_tag,
- AMAS_REG_EXTLIMIT(node));
- ebase_addr = AMAS_REG_EBL_ADDR(ebase);
- elimit_addr = AMAS_REG_EBL_ADDR(elimit);
- }
-#endif /* 0 */
-
- if (base_addr == limit_addr && ebase_addr == elimit_addr) {
- /* no memory present */
- *start_pg_idx = 0;
- *end_pg_idx = 0;
- return;
- }
-
- /* Guaranteed by spec. */
- KASSERT(node == AMAS_DST_NODE(base, limit));
-
- *start_pg_idx = AMAS_ADDR2PAGE_BASE(base_addr, ebase_addr);
- *end_pg_idx = AMAS_ADDR2PAGE_LIMIT(limit_addr, elimit_addr);
- return;
-}