LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: entry point of kernel in RAM at 0x0c--linux tree file name
From: Laurent Pinchart @ 2006-06-23 10:18 UTC (permalink / raw)
  To: linuxppc-embedded; +Cc: Arun Kumar
In-Reply-To: <edd12c050606230253u5842ea5bvd78d06f0354cb4bd@mail.gmail.com>

Hi Arun,

please keep the list posted when you reply.

> Thanks for the response .I would also like to ask another query hoever
> naive it might sound .I am using a Linux 2.4.1

That's very old. Can't you upgrade to 2.6 ?

> wherein my entry point 
> code at 0x0c expects at R3 ,R4,R5,R6 some parameters which I strongly
> suspect to be residual record bi_rec *,start of initrd and end of initrd
> sections as my kernel is crashing immediately after  MMU_init and I
> suspect that machine _init that is done prior to  MMU_init expects __res
> in R3 as a input parameter .Please confirm .

Depending on your platform and boot loader, r3 to r7 are initialized with 
different values. If you're using ppcboot, the kernel expects r3 to be 
initialized with the residual record, right.

> I am using ppcboot2..0.0 as my bootloader .

That' very old too. You should upgrade to U-Boot.

> Also I would like to know how can i enable serial console in these early
> kernel initialsaiotns process. I am using a CONFIG_SANDPOINT(8260) on a
> MPC 8245 platform and trying to port the code on MPC8245 platform .the
> board has a very similar config as a SANDPOINT board .

If I'm not mistaken, you can't enable a serial console that early. Do you have 
a hardware debugger (BDI2000) ? If not, you could try LED debugging.

Best regards,

Laurent Pinchart

^ permalink raw reply

* Re: [PATCH 2/8] Assume we're on cpu 0 in early boot
From: Jimi Xenidis @ 2006-06-23 10:03 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: linuxppc-dev, Paul Mackerras, Arnd Bergmann
In-Reply-To: <20060623082007.34A9867A79@ozlabs.org>


On Jun 23, 2006, at 4:20 AM, Michael Ellerman wrote:
> +	/* Assume we're on cpu for now, we don't actually know yet.

oops :( "Assume we're on cpu _0_ for now"
-JX

^ permalink raw reply

* [PATCH 8/8] Enable XMON in cell_defconfig
From: Michael Ellerman @ 2006-06-23  8:20 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev, Arnd Bergmann

Now that we have the udbg callbacks we can enable XMON by default.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---

 arch/powerpc/configs/cell_defconfig |    7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

Index: to-merge/arch/powerpc/configs/cell_defconfig
===================================================================
--- to-merge.orig/arch/powerpc/configs/cell_defconfig
+++ to-merge/arch/powerpc/configs/cell_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.17
-# Mon Jun 19 17:23:03 2006
+# Linux kernel version: 2.6.17-rc6
+# Thu Jun 22 15:28:36 2006
 #
 CONFIG_PPC64=y
 CONFIG_64BIT=y
@@ -1063,7 +1063,8 @@ CONFIG_DEBUG_FS=y
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 CONFIG_DEBUGGER=y
-# CONFIG_XMON is not set
+CONFIG_XMON=y
+CONFIG_XMON_DEFAULT=y
 CONFIG_IRQSTACKS=y
 # CONFIG_BOOTX_TEXT is not set
 # CONFIG_PPC_EARLY_DEBUG is not set

^ permalink raw reply

* [PATCH 7/8] Enable the RTAS udbg console on IBM Cell Blade
From: Michael Ellerman @ 2006-06-23  8:20 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev, Arnd Bergmann

Enable the RTAS udbg console on IBM Cell Blade, this allows xmon
to work.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---

 arch/powerpc/Kconfig                |    1 +
 arch/powerpc/platforms/cell/setup.c |    4 ++++
 2 files changed, 5 insertions(+)

Index: to-merge/arch/powerpc/Kconfig
===================================================================
--- to-merge.orig/arch/powerpc/Kconfig
+++ to-merge/arch/powerpc/Kconfig
@@ -419,6 +419,7 @@ config PPC_IBM_CELL_BLADE
 	select PPC_RTAS
 	select MMIO_NVRAM
 	select PPC_UDBG_16550
+	select UDBG_RTAS_CONSOLE
 
 config UDBG_RTAS_CONSOLE
 	bool
Index: to-merge/arch/powerpc/platforms/cell/setup.c
===================================================================
--- to-merge.orig/arch/powerpc/platforms/cell/setup.c
+++ to-merge/arch/powerpc/platforms/cell/setup.c
@@ -141,6 +141,10 @@ static int __init cell_probe(void)
 	    !of_flat_dt_is_compatible(root, "IBM,CPBW-1.0"))
 		return 0;
 
+#ifdef CONFIG_UDBG_RTAS_CONSOLE
+	udbg_init_rtas_console();
+#endif
+
 	hpte_init_native();
 
 	return 1;

^ permalink raw reply

* [PATCH 6/8] Add udbg support for RTAS console
From: Michael Ellerman @ 2006-06-23  8:20 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev, Arnd Bergmann

Add udbg hooks for the RTAS console, based on the RTAS put-term-char
and get-term-char calls. Along with my previous patches, this should
enable debugging as soon as early_init_dt_scan_rtas() is called.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---

 arch/powerpc/Kconfig       |    4 ++
 arch/powerpc/Kconfig.debug |    9 +++++
 arch/powerpc/kernel/rtas.c |   72 ++++++++++++++++++++++++++++++++++++++++++++-
 arch/powerpc/kernel/udbg.c |    7 +++-
 include/asm-powerpc/udbg.h |    3 +
 5 files changed, 90 insertions(+), 5 deletions(-)

Index: to-merge/arch/powerpc/Kconfig
===================================================================
--- to-merge.orig/arch/powerpc/Kconfig
+++ to-merge/arch/powerpc/Kconfig
@@ -420,6 +420,10 @@ config PPC_IBM_CELL_BLADE
 	select MMIO_NVRAM
 	select PPC_UDBG_16550
 
+config UDBG_RTAS_CONSOLE
+	bool
+	default n
+
 config XICS
 	depends on PPC_PSERIES
 	bool
Index: to-merge/arch/powerpc/Kconfig.debug
===================================================================
--- to-merge.orig/arch/powerpc/Kconfig.debug
+++ to-merge/arch/powerpc/Kconfig.debug
@@ -134,12 +134,19 @@ config PPC_EARLY_DEBUG_G5
 	help
 	  Select this to enable early debugging for Apple G5 machines.
 
-config PPC_EARLY_DEBUG_RTAS
+config PPC_EARLY_DEBUG_RTAS_PANEL
 	bool "RTAS Panel"
 	depends on PPC_RTAS
 	help
 	  Select this to enable early debugging via the RTAS panel.
 
+config PPC_EARLY_DEBUG_RTAS_CONSOLE
+	bool "RTAS Console"
+	depends on PPC_RTAS
+	select UDBG_RTAS_CONSOLE
+	help
+	  Select this to enable early debugging via the RTAS console.
+
 config PPC_EARLY_DEBUG_MAPLE
 	bool "Maple real mode"
 	depends on PPC_MAPLE
Index: to-merge/arch/powerpc/kernel/rtas.c
===================================================================
--- to-merge.orig/arch/powerpc/kernel/rtas.c
+++ to-merge/arch/powerpc/kernel/rtas.c
@@ -109,11 +109,71 @@ static void call_rtas_display_status_del
 	}
 }
 
-void __init udbg_init_rtas(void)
+void __init udbg_init_rtas_panel(void)
 {
 	udbg_putc = call_rtas_display_status_delay;
 }
 
+#ifdef CONFIG_UDBG_RTAS_CONSOLE
+
+/* If you think you're dying before early_init_dt_scan_rtas() does its
+ * work, you can hard code the token values for your firmware here and
+ * hardcode rtas.base/entry etc.
+ */
+static unsigned int rtas_putchar_token = RTAS_UNKNOWN_SERVICE;
+static unsigned int rtas_getchar_token = RTAS_UNKNOWN_SERVICE;
+
+static void udbg_rtascon_putc(char c)
+{
+	int tries;
+
+	if (!rtas.base)
+		return;
+
+	/* Add CRs before LFs */
+	if (c == '\n')
+		udbg_rtascon_putc('\r');
+
+	/* if there is more than one character to be displayed, wait a bit */
+	for (tries = 0; tries < 16; tries++) {
+		if (rtas_call(rtas_putchar_token, 1, 1, NULL, c) == 0)
+			break;
+		udelay(1000);
+	}
+}
+
+static int udbg_rtascon_getc_poll(void)
+{
+	int c;
+
+	if (!rtas.base)
+		return -1;
+
+	if (rtas_call(rtas_getchar_token, 0, 2, &c))
+		return -1;
+
+	return c;
+}
+
+static int udbg_rtascon_getc(void)
+{
+	int c;
+
+	while ((c = udbg_rtascon_getc_poll()) == -1)
+		;
+
+	return c;
+}
+
+
+void __init udbg_init_rtas_console(void)
+{
+	udbg_putc = udbg_rtascon_putc;
+	udbg_getc = udbg_rtascon_getc;
+	udbg_getc_poll = udbg_rtascon_getc_poll;
+}
+#endif /* CONFIG_UDBG_RTAS_CONSOLE */
+
 void rtas_progress(char *s, unsigned short hex)
 {
 	struct device_node *root;
@@ -820,6 +880,16 @@ int __init early_init_dt_scan_rtas(unsig
 		rtas.size = *sizep;
 	}
 
+#ifdef CONFIG_UDBG_RTAS_CONSOLE
+	basep = of_get_flat_dt_prop(node, "put-term-char", NULL);
+	if (basep)
+		rtas_putchar_token = *basep;
+
+	basep = of_get_flat_dt_prop(node, "get-term-char", NULL);
+	if (basep)
+		rtas_getchar_token = *basep;
+#endif
+
 	/* break now */
 	return 1;
 }
Index: to-merge/arch/powerpc/kernel/udbg.c
===================================================================
--- to-merge.orig/arch/powerpc/kernel/udbg.c
+++ to-merge/arch/powerpc/kernel/udbg.c
@@ -34,9 +34,12 @@ void __init udbg_early_init(void)
 #elif defined(CONFIG_PPC_EARLY_DEBUG_G5)
 	/* For use on Apple G5 machines */
 	udbg_init_pmac_realmode();
-#elif defined(CONFIG_PPC_EARLY_DEBUG_RTAS)
+#elif defined(CONFIG_PPC_EARLY_DEBUG_RTAS_PANEL)
 	/* RTAS panel debug */
-	udbg_init_rtas();
+	udbg_init_rtas_panel();
+#elif defined(CONFIG_PPC_EARLY_DEBUG_RTAS_CONSOLE)
+	/* RTAS console debug */
+	udbg_init_rtas_console();
 #elif defined(CONFIG_PPC_EARLY_DEBUG_MAPLE)
 	/* Maple real mode debug */
 	udbg_init_maple_realmode();
Index: to-merge/include/asm-powerpc/udbg.h
===================================================================
--- to-merge.orig/include/asm-powerpc/udbg.h
+++ to-merge/include/asm-powerpc/udbg.h
@@ -42,7 +42,8 @@ extern void __init udbg_init_debug_lpar(
 extern void __init udbg_init_pmac_realmode(void);
 extern void __init udbg_init_maple_realmode(void);
 extern void __init udbg_init_iseries(void);
-extern void __init udbg_init_rtas(void);
+extern void __init udbg_init_rtas_panel(void);
+extern void __init udbg_init_rtas_console(void);
 
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_UDBG_H */

^ permalink raw reply

* [PATCH 5/8] Setup RTAS values earlier, to enable rtas_call() earlier
From: Michael Ellerman @ 2006-06-23  8:20 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev, Arnd Bergmann

Althought RTAS is instantiated when we enter the kernel, we can't actually
call into it until we know its entry point address. Currently we grab that
in rtas_initialize(), however that's quite late in the boot sequence.

To enable rtas_call() earlier, we can grab the RTAS entry etc. values while
we're scanning the flattened device tree. There's existing code to retrieve
the values from /chosen, however we don't store them there anymore, so remove
that code.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---

 arch/powerpc/kernel/prom.c |   23 +++++------------------
 arch/powerpc/kernel/rtas.c |   22 ++++++++++++++++++++++
 include/asm-powerpc/rtas.h |    3 +++
 3 files changed, 30 insertions(+), 18 deletions(-)

Index: to-merge/arch/powerpc/kernel/prom.c
===================================================================
--- to-merge.orig/arch/powerpc/kernel/prom.c
+++ to-merge/arch/powerpc/kernel/prom.c
@@ -1125,24 +1125,6 @@ static int __init early_init_dt_scan_cho
  		tce_alloc_end = *lprop;
 #endif
 
-#ifdef CONFIG_PPC_RTAS
-	/* To help early debugging via the front panel, we retrieve a minimal
-	 * set of RTAS infos now if available
-	 */
-	{
-		u64 *basep, *entryp, *sizep;
-
-		basep = of_get_flat_dt_prop(node, "linux,rtas-base", NULL);
-		entryp = of_get_flat_dt_prop(node, "linux,rtas-entry", NULL);
-		sizep = of_get_flat_dt_prop(node, "linux,rtas-size", NULL);
-		if (basep && entryp && sizep) {
-			rtas.base = *basep;
-			rtas.entry = *entryp;
-			rtas.size = *sizep;
-		}
-	}
-#endif /* CONFIG_PPC_RTAS */
-
 #ifdef CONFIG_KEXEC
        lprop = (u64*)of_get_flat_dt_prop(node, "linux,crashkernel-base", NULL);
        if (lprop)
@@ -1327,6 +1309,11 @@ void __init early_init_devtree(void *par
 	/* Setup flat device-tree pointer */
 	initial_boot_params = params;
 
+#ifdef CONFIG_PPC_RTAS
+	/* Some machines might need RTAS info for debugging, grab it now. */
+	of_scan_flat_dt(early_init_dt_scan_rtas, NULL);
+#endif
+
 	/* Retrieve various informations from the /chosen node of the
 	 * device-tree, including the platform type, initrd location and
 	 * size, TCE reserve, and more ...
Index: to-merge/arch/powerpc/kernel/rtas.c
===================================================================
--- to-merge.orig/arch/powerpc/kernel/rtas.c
+++ to-merge/arch/powerpc/kernel/rtas.c
@@ -801,3 +801,25 @@ void __init rtas_initialize(void)
 	rtas_last_error_token = rtas_token("rtas-last-error");
 #endif
 }
+
+int __init early_init_dt_scan_rtas(unsigned long node,
+		const char *uname, int depth, void *data)
+{
+	u32 *basep, *entryp, *sizep;
+
+	if (depth != 1 || strcmp(uname, "rtas") != 0)
+		return 0;
+
+	basep  = of_get_flat_dt_prop(node, "linux,rtas-base", NULL);
+	entryp = of_get_flat_dt_prop(node, "linux,rtas-entry", NULL);
+	sizep  = of_get_flat_dt_prop(node, "rtas-size", NULL);
+
+	if (basep && entryp && sizep) {
+		rtas.base = *basep;
+		rtas.entry = *entryp;
+		rtas.size = *sizep;
+	}
+
+	/* break now */
+	return 1;
+}
Index: to-merge/include/asm-powerpc/rtas.h
===================================================================
--- to-merge.orig/include/asm-powerpc/rtas.h
+++ to-merge/include/asm-powerpc/rtas.h
@@ -181,6 +181,9 @@ extern int rtas_set_rtc_time(struct rtc_
 extern unsigned int rtas_busy_delay_time(int status);
 extern unsigned int rtas_busy_delay(int status);
 
+extern int early_init_dt_scan_rtas(unsigned long node,
+		const char *uname, int depth, void *data);
+
 extern void pSeries_log_error(char *buf, unsigned int err_type, int fatal);
 
 /* Error types logged.  */

^ permalink raw reply

* [PATCH 4/8] Move RTAS exports next to their declarations
From: Michael Ellerman @ 2006-06-23  8:20 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev, Arnd Bergmann

Move RTAS exports next to their declarations.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---

 arch/powerpc/kernel/rtas.c |   27 +++++++++++++--------------
 1 file changed, 13 insertions(+), 14 deletions(-)

Index: to-merge/arch/powerpc/kernel/rtas.c
===================================================================
--- to-merge.orig/arch/powerpc/kernel/rtas.c
+++ to-merge/arch/powerpc/kernel/rtas.c
@@ -38,16 +38,19 @@
 struct rtas_t rtas = {
 	.lock = SPIN_LOCK_UNLOCKED
 };
+EXPORT_SYMBOL(rtas);
 
 struct rtas_suspend_me_data {
 	long waiting;
 	struct rtas_args *args;
 };
 
-EXPORT_SYMBOL(rtas);
-
 DEFINE_SPINLOCK(rtas_data_buf_lock);
+EXPORT_SYMBOL(rtas_data_buf_lock);
+
 char rtas_data_buf[RTAS_DATA_BUF_SIZE] __cacheline_aligned;
+EXPORT_SYMBOL(rtas_data_buf);
+
 unsigned long rtas_rmo_buf;
 
 /*
@@ -236,6 +239,7 @@ int rtas_token(const char *service)
 	tokp = (int *) get_property(rtas.dev, service, NULL);
 	return tokp ? *tokp : RTAS_UNKNOWN_SERVICE;
 }
+EXPORT_SYMBOL(rtas_token);
 
 #ifdef CONFIG_RTAS_ERROR_LOGGING
 /*
@@ -369,6 +373,7 @@ int rtas_call(int token, int nargs, int 
 	}
 	return ret;
 }
+EXPORT_SYMBOL(rtas_call);
 
 /* For RTAS_BUSY (-2), delay for 1 millisecond.  For an extended busy status
  * code of 990n, perform the hinted delay of 10^n (last digit) milliseconds.
@@ -388,6 +393,7 @@ unsigned int rtas_busy_delay_time(int st
 
 	return ms;
 }
+EXPORT_SYMBOL(rtas_busy_delay_time);
 
 /* For an RTAS busy status code, perform the hinted delay. */
 unsigned int rtas_busy_delay(int status)
@@ -401,6 +407,7 @@ unsigned int rtas_busy_delay(int status)
 
 	return ms;
 }
+EXPORT_SYMBOL(rtas_busy_delay);
 
 int rtas_error_rc(int rtas_rc)
 {
@@ -446,6 +453,7 @@ int rtas_get_power_level(int powerdomain
 		return rtas_error_rc(rc);
 	return rc;
 }
+EXPORT_SYMBOL(rtas_get_power_level);
 
 int rtas_set_power_level(int powerdomain, int level, int *setlevel)
 {
@@ -463,6 +471,7 @@ int rtas_set_power_level(int powerdomain
 		return rtas_error_rc(rc);
 	return rc;
 }
+EXPORT_SYMBOL(rtas_set_power_level);
 
 int rtas_get_sensor(int sensor, int index, int *state)
 {
@@ -480,6 +489,7 @@ int rtas_get_sensor(int sensor, int inde
 		return rtas_error_rc(rc);
 	return rc;
 }
+EXPORT_SYMBOL(rtas_get_sensor);
 
 int rtas_set_indicator(int indicator, int index, int new_value)
 {
@@ -497,6 +507,7 @@ int rtas_set_indicator(int indicator, in
 		return rtas_error_rc(rc);
 	return rc;
 }
+EXPORT_SYMBOL(rtas_set_indicator);
 
 void rtas_restart(char *cmd)
 {
@@ -790,15 +801,3 @@ void __init rtas_initialize(void)
 	rtas_last_error_token = rtas_token("rtas-last-error");
 #endif
 }
-
-
-EXPORT_SYMBOL(rtas_token);
-EXPORT_SYMBOL(rtas_call);
-EXPORT_SYMBOL(rtas_data_buf);
-EXPORT_SYMBOL(rtas_data_buf_lock);
-EXPORT_SYMBOL(rtas_busy_delay_time);
-EXPORT_SYMBOL(rtas_busy_delay);
-EXPORT_SYMBOL(rtas_get_sensor);
-EXPORT_SYMBOL(rtas_get_power_level);
-EXPORT_SYMBOL(rtas_set_power_level);
-EXPORT_SYMBOL(rtas_set_indicator);

^ permalink raw reply

* [PATCH 3/8] Make rtas_call() safe if RTAS hasn't been initialised
From: Michael Ellerman @ 2006-06-23  8:20 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev, Arnd Bergmann

Currently it's unsafe to call rtas_call() prior to rtas_initialize(). This
is because the rtas.entry value hasn't been setup and so we don't know
where to enter, but we just try anyway.

We can't do anything intelligent without rtas.entry, so if it's not set, just
return. Code that calls rtas_call() early needs to be aware that the call
might fail.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---

 arch/powerpc/kernel/rtas.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: to-merge/arch/powerpc/kernel/rtas.c
===================================================================
--- to-merge.orig/arch/powerpc/kernel/rtas.c
+++ to-merge/arch/powerpc/kernel/rtas.c
@@ -328,7 +328,7 @@ int rtas_call(int token, int nargs, int 
 	char *buff_copy = NULL;
 	int ret;
 
-	if (token == RTAS_UNKNOWN_SERVICE)
+	if (!rtas.entry || token == RTAS_UNKNOWN_SERVICE)
 		return -1;
 
 	/* Gotta do something different here, use global lock for now... */

^ permalink raw reply

* [PATCH 2/8] Assume we're on cpu 0 in early boot
From: Michael Ellerman @ 2006-06-23  8:20 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev, Arnd Bergmann

There's a small period early in boot where we don't know which cpu we're
running on. That's ok, except that it means we have no paca, or more
correctly that our paca pointer points somewhere random.

So that we can safely call things like smp_processor_id(), we need a paca,
so just assume we're on cpu 0. No code should _write_ to the paca before
we've set the correct one up.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---

 arch/powerpc/kernel/head_64.S |   10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

Index: to-merge/arch/powerpc/kernel/head_64.S
===================================================================
--- to-merge.orig/arch/powerpc/kernel/head_64.S
+++ to-merge/arch/powerpc/kernel/head_64.S
@@ -1583,9 +1583,6 @@ _GLOBAL(__start_initialization_multiplat
 	/* Setup some critical 970 SPRs before switching MMU off */
 	bl	.__970_cpu_preinit
 
-	/* cpu # */
-	li	r24,0
-
 	/* Switch off MMU if not already */
 	LOAD_REG_IMMEDIATE(r4, .__after_prom_start - KERNELBASE)
 	add	r4,r4,r30
@@ -1908,6 +1905,13 @@ _STATIC(start_here_multiplatform)
 	bl	.__save_cpu_setup
 	sync
 
+	/* Assume we're on cpu for now, we don't actually know yet.
+	 * The early setup code should not write to any paca fields until
+	 * after we've setup the correct paca. See early_setup() */
+	li	r24,0
+	li	r3,0
+	bl	.setup_paca
+
 	/* Do very early kernel initializations, including initial hash table,
 	 * stab and slb setup before we turn on relocation.	*/
 

^ permalink raw reply

* [PATCH 1/8] Setup the boot cpu's paca pointer in C rather than asm
From: Michael Ellerman @ 2006-06-23  8:20 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev, Arnd Bergmann

There's no need to set the boot cpu paca in asm, so do it in C so us
mere mortals can understand it.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---

 arch/powerpc/kernel/head_64.S  |   11 -----------
 arch/powerpc/kernel/setup_64.c |    9 ++++++++-
 2 files changed, 8 insertions(+), 12 deletions(-)

Index: to-merge/arch/powerpc/kernel/head_64.S
===================================================================
--- to-merge.orig/arch/powerpc/kernel/head_64.S
+++ to-merge/arch/powerpc/kernel/head_64.S
@@ -1976,17 +1976,6 @@ _STATIC(start_here_common)
 	/* Not reached */
 	BUG_OPCODE
 
-/* Put the paca pointer into r13 and SPRG3 */
-_GLOBAL(setup_boot_paca)
-	LOAD_REG_IMMEDIATE(r3, boot_cpuid)
-	lwz	r3,0(r3)
-	LOAD_REG_IMMEDIATE(r4, paca) 	/* Get base vaddr of paca array	 */
-	mulli	r3,r3,PACA_SIZE		/* Calculate vaddr of right paca */
-	add	r13,r3,r4		/* for this processor.		 */
-	mtspr	SPRN_SPRG3,r13
-
-	blr
-
 /*
  * We put a few things here that have to be page-aligned.
  * This stuff goes at the beginning of the bss, which is page-aligned.
Index: to-merge/arch/powerpc/kernel/setup_64.c
===================================================================
--- to-merge.orig/arch/powerpc/kernel/setup_64.c
+++ to-merge/arch/powerpc/kernel/setup_64.c
@@ -149,6 +149,13 @@ early_param("smt-enabled", early_smt_ena
 #define check_smt_enabled()
 #endif /* CONFIG_SMP */
 
+/* Put the paca pointer into r13 and SPRG3 */
+void __init setup_paca(int cpu)
+{
+	local_paca = &paca[cpu];
+	mtspr(SPRN_SPRG3, local_paca);
+}
+
 /*
  * Early initialization entry point. This is called by head.S
  * with MMU translation disabled. We rely on the "feature" of
@@ -183,7 +190,7 @@ void __init early_setup(unsigned long dt
 	early_init_devtree(__va(dt_ptr));
 
 	/* Now we know the logical id of our boot cpu, setup the paca. */
-	setup_boot_paca();
+	setup_paca(boot_cpuid);
 
 	/* Fix up paca fields required for the boot cpu */
 	get_paca()->cpu_start = 1;

^ permalink raw reply

* [PATCH] Make kexec_setup() a regular initcall
From: Michael Ellerman @ 2006-06-23  8:17 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev

There's no reason kexec_setup() needs to be called explicitly from
setup_system(), it can just be a regular initcall.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---

 arch/powerpc/kernel/machine_kexec_64.c |    4 +++-
 arch/powerpc/kernel/setup_64.c         |    4 ----
 include/asm-powerpc/kexec.h            |    1 -
 3 files changed, 3 insertions(+), 6 deletions(-)

Index: to-merge/arch/powerpc/kernel/machine_kexec_64.c
===================================================================
--- to-merge.orig/arch/powerpc/kernel/machine_kexec_64.c
+++ to-merge/arch/powerpc/kernel/machine_kexec_64.c
@@ -378,11 +378,13 @@ static void __init export_crashk_values(
 	of_node_put(node);
 }
 
-void __init kexec_setup(void)
+static int __init kexec_setup(void)
 {
 	export_htab_values();
 	export_crashk_values();
+	return 0;
 }
+__initcall(kexec_setup);
 
 static int __init early_parse_crashk(char *p)
 {
Index: to-merge/arch/powerpc/kernel/setup_64.c
===================================================================
--- to-merge.orig/arch/powerpc/kernel/setup_64.c
+++ to-merge/arch/powerpc/kernel/setup_64.c
@@ -350,10 +350,6 @@ void __init setup_system(void)
 	 */
 	unflatten_device_tree();
 
-#ifdef CONFIG_KEXEC
-	kexec_setup();	/* requires unflattened device tree. */
-#endif
-
 	/*
 	 * Fill the ppc64_caches & systemcfg structures with informations
 	 * retrieved from the device-tree. Need to be called before
Index: to-merge/include/asm-powerpc/kexec.h
===================================================================
--- to-merge.orig/include/asm-powerpc/kexec.h
+++ to-merge/include/asm-powerpc/kexec.h
@@ -112,7 +112,6 @@ static inline void crash_setup_regs(stru
 #ifdef __powerpc64__
 extern void kexec_smp_wait(void);	/* get and clear naca physid, wait for
 					  master to copy new code to 0 */
-extern void __init kexec_setup(void);
 extern int crashing_cpu;
 extern void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *));
 #endif /* __powerpc64 __ */

^ permalink raw reply

* [PATCH 2/2] Use ppc_md.hpte_insert() in htab_bolt_mapping()
From: Michael Ellerman @ 2006-06-23  8:16 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev

With the ppc_md htab pointers setup earlier, we can use ppc_md.hpte_insert
in htab_bolt_mapping(), rather than deciding which version to call by hand.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---

 arch/powerpc/mm/hash_utils_64.c |   34 ++++++----------------------------
 1 file changed, 6 insertions(+), 28 deletions(-)

Index: to-merge/arch/powerpc/mm/hash_utils_64.c
===================================================================
--- to-merge.orig/arch/powerpc/mm/hash_utils_64.c
+++ to-merge/arch/powerpc/mm/hash_utils_64.c
@@ -167,34 +167,12 @@ int htab_bolt_mapping(unsigned long vsta
 		hash = hpt_hash(va, shift);
 		hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP);
 
-		/* The crap below can be cleaned once ppd_md.probe() can
-		 * set up the hash callbacks, thus we can just used the
-		 * normal insert callback here.
-		 */
-#ifdef CONFIG_PPC_ISERIES
-		if (machine_is(iseries))
-			ret = iSeries_hpte_insert(hpteg, va,
-						  paddr,
-						  tmp_mode,
-						  HPTE_V_BOLTED,
-						  psize);
-		else
-#endif
-#ifdef CONFIG_PPC_PSERIES
-		if (machine_is(pseries) && firmware_has_feature(FW_FEATURE_LPAR))
-			ret = pSeries_lpar_hpte_insert(hpteg, va,
-						       paddr,
-						       tmp_mode,
-						       HPTE_V_BOLTED,
-						       psize);
-		else
-#endif
-#ifdef CONFIG_PPC_MULTIPLATFORM
-			ret = native_hpte_insert(hpteg, va,
-						 paddr,
-						 tmp_mode, HPTE_V_BOLTED,
-						 psize);
-#endif
+		DBG("htab_bolt_mapping: calling %p\n", ppc_md.hpte_insert);
+
+		BUG_ON(!ppc_md.hpte_insert);
+		ret = ppc_md.hpte_insert(hpteg, va, paddr,
+				tmp_mode, HPTE_V_BOLTED, psize);
+
 		if (ret < 0)
 			break;
 	}

^ permalink raw reply

* [PATCH 1/2] powerpc: Initialise ppc_md htab pointers earlier
From: Michael Ellerman @ 2006-06-23  8:16 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev

Initialise the ppc_md htab callbacks earlier, in the probe routines. This
allows us to call htab_finish_init() from htab_initialize(), and makes it
private to hash_utils_64.c. Move htab_finish_init() and make_bl() above
htab_initialize() to avoid forward declarations.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---

 arch/powerpc/kernel/setup_64.c          |    6 --
 arch/powerpc/mm/hash_native_64.c        |    3 -
 arch/powerpc/mm/hash_utils_64.c         |   72 ++++++++++++++++----------------
 arch/powerpc/platforms/cell/setup.c     |   12 ++---
 arch/powerpc/platforms/iseries/htab.c   |    4 -
 arch/powerpc/platforms/iseries/setup.c  |    7 ---
 arch/powerpc/platforms/maple/setup.c    |    7 ---
 arch/powerpc/platforms/powermac/setup.c |    9 ----
 arch/powerpc/platforms/pseries/lpar.c   |    4 -
 arch/powerpc/platforms/pseries/setup.c  |   10 ++--
 include/asm-powerpc/mmu.h               |    1 
 11 files changed, 58 insertions(+), 77 deletions(-)

Index: to-merge/arch/powerpc/kernel/setup_64.c
===================================================================
--- to-merge.orig/arch/powerpc/kernel/setup_64.c
+++ to-merge/arch/powerpc/kernel/setup_64.c
@@ -358,11 +358,7 @@ void __init setup_system(void)
 	 * Fill the ppc64_caches & systemcfg structures with informations
 	 * retrieved from the device-tree. Need to be called before
 	 * finish_device_tree() since the later requires some of the
-	 * informations filled up here to properly parse the interrupt
-	 * tree.
-	 * It also sets up the cache line sizes which allows to call
-	 * routines like flush_icache_range (used by the hash init
-	 * later on).
+	 * informations filled up here to properly parse the interrupt tree.
 	 */
 	initialize_cache_info();
 
Index: to-merge/arch/powerpc/mm/hash_native_64.c
===================================================================
--- to-merge.orig/arch/powerpc/mm/hash_native_64.c
+++ to-merge/arch/powerpc/mm/hash_native_64.c
@@ -520,7 +520,7 @@ static inline int tlb_batching_enabled(v
 }
 #endif
 
-void hpte_init_native(void)
+void __init hpte_init_native(void)
 {
 	ppc_md.hpte_invalidate	= native_hpte_invalidate;
 	ppc_md.hpte_updatepp	= native_hpte_updatepp;
@@ -530,5 +530,4 @@ void hpte_init_native(void)
 	ppc_md.hpte_clear_all	= native_hpte_clear;
 	if (tlb_batching_enabled())
 		ppc_md.flush_hash_range = native_flush_hash_range;
-	htab_finish_init();
 }
Index: to-merge/arch/powerpc/mm/hash_utils_64.c
===================================================================
--- to-merge.orig/arch/powerpc/mm/hash_utils_64.c
+++ to-merge/arch/powerpc/mm/hash_utils_64.c
@@ -413,6 +413,41 @@ void create_section_mapping(unsigned lon
 }
 #endif /* CONFIG_MEMORY_HOTPLUG */
 
+static inline void make_bl(unsigned int *insn_addr, void *func)
+{
+	unsigned long funcp = *((unsigned long *)func);
+	int offset = funcp - (unsigned long)insn_addr;
+
+	*insn_addr = (unsigned int)(0x48000001 | (offset & 0x03fffffc));
+	flush_icache_range((unsigned long)insn_addr, 4+
+			   (unsigned long)insn_addr);
+}
+
+static void __init htab_finish_init(void)
+{
+	extern unsigned int *htab_call_hpte_insert1;
+	extern unsigned int *htab_call_hpte_insert2;
+	extern unsigned int *htab_call_hpte_remove;
+	extern unsigned int *htab_call_hpte_updatepp;
+
+#ifdef CONFIG_PPC_64K_PAGES
+	extern unsigned int *ht64_call_hpte_insert1;
+	extern unsigned int *ht64_call_hpte_insert2;
+	extern unsigned int *ht64_call_hpte_remove;
+	extern unsigned int *ht64_call_hpte_updatepp;
+
+	make_bl(ht64_call_hpte_insert1, ppc_md.hpte_insert);
+	make_bl(ht64_call_hpte_insert2, ppc_md.hpte_insert);
+	make_bl(ht64_call_hpte_remove, ppc_md.hpte_remove);
+	make_bl(ht64_call_hpte_updatepp, ppc_md.hpte_updatepp);
+#endif /* CONFIG_PPC_64K_PAGES */
+
+	make_bl(htab_call_hpte_insert1, ppc_md.hpte_insert);
+	make_bl(htab_call_hpte_insert2, ppc_md.hpte_insert);
+	make_bl(htab_call_hpte_remove, ppc_md.hpte_remove);
+	make_bl(htab_call_hpte_updatepp, ppc_md.hpte_updatepp);
+}
+
 void __init htab_initialize(void)
 {
 	unsigned long table;
@@ -525,6 +560,8 @@ void __init htab_initialize(void)
 					 mmu_linear_psize));
 	}
 
+	htab_finish_init();
+
 	DBG(" <- htab_initialize()\n");
 }
 #undef KB
@@ -787,16 +824,6 @@ void flush_hash_range(unsigned long numb
 	}
 }
 
-static inline void make_bl(unsigned int *insn_addr, void *func)
-{
-	unsigned long funcp = *((unsigned long *)func);
-	int offset = funcp - (unsigned long)insn_addr;
-
-	*insn_addr = (unsigned int)(0x48000001 | (offset & 0x03fffffc));
-	flush_icache_range((unsigned long)insn_addr, 4+
-			   (unsigned long)insn_addr);
-}
-
 /*
  * low_hash_fault is called when we the low level hash code failed
  * to instert a PTE due to an hypervisor error
@@ -815,28 +842,3 @@ void low_hash_fault(struct pt_regs *regs
 	}
 	bad_page_fault(regs, address, SIGBUS);
 }
-
-void __init htab_finish_init(void)
-{
-	extern unsigned int *htab_call_hpte_insert1;
-	extern unsigned int *htab_call_hpte_insert2;
-	extern unsigned int *htab_call_hpte_remove;
-	extern unsigned int *htab_call_hpte_updatepp;
-
-#ifdef CONFIG_PPC_64K_PAGES
-	extern unsigned int *ht64_call_hpte_insert1;
-	extern unsigned int *ht64_call_hpte_insert2;
-	extern unsigned int *ht64_call_hpte_remove;
-	extern unsigned int *ht64_call_hpte_updatepp;
-
-	make_bl(ht64_call_hpte_insert1, ppc_md.hpte_insert);
-	make_bl(ht64_call_hpte_insert2, ppc_md.hpte_insert);
-	make_bl(ht64_call_hpte_remove, ppc_md.hpte_remove);
-	make_bl(ht64_call_hpte_updatepp, ppc_md.hpte_updatepp);
-#endif /* CONFIG_PPC_64K_PAGES */
-
-	make_bl(htab_call_hpte_insert1, ppc_md.hpte_insert);
-	make_bl(htab_call_hpte_insert2, ppc_md.hpte_insert);
-	make_bl(htab_call_hpte_remove, ppc_md.hpte_remove);
-	make_bl(htab_call_hpte_updatepp, ppc_md.hpte_updatepp);
-}
Index: to-merge/arch/powerpc/platforms/cell/setup.c
===================================================================
--- to-merge.orig/arch/powerpc/platforms/cell/setup.c
+++ to-merge/arch/powerpc/platforms/cell/setup.c
@@ -125,8 +125,6 @@ static void __init cell_init_early(void)
 {
 	DBG(" -> cell_init_early()\n");
 
-	hpte_init_native();
-
 	cell_init_iommu();
 
 	ppc64_interrupt_controller = IC_CELL_PIC;
@@ -139,11 +137,13 @@ static int __init cell_probe(void)
 {
 	unsigned long root = of_get_flat_dt_root();
 
-	if (of_flat_dt_is_compatible(root, "IBM,CBEA") ||
-	    of_flat_dt_is_compatible(root, "IBM,CPBW-1.0"))
-		return 1;
+	if (!of_flat_dt_is_compatible(root, "IBM,CBEA") &&
+	    !of_flat_dt_is_compatible(root, "IBM,CPBW-1.0"))
+		return 0;
+
+	hpte_init_native();
 
-	return 0;
+	return 1;
 }
 
 /*
Index: to-merge/arch/powerpc/platforms/iseries/htab.c
===================================================================
--- to-merge.orig/arch/powerpc/platforms/iseries/htab.c
+++ to-merge/arch/powerpc/platforms/iseries/htab.c
@@ -242,13 +242,11 @@ static void iSeries_hpte_invalidate(unsi
 	local_irq_restore(flags);
 }
 
-void hpte_init_iSeries(void)
+void __init hpte_init_iSeries(void)
 {
 	ppc_md.hpte_invalidate	= iSeries_hpte_invalidate;
 	ppc_md.hpte_updatepp	= iSeries_hpte_updatepp;
 	ppc_md.hpte_updateboltedpp = iSeries_hpte_updateboltedpp;
 	ppc_md.hpte_insert	= iSeries_hpte_insert;
 	ppc_md.hpte_remove	= iSeries_hpte_remove;
-
-	htab_finish_init();
 }
Index: to-merge/arch/powerpc/platforms/iseries/setup.c
===================================================================
--- to-merge.orig/arch/powerpc/platforms/iseries/setup.c
+++ to-merge/arch/powerpc/platforms/iseries/setup.c
@@ -319,11 +319,6 @@ static void __init iSeries_init_early(vo
 	iSeries_recal_titan = HvCallXm_loadTod();
 
 	/*
-	 * Initialize the hash table management pointers
-	 */
-	hpte_init_iSeries();
-
-	/*
 	 * Initialize the DMA/TCE management
 	 */
 	iommu_init_early_iSeries();
@@ -671,6 +666,8 @@ static int __init iseries_probe(void)
 	 */
 	virt_irq_max = 255;
 
+	hpte_init_iSeries();
+
 	return 1;
 }
 
Index: to-merge/arch/powerpc/platforms/maple/setup.c
===================================================================
--- to-merge.orig/arch/powerpc/platforms/maple/setup.c
+++ to-merge/arch/powerpc/platforms/maple/setup.c
@@ -199,11 +199,6 @@ static void __init maple_init_early(void
 {
 	DBG(" -> maple_init_early\n");
 
-	/* Initialize hash table, from now on, we can take hash faults
-	 * and call ioremap
-	 */
-	hpte_init_native();
-
 	/* Setup interrupt mapping options */
 	ppc64_interrupt_controller = IC_OPEN_PIC;
 
@@ -272,6 +267,8 @@ static int __init maple_probe(void)
 	 */
 	alloc_dart_table();
 
+	hpte_init_native();
+
 	return 1;
 }
 
Index: to-merge/arch/powerpc/platforms/powermac/setup.c
===================================================================
--- to-merge.orig/arch/powerpc/platforms/powermac/setup.c
+++ to-merge/arch/powerpc/platforms/powermac/setup.c
@@ -600,13 +600,6 @@ pmac_halt(void)
  */
 static void __init pmac_init_early(void)
 {
-#ifdef CONFIG_PPC64
-	/* Initialize hash table, from now on, we can take hash faults
-	 * and call ioremap
-	 */
-	hpte_init_native();
-#endif
-
 	/* Enable early btext debug if requested */
 	if (strstr(cmd_line, "btextdbg")) {
 		udbg_adb_init_early();
@@ -683,6 +676,8 @@ static int __init pmac_probe(void)
 	 * part of the cacheable linar mapping
 	 */
 	alloc_dart_table();
+
+	hpte_init_native();
 #endif
 
 #ifdef CONFIG_PPC32
Index: to-merge/arch/powerpc/platforms/pseries/lpar.c
===================================================================
--- to-merge.orig/arch/powerpc/platforms/pseries/lpar.c
+++ to-merge/arch/powerpc/platforms/pseries/lpar.c
@@ -513,7 +513,7 @@ void pSeries_lpar_flush_hash_range(unsig
 		spin_unlock_irqrestore(&pSeries_lpar_tlbie_lock, flags);
 }
 
-void hpte_init_lpar(void)
+void __init hpte_init_lpar(void)
 {
 	ppc_md.hpte_invalidate	= pSeries_lpar_hpte_invalidate;
 	ppc_md.hpte_updatepp	= pSeries_lpar_hpte_updatepp;
@@ -522,6 +522,4 @@ void hpte_init_lpar(void)
 	ppc_md.hpte_remove	= pSeries_lpar_hpte_remove;
 	ppc_md.flush_hash_range	= pSeries_lpar_flush_hash_range;
 	ppc_md.hpte_clear_all   = pSeries_lpar_hptab_clear;
-
-	htab_finish_init();
 }
Index: to-merge/arch/powerpc/platforms/pseries/setup.c
===================================================================
--- to-merge.orig/arch/powerpc/platforms/pseries/setup.c
+++ to-merge/arch/powerpc/platforms/pseries/setup.c
@@ -322,11 +322,6 @@ static void __init pSeries_init_early(vo
 	DBG(" -> pSeries_init_early()\n");
 
 	fw_feature_init();
-	
-	if (firmware_has_feature(FW_FEATURE_LPAR))
-		hpte_init_lpar();
-	else
-		hpte_init_native();
 
 	if (firmware_has_feature(FW_FEATURE_LPAR))
 		find_udbg_vterm();
@@ -384,6 +379,11 @@ static int __init pSeries_probe_hypertas
 	if (of_get_flat_dt_prop(node, "ibm,hypertas-functions", NULL) != NULL)
  		powerpc_firmware_features |= FW_FEATURE_LPAR;
 
+	if (firmware_has_feature(FW_FEATURE_LPAR))
+		hpte_init_lpar();
+	else
+		hpte_init_native();
+
  	return 1;
 }
 
Index: to-merge/include/asm-powerpc/mmu.h
===================================================================
--- to-merge.orig/include/asm-powerpc/mmu.h
+++ to-merge/include/asm-powerpc/mmu.h
@@ -238,7 +238,6 @@ extern int hash_huge_page(struct mm_stru
 			  unsigned long ea, unsigned long vsid, int local,
 			  unsigned long trap);
 
-extern void htab_finish_init(void);
 extern int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
 			     unsigned long pstart, unsigned long mode,
 			     int psize);

^ permalink raw reply

* [PATCH] Export flat device tree via debugfs for debugging
From: Michael Ellerman @ 2006-06-23  8:16 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev

If DEBUG is turned on in prom.c, export the flat device tree via debugfs.
This has been handy on several occasions.

To look at it:
 # mount -t debugfs none /sys/kernel/debug
 # od -a /sys/kernel/debug/powerpc/flat-device-tree
 and/or
 # dtc -fI dtb /sys/kernel/debug/powerpc/flat-device-tree -O dts

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---

 arch/powerpc/kernel/prom.c |   25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

Index: to-merge/arch/powerpc/kernel/prom.c
===================================================================
--- to-merge.orig/arch/powerpc/kernel/prom.c
+++ to-merge/arch/powerpc/kernel/prom.c
@@ -30,6 +30,7 @@
 #include <linux/bitops.h>
 #include <linux/module.h>
 #include <linux/kexec.h>
+#include <linux/debugfs.h>
 
 #include <asm/prom.h>
 #include <asm/rtas.h>
@@ -2148,3 +2149,27 @@ struct device_node *of_get_cpu_node(int 
 	}
 	return NULL;
 }
+
+#ifdef DEBUG
+static struct debugfs_blob_wrapper flat_dt_blob;
+
+static int __init export_flat_device_tree(void)
+{
+	struct dentry *d;
+
+	d = debugfs_create_dir("powerpc", NULL);
+	if (!d)
+		return 1;
+
+	flat_dt_blob.data = initial_boot_params;
+	flat_dt_blob.size = initial_boot_params->totalsize;
+
+	d = debugfs_create_blob("flat-device-tree", S_IFREG | S_IRUSR,
+				d, &flat_dt_blob);
+	if (!d)
+		return 1;
+
+	return 0;
+}
+__initcall(export_flat_device_tree);
+#endif

^ permalink raw reply

* [PATCH] Remove remaining iSeries debugger cruft
From: Michael Ellerman @ 2006-06-23  8:15 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev

None of this seems to be necessary, so let's see if can remove it and not
break anything. Booted on iSeries & pSeries here.

NB. we don't remove the hvReleaseData, we just move it down so that the file
reads more clearly.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---

 arch/powerpc/kernel/head_64.S          |   37 ++++++++-------------------------
 arch/powerpc/platforms/iseries/setup.c |   12 ----------
 2 files changed, 9 insertions(+), 40 deletions(-)

Index: to-merge/arch/powerpc/kernel/head_64.S
===================================================================
--- to-merge.orig/arch/powerpc/kernel/head_64.S
+++ to-merge/arch/powerpc/kernel/head_64.S
@@ -85,34 +85,6 @@ END_FTR_SECTION(0, 1)
 	/* Catch branch to 0 in real mode */
 	trap
 
-#ifdef CONFIG_PPC_ISERIES
-	/*
-	 * At offset 0x20, there is a pointer to iSeries LPAR data.
-	 * This is required by the hypervisor
-	 */
-	. = 0x20
-	.llong hvReleaseData-KERNELBASE
-
-	/*
-	 * At offset 0x28 and 0x30 are offsets to the mschunks_map
-	 * array (used by the iSeries LPAR debugger to do translation
-	 * between physical addresses and absolute addresses) and
-	 * to the pidhash table (also used by the debugger)
-	 */
-	.llong mschunks_map-KERNELBASE
-	.llong 0	/* pidhash-KERNELBASE SFRXXX */
-
-	/* Offset 0x38 - Pointer to start of embedded System.map */
-	.globl	embedded_sysmap_start
-embedded_sysmap_start:
-	.llong	0
-	/* Offset 0x40 - Pointer to end of embedded System.map */
-	.globl	embedded_sysmap_end
-embedded_sysmap_end:
-	.llong	0
-
-#endif /* CONFIG_PPC_ISERIES */
-
 	/* Secondary processors spin on this value until it goes to 1. */
 	.globl  __secondary_hold_spinloop
 __secondary_hold_spinloop:
@@ -124,6 +96,15 @@ __secondary_hold_spinloop:
 __secondary_hold_acknowledge:
 	.llong	0x0
 
+#ifdef CONFIG_PPC_ISERIES
+	/*
+	 * At offset 0x20, there is a pointer to iSeries LPAR data.
+	 * This is required by the hypervisor
+	 */
+	. = 0x20
+	.llong hvReleaseData-KERNELBASE
+#endif /* CONFIG_PPC_ISERIES */
+
 	. = 0x60
 /*
  * The following code is used on pSeries to hold secondary processors
Index: to-merge/arch/powerpc/platforms/iseries/setup.c
===================================================================
--- to-merge.orig/arch/powerpc/platforms/iseries/setup.c
+++ to-merge/arch/powerpc/platforms/iseries/setup.c
@@ -81,8 +81,6 @@ static void iSeries_pci_final_fixup(void
 #endif
 
 extern int rd_size;		/* Defined in drivers/block/rd.c */
-extern unsigned long embedded_sysmap_start;
-extern unsigned long embedded_sysmap_end;
 
 extern unsigned long iSeries_recal_tb;
 extern unsigned long iSeries_recal_titan;
@@ -563,16 +561,6 @@ static void __init iSeries_fixup_klimit(
 	if (naca.xRamDisk)
 		klimit = KERNELBASE + (u64)naca.xRamDisk +
 			(naca.xRamDiskSize * HW_PAGE_SIZE);
-	else {
-		/*
-		 * No ram disk was included - check and see if there
-		 * was an embedded system map.  Change klimit to take
-		 * into account any embedded system map
-		 */
-		if (embedded_sysmap_end)
-			klimit = KERNELBASE + ((embedded_sysmap_end + 4095) &
-					0xfffffffffffff000);
-	}
 }
 
 static int __init iSeries_src_init(void)

^ permalink raw reply

* Help on OHCI USB host present in SM501 chip
From: robinpv @ 2006-06-23  6:48 UTC (permalink / raw)
  To: linuxppc-dev

Hi ,
I am using MPC5200 based board and i have SM501 Mobile Multimedia 
companion chip on the PCI bus.
I am writing OHCI USB host present on the SM501 chip. I wanted to know 
if driver already exists.
I searched in linux ppc,  i could find the driver for the VGA( 
controller present in SM501) but not USB.
Currently i am referring to ohci-sa1111.c as reference.

Thanks in advance
Robin

^ permalink raw reply

* [PATCH] powerpc: kdump: Reserve the existing TCE mappings left by the first kernel
From: Haren Myneni @ 2006-06-23  6:35 UTC (permalink / raw)
  To: Paul Mackerras, Olof Johansson; +Cc: linuxppc-dev

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

Paul, Olof,

tce_union got removed in powerpc.git tree. Hence reposting the patch 
created against this tree. This patch is implemented based on Olof's 
suggestion of reserving TCE entries and use only available ones in the 
kdump boot and tested on P5, P4, JS20 and JS21 machines.

If you are OK with this patch, please send it to upstream.

Thanks
Haren

During kdump boot, noticed some machines checkstop on dma protection 
fault for ongoing DMA left in the first kernel. Instead of initializing 
TCE entries in iommu_init() for the kdump boot, this patch fixes this 
issue by walking through the each TCE table and checks whether the 
entries are in use by the first kernel. If so, reserve those entries by 
setting the corresponding bit in tbl->it_map such that these entries 
will not be available for the kdump boot.

However it could be possible that all TCE entries might be used up due 
to the driver bug that does continuous mapping. My observation is around 
1700 TCE  entries are used on some systems (Ex: P4) at some point of 
time during kdump boot and saving dump (either write into the disk or 
sending to remote machine). Hence, this patch will make sure that 
minimum of 2048 entries will be available such that kdump boot could be 
successful in some cases.

Signed-off-by: Haren Myneni <haren@us.ibm.com>



[-- Attachment #2: ppc64-kdump-checkstop-DMA-fault-fix.patch --]
[-- Type: text/x-patch, Size: 4853 bytes --]

diff -Naurp powerpc.git.orig/arch/powerpc/kernel/iommu.c powerpc.git/arch/powerpc/kernel/iommu.c
--- powerpc.git.orig/arch/powerpc/kernel/iommu.c	2006-06-19 00:54:37.000000000 -0500
+++ powerpc.git/arch/powerpc/kernel/iommu.c	2006-06-19 00:52:31.000000000 -0500
@@ -38,6 +38,7 @@
 #include <asm/iommu.h>
 #include <asm/pci-bridge.h>
 #include <asm/machdep.h>
+#include <asm/kdump.h>
 
 #define DBG(...)
 
@@ -440,8 +441,37 @@ struct iommu_table *iommu_init_table(str
 	tbl->it_largehint = tbl->it_halfpoint;
 	spin_lock_init(&tbl->it_lock);
 
+#ifdef CONFIG_CRASH_DUMP
+	if (ppc_md.tce_get) {
+		unsigned long index, tceval;
+		unsigned long tcecount = 0;
+
+		/*
+		 * Reserve the existing mappings left by the first kernel.
+		 */
+		for (index = 0; index < tbl->it_size; index++) {
+			tceval = ppc_md.tce_get(tbl, index + tbl->it_offset);
+			/*
+			 * Freed TCE entry contains 0x7fffffffffffffff on JS20
+			 */
+			if (tceval && (tceval != 0x7fffffffffffffffUL)) {
+				__set_bit(index, tbl->it_map);
+				tcecount++;
+			}
+		}
+		if ((tbl->it_size - tcecount) < KDUMP_MIN_TCE_ENTRIES) {
+			printk(KERN_WARNING "TCE table is full; ");
+			printk(KERN_WARNING "freeing %d entries for the kdump boot\n",
+				KDUMP_MIN_TCE_ENTRIES);
+			for (index = tbl->it_size - KDUMP_MIN_TCE_ENTRIES;
+				index < tbl->it_size; index++) 
+				__clear_bit(index, tbl->it_map);
+		}
+	}
+#else
 	/* Clear the hardware table in case firmware left allocations in it */
 	ppc_md.tce_free(tbl, tbl->it_offset, tbl->it_size);
+#endif
 
 	if (!welcomed) {
 		printk(KERN_INFO "IOMMU table initialized, virtual merging %s\n",
diff -Naurp powerpc.git.orig/arch/powerpc/platforms/pseries/iommu.c powerpc.git/arch/powerpc/platforms/pseries/iommu.c
--- powerpc.git.orig/arch/powerpc/platforms/pseries/iommu.c	2006-06-19 00:54:27.000000000 -0500
+++ powerpc.git/arch/powerpc/platforms/pseries/iommu.c	2006-06-19 00:52:44.000000000 -0500
@@ -92,6 +92,15 @@ static void tce_free_pSeries(struct iomm
 		*(tcep++) = 0;
 }
 
+static unsigned long tce_get_pseries(struct iommu_table *tbl, long index)
+{
+	u64 *tcep;
+
+	index <<= TCE_PAGE_FACTOR;
+	tcep = ((u64 *)tbl->it_base) + index;
+
+	return *tcep;
+}
 
 static void tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum,
 				long npages, unsigned long uaddr,
@@ -235,6 +244,25 @@ static void tce_freemulti_pSeriesLP(stru
 	}
 }
 
+static unsigned long tce_get_pSeriesLP(struct iommu_table *tbl, long tcenum)
+{
+	u64 rc;
+	unsigned long tce_ret;
+
+	tcenum <<= TCE_PAGE_FACTOR;
+	rc = plpar_tce_get((u64)tbl->it_index, (u64)tcenum << 12, &tce_ret);
+	
+	if (rc && printk_ratelimit()) {
+		printk("tce_get_pSeriesLP: plpar_tce_get failed. rc=%ld\n",
+			rc);
+		printk("\tindex   = 0x%lx\n", (u64)tbl->it_index);
+		printk("\ttcenum  = 0x%lx\n", (u64)tcenum);
+		show_stack(current, (unsigned long *)__get_SP());
+	}
+	
+	return tce_ret;
+}
+
 static void iommu_table_setparms(struct pci_controller *phb,
 				 struct device_node *dn,
 				 struct iommu_table *tbl)
@@ -254,7 +282,10 @@ static void iommu_table_setparms(struct 
 	}
 
 	tbl->it_base = (unsigned long)__va(*basep);
+
+#ifndef CONFIG_CRASH_DUMP
 	memset((void *)tbl->it_base, 0, *sizep);
+#endif
 
 	tbl->it_busno = phb->bus->number;
 
@@ -564,11 +595,13 @@ void iommu_init_early_pSeries(void)
 			ppc_md.tce_build = tce_build_pSeriesLP;
 			ppc_md.tce_free	 = tce_free_pSeriesLP;
 		}
+		ppc_md.tce_get   = tce_get_pSeriesLP;
 		ppc_md.iommu_bus_setup = iommu_bus_setup_pSeriesLP;
 		ppc_md.iommu_dev_setup = iommu_dev_setup_pSeriesLP;
 	} else {
 		ppc_md.tce_build = tce_build_pSeries;
 		ppc_md.tce_free  = tce_free_pSeries;
+		ppc_md.tce_get   = tce_get_pseries;
 		ppc_md.iommu_bus_setup = iommu_bus_setup_pSeries;
 		ppc_md.iommu_dev_setup = iommu_dev_setup_pSeries;
 	}
diff -Naurp powerpc.git.orig/include/asm-powerpc/kdump.h powerpc.git/include/asm-powerpc/kdump.h
--- powerpc.git.orig/include/asm-powerpc/kdump.h	2006-06-19 00:55:11.000000000 -0500
+++ powerpc.git/include/asm-powerpc/kdump.h	2006-06-22 02:48:15.000000000 -0500
@@ -15,6 +15,8 @@
 #define KDUMP_TRAMPOLINE_START	0x0100
 #define KDUMP_TRAMPOLINE_END	0x3000
 
+#define KDUMP_MIN_TCE_ENTRIES	2048
+
 #else /* !CONFIG_CRASH_DUMP */
 
 #define PHYSICAL_START	0x0
diff -Naurp powerpc.git.orig/include/asm-powerpc/machdep.h powerpc.git/include/asm-powerpc/machdep.h
--- powerpc.git.orig/include/asm-powerpc/machdep.h	2006-06-19 00:54:58.000000000 -0500
+++ powerpc.git/include/asm-powerpc/machdep.h	2006-06-19 00:53:05.000000000 -0500
@@ -82,6 +82,8 @@ struct machdep_calls {
 	void		(*tce_free)(struct iommu_table *tbl,
 				    long index,
 				    long npages);
+	unsigned long	(*tce_get)(struct iommu_table *tbl,
+				    long index);
 	void		(*tce_flush)(struct iommu_table *tbl);
 	void		(*iommu_dev_setup)(struct pci_dev *dev);
 	void		(*iommu_bus_setup)(struct pci_bus *bus);

^ permalink raw reply

* Fixed PPC SHA1
From: linux @ 2006-06-23  0:09 UTC (permalink / raw)
  To: git, linuxppc-dev; +Cc: linux
In-Reply-To: <20060619084135.18632.qmail@science.horizon.com>

Okay, here's a tested and working version (the earlier version worked,
too) of a better-scheduled PPC SHA1.  This is about 15% faster that the
current sha1ppc.S on a G4, and 5% faster on a G5 when hashing 10 million
bytes, unaligned.  (The G5 ratio seems to get better as the sizes fall.)

It's also somewhat smaller, due to using load-multiple instructions.

I have a variant that uses load string (lswi) to load the values to be
hashed that is a few percent faster on a G5, but a few percent slower
on a G4.  It's also 52 bytes smaller (out of 4000).

Does anyone have any feeling for the ratio of G4 and G5 machines
out there?  I presume for that small a percentage, run-time processor
detection isn't worth it.  (Cc: to linuxppc-dev for the experts on
this question.)

I've tried using lmw to load the data, and it's faster if the data is
aligned, but it absolutely dies if the data is not.  And due to git's
variable-sized hash prefix, most of git's hashes are of unaligned data.

(No copyright is claimed on the changes to Paul Mackerras' work below.
Enjoy.)

/*
 * SHA-1 implementation for PowerPC.
 *
 * Copyright (C) 2005 Paul Mackerras <paulus@samba.org>
 */

/*
 * PowerPC calling convention:
 * %r0 - volatile temp
 * %r1 - stack pointer.
 * %r2 - reserved
 * %r3-%r12 - Incoming arguments & return values; volatile.
 * %r13-%r31 - Callee-save registers
 * %lr - Return address, volatile
 * %ctr - volatile
 *
 * Register usage in this routine:
 * %r0 - temp
 * %r3 - argument (pointer to 5 words of SHA state)
 * %r4 - argument (pointer to data to hash)
 * %r5 - Contant K in SHA round (initially number of blocks to hash)
 * %r6-%r10 - Working copies of SHA variables A..E (actually E..A order)
 * %r11-%r26 - Data being hashed W[].
 * %r27-%r31 - Previous copies of A..E, for final add back.
 * %ctr - loop count
 */


/*
 * We roll the registers for A, B, C, D, E around on each
 * iteration; E on iteration t is D on iteration t+1, and so on.
 * We use registers 6 - 10 for this.  (Registers 27 - 31 hold
 * the previous values.)
 */
#define RA(t)	(((t)+4)%5+6)
#define RB(t)	(((t)+3)%5+6)
#define RC(t)	(((t)+2)%5+6)
#define RD(t)	(((t)+1)%5+6)
#define RE(t)	(((t)+0)%5+6)

/* We use registers 11 - 26 for the W values */
#define W(t)	((t)%16+11)

/* Register 5 is used for the constant k */

/*
 * The basic SHA-1 round function is:
 * E += ROTL(A,5) + F(B,C,D) + W[i] + K;  B = ROTL(B,30)
 * Then the variables are renamed: (A,B,C,D,E) = (E,A,B,C,D).
 *
 * Every 20 rounds, the function F() and the contant K changes:
 * - 20 rounds of f0(b,c,d) = "bit wise b ? c : d" =  (^b & d) + (b & c)
 * - 20 rounds of f1(b,c,d) = b^c^d = (b^d)^c
 * - 20 rounds of f2(b,c,d) = majority(b,c,d) = (b&d) + ((b^d)&c)
 * - 20 more rounds of f1(b,c,d)
 *
 * These are all scheduled for near-optimal performance on a G4.
 * The G4 is a 3-issue out-of-order machine with 3 ALUs, but it can only
 * *consider* starting the oldest 3 instructions per cycle.  So to get
 * maximum performace out of it, you have to treat it as an in-order
 * machine.  Which means interleaving the computation round t with the
 * computation of W[t+4].
 *
 * The first 16 rounds use W values loaded directly from memory, while the
 * remianing 64 use values computed from those first 16.  We preload
 * 4 values before starting, so there are three kinds of rounds:
 * - The first 12 (all f0) also load the W values from memory.
 * - The next 64 compute W(i+4) in parallel. 8*f0, 20*f1, 20*f2, 16*f1.
 * - The last 4 (all f1) do not do anything with W.
 *
 * Therefore, we have 6 different round functions:
 * STEPD0_LOAD(t,s) - Perform round t and load W(s).  s < 16
 * STEPD0_UPDATE(t,s) - Perform round t and compute W(s).  s >= 16.
 * STEPD1_UPDATE(t,s)
 * STEPD2_UPDATE(t,s)
 * STEPD1(t) - Perform round t with no load or update.
 * 
 * The G5 is more fully out-of-order, and can find the parallelism
 * by itself.  The big limit is that it has a 2-cycle ALU latency, so
 * even though it's 2-way, the code has to be scheduled as if it's
 * 4-way, which can be a limit.  To help it, we try to schedule the
 * read of RA(t) as late as possible so it doesn't stall waiting for
 * the previous round's RE(t-1), and we try to rotate RB(t) as early
 * as possible while reading RC(t) (= RB(t-1)) as late as possible.
 */

/* the initial loads. */
#define LOADW(s) \
	lwz	W(s),(s)*4(%r4)

/*
 * Perform a step with F0, and load W(s).  Uses W(s) as a temporary
 * before loading it.
 * This is actually 10 instructions, which is an awkward fit.
 * It can execute grouped as listed, or delayed one instruction.
 * (If delayed two instructions, there is a stall before the start of the
 * second line.)  Thus, two iterations take 7 cycles, 3.5 cycles per round.
 */
#define STEPD0_LOAD(t,s) \
add RE(t),RE(t),W(t); andc   %r0,RD(t),RB(t);  and    W(s),RC(t),RB(t); \
add RE(t),RE(t),%r0;  rotlwi %r0,RA(t),5;      rotlwi RB(t),RB(t),30;   \
add RE(t),RE(t),W(s); add    %r0,%r0,%r5;      lwz    W(s),(s)*4(%r4);  \
add RE(t),RE(t),%r0

/*
 * This is likewise awkward, 13 instructions.  However, it can also
 * execute starting with 2 out of 3 possible moduli, so it does 2 rounds
 * in 9 cycles, 4.5 cycles/round.
 */
#define STEPD0_UPDATE(t,s,loadk...) \
add RE(t),RE(t),W(t); andc   %r0,RD(t),RB(t); xor    W(s),W((s)-16),W((s)-3); \
add RE(t),RE(t),%r0;  and    %r0,RC(t),RB(t); xor    W(s),W(s),W((s)-8);      \
add RE(t),RE(t),%r0;  rotlwi %r0,RA(t),5;     xor    W(s),W(s),W((s)-14);     \
add RE(t),RE(t),%r5;  loadk; rotlwi RB(t),RB(t),30;  rotlwi W(s),W(s),1;     \
add RE(t),RE(t),%r0

/* Nicely optimal.  Conveniently, also the most common. */
#define STEPD1_UPDATE(t,s,loadk...) \
add RE(t),RE(t),W(t); xor    %r0,RD(t),RB(t); xor    W(s),W((s)-16),W((s)-3); \
add RE(t),RE(t),%r5;  loadk; xor %r0,%r0,RC(t);  xor W(s),W(s),W((s)-8);      \
add RE(t),RE(t),%r0;  rotlwi %r0,RA(t),5;     xor    W(s),W(s),W((s)-14);     \
add RE(t),RE(t),%r0;  rotlwi RB(t),RB(t),30;  rotlwi W(s),W(s),1

/*
 * The naked version, no UPDATE, for the last 4 rounds.  3 cycles per.
 * We could use W(s) as a temp register, but we don't need it.
 */
#define STEPD1(t) \
                        add   RE(t),RE(t),W(t); xor    %r0,RD(t),RB(t); \
rotlwi RB(t),RB(t),30;  add   RE(t),RE(t),%r5;  xor    %r0,%r0,RC(t);   \
add    RE(t),RE(t),%r0; rotlwi %r0,RA(t),5;     /* spare slot */        \
add    RE(t),RE(t),%r0

/*
 * 14 instructions, 5 cycles per.  The majority function is a bit
 * awkward to compute.  This can execute with a 1-instruction delay,
 * but it causes a 2-instruction delay, which triggers a stall.
 */
#define STEPD2_UPDATE(t,s,loadk...) \
add RE(t),RE(t),W(t); and    %r0,RD(t),RB(t); xor    W(s),W((s)-16),W((s)-3); \
add RE(t),RE(t),%r0;  xor    %r0,RD(t),RB(t); xor    W(s),W(s),W((s)-8);      \
add RE(t),RE(t),%r5;  loadk; and %r0,%r0,RC(t);  xor W(s),W(s),W((s)-14);     \
add RE(t),RE(t),%r0;  rotlwi %r0,RA(t),5;     rotlwi W(s),W(s),1;             \
add RE(t),RE(t),%r0;  rotlwi RB(t),RB(t),30

#define STEP0_LOAD4(t,s)		\
	STEPD0_LOAD(t,s);		\
	STEPD0_LOAD((t+1),(s)+1);	\
	STEPD0_LOAD((t)+2,(s)+2);	\
	STEPD0_LOAD((t)+3,(s)+3)

#define STEPUP4(fn, t, s, loadk...)		\
	STEP##fn##_UPDATE(t,s,);		\
	STEP##fn##_UPDATE((t)+1,(s)+1,);	\
	STEP##fn##_UPDATE((t)+2,(s)+2,);	\
	STEP##fn##_UPDATE((t)+3,(s)+3,loadk)

#define STEPUP20(fn, t, s, loadk...)	\
	STEPUP4(fn, t, s,);		\
	STEPUP4(fn, (t)+4, (s)+4,);	\
	STEPUP4(fn, (t)+8, (s)+8,);	\
	STEPUP4(fn, (t)+12, (s)+12,);	\
	STEPUP4(fn, (t)+16, (s)+16, loadk)

	.globl	sha1_core
sha1_core:
	stwu	%r1,-80(%r1)
	stmw	%r13,4(%r1)

	/* Load up A - E */
	lmw	%r27,0(%r3)

	mtctr	%r5

1:
	LOADW(0)
	lis	%r5,0x5a82
	mr	RE(0),%r31
	LOADW(1)
	mr	RD(0),%r30
	mr	RC(0),%r29
	LOADW(2)
	ori	%r5,%r5,0x7999	/* K0-19 */
	mr	RB(0),%r28
	LOADW(3)
	mr	RA(0),%r27

	STEP0_LOAD4(0, 4)
	STEP0_LOAD4(4, 8)
	STEP0_LOAD4(8, 12)
	STEPUP4(D0, 12, 16,)
	STEPUP4(D0, 16, 20, lis %r5,0x6ed9)

	ori	%r5,%r5,0xeba1	/* K20-39 */
	STEPUP20(D1, 20, 24, lis %r5,0x8f1b)

	ori	%r5,%r5,0xbcdc	/* K40-59 */
	STEPUP20(D2, 40, 44, lis %r5,0xca62)

	ori	%r5,%r5,0xc1d6	/* K60-79 */
	STEPUP4(D1, 60, 64,)
	STEPUP4(D1, 64, 68,)
	STEPUP4(D1, 68, 72,)
	STEPUP4(D1, 72, 76,)
	addi	%r4,%r4,64
	STEPD1(76)
	STEPD1(77)
	STEPD1(78)
	STEPD1(79)

	/* Add results to original values */
	add	%r31,%r31,RE(0)
	add	%r30,%r30,RD(0)
	add	%r29,%r29,RC(0)
	add	%r28,%r28,RB(0)
	add	%r27,%r27,RA(0)

	bdnz	1b

	/* Save final hash, restore registers, and return */
	stmw	%r27,0(%r3)
	lmw	%r13,4(%r1)
	addi	%r1,%r1,80
	blr

^ permalink raw reply

* Re: Problem for "insmod: unresolved symbol printk"
From: Zhou Rui @ 2006-06-23  3:43 UTC (permalink / raw)
  To: Olof Johansson; +Cc: linuxppc-dev
In-Reply-To: <20060622174810.GA16973@pb15.lixom.net>

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

Hi,
    My host machine kernel was 2.4.28 and the PowerPC board was 2.4.25-rthal5. I followed  the Standard Makefile for 2.4(<=) kernels on the page http://kernelnewbies.org/FAQ/LinuxKernelModuleCompile?highlight=%28insmod%29, and do some changes based on my situation:

TARGET := hello
INCLUDE := -I/lib/modules/2.4.25-rthal5/build/include
CFLAGS := -O2 -Wall -DMODULE -D__KERNEL__ -DLINUX
CC := powerpc-linux-gcc

${TARGET}.o: ${TARGET}.c
        $(CC) $(CFLAGS) ${INCLUDE} -c ${TARGET}.c

The problem is still "insmod: unresolved symbol printk". But when I logged in the PowerPC board, and # fgrep 'printk' /proc/ksyms, there was "c0015500 printk_Rdd132261".



Olof Johansson <olof@lixom.net> : On Thu, Jun 22, 2006 at 10:31:56PM +0800, Zhou Rui wrote:
> Hi, all
>     I'm a newbie for linuxppc. I've tried to write a simple hello.c as a kernel module.

Hi,

http://kernelnewbies.org/  should have information on kernel module
basics, and where to find help if you still have problems.


-Olof



Zhou Rui
Distributed & Embedded System Lab
School of Information Science & Engineering
Lanzhou University, P. R. China
http://dslab.lzu.edu.cn/~zr/
 		
---------------------------------
 Mp3疯狂搜-新歌热歌高速下   

[-- Attachment #2: Type: text/html, Size: 1697 bytes --]

^ permalink raw reply

* Re: Fixed PPC SHA1
From: linux @ 2006-06-23  0:54 UTC (permalink / raw)
  To: git, linuxppc-dev; +Cc: linux
In-Reply-To: <20060623000908.9370.qmail@science.horizon.com>

Here's the lwsi-based version that's slightly faster on a G5, but slightly
slower on a G4.

/*
 * SHA-1 implementation for PowerPC.
 *
 * Copyright (C) 2005 Paul Mackerras <paulus@samba.org>
 */

/*
 * PowerPC calling convention:
 * %r0 - volatile temp
 * %r1 - stack pointer.
 * %r2 - reserved
 * %r3-%r12 - Incoming arguments & return values; volatile.
 * %r13-%r31 - Callee-save registers
 * %lr - Return address, volatile
 * %ctr - volatile
 *
 * Register usage in this routine:
 * %r0 - temp
 * %r3 - argument (pointer to 5 words of SHA state)
 * %r4 - argument (pointer to data to hash)
 * %r5-%r20 - Data being hashed W[]. (%r5 is initially count of blocks)
 * %r21 - Contant K in SHA round
 * %r22-%r26 - Working copies of SHA variables A..E (actually E..A order) 
 * %r27-%r31 - Previous copies of A..E, for final add back.
 * %ctr - loop count (copied from %r5 argument)
 *
 * It's also worth mentioning that PPC assembly accept a bare
 * number as a register specifier; the "%r" prefix is actually optional.
 * And that number cna be an expression!  That simplifies the
 * loop unrolling significantly.
 */

/*
 * We roll the registers for A, B, C, D, E around on each
 * iteration; E on iteration t is D on iteration t+1, and so on.
 * We use registers 22 - 26 for this.  (Registers 27 - 31 hold
 * the previous values.)
 */
#define RA(t)	(((t)+4)%5+22)
#define RB(t)	(((t)+3)%5+22)
#define RC(t)	(((t)+2)%5+22)
#define RD(t)	(((t)+1)%5+22)
#define RE(t)	(((t)+0)%5+22)

/* Register 21 is used for the constant k */

/* We use registers 5 - 20 for the W values */
#define W(t)	((t)%16+5)

/*
 * The basic SHA-1 round function is:
 * E += ROTL(A,5) + F(B,C,D) + W[i] + K;  B = ROTL(B,30)
 * Then the variables are renamed: (A,B,C,D,E) = (E,A,B,C,D).
 *
 * Every 20 rounds, the function F() and the contant K changes:
 * - 20 rounds of f0(b,c,d) = "bit wise b ? c : d" =  (^b & d) + (b & c)
 * - 20 rounds of f1(b,c,d) = b^c^d = (b^d)^c
 * - 20 rounds of f2(b,c,d) = majority(b,c,d) = (b&d) + ((b^d)&c)
 * - 20 more rounds of f1(b,c,d)
 *
 * These are all scheduled for near-optimal performance on a G4.
 * The G4 is a 3-issue out-of-order machine with 3 ALUs, but it can only
 * *consider* starting the oldest 3 instructions per cycle.  So to get
 * maximum performace out of it, you have to treat it as an in-order
 * machine.  Which means interleaving the computation round t with the
 * computation of W[t+4].
 *
 * The first 16 rounds use W values loaded directly from memory, while the
 * remianing 64 use values computed from those first 16.  We preload
 * 4 values before starting, so there are three kinds of rounds:
 * - The first 12 (all f0) also load the W values from memory.
 * - The next 64 compute W(i+4) in parallel. 8*f0, 20*f1, 20*f2, 16*f1.
 * - The last 4 (all f1) do not do anything with W.
 *
 * Therefore, we have 5 different round functions:
 * STEPD0(t,s) - Perform round t
 * STEPD0_UPDATE(t,s) - Perform round t and compute W(s).  s >= 16.
 * STEPD1_UPDATE(t,s)
 * STEPD2_UPDATE(t,s)
 * STEPD1(t) - Perform round t with no load or update.
 *
 * There's also provision for inserting an instruction to start loading
 * the new K value after it's last used in the given step.
 * 
 * The G5 is more fully out-of-order, and can find the parallelism
 * by itself.  The big limit is that it has a 2-cycle ALU latency, so
 * even though it's 2-way, the code has to be scheduled as if it's
 * 4-way, which can be a limit.  To help it, we try to schedule the
 * read of RA(t) as late as possible so it doesn't stall waiting for
 * the previous round's RE(t-1), and we try to rotate RB(t) as early
 * as possible while reading RC(t) (= RB(t-1)) as late as possible.
 */

/*
 * Okay, we need a naked version of STEPD0.  It's 9 instructions.
 * Can that be done in 3 cycles, WITHOUT using W(s) as a temp?
 * NO.  So we need W(s) as a temp.  That can be arranged with some
 * clever scheduling.
 */
#define STEPD0(t,s) \
/* spare slot */      add RE(t),RE(t),W(t); andc   %r0,RD(t),RB(t); \
add RE(t),RE(t),%r0;  and W(s),RC(t),RB(t); rotlwi %r0,RA(t),5;     \
add RE(t),RE(t),W(s); add %r0,%r0,%r21;     rotlwi RB(t),RB(t),30;  \
add RE(t),RE(t),%r0;

/*
 * This can execute starting with 2 out of 3 possible moduli, so it
 * does 2 rounds in 9 cycles, 4.5 cycles/round.
 */
#define STEPD0_UPDATE(t,s,loadk...) \
add RE(t),RE(t),W(t); andc   %r0,RD(t),RB(t); xor    W(s),W((s)-16),W((s)-3); \
add RE(t),RE(t),%r0;  and    %r0,RC(t),RB(t); xor    W(s),W(s),W((s)-8);      \
add RE(t),RE(t),%r0;  rotlwi %r0,RA(t),5;     xor    W(s),W(s),W((s)-14);     \
add RE(t),RE(t),%r21; loadk; rotlwi RB(t),RB(t),30;  rotlwi W(s),W(s),1;     \
add RE(t),RE(t),%r0

/* Nicely optimal.  Conveniently, also the most common. */
#define STEPD1_UPDATE(t,s,loadk...) \
add RE(t),RE(t),W(t); xor    %r0,RD(t),RB(t); xor    W(s),W((s)-16),W((s)-3); \
add RE(t),RE(t),%r21; loadk; xor %r0,%r0,RC(t);  xor W(s),W(s),W((s)-8);      \
add RE(t),RE(t),%r0;  rotlwi %r0,RA(t),5;     xor    W(s),W(s),W((s)-14);     \
add RE(t),RE(t),%r0;  rotlwi RB(t),RB(t),30;  rotlwi W(s),W(s),1

/*
 * The naked version, no UPDATE, for the last 4 rounds.  3 cycles per.
 * We could use W(s) as a temp register, but we don't need it.
 */
#define STEPD1(t) \
                      add   RE(t),RE(t),W(t); xor    %r0,RD(t),RB(t); \
add RE(t),RE(t),%r21; xor    %r0,%r0,RC(t);   rotlwi RB(t),RB(t),30;  \
add RE(t),RE(t),%r0;  rotlwi %r0,RA(t),5;     /* spare slot */        \
add RE(t),RE(t),%r0

/* 5 cycles per */
#define STEPD2_UPDATE(t,s,loadk...) \
add RE(t),RE(t),W(t); and    %r0,RD(t),RB(t); xor    W(s),W((s)-16),W((s)-3); \
add RE(t),RE(t),%r0;  xor    %r0,RD(t),RB(t); xor    W(s),W(s),W((s)-8);      \
add RE(t),RE(t),%r21; loadk; and %r0,%r0,RC(t);  xor W(s),W(s),W((s)-14);     \
add RE(t),RE(t),%r0;  rotlwi %r0,RA(t),5;     rotlwi W(s),W(s),1;             \
add RE(t),RE(t),%r0;  rotlwi RB(t),RB(t),30

#define STEP0_LOAD4(t,s)		\
	STEPD0_LOAD(t,s);		\
	STEPD0_LOAD((t+1),(s)+1);	\
	STEPD0_LOAD((t)+2,(s)+2);	\
	STEPD0_LOAD((t)+3,(s)+3);

#define STEP0_4(t,s)		\
	STEPD0(t,s);		\
	STEPD0((t+1),(s)+1);	\
	STEPD0((t)+2,(s)+2);	\
	STEPD0((t)+3,(s)+3);

#define STEP1_4(t)		\
	STEPD1(t);		\
	STEPD1((t+1));		\
	STEPD1((t)+2);		\
	STEPD1((t)+3);

#define STEPUP4(fn, t, s, loadk...)		\
	STEP##fn##_UPDATE(t,s,);		\
	STEP##fn##_UPDATE((t)+1,(s)+1,);	\
	STEP##fn##_UPDATE((t)+2,(s)+2,);	\
	STEP##fn##_UPDATE((t)+3,(s)+3,loadk)

#define STEPUP20(fn, t, s, loadk...)	\
	STEPUP4(fn, t, s,);		\
	STEPUP4(fn, (t)+4, (s)+4,);	\
	STEPUP4(fn, (t)+8, (s)+8,);	\
	STEPUP4(fn, (t)+12, (s)+12,);	\
	STEPUP4(fn, (t)+16, (s)+16, loadk)

	.globl	sha1_core
sha1_core:
	stwu	%r1,-80(%r1)
	stmw	%r13,4(%r1)

	/* Load up A - E */
	lmw	%r27,0(%r3)

	mtctr	%r5

1:
	lswi	W(0),%r4,32
	lis	%r21,0x5a82
	addi	%r4,%r4,32
	mr	RE(0),%r31
	mr	RD(0),%r30
	mr	RC(0),%r29
	ori	%r21,%r21,0x7999	/* K0-19 */
	mr	RB(0),%r28
	mr	RA(0),%r27

	STEP0_4(0, 8)
	STEP0_4(4, 12)
	lswi	W(8),%r4,32
	STEPUP4(D0, 8, 16,)
	STEPUP4(D0, 12, 20,)
	STEPUP4(D0, 16, 24, lis %r21,0x6ed9)

	ori	%r21,%r21,0xeba1	/* K20-39 */
	STEPUP20(D1, 20, 28, lis %r21,0x8f1b)

	ori	%r21,%r21,0xbcdc	/* K40-59 */
	STEPUP20(D2, 40, 48, lis %r21,0xca62)

	ori	%r21,%r21,0xc1d6	/* K60-79 */
	STEPUP4(D1, 60, 68,)
	STEPUP4(D1, 64, 72,)
	STEPUP4(D1, 68, 76,)
	addi	%r4,%r4,32
	STEP1_4(72);
	STEP1_4(76);

	/* Add results to original values */
	add	%r31,%r31,RE(0)
	add	%r30,%r30,RD(0)
	add	%r29,%r29,RC(0)
	add	%r28,%r28,RB(0)
	add	%r27,%r27,RA(0)

	bdnz	1b

	/* Save final hash, restore registers, and return */
	stmw	%r27,0(%r3)
	lmw	%r13,4(%r1)
	addi	%r1,%r1,80
	blr

^ permalink raw reply

* Q about i2c controller on mpc8245
From: Reeve Yang @ 2006-06-23  1:06 UTC (permalink / raw)
  To: linuxppc-dev

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

Hello,

I'm new to this list and wish to get help from it since I'm currently
developing a switch box based on mpc8245, the kernel I'm using is 2.6.14.

Now I'm trying to bring up the I2C controller then I2C devices. Is fsl-i2c
the driver for I2C controller of MPC8245? I enabled that driver and it was
installed, but there is no any device found. Why is it like that? Following
are the dump from sysfs.

/ # systool -b platform -d
Bus = "platform"

  Device = "serial8250"
  Device = "serial8250.0"
  Device = "serial8250.1"

/ # systool -b platform -D
Bus = "platform"

  Driver = "fsl-i2c"

  Driver = "serial8250"
    Devices using "serial8250" are:
      Device = "serial8250"

      Device = "serial8250.0"

      Device = "serial8250.1"

In the booting sequence, I got following error message:

PCI: Probing PCI hardware
PCI: Cannot allocate resource region 1 of device 0000:00:00.0
fsl-i2c.1: failed to claim resource 0
unable to register device 0
fsl-dma.0: failed to claim resource 0
unable to register device 1
fsl-dma.1: failed to claim resource 0
unable to register device 2

Does this error make device undetected? What might be the reason for above
errors? I'd appreciate if you could shed some lights.

Regards,

- Reeve

[-- Attachment #2: Type: text/html, Size: 1630 bytes --]

^ permalink raw reply

* Re: [PATCH 0/3] powerpc: Instrument Hypervisor Calls
From: Segher Boessenkool @ 2006-06-23  0:28 UTC (permalink / raw)
  To: Mike Kravetz
  Cc: Bryan Rosenburg, linuxppc-dev, Nathan Lynch, Arnd Bergmann,
	Christopher Yeoh
In-Reply-To: <20060622225609.GA4877@w-mikek2.ibm.com>

> Statistic files are moved to debugfs, and remain split out by CPU.

Having done some if this myself long ago, I really like to see these
per-cpu statistics.  "Not useful" in real life, but for most testcases
they're invaluable.  It would be useful to also add a "total" column
as well, of course, but it can also be done in userland.


Segher

^ permalink raw reply

* Re: [PATCH] Use IRQ and senses from OF-tree on 8641hpcn.
From: Benjamin Herrenschmidt @ 2006-06-23  0:11 UTC (permalink / raw)
  To: Jon Loeliger; +Cc: linuxppc-dev@ozlabs.org
In-Reply-To: <1150999473.9022.79.camel@cashmere.sps.mot.com>


> -static void __devinit quirk_ali1575(struct pci_dev *dev)
> +static int __init get_pci_irq_from_of(struct pci_controller *hose,
> +				   int slot, int pin)
> +{
> +	struct device_node *node;
> +	unsigned long *interrupt, *interrupt_mask;
> +	int len, mask_len;
> +	int shift, i;
> +	int irq = 0;
> +
> +	if (!hose) {
> +		printk(KERN_ERR "No PCI hose found!\n");
> +		return -EFAULT;
> +	}
> +
> +	node = (struct device_node *)hose->arch_data;
> +	interrupt = (unsigned long *)get_property(node,
> +			"interrupt-map", &len);
> +	interrupt_mask = (unsigned long *)get_property(node,
> +			"interrupt-map-mask", &mask_len);
> +	if (!interrupt || !interrupt_mask) {
> +		printk(KERN_ERR "No PCI interrupt-map or interrupt-map-mask"
> +				"property in OpenFirmware device tree!\n");
> +		return -EFAULT;
> +	}
> +	shift = __ilog2((~interrupt_mask[0] + 1) & 0xffff);

Nice hack :)

But not something mergeable as it strictly relies on the specific format
of the interrupt map on that platform :) I have a generic parser on the
way, it's hot and will be released for public consumption later today or
this week-end along with the rest of the irq patches.

I'll need you guys to help porting the few embedded boards already in
arch/powerpc.

Ben.

> +	/*
> +	 * Find matched irq in interrupt-map node of OF-tree.
> +	 *
> +	 * interrupt-map entries format:
> +	 * <slot>     <pin> <interrupt-parent> <irq#>
> +	 *  8800  0 0   1         40000           3   0
> +	 */
> +	pr_debug("PCI slot %x, pin %d ", slot, pin);
> +	for (i = 0; i < (len / 7); i++)
> +		if (((interrupt[i * 7] & interrupt_mask[0]) == (slot << shift))
> +				&& (interrupt[i * 7 + 3] == pin))
> +			irq = interrupt[i * 7 + 5] & interrupt_mask[3];
> +	pr_debug("irq %d\n", irq);
> +
> +	if (!irq)
> +		printk(KERN_WARNING "PCI Slot %d, Pin %d device "
> +				"has no matched irq!\n", slot, pin);
> +
> +	return irq;
> +}
> +
> +static int __init mpc86xx_irq_fixup(struct pci_dev *dev)
> +{
> +	struct pci_controller *hose = NULL;
> +	int pin, slot;
> +
> +	hose = pci_bus_to_hose(dev->bus->number);
> +	if (!hose) {
> +		printk(KERN_ERR "No PCI hose found!\n");
> +		return -EFAULT;
> +	}
> +
> +	pin = dev->pin;
> +	if (dev->bus->number != hose->first_busno) {
> +		do {
> +			pin = ((pin-1) + PCI_SLOT(dev->devfn)) %4 + 1;
> +			/* Move up the chain of bridges. */
> +			dev = dev->bus->self;
> +		} while (dev->bus->self);
> +		/* The slot is the idsel of the last bridge. */
> +	}
> +	slot = PCI_SLOT(dev->devfn);
> +
> +	return get_pci_irq_from_of(hose, slot, pin);
> +}
> +
> +void __init mpc86xx_pcibios_fixup(void)
> +{
> +	struct pci_dev *dev = NULL;
> +
> +	for_each_pci_dev(dev) {
> +		dev->irq = mpc86xx_irq_fixup(dev);
> +		if (dev->irq < 0)
> +			return;
> +		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
> +	}
> +}
> +
> +enum pirq{PIRQA = 8, PIRQB, PIRQC, PIRQD, PIRQE, PIRQF, PIRQG, PIRQH};
> +const unsigned char uli1575_irq_route_table[16] = {
> +	0, 	/* 0: Reserved */
> +	0x8, 	/* 1: 0b1000 */
> +	0, 	/* 2: Reserved */
> +	0x2,	/* 3: 0b0010 */
> +	0x4,	/* 4: 0b0100 */
> +	0x5, 	/* 5: 0b0101 */
> +	0x7,	/* 6: 0b0111 */
> +	0x6,	/* 7: 0b0110 */
> +	0, 	/* 8: Reserved */
> +	0x1,	/* 9: 0b0001 */
> +	0x3,	/* 10: 0b0011 */
> +	0x9,	/* 11: 0b1001 */
> +	0xb,	/* 12: 0b1011 */
> +	0, 	/* 13: Reserved */
> +	0xd,	/* 14, 0b1101 */
> +	0xf,	/* 15, 0b1111 */
> +};
> +
> +
> +static void __devinit quirk_uli1575(struct pci_dev *dev)
>  {
>  	unsigned short temp;
> +	struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);
> +	int i, irq;
> +	unsigned char irq2pin[16];
> +	unsigned long pirq_map_word = 0;
> +
> +	if (!hose) {
> +		printk(KERN_ERR "No PCI hose!\n");
> +		return;
> +	}
>  
>  	/*
> -	 * ALI1575 interrupts route table setup:
> +	 * ULI1575 interrupts route setup
> +	 */
> +	memset(irq2pin, 0, 16); /* Initialize default value 0 */
> +
> +	/*
> +	 * PIRQA -> PIRQD mapping read from OF-tree
> +	 *
> +	 * interrupts for PCI slot0 -- PIRQA / PIRQB / PIRQC / PIRQD
> +	 *                PCI slot1 -- PIRQB / PIRQC / PIRQD / PIRQA
> +	 */
> +	for (i = 0; i < 4; i++){
> +		irq = get_pci_irq_from_of(hose, 17, i + 1);
> +		if (irq >= 0 && irq <= 15)
> +			irq2pin[irq] = PIRQA + i;
> +	}
> +
> +	/*
> +	 * PIRQE -> PIRQF mapping set manually
>  	 *
>  	 * IRQ pin   IRQ#
> -	 * PIRQA ---- 3
> -	 * PIRQB ---- 4
> -	 * PIRQC ---- 5
> -	 * PIRQD ---- 6
>  	 * PIRQE ---- 9
>  	 * PIRQF ---- 10
>  	 * PIRQG ---- 11
>  	 * PIRQH ---- 12
> -	 *
> -	 * interrupts for PCI slot0 -- PIRQA / PIRQB / PIRQC / PIRQD
> -	 *                PCI slot1 -- PIRQB / PIRQC / PIRQD / PIRQA
>  	 */
> -	pci_write_config_dword(dev, 0x48, 0xb9317542);
> +	for (i = 0; i < 4; i++) irq2pin[i + 9] = PIRQE + i;
>  
> -	/* USB 1.1 OHCI controller 1, interrupt: PIRQE */
> -	pci_write_config_byte(dev, 0x86, 0x0c);
> +	/* Set IRQ-PIRQ Mapping to ULI1575 */
> +	for (i = 0; i < 16; i++)
> +		if (irq2pin[i])
> +			pirq_map_word |= (uli1575_irq_route_table[i] & 0xf)
> +				<< ((irq2pin[i] - PIRQA) * 4);
>  
> -	/* USB 1.1 OHCI controller 2, interrupt: PIRQF */
> -	pci_write_config_byte(dev, 0x87, 0x0d);
> +	DBG("Setup ULI1575 IRQ mapping configuration register value = 0x%x\n",
> +			pirq_map_word);
> +	pci_write_config_dword(dev, 0x48, pirq_map_word);
>  
> -	/* USB 1.1 OHCI controller 3, interrupt: PIRQH */
> -	pci_write_config_byte(dev, 0x88, 0x0f);
> +#define ULI1575_SET_DEV_IRQ(slot, pin, reg) 				\
> +	do { 								\
> +		int irq; 						\
> +		irq = get_pci_irq_from_of(hose, slot, pin); 		\
> +		if (irq >= 0 && irq <=15) 				\
> +			pci_write_config_byte(dev, reg, irq2pin[irq]); 	\
> +	} while(0)
>  
> -	/* USB 2.0 controller, interrupt: PIRQ7 */
> -	pci_write_config_byte(dev, 0x74, 0x06);
> +	/* USB 1.1 OHCI controller 1, slot 28, pin 1 */
> +	ULI1575_SET_DEV_IRQ(28, 1, 0x86);
>  
> -	/* Audio controller, interrupt: PIRQE */
> -	pci_write_config_byte(dev, 0x8a, 0x0c);
> +	/* USB 1.1 OHCI controller 2, slot 28, pin 2 */
> +	ULI1575_SET_DEV_IRQ(28, 2, 0x87);
>  
> -	/* Modem controller, interrupt: PIRQF */
> -	pci_write_config_byte(dev, 0x8b, 0x0d);
> +	/* USB 1.1 OHCI controller 3, slot 28, pin 3 */
> +	ULI1575_SET_DEV_IRQ(28, 3, 0x88);
>  
> -	/* HD audio controller, interrupt: PIRQG */
> -	pci_write_config_byte(dev, 0x8c, 0x0e);
> +	/* USB 2.0 controller, slot 28, pin 4 */
> +	irq = get_pci_irq_from_of(hose, 28, 4);
> +	if (irq >= 0 && irq <=15)
> +		pci_write_config_dword(dev, 0x74, uli1575_irq_route_table[irq]);
>  
> -	/* Serial ATA interrupt: PIRQD */
> -	pci_write_config_byte(dev, 0x8d, 0x0b);
> +	/* Audio controller, slot 29, pin 1 */
> +	ULI1575_SET_DEV_IRQ(29, 1, 0x8a);
>  
> -	/* SMB interrupt: PIRQH */
> -	pci_write_config_byte(dev, 0x8e, 0x0f);
> +	/* Modem controller, slot 29, pin 2 */
> +	ULI1575_SET_DEV_IRQ(29, 2, 0x8b);
>  
> -	/* PMU ACPI SCI interrupt: PIRQH */
> -	pci_write_config_byte(dev, 0x8f, 0x0f);
> +	/* HD audio controller, slot 29, pin 3 */
> +	ULI1575_SET_DEV_IRQ(29, 3, 0x8c);
> +
> +	/* SMB interrupt: slot 30, pin 1 */
> +	ULI1575_SET_DEV_IRQ(30, 1, 0x8e);
> +
> +	/* PMU ACPI SCI interrupt: slot 30, pin 2 */
> +	ULI1575_SET_DEV_IRQ(30, 2, 0x8f);
> +
> +	/* Serial ATA interrupt: slot 31, pin 1 */
> +	ULI1575_SET_DEV_IRQ(31, 1, 0x8d);
>  
>  	/* Primary PATA IDE IRQ: 14
>  	 * Secondary PATA IDE IRQ: 15
>  	 */
> -	pci_write_config_byte(dev, 0x44, 0x3d);
> -	pci_write_config_byte(dev, 0x75, 0x0f);
> +	pci_write_config_byte(dev, 0x44, 0x30 | uli1575_irq_route_table[14]);
> +	pci_write_config_byte(dev, 0x75, uli1575_irq_route_table[15]);
>  
>  	/* Set IRQ14 and IRQ15 to legacy IRQs */
>  	pci_read_config_word(dev, 0x46, &temp);
> @@ -277,6 +421,8 @@ static void __devinit quirk_ali1575(stru
>  	 */
>  	outb(0xfa, 0x4d0);
>  	outb(0x1e, 0x4d1);
> +
> +#undef ULI1575_SET_DEV_IRQ
>  }
>  
>  static void __devinit quirk_uli5288(struct pci_dev *dev)
> @@ -319,7 +465,7 @@ static void __devinit early_uli5249(stru
>  	dev->class |= 0x1;
>  }
>  
> -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, quirk_ali1575);
> +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, quirk_uli1575);
>  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5288, quirk_uli5288);
>  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5229, quirk_uli5229);
>  DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AL, 0x5249, early_uli5249);

^ permalink raw reply

* [PATCH 3/3] powerpc: Instrument Hypervisor Calls: add debugfs files
From: Mike Kravetz @ 2006-06-22 23:00 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: Bryan Rosenburg, Christopher Yeoh, Nathan Lynch, Arnd Bergmann
In-Reply-To: <20060622225609.GA4877@w-mikek2.ibm.com>

Make statistics available via files in debugfs.

--
Signed-off-by: Mike Kravetz <kravetz@us.ibm.com>

diff -Naupr linux-2.6.17.1/arch/powerpc/platforms/pseries/hvCall_inst.c linux-2.6.17.1.work/arch/powerpc/platforms/pseries/hvCall_inst.c
--- linux-2.6.17.1/arch/powerpc/platforms/pseries/hvCall_inst.c	2006-06-22 23:02:50.000000000 +0000
+++ linux-2.6.17.1.work/arch/powerpc/platforms/pseries/hvCall_inst.c	2006-06-22 23:03:55.000000000 +0000
@@ -217,3 +217,94 @@ long plpar_hcall_9arg_9ret(unsigned long
 	preempt_enable();
 	return rc;
 }
+
+/*
+ * Routines for displaying the statistics in debugfs
+ */
+static void *hc_start(struct seq_file *m, loff_t *pos)
+{
+	if ((int)*pos < MAX_HCALL_OPCODES)
+		return (void *)(unsigned long)(*pos + 1);
+
+	return NULL;
+}
+
+static void *hc_next(struct seq_file *m, void *p, loff_t * pos)
+{
+	++*pos;
+
+	return hc_start(m, pos);
+}
+
+static void hc_stop(struct seq_file *m, void *p)
+{
+}
+
+static int hc_show(struct seq_file *m, void *p)
+{
+	unsigned long h_num = (unsigned long)p;
+	struct hcall_stats *hs = (struct hcall_stats *)m->private;
+
+	if (hs[h_num].num_calls)
+		seq_printf(m, "%lu %lu %lu\n", h_num<<2, hs[h_num].num_calls,
+			   hs[h_num].total_time);
+
+	return 0;
+}
+
+static struct seq_operations hcall_inst_seq_ops = {
+        .start = hc_start,
+        .next  = hc_next,
+        .stop  = hc_stop,
+        .show  = hc_show
+};
+
+static int hcall_inst_seq_open(struct inode *inode, struct file *file)
+{
+	int rc;
+	struct seq_file *seq;
+
+	rc = seq_open(file, &hcall_inst_seq_ops);
+	seq = file->private_data;
+	seq->private = file->f_dentry->d_inode->u.generic_ip;
+
+	return rc;
+}
+
+static struct file_operations hcall_inst_seq_fops = {
+	.open = hcall_inst_seq_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = seq_release,
+};
+
+#define	HCALL_ROOT_DIR		"hcall_inst"
+#define CPU_NAME_BUF_SIZE	32
+
+static int __init hcall_inst_init(void)
+{
+	struct dentry *hcall_root;
+	struct dentry *hcall_file;
+	char cpu_name_buf[CPU_NAME_BUF_SIZE];
+	int cpu;
+
+	if (!firmware_has_feature(FW_FEATURE_LPAR))
+		return 0;
+
+	hcall_root = debugfs_create_dir(HCALL_ROOT_DIR, NULL);
+	if (!hcall_root)
+		return -ENOMEM;
+
+	for_each_cpu(cpu) {
+		snprintf(cpu_name_buf, CPU_NAME_BUF_SIZE, "cpu%d", cpu);
+		hcall_file = debugfs_create_file(cpu_name_buf, S_IRUGO,
+						 hcall_root,
+						 per_cpu(hcall_stats, cpu),
+						 &hcall_inst_seq_fops);
+		if (!hcall_file)
+			return -ENOMEM;
+	}
+
+	return 0;
+}
+__initcall(hcall_inst_init);

^ permalink raw reply

* [PATCH 0/3] powerpc: Instrument Hypervisor Calls
From: Mike Kravetz @ 2006-06-22 22:56 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: Bryan Rosenburg, Christopher Yeoh, Nathan Lynch, Arnd Bergmann

Here is an updated version of the hcall instrumentation patches.
Unfortunately, I have not been able to spend as much time as I
would like on this (and it seems that will continue).  

This version addresses all comments received except Arnd's issue
with an #ifdef for each function in the assembly file.  I like
Jimi's suggestion for creating macros(which could also minimize
the #ifdefs), but have not got around to implementing this.
Suggestions of others way to accomplish this are welcome.

Statistic files are moved to debugfs, and remain split out by CPU.
After some thought, disable/enable of preemption was added around
the statistic gathering(mostly for timing).

-- 
Mike

^ 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