svn commit: r206720 - in projects/altix/sys: conf dev/uart ia64/acpica ia64/ia64 ia64/include ia64/pci ia64/sgisn

Marcel Moolenaar marcel at FreeBSD.org
Sat Apr 17 02:28:28 UTC 2010


Author: marcel
Date: Sat Apr 17 02:28:28 2010
New Revision: 206720
URL: http://svn.freebsd.org/changeset/base/206720

Log:
  Snapshot: PCI busses are discovered, though no devices are enumerable
  yet.

Added:
  projects/altix/sys/ia64/include/sgisn.h
  projects/altix/sys/ia64/sgisn/
  projects/altix/sys/ia64/sgisn/sgisn_pcib.c
Modified:
  projects/altix/sys/conf/files.ia64
  projects/altix/sys/dev/uart/uart_dev_sgisn.c
  projects/altix/sys/ia64/acpica/acpi_machdep.c
  projects/altix/sys/ia64/ia64/autoconf.c
  projects/altix/sys/ia64/ia64/interrupt.c
  projects/altix/sys/ia64/ia64/machdep.c
  projects/altix/sys/ia64/ia64/mp_machdep.c
  projects/altix/sys/ia64/include/ia64_cpu.h
  projects/altix/sys/ia64/include/md_var.h
  projects/altix/sys/ia64/include/pcpu.h
  projects/altix/sys/ia64/include/sal.h
  projects/altix/sys/ia64/pci/pci_cfgreg.c

Modified: projects/altix/sys/conf/files.ia64
==============================================================================
--- projects/altix/sys/conf/files.ia64	Sat Apr 17 02:28:24 2010	(r206719)
+++ projects/altix/sys/conf/files.ia64	Sat Apr 17 02:28:28 2010	(r206720)
@@ -116,6 +116,7 @@ ia64/ia64/vm_machdep.c		standard
 ia64/isa/isa.c			optional	isa
 ia64/isa/isa_dma.c		optional	isa
 ia64/pci/pci_cfgreg.c		optional	pci
+ia64/sgisn/sgisn_pcib.c		standard
 isa/syscons_isa.c		optional	sc
 isa/vga_isa.c			optional	vga
 kern/imgact_elf32.c		optional	compat_freebsd32

Modified: projects/altix/sys/dev/uart/uart_dev_sgisn.c
==============================================================================
--- projects/altix/sys/dev/uart/uart_dev_sgisn.c	Sat Apr 17 02:28:24 2010	(r206719)
+++ projects/altix/sys/dev/uart/uart_dev_sgisn.c	Sat Apr 17 02:28:28 2010	(r206720)
@@ -65,7 +65,7 @@ sgisn_probe(struct uart_bas *bas)
 {
 	struct ia64_sal_result result;
 
-	result = ia64_sal_entry(SAL_SGISN_INFO, 0, 0, 0, 0, 0, 0, 0);
+	result = ia64_sal_entry(SAL_SGISN_SN_INFO, 0, 0, 0, 0, 0, 0, 0);
 	return ((result.sal_status != 0) ? ENXIO : 0);
 }
 

Modified: projects/altix/sys/ia64/acpica/acpi_machdep.c
==============================================================================
--- projects/altix/sys/ia64/acpica/acpi_machdep.c	Sat Apr 17 02:28:24 2010	(r206719)
+++ projects/altix/sys/ia64/acpica/acpi_machdep.c	Sat Apr 17 02:28:28 2010	(r206720)
@@ -28,11 +28,12 @@
 
 #include <sys/param.h>
 #include <sys/bus.h>
+#include <machine/md_var.h>
+#include <machine/pal.h>
 
 #include <contrib/dev/acpica/include/acpi.h>
-
+#include <contrib/dev/acpica/include/actables.h>
 #include <dev/acpica/acpivar.h>
-#include <machine/pal.h>
 
 int
 acpi_machdep_init(device_t dev)
@@ -57,3 +58,37 @@ acpi_cpu_c1()
 {
 	ia64_call_pal_static(PAL_HALT_LIGHT, 0, 0, 0);
 }
+
+void *
+acpi_find_table(const char *sig)
+{
+	ACPI_PHYSICAL_ADDRESS rsdp_ptr;
+	ACPI_TABLE_RSDP *rsdp;
+	ACPI_TABLE_XSDT *xsdt;
+	ACPI_TABLE_HEADER *table;
+	UINT64 addr;
+	u_int i, count;
+
+	if ((rsdp_ptr = AcpiOsGetRootPointer()) == 0)
+		return (NULL);
+
+	rsdp = (ACPI_TABLE_RSDP *)IA64_PHYS_TO_RR7(rsdp_ptr);
+	xsdt = (ACPI_TABLE_XSDT *)IA64_PHYS_TO_RR7(rsdp->XsdtPhysicalAddress);
+
+	count = (UINT64 *)((char *)xsdt + xsdt->Header.Length) -
+	    xsdt->TableOffsetEntry;
+
+	for (i = 0; i < count; i++) {
+		addr = xsdt->TableOffsetEntry[i];
+		table = (ACPI_TABLE_HEADER *)IA64_PHYS_TO_RR7(addr);
+
+		if (strncmp(table->Signature, sig, ACPI_NAME_SIZE) != 0)
+			continue;
+		if (ACPI_FAILURE(AcpiTbChecksum((void *)table, table->Length)))
+			continue;
+
+		return (table);
+	}
+
+	return (NULL);
+}

Modified: projects/altix/sys/ia64/ia64/autoconf.c
==============================================================================
--- projects/altix/sys/ia64/ia64/autoconf.c	Sat Apr 17 02:28:24 2010	(r206719)
+++ projects/altix/sys/ia64/ia64/autoconf.c	Sat Apr 17 02:28:28 2010	(r206720)
@@ -26,7 +26,6 @@
  * $FreeBSD$
  */
 
-#include "opt_bootp.h"
 #include "opt_isa.h"
 
 #include <sys/param.h>
@@ -53,10 +52,6 @@ SYSINIT(configure2, SI_SUB_CONFIGURE, SI
 /* SI_ORDER_MIDDLE is hookable */
 SYSINIT(configure3, SI_SUB_CONFIGURE, SI_ORDER_ANY, configure_final, NULL);
 
-#ifdef BOOTP
-void bootpc_init(void);
-#endif
-
 #ifdef DEV_ISA
 #include <isa/isavar.h>
 device_t isa_bus_device = 0;

Modified: projects/altix/sys/ia64/ia64/interrupt.c
==============================================================================
--- projects/altix/sys/ia64/ia64/interrupt.c	Sat Apr 17 02:28:24 2010	(r206719)
+++ projects/altix/sys/ia64/ia64/interrupt.c	Sat Apr 17 02:28:28 2010	(r206720)
@@ -210,7 +210,9 @@ ia64_setup_intr(const char *name, int ir
 	sa = sapic_lookup(irq, &xiv);
 	if (sa == NULL) {
 		/* XXX unlock */
-		return (EINVAL);
+		printf("XXX %s: no I/O SAPIC -- can't setup IRQ %u\n",
+		    __func__, irq);
+		return (0);
 	}
 
 	if (xiv == 0) {

Modified: projects/altix/sys/ia64/ia64/machdep.c
==============================================================================
--- projects/altix/sys/ia64/ia64/machdep.c	Sat Apr 17 02:28:24 2010	(r206719)
+++ projects/altix/sys/ia64/ia64/machdep.c	Sat Apr 17 02:28:28 2010	(r206720)
@@ -174,6 +174,70 @@ struct kva_md_info kmi;
 #define	Mhz	1000000L
 #define	Ghz	(1000L*Mhz)
 
+#define	SN_SAL_SET_OS_FEATURE_SET	0x02000066
+
+#define	OSF_ACPI_ENABLE		2
+#define	OSF_PCISEGMENT_ENABLE	3
+
+#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/actables.h>
+#include <dev/acpica/acpivar.h>
+
+static void
+srat_dump_entry(ACPI_SUBTABLE_HEADER *entry, void *arg)
+{
+	ACPI_SRAT_CPU_AFFINITY *cpu;
+	ACPI_SRAT_MEM_AFFINITY *mem;
+	uint32_t domain;
+	uint16_t sapicid;
+
+	switch (entry->Type) {
+	case ACPI_SRAT_TYPE_CPU_AFFINITY:
+		cpu = (ACPI_SRAT_CPU_AFFINITY *)entry;
+		domain = cpu->ProximityDomainLo |
+		    cpu->ProximityDomainHi[0] << 8 |
+		    cpu->ProximityDomainHi[1] << 16 |
+		    cpu->ProximityDomainHi[2] << 24;
+		sapicid = (cpu->ApicId << 8) | cpu->LocalSapicEid;
+		printf("SRAT: Sapic ID %u domain %d: %s\n", sapicid, domain,
+		    (cpu->Flags & ACPI_SRAT_CPU_ENABLED) ? "enabled" :
+		    "disabled");
+		break;
+	case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
+		mem = (ACPI_SRAT_MEM_AFFINITY *)entry;
+		printf("SRAT: memory domain %d addr %lx len %lx: %s\n",
+		    mem->ProximityDomain, mem->BaseAddress, mem->Length,
+		    (mem->Flags & ACPI_SRAT_MEM_ENABLED) ? "enabled" :
+		    "disabled");
+		break;
+	default:
+		printf("SRAT: unknown type (%u)\n", entry->Type);
+		break;
+	}
+}
+
+static void
+check_sn_sal(void)
+{
+	struct ia64_sal_result r;
+	ACPI_TABLE_HEADER *tbl;
+	void *ptr;
+
+	r = ia64_sal_entry(SAL_SGISN_SN_INFO, 0, 0, 0, 0, 0, 0, 0);
+	printf("XXX: %s: stat=%ld, res0=%#lx, res1=%#lx, res2=%#lx\n",
+	    __func__, r.sal_status, r.sal_result[0], r.sal_result[1],
+	    r.sal_result[2]);
+	if (r.sal_status != 0)
+		return;
+
+	tbl = ptr = acpi_find_table(ACPI_SIG_SRAT);
+	printf("XXX: %s: SRAT table at %p\n", __func__, ptr);
+	acpi_walk_subtables((char *)ptr + sizeof(ACPI_TABLE_SRAT), 
+	    (char *)ptr + tbl->Length, srat_dump_entry, ptr);
+	tbl = acpi_find_table(ACPI_SIG_SLIT);
+	printf("XXX: %s: SLIT table at %p\n", __func__, tbl);
+}
+
 static void
 identifycpu(void)
 {
@@ -509,6 +573,22 @@ cpu_pcpu_init(struct pcpu *pcpu, int cpu
 }
 
 void
+cpu_pcpu_setup(struct pcpu *pc, u_int acpi_id, u_int sapic_id)
+{
+	struct ia64_sal_result r;
+
+	pc->pc_acpi_id = acpi_id;
+	pc->pc_md.lid = IA64_LID_SET_SAPIC_ID(sapic_id);
+
+	r = ia64_sal_entry(SAL_SGISN_SAPIC_INFO, sapic_id, 0, 0, 0, 0, 0, 0);
+	if (r.sal_status == 0) {
+		pc->pc_md.sgisn_nasid = r.sal_result[0];
+		pc->pc_md.sgisn_subnode = r.sal_result[1];
+		pc->pc_md.sgisn_slice = r.sal_result[2];
+	}
+}
+ 
+void
 spinlock_enter(void)
 {
 	struct thread *td;
@@ -745,16 +825,11 @@ ia64_init(void)
 	ia64_set_k4((u_int64_t)pcpup);
 	pcpu_init(pcpup, 0, sizeof(pcpu0));
 	dpcpu_init((void *)kernend, 0);
+	cpu_pcpu_setup(pcpup, ~0U, ia64_get_lid());
 	kernend += DPCPU_SIZE;
 	PCPU_SET(curthread, &thread0);
 
-	/*
-	 * Initialize the console before we print anything out.
-	 */
-	cninit();
-
-	/* OUTPUT NOW ALLOWED */
-
+#if 0
 	if (ia64_pal_base != 0) {
 		ia64_pal_base &= ~IA64_ID_PAGE_MASK;
 		/*
@@ -765,6 +840,7 @@ ia64_init(void)
 			printf("PAL code mapped by the kernel's TR\n");
 	} else
 		printf("PAL code not found\n");
+#endif
 
 	/*
 	 * Wire things up so we can call the firmware.
@@ -775,9 +851,18 @@ ia64_init(void)
 	ia64_sal_init();
 	calculate_frequencies();
 
+	/*
+	 * Initialize the console before we print anything out.
+	 */
+	cninit();
+
+	/* OUTPUT NOW ALLOWED */
+
 	if (metadata_missing)
 		printf("WARNING: loader(8) metadata is missing!\n");
 
+	check_sn_sal();
+
 	/* Get FPSWA interface */
 	fpswa_iface = (bootinfo.bi_fpswa == 0) ? NULL :
 	    (struct fpswa_iface *)IA64_PHYS_TO_RR7(bootinfo.bi_fpswa);

Modified: projects/altix/sys/ia64/ia64/mp_machdep.c
==============================================================================
--- projects/altix/sys/ia64/ia64/mp_machdep.c	Sat Apr 17 02:28:24 2010	(r206719)
+++ projects/altix/sys/ia64/ia64/mp_machdep.c	Sat Apr 17 02:28:28 2010	(r206720)
@@ -66,11 +66,9 @@ MALLOC_DEFINE(M_SMP, "SMP", "SMP related
 
 void ia64_ap_startup(void);
 
-#define	LID_SAPIC(x)		((u_int)((x) >> 16))
-#define	LID_SAPIC_ID(x)		((u_int)((x) >> 24) & 0xff)
-#define	LID_SAPIC_EID(x)	((u_int)((x) >> 16) & 0xff)
-#define	LID_SAPIC_SET(id,eid)	(((id & 0xff) << 8 | (eid & 0xff)) << 16);
-#define	LID_SAPIC_MASK		0xffff0000UL
+#define	SAPIC_ID_GET_ID(x)	((u_int)((x) >> 8) & 0xff)
+#define	SAPIC_ID_GET_EID(x)	((u_int)(x) & 0xff)
+#define	SAPIC_ID_SET(id, eid)	((u_int)(((id) & 0xff) << 8) | ((eid) & 0xff))
 
 /* Variables used by os_boot_rendez and ia64_ap_startup */
 struct pcpu *ap_pcpu;
@@ -251,18 +249,18 @@ cpu_mp_probe(void)
 }
 
 void
-cpu_mp_add(u_int acpiid, u_int apicid, u_int apiceid)
+cpu_mp_add(u_int acpi_id, u_int id, u_int eid)
 {
 	struct pcpu *pc;
-	u_int64_t lid;
 	void *dpcpu;
-	u_int cpuid;
+	u_int cpuid, sapic_id;
 
-	lid = LID_SAPIC_SET(apicid, apiceid);
-	cpuid = ((ia64_get_lid() & LID_SAPIC_MASK) == lid) ? 0 : smp_cpus++;
+	sapic_id = SAPIC_ID_SET(id, eid);
+	cpuid = (IA64_LID_GET_SAPIC_ID(ia64_get_lid()) == sapic_id)
+	    ? 0 : smp_cpus++;
 
 	KASSERT((all_cpus & (1UL << cpuid)) == 0,
-	    ("%s: cpu%d already in CPU map", __func__, acpiid));
+	    ("%s: cpu%d already in CPU map", __func__, acpi_id));
 
 	if (cpuid != 0) {
 		pc = (struct pcpu *)malloc(sizeof(*pc), M_SMP, M_WAITOK);
@@ -272,23 +270,25 @@ cpu_mp_add(u_int acpiid, u_int apicid, u
 	} else
 		pc = pcpup;
 
-	pc->pc_acpi_id = acpiid;
-	pc->pc_md.lid = lid;
-	all_cpus |= (1UL << cpuid);
+	cpu_pcpu_setup(pc, acpi_id, sapic_id);
+ 
+	all_cpus |= (1UL << pc->pc_cpuid);
 }
 
 void
 cpu_mp_announce()
 {
 	struct pcpu *pc;
+	uint32_t sapic_id;
 	int i;
 
 	for (i = 0; i <= mp_maxid; i++) {
 		pc = pcpu_find(i);
 		if (pc != NULL) {
+			sapic_id = IA64_LID_GET_SAPIC_ID(pc->pc_md.lid);
 			printf("cpu%d: ACPI Id=%x, SAPIC Id=%x, SAPIC Eid=%x",
-			    i, pc->pc_acpi_id, LID_SAPIC_ID(pc->pc_md.lid),
-			    LID_SAPIC_EID(pc->pc_md.lid));
+			    i, pc->pc_acpi_id, SAPIC_ID_GET_ID(sapic_id),
+			    SAPIC_ID_GET_EID(sapic_id));
 			if (i == 0)
 				printf(" (BSP)\n");
 			else
@@ -420,21 +420,19 @@ ipi_all_but_self(int ipi)
 }
 
 /*
- * Send an IPI to the specified processor. The lid parameter holds the
- * cr.lid (CR64) contents of the target processor. Only the id and eid
- * fields are used here.
+ * Send an IPI to the specified processor.
  */
 void
 ipi_send(struct pcpu *cpu, int xiv)
 {
-	u_int lid;
+	u_int sapic_id;
 
 	KASSERT(xiv != 0, ("ipi_send"));
 
-	lid = LID_SAPIC(cpu->pc_md.lid);
+	sapic_id = IA64_LID_GET_SAPIC_ID(cpu->pc_md.lid);
 
 	ia64_mf();
-	ia64_st8(&(ia64_pib->ib_ipi[lid][0]), xiv);
+	ia64_st8(&(ia64_pib->ib_ipi[sapic_id][0]), xiv);
 	ia64_mf_a();
 	CTR3(KTR_SMP, "ipi_send(%p, %d): cpuid=%d", cpu, xiv, PCPU_GET(cpuid));
 }

Modified: projects/altix/sys/ia64/include/ia64_cpu.h
==============================================================================
--- projects/altix/sys/ia64/include/ia64_cpu.h	Sat Apr 17 02:28:24 2010	(r206719)
+++ projects/altix/sys/ia64/include/ia64_cpu.h	Sat Apr 17 02:28:28 2010	(r206720)
@@ -31,6 +31,12 @@
 #define _MACHINE_IA64_CPU_H_
 
 /*
+ * Local Interrupt ID.
+ */
+#define	IA64_LID_GET_SAPIC_ID(x)	((u_int)((x) >> 16) & 0xffff)
+#define	IA64_LID_SET_SAPIC_ID(x)	((u_int)((x) & 0xffff) << 16)
+
+/*
  * Definition of DCR bits.
  */
 #define	IA64_DCR_PP		0x0000000000000001

Modified: projects/altix/sys/ia64/include/md_var.h
==============================================================================
--- projects/altix/sys/ia64/include/md_var.h	Sat Apr 17 02:28:24 2010	(r206719)
+++ projects/altix/sys/ia64/include/md_var.h	Sat Apr 17 02:28:28 2010	(r206720)
@@ -61,6 +61,7 @@ ia64_bsp_adjust(uint64_t bsp, int nslots
 #ifdef _KERNEL
 
 struct _special;
+struct pcpu;
 struct thread;
 struct trapframe;
 
@@ -76,9 +77,11 @@ extern uint64_t ia64_lapic_addr;
 
 extern long Maxmem;
 
+void	*acpi_find_table(const char *sig);
 void	busdma_swi(void);
 int	copyout_regstack(struct thread *, uint64_t *, uint64_t *);
 void	cpu_mp_add(u_int, u_int, u_int);
+void	cpu_pcpu_setup(struct pcpu *, u_int, u_int);
 int	do_ast(struct trapframe *);
 void	ia32_trap(int, struct trapframe *);
 int	ia64_count_cpus(void);

Modified: projects/altix/sys/ia64/include/pcpu.h
==============================================================================
--- projects/altix/sys/ia64/include/pcpu.h	Sat Apr 17 02:28:24 2010	(r206719)
+++ projects/altix/sys/ia64/include/pcpu.h	Sat Apr 17 02:28:28 2010	(r206720)
@@ -52,6 +52,9 @@ struct pcpu_md {
 	uint64_t	lid;			/* local CPU ID */
 	uint64_t	clock;			/* Clock counter. */
 	uint64_t	clockadj;		/* Clock adjust. */
+	uint32_t	sgisn_nasid;
+	uint32_t	sgisn_subnode;
+	uint32_t	sgisn_slice;
 	uint32_t	awake:1;		/* CPU is awake? */
 	struct pcpu_stats stats;		/* Interrupt stats. */
 #ifdef _KERNEL

Modified: projects/altix/sys/ia64/include/sal.h
==============================================================================
--- projects/altix/sys/ia64/include/sal.h	Sat Apr 17 02:28:24 2010	(r206719)
+++ projects/altix/sys/ia64/include/sal.h	Sat Apr 17 02:28:28 2010	(r206720)
@@ -114,10 +114,13 @@ struct sal_ap_wakeup_descriptor {
 #define SAL_FREQ_BASE		0x01000012
 #define SAL_UPDATE_PAL		0x01000020
 
-#define	SAL_SGISN_INFO		0x0200001e
+#define	SAL_SGISN_SAPIC_INFO	0x0200001d
+#define	SAL_SGISN_SN_INFO	0x0200001e
 #define	SAL_SGISN_PUTC		0x02000021
 #define	SAL_SGISN_GETC		0x02000022
 #define	SAL_SGISN_POLL		0x02000026
+#define	SAL_SGISN_IOHUB_INFO	0x02000055
+#define	SAL_SGISN_IOBUS_INFO	0x02000056
 
 /* SAL_SET_VECTORS event handler types */
 #define	SAL_OS_MCA		0

Added: projects/altix/sys/ia64/include/sgisn.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/altix/sys/ia64/include/sgisn.h	Sat Apr 17 02:28:28 2010	(r206720)
@@ -0,0 +1,105 @@
+/*-
+ * Copyright (c) 2010 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * 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 AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD$
+ */
+#ifndef _MACHINE_SGISN_H_
+#define _MACHINE_SGISN_H_
+
+#define	SGISN_GEOID_MODULE(id)		(((id) >> 0) & 0xffffffffu)
+#define	SGISN_GEOID_TYPE(id)		(((id) >> 32) & 0xff)
+#define	SGISN_GEOID_SLAB(id)		(((id) >> 40) & 0xff)
+#define	SGISN_GEOID_ADDIT(id)		(((id) >> 48) & 0xffff);
+#define	SGISN_GEOID_CPU_SLICE(id)	((SGISN_GEOID_ADDIT(id) >> 0) & 0xff)
+#define	SGISN_GEOID_DEV_BUS(id)		((SGISN_GEOID_ADDIT(id) >> 0) & 0xff)
+#define	SGISN_GEOID_DEV_SLOT(id)	((SGISN_GEOID_ADDIT(id) >> 8) & 0xff)
+#define	SGISN_GEOID_MEM_BUS(id)		((SGISN_GEOID_ADDIT(id) >> 0) & 0xff)
+#define	SGISN_GEOID_MEM_SLOT(id)	((SGISN_GEOID_ADDIT(id) >> 8) & 0xff)
+
+#define	SGISN_GEO_TYPE_INVALID	0
+#define	SGISN_GEO_TYPE_MODULE	1
+#define	SGISN_GEO_TYPE_NODE	2
+#define	SGISN_GEO_TYPE_RTR	3
+#define	SGISN_GEO_TYPE_IOC	4
+#define	SGISN_GEO_TYPE_DEV	5	/* PCI device */
+#define	SGISN_GEO_TYPE_CPU	6
+#define	SGISN_GEO_TYPE_MEM	7
+
+#define	SGISN_HUB_NITTES	8
+#define	SGISN_HUB_NWIDGETS	16
+
+struct sgisn_widget {
+	uint32_t		wgt_hwmfg;
+	uint32_t		wgt_hwrev;
+	uint32_t		wgt_hwpn;
+	uint8_t			wgt_port;
+	char	_pad[3];
+	uint64_t		wgt_private;
+	uint64_t		wgt_provider;
+	uint64_t		wgt_vertex;
+};
+
+struct sgisn_hub {
+	uint64_t		hub_geoid;
+	uint16_t		hub_nasid;
+	uint16_t		hub_peer_nasid;
+	char	_pad[4];
+	uint64_t		hub_pointer;
+	uint64_t		hub_dma_itte[SGISN_HUB_NITTES];
+	struct sgisn_widget	hub_widget[SGISN_HUB_NWIDGETS];
+
+	void	*hdi_nodepda;
+	void	*hdi_node_vertex;
+
+	uint32_t		hub_pci_maxseg;
+	uint32_t		hub_pci_maxbus;
+};
+
+struct sgisn_irq {
+	uint64_t		irq_unused;
+	uint16_t		irq_nasid;
+	char	_pad1[2];
+	u_int			irq_slice;
+	u_int			irq_cpuid;
+	u_int			irq_no;
+	u_int			irq_pin;
+	uint64_t		irq_xtaddr;
+	u_int			irq_br_type;
+	char	_pad2[4];
+	uint64_t		irq_bridge;
+	uint64_t		irq_io_info;
+	u_int			irq_last;
+	u_int			irq_cookie;
+	u_int			irq_flags;
+	u_int			irq_refcnt;
+};
+
+struct sgisn_dev {
+	uint64_t		dev_bar[6];
+	uint64_t		dev_rom;
+	uint64_t		dev_handle;
+};
+
+#endif /* !_MACHINE_SGISN_H_ */

Modified: projects/altix/sys/ia64/pci/pci_cfgreg.c
==============================================================================
--- projects/altix/sys/ia64/pci/pci_cfgreg.c	Sat Apr 17 02:28:24 2010	(r206719)
+++ projects/altix/sys/ia64/pci/pci_cfgreg.c	Sat Apr 17 02:28:28 2010	(r206720)
@@ -70,7 +70,7 @@ pci_cfgregread(int bus, int slot, int fu
 	register_t is;
 	u_long addr;
 
-	addr = pci_sal_address(0, bus, slot, func, reg);
+	addr = pci_sal_address(bus >> 8, bus & 0xff, slot, func, reg);
 	if (addr == ~0ul)
 		return (~0);
 
@@ -91,7 +91,7 @@ pci_cfgregwrite(int bus, int slot, int f
 	register_t is;
 	u_long addr;
 
-	addr = pci_sal_address(0, bus, slot, func, reg);
+	addr = pci_sal_address(bus >> 8, bus & 0xff, slot, func, reg);
 	if (addr == ~0ul)
 		return;
 

Added: projects/altix/sys/ia64/sgisn/sgisn_pcib.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/altix/sys/ia64/sgisn/sgisn_pcib.c	Sat Apr 17 02:28:28 2010	(r206720)
@@ -0,0 +1,212 @@
+/*-
+ * Copyright (c) 2010 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * 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 AUTHOR 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 AUTHOR 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/pcpu.h>
+
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcib_private.h>
+
+#include "pcib_if.h"
+
+#include <machine/pci_cfgreg.h>
+#include <machine/sal.h>
+#include <machine/sgisn.h>
+
+static struct sgisn_hub sgisn_pcib_hub;
+
+struct sgisn_pcib_softc {
+	device_t	sc_dev;
+	u_int		sc_busnr;
+};
+
+static int sgisn_pcib_attach(device_t);
+static void sgisn_pcib_identify(driver_t *, device_t);
+static int sgisn_pcib_probe(device_t);
+
+static int sgisn_pcib_read_ivar(device_t, device_t, int, uintptr_t *);
+static int sgisn_pcib_write_ivar(device_t, device_t, int, uintptr_t);
+
+static int sgisn_pcib_maxslots(device_t);
+static uint32_t sgisn_pcib_cfgread(device_t, u_int, u_int, u_int, u_int, int);
+static void sgisn_pcib_cfgwrite(device_t, u_int, u_int, u_int, u_int, uint32_t,
+    int);
+
+/*
+ * Bus interface definitions.
+ */
+static device_method_t sgisn_pcib_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_identify,	sgisn_pcib_identify),
+	DEVMETHOD(device_probe,		sgisn_pcib_probe),
+	DEVMETHOD(device_attach,	sgisn_pcib_attach),
+
+	/* Bus interface */
+        DEVMETHOD(bus_read_ivar,	sgisn_pcib_read_ivar),
+        DEVMETHOD(bus_write_ivar,	sgisn_pcib_write_ivar),
+	DEVMETHOD(bus_print_child,	bus_generic_print_child),
+	DEVMETHOD(bus_alloc_resource,	bus_generic_alloc_resource),
+	DEVMETHOD(bus_release_resource,	bus_generic_release_resource),
+	DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+	DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+	DEVMETHOD(bus_setup_intr,	bus_generic_setup_intr),
+	DEVMETHOD(bus_teardown_intr,	bus_generic_teardown_intr),
+
+	/* pcib interface */
+	DEVMETHOD(pcib_maxslots,	sgisn_pcib_maxslots),
+	DEVMETHOD(pcib_read_config,	sgisn_pcib_cfgread),
+	DEVMETHOD(pcib_write_config,	sgisn_pcib_cfgwrite),
+	DEVMETHOD(pcib_route_interrupt,	pcib_route_interrupt),
+
+	{ 0, 0 }
+};
+
+static driver_t sgisn_pcib_driver = {
+	"pcib",
+	sgisn_pcib_methods,
+	sizeof(struct sgisn_pcib_softc),
+};
+
+devclass_t pcib_devclass;
+
+DRIVER_MODULE(pcib, nexus, sgisn_pcib_driver, pcib_devclass, 0, 0);
+
+static int
+sgisn_pcib_maxslots(device_t dev)
+{
+
+	return (31);
+}
+
+static uint32_t
+sgisn_pcib_cfgread(device_t dev, u_int bus, u_int slot, u_int func,
+    u_int reg, int bytes)
+{
+	u_int domain = device_get_unit(dev);
+	uint32_t val;
+
+	device_printf(dev, "%u:%u:%u: reg=%u", bus, slot, func, reg);
+	val = pci_cfgregread(domain << 8 | bus, slot, func, reg, bytes);
+	printf(" -> %u (%u bytes)\n", val, bytes);
+	return (val);
+}
+
+static void
+sgisn_pcib_cfgwrite(device_t dev, u_int bus, u_int slot, u_int func,
+    u_int reg, uint32_t val, int bytes)
+{
+	u_int domain = device_get_unit(dev);
+
+	device_printf(dev, "%u:%u:%u: reg=%u <- %u (%u bytes)\n", bus, slot,
+	    func, reg, val, bytes);
+	pci_cfgregwrite(domain << 8 | bus, slot, func, reg, val, bytes);
+}
+
+static void
+sgisn_pcib_identify(driver_t *drv, device_t bus)
+{
+	struct ia64_sal_result r;
+	void *addr;
+	u_int seg;
+
+	sgisn_pcib_hub.hub_pci_maxseg = 0xffffffff;
+	sgisn_pcib_hub.hub_pci_maxbus = 0xff;
+	r = ia64_sal_entry(SAL_SGISN_IOHUB_INFO, PCPU_GET(md.sgisn_nasid),
+	    ia64_tpa((uintptr_t)&sgisn_pcib_hub), 0, 0, 0, 0, 0);
+	if (r.sal_status != 0)
+		return;
+
+	printf("XXX: %s: maxseg=%u, maxbus=%u\n", __func__,
+	    sgisn_pcib_hub.hub_pci_maxseg, sgisn_pcib_hub.hub_pci_maxbus);
+
+	for (seg = 0; seg <= sgisn_pcib_hub.hub_pci_maxseg; seg++) {
+		r = ia64_sal_entry(SAL_SGISN_IOBUS_INFO, seg, 0,
+		    ia64_tpa((uintptr_t)&addr), 0, 0, 0, 0);
+
+		printf("XXX: %s: seg=%u: stat=%#lx, addr=%p\n", __func__, seg,
+		    r.sal_status, addr);
+
+		if (r.sal_status == 0)
+			BUS_ADD_CHILD(bus, 100 + seg, drv->name, seg);
+	}
+}
+
+static int
+sgisn_pcib_probe(device_t dev)
+{
+
+	device_set_desc(dev, "SGI PCI-X host controller");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+sgisn_pcib_attach(device_t dev)
+{
+	struct sgisn_pcib_softc *sc;
+
+	sc = device_get_softc(dev);
+	sc->sc_dev = dev;
+
+	device_add_child(dev, "pci", -1);
+	return (bus_generic_attach(dev));
+}
+
+static int
+sgisn_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *res)
+{
+	struct sgisn_pcib_softc *sc = device_get_softc(dev);
+
+	switch (which) {
+	case PCIB_IVAR_BUS:
+		*res = sc->sc_busnr;
+		return (0);
+	case PCIB_IVAR_DOMAIN:
+		*res = device_get_unit(dev);
+		return (0);
+	}
+	return (ENOENT);
+}
+
+static int
+sgisn_pcib_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
+{
+	struct sgisn_pcib_softc *sc = device_get_softc(dev);
+
+	switch (which) {
+	case PCIB_IVAR_BUS:
+		sc->sc_busnr = value;
+		return (0);
+	}
+	return (ENOENT);
+}


More information about the svn-src-projects mailing list