LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] convert powermac ide blink to new led infrastructure
From: Johannes Berg @ 2006-04-28 14:49 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev list, debian-powerpc

This patch removes the old pmac ide led blink code and adds generic LED
subsystem support for the LED.

Ben: I removed the retry code that was present in the original. I guess
LEDs aren't really too important but if it really is necessary please
tell me and I'll add it back.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>

--- linux-2.6.orig/drivers/ide/Kconfig	2006-04-28 13:13:38.777288704 +0200
+++ linux-2.6/drivers/ide/Kconfig	2006-04-28 13:13:48.797288704 +0200
@@ -773,13 +773,6 @@ config BLK_DEV_IDEDMA_PMAC
 	  to transfer data to and from memory.  Saying Y is safe and improves
 	  performance.
 
-config BLK_DEV_IDE_PMAC_BLINK
-	bool "Blink laptop LED on drive activity"
-	depends on BLK_DEV_IDE_PMAC && ADB_PMU
-	help
-	  This option enables the use of the sleep LED as a hard drive
-	  activity LED.
-
 config BLK_DEV_IDE_SWARM
 	tristate "IDE for Sibyte evaluation boards"
 	depends on SIBYTE_SB1xxx_SOC
--- linux-2.6.orig/drivers/ide/ppc/pmac.c	2006-04-28 13:13:58.967288704 +0200
+++ linux-2.6/drivers/ide/ppc/pmac.c	2006-04-28 13:17:01.657288704 +0200
@@ -421,107 +421,6 @@ static void pmac_ide_kauai_selectproc(id
 #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
 
 /*
- * Below is the code for blinking the laptop LED along with hard
- * disk activity.
- */
-
-#ifdef CONFIG_BLK_DEV_IDE_PMAC_BLINK
-
-/* Set to 50ms minimum led-on time (also used to limit frequency
- * of requests sent to the PMU
- */
-#define PMU_HD_BLINK_TIME	(HZ/50)
-
-static struct adb_request pmu_blink_on, pmu_blink_off;
-static spinlock_t pmu_blink_lock;
-static unsigned long pmu_blink_stoptime;
-static int pmu_blink_ledstate;
-static struct timer_list pmu_blink_timer;
-static int pmu_ide_blink_enabled;
-
-
-static void
-pmu_hd_blink_timeout(unsigned long data)
-{
-	unsigned long flags;
-	
-	spin_lock_irqsave(&pmu_blink_lock, flags);
-
-	/* We may have been triggered again in a racy way, check
-	 * that we really want to switch it off
-	 */
-	if (time_after(pmu_blink_stoptime, jiffies))
-		goto done;
-
-	/* Previous req. not complete, try 100ms more */
-	if (pmu_blink_off.complete == 0)
-		mod_timer(&pmu_blink_timer, jiffies + PMU_HD_BLINK_TIME);
-	else if (pmu_blink_ledstate) {
-		pmu_request(&pmu_blink_off, NULL, 4, 0xee, 4, 0, 0);
-		pmu_blink_ledstate = 0;
-	}
-done:
-	spin_unlock_irqrestore(&pmu_blink_lock, flags);
-}
-
-static void
-pmu_hd_kick_blink(void *data, int rw)
-{
-	unsigned long flags;
-	
-	pmu_blink_stoptime = jiffies + PMU_HD_BLINK_TIME;
-	wmb();
-	mod_timer(&pmu_blink_timer, pmu_blink_stoptime);
-	/* Fast path when LED is already ON */
-	if (pmu_blink_ledstate == 1)
-		return;
-	spin_lock_irqsave(&pmu_blink_lock, flags);
-	if (pmu_blink_on.complete && !pmu_blink_ledstate) {
-		pmu_request(&pmu_blink_on, NULL, 4, 0xee, 4, 0, 1);
-		pmu_blink_ledstate = 1;
-	}
-	spin_unlock_irqrestore(&pmu_blink_lock, flags);
-}
-
-static int
-pmu_hd_blink_init(void)
-{
-	struct device_node *dt;
-	const char *model;
-
-	/* Currently, I only enable this feature on KeyLargo based laptops,
-	 * older laptops may support it (at least heathrow/paddington) but
-	 * I don't feel like loading those venerable old machines with so
-	 * much additional interrupt & PMU activity...
-	 */
-	if (pmu_get_model() != PMU_KEYLARGO_BASED)
-		return 0;
-	
-	dt = of_find_node_by_path("/");
-	if (dt == NULL)
-		return 0;
-	model = (const char *)get_property(dt, "model", NULL);
-	if (model == NULL)
-		return 0;
-	if (strncmp(model, "PowerBook", strlen("PowerBook")) != 0 &&
-	    strncmp(model, "iBook", strlen("iBook")) != 0) {
-		of_node_put(dt);
-	    	return 0;
-	}
-	of_node_put(dt);
-
-	pmu_blink_on.complete = 1;
-	pmu_blink_off.complete = 1;
-	spin_lock_init(&pmu_blink_lock);
-	init_timer(&pmu_blink_timer);
-	pmu_blink_timer.function = pmu_hd_blink_timeout;
-
-	return 1;
-}
-
-#endif /* CONFIG_BLK_DEV_IDE_PMAC_BLINK */
-
-/*
  * N.B. this can't be an initfunc, because the media-bay task can
  * call ide_[un]register at any time.
  */
@@ -1190,23 +1089,6 @@ pmac_ide_do_suspend(ide_hwif_t *hwif)
 	pmif->timings[0] = 0;
 	pmif->timings[1] = 0;
 	
-#ifdef CONFIG_BLK_DEV_IDE_PMAC_BLINK
-	/* Note: This code will be called for every hwif, thus we'll
-	 * try several time to stop the LED blinker timer,  but that
-	 * should be harmless
-	 */
-	if (pmu_ide_blink_enabled) {
-		unsigned long flags;
-
-		/* Make sure we don't hit the PMU blink */
-		spin_lock_irqsave(&pmu_blink_lock, flags);
-		if (pmu_blink_ledstate)
-			del_timer(&pmu_blink_timer);
-		pmu_blink_ledstate = 0;
-		spin_unlock_irqrestore(&pmu_blink_lock, flags);
-	}
-#endif /* CONFIG_BLK_DEV_IDE_PMAC_BLINK */
-
 	disable_irq(pmif->irq);
 
 	/* The media bay will handle itself just fine */
@@ -1374,13 +1256,6 @@ pmac_ide_setup_device(pmac_ide_hwif_t *p
 		hwif->selectproc = pmac_ide_selectproc;
 	hwif->speedproc = pmac_ide_tune_chipset;
 
-#ifdef CONFIG_BLK_DEV_IDE_PMAC_BLINK
-	pmu_ide_blink_enabled = pmu_hd_blink_init();
-
-	if (pmu_ide_blink_enabled)
-		hwif->led_act = pmu_hd_kick_blink;
-#endif
-
 	printk(KERN_INFO "ide%d: Found Apple %s controller, bus ID %d%s, irq %d\n",
 	       hwif->index, model_name[pmif->kind], pmif->aapl_bus_id,
 	       pmif->mediabay ? " (mediabay)" : "", hwif->irq);
--- linux-2.6.orig/drivers/macintosh/Kconfig	2006-04-28 13:31:24.347288704 +0200
+++ linux-2.6/drivers/macintosh/Kconfig	2006-04-28 13:31:43.677288704 +0200
@@ -78,6 +78,16 @@ config ADB_PMU
 	  this device; you should do so if your machine is one of those
 	  mentioned above.
 
+config ADB_PMU_LED
+	bool "Support for the Power/iBook front LED"
+	depends on LEDS_CLASS && ADB_PMU
+	help
+	  Support the front LED on Power/iBooks as a generic LED that can
+	  be triggered by any of the supported triggers. To get the
+	  behaviour of the old CONFIG_BLK_DEV_IDE_PMAC_BLINK, select this
+	  and the ide-disk LED trigger and configure appropriately through
+	  sysfs.
+
 config PMAC_SMU
 	bool "Support for SMU  based PowerMacs"
 	depends on PPC_PMAC64
--- linux-2.6.orig/drivers/macintosh/Makefile	2006-04-28 13:35:17.977288704 +0200
+++ linux-2.6/drivers/macintosh/Makefile	2006-04-28 13:46:44.887288704 +0200
@@ -12,6 +12,7 @@ obj-$(CONFIG_INPUT_ADBHID)	+= adbhid.o
 obj-$(CONFIG_ANSLCD)		+= ans-lcd.o
 
 obj-$(CONFIG_ADB_PMU)		+= via-pmu.o
+obj-$(CONFIG_ADB_PMU_LED)	+= via-pmu-led.o
 obj-$(CONFIG_ADB_CUDA)		+= via-cuda.o
 obj-$(CONFIG_PMAC_APM_EMU)	+= apm_emu.o
 obj-$(CONFIG_PMAC_SMU)		+= smu.o
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6/drivers/macintosh/via-pmu-led.c	2006-04-28 13:56:28.537288704 +0200
@@ -0,0 +1,80 @@
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/leds.h>
+#include <linux/adb.h>
+#include <linux/pmu.h>
+#include <asm/prom.h>
+#include "via-pmu-led.h"
+
+static spinlock_t pmu_blink_lock;
+static struct adb_request pmu_blink_req;
+
+static void pmu_led_off(void)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&pmu_blink_lock, flags);
+	/* I currently ignore the result of this request */
+	pmu_request(&pmu_blink_req, NULL, 4, 0xee, 4, 0, 0);
+	spin_unlock_irqrestore(&pmu_blink_lock, flags);
+}
+
+static void pmu_led_on(void)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&pmu_blink_lock, flags);
+	pmu_request(&pmu_blink_req, NULL, 4, 0xee, 4, 0, 1);
+	spin_unlock_irqrestore(&pmu_blink_lock, flags);
+}
+
+static void pmu_led_set(struct led_classdev *led_cdev,
+			 enum led_brightness brightness)
+{
+	switch (brightness) {
+	case LED_OFF:
+		pmu_led_off();
+		break;
+	case LED_FULL:
+		pmu_led_on();
+		break;
+	default:
+		/* ignore other levels */
+		break;
+	}
+}
+
+static struct led_classdev pmu_led = {
+	.name = "pmu-front-led",
+	.brightness_set = pmu_led_set,
+};
+
+int pmu_led_init(void)
+{
+	/* this is only called for keylargo based systems */
+	struct device_node *dt;
+	const char *model;
+
+	dt = of_find_node_by_path("/");
+	if (dt == NULL)
+		return -ENODEV;
+	model = (const char *)get_property(dt, "model", NULL);
+	if (model == NULL)
+		return -ENODEV;
+	if (strncmp(model, "PowerBook", strlen("PowerBook")) != 0 &&
+	    strncmp(model, "iBook", strlen("iBook")) != 0) {
+		of_node_put(dt);
+		/* silently ignore */
+		return 0;
+	}
+	of_node_put(dt);
+
+	spin_lock_init(&pmu_blink_lock);
+	return led_classdev_register(NULL, &pmu_led);
+}
+
+void pmu_led_exit(void)
+{
+	led_classdev_unregister(&pmu_led);
+}
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6/drivers/macintosh/via-pmu-led.h	2006-04-28 13:48:19.177288704 +0200
@@ -0,0 +1,18 @@
+#ifndef __VIA_PMU_LED_H
+#define __VIA_PMU_LED_H
+#include <config/adb/pmu/led.h>
+
+#ifdef CONFIG_ADB_PMU_LED
+extern int pmu_led_init(void);
+extern void pmu_led_exit(void);
+#else
+static inline int pmu_led_init(void)
+{
+	return 0;
+}
+static inline void pmu_led_exit(void)
+{
+}
+#endif /* CONFIG_ADB_PMU_LED */
+
+#endif /* __VIA_PMU_LED_H */
--- linux-2.6.orig/drivers/macintosh/via-pmu.c	2006-04-28 13:09:02.197288704 +0200
+++ linux-2.6/drivers/macintosh/via-pmu.c	2006-04-28 15:58:45.497288704 +0200
@@ -69,6 +69,8 @@
 #include <asm/open_pic.h>
 #endif
 
+#include "via-pmu-led.h"
+
 /* Some compile options */
 #undef SUSPEND_USES_PMU
 #define DEBUG_SLEEP
@@ -2896,11 +2898,25 @@ static int __init init_pmu_sysfs(void)
 		printk(KERN_ERR "Failed registering PMU sys driver\n");
 		return -ENODEV;
 	}
+
 	return 0;
 }
 
 subsys_initcall(init_pmu_sysfs);
 
+static int __init init_pmu_led(void)
+{
+	if (pmu_kind == PMU_KEYLARGO_BASED) {
+		if (pmu_led_init()) {
+			printk(KERN_WARNING "via-pmu: LED failed to init\n");
+		}
+	}
+
+	return 0;
+}
+
+late_initcall(init_pmu_led);
+
 EXPORT_SYMBOL(pmu_request);
 EXPORT_SYMBOL(pmu_queue_request);
 EXPORT_SYMBOL(pmu_poll);

^ permalink raw reply

* Re: FT u-boot shim
From: Kumar Gala @ 2006-04-28 16:01 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev@ozlabs.org list
In-Reply-To: <17489.64606.75404.314368@cargo.ozlabs.ibm.com>


On Apr 28, 2006, at 6:28 AM, Paul Mackerras wrote:

> Kumar Gala writes:
>
>> If we have a u-boot shim there are some questions that need  
>> answering:
>> * where should the .dts live (hate duplicating the file both in u-
>> boot and kernel source tree)
>> * how does build system find .dts
>> * a Kconfig option to enable shim
>> * assume done as a boot wrapper of sorts
>
> What I think would be useful is a stand-alone tool that would take a
> kernel and a dts and construct an image that is bootable on a given
> board by its existing firmware.  That means there would either need to
> be a version of the tool for each firmware, or alternatively a set of
> command-line options to tell it what sort of firmware you have.
>
> This wouldn't have to be done at kernel build time; it could be
> potentially be done much later.  Hopefully then the board vendors
> could take on the job of generating the dts.  In fact for some boards
> the board-support package could be just the dts.
>
> This tool would need to insert a suitable shim, which might actually
> need to contain code to pull stuff out of a firmware-specific
> structure such as a bd_t, and stuff it into the dts.  That should be
> doable provided there is a convention about labels in the dts for
> things such as memory size, ethernet mac address, etc.
>
> Clearly it is neater if the firmware can supply the device-tree blob
> directly, and just boot a raw kernel.  However, there will always be
> situations where we don't get to choose the firmware, so I think we
> need this tool.

I agree with this (after having it beaten into me :).

However, I really hate introducing some third project that is  
required.  If we decide to pull ALL of boot wrappers out of the  
kernel tree than I'd be ok with it.  But until that time I think this  
lives under arch/powerpc/boot/...

What I envision as the way one boots for something like u-boot is one  
of three options:
1. using an old u-boot + boot wrapper (bd_t -> wrapper -> kernel)
2. using a u-boot that is ft aware + dtb (boot command in u-boot  
takes kernel & dtb images, updates blob and passes to kernel)
3. using a u-boot that is ft aware + built in dtb.

The issue is that for a given system/board you may need to support  
multiple or all three.  This raises the question where does the .dts  
live.  For the time being I say it lives in the boot wrapper part of  
the kernel tree.  Thus we handle the three cases as follows:

1. built as part of the boot wrapper
2. build a multi image u-boot image, one section for the blob
3. point u-boot build system at .dts

- kumar

^ permalink raw reply

* [RFC , PATCH] support for the ibm,pa_features cpu property
From: Will Schmidt @ 2006-04-28 18:41 UTC (permalink / raw)
  To: linuxppc-dev list, paulus


To determine if our processors support some features, such as large
pages, we should be using the ibm,pa_features property, rather than just
the PVR values.  
This is an initial pass at the functionality.  This has been tested in
the case where the property is missing, but still needs to be tested
against a system where the property actually exists.  :-o  



diff --git a/arch/powerpc/kernel/setup_64.c
b/arch/powerpc/kernel/setup_64.c
index 13e91c4..78ad054 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -106,6 +106,65 @@ static struct notifier_block ppc64_panic
 	.priority = INT_MIN /* may not return; must be done last */
 };
 
+/*
+ * ibm,pa-features is a per-cpu property that contains a 2 byte header
+ * plus up to 256 bytes worth of processor attributes.  First header
+ * byte specifies the number of bytes implemented by the platform.
+ * Second header byte is an "attribute-specifier" type, which should
+ * be zero.  Remainder of the data consists of ones and zeros.
+ * Implementation:  Pass in the byte and bit offset for the feature
+ * that we are interested in.  The function will return -1 if the
+ * pa-features property is missing, or a 1/0 to indicate if the feature
+ * is supported/not supported.
+ */
+
+static int get_pa_features(int pabyte,int pabit)
+{
+	struct device_node *cpu;
+	char *pa_feature_table;
+
+	cpu = of_find_node_by_type(NULL, "cpu");
+	pa_feature_table = 
+		(char *)get_property(cpu, "ibm,pa-features", NULL);
+
+	if ( pa_feature_table == NULL ) {
+		printk("ibm,pa-features property is missing.\n");
+		return -1;
+	}
+
+	/* sanity check */
+	if ( pabyte > pa_feature_table[0] ) {
+		printk("%s: %d out of range for table of size %d\n",
+			__FUNCTION__,pabyte,pa_feature_table[0]);
+		return -1;
+	}
+	
+	return pa_feature_table[2+pabyte*8+pabit];
+}
+
+/*
+ * set values within the cur_cpu_spec table according to
+ * the ibm,pa_features property. 
+ * potential entries include: 
+ * Byte 0, bit 1 - FPU available
+ * Byte 1, bit 2 - Large Pages 
+ * Byte 2, bit 3 - DAR set on alignment Interrupt. 
+ */
+static void add_cpu_features()
+{
+	/* if no property, bail early */
+	if (get_pa_features(0,0) == -1 ) return;
+
+	if (get_pa_features(1,2) ) {
+		printk("Adding CI_LARGE_PAGE to cur_cpu_spec \n");
+		cur_cpu_spec->cpu_features |= CPU_FTR_CI_LARGE_PAGE;
+	}
+
+	/* add more here... */
+
+}
+
+
 #ifdef CONFIG_SMP
 
 static int smt_enabled_cmdline;
@@ -425,6 +484,8 @@ void __init setup_system(void)
 
 	parse_early_param();
 
+	add_cpu_features();
+
 	check_smt_enabled();
 	smp_setup_cpu_maps();
 

^ permalink raw reply related

* Re: FT u-boot shim
From: Wolfgang Denk @ 2006-04-28 19:11 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev@ozlabs.org list, Paul Mackerras
In-Reply-To: <EA2821E8-FB7E-4DDA-8C18-C659B5483DC2@kernel.crashing.org>

In message <EA2821E8-FB7E-4DDA-8C18-C659B5483DC2@kernel.crashing.org>
Kumar Gala wrote:
> 
> What I envision as the way one boots for something like u-boot is one  
> of three options:
> 1. using an old u-boot + boot wrapper (bd_t -> wrapper -> kernel)
> 2. using a u-boot that is ft aware + dtb (boot command in u-boot  
> takes kernel & dtb images, updates blob and passes to kernel)
> 3. using a u-boot that is ft aware + built in dtb.
> 
> The issue is that for a given system/board you may need to support  
> multiple or all three.  This raises the question where does the .dts  

Assuming we had 2., under which circumstances would we need 3. then?


Best regards,

Wolfgang Denk

-- 
Software Engineering:  Embedded and Realtime Systems,  Embedded Linux
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
A conservative is a man with two perfectly good legs  who  has  never
learned to walk.                              - Franklin D. Roosevelt

^ permalink raw reply

* [PATCH] via-pmu: report powerbutton as proper input event
From: Johannes Berg @ 2006-04-28 19:15 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev list, debian-powerpc

This patch adds an input device for the power button so that userspace gets
notified about the user pressing it via the standard input layer.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>

--- linux-2.6.orig/drivers/macintosh/Makefile	2006-04-28 19:07:27.057288704 +0200
+++ linux-2.6/drivers/macintosh/Makefile	2006-04-28 19:07:49.987288704 +0200
@@ -11,7 +11,7 @@ obj-$(CONFIG_MAC_EMUMOUSEBTN)	+= mac_hid
 obj-$(CONFIG_INPUT_ADBHID)	+= adbhid.o
 obj-$(CONFIG_ANSLCD)		+= ans-lcd.o
 
-obj-$(CONFIG_ADB_PMU)		+= via-pmu.o
+obj-$(CONFIG_ADB_PMU)		+= via-pmu.o via-pmu-event.o
 obj-$(CONFIG_ADB_PMU_LED)	+= via-pmu-led.o
 obj-$(CONFIG_ADB_CUDA)		+= via-cuda.o
 obj-$(CONFIG_PMAC_APM_EMU)	+= apm_emu.o
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6/drivers/macintosh/via-pmu-event.c	2006-04-28 20:35:12.277288704 +0200
@@ -0,0 +1,35 @@
+#include <linux/input.h>
+#include "via-pmu-event.h"
+
+static struct input_dev *pmu_input_dev;
+
+int pmu_event_init(void)
+{
+	pmu_input_dev = input_allocate_device();
+	if (unlikely(!pmu_input_dev))
+		return -ENODEV;
+
+	pmu_input_dev->name = "PMU powerbutton";
+	pmu_input_dev->id.bustype = BUS_PMU;
+	pmu_input_dev->id.vendor = 0x0001;
+	pmu_input_dev->id.product = 0x0001;
+	pmu_input_dev->id.version = 0x0100;
+
+	pmu_input_dev->evbit[0] = BIT(EV_KEY);
+	pmu_input_dev->keybit[LONG(KEY_POWER)] = BIT(KEY_POWER);
+
+	return input_register_device(pmu_input_dev);
+}
+
+void pmu_event_powerbutton(int down)
+{
+	static int powerbutton_pressed;
+
+	if (unlikely(!pmu_input_dev))
+		return;
+	if (powerbutton_pressed == down)
+		return;
+	powerbutton_pressed = down;
+	input_report_key(pmu_input_dev, KEY_POWER, down);
+	input_sync(pmu_input_dev);
+}
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6/drivers/macintosh/via-pmu-event.h	2006-04-28 20:09:34.967288704 +0200
@@ -0,0 +1,8 @@
+#ifndef __VIA_PMU_EVENT_H
+#define __VIA_PMU_EVENT_H
+
+extern int pmu_event_init(void);
+
+extern void pmu_event_powerbutton(int down);
+
+#endif /* __VIA_PMU_EVENT_H */
--- linux-2.6.orig/include/linux/input.h	2006-04-28 20:00:37.417288704 +0200
+++ linux-2.6/include/linux/input.h	2006-04-28 20:00:48.157288704 +0200
@@ -658,6 +658,7 @@ struct input_absinfo {
 #define BUS_I2C			0x18
 #define BUS_HOST		0x19
 #define BUS_GSC			0x1A
+#define BUS_PMU			0x20
 
 /*
  * Values describing the status of an effect
--- linux-2.6.orig/drivers/macintosh/via-pmu.c	2006-04-28 19:07:19.207288704 +0200
+++ linux-2.6/drivers/macintosh/via-pmu.c	2006-04-28 20:35:23.417288704 +0200
@@ -70,6 +70,7 @@
 #endif
 
 #include "via-pmu-led.h"
+#include "via-pmu-event.h"
 
 /* Some compile options */
 #undef SUSPEND_USES_PMU
@@ -1443,6 +1444,11 @@ next:
 		if (pmu_battery_count)
 			query_battery_state();
 		pmu_pass_intr(data, len);
+		/* if the thing has the powerbutton bit set then
+		 * update the powerbutton key status */
+		if (len == 6) {
+			pmu_event_powerbutton(!!(data[1]&8));
+		}
 	} else {
 	       pmu_pass_intr(data, len);
 	}
@@ -2915,6 +2921,10 @@ static int __init init_pmu_led(void)
 		if (pmu_led_init()) {
 			printk(KERN_WARNING "via-pmu: LED failed to init\n");
 		}
+
+		/* only on keylargo can the power button be on the pmu ... */
+		if (pmu_event_init())
+			printk(KERN_WARNING "via-pmu: couldn't add event device");
 	}
 
 	return 0;

^ permalink raw reply

* Re: [RFC , PATCH] support for the ibm,pa_features cpu property
From: Olof Johansson @ 2006-04-28 19:21 UTC (permalink / raw)
  To: Will Schmidt; +Cc: linuxppc-dev list, paulus
In-Reply-To: <1146249684.27214.18.camel@localhost.localdomain>

Hi Will,

Some general comments below. Not having seen the documentation for the
new property I obviously can't comment on the correctness from that
perspective.

Do you know why they went for this brand new extra architected bitfield
instead of continuing down the way that processor features always have
been documented before, by adding a property to the cpu device node?

That seems like a much more logical solution to me. It sort of sounds
like someone was bored one day and decided to get busy with architecting
yet another way to specify processor capabilities. :(

(Now, the naming convention of calling it a "pa feature" is unfortunate,
but nothing I can really complain about since our stuff is not yet in
tree.)


-Olof

On Fri, Apr 28, 2006 at 01:41:24PM -0500, Will Schmidt wrote:
> 
> To determine if our processors support some features, such as large
> pages, we should be using the ibm,pa_features property, rather than just
> the PVR values.  
> This is an initial pass at the functionality.  This has been tested in
> the case where the property is missing, but still needs to be tested
> against a system where the property actually exists.  :-o  
> 
> 
> 
> diff --git a/arch/powerpc/kernel/setup_64.c
> b/arch/powerpc/kernel/setup_64.c
> index 13e91c4..78ad054 100644
> --- a/arch/powerpc/kernel/setup_64.c
> +++ b/arch/powerpc/kernel/setup_64.c
> @@ -106,6 +106,65 @@ static struct notifier_block ppc64_panic
>  	.priority = INT_MIN /* may not return; must be done last */
>  };
>  
> +/*
> + * ibm,pa-features is a per-cpu property that contains a 2 byte header
> + * plus up to 256 bytes worth of processor attributes.  First header
> + * byte specifies the number of bytes implemented by the platform.
> + * Second header byte is an "attribute-specifier" type, which should
> + * be zero.  Remainder of the data consists of ones and zeros.

So, essentially a bit array with one bit per feature with a 2-byte
header?

> + * Implementation:  Pass in the byte and bit offset for the feature
> + * that we are interested in.  The function will return -1 if the
> + * pa-features property is missing, or a 1/0 to indicate if the feature
> + * is supported/not supported.
> + */
> +
> +static int get_pa_features(int pabyte,int pabit)

So this is more of a check_pa_feature (int pabyte, int pabit)

(note space after comma, CodingStyle)

> +{
> +	struct device_node *cpu;
> +	char *pa_feature_table;
> +
> +	cpu = of_find_node_by_type(NULL, "cpu");
> +	pa_feature_table = 
> +		(char *)get_property(cpu, "ibm,pa-features", NULL);
> +	if ( pa_feature_table == NULL ) {

No spaces after ( and before )

> +		printk("ibm,pa-features property is missing.\n");
> +		return -1;
> +	}

This will read the property on every call. How about making the table
pointer static instead and keeping it cached?

> +
> +	/* sanity check */
> +	if ( pabyte > pa_feature_table[0] ) {
> +		printk("%s: %d out of range for table of size %d\n",
> +			__FUNCTION__,pabyte,pa_feature_table[0]);

This might pop on regular machines, so you might want to do away with
the printk by default, or add it under a DBG() macro that's not enabled
by default (see other powerpc files for examples)

> +		return -1;
> +	}
> +	
> +	return pa_feature_table[2+pabyte*8+pabit];
> +}

Not knowing the order of the bitfield, I'm guessing you might want this
instead:

	return pa_feature_table[2+pabyte] & (0x80 >> pabit);

I would prefer to see a 0/1 return. 1 if the feature is set, 0
otherwise. I.e. no -1 on failure.

> +/*
> + * set values within the cur_cpu_spec table according to
> + * the ibm,pa_features property. 
> + * potential entries include: 
> + * Byte 0, bit 1 - FPU available
> + * Byte 1, bit 2 - Large Pages 
> + * Byte 2, bit 3 - DAR set on alignment Interrupt. 

Wow, that's a really sparse array, 8 empty entries between each
allocated bit so far.

I would like to see these as #defines as well. It might make more sense
to have them as just bit number, and calculate the byte in the function
above instead. That way it's only one define per feature.

> + */
> +static void add_cpu_features()
> +{
> +	/* if no property, bail early */
> +	if (get_pa_features(0,0) == -1 ) return;

Probably no need to bail early, especially if the feature check function
just returns 0 if it's out-of-bounds (or no property exists)

> +
> +	if (get_pa_features(1,2) ) {
> +		printk("Adding CI_LARGE_PAGE to cur_cpu_spec \n");
> +		cur_cpu_spec->cpu_features |= CPU_FTR_CI_LARGE_PAGE;
> +	}
> +
> +	/* add more here... */
> +
> +}
> +
> +
>  #ifdef CONFIG_SMP
>  
>  static int smt_enabled_cmdline;
> @@ -425,6 +484,8 @@ void __init setup_system(void)
>  
>  	parse_early_param();
>  
> +	add_cpu_features();
> +
>  	check_smt_enabled();
>  	smp_setup_cpu_maps();
>  
> 
> 
> 
> 
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev

^ permalink raw reply

* Re: [RFC , PATCH] support for the ibm,pa_features cpu property
From: Nathan Lynch @ 2006-04-28 19:31 UTC (permalink / raw)
  To: Will Schmidt; +Cc: linuxppc-dev list, paulus
In-Reply-To: <1146249684.27214.18.camel@localhost.localdomain>

Will Schmidt wrote:
> +static int get_pa_features(int pabyte,int pabit)
> +{
> +	struct device_node *cpu;
> +	char *pa_feature_table;
> +
> +	cpu = of_find_node_by_type(NULL, "cpu");
> +	pa_feature_table = 
> +		(char *)get_property(cpu, "ibm,pa-features", NULL);
> +
> +	if ( pa_feature_table == NULL ) {
> +		printk("ibm,pa-features property is missing.\n");
> +		return -1;
> +	}
> +
> +	/* sanity check */
> +	if ( pabyte > pa_feature_table[0] ) {
> +		printk("%s: %d out of range for table of size %d\n",
> +			__FUNCTION__,pabyte,pa_feature_table[0]);
> +		return -1;
> +	}
> +	
> +	return pa_feature_table[2+pabyte*8+pabit];
> +}

This function needs to of_node_put(cpu) before returning or we won't
be able to deconfigure the processor.

^ permalink raw reply

* Re: [PATCH] powerpc: ibmveth: Harden driver initilisation for kexec
From: Santiago Leon @ 2006-04-28 19:51 UTC (permalink / raw)
  To: michael; +Cc: linuxppc64-dev, jgarzik, netdev
In-Reply-To: <1146047837.10735.29.camel@localhost.localdomain>

[-- Attachment #1: Type: text/plain, Size: 314 bytes --]

Michael Ellerman wrote:
>>Looks like this hit the floor. Any chance of getting it into to 2.6.17
>>Jeff? AFAICT it should still apply cleanly.
>  
> /me knocks politely

Actually, it doesn't apply cleanly anymore.  Here's a patch that does.
-- 
Santiago A. Leon
Power Linux Development
IBM Linux Technology Center

[-- Attachment #2: ibmveth_harden_init.patch --]
[-- Type: text/plain, Size: 2193 bytes --]

From: Michael Ellerman <michael@ellerman.id.au>

After a kexec the ibmveth driver will fail when trying to register with the Hypervisor because the previous kernel has not unregistered.

So if the registration fails, we unregister and then try again.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Acked-by: Anton Blanchard <anton@samba.org>
Signed-off-by: Santiago Leon <santil@us.ibm.com>

 ibmveth.c |   31 ++++++++++++++++++++++++++-----
 1 file changed, 26 insertions(+), 5 deletions(-)

Index: kexec/drivers/net/ibmveth.c
===================================================================
--- a/drivers/net/ibmveth.c	2006-04-28 13:16:22.244724056 -0500
+++ b/drivers/net/ibmveth.c	2006-04-28 13:29:49.429736784 -0500
@@ -436,6 +436,31 @@ static void ibmveth_cleanup(struct ibmve
 		ibmveth_free_buffer_pool(adapter, &adapter->rx_buff_pool[i]);
 }
 
+static int ibmveth_register_logical_lan(struct ibmveth_adapter *adapter,
+        union ibmveth_buf_desc rxq_desc, u64 mac_address)
+{
+	int rc, try_again = 1;
+
+	/* After a kexec the adapter will still be open, so our attempt to
+	* open it will fail. So if we get a failure we free the adapter and
+	* try again, but only once. */
+retry:
+	rc = h_register_logical_lan(adapter->vdev->unit_address,
+				    adapter->buffer_list_dma, rxq_desc.desc,
+				    adapter->filter_list_dma, mac_address);
+
+	if (rc != H_SUCCESS && try_again) {
+		do {
+			rc = h_free_logical_lan(adapter->vdev->unit_address);
+		} while (H_IS_LONG_BUSY(rc) || (rc == H_BUSY));
+
+		try_again = 0;
+		goto retry;
+	}
+
+	return rc;
+}
+
 static int ibmveth_open(struct net_device *netdev)
 {
 	struct ibmveth_adapter *adapter = netdev->priv;
@@ -505,11 +530,7 @@ static int ibmveth_open(struct net_devic
 	ibmveth_debug_printk("receive q   @ 0x%p\n", adapter->rx_queue.queue_addr);
 
     
-	lpar_rc = h_register_logical_lan(adapter->vdev->unit_address,
-					 adapter->buffer_list_dma,
-					 rxq_desc.desc,
-					 adapter->filter_list_dma,
-					 mac_address);
+	lpar_rc = ibmveth_register_logical_lan(adapter, rxq_desc, mac_address);
 
 	if(lpar_rc != H_SUCCESS) {
 		ibmveth_error_printk("h_register_logical_lan failed with %ld\n", lpar_rc);

^ permalink raw reply

* Re: FT u-boot shim
From: Tom Rini @ 2006-04-28 19:52 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev@ozlabs.org list, Paul Mackerras
In-Reply-To: <EA2821E8-FB7E-4DDA-8C18-C659B5483DC2@kernel.crashing.org>

On Fri, Apr 28, 2006 at 11:01:20AM -0500, Kumar Gala wrote:

> However, I really hate introducing some third project that is  
> required.  If we decide to pull ALL of boot wrappers out of the  
> kernel tree than I'd be ok with it.  But until that time I think this  
> lives under arch/powerpc/boot/...

The more I think about this, and hear about what some vendors do,
pulling arch/p*pc/boot/ out of the kernel is making more and more sense.
Especially with the serial headache, a depends-on-nothing,
can-translate-$(firmware information) tool might be best.

> What I envision as the way one boots for something like u-boot is one  
> of three options:
> 1. using an old u-boot + boot wrapper (bd_t -> wrapper -> kernel)
> 2. using a u-boot that is ft aware + dtb (boot command in u-boot  
> takes kernel & dtb images, updates blob and passes to kernel)
> 3. using a u-boot that is ft aware + built in dtb.

And more generally:
1. using an old firmware + kernel boot wrapper (firmware->dtb converter)
boots kernel.
2. using a dtb-aware firmware boots kernel (compressed or not) and
passes dtb in.

> The issue is that for a given system/board you may need to support  
> multiple or all three.  This raises the question where does the .dts  
> live.  For the time being I say it lives in the boot wrapper part of  
> the kernel tree.  Thus we handle the three cases as follows:

We could stick it in the seprate kernel boot wrapper project.  But I
really think this really has to live in two places.  The kernel should
be The Owner, as until *BSD or something adopts this, it's a
Linux-specific thing.  But any firmware that wishes to skip the kernel
boot wrapper and be a direct kernel booter, will need to own a copy.

-- 
Tom Rini
http://gate.crashing.org/~trini/

^ permalink raw reply

* Re: [PATCH] [2.6.18] powerpc: kill union tce_entry
From: Jon Mason @ 2006-04-28 20:42 UTC (permalink / raw)
  To: Olof Johansson; +Cc: linuxppc-dev, mulix, paulus, sfr
In-Reply-To: <20060428140835.GG5518@pb15.lixom.net>

This looks very similar to the way Muli did it for x86_64 Calgary, only
in the reverse.  You gotta love endianness. :-)

Looks good to my eyeball.

Thanks,
Jon


On Fri, Apr 28, 2006 at 09:08:35AM -0500, Olof Johansson wrote:
> It's been long overdue to kill the union tce_entry in the pSeries/iSeries
> TCE code, especially since I asked the Summit guys to do it on the code
> they copied from us.
> 
> Also, while I was at it, I cleaned up some whitespace.
> 
> Built and booted on pSeries, built on iSeries.
> 
> 
> Signed-off-by: Olof Johansson <olof@lixom.net>
> 
> 
> Index: powerpc/arch/powerpc/platforms/iseries/iommu.c
> ===================================================================
> --- powerpc.orig/arch/powerpc/platforms/iseries/iommu.c
> +++ powerpc/arch/powerpc/platforms/iseries/iommu.c
> @@ -4,6 +4,7 @@
>   * Rewrite, cleanup:
>   *
>   * Copyright (C) 2004 Olof Johansson <olof@lixom.net>, IBM Corporation
> + * Copyright (C) 2006 Olof Johansson <olof@lixom.net>
>   *
>   * Dynamic DMA mapping support, iSeries-specific parts.
>   *
> @@ -43,30 +44,28 @@ static void tce_build_iSeries(struct iom
>  		unsigned long uaddr, enum dma_data_direction direction)
>  {
>  	u64 rc;
> -	union tce_entry tce;
> +	u64 tce, rpn;
>  
>  	index <<= TCE_PAGE_FACTOR;
>  	npages <<= TCE_PAGE_FACTOR;
>  
>  	while (npages--) {
> -		tce.te_word = 0;
> -		tce.te_bits.tb_rpn = virt_to_abs(uaddr) >> TCE_SHIFT;
> +		rpn = virt_to_abs(uaddr) >> TCE_SHIFT;
> +		tce = (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT;
>  
>  		if (tbl->it_type == TCE_VB) {
>  			/* Virtual Bus */
> -			tce.te_bits.tb_valid = 1;
> -			tce.te_bits.tb_allio = 1;
> +			tce |= TCE_VALID|TCE_ALLIO;
>  			if (direction != DMA_TO_DEVICE)
> -				tce.te_bits.tb_rdwr = 1;
> +				tce |= TCE_VB_WRITE;
>  		} else {
>  			/* PCI Bus */
> -			tce.te_bits.tb_rdwr = 1; /* Read allowed */
> +			tce |= TCE_PCI_READ; /* Read allowed */
>  			if (direction != DMA_TO_DEVICE)
> -				tce.te_bits.tb_pciwr = 1;
> +				tce |= TCE_PCI_WRITE;
>  		}
>  
> -		rc = HvCallXm_setTce((u64)tbl->it_index, (u64)index,
> -				tce.te_word);
> +		rc = HvCallXm_setTce((u64)tbl->it_index, (u64)index, tce);
>  		if (rc)
>  			panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%lx\n",
>  					rc);
> @@ -124,7 +123,7 @@ void iommu_table_getparms_iSeries(unsign
>  
>  	/* itc_size is in pages worth of table, it_size is in # of entries */
>  	tbl->it_size = ((parms->itc_size * TCE_PAGE_SIZE) /
> -			sizeof(union tce_entry)) >> TCE_PAGE_FACTOR;
> +			TCE_ENTRY_SIZE) >> TCE_PAGE_FACTOR;
>  	tbl->it_busno = parms->itc_busno;
>  	tbl->it_offset = parms->itc_offset >> TCE_PAGE_FACTOR;
>  	tbl->it_index = parms->itc_index;
> Index: powerpc/arch/powerpc/platforms/pseries/iommu.c
> ===================================================================
> --- powerpc.orig/arch/powerpc/platforms/pseries/iommu.c
> +++ powerpc/arch/powerpc/platforms/pseries/iommu.c
> @@ -1,23 +1,24 @@
>  /*
>   * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
>   *
> - * Rewrite, cleanup: 
> + * Rewrite, cleanup:
>   *
>   * Copyright (C) 2004 Olof Johansson <olof@lixom.net>, IBM Corporation
> + * Copyright (C) 2006 Olof Johansson <olof@lixom.net>
>   *
>   * Dynamic DMA mapping support, pSeries-specific parts, both SMP and LPAR.
>   *
> - * 
> + *
>   * This program is free software; you can redistribute it and/or modify
>   * it under the terms of the GNU General Public License as published by
>   * the Free Software Foundation; either version 2 of the License, or
>   * (at your option) any later version.
> - * 
> + *
>   * This program is distributed in the hope that it will be useful,
>   * but WITHOUT ANY WARRANTY; without even the implied warranty of
>   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>   * GNU General Public License for more details.
> - * 
> + *
>   * You should have received a copy of the GNU General Public License
>   * along with this program; if not, write to the Free Software
>   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
> @@ -49,52 +50,46 @@
>  
>  #define DBG(fmt...)
>  
> -static void tce_build_pSeries(struct iommu_table *tbl, long index, 
> -			      long npages, unsigned long uaddr, 
> +static void tce_build_pSeries(struct iommu_table *tbl, long index,
> +			      long npages, unsigned long uaddr,
>  			      enum dma_data_direction direction)
>  {
> -	union tce_entry t;
> -	union tce_entry *tp;
> +	u64 proto_tce;
> +	u64 *tcep;
> +	u64 rpn;
>  
>  	index <<= TCE_PAGE_FACTOR;
>  	npages <<= TCE_PAGE_FACTOR;
>  
> -	t.te_word = 0;
> -	t.te_rdwr = 1; // Read allowed 
> +	proto_tce = TCE_PCI_READ; // Read allowed
>  
>  	if (direction != DMA_TO_DEVICE)
> -		t.te_pciwr = 1;
> +		proto_tce |= TCE_PCI_WRITE;
>  
> -	tp = ((union tce_entry *)tbl->it_base) + index;
> +	tcep = ((u64 *)tbl->it_base) + index;
>  
>  	while (npages--) {
>  		/* can't move this out since we might cross LMB boundary */
> -		t.te_rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT;
> -	
> -		tp->te_word = t.te_word;
> +		rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT;
> +		*tcep = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT;
>  
>  		uaddr += TCE_PAGE_SIZE;
> -		tp++;
> +		tcep++;
>  	}
>  }
>  
>  
>  static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages)
>  {
> -	union tce_entry t;
> -	union tce_entry *tp;
> +	u64 *tcep;
>  
>  	npages <<= TCE_PAGE_FACTOR;
>  	index <<= TCE_PAGE_FACTOR;
>  
> -	t.te_word = 0;
> -	tp  = ((union tce_entry *)tbl->it_base) + index;
> -		
> -	while (npages--) {
> -		tp->te_word = t.te_word;
> -		
> -		tp++;
> -	}
> +	tcep = ((u64 *)tbl->it_base) + index;
> +
> +	while (npages--)
> +		*(tcep++) = 0;
>  }
>  
>  
> @@ -103,43 +98,44 @@ static void tce_build_pSeriesLP(struct i
>  				enum dma_data_direction direction)
>  {
>  	u64 rc;
> -	union tce_entry tce;
> +	u64 proto_tce, tce;
> +	u64 rpn;
>  
>  	tcenum <<= TCE_PAGE_FACTOR;
>  	npages <<= TCE_PAGE_FACTOR;
>  
> -	tce.te_word = 0;
> -	tce.te_rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT;
> -	tce.te_rdwr = 1;
> +	rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT;
> +	proto_tce = TCE_PCI_READ;
>  	if (direction != DMA_TO_DEVICE)
> -		tce.te_pciwr = 1;
> +		proto_tce |= TCE_PCI_WRITE;
>  
>  	while (npages--) {
> -		rc = plpar_tce_put((u64)tbl->it_index, 
> -				   (u64)tcenum << 12, 
> -				   tce.te_word );
> -		
> +		tce = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT;
> +		rc = plpar_tce_put((u64)tbl->it_index, (u64)tcenum << 12, tce);
> +
>  		if (rc && printk_ratelimit()) {
>  			printk("tce_build_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc);
>  			printk("\tindex   = 0x%lx\n", (u64)tbl->it_index);
>  			printk("\ttcenum  = 0x%lx\n", (u64)tcenum);
> -			printk("\ttce val = 0x%lx\n", tce.te_word );
> +			printk("\ttce val = 0x%lx\n", tce );
>  			show_stack(current, (unsigned long *)__get_SP());
>  		}
> -			
> +
>  		tcenum++;
> -		tce.te_rpn++;
> +		rpn++;
>  	}
>  }
>  
> -static DEFINE_PER_CPU(void *, tce_page) = NULL;
> +static DEFINE_PER_CPU(u64 *, tce_page) = NULL;
>  
>  static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
>  				     long npages, unsigned long uaddr,
>  				     enum dma_data_direction direction)
>  {
>  	u64 rc;
> -	union tce_entry tce, *tcep;
> +	u64 proto_tce;
> +	u64 *tcep;
> +	u64 rpn;
>  	long l, limit;
>  
>  	if (TCE_PAGE_FACTOR == 0 && npages == 1)
> @@ -152,7 +148,7 @@ static void tce_buildmulti_pSeriesLP(str
>  	 * from iommu_alloc{,_sg}()
>  	 */
>  	if (!tcep) {
> -		tcep = (void *)__get_free_page(GFP_ATOMIC);
> +		tcep = (u64 *)__get_free_page(GFP_ATOMIC);
>  		/* If allocation fails, fall back to the loop implementation */
>  		if (!tcep)
>  			return tce_build_pSeriesLP(tbl, tcenum, npages,
> @@ -163,11 +159,10 @@ static void tce_buildmulti_pSeriesLP(str
>  	tcenum <<= TCE_PAGE_FACTOR;
>  	npages <<= TCE_PAGE_FACTOR;
>  
> -	tce.te_word = 0;
> -	tce.te_rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT;
> -	tce.te_rdwr = 1;
> +	rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT;
> +	proto_tce = TCE_PCI_READ;
>  	if (direction != DMA_TO_DEVICE)
> -		tce.te_pciwr = 1;
> +		proto_tce |= TCE_PCI_WRITE;
>  
>  	/* We can map max one pageful of TCEs at a time */
>  	do {
> @@ -175,11 +170,11 @@ static void tce_buildmulti_pSeriesLP(str
>  		 * Set up the page with TCE data, looping through and setting
>  		 * the values.
>  		 */
> -		limit = min_t(long, npages, 4096/sizeof(union tce_entry));
> +		limit = min_t(long, npages, 4096/TCE_ENTRY_SIZE);
>  
>  		for (l = 0; l < limit; l++) {
> -			tcep[l] = tce;
> -			tce.te_rpn++;
> +			tcep[l] = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT;
> +			rpn++;
>  		}
>  
>  		rc = plpar_tce_put_indirect((u64)tbl->it_index,
> @@ -195,7 +190,7 @@ static void tce_buildmulti_pSeriesLP(str
>  		printk("tce_buildmulti_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc);
>  		printk("\tindex   = 0x%lx\n", (u64)tbl->it_index);
>  		printk("\tnpages  = 0x%lx\n", (u64)npages);
> -		printk("\ttce[0] val = 0x%lx\n", tcep[0].te_word);
> +		printk("\ttce[0] val = 0x%lx\n", tcep[0]);
>  		show_stack(current, (unsigned long *)__get_SP());
>  	}
>  }
> @@ -203,23 +198,17 @@ static void tce_buildmulti_pSeriesLP(str
>  static void tce_free_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages)
>  {
>  	u64 rc;
> -	union tce_entry tce;
>  
>  	tcenum <<= TCE_PAGE_FACTOR;
>  	npages <<= TCE_PAGE_FACTOR;
>  
> -	tce.te_word = 0;
> -
>  	while (npages--) {
> -		rc = plpar_tce_put((u64)tbl->it_index,
> -				   (u64)tcenum << 12,
> -				   tce.te_word);
> +		rc = plpar_tce_put((u64)tbl->it_index, (u64)tcenum << 12, 0);
>  
>  		if (rc && printk_ratelimit()) {
>  			printk("tce_free_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc);
>  			printk("\tindex   = 0x%lx\n", (u64)tbl->it_index);
>  			printk("\ttcenum  = 0x%lx\n", (u64)tcenum);
> -			printk("\ttce val = 0x%lx\n", tce.te_word );
>  			show_stack(current, (unsigned long *)__get_SP());
>  		}
>  
> @@ -231,31 +220,24 @@ static void tce_free_pSeriesLP(struct io
>  static void tce_freemulti_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages)
>  {
>  	u64 rc;
> -	union tce_entry tce;
>  
>  	tcenum <<= TCE_PAGE_FACTOR;
>  	npages <<= TCE_PAGE_FACTOR;
>  
> -	tce.te_word = 0;
> -
> -	rc = plpar_tce_stuff((u64)tbl->it_index,
> -			   (u64)tcenum << 12,
> -			   tce.te_word,
> -			   npages);
> +	rc = plpar_tce_stuff((u64)tbl->it_index, (u64)tcenum << 12, 0, npages);
>  
>  	if (rc && printk_ratelimit()) {
>  		printk("tce_freemulti_pSeriesLP: plpar_tce_stuff failed\n");
>  		printk("\trc      = %ld\n", rc);
>  		printk("\tindex   = 0x%lx\n", (u64)tbl->it_index);
>  		printk("\tnpages  = 0x%lx\n", (u64)npages);
> -		printk("\ttce val = 0x%lx\n", tce.te_word );
>  		show_stack(current, (unsigned long *)__get_SP());
>  	}
>  }
>  
>  static void iommu_table_setparms(struct pci_controller *phb,
>  				 struct device_node *dn,
> -				 struct iommu_table *tbl) 
> +				 struct iommu_table *tbl)
>  {
>  	struct device_node *node;
>  	unsigned long *basep;
> @@ -275,16 +257,16 @@ static void iommu_table_setparms(struct 
>  	memset((void *)tbl->it_base, 0, *sizep);
>  
>  	tbl->it_busno = phb->bus->number;
> -	
> +
>  	/* Units of tce entries */
>  	tbl->it_offset = phb->dma_window_base_cur >> PAGE_SHIFT;
> -	
> +
>  	/* Test if we are going over 2GB of DMA space */
>  	if (phb->dma_window_base_cur + phb->dma_window_size > 0x80000000ul) {
>  		udbg_printf("PCI_DMA: Unexpected number of IOAs under this PHB.\n");
> -		panic("PCI_DMA: Unexpected number of IOAs under this PHB.\n"); 
> +		panic("PCI_DMA: Unexpected number of IOAs under this PHB.\n");
>  	}
> -	
> +
>  	phb->dma_window_base_cur += phb->dma_window_size;
>  
>  	/* Set the tce table size - measured in entries */
> @@ -442,7 +424,7 @@ static void iommu_bus_setup_pSeriesLP(st
>  
>  		tbl = (struct iommu_table *)kmalloc(sizeof(struct iommu_table),
>  						    GFP_KERNEL);
> -	
> +
>  		iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window);
>  
>  		ppci->iommu_table = iommu_init_table(tbl);
> Index: powerpc/include/asm-powerpc/tce.h
> ===================================================================
> --- powerpc.orig/include/asm-powerpc/tce.h
> +++ powerpc/include/asm-powerpc/tce.h
> @@ -35,32 +35,15 @@
>  #define TCE_PAGE_SIZE	(1 << TCE_SHIFT)
>  #define TCE_PAGE_FACTOR	(PAGE_SHIFT - TCE_SHIFT)
>  
> +#define TCE_ENTRY_SIZE		8		/* each TCE is 64 bits */
>  
> -/* tce_entry
> - * Used by pSeries (SMP) and iSeries/pSeries LPAR, but there it's
> - * abstracted so layout is irrelevant.
> - */
> -union tce_entry {
> -   	unsigned long te_word;
> -	struct {
> -		unsigned int  tb_cacheBits :6;	/* Cache hash bits - not used */
> -		unsigned int  tb_rsvd      :6;
> -		unsigned long tb_rpn       :40;	/* Real page number */
> -		unsigned int  tb_valid     :1;	/* Tce is valid (vb only) */
> -		unsigned int  tb_allio     :1;	/* Tce is valid for all lps (vb only) */
> -		unsigned int  tb_lpindex   :8;	/* LpIndex for user of TCE (vb only) */
> -		unsigned int  tb_pciwr     :1;	/* Write allowed (pci only) */
> -		unsigned int  tb_rdwr      :1;	/* Read allowed  (pci), Write allowed (vb) */
> -	} te_bits;
> -#define te_cacheBits te_bits.tb_cacheBits
> -#define te_rpn       te_bits.tb_rpn
> -#define te_valid     te_bits.tb_valid
> -#define te_allio     te_bits.tb_allio
> -#define te_lpindex   te_bits.tb_lpindex
> -#define te_pciwr     te_bits.tb_pciwr
> -#define te_rdwr      te_bits.tb_rdwr
> -};
> -
> +#define TCE_RPN_MASK		0xfffffffffful  /* 40-bit RPN (4K pages) */
> +#define TCE_RPN_SHIFT		12
> +#define TCE_VALID		0x200		/* TCE valid */
> +#define TCE_ALLIO		0x100		/* TCE valid for all lpars */
> +#define TCE_PCI_WRITE		0x2		/* write from PCI allowed */
> +#define TCE_PCI_READ		0x1		/* read from PCI allowed */
> +#define TCE_VB_WRITE		0x1		/* write from VB allowed */
>  
>  #endif /* __KERNEL__ */
>  #endif /* _ASM_POWERPC_TCE_H */
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev

^ permalink raw reply

* Re: FT u-boot shim
From: Tom Rini @ 2006-04-28 19:44 UTC (permalink / raw)
  To: Wolfgang Denk; +Cc: linuxppc-dev@ozlabs.org list, Paul Mackerras
In-Reply-To: <20060428191124.B202B353DAC@atlas.denx.de>

On Fri, Apr 28, 2006 at 09:11:24PM +0200, Wolfgang Denk wrote:
> In message <EA2821E8-FB7E-4DDA-8C18-C659B5483DC2@kernel.crashing.org>
> Kumar Gala wrote:
> > 
> > What I envision as the way one boots for something like u-boot is one  
> > of three options:
> > 1. using an old u-boot + boot wrapper (bd_t -> wrapper -> kernel)
> > 2. using a u-boot that is ft aware + dtb (boot command in u-boot  
> > takes kernel & dtb images, updates blob and passes to kernel)
> > 3. using a u-boot that is ft aware + built in dtb.
> > 
> > The issue is that for a given system/board you may need to support  
> > multiple or all three.  This raises the question where does the .dts  
> 
> Assuming we had 2., under which circumstances would we need 3. then?

Especially if we had mkuimage let you tack your dtb into the 'kernel'
image.

-- 
Tom Rini
http://gate.crashing.org/~trini/

^ permalink raw reply

* [patch 0/4] cell: support multi-platform image
From: Geoff Levand @ 2006-04-28 21:44 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev, cbe-oss-dev, arnd

Paul,

This series of patches adds support to build multi-platform
images with Cell BPA targets.

These patches apply to current powerpc.git, and should be
considered for inclusion in 2.6.18

They have already seen some review on the
cbe-oss-dev@ozlabs.org ML.

-Geoff

^ permalink raw reply

* [patch 1/4] spufs: add missing headers
From: Geoff Levand @ 2006-04-28 21:44 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev, cbe-oss-dev, arnd

Add spu.h header dependencies.  Fixes these errors:

spu.h:168: warning: 'struct file' declared inside parameter list
spu.h:186: error: syntax error before 'cell_spumem_init'


Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>

---
Index: linux-powerpc.git/include/asm-powerpc/spu.h
===================================================================
--- linux-powerpc.git.orig/include/asm-powerpc/spu.h	2006-04-28 14:32:25.000000000 -0700
+++ linux-powerpc.git/include/asm-powerpc/spu.h	2006-04-28 14:38:18.000000000 -0700
@@ -27,6 +27,8 @@
 #include <linux/config.h>
 #include <linux/kref.h>
 #include <linux/workqueue.h>
+#include <linux/file.h>
+#include <linux/init.h>

 #define LS_SIZE (256 * 1024)
 #define LS_ADDR_MASK (LS_SIZE - 1)

^ permalink raw reply

* [patch 2/4] cell: split out platform code
From: Geoff Levand @ 2006-04-28 21:44 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev, cbe-oss-dev, arnd

Split the Cell BPA support into generic and platform
dependant parts.

Creates a new config variable CONFIG_PPC_IBM_CELL_BLADE.
The existing CONFIG_PPC_CELL is now used to denote the
generic Cell processor support.  Also renames spu_priv1.c
to spu_priv1_mmio.c.


Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>

---
Index: linux-powerpc.git/arch/powerpc/Kconfig
===================================================================
--- linux-powerpc.git.orig/arch/powerpc/Kconfig	2006-04-28 14:32:25.000000000 -0700
+++ linux-powerpc.git/arch/powerpc/Kconfig	2006-04-28 14:34:06.000000000 -0700
@@ -391,11 +391,17 @@
 	  For more informations, refer to <http://www.970eval.com>

 config PPC_CELL
-	bool "  Cell Broadband Processor Architecture"
+	bool
+	default n
+
+config PPC_IBM_CELL_BLADE
+	bool "  IBM Cell Blade"
 	depends on PPC_MULTIPLATFORM && PPC64
+	select PPC_CELL
 	select PPC_RTAS
 	select MMIO_NVRAM
 	select PPC_UDBG_16550
+	select SPUFS_PRIV1_MMIO

 config XICS
 	depends on PPC_PSERIES
@@ -440,7 +446,7 @@
 	default y

 config CELL_IIC
-	depends on PPC_CELL
+	depends on PPC_IBM_CELL_BLADE
 	bool
 	default y

Index: linux-powerpc.git/arch/powerpc/configs/cell_defconfig
===================================================================
--- linux-powerpc.git.orig/arch/powerpc/configs/cell_defconfig	2006-04-28 14:32:25.000000000 -0700
+++ linux-powerpc.git/arch/powerpc/configs/cell_defconfig	2006-04-28 14:34:06.000000000 -0700
@@ -118,6 +118,7 @@
 # CONFIG_PPC_PMAC is not set
 # CONFIG_PPC_MAPLE is not set
 CONFIG_PPC_CELL=y
+CONFIG_PPC_IBM_CELL_BLADE=y
 # CONFIG_U3_DART is not set
 CONFIG_PPC_RTAS=y
 # CONFIG_RTAS_ERROR_LOGGING is not set
@@ -133,6 +134,8 @@
 # Cell Broadband Engine options
 #
 CONFIG_SPU_FS=m
+CONFIG_SPU_BASE=y
+CONFIG_SPUFS_PRIV1_MMIO=y
 CONFIG_SPUFS_MMAP=y

 #
Index: linux-powerpc.git/arch/powerpc/platforms/cell/Kconfig
===================================================================
--- linux-powerpc.git.orig/arch/powerpc/platforms/cell/Kconfig	2006-04-28 14:32:25.000000000 -0700
+++ linux-powerpc.git/arch/powerpc/platforms/cell/Kconfig	2006-04-28 14:34:06.000000000 -0700
@@ -5,11 +5,20 @@
 	tristate "SPU file system"
 	default m
 	depends on PPC_CELL
+	select SPU_BASE
 	help
 	  The SPU file system is used to access Synergistic Processing
 	  Units on machines implementing the Broadband Processor
 	  Architecture.

+config SPU_BASE
+	bool
+	default n
+
+config SPUFS_PRIV1_MMIO
+	bool
+	default n
+
 config SPUFS_MMAP
 	bool
 	depends on SPU_FS && SPARSEMEM && !PPC_64K_PAGES
Index: linux-powerpc.git/arch/powerpc/platforms/cell/Makefile
===================================================================
--- linux-powerpc.git.orig/arch/powerpc/platforms/cell/Makefile	2006-04-28 14:32:25.000000000 -0700
+++ linux-powerpc.git/arch/powerpc/platforms/cell/Makefile	2006-04-28 14:34:06.000000000 -0700
@@ -1,16 +1,13 @@
-obj-y			+= interrupt.o iommu.o setup.o spider-pic.o
-obj-y			+= pervasive.o
-
-obj-$(CONFIG_SMP)	+= smp.o
-obj-$(CONFIG_SPU_FS)	+= spu-base.o spufs/
-
-spu-base-y		+= spu_base.o spu_priv1.o
+obj-$(CONFIG_PPC_IBM_CELL_BLADE)	+= interrupt.o iommu.o setup.o \
+					   spider-pic.o pervasive.o
+ifeq ($(CONFIG_SMP),y)
+obj-$(CONFIG_PPC_IBM_CELL_BLADE)	+= smp.o
+endif

 # needed only when building loadable spufs.ko
-spufs-modular-$(CONFIG_SPU_FS) += spu_syscalls.o
-obj-y			+= $(spufs-modular-m)
-
-# always needed in kernel
-spufs-builtin-$(CONFIG_SPU_FS) += spu_callbacks.o
-obj-y			+= $(spufs-builtin-y) $(spufs-builtin-m)
+spufs-modular-$(CONFIG_SPU_FS)		+= spu_syscalls.o

+obj-$(CONFIG_SPU_BASE)			+= spu_callbacks.o spu_base.o \
+					   $(spufs-modular-m)
+obj-$(CONFIG_SPUFS_PRIV1_MMIO)		+= spu_priv1_mmio.o
+obj-$(CONFIG_SPU_FS)			+= spufs/
Index: linux-powerpc.git/arch/powerpc/platforms/cell/spu_priv1.c
===================================================================
--- linux-powerpc.git.orig/arch/powerpc/platforms/cell/spu_priv1.c	2006-04-28 14:32:25.000000000 -0700
+++ linux-powerpc.git/arch/powerpc/platforms/cell/spu_priv1.c	2006-04-21 13:04:41.284693750 -0700
@@ -1,133 +0,0 @@
-/*
- * access to SPU privileged registers
- */
-#include <linux/module.h>
-
-#include <asm/io.h>
-#include <asm/spu.h>
-
-void spu_int_mask_and(struct spu *spu, int class, u64 mask)
-{
-	u64 old_mask;
-
-	old_mask = in_be64(&spu->priv1->int_mask_RW[class]);
-	out_be64(&spu->priv1->int_mask_RW[class], old_mask & mask);
-}
-EXPORT_SYMBOL_GPL(spu_int_mask_and);
-
-void spu_int_mask_or(struct spu *spu, int class, u64 mask)
-{
-	u64 old_mask;
-
-	old_mask = in_be64(&spu->priv1->int_mask_RW[class]);
-	out_be64(&spu->priv1->int_mask_RW[class], old_mask | mask);
-}
-EXPORT_SYMBOL_GPL(spu_int_mask_or);
-
-void spu_int_mask_set(struct spu *spu, int class, u64 mask)
-{
-	out_be64(&spu->priv1->int_mask_RW[class], mask);
-}
-EXPORT_SYMBOL_GPL(spu_int_mask_set);
-
-u64 spu_int_mask_get(struct spu *spu, int class)
-{
-	return in_be64(&spu->priv1->int_mask_RW[class]);
-}
-EXPORT_SYMBOL_GPL(spu_int_mask_get);
-
-void spu_int_stat_clear(struct spu *spu, int class, u64 stat)
-{
-	out_be64(&spu->priv1->int_stat_RW[class], stat);
-}
-EXPORT_SYMBOL_GPL(spu_int_stat_clear);
-
-u64 spu_int_stat_get(struct spu *spu, int class)
-{
-	return in_be64(&spu->priv1->int_stat_RW[class]);
-}
-EXPORT_SYMBOL_GPL(spu_int_stat_get);
-
-void spu_int_route_set(struct spu *spu, u64 route)
-{
-	out_be64(&spu->priv1->int_route_RW, route);
-}
-EXPORT_SYMBOL_GPL(spu_int_route_set);
-
-u64 spu_mfc_dar_get(struct spu *spu)
-{
-	return in_be64(&spu->priv1->mfc_dar_RW);
-}
-EXPORT_SYMBOL_GPL(spu_mfc_dar_get);
-
-u64 spu_mfc_dsisr_get(struct spu *spu)
-{
-	return in_be64(&spu->priv1->mfc_dsisr_RW);
-}
-EXPORT_SYMBOL_GPL(spu_mfc_dsisr_get);
-
-void spu_mfc_dsisr_set(struct spu *spu, u64 dsisr)
-{
-	out_be64(&spu->priv1->mfc_dsisr_RW, dsisr);
-}
-EXPORT_SYMBOL_GPL(spu_mfc_dsisr_set);
-
-void spu_mfc_sdr_set(struct spu *spu, u64 sdr)
-{
-	out_be64(&spu->priv1->mfc_sdr_RW, sdr);
-}
-EXPORT_SYMBOL_GPL(spu_mfc_sdr_set);
-
-void spu_mfc_sr1_set(struct spu *spu, u64 sr1)
-{
-	out_be64(&spu->priv1->mfc_sr1_RW, sr1);
-}
-EXPORT_SYMBOL_GPL(spu_mfc_sr1_set);
-
-u64 spu_mfc_sr1_get(struct spu *spu)
-{
-	return in_be64(&spu->priv1->mfc_sr1_RW);
-}
-EXPORT_SYMBOL_GPL(spu_mfc_sr1_get);
-
-void spu_mfc_tclass_id_set(struct spu *spu, u64 tclass_id)
-{
-	out_be64(&spu->priv1->mfc_tclass_id_RW, tclass_id);
-}
-EXPORT_SYMBOL_GPL(spu_mfc_tclass_id_set);
-
-u64 spu_mfc_tclass_id_get(struct spu *spu)
-{
-	return in_be64(&spu->priv1->mfc_tclass_id_RW);
-}
-EXPORT_SYMBOL_GPL(spu_mfc_tclass_id_get);
-
-void spu_tlb_invalidate(struct spu *spu)
-{
-	out_be64(&spu->priv1->tlb_invalidate_entry_W, 0ul);
-}
-EXPORT_SYMBOL_GPL(spu_tlb_invalidate);
-
-void spu_resource_allocation_groupID_set(struct spu *spu, u64 id)
-{
-	out_be64(&spu->priv1->resource_allocation_groupID_RW, id);
-}
-EXPORT_SYMBOL_GPL(spu_resource_allocation_groupID_set);
-
-u64 spu_resource_allocation_groupID_get(struct spu *spu)
-{
-	return in_be64(&spu->priv1->resource_allocation_groupID_RW);
-}
-EXPORT_SYMBOL_GPL(spu_resource_allocation_groupID_get);
-
-void spu_resource_allocation_enable_set(struct spu *spu, u64 enable)
-{
-	out_be64(&spu->priv1->resource_allocation_enable_RW, enable);
-}
-EXPORT_SYMBOL_GPL(spu_resource_allocation_enable_set);
-
-u64 spu_resource_allocation_enable_get(struct spu *spu)
-{
-	return in_be64(&spu->priv1->resource_allocation_enable_RW);
-}
-EXPORT_SYMBOL_GPL(spu_resource_allocation_enable_get);
Index: linux-powerpc.git/arch/powerpc/platforms/cell/spu_priv1_mmio.c
===================================================================
--- linux-powerpc.git.orig/arch/powerpc/platforms/cell/spu_priv1_mmio.c	2006-04-21 13:04:41.284693750 -0700
+++ linux-powerpc.git/arch/powerpc/platforms/cell/spu_priv1_mmio.c	2006-04-28 14:38:18.000000000 -0700
@@ -0,0 +1,133 @@
+/*
+ * access to SPU privileged registers
+ */
+#include <linux/module.h>
+
+#include <asm/io.h>
+#include <asm/spu.h>
+
+void spu_int_mask_and(struct spu *spu, int class, u64 mask)
+{
+	u64 old_mask;
+
+	old_mask = in_be64(&spu->priv1->int_mask_RW[class]);
+	out_be64(&spu->priv1->int_mask_RW[class], old_mask & mask);
+}
+EXPORT_SYMBOL_GPL(spu_int_mask_and);
+
+void spu_int_mask_or(struct spu *spu, int class, u64 mask)
+{
+	u64 old_mask;
+
+	old_mask = in_be64(&spu->priv1->int_mask_RW[class]);
+	out_be64(&spu->priv1->int_mask_RW[class], old_mask | mask);
+}
+EXPORT_SYMBOL_GPL(spu_int_mask_or);
+
+void spu_int_mask_set(struct spu *spu, int class, u64 mask)
+{
+	out_be64(&spu->priv1->int_mask_RW[class], mask);
+}
+EXPORT_SYMBOL_GPL(spu_int_mask_set);
+
+u64 spu_int_mask_get(struct spu *spu, int class)
+{
+	return in_be64(&spu->priv1->int_mask_RW[class]);
+}
+EXPORT_SYMBOL_GPL(spu_int_mask_get);
+
+void spu_int_stat_clear(struct spu *spu, int class, u64 stat)
+{
+	out_be64(&spu->priv1->int_stat_RW[class], stat);
+}
+EXPORT_SYMBOL_GPL(spu_int_stat_clear);
+
+u64 spu_int_stat_get(struct spu *spu, int class)
+{
+	return in_be64(&spu->priv1->int_stat_RW[class]);
+}
+EXPORT_SYMBOL_GPL(spu_int_stat_get);
+
+void spu_int_route_set(struct spu *spu, u64 route)
+{
+	out_be64(&spu->priv1->int_route_RW, route);
+}
+EXPORT_SYMBOL_GPL(spu_int_route_set);
+
+u64 spu_mfc_dar_get(struct spu *spu)
+{
+	return in_be64(&spu->priv1->mfc_dar_RW);
+}
+EXPORT_SYMBOL_GPL(spu_mfc_dar_get);
+
+u64 spu_mfc_dsisr_get(struct spu *spu)
+{
+	return in_be64(&spu->priv1->mfc_dsisr_RW);
+}
+EXPORT_SYMBOL_GPL(spu_mfc_dsisr_get);
+
+void spu_mfc_dsisr_set(struct spu *spu, u64 dsisr)
+{
+	out_be64(&spu->priv1->mfc_dsisr_RW, dsisr);
+}
+EXPORT_SYMBOL_GPL(spu_mfc_dsisr_set);
+
+void spu_mfc_sdr_set(struct spu *spu, u64 sdr)
+{
+	out_be64(&spu->priv1->mfc_sdr_RW, sdr);
+}
+EXPORT_SYMBOL_GPL(spu_mfc_sdr_set);
+
+void spu_mfc_sr1_set(struct spu *spu, u64 sr1)
+{
+	out_be64(&spu->priv1->mfc_sr1_RW, sr1);
+}
+EXPORT_SYMBOL_GPL(spu_mfc_sr1_set);
+
+u64 spu_mfc_sr1_get(struct spu *spu)
+{
+	return in_be64(&spu->priv1->mfc_sr1_RW);
+}
+EXPORT_SYMBOL_GPL(spu_mfc_sr1_get);
+
+void spu_mfc_tclass_id_set(struct spu *spu, u64 tclass_id)
+{
+	out_be64(&spu->priv1->mfc_tclass_id_RW, tclass_id);
+}
+EXPORT_SYMBOL_GPL(spu_mfc_tclass_id_set);
+
+u64 spu_mfc_tclass_id_get(struct spu *spu)
+{
+	return in_be64(&spu->priv1->mfc_tclass_id_RW);
+}
+EXPORT_SYMBOL_GPL(spu_mfc_tclass_id_get);
+
+void spu_tlb_invalidate(struct spu *spu)
+{
+	out_be64(&spu->priv1->tlb_invalidate_entry_W, 0ul);
+}
+EXPORT_SYMBOL_GPL(spu_tlb_invalidate);
+
+void spu_resource_allocation_groupID_set(struct spu *spu, u64 id)
+{
+	out_be64(&spu->priv1->resource_allocation_groupID_RW, id);
+}
+EXPORT_SYMBOL_GPL(spu_resource_allocation_groupID_set);
+
+u64 spu_resource_allocation_groupID_get(struct spu *spu)
+{
+	return in_be64(&spu->priv1->resource_allocation_groupID_RW);
+}
+EXPORT_SYMBOL_GPL(spu_resource_allocation_groupID_get);
+
+void spu_resource_allocation_enable_set(struct spu *spu, u64 enable)
+{
+	out_be64(&spu->priv1->resource_allocation_enable_RW, enable);
+}
+EXPORT_SYMBOL_GPL(spu_resource_allocation_enable_set);
+
+u64 spu_resource_allocation_enable_get(struct spu *spu)
+{
+	return in_be64(&spu->priv1->resource_allocation_enable_RW);
+}
+EXPORT_SYMBOL_GPL(spu_resource_allocation_enable_get);
Index: linux-powerpc.git/drivers/net/Kconfig
===================================================================
--- linux-powerpc.git.orig/drivers/net/Kconfig	2006-04-28 14:32:25.000000000 -0700
+++ linux-powerpc.git/drivers/net/Kconfig	2006-04-28 14:34:06.000000000 -0700
@@ -2171,7 +2171,7 @@

 config SPIDER_NET
 	tristate "Spider Gigabit Ethernet driver"
-	depends on PCI && PPC_CELL
+	depends on PCI && PPC_IBM_CELL_BLADE
 	select FW_LOADER
 	help
 	  This driver supports the Gigabit Ethernet chips present on the

^ permalink raw reply

* [patch 3/4] spufs: support multi-platform priv1 access
From: Geoff Levand @ 2006-04-28 21:44 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev, cbe-oss-dev, arnd

To support muti-platform binaries the spu hypervisor accessor
routines must have runtime binding.

I removed the existing statically linked routines in spu.h
and spu_priv1_mmio.c and created new accessor routines in spu_priv1.h
that operate indirectly through an ops struct spu_priv1_ops.
spu_priv1_mmio.c contains the instance of the accessor routines
for running on raw hardware.


Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>

---
Index: linux-powerpc.git/arch/powerpc/platforms/cell/setup.c
===================================================================
--- linux-powerpc.git.orig/arch/powerpc/platforms/cell/setup.c	2006-04-28 14:32:25.000000000 -0700
+++ linux-powerpc.git/arch/powerpc/platforms/cell/setup.c	2006-04-28 14:34:06.000000000 -0700
@@ -46,6 +46,7 @@
 #include <asm/cputable.h>
 #include <asm/ppc-pci.h>
 #include <asm/irq.h>
+#include <asm/spu_priv1.h>

 #include "interrupt.h"
 #include "iommu.h"
@@ -149,6 +150,9 @@
 {
 	ppc_md.init_IRQ       = iic_init_IRQ;
 	ppc_md.get_irq        = iic_get_irq;
+#ifdef CONFIG_SPU_BASE
+	spu_priv1_ops         = &spu_priv1_mmio_ops;
+#endif

 #ifdef CONFIG_SMP
 	smp_init_cell();
Index: linux-powerpc.git/arch/powerpc/platforms/cell/spu_base.c
===================================================================
--- linux-powerpc.git.orig/arch/powerpc/platforms/cell/spu_base.c	2006-04-28 14:32:25.000000000 -0700
+++ linux-powerpc.git/arch/powerpc/platforms/cell/spu_base.c	2006-04-28 14:38:16.000000000 -0700
@@ -34,10 +34,15 @@
 #include <asm/prom.h>
 #include <linux/mutex.h>
 #include <asm/spu.h>
+#include <asm/spu_priv1.h>
 #include <asm/mmu_context.h>

 #include "interrupt.h"

+const struct spu_priv1_ops *spu_priv1_ops;
+
+EXPORT_SYMBOL_GPL(spu_priv1_ops);
+
 static int __spu_trap_invalid_dma(struct spu *spu)
 {
 	pr_debug("%s\n", __FUNCTION__);
@@ -687,6 +692,8 @@
 	struct device_node *node;
 	int ret;

+	BUG_ON(!spu_priv1_ops);
+
 	ret = -ENODEV;
 	for (node = of_find_node_by_type(NULL, "spe");
 			node; node = of_find_node_by_type(node, "spe")) {
Index: linux-powerpc.git/arch/powerpc/platforms/cell/spu_priv1_mmio.c
===================================================================
--- linux-powerpc.git.orig/arch/powerpc/platforms/cell/spu_priv1_mmio.c	2006-04-28 14:34:06.000000000 -0700
+++ linux-powerpc.git/arch/powerpc/platforms/cell/spu_priv1_mmio.c	2006-04-28 14:38:16.000000000 -0700
@@ -1,133 +1,165 @@
 /*
- * access to SPU privileged registers
+ * spu hypervisor abstraction for direct hardware access.
+ *
+ *  (C) Copyright IBM Deutschland Entwicklung GmbH 2005
+ *  Copyright 2006 Sony Corp.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
+
 #include <linux/module.h>

 #include <asm/io.h>
 #include <asm/spu.h>
+#include <asm/spu_priv1.h>

-void spu_int_mask_and(struct spu *spu, int class, u64 mask)
+static void int_mask_and(struct spu *spu, int class, u64 mask)
 {
 	u64 old_mask;

 	old_mask = in_be64(&spu->priv1->int_mask_RW[class]);
 	out_be64(&spu->priv1->int_mask_RW[class], old_mask & mask);
 }
-EXPORT_SYMBOL_GPL(spu_int_mask_and);

-void spu_int_mask_or(struct spu *spu, int class, u64 mask)
+static void int_mask_or(struct spu *spu, int class, u64 mask)
 {
 	u64 old_mask;

 	old_mask = in_be64(&spu->priv1->int_mask_RW[class]);
 	out_be64(&spu->priv1->int_mask_RW[class], old_mask | mask);
 }
-EXPORT_SYMBOL_GPL(spu_int_mask_or);

-void spu_int_mask_set(struct spu *spu, int class, u64 mask)
+static void int_mask_set(struct spu *spu, int class, u64 mask)
 {
 	out_be64(&spu->priv1->int_mask_RW[class], mask);
 }
-EXPORT_SYMBOL_GPL(spu_int_mask_set);

-u64 spu_int_mask_get(struct spu *spu, int class)
+static u64 int_mask_get(struct spu *spu, int class)
 {
 	return in_be64(&spu->priv1->int_mask_RW[class]);
 }
-EXPORT_SYMBOL_GPL(spu_int_mask_get);

-void spu_int_stat_clear(struct spu *spu, int class, u64 stat)
+static void int_stat_clear(struct spu *spu, int class, u64 stat)
 {
 	out_be64(&spu->priv1->int_stat_RW[class], stat);
 }
-EXPORT_SYMBOL_GPL(spu_int_stat_clear);

-u64 spu_int_stat_get(struct spu *spu, int class)
+static u64 int_stat_get(struct spu *spu, int class)
 {
 	return in_be64(&spu->priv1->int_stat_RW[class]);
 }
-EXPORT_SYMBOL_GPL(spu_int_stat_get);

-void spu_int_route_set(struct spu *spu, u64 route)
+static void int_route_set(struct spu *spu, u64 route)
 {
 	out_be64(&spu->priv1->int_route_RW, route);
 }
-EXPORT_SYMBOL_GPL(spu_int_route_set);

-u64 spu_mfc_dar_get(struct spu *spu)
+static u64 mfc_dar_get(struct spu *spu)
 {
 	return in_be64(&spu->priv1->mfc_dar_RW);
 }
-EXPORT_SYMBOL_GPL(spu_mfc_dar_get);

-u64 spu_mfc_dsisr_get(struct spu *spu)
+static u64 mfc_dsisr_get(struct spu *spu)
 {
 	return in_be64(&spu->priv1->mfc_dsisr_RW);
 }
-EXPORT_SYMBOL_GPL(spu_mfc_dsisr_get);

-void spu_mfc_dsisr_set(struct spu *spu, u64 dsisr)
+static void mfc_dsisr_set(struct spu *spu, u64 dsisr)
 {
 	out_be64(&spu->priv1->mfc_dsisr_RW, dsisr);
 }
-EXPORT_SYMBOL_GPL(spu_mfc_dsisr_set);

-void spu_mfc_sdr_set(struct spu *spu, u64 sdr)
+static void mfc_sdr_set(struct spu *spu, u64 sdr)
 {
 	out_be64(&spu->priv1->mfc_sdr_RW, sdr);
 }
-EXPORT_SYMBOL_GPL(spu_mfc_sdr_set);

-void spu_mfc_sr1_set(struct spu *spu, u64 sr1)
+static void mfc_sr1_set(struct spu *spu, u64 sr1)
 {
 	out_be64(&spu->priv1->mfc_sr1_RW, sr1);
 }
-EXPORT_SYMBOL_GPL(spu_mfc_sr1_set);

-u64 spu_mfc_sr1_get(struct spu *spu)
+static u64 mfc_sr1_get(struct spu *spu)
 {
 	return in_be64(&spu->priv1->mfc_sr1_RW);
 }
-EXPORT_SYMBOL_GPL(spu_mfc_sr1_get);

-void spu_mfc_tclass_id_set(struct spu *spu, u64 tclass_id)
+static void mfc_tclass_id_set(struct spu *spu, u64 tclass_id)
 {
 	out_be64(&spu->priv1->mfc_tclass_id_RW, tclass_id);
 }
-EXPORT_SYMBOL_GPL(spu_mfc_tclass_id_set);

-u64 spu_mfc_tclass_id_get(struct spu *spu)
+static u64 mfc_tclass_id_get(struct spu *spu)
 {
 	return in_be64(&spu->priv1->mfc_tclass_id_RW);
 }
-EXPORT_SYMBOL_GPL(spu_mfc_tclass_id_get);

-void spu_tlb_invalidate(struct spu *spu)
+static void smm_pgsz_set(struct spu *spu, u64 pgsz)
+{
+	u64 smm_hid;
+	smm_hid = in_be64(&spu->priv1->smm_hid);
+	smm_hid &= ~(0xfull << 60);
+	smm_hid |= pgsz << 60;
+	out_be64(&spu->priv1->smm_hid, smm_hid);
+}
+
+static void tlb_invalidate(struct spu *spu)
 {
 	out_be64(&spu->priv1->tlb_invalidate_entry_W, 0ul);
 }
-EXPORT_SYMBOL_GPL(spu_tlb_invalidate);

-void spu_resource_allocation_groupID_set(struct spu *spu, u64 id)
+static void resource_allocation_groupID_set(struct spu *spu, u64 id)
 {
 	out_be64(&spu->priv1->resource_allocation_groupID_RW, id);
 }
-EXPORT_SYMBOL_GPL(spu_resource_allocation_groupID_set);

-u64 spu_resource_allocation_groupID_get(struct spu *spu)
+static u64 resource_allocation_groupID_get(struct spu *spu)
 {
 	return in_be64(&spu->priv1->resource_allocation_groupID_RW);
 }
-EXPORT_SYMBOL_GPL(spu_resource_allocation_groupID_get);

-void spu_resource_allocation_enable_set(struct spu *spu, u64 enable)
+static void resource_allocation_enable_set(struct spu *spu, u64 enable)
 {
 	out_be64(&spu->priv1->resource_allocation_enable_RW, enable);
 }
-EXPORT_SYMBOL_GPL(spu_resource_allocation_enable_set);

-u64 spu_resource_allocation_enable_get(struct spu *spu)
+static u64 resource_allocation_enable_get(struct spu *spu)
 {
 	return in_be64(&spu->priv1->resource_allocation_enable_RW);
 }
-EXPORT_SYMBOL_GPL(spu_resource_allocation_enable_get);
+
+const struct spu_priv1_ops spu_priv1_mmio_ops =
+{
+	.int_mask_and = int_mask_and,
+	.int_mask_or = int_mask_or,
+	.int_mask_set = int_mask_set,
+	.int_mask_get = int_mask_get,
+	.int_stat_clear = int_stat_clear,
+	.int_stat_get = int_stat_get,
+	.int_route_set = int_route_set,
+	.mfc_dar_get = mfc_dar_get,
+	.mfc_dsisr_get = mfc_dsisr_get,
+	.mfc_dsisr_set = mfc_dsisr_set,
+	.mfc_sdr_set = mfc_sdr_set,
+	.mfc_sr1_set = mfc_sr1_set,
+	.mfc_sr1_get = mfc_sr1_get,
+	.mfc_tclass_id_set = mfc_tclass_id_set,
+	.mfc_tclass_id_get = mfc_tclass_id_get,
+	.smm_pgsz_set = smm_pgsz_set,
+	.tlb_invalidate = tlb_invalidate,
+	.resource_allocation_groupID_set = resource_allocation_groupID_set,
+	.resource_allocation_groupID_get = resource_allocation_groupID_get,
+	.resource_allocation_enable_set = resource_allocation_enable_set,
+	.resource_allocation_enable_get = resource_allocation_enable_get,
+};
Index: linux-powerpc.git/arch/powerpc/platforms/cell/spufs/hw_ops.c
===================================================================
--- linux-powerpc.git.orig/arch/powerpc/platforms/cell/spufs/hw_ops.c	2006-04-28 14:32:25.000000000 -0700
+++ linux-powerpc.git/arch/powerpc/platforms/cell/spufs/hw_ops.c	2006-04-28 14:34:06.000000000 -0700
@@ -32,6 +32,7 @@

 #include <asm/io.h>
 #include <asm/spu.h>
+#include <asm/spu_priv1.h>
 #include <asm/spu_csa.h>
 #include <asm/mmu_context.h>
 #include "spufs.h"
Index: linux-powerpc.git/arch/powerpc/platforms/cell/spufs/switch.c
===================================================================
--- linux-powerpc.git.orig/arch/powerpc/platforms/cell/spufs/switch.c	2006-04-28 14:32:25.000000000 -0700
+++ linux-powerpc.git/arch/powerpc/platforms/cell/spufs/switch.c	2006-04-28 14:34:06.000000000 -0700
@@ -46,6 +46,7 @@

 #include <asm/io.h>
 #include <asm/spu.h>
+#include <asm/spu_priv1.h>
 #include <asm/spu_csa.h>
 #include <asm/mmu_context.h>

Index: linux-powerpc.git/include/asm-powerpc/spu.h
===================================================================
--- linux-powerpc.git.orig/include/asm-powerpc/spu.h	2006-04-28 14:34:06.000000000 -0700
+++ linux-powerpc.git/include/asm-powerpc/spu.h	2006-04-28 14:34:06.000000000 -0700
@@ -182,30 +182,6 @@
 }
 #endif /* MODULE */

-
-/* access to priv1 registers */
-void spu_int_mask_and(struct spu *spu, int class, u64 mask);
-void spu_int_mask_or(struct spu *spu, int class, u64 mask);
-void spu_int_mask_set(struct spu *spu, int class, u64 mask);
-u64 spu_int_mask_get(struct spu *spu, int class);
-void spu_int_stat_clear(struct spu *spu, int class, u64 stat);
-u64 spu_int_stat_get(struct spu *spu, int class);
-void spu_int_route_set(struct spu *spu, u64 route);
-u64 spu_mfc_dar_get(struct spu *spu);
-u64 spu_mfc_dsisr_get(struct spu *spu);
-void spu_mfc_dsisr_set(struct spu *spu, u64 dsisr);
-void spu_mfc_sdr_set(struct spu *spu, u64 sdr);
-void spu_mfc_sr1_set(struct spu *spu, u64 sr1);
-u64 spu_mfc_sr1_get(struct spu *spu);
-void spu_mfc_tclass_id_set(struct spu *spu, u64 tclass_id);
-u64 spu_mfc_tclass_id_get(struct spu *spu);
-void spu_tlb_invalidate(struct spu *spu);
-void spu_resource_allocation_groupID_set(struct spu *spu, u64 id);
-u64 spu_resource_allocation_groupID_get(struct spu *spu);
-void spu_resource_allocation_enable_set(struct spu *spu, u64 enable);
-u64 spu_resource_allocation_enable_get(struct spu *spu);
-
-
 /*
  * This defines the Local Store, Problem Area and Privlege Area of an SPU.
  */
Index: linux-powerpc.git/include/asm-powerpc/spu_priv1.h
===================================================================
--- linux-powerpc.git.orig/include/asm-powerpc/spu_priv1.h	2006-04-21 13:04:41.284693750 -0700
+++ linux-powerpc.git/include/asm-powerpc/spu_priv1.h	2006-04-28 14:38:16.000000000 -0700
@@ -0,0 +1,189 @@
+/*
+ * Defines an spu hypervisor abstraction layer.
+ *
+ *  Copyright 2006 Sony Corp.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#if !defined(_SPU_PRIV1_H)
+#define _SPU_PRIV1_H
+#if defined(__KERNEL__)
+
+struct spu;
+
+/* access to priv1 registers */
+
+struct spu_priv1_ops
+{
+	void (*int_mask_and) (struct spu *spu, int class, u64 mask);
+	void (*int_mask_or) (struct spu *spu, int class, u64 mask);
+	void (*int_mask_set) (struct spu *spu, int class, u64 mask);
+	u64 (*int_mask_get) (struct spu *spu, int class);
+	void (*int_stat_clear) (struct spu *spu, int class, u64 stat);
+	u64 (*int_stat_get) (struct spu *spu, int class);
+	void (*int_route_set) (struct spu *spu, u64 route);
+	u64 (*mfc_dar_get) (struct spu *spu);
+	u64 (*mfc_dsisr_get) (struct spu *spu);
+	void (*mfc_dsisr_set) (struct spu *spu, u64 dsisr);
+	void (*mfc_sdr_set) (struct spu *spu, u64 sdr);
+	void (*mfc_sr1_set) (struct spu *spu, u64 sr1);
+	u64 (*mfc_sr1_get) (struct spu *spu);
+	void (*mfc_tclass_id_set) (struct spu *spu, u64 tclass_id);
+	u64 (*mfc_tclass_id_get) (struct spu *spu);
+	void (*smm_pgsz_set) (struct spu *spu, u64 pgsz);
+	void (*tlb_invalidate) (struct spu *spu);
+	void (*resource_allocation_groupID_set) (struct spu *spu, u64 id);
+	u64 (*resource_allocation_groupID_get) (struct spu *spu);
+	void (*resource_allocation_enable_set) (struct spu *spu, u64 enable);
+	u64 (*resource_allocation_enable_get) (struct spu *spu);
+};
+
+extern const struct spu_priv1_ops* spu_priv1_ops;
+
+static inline void
+spu_int_mask_and (struct spu *spu, int class, u64 mask)
+{
+	spu_priv1_ops->int_mask_and(spu, class, mask);
+}
+
+static inline void
+spu_int_mask_or (struct spu *spu, int class, u64 mask)
+{
+	spu_priv1_ops->int_mask_or(spu, class, mask);
+}
+
+static inline void
+spu_int_mask_set (struct spu *spu, int class, u64 mask)
+{
+	spu_priv1_ops->int_mask_set(spu, class, mask);
+}
+
+static inline u64
+spu_int_mask_get (struct spu *spu, int class)
+{
+	return spu_priv1_ops->int_mask_get(spu, class);
+}
+
+static inline void
+spu_int_stat_clear (struct spu *spu, int class, u64 stat)
+{
+	spu_priv1_ops->int_stat_clear(spu, class, stat);
+}
+
+static inline u64
+spu_int_stat_get (struct spu *spu, int class)
+{
+	return spu_priv1_ops->int_stat_get (spu, class);
+}
+
+static inline void
+spu_int_route_set (struct spu *spu, u64 route)
+{
+	spu_priv1_ops->int_stat_get(spu, route);
+}
+
+static inline u64
+spu_mfc_dar_get (struct spu *spu)
+{
+	return spu_priv1_ops->mfc_dar_get(spu);
+}
+
+static inline u64
+spu_mfc_dsisr_get (struct spu *spu)
+{
+	return spu_priv1_ops->mfc_dsisr_get(spu);
+}
+
+static inline void
+spu_mfc_dsisr_set (struct spu *spu, u64 dsisr)
+{
+	spu_priv1_ops->mfc_dsisr_set(spu, dsisr);
+}
+
+static inline void
+spu_mfc_sdr_set (struct spu *spu, u64 sdr)
+{
+	spu_priv1_ops->mfc_sdr_set(spu, sdr);
+}
+
+static inline void
+spu_mfc_sr1_set (struct spu *spu, u64 sr1)
+{
+	spu_priv1_ops->mfc_sr1_set(spu, sr1);
+}
+
+static inline u64
+spu_mfc_sr1_get (struct spu *spu)
+{
+	return spu_priv1_ops->mfc_sr1_get(spu);
+}
+
+static inline void
+spu_mfc_tclass_id_set (struct spu *spu, u64 tclass_id)
+{
+	spu_priv1_ops->mfc_tclass_id_set(spu, tclass_id);
+}
+
+static inline u64
+spu_mfc_tclass_id_get (struct spu *spu)
+{
+	return spu_priv1_ops->mfc_tclass_id_get(spu);
+}
+
+static inline void
+spu_smm_pgsz_set (struct spu *spu, u64 pgsz)
+{
+	spu_priv1_ops->smm_pgsz_set(spu, pgsz);
+}
+
+static inline void
+spu_tlb_invalidate (struct spu *spu)
+{
+	spu_priv1_ops->tlb_invalidate(spu);
+}
+
+static inline void
+spu_resource_allocation_groupID_set (struct spu *spu, u64 id)
+{
+	spu_priv1_ops->resource_allocation_groupID_set(spu, id);
+}
+
+static inline u64
+spu_resource_allocation_groupID_get (struct spu *spu)
+{
+	return spu_priv1_ops->resource_allocation_groupID_get(spu);
+}
+
+static inline void
+spu_resource_allocation_enable_set (struct spu *spu, u64 enable)
+{
+	spu_priv1_ops->resource_allocation_enable_set(spu, enable);
+}
+
+static inline u64
+spu_resource_allocation_enable_get (struct spu *spu)
+{
+	return spu_priv1_ops->resource_allocation_enable_get(spu);
+}
+
+/* The declarations folowing are put here for convenience
+ * and only intended to be used by the platform setup code
+ * for initializing spu_priv1_ops.
+ */
+
+extern const struct spu_priv1_ops spu_priv1_mmio_ops;
+
+#endif /* __KERNEL__ */
+#endif

^ permalink raw reply

* [patch 4/4] spufs: wrap cpu affinity
From: Geoff Levand @ 2006-04-28 21:44 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev, cbe-oss-dev, arnd

This changes the hypervisor abstraction of setting cpu affinity to a
higher level to avoid platform dependent interrupt controller
routines.  I replaced spu_priv1_ops:spu_int_route_set() with a
new routine spu_priv1_ops:spu_cpu_affinity_set().

As a by-product, this change eliminated what looked like an
existing bug in the set affinity code where spu_int_route_set()
mistakenly called int_stat_get().


Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>

---
Index: linux-powerpc.git/arch/powerpc/platforms/cell/spu_base.c
===================================================================
--- linux-powerpc.git.orig/arch/powerpc/platforms/cell/spu_base.c	2006-04-28 14:34:06.000000000 -0700
+++ linux-powerpc.git/arch/powerpc/platforms/cell/spu_base.c	2006-04-28 14:34:06.000000000 -0700
@@ -513,14 +513,6 @@
 	return ret;
 }

-void spu_irq_setaffinity(struct spu *spu, int cpu)
-{
-	u64 target = iic_get_target_id(cpu);
-	u64 route = target << 48 | target << 32 | target << 16;
-	spu_int_route_set(spu, route);
-}
-EXPORT_SYMBOL_GPL(spu_irq_setaffinity);
-
 static void __iomem * __init map_spe_prop(struct device_node *n,
 						 const char *name)
 {
Index: linux-powerpc.git/arch/powerpc/platforms/cell/spu_priv1_mmio.c
===================================================================
--- linux-powerpc.git.orig/arch/powerpc/platforms/cell/spu_priv1_mmio.c	2006-04-28 14:34:06.000000000 -0700
+++ linux-powerpc.git/arch/powerpc/platforms/cell/spu_priv1_mmio.c	2006-04-28 14:34:06.000000000 -0700
@@ -24,6 +24,8 @@
 #include <asm/spu.h>
 #include <asm/spu_priv1.h>

+#include "interrupt.h"
+
 static void int_mask_and(struct spu *spu, int class, u64 mask)
 {
 	u64 old_mask;
@@ -60,8 +62,10 @@
 	return in_be64(&spu->priv1->int_stat_RW[class]);
 }

-static void int_route_set(struct spu *spu, u64 route)
+static void cpu_affinity_set(struct spu *spu, int cpu)
 {
+	u64 target = iic_get_target_id(cpu);
+	u64 route = target << 48 | target << 32 | target << 16;
 	out_be64(&spu->priv1->int_route_RW, route);
 }

@@ -147,7 +151,7 @@
 	.int_mask_get = int_mask_get,
 	.int_stat_clear = int_stat_clear,
 	.int_stat_get = int_stat_get,
-	.int_route_set = int_route_set,
+	.cpu_affinity_set = cpu_affinity_set,
 	.mfc_dar_get = mfc_dar_get,
 	.mfc_dsisr_get = mfc_dsisr_get,
 	.mfc_dsisr_set = mfc_dsisr_set,
Index: linux-powerpc.git/arch/powerpc/platforms/cell/spufs/sched.c
===================================================================
--- linux-powerpc.git.orig/arch/powerpc/platforms/cell/spufs/sched.c	2006-04-19 11:48:28.000000000 -0700
+++ linux-powerpc.git/arch/powerpc/platforms/cell/spufs/sched.c	2006-04-28 14:34:06.000000000 -0700
@@ -43,6 +43,7 @@
 #include <asm/mmu_context.h>
 #include <asm/spu.h>
 #include <asm/spu_csa.h>
+#include <asm/spu_priv1.h>
 #include "spufs.h"

 #define SPU_MIN_TIMESLICE 	(100 * HZ / 1000)
@@ -363,7 +364,7 @@
 	 * We're likely to wait for interrupts on the same
 	 * CPU that we are now on, so send them here.
 	 */
-	spu_irq_setaffinity(spu, raw_smp_processor_id());
+	spu_cpu_affinity_set(spu, raw_smp_processor_id());
 	put_active_spu(spu);
 	return 0;
 }
Index: linux-powerpc.git/include/asm-powerpc/spu_priv1.h
===================================================================
--- linux-powerpc.git.orig/include/asm-powerpc/spu_priv1.h	2006-04-28 14:34:06.000000000 -0700
+++ linux-powerpc.git/include/asm-powerpc/spu_priv1.h	2006-04-28 14:34:06.000000000 -0700
@@ -33,7 +33,7 @@
 	u64 (*int_mask_get) (struct spu *spu, int class);
 	void (*int_stat_clear) (struct spu *spu, int class, u64 stat);
 	u64 (*int_stat_get) (struct spu *spu, int class);
-	void (*int_route_set) (struct spu *spu, u64 route);
+	void (*cpu_affinity_set) (struct spu *spu, int cpu);
 	u64 (*mfc_dar_get) (struct spu *spu);
 	u64 (*mfc_dsisr_get) (struct spu *spu);
 	void (*mfc_dsisr_set) (struct spu *spu, u64 dsisr);
@@ -89,9 +89,9 @@
 }

 static inline void
-spu_int_route_set (struct spu *spu, u64 route)
+spu_cpu_affinity_set (struct spu *spu, int cpu)
 {
-	spu_priv1_ops->int_stat_get(spu, route);
+	spu_priv1_ops->cpu_affinity_set(spu, cpu);
 }

 static inline u64

^ permalink raw reply

* Re: [RFC , PATCH] support for the ibm,pa_features cpu property
From: Will Schmidt @ 2006-04-28 21:53 UTC (permalink / raw)
  To: linuxppc-dev list; +Cc: paulus
In-Reply-To: <1146249684.27214.18.camel@localhost.localdomain>

Whoops.. funny thing occurred to me on my drive home..   comment inline

On Fri, 2006-04-28 at 13:41 -0500, Will Schmidt wrote:
> To determine if our processors support some features, such as large
> pages, we should be using the ibm,pa_features property, rather than just
> the PVR values.  
> This is an initial pass at the functionality.  This has been tested in
> the case where the property is missing, but still needs to be tested
> against a system where the property actually exists.  :-o  
> 
> 
> 
> diff --git a/arch/powerpc/kernel/setup_64.c
> b/arch/powerpc/kernel/setup_64.c
> index 13e91c4..78ad054 100644
> --- a/arch/powerpc/kernel/setup_64.c
> +++ b/arch/powerpc/kernel/setup_64.c
> @@ -106,6 +106,65 @@ static struct notifier_block ppc64_panic
>  	.priority = INT_MIN /* may not return; must be done last */
>  };
> 
> +/*
> + * ibm,pa-features is a per-cpu property that contains a 2 byte header
> + * plus up to 256 bytes worth of processor attributes.  First header
> + * byte specifies the number of bytes implemented by the platform.
> + * Second header byte is an "attribute-specifier" type, which should
> + * be zero.  Remainder of the data consists of ones and zeros.
> + * Implementation:  Pass in the byte and bit offset for the feature
> + * that we are interested in.  The function will return -1 if the
> + * pa-features property is missing, or a 1/0 to indicate if the feature
> + * is supported/not supported.
> + */
> +
> +static int get_pa_features(int pabyte,int pabit)
> +{
> +	struct device_node *cpu;
> +	char *pa_feature_table;
> +
> +	cpu = of_find_node_by_type(NULL, "cpu");
> +	pa_feature_table = 
> +		(char *)get_property(cpu, "ibm,pa-features", NULL);
> +
> +	if ( pa_feature_table == NULL ) {
> +		printk("ibm,pa-features property is missing.\n");
> +		return -1;
> +	}
> +
> +	/* sanity check */
> +	if ( pabyte > pa_feature_table[0] ) {
> +		printk("%s: %d out of range for table of size %d\n",
> +			__FUNCTION__,pabyte,pa_feature_table[0]);
> +		return -1;
> +	}
> +	
> +	return pa_feature_table[2+pabyte*8+pabit];

pa_feature_table would be byte (char) addressable, while the fields that
we are interested with inside are actually bit values.  So this should
be something like

	return   (pa_feature_table[2+pabyte] & 1<<pabit);


> +}
> +
> +/*
> + * set values within the cur_cpu_spec table according to
> + * the ibm,pa_features property. 
> + * potential entries include: 
> + * Byte 0, bit 1 - FPU available
> + * Byte 1, bit 2 - Large Pages 
> + * Byte 2, bit 3 - DAR set on alignment Interrupt. 
> + */
> +static void add_cpu_features()
> +{
> +	/* if no property, bail early */
> +	if (get_pa_features(0,0) == -1 ) return;
> +
> +	if (get_pa_features(1,2) ) {
> +		printk("Adding CI_LARGE_PAGE to cur_cpu_spec \n");
> +		cur_cpu_spec->cpu_features |= CPU_FTR_CI_LARGE_PAGE;
> +	}
> +
> +	/* add more here... */
> +
> +}
> +
> +
>  #ifdef CONFIG_SMP
> 
>  static int smt_enabled_cmdline;
> @@ -425,6 +484,8 @@ void __init setup_system(void)
> 
>  	parse_early_param();
> 
> +	add_cpu_features();
> +
>  	check_smt_enabled();
>  	smp_setup_cpu_maps();
> 
> 
> 
> 
> 
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev

^ permalink raw reply

* [PATCH]: powerpc/pseries: Increment fail counter in PCI recovery
From: Linas Vepstas @ 2006-04-28 22:39 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev, linux-kernel

Paul,

A small medium-priority patch; please send upstream as appropriate.

--linas

[PATCH]: powerpc/pseries: Increment fail counter in PCI recovery

When a PCI device driver does not support PCI error recovery,
the powerpc/pseries code takes a walk through a branch of code 
that resets the failure counter. Because of this, if a broken
PCI card is present, the kernel will attempt to reset it an
infinite number of times. (This is annoying but mostly harmless:
each reset takes about 10-20 seconds, and uses almost no CPU time).

This patch preserves the failure count across resets.

Signed-off-by: Linas Vepstas <linas@austin.ibm.com>

----
 arch/powerpc/platforms/pseries/eeh_driver.c |    7 ++++++-
 1 files changed, 6 insertions(+), 1 deletion(-)

Index: linux-2.6.17-rc1/arch/powerpc/platforms/pseries/eeh_driver.c
===================================================================
--- linux-2.6.17-rc1.orig/arch/powerpc/platforms/pseries/eeh_driver.c	2006-04-28 17:30:21.000000000 -0500
+++ linux-2.6.17-rc1/arch/powerpc/platforms/pseries/eeh_driver.c	2006-04-28 17:31:31.000000000 -0500
@@ -201,7 +201,11 @@ static void eeh_report_failure(struct pc
 
 static int eeh_reset_device (struct pci_dn *pe_dn, struct pci_bus *bus)
 {
-	int rc;
+	int cnt, rc;
+
+	/* pcibios will clear the counter; save the value */
+	cnt = pe_dn->eeh_freeze_count;
+
 	if (bus)
 		pcibios_remove_pci_devices(bus);
 
@@ -240,6 +244,7 @@ static int eeh_reset_device (struct pci_
 		ssleep (5);
 		pcibios_add_pci_devices(bus);
 	}
+	pe_dn->eeh_freeze_count = cnt;
 
 	return 0;
 }

^ permalink raw reply

* [PATCH]: powerpc/pseries: Print PCI slot location code on failure
From: Linas Vepstas @ 2006-04-28 22:42 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev, linux-kernel


Paul,

A low-priority patch the improves diagnostic printing on EEH failures.
Please review and forward upstream as appropriate.

--linas

[PATCH]: powerpc/pseries: Print PCI slot location code on failure

The PCI error recovery code will printk diagnostic info when
a PCI error event occurs. Change the messages to include the slot
location code, which is how most sysadmins will know the device.

Signed-off-by: Linas Vepstas <linas@austin.ibm.com>

----
 arch/powerpc/platforms/pseries/eeh_driver.c |   33 ++++++++++++++++------------
 1 files changed, 20 insertions(+), 13 deletions(-)

Index: linux-2.6.17-rc1/arch/powerpc/platforms/pseries/eeh_driver.c
===================================================================
--- linux-2.6.17-rc1.orig/arch/powerpc/platforms/pseries/eeh_driver.c	2006-04-28 17:31:31.000000000 -0500
+++ linux-2.6.17-rc1/arch/powerpc/platforms/pseries/eeh_driver.c	2006-04-28 17:31:39.000000000 -0500
@@ -261,16 +261,20 @@ struct pci_dn * handle_eeh_events (struc
 	struct pci_bus *frozen_bus;
 	int rc = 0;
 	enum pci_ers_result result = PCI_ERS_RESULT_NONE;
-	const char *pci_str, *drv_str;
+	const char *location, *pci_str, *drv_str;
 
 	frozen_dn = find_device_pe(event->dn);
 	frozen_bus = pcibios_find_pci_bus(frozen_dn);
 
 	if (!frozen_dn) {
-		printk(KERN_ERR "EEH: Error: Cannot find partition endpoint for %s\n",
-		        pci_name(event->dev));
+
+		location = (char *) get_property(event->dn, "ibm,loc-code", NULL);
+		printk(KERN_ERR "EEH: Error: Cannot find partition endpoint "
+		                "for location=%s pci addr=%s\n",
+		        location, pci_name(event->dev));
 		return NULL;
 	}
+	location = (char *) get_property(frozen_dn, "ibm,loc-code", NULL);
 
 	/* There are two different styles for coming up with the PE.
 	 * In the old style, it was the highest EEH-capable device
@@ -282,8 +286,9 @@ struct pci_dn * handle_eeh_events (struc
 		frozen_bus = pcibios_find_pci_bus (frozen_dn->parent);
 
 	if (!frozen_bus) {
-		printk(KERN_ERR "EEH: Cannot find PCI bus for %s\n",
-		        frozen_dn->full_name);
+		printk(KERN_ERR "EEH: Cannot find PCI bus "
+		        "for location=%s dn=%s\n",
+		        location, frozen_dn->full_name);
 		return NULL;
 	}
 
@@ -318,8 +323,9 @@ struct pci_dn * handle_eeh_events (struc
 
 	eeh_slot_error_detail(frozen_pdn, 1 /* Temporary Error */);
 	printk(KERN_WARNING
-	   "EEH: This PCI device has failed %d times since last reboot: %s - %s\n",
-		frozen_pdn->eeh_freeze_count, drv_str, pci_str);
+	   "EEH: This PCI device has failed %d times since last reboot: "
+		"location=%s driver=%s pci addr=%s\n",
+		frozen_pdn->eeh_freeze_count, location, drv_str, pci_str);
 
 	/* Walk the various device drivers attached to this slot through
 	 * a reset sequence, giving each an opportunity to do what it needs
@@ -368,17 +374,18 @@ excess_failures:
 	 * due to actual, failed cards.
 	 */
 	printk(KERN_ERR
-	   "EEH: PCI device %s - %s has failed %d times \n"
-	   "and has been permanently disabled.  Please try reseating\n"
-	   "this device or replacing it.\n",
-		drv_str, pci_str, frozen_pdn->eeh_freeze_count);
+	   "EEH: PCI device at location=%s driver=%s pci addr=%s \n"
+		"has failed %d times and has been permanently disabled. \n"
+		"Please try reseating this device or replacing it.\n",
+		location, drv_str, pci_str, frozen_pdn->eeh_freeze_count);
 	goto perm_error;
 
 hard_fail:
 	printk(KERN_ERR
-	   "EEH: Unable to recover from failure of PCI device %s - %s\n"
+	   "EEH: Unable to recover from failure of PCI device "
+	   "at location=%s driver=%s pci addr=%s \n"
 	   "Please try reseating this device or replacing it.\n",
-		drv_str, pci_str);
+		location, drv_str, pci_str);
 
 perm_error:
 	eeh_slot_error_detail(frozen_pdn, 2 /* Permanent Error */);

^ permalink raw reply

* PCI init vs. memory init
From: Linas Vepstas @ 2006-04-28 23:04 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev, linux-kernel


Paul,

I'd previously reported a problem where the PCI subsystem 
was getting inited before the memory subsystem. In the unusual
case of an EEH failure, this resulted in a crash in kmalloc,
which I hacked around with a if(!mem_init_done).

You mentioned that the sequence of inits seemed wrong, that the 
PCI init should be done later, after the memory init. I think
I agree; but when I took a very very quick look at the code, there 
was no obvious hook in later init to move the PCI init over to. 

Are you pursuing this further? Should I dig into it?  Any bright
ideas? Am I missing something obvious?  

There are several spots in in the powerpc PCI init code where 
a boot_mem alloc is used instead of kmalloc, and this boot_mem is 
then hacked around in the case of a PCI hotplug remove.  It would 
be nice to fix this...

--linas

^ permalink raw reply

* Re: FT u-boot shim
From: Wolfgang Denk @ 2006-04-28 23:07 UTC (permalink / raw)
  To: Tom Rini; +Cc: linuxppc-dev@ozlabs.org list, Paul Mackerras
In-Reply-To: <20060428194457.GA458@smtp.west.cox.net>

Dear Tom,

in message <20060428194457.GA458@smtp.west.cox.net> you wrote:
>
> > > 3. using a u-boot that is ft aware + built in dtb.
...
> > Assuming we had 2., under which circumstances would we need 3. then?
> 
> Especially if we had mkuimage let you tack your dtb into the 'kernel'
> image.

Sorry, but I don't understand. If we have the dtb combined  with  the
kernel  image,  then  why would we need another copy of the dtb built
into U-Boot?

Best regards,

Wolfgang Denk

-- 
Software Engineering:  Embedded and Realtime Systems,  Embedded Linux
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
A day without sunshine is like night.

^ permalink raw reply

* Re: FT u-boot shim
From: Tom Rini @ 2006-04-28 23:22 UTC (permalink / raw)
  To: Wolfgang Denk; +Cc: linuxppc-dev@ozlabs.org list, Paul Mackerras
In-Reply-To: <20060428230720.7C0CB353DAC@atlas.denx.de>

On Sat, Apr 29, 2006 at 01:07:20AM +0200, Wolfgang Denk wrote:
> Dear Tom,
> 
> in message <20060428194457.GA458@smtp.west.cox.net> you wrote:
> >
> > > > 3. using a u-boot that is ft aware + built in dtb.
> ...
> > > Assuming we had 2., under which circumstances would we need 3. then?
> > 
> > Especially if we had mkuimage let you tack your dtb into the 'kernel'
> > image.
> 
> Sorry, but I don't understand. If we have the dtb combined  with  the
> kernel  image,  then  why would we need another copy of the dtb built
> into U-Boot?

You wouldn't have the dtb combined in the kernel image, unless you have
the shim.   This is instead of loading a separate dtb anyhow.

-- 
Tom Rini
http://gate.crashing.org/~trini/

^ permalink raw reply

* Re: sign extension for 32bit syscalls on ppc64
From: Paul Mackerras @ 2006-04-28 23:32 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linuxppc-dev
In-Reply-To: <20060428131254.GA507@lst.de>

Christoph Hellwig writes:

> OTOH various syscalls in the generic code don't do that and it seems to
> still work fine.  I have patches for various new generic compat
> routines, and they all seem to work fine without this sign extension.
> 
> What's the exact sign extention rules for ppc64?

As far as the ABI and the compiler are concerned, 32-bit values stored
in registers are always correctly extended to 64 bits according to
their type.  That is, the top 32 bits of the register will be either
all zeroes or all ones, and will only be all ones for negative values
of a signed type.

Syscall arguments are zero-extended in the syscall entry path for
32-bit processes (see lines 131-136 of arch/powerpc/kernel/entry_64.S)
so if the argument is an int, we do an (int) cast in the compat
wrapper, which makes the compiler emit an extsw instruction to get the
value correctly sign-extended.

However, it's debatable whether file descriptor arguments really need
to be sign-extended.  Although they are typed as int, negative values
are not generally valid (although there are one or two cases where
they are), and an fd value of 4294967295 will generate an EBADF error
just as well as -1 will.

Paul.

^ permalink raw reply

* Re: FT u-boot shim
From: Paul Mackerras @ 2006-04-28 23:35 UTC (permalink / raw)
  To: Wolfgang Denk; +Cc: linuxppc-dev@ozlabs.org list
In-Reply-To: <20060428191124.B202B353DAC@atlas.denx.de>

Wolfgang Denk writes:

> > 2. using a u-boot that is ft aware + dtb (boot command in u-boot  
> > takes kernel & dtb images, updates blob and passes to kernel)
> > 3. using a u-boot that is ft aware + built in dtb.
> > 
> > The issue is that for a given system/board you may need to support  
> > multiple or all three.  This raises the question where does the .dts  
> 
> Assuming we had 2., under which circumstances would we need 3. then?

I imagine 3. would be more convenient for users than 2., or at least
it would seem to mean less typing for them.

Paul.

^ permalink raw reply

* Re: alignment exceptionhandler sleeps in invalid context
From: Paul Mackerras @ 2006-04-28 23:41 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev, Olaf Hering
In-Reply-To: <27BDABD8-B970-4F2C-AA0A-07D55A9D3303@kernel.crashing.org>

Kumar Gala writes:

> I was going to ask how this was actually hit.  It seems odd that we  
> would have an alignment error in the network stack.  From the oops  
> can we determine what the instruction was that faulted and what  
> address it was trying to access.

No, it's not particularly odd, given that our get_unaligned() and
put_unaligned() in include/asm-powerpc/unaligned.h just do a single
access.  That makes the common case (address is actually aligned, or
cpu handles it in hardware) fast at the expense of occasionally taking
an alignment exception.

Paul.

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox