Skip to contentSkip to conversation

ppc64: Introduce BPA platform

PATCH In review Arnd Bergmann 6 participants 15 messages Apr 28, 2005 – Apr 29, 2005

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

cover ppc64: Introduce BPA platform

This series of patches add support for a fifth platform type in the ppc64 architecture tree. The Broadband Processor Architecture (BPA) is currently used in a single machine from IBM, with others likely to be added at a later point.

I already sent preparation patches before, these need to be applied on top of them.
The first three patches add the actual platform code, which should be usable for any BPA compatible implementation.

The final patch introduces a new file system to make use of the SPUs inside the processors. This patch is still in a prototype stage and not intended for merging yet.

	Arnd <><
#1 lore raw

PATCH 1/4 ppc64: add BPA platform type

This adds the basic support for running on BPA machines.

It should be possible to configure a kernel for any combination of CONFIG_PPC_BPA with any of the other multiplatform targets.

MAINTAINERS +7 -0
Index: linus-2.5/MAINTAINERS
===================================================================
@@ -493,6 +493,13 @@
 W:   http://sourceforge.net/projects/bonding/
 S:   Supported
 
+BROADBAND PROCESSOR ARCHITECTURE
+P:	Arnd Bergmann
+M:	[email protected]
+L:	[email protected]
+W:	http://linuxppc64.org
+S:	Supported
+
 BTTV VIDEO4LINUX DRIVER
 P:	Gerd Knorr
 M:	[email protected]
arch/ppc64/Kconfig +5 -1
Index: linus-2.5/arch/ppc64/Kconfig
===================================================================
@@ -73,6 +73,10 @@
 	bool "  IBM pSeries & new iSeries"
 	default y
 
+config PPC_BPA
+	bool "  Broadband Processor Architecture"
+	depends on PPC_MULTIPLATFORM
+
 config PPC_PMAC
 	depends on PPC_MULTIPLATFORM
 	bool "  Apple G5 based machines"
@@ -252,7 +256,7 @@
 
 config PPC_RTAS
 	bool
-	depends on PPC_PSERIES
+	depends on PPC_PSERIES || PPC_BPA
 	default y
 
 config RTAS_PROC
arch/ppc64/Makefile +2 -0
Index: linus-2.5/arch/ppc64/Makefile
===================================================================
@@ -83,12 +83,14 @@
 boottarget-$(CONFIG_PPC_PSERIES) := zImage zImage.initrd
 boottarget-$(CONFIG_PPC_MAPLE) := zImage zImage.initrd
 boottarget-$(CONFIG_PPC_ISERIES) := vmlinux.sminitrd vmlinux.initrd vmlinux.sm
+boottarget-$(CONFIG_PPC_BPA) := zImage zImage.initrd
 $(boottarget-y): vmlinux
 	$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
 
 bootimage-$(CONFIG_PPC_PSERIES) := $(boot)/zImage
 bootimage-$(CONFIG_PPC_PMAC) := vmlinux
 bootimage-$(CONFIG_PPC_MAPLE) := $(boot)/zImage
+bootimage-$(CONFIG_PPC_BPA) := zImage
 bootimage-$(CONFIG_PPC_ISERIES) := vmlinux
 BOOTIMAGE := $(bootimage-y)
 install: vmlinux
arch/ppc64/kernel/Makefile +3 -0
Index: linus-2.5/arch/ppc64/kernel/Makefile
===================================================================
@@ -34,6 +34,8 @@
 			     pSeries_nvram.o rtasd.o ras.o pSeries_reconfig.o \
 			     xics.o pSeries_setup.o pSeries_iommu.o
 
+obj-$(CONFIG_PPC_BPA) += bpa_setup.o bpa_nvram.o
+
 obj-$(CONFIG_EEH)		+= eeh.o
 obj-$(CONFIG_PROC_FS)		+= proc_ppc64.o
 obj-$(CONFIG_RTAS_FLASH)	+= rtas_flash.o
@@ -60,6 +62,7 @@
 obj-$(CONFIG_PPC_PMAC)		+= pmac_smp.o smp-tbsync.o
 obj-$(CONFIG_PPC_ISERIES)	+= iSeries_smp.o
 obj-$(CONFIG_PPC_PSERIES)	+= pSeries_smp.o
+obj-$(CONFIG_PPC_BPA)		+= pSeries_smp.o
 obj-$(CONFIG_PPC_MAPLE)		+= smp-tbsync.o
 endif
 
arch/ppc64/kernel/bpa_setup.c new file +207 -0

207 lines not on this page · raw message

arch/ppc64/kernel/cpu_setup_power4.S +15 -1
Index: linus-2.5/arch/ppc64/kernel/cpu_setup_power4.S
===================================================================
@@ -73,7 +73,21 @@
 
 _GLOBAL(__setup_cpu_power4)
 	blr
-	
+
+_GLOBAL(__setup_cpu_be)
+        /* Set large page sizes LP=0: 16MB, LP=1: 64KB */
+        addi    r3, 0,  0
+        ori     r3, r3, HID6_LB
+        sldi    r3, r3, 32
+        nor     r3, r3, r3
+        mfspr   r4, SPRN_HID6
+        and     r4, r4, r3
+        addi    r3, 0, 0x02000
+        sldi    r3, r3, 32
+        or      r4, r4, r3
+        mtspr   SPRN_HID6, r4
+	blr
+
 _GLOBAL(__setup_cpu_ppc970)
 	mfspr	r0,SPRN_HID0
 	li	r11,5			/* clear DOZE and SLEEP */
arch/ppc64/kernel/cputable.c +11 -0
Index: linus-2.5/arch/ppc64/kernel/cputable.c
===================================================================
@@ -34,6 +34,7 @@
 extern void __setup_cpu_power3(unsigned long offset, struct cpu_spec* spec);
 extern void __setup_cpu_power4(unsigned long offset, struct cpu_spec* spec);
 extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec);
+extern void __setup_cpu_be(unsigned long offset, struct cpu_spec* spec);
 
 
 /* We only set the altivec features if the kernel was compiled with altivec
@@ -162,6 +163,16 @@
 	    __setup_cpu_power4,
 	    COMMON_PPC64_FW
     },
+    {	/* BE DD1.x  */
+	    0xffff0000, 0x00700000, "Broadband Engine",
+	    CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
+		    CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP |
+		    CPU_FTR_SMT,
+	    COMMON_USER_PPC64 | PPC_FEATURE_HAS_ALTIVEC_COMP,
+	    128, 128,
+	    __setup_cpu_be,
+	    COMMON_PPC64_FW
+    },
     {	/* default match */
 	    0x00000000, 0x00000000, "POWER4 (compatible)",
   	    CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
arch/ppc64/kernel/irq.c +3 -0
Index: linus-2.5/arch/ppc64/kernel/irq.c
===================================================================
@@ -395,6 +395,9 @@
 	if (ppc64_interrupt_controller == IC_OPEN_PIC)
 		return real_irq;	/* no mapping for openpic (for now) */
 
+	if (ppc64_interrupt_controller == IC_BPA_IIC)
+		return real_irq;	/* no mapping for iic either */
+
 	/* don't map interrupts < MIN_VIRT_IRQ */
 	if (real_irq < MIN_VIRT_IRQ) {
 		virt_irq_to_real_map[real_irq] = real_irq;
arch/ppc64/kernel/proc_ppc64.c +1 -1
Index: linus-2.5/arch/ppc64/kernel/proc_ppc64.c
===================================================================
@@ -53,7 +53,7 @@
 	if (!root)
 		return 1;
 
-	if (!(systemcfg->platform & PLATFORM_PSERIES))
+	if (!(systemcfg->platform & (PLATFORM_PSERIES | PLATFORM_BPA)))
 		return 0;
 
 	if (!proc_mkdir("rtas", root))
arch/ppc64/kernel/prom_init.c +2 -2
Index: linus-2.5/arch/ppc64/kernel/prom_init.c
===================================================================
@@ -1731,9 +1731,9 @@
 		     &getprop_rval, sizeof(getprop_rval));
 
 	/*
-	 * On pSeries, copy the CPU hold code
+	 * On pSeries and BPA, copy the CPU hold code
 	 */
-       	if (RELOC(of_platform) & PLATFORM_PSERIES)
+       	if (RELOC(of_platform) & (PLATFORM_PSERIES | PLATFORM_BPA))
        		copy_and_flush(0, KERNELBASE - offset, 0x100, 0);
 
 	/*
arch/ppc64/kernel/setup.c +4 -0
Index: linus-2.5/arch/ppc64/kernel/setup.c
===================================================================
@@ -348,6 +348,7 @@
 extern struct machdep_calls pSeries_md;
 extern struct machdep_calls pmac_md;
 extern struct machdep_calls maple_md;
+extern struct machdep_calls bpa_md;
 
 /* Ultimately, stuff them in an elf section like initcalls... */
 static struct machdep_calls __initdata *machines[] = {
@@ -360,6 +361,9 @@
 #ifdef CONFIG_PPC_MAPLE
 	&maple_md,
 #endif /* CONFIG_PPC_MAPLE */
+#ifdef CONFIG_PPC_BPA
+	&bpa_md,
+#endif
 	NULL
 };
 
arch/ppc64/kernel/traps.c +4 -0
Index: linus-2.5/arch/ppc64/kernel/traps.c
===================================================================
@@ -126,6 +126,10 @@
 			printk("POWERMAC ");
 			nl = 1;
 			break;
+		case PLATFORM_BPA:
+			printk("BPA ");
+			nl = 1;
+			break;
 	}
 	if (nl)
 		printk("\n");
include/asm-ppc64/mmu.h +2 -0
Index: linus-2.5/include/asm-ppc64/mmu.h
===================================================================
@@ -196,6 +196,8 @@
 #define SLB_VSID_N		0x0000000000000200	/* no-execute */
 #define SLB_VSID_L		0x0000000000000100	/* largepage (4M) */
 #define SLB_VSID_C		0x0000000000000080	/* class */
+#define SLB_VSID_LS		0x0000000000000070	/* LS if 1, then second
+							   large page size */
 
 #define SLB_VSID_KERNEL		(SLB_VSID_KP|SLB_VSID_C)
 #define SLB_VSID_USER		(SLB_VSID_KP|SLB_VSID_KS)
include/asm-ppc64/processor.h +15 -4
Index: linus-2.5/include/asm-ppc64/processor.h
===================================================================
@@ -217,14 +217,22 @@
 #define   HID0_ABE	(1<<3)		/* Address Broadcast Enable */
 #define	  HID0_BHTE	(1<<2)		/* Branch History Table Enable */
 #define	  HID0_BTCD	(1<<1)		/* Branch target cache disable */
+#define	SPRN_HID6	0x3F9	/* Hardware Implementation Register 6 */
+#define	  HID6_LB	(0x0F<<12)	/* Concurrent Large Page Modes */
+#define	  HID6_DLP	(1<<20)		/* Disable all large page modes (4K only) */
 #define	SPRN_MSRDORM	0x3F1	/* Hardware Implementation Register 1 */
 #define SPRN_HID1	0x3F1	/* Hardware Implementation Register 1 */
 #define	SPRN_IABR	0x3F2	/* Instruction Address Breakpoint Register */
 #define	SPRN_NIADORM	0x3F3	/* Hardware Implementation Register 2 */
 #define SPRN_HID4	0x3F4	/* 970 HID4 */
 #define SPRN_HID5	0x3F6	/* 970 HID5 */
-#define	SPRN_TSC 	0x3FD	/* Thread switch control */
-#define	SPRN_TST 	0x3FC	/* Thread switch timeout */
+#define	SPRN_TSCR	0x399   /* Thread switch control on BE */
+#define	SPRN_TTR	0x39A   /* Thread switch timeout on BE */
+#define	  TSCR_DEC_ENABLE	0x200000 /* Decrementer Interrupt */
+#define	  TSCR_EE_ENABLE	0x100000 /* External Interrupt */
+#define	  TSCR_EE_BOOST		0x080000 /* External Interrupt Boost */
+#define	SPRN_TSC 	0x3FD	/* Thread switch control on others */
+#define	SPRN_TST 	0x3FC	/* Thread switch timeout on others */
 #define	SPRN_IAC1	0x3F4	/* Instruction Address Compare 1 */
 #define	SPRN_IAC2	0x3F5	/* Instruction Address Compare 2 */
 #define	SPRN_ICCR	0x3FB	/* Instruction Cache Cacheability Register */
@@ -411,8 +419,9 @@
 #define	PV_POWER5	0x003A
 #define PV_POWER5p	0x003B
 #define PV_970FX	0x003C
-#define	PV_630        	0x0040
-#define	PV_630p	        0x0041
+#define	PV_630		0x0040
+#define	PV_630p		0x0041
+#define	PV_BE		0x0070
 
 /* Platforms supported by PPC64 */
 #define PLATFORM_PSERIES      0x0100
@@ -421,6 +430,7 @@
 #define PLATFORM_LPAR         0x0001
 #define PLATFORM_POWERMAC     0x0400
 #define PLATFORM_MAPLE        0x0500
+#define PLATFORM_BPA          0x1000
 
 /* Compatibility with drivers coming from PPC32 world */
 #define _machine	(systemcfg->platform)
@@ -432,6 +442,7 @@
 #define IC_INVALID    0
 #define IC_OPEN_PIC   1
 #define IC_PPC_XIC    2
+#define IC_BPA_IIC    3
 
 #define XGLUE(a,b) a##b
 #define GLUE(a,b) XGLUE(a,b)
include/asm-ppc64/smp.h +8 -0
Index: linus-2.5/include/asm-ppc64/smp.h
===================================================================
@@ -85,6 +85,14 @@
 
 extern struct smp_ops_t *smp_ops;
 
+#ifdef CONFIG_PPC_PSERIES
+void vpa_init(int cpu);
+#else
+static inline void vpa_init(int cpu)
+{
+}
+#endif /* CONFIG_PPC_PSERIES */
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* !(_PPC64_SMP_H) */
#2 lore raw

PATCH 2/4 ppc64: Add driver for BPA interrupt controllers

In reply to Arnd Bergmann

Add support for the integrated interrupt controller on BPA CPUs. There is one of those for each SMT thread.

The mapping of interrupt numbers to HW interrupt sources is described in arch/ppc64/kernel/bpa_iic.h.

This version hardcodes the 'Spider' chip as the secondary interrupt controller. That is not really generic for the architecture, but at the moment it is the only secondary PIC that exists.

A little more work will be needed on this as soon as we have boards with multiple external interrupt controllers.

arch/ppc64/Kconfig +15 -0
Index: linus-2.5/arch/ppc64/Kconfig
===================================================================
@@ -106,6 +106,21 @@
 	bool
 	default y
 
+config XICS
+	depends on PPC_PSERIES
+	bool
+	default y
+
+config MPIC
+	depends on PPC_PSERIES || PPC_PMAC || PPC_MAPLE
+	bool
+	default y
+
+config BPA_IIC
+	depends on PPC_BPA
+	bool
+	default y
+
 # VMX is pSeries only for now until somebody writes the iSeries
 # exception vectors for it
 config ALTIVEC
arch/ppc64/kernel/Makefile +5 -3
Index: linus-2.5/arch/ppc64/kernel/Makefile
===================================================================
@@ -28,13 +28,13 @@
 			     mf.o HvLpEvent.o iSeries_proc.o iSeries_htab.o \
 			     iSeries_iommu.o
 
-obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o i8259.o prom_init.o prom.o mpic.o
+obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o i8259.o prom_init.o prom.o
 
 obj-$(CONFIG_PPC_PSERIES) += pSeries_pci.o pSeries_lpar.o pSeries_hvCall.o \
 			     pSeries_nvram.o rtasd.o ras.o pSeries_reconfig.o \
-			     xics.o pSeries_setup.o pSeries_iommu.o
+			     pSeries_setup.o pSeries_iommu.o
 
-obj-$(CONFIG_PPC_BPA) += bpa_setup.o bpa_nvram.o
+obj-$(CONFIG_PPC_BPA) += bpa_setup.o bpa_nvram.o bpa_iic.o spider-pic.o
 
 obj-$(CONFIG_EEH)		+= eeh.o
 obj-$(CONFIG_PROC_FS)		+= proc_ppc64.o
@@ -50,6 +50,8 @@
 obj-$(CONFIG_BOOTX_TEXT)	+= btext.o
 obj-$(CONFIG_HVCS)		+= hvcserver.o
 obj-$(CONFIG_IBMVIO)		+= vio.o
+obj-$(CONFIG_XICS)		+= xics.o
+obj-$(CONFIG_MPIC)		+= mpic.o
 
 obj-$(CONFIG_PPC_PMAC)		+= pmac_setup.o pmac_feature.o pmac_pci.o \
 				   pmac_time.o pmac_nvram.o pmac_low_i2c.o
arch/ppc64/kernel/bpa_iic.c new file +270 -0

270 lines not on this page · raw message

arch/ppc64/kernel/bpa_iic.h new file +62 -0

62 lines not on this page · raw message

arch/ppc64/kernel/bpa_setup.c +5 -1
Index: linus-2.5/arch/ppc64/kernel/bpa_setup.c
===================================================================
@@ -45,6 +45,7 @@
 #include <asm/cputable.h>
 
 #include "pci.h"
+#include "bpa_iic.h"
 
 #ifdef DEBUG
 #define DBG(fmt...) udbg_printf(fmt)
@@ -143,6 +144,9 @@
 
 static void __init bpa_setup_arch(void)
 {
+	ppc_md.init_IRQ       = iic_init_IRQ;
+	ppc_md.get_irq        = iic_get_irq;
+
 #ifdef CONFIG_SMP
 	smp_init_pSeries();
 #endif
@@ -158,7 +162,7 @@
 	/* Find and initialize PCI host bridges */
 	init_pci_config_tokens();
 	find_and_init_phbs();
-
+	spider_init_IRQ();
 #ifdef CONFIG_DUMMY_CONSOLE
 	conswitchp = &dummy_con;
 #endif
arch/ppc64/kernel/pSeries_smp.c +64 -5

117 lines not on this page · raw message

arch/ppc64/kernel/smp.c +1 -1
Index: linus-2.5/arch/ppc64/kernel/smp.c
===================================================================
@@ -71,7 +71,7 @@
 
 int smt_enabled_at_boot = 1;
 
-#ifdef CONFIG_PPC_MULTIPLATFORM
+#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE)
 void smp_mpic_message_pass(int target, int msg)
 {
 	/* make sure we're sending something that translates to an IPI */
arch/ppc64/kernel/spider-pic.c new file +191 -0

191 lines not on this page · raw message

#3 lore raw

PATCH 3/4 ppc64: Add driver for BPA iommu

In reply to Arnd Bergmann

Implementation of software load support for the BE iommu. This is very different from other iommu code on ppc64, since we only do a static mapping. The mapping is currently hardcoded but should really be read from the firmware, but they don't set up the device nodes yet.

Software load is ok as long as the DMA windows all fit below 4GB. Currently, there is a single 512MB DMA window for PCI, USB and ethernet at 0x20000000 for our RAM. No machine we have has more than 512 MB anyway, but we might want to change the firmware to use separate DMA windows for each device.

arch/ppc64/kernel/Makefile +2 -1
Index: linus-2.5/arch/ppc64/kernel/Makefile
===================================================================
@@ -34,7 +34,8 @@
 			     pSeries_nvram.o rtasd.o ras.o pSeries_reconfig.o \
 			     pSeries_setup.o pSeries_iommu.o
 
-obj-$(CONFIG_PPC_BPA) += bpa_setup.o bpa_nvram.o bpa_iic.o spider-pic.o
+obj-$(CONFIG_PPC_BPA) += bpa_setup.o bpa_iommu.o bpa_nvram.o \
+			 bpa_iic.o spider-pic.o
 
 obj-$(CONFIG_EEH)		+= eeh.o
 obj-$(CONFIG_PROC_FS)		+= proc_ppc64.o
arch/ppc64/kernel/bpa_iommu.c new file +433 -0

433 lines not on this page · raw message

arch/ppc64/kernel/bpa_iommu.h new file +6 -0
Index: linus-2.5/arch/ppc64/kernel/bpa_iommu.h
===================================================================
@@ -0,0 +1,6 @@
+#ifndef BPA_IOMMU_H
+#define BPA_IOMMU_H
+
+void bpa_init_iommu(void);
+
+#endif
arch/ppc64/kernel/bpa_setup.c +2 -1
Index: linus-2.5/arch/ppc64/kernel/bpa_setup.c
===================================================================
@@ -46,6 +46,7 @@
 
 #include "pci.h"
 #include "bpa_iic.h"
+#include "bpa_iommu.h"
 
 #ifdef DEBUG
 #define DBG(fmt...) udbg_printf(fmt)
@@ -179,7 +180,7 @@
 
 	hpte_init_native();
 
-	pci_direct_iommu_init();
+	bpa_init_iommu();
 
 	ppc64_interrupt_controller = IC_BPA_IIC;
 
#4 lore raw

Re: [PATCH 3/4] ppc64: Add driver for BPA iommu

Hi,

Some comments below.

Quoted 9 lines · Arnd Bergmann

Index: linus-2.5/arch/ppc64/kernel/bpa_iommu.c
===================================================================

arch/ppc64/kernel/bpa_iommu.c new file +3 -0
@@ -0,0 +1,433 @@
 
+/* some constants */
+enum {
+	/* segment table entries */

[...]

Quoted 1 line

+};

Hmm. I thought the benefit of enum was to be able to do type checking later on if it's a typed enum. Here you mix different definitions in the same large untyped enum declaration. Can they be moved to a bpa_iommu.h file and #defined instead?

Quoted 2 lines
arch/ppc64/kernel/bpa_iommu.c new file +2 -0
+/* cause link error for invalid use */
+extern unsigned long __ioc_invalid_page_size;

[...]

arch/ppc64/kernel/bpa_iommu.c line 160

Quoted 4 lines
arch/ppc64/kernel/bpa_iommu.c new file +4 -0
+	default: /* not a known compile time constant */
+		ps = __ioc_invalid_page_size;
+		break;
+	}

Why do we need to detect this at link time?

arch/ppc64/kernel/bpa_iommu.c line 170

Quoted 1 line
arch/ppc64/kernel/bpa_iommu.c new file +1 -0
+	nnpt++; /* XXX is this right? */

Well, does it work? :-)

arch/ppc64/kernel/bpa_iommu.c line 176

Quoted 6 lines
arch/ppc64/kernel/bpa_iommu.c new file +6 -0
+	return (ioste) {
+		.val = IOST_VALID_MASK
+			| (iostep & IOST_PT_BASE_MASK)
+			| ((nnpt << 5) & IOST_NNPT_MASK)
+			| (ps & IOST_PS_MASK)
+		};

Can you create a mk_ioste() inline instead of doing this construct?

arch/ppc64/kernel/bpa_iommu.c line 190

Quoted 11 lines
arch/ppc64/kernel/bpa_iommu.c new file +11 -0
+static inline unsigned long
+get_ioptep(ioste iost_entry, unsigned long io_address)
+{
+	unsigned long iopt_base;
+	unsigned long ps;
+	unsigned long iopt_offset;
+
+	iopt_base = iost_entry.val & IOST_PT_BASE_MASK;
+	ps        = iost_entry.val & IOST_PS_MASK;
+
+	iopt_offset = ((io_address & 0x0fffffff) >> (7 + 2 * ps)) & 0x7fff8ul;

Magic. Can we get it explained either by defines instead of constants or by a comment?

arch/ppc64/kernel/bpa_iommu.c line 217

Quoted 13 lines
arch/ppc64/kernel/bpa_iommu.c new file +13 -0
+/* compute the hashed 6 bit index for the 4-way associative pte cache */
+static inline unsigned long
+get_ioc_hash(ioste iost_entry, unsigned long io_address)
+{
+	unsigned long iopte = get_ioptep(iost_entry, io_address);
+
+	return ((iopte & 0x000000000000001f8ul) >> 3)
+	     ^ ((iopte & 0x00000000000020000ul) >> 17)
+	     ^ ((iopte & 0x00000000000010000ul) >> 15)
+	     ^ ((iopte & 0x00000000000008000ul) >> 13)
+	     ^ ((iopte & 0x00000000000004000ul) >> 11)
+	     ^ ((iopte & 0x00000000000002000ul) >> 9)
+	     ^ ((iopte & 0x00000000000001000ul) >> 7);

Can't you reverse the subword by just doing one XOR instead of 6? That's what I did for the ext2 bitops on ppc64. See
http://www.ussg.iu.edu/hypermail/linux/kernel/0408.2/1321.html

arch/ppc64/kernel/bpa_iommu.c line 241

Quoted 5 lines
arch/ppc64/kernel/bpa_iommu.c new file +5 -0
+static inline ioste
+get_iost_cache(void __iomem *base, unsigned long index)
+{
+	unsigned long __iomem *p = (base + IOC_ST_CACHE_DIR);
+	return (ioste) { in_be64(&p[index]) };

mk_ioste() would be nice here too.

Quoted 1 line

+#ifdef __KERNEL__

Are we ever not __KERNEL__?

Quoted 3 lines
arch/ppc64/kernel/bpa_iommu.c new file +3 -0
+/* initialize the iommu to support a simple linear mapping */
+static void bpa_map_iommu(void)
+{

[...]

arch/ppc64/kernel/bpa_iommu.c line 348

Quoted 1 line
arch/ppc64/kernel/bpa_iommu.c new file +1 -0
+	for (address = 0; address < 0x100000000ul; address += io_page_size) {

This looks like way more than the 512MB DMA window you mentioned in the beginning.

-Olof

#5 lore raw

Re: [PATCH 3/4] ppc64: Add driver for BPA iommu

Quoted 7 lines · Olof Johansson
Quoted 7 lines
arch/ppc64/kernel/bpa_iommu.c new file +7 -0
+/* compute the hashed 6 bit index for the 4-way associative pte cache */
+static inline unsigned long
+get_ioc_hash(ioste iost_entry, unsigned long io_address)
+{
+	unsigned long iopte = get_ioptep(iost_entry, io_address);
+
+	return ((iopte & 0x000000000000001f8ul) >> 3)
Quoted 8 lines

arch/ppc64/kernel/bpa_iommu.c line 217

Quoted 6 lines
arch/ppc64/kernel/bpa_iommu.c new file +6 -0
+	     ^ ((iopte & 0x00000000000020000ul) >> 17)
+	     ^ ((iopte & 0x00000000000010000ul) >> 15)
+	     ^ ((iopte & 0x00000000000008000ul) >> 13)
+	     ^ ((iopte & 0x00000000000004000ul) >> 11)
+	     ^ ((iopte & 0x00000000000002000ul) >> 9)
+	     ^ ((iopte & 0x00000000000001000ul) >> 7);

Can't you reverse the subword by just doing one XOR instead of 6?

Ugh, I wrote that before I had coffee. No you can't, you can just negate the value by doing the XOR. Nevermind.

-Olof

#6 lore raw

Re: [PATCH 3/4] ppc64: Add driver for BPA iommu

In reply to Olof Johansson
Quoted 11 lines · Olof Johansson
Quoted 3 lines · Arnd Bergmann
arch/ppc64/kernel/bpa_iommu.c new file +3 -0
+/* some constants */
+enum {
+	/* segment table entries */

[...]

Quoted 1 line

+};

Hmm. I thought the benefit of enum was to be able to do type checking later on if it's a typed enum. Here you mix different definitions in the same large untyped enum declaration. Can they be moved to a bpa_iommu.h file and #defined instead?

I prefer to avoid macros altogether, and this is one of the ways to do it. We have had the discussion about how to define constants a few times before on lkml without reaching a conclusion.

Quoted 9 lines
Quoted 2 lines
arch/ppc64/kernel/bpa_iommu.c new file +2 -0
+/* cause link error for invalid use */
+extern unsigned long __ioc_invalid_page_size;

[...]

arch/ppc64/kernel/bpa_iommu.c line 160

Quoted 4 lines
arch/ppc64/kernel/bpa_iommu.c new file +4 -0
+	default: /* not a known compile time constant */
+		ps = __ioc_invalid_page_size;
+		break;
+	}

Why do we need to detect this at link time?

I want to avoid doing BUG() or something similar, so I try to detect a user error as early as possible.

Quoted 3 lines

arch/ppc64/kernel/bpa_iommu.c line 170

Quoted 1 line
arch/ppc64/kernel/bpa_iommu.c new file +1 -0
+	nnpt++; /* XXX is this right? */

Well, does it work? :-)

Yes, but it seems to contradict the specs...

Quoted 8 lines

arch/ppc64/kernel/bpa_iommu.c line 176

Quoted 6 lines
arch/ppc64/kernel/bpa_iommu.c new file +6 -0
+	return (ioste) {
+		.val = IOST_VALID_MASK
+			| (iostep & IOST_PT_BASE_MASK)
+			| ((nnpt << 5) & IOST_NNPT_MASK)
+			| (ps & IOST_PS_MASK)
+		};

Can you create a mk_ioste() inline instead of doing this construct?

ok.

Quoted 6 lines
Quoted 6 lines
arch/ppc64/kernel/bpa_iommu.c new file +6 -0
+static inline unsigned long
+get_ioptep(ioste iost_entry, unsigned long io_address)
+{
+	unsigned long iopt_base;
+	unsigned long ps;
+	unsigned long iopt_offset;
Quoted 8 lines

arch/ppc64/kernel/bpa_iommu.c line 190

Quoted 5 lines
arch/ppc64/kernel/bpa_iommu.c new file +5 -0
+
+	iopt_base = iost_entry.val & IOST_PT_BASE_MASK;
+	ps        = iost_entry.val & IOST_PS_MASK;
+
+	iopt_offset = ((io_address & 0x0fffffff) >> (7 + 2 * ps)) & 0x7fff8ul;

Magic. Can we get it explained either by defines instead of constants or by a comment?

This comes from a graphical representation in the specs. I'll add a comment to point to that image.

Quoted 7 lines

arch/ppc64/kernel/bpa_iommu.c line 241

Quoted 5 lines
arch/ppc64/kernel/bpa_iommu.c new file +5 -0
+static inline ioste
+get_iost_cache(void __iomem *base, unsigned long index)
+{
+	unsigned long __iomem *p = (base + IOC_ST_CACHE_DIR);
+	return (ioste) { in_be64(&p[index]) };

mk_ioste() would be nice here too.

ok.

Quoted 3 lines
Quoted 1 line

+#ifdef __KERNEL__

Are we ever not __KERNEL__?

Sorry, I thought I had removed that code already. This does not belong there.

Quoted 8 lines
Quoted 3 lines
arch/ppc64/kernel/bpa_iommu.c new file +3 -0
+/* initialize the iommu to support a simple linear mapping */
+static void bpa_map_iommu(void)
+{

[...]

arch/ppc64/kernel/bpa_iommu.c line 348

Quoted 1 line
arch/ppc64/kernel/bpa_iommu.c new file +1 -0
+	for (address = 0; address < 0x100000000ul; address += io_page_size) {

This looks like way more than the 512MB DMA window you mentioned in the beginning.

True. This is probably a bug in the comment. The code will change as soon as the firmware provides the correct dma-window properties.

	Arnd <><
#7 lore raw

Re: [PATCH 3/4] ppc64: Add driver for BPA iommu

Quoted 9 lines · Arnd Bergmann
Quoted 7 lines · Olof Johansson
Quoted 3 lines · Arnd Bergmann
arch/ppc64/kernel/bpa_iommu.c new file +3 -0
+/* some constants */
+enum {
+	/* segment table entries */

[...]

Quoted 1 line

+};

Quoted 8 lines
Quoted 4 lines

Hmm. I thought the benefit of enum was to be able to do type checking later on if it's a typed enum. Here you mix different definitions in the same large untyped enum declaration. Can they be moved to a bpa_iommu.h file and #defined instead?

I prefer to avoid macros altogether, and this is one of the ways to do it. We have had the discussion about how to define constants a few times before on lkml without reaching a conclusion.

Most of arch/ppc64/* uses #defines, for whatever that's worth. Still, CodingStyle seems to recommend enums for "related constants", I assume it's so they can be typed. I don't care enough either way to argue it further.

Anyhow, enum or #define, it should be moved to bpa_iommu.h.

Quoted 4 lines
Quoted 1 line

Why do we need to detect this at link time?

I want to avoid doing BUG() or something similar, so I try to detect a user error as early as possible.

User or developer error? I thought it was a developer one, and a quite specialized one at that. Either way, there's already a primitive that can be used instead of making your own: BUILD_BUG_ON().

Quoted 5 lines
Quoted 3 lines

arch/ppc64/kernel/bpa_iommu.c line 170

Quoted 1 line
arch/ppc64/kernel/bpa_iommu.c new file +1 -0
+	nnpt++; /* XXX is this right? */

Well, does it work? :-)

Yes, but it seems to contradict the specs...

A comment to that effect could be nice.

Quoted 15 lines
Quoted 6 lines
Quoted 6 lines
arch/ppc64/kernel/bpa_iommu.c new file +6 -0
+static inline unsigned long
+get_ioptep(ioste iost_entry, unsigned long io_address)
+{
+	unsigned long iopt_base;
+	unsigned long ps;
+	unsigned long iopt_offset;
Quoted 8 lines

arch/ppc64/kernel/bpa_iommu.c line 190

Quoted 5 lines
arch/ppc64/kernel/bpa_iommu.c new file +5 -0
+
+	iopt_base = iost_entry.val & IOST_PT_BASE_MASK;
+	ps        = iost_entry.val & IOST_PS_MASK;
+
+	iopt_offset = ((io_address & 0x0fffffff) >> (7 + 2 * ps)) & 0x7fff8ul;

Magic. Can we get it explained either by defines instead of constants or by a comment?

Quoted 2 lines

This comes from a graphical representation in the specs. I'll add a comment to point to that image.

I guess it'd be a bit much information to just add in a comment, but for readability that's probably the best way to go. Not many people have the specs, but on the other hand if you're messing around with this code then chances are you have them.

I don't know what the status is for a release of public specifications, but if they're not available then people will be looking to learn from the implementation and the documentation around it instead.

-Olof

#8 lore raw

Re: [PATCH 3/4] ppc64: Add driver for BPA iommu

Quoted 3 lines · Olof Johansson
Quoted 1 line · Arnd Bergmann

Anyhow, enum or #define, it should be moved to bpa_iommu.h.

I don't interface with any other files, so I prefer to have everything in one file here. If there is anyone else who agrees with you on moving this into a separate file, I don't mind doing that.

Quoted 3 lines

User or developer error? I thought it was a developer one, and a quite specialized one at that. Either way, there's already a primitive that can be used instead of making your own: BUILD_BUG_ON().

Right. I had forgotten about that, thanks.

Quoted 3 lines
Quoted 1 line

Yes, but it seems to contradict the specs...

A comment to that effect could be nice.

Ok, I'll change that.

Quoted 7 lines
Quoted 2 lines

This comes from a graphical representation in the specs. I'll add a comment to point to that image.

I guess it'd be a bit much information to just add in a comment, but for readability that's probably the best way to go. Not many people have the specs, but on the other hand if you're messing around with this code then chances are you have them.

The picture should be in the parts that we are working on getting public.

Quoted 3 lines

I don't know what the status is for a release of public specifications, but if they're not available then people will be looking to learn from the implementation and the documentation around it instead.

There will be a supplement to Book 1-3 of PowerPC AS that is going to be public. Book 4 is rarely needed and the chances of publishing that are not as good.

Thanks,

	Arnd <><
#9 lore raw

Re: [PATCH 3/4] ppc64: Add driver for BPA iommu

Quoted 9 lines · Arnd Bergmann
Quoted 3 lines · Olof Johansson
Quoted 1 line · Arnd Bergmann

Anyhow, enum or #define, it should be moved to bpa_iommu.h.

I don't interface with any other files, so I prefer to have everything in one file here. If there is anyone else who agrees with you on moving this into a separate file, I don't mind doing that.

The habit here is for such "private" .h to be next to the .c, while a shared one goes in include/asm-* or include/linux.

Ben.

#10 lore raw

Re: [PATCH 3/4] ppc64: Add driver for BPA iommu

Quoted 2 lines · Benjamin Herrenschmidt

The habit here is for such "private" .h to be next to the .c, while a shared one goes in include/asm-* or include/linux.

Ok, here comes an updated version, which should integrate changes for all comments I got so far.

Implementation of software load support for the BE iommu. This is very different from other iommu code on ppc64, since we only do a static mapping. The mapping is currently hardcoded but should really be read from the firmware, but they don't set up the device nodes yet.

Software load is ok as long as the DMA windows all fit below 4GB. Currently, there is a single 512MB DMA window for PCI, USB and ethernet at 0x20000000 for our RAM. No machine we have has more than 512 MB anyway, but we might want to change the firmware to use separate DMA windows for each device.

arch/ppc64/kernel/Makefile +2 -1
Index: linus-2.5/arch/ppc64/kernel/Makefile
===================================================================
@@ -34,7 +34,8 @@
 			     pSeries_nvram.o rtasd.o ras.o pSeries_reconfig.o \
 			     pSeries_setup.o pSeries_iommu.o
 
-obj-$(CONFIG_PPC_BPA) += bpa_setup.o bpa_nvram.o bpa_iic.o spider-pic.o
+obj-$(CONFIG_PPC_BPA) += bpa_setup.o bpa_iommu.o bpa_nvram.o \
+			 bpa_iic.o spider-pic.o
 
 obj-$(CONFIG_EEH)		+= eeh.o
 obj-$(CONFIG_PROC_FS)		+= proc_ppc64.o
arch/ppc64/kernel/bpa_iommu.c new file +377 -0

377 lines not on this page · raw message

arch/ppc64/kernel/bpa_iommu.h new file +65 -0

65 lines not on this page · raw message

arch/ppc64/kernel/bpa_setup.c +2 -1
Index: linus-2.5/arch/ppc64/kernel/bpa_setup.c
===================================================================
@@ -46,6 +46,7 @@
 
 #include "pci.h"
 #include "bpa_iic.h"
+#include "bpa_iommu.h"
 
 #ifdef DEBUG
 #define DBG(fmt...) udbg_printf(fmt)
@@ -179,7 +180,7 @@
 
 	hpte_init_native();
 
-	pci_direct_iommu_init();
+	bpa_init_iommu();
 
 	ppc64_interrupt_controller = IC_BPA_IIC;
 
#11 lore raw

Re: [PATCH 3/4] ppc64: Add driver for BPA iommu

Quoted 1 line · Arnd Bergmann

Implementation of software load support for the BE iommu. This is very

Could you expand a bit on what "software load support" is? Your description is a bit terse.

Thanks,
Paul.

#12 lore raw

PATCH 4/4 ppc64: Add SPU file system

In reply to Arnd Bergmann

This is an early version of the SPU file system, which is used to run code on the Synergistic Processing Units of the Broadband Engine.

The file system provides a name space similar to posix shared memory or message queues. Users that have write permissions on the file system can create directories in the spufs root.

Every directory represents an SPU context, which is currently mapped to a physical SPU, but that is going to change to a virtualization scheme in future updates.

An SPU context directory contains a predefined set of files used for manipulating the state of the logical SPU. Users can change permissions on those files, but not actually add or remove files without removing the complete directory.

The current set of files is:

/mem the contents of the local store memory of the SPU.
This can be accessed like a regular shared memory file and contains both code and data in the address space of the SPU.
The implemented file operations currently are read(), write() and mmap(). We will need our own address space operations as soon as we allow the SPU context to be scheduled away from the physical SPU into page cache.

/run A stub file that lets us do ioctl. The only ioctl
method we need is the spu_run() call. spu_run suspends the current thread from the host CPU and transfers the flow of execution to the SPU.
The ioctl call return to the calling thread when a state is entered that can not be handled by the kernel, e.g. an error in the SPU code or an exit() from it. When a signal is pending for the host CPU thread, the ioctl is interrupted and the SPU stopped in order to call the signal handler.

/mbox The first SPU to CPU communication mailbox. This file
is read-only and can be read in units of 32 bits. The file can only be used in non-blocking mode and it even poll() will not block on it.
When no data is available in the mailbox, read() returns EAGAIN.

/ibox The second SPU to CPU communication mailbox. This file
is similar to the first mailbox file, but can be read in blocking I/O mode, and the poll familiy of system calls can be used to wait for it.

/wbox The CPU to SPU communation mailbox. It is write-only
can can be written in units of 32 bits. If the mailbox is full, write() will block and poll can be used to wait for it becoming empty again.

Other files are planned but currently are not implemented or not functional.

arch/ppc64/kernel/Makefile +1 -0
@@ -53,6 +53,7 @@ obj-$(CONFIG_HVCS)		+= hvcserver.o
 obj-$(CONFIG_IBMVIO)		+= vio.o
 obj-$(CONFIG_XICS)		+= xics.o
 obj-$(CONFIG_MPIC)		+= mpic.o
+obj-$(CONFIG_SPU_FS)		+= spu_base.o
 
 obj-$(CONFIG_PPC_PMAC)		+= pmac_setup.o pmac_feature.o pmac_pci.o \
 				   pmac_time.o pmac_nvram.o pmac_low_i2c.o
arch/ppc64/kernel/spu_base.c +573 -0

573 lines not on this page · raw message

arch/ppc64/mm/hash_utils.c +1 -0
@@ -355,6 +355,7 @@ int hash_page(unsigned long ea, unsigned
 
 	return ret;
 }
+EXPORT_SYMBOL_GPL(hash_page);
 
 void flush_hash_page(unsigned long context, unsigned long ea, pte_t pte,
 		     int local)
fs/Kconfig +10 -0
@@ -853,6 +853,16 @@ config HUGETLBFS
 config HUGETLB_PAGE
 	def_bool HUGETLBFS
 
+config SPU_FS
+	tristate "SPU file system"
+	default m
+	depends on PPC_BPA
+	help
+	  The SPU file system is used to access Synergistic Processing
+	  Units on machines implementing the Broadband Processor
+	  Architecture.
+	
+
 config RAMFS
 	bool
 	default y
fs/Makefile +1 -0
@@ -95,3 +95,4 @@ obj-$(CONFIG_BEFS_FS)		+= befs/
 obj-$(CONFIG_HOSTFS)		+= hostfs/
 obj-$(CONFIG_HPPFS)		+= hppfs/
 obj-$(CONFIG_DEBUG_FS)		+= debugfs/
+obj-$(CONFIG_SPU_FS)		+= spufs/
fs/spufs/Makefile +3 -0
@@ -0,0 +1,3 @@
+obj-$(CONFIG_SPU_FS) += spufs.o
+
+spufs-y += inode.o
fs/spufs/inode.c +991 -0

991 lines not on this page · raw message

include/asm-ppc64/spu.h +459 -0

459 lines not on this page · raw message

mm/memory.c +1 -0
@@ -2108,6 +2108,7 @@ unsigned long vmalloc_to_pfn(void * vmal
 {
 	return page_to_pfn(vmalloc_to_page(vmalloc_addr));
 }
+EXPORT_SYMBOL_GPL(handle_mm_fault);
 
 EXPORT_SYMBOL(vmalloc_to_pfn);
 
#13 lore raw
In reply to Arnd Bergmann
Quoted 10 lines · Arnd Bergmann

This series of patches add support for a fifth platform type in the ppc64 architecture tree. The Broadband Processor Architecture (BPA) is currently used in a single machine from IBM, with others likely to be added at a later point.

I already sent preparation patches before, these need to be applied on top of them.
The first three patches add the actual platform code, which should be usable for any BPA compatible implementation.

Quoted 5 lines

The final patch introduces a new file system to make use of the SPUs inside the processors. This patch is still in a prototype stage and not intended for merging yet.

	Arnd <><

Is BPA the same thing (architecture) as the STI Cell Processor?

Sonny

#14 lore raw
Quoted 1 line · Sonny Rao

Is BPA the same thing (architecture) as the STI Cell Processor?

Yes, that is it. BPA is what Cell is called in the official specification.

	Arnd <><