LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH 10/11] Add MPC8360EMDS board support
From: Benjamin Herrenschmidt @ 2006-10-04  5:52 UTC (permalink / raw)
  To: Dan Malek; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <CE624A83-809E-4180-800E-660A578FFCFC@embeddedalley.com>


> I still think an embedded_feature_call() support in a
> board port would be the best solution to many of these
> complex things we are trying to define in this device
> tree information.  In the places where we need some
> kind of board specific support, like hardware set up for
> some peripheral, just do the feature_call, passing enough
> information to indicate what is needed, and let the
> board support do what is necessary.  This could be
> setting bits in a BCSR, setting up the processor IO
> ports, enabling power to external logic, etc.  This has
> been proven to work well on the PMAC, just extend it
> to be used on embedded boards.

I don't see how a mecanism of feature call at the board support level is
in any way incompatible with the device-tree thing. I'm happy mixing
both on powermac :)

Ben.

^ permalink raw reply

* Re: [PATCH 10/11] Add MPC8360EMDS board support
From: Benjamin Herrenschmidt @ 2006-10-04  6:08 UTC (permalink / raw)
  To: Dan Malek; +Cc: Olof Johansson, linuxppc-dev, Paul Mackerras
In-Reply-To: <EBD0615C-4F22-430F-BD23-1283DF98F1B3@embeddedalley.com>


> Now, we have something that is way more complex than
> we initially thought was necessary, trying to describe nearly
> everything addressable in the system instead of just the
> internal memory map.  I suspect the software to attain
> (IMHO the useless) goal of a single binary for multiple
> boards will create exponentially complex software,
> something that highly reliable embedded systems
> are trying to avoid.

It's not that complex and the single binary is not necessarily the main
objective (it's a good practice as it enforce avoiding ugly #ifdef hacks
where not necessary, often not in performance critical code anyway).
There is fundamentally little difference between the OCP tables we had
before and the device-tree. In both cases, the choice was made to not
hard-code the device-infos in the drivers, not only because of the
possible booting-multiple-board stuff (which could have been acheived
with the OCP tables with simple tricks too), but also to make it easier
to have several instances of a given device (very common) etc...

The new device-tree model provides a more flexible and richer semantic
for adding all sort of driver or BSP private infos, and for dealing with
address mapping and interrupt mapping.

When done right, it does simplify the matter. An example that I've seen
internally is embedded boards with all sorts of variety of dodgy
interrupt controllers cascaded on each other. The interrupt tree
mecanism along with the new interrupt code in the powerpc architecture
makes it very easy to handle that, by completely separating the domain
number between the various controllers and using the device-tree to
express the relationship between the devices and interrupt controllers.

It simplifies the code, both on the driver and the platform side, and
keep the whole interrupt tree resresentation in one place: the
device-tree.

I agree that too complex trees are not a good idea, but so far, the
definition we provided for a minimum tree is fairly slim. You do not
-have- to put all your devices in there, but in many case, doing so
makes it simpler for your own code/driver to retreive informations such
as base addresses, interrupts (see above), and all sort of auxilliary
infos you may which to pass to a given driver (MAC address, serial
number, default clock, whatever).

There is a great flexibility of putting whatever you want in there... or
not. It's up to the embedded developper to use that tool, it can be used
in a bloated way, or in a smart way, we aren't enforcing any direction
here.

> What value does this provide to my client trying
> to create a cost effective wireless home networking
> device?  It certainly doesn't make the board port
> from hell any easier, since cramming the software
> into 4M of flash will likely cause the choice of a
> processor other than PowerPC that can configure
> a smaller kernel and use a tiny custom piece of
> boot code.  Highly configurable development/evaluation
> boards running a single binary aren't high volume
> products, and the additional resources required
> by such software could ensure real products aren't
> developed with PPCs.  We need to be sensitive
> to this.

I think you are a bit too dismissive here. The approach has always been
to provide the choice, and I've been fairly careful when designing the
flattened device tree format to keep it as compact as possible. Thus I
expect little overhead of using that mecanism to discover and
instanciate drivers and provide them with configuration informations. 

The value provided to your client, once we have fully sorted out the
matter (some things are still being ironed out and developped, for
example, I'm working on a more generic way to instanciate drivers for
devices probed from the device-tree outside of the well-known realm of
PCI) is hopefully an easier way to create the BSP in the first place, a
central and more maintainable location where what is on his board is
defined, the ability to more easily maintain multiple revisions of the
board, with very little overhead. For such a client, I wouldn't expect
him to build a heavily multi-board kernel nor use a massive bootloader,
and neither are made necessary. The -ability- to build multi-board
kernels is made mandatory for code to be merged upstream, as it enforces
a certain level of quality, but you don't have to actually do it on the
field. In fact, you client may be happy, once it's done rev 3 of the
board with a 3rd type of wifi chip or a 2nd type of ethernet HUB to have
the ability to easily build, maintain, distribute and test a single
kernel image, and just at install (or download) time slap the right
device-tree to form a zImage with embedded device-tree using paulus
latest tool.

Ben.

^ permalink raw reply

* [PATCH] Lazy interrupt disabling for 64-bit machines
From: Paul Mackerras @ 2006-10-04  6:47 UTC (permalink / raw)
  To: linuxppc-dev

This implements a lazy strategy for disabling interrupts.  This means
that local_irq_disable() et al. just clear the 'interrupts are
enabled' flag in the paca.  If an interrupt comes along, the interrupt
entry code notices that interrupts are supposed to be disabled, and
clears the EE bit in SRR1, clears the 'interrupts are hard-enabled'
flag in the paca, and returns.  This means that interrupts only
actually get disabled in the processor when an interrupt comes along.

When interrupts are enabled by local_irq_enable() et al., the code
sets the interrupts-enabled flag in the paca, and then checks whether
interrupts got hard-disabled.  If so, it also sets the EE bit in the
MSR to hard-enable the interrupts.

This has the potential to improve performance, and also makes it
easier to make a kernel that can boot on iSeries and on other 64-bit
machines, since this lazy-disable strategy is very similar to the
soft-disable strategy that iSeries already uses.

This version renames paca->proc_enabled to paca->soft_enabled, and
changes a couple of soft-disables in the kexec code to hard-disables,
which should fix the crash that Michael Ellerman saw.  This doesn't
yet use a reserved CR field for the soft_enabled and hard_enabled
flags.  This applies on top of Stephen Rothwell's patches to make it
possible to build a combined iSeries/other kernel.

Signed-off-by: Paul Mackerras <paulus@samba.org>
---
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index d06f378..e965215 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -118,7 +118,8 @@ #ifdef CONFIG_PPC64
 	DEFINE(PACASTABRR, offsetof(struct paca_struct, stab_rr));
 	DEFINE(PACAR1, offsetof(struct paca_struct, saved_r1));
 	DEFINE(PACATOC, offsetof(struct paca_struct, kernel_toc));
-	DEFINE(PACAPROCENABLED, offsetof(struct paca_struct, proc_enabled));
+	DEFINE(PACASOFTIRQEN, offsetof(struct paca_struct, soft_enabled));
+	DEFINE(PACAHARDIRQEN, offsetof(struct paca_struct, hard_enabled));
 	DEFINE(PACASLBCACHE, offsetof(struct paca_struct, slb_cache));
 	DEFINE(PACASLBCACHEPTR, offsetof(struct paca_struct, slb_cache_ptr));
 	DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id));
diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c
index 1af41f7..89b03c8 100644
--- a/arch/powerpc/kernel/crash.c
+++ b/arch/powerpc/kernel/crash.c
@@ -111,7 +111,7 @@ void crash_ipi_callback(struct pt_regs *
 	if (!cpu_online(cpu))
 		return;
 
-	local_irq_disable();
+	hard_irq_disable();
 	if (!cpu_isset(cpu, cpus_in_crash))
 		crash_save_this_cpu(regs, cpu);
 	cpu_set(cpu, cpus_in_crash);
@@ -289,7 +289,7 @@ void default_machine_crash_shutdown(stru
 	 * an SMP system.
 	 * The kernel is broken so disable interrupts.
 	 */
-	local_irq_disable();
+	hard_irq_disable();
 
 	for_each_irq(irq) {
 		struct irq_desc *desc = irq_desc + irq;
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 748e74f..efda487 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -87,6 +87,10 @@ system_call_common:
 	addi	r9,r1,STACK_FRAME_OVERHEAD
 	ld	r11,exception_marker@toc(r2)
 	std	r11,-16(r9)		/* "regshere" marker */
+	li	r10,1
+	stb	r10,PACASOFTIRQEN(r13)
+	stb	r10,PACAHARDIRQEN(r13)
+	std	r10,SOFTE(r1)
 #ifdef CONFIG_PPC_ISERIES
 BEGIN_FW_FTR_SECTION
 	/* Hack for handling interrupts when soft-enabling on iSeries */
@@ -94,8 +98,6 @@ BEGIN_FW_FTR_SECTION
 	andi.	r10,r12,MSR_PR		/* from kernel */
 	crand	4*cr0+eq,4*cr1+eq,4*cr0+eq
 	beq	hardware_interrupt_entry
-	lbz	r10,PACAPROCENABLED(r13)
-	std	r10,SOFTE(r1)
 END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
 #endif
 	mfmsr	r11
@@ -460,9 +462,9 @@ #else /* !CONFIG_PREEMPT */
 #endif
 
 restore:
+	ld	r5,SOFTE(r1)
 #ifdef CONFIG_PPC_ISERIES
 BEGIN_FW_FTR_SECTION
-	ld	r5,SOFTE(r1)
 	cmpdi	0,r5,0
 	beq	4f
 	/* Check for pending interrupts (iSeries) */
@@ -472,16 +474,16 @@ BEGIN_FW_FTR_SECTION
 	beq+	4f			/* skip do_IRQ if no interrupts */
 
 	li	r3,0
-	stb	r3,PACAPROCENABLED(r13)	/* ensure we are soft-disabled */
+	stb	r3,PACASOFTIRQEN(r13)	/* ensure we are soft-disabled */
 	ori	r10,r10,MSR_EE
 	mtmsrd	r10			/* hard-enable again */
 	addi	r3,r1,STACK_FRAME_OVERHEAD
 	bl	.do_IRQ
 	b	.ret_from_except_lite		/* loop back and handle more */
-
-4:	stb	r5,PACAPROCENABLED(r13)
+4:
 END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
 #endif
+	stb	r5,PACASOFTIRQEN(r13)
 
 	ld	r3,_MSR(r1)
 	andi.	r0,r3,MSR_RI
@@ -538,25 +540,15 @@ #ifdef CONFIG_PREEMPT
 	/* Check that preempt_count() == 0 and interrupts are enabled */
 	lwz	r8,TI_PREEMPT(r9)
 	cmpwi	cr1,r8,0
-#ifdef CONFIG_PPC_ISERIES
-BEGIN_FW_FTR_SECTION
 	ld	r0,SOFTE(r1)
 	cmpdi	r0,0
-END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
-#endif
-BEGIN_FW_FTR_SECTION
-	andi.	r0,r3,MSR_EE
-END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
 	crandc	eq,cr1*4+eq,eq
 	bne	restore
 	/* here we are preempting the current task */
 1:
-#ifdef CONFIG_PPC_ISERIES
-BEGIN_FW_FTR_SECTION
 	li	r0,1
-	stb	r0,PACAPROCENABLED(r13)
-END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
-#endif
+	stb	r0,PACASOFTIRQEN(r13)
+	stb	r0,PACAHARDIRQEN(r13)
 	ori	r10,r10,MSR_EE
 	mtmsrd	r10,1		/* reenable interrupts */
 	bl	.preempt_schedule
@@ -639,8 +631,7 @@ _GLOBAL(enter_rtas)
 	/* There is no way it is acceptable to get here with interrupts enabled,
 	 * check it with the asm equivalent of WARN_ON
 	 */
-	mfmsr	r6
-	andi.	r0,r6,MSR_EE
+	lbz	r0,PACASOFTIRQEN(r13)
 1:	tdnei	r0,0
 .section __bug_table,"a"
 	.llong	1b,__LINE__ + 0x1000000, 1f, 2f
@@ -649,7 +640,13 @@ _GLOBAL(enter_rtas)
 1:	.asciz	__FILE__
 2:	.asciz "enter_rtas"
 .previous
-	
+
+	/* Hard-disable interrupts */
+	mfmsr	r6
+	rldicl	r7,r6,48,1
+	rotldi	r7,r7,16
+	mtmsrd	r7,1
+
 	/* Unfortunately, the stack pointer and the MSR are also clobbered,
 	 * so they are saved in the PACA which allows us to restore
 	 * our original state after RTAS returns.
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 645c7f1..c93d9f3 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -35,9 +35,7 @@ #include <asm/iseries/lpar_map.h>
 #include <asm/thread_info.h>
 #include <asm/firmware.h>
 
-#ifdef CONFIG_PPC_ISERIES
 #define DO_SOFT_DISABLE
-#endif
 
 /*
  * We layout physical memory as follows:
@@ -308,7 +306,9 @@ #define EXCEPTION_PROLOG_COMMON(n, area)
 	std	r9,_LINK(r1);						   \
 	mfctr	r10;			/* save CTR in stackframe	*/ \
 	std	r10,_CTR(r1);						   \
+	lbz	r10,PACASOFTIRQEN(r13);				   \
 	mfspr	r11,SPRN_XER;		/* save XER in stackframe	*/ \
+	std	r10,SOFTE(r1);						   \
 	std	r11,_XER(r1);						   \
 	li	r9,(n)+1;						   \
 	std	r9,_TRAP(r1);		/* set trap number		*/ \
@@ -343,6 +343,34 @@ label##_pSeries:					\
 	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
 
 
+#define MASKABLE_EXCEPTION_PSERIES(n, label)				\
+	. = n;								\
+	.globl label##_pSeries;						\
+label##_pSeries:							\
+	HMT_MEDIUM;							\
+	mtspr	SPRN_SPRG1,r13;		/* save r13 */			\
+	mfspr	r13,SPRN_SPRG3;		/* get paca address into r13 */	\
+	std	r9,PACA_EXGEN+EX_R9(r13);	/* save r9, r10 */	\
+	std	r10,PACA_EXGEN+EX_R10(r13);				\
+	lbz	r10,PACASOFTIRQEN(r13);					\
+	mfcr	r9;							\
+	cmpwi	r10,0;							\
+	beq	masked_interrupt;					\
+	mfspr	r10,SPRN_SPRG1;						\
+	std	r10,PACA_EXGEN+EX_R13(r13);				\
+	std	r11,PACA_EXGEN+EX_R11(r13);				\
+	std	r12,PACA_EXGEN+EX_R12(r13);				\
+	clrrdi	r12,r13,32;		/* get high part of &label */	\
+	mfmsr	r10;							\
+	mfspr	r11,SPRN_SRR0;		/* save SRR0 */			\
+	LOAD_HANDLER(r12,label##_common)				\
+	ori	r10,r10,MSR_IR|MSR_DR|MSR_RI;				\
+	mtspr	SPRN_SRR0,r12;						\
+	mfspr	r12,SPRN_SRR1;		/* and SRR1 */			\
+	mtspr	SPRN_SRR1,r10;						\
+	rfid;								\
+	b	.	/* prevent speculative execution */
+
 #define STD_EXCEPTION_ISERIES(n, label, area)		\
 	.globl label##_iSeries;				\
 label##_iSeries:					\
@@ -358,40 +386,32 @@ label##_iSeries:							\
 	HMT_MEDIUM;							\
 	mtspr	SPRN_SPRG1,r13;		/* save r13 */			\
 	EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN);				\
-	lbz	r10,PACAPROCENABLED(r13);				\
+	lbz	r10,PACASOFTIRQEN(r13);					\
 	cmpwi	0,r10,0;						\
 	beq-	label##_iSeries_masked;					\
 	EXCEPTION_PROLOG_ISERIES_2;					\
 	b	label##_common;						\
 
-#ifdef DO_SOFT_DISABLE
+#ifdef CONFIG_PPC_ISERIES
 #define DISABLE_INTS				\
-BEGIN_FW_FTR_SECTION;				\
-	lbz	r10,PACAPROCENABLED(r13);	\
 	li	r11,0;				\
-	std	r10,SOFTE(r1);			\
+	stb	r11,PACASOFTIRQEN(r13);		\
+BEGIN_FW_FTR_SECTION;				\
+	stb	r11,PACAHARDIRQEN(r13);		\
+END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES);	\
+BEGIN_FW_FTR_SECTION;				\
 	mfmsr	r10;				\
-	stb	r11,PACAPROCENABLED(r13);	\
 	ori	r10,r10,MSR_EE;			\
 	mtmsrd	r10,1;				\
 END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
 
-#define ENABLE_INTS				\
-BEGIN_FW_FTR_SECTION;				\
-	lbz	r10,PACAPROCENABLED(r13);	\
-	mfmsr	r11;				\
-	std	r10,SOFTE(r1);			\
-	ori	r11,r11,MSR_EE;			\
-END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES);	\
-BEGIN_FW_FTR_SECTION;				\
-	ld	r12,_MSR(r1);			\
-	mfmsr	r11;				\
-	rlwimi	r11,r12,0,MSR_EE;		\
-END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES);	\
-	mtmsrd	r11,1
+#else
+#define DISABLE_INTS				\
+	li	r11,0;				\
+	stb	r11,PACASOFTIRQEN(r13);		\
+	stb	r11,PACAHARDIRQEN(r13)
 
-#else	/* hard enable/disable interrupts */
-#define DISABLE_INTS
+#endif /* CONFIG_PPC_ISERIES */
 
 #define ENABLE_INTS				\
 	ld	r12,_MSR(r1);			\
@@ -399,8 +419,6 @@ #define ENABLE_INTS				\
 	rlwimi	r11,r12,0,MSR_EE;		\
 	mtmsrd	r11,1
 
-#endif
-
 #define STD_EXCEPTION_COMMON(trap, label, hdlr)		\
 	.align	7;					\
 	.globl label##_common;				\
@@ -541,11 +559,11 @@ #endif /* __DISABLED__ */
 	mfspr	r12,SPRN_SRR1		/* and SRR1 */
 	b	.slb_miss_realmode	/* Rel. branch works in real mode */
 
-	STD_EXCEPTION_PSERIES(0x500, hardware_interrupt)
+	MASKABLE_EXCEPTION_PSERIES(0x500, hardware_interrupt)
 	STD_EXCEPTION_PSERIES(0x600, alignment)
 	STD_EXCEPTION_PSERIES(0x700, program_check)
 	STD_EXCEPTION_PSERIES(0x800, fp_unavailable)
-	STD_EXCEPTION_PSERIES(0x900, decrementer)
+	MASKABLE_EXCEPTION_PSERIES(0x900, decrementer)
 	STD_EXCEPTION_PSERIES(0xa00, trap_0a)
 	STD_EXCEPTION_PSERIES(0xb00, trap_0b)
 
@@ -597,7 +615,24 @@ #endif /* CONFIG_CBE_RAS */
 /*** pSeries interrupt support ***/
 
 	/* moved from 0xf00 */
-	STD_EXCEPTION_PSERIES(., performance_monitor)
+	MASKABLE_EXCEPTION_PSERIES(., performance_monitor)
+
+/*
+ * An interrupt came in while soft-disabled; clear EE in SRR1,
+ * clear paca->hard_enabled and return.
+ */
+masked_interrupt:
+	stb	r10,PACAHARDIRQEN(r13)
+	mtcrf	0x80,r9
+	ld	r9,PACA_EXGEN+EX_R9(r13)
+	mfspr	r10,SPRN_SRR1
+	rldicl	r10,r10,48,1		/* clear MSR_EE */
+	rotldi	r10,r10,16
+	mtspr	SPRN_SRR1,r10
+	ld	r10,PACA_EXGEN+EX_R10(r13)
+	mfspr	r13,SPRN_SPRG1
+	rfid
+	b	.
 
 	.align	7
 _GLOBAL(do_stab_bolted_pSeries)
@@ -952,7 +987,8 @@ #endif
 	REST_8GPRS(2, r1)
 
 	mfmsr	r10
-	clrrdi	r10,r10,2		/* clear RI (LE is 0 already) */
+	rldicl	r10,r10,48,1		/* clear EE */
+	rldicr	r10,r10,16,61		/* clear RI (LE is 0 already) */
 	mtmsrd	r10,1
 
 	mtspr	SPRN_SRR1,r12
@@ -1877,11 +1913,16 @@ _GLOBAL(__secondary_start)
 	/* enable MMU and jump to start_secondary */
 	LOAD_REG_ADDR(r3, .start_secondary_prolog)
 	LOAD_REG_IMMEDIATE(r4, MSR_KERNEL)
-#ifdef DO_SOFT_DISABLE
+#ifdef CONFIG_PPC_ISERIES
 BEGIN_FW_FTR_SECTION
 	ori	r4,r4,MSR_EE
 END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
 #endif
+BEGIN_FW_FTR_SECTION
+	stb	r7,PACASOFTIRQEN(r13)
+	stb	r7,PACAHARDIRQEN(r13)
+END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
+
 	mtspr	SPRN_SRR0,r3
 	mtspr	SPRN_SRR1,r4
 	rfid
@@ -2019,15 +2060,18 @@ _STATIC(start_here_common)
 
 	/* Load up the kernel context */
 5:
-#ifdef DO_SOFT_DISABLE
-BEGIN_FW_FTR_SECTION
 	li	r5,0
-	stb	r5,PACAPROCENABLED(r13)	/* Soft Disabled */
+	stb	r5,PACASOFTIRQEN(r13)	/* Soft Disabled */
+#ifdef CONFIG_PPC_ISERIES
+BEGIN_FW_FTR_SECTION
 	mfmsr	r5
 	ori	r5,r5,MSR_EE		/* Hard Enabled */
 	mtmsrd	r5
 END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
 #endif
+BEGIN_FW_FTR_SECTION
+	stb	r5,PACAHARDIRQEN(r13)
+END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
 
 	bl .start_kernel
 
diff --git a/arch/powerpc/kernel/idle_power4.S b/arch/powerpc/kernel/idle_power4.S
index 30de81d..ba31954 100644
--- a/arch/powerpc/kernel/idle_power4.S
+++ b/arch/powerpc/kernel/idle_power4.S
@@ -30,6 +30,13 @@ END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP)
 	beqlr
 
 	/* Go to NAP now */
+	mfmsr	r7
+	rldicl	r0,r7,48,1
+	rotldi	r0,r0,16
+	mtmsrd	r0,1			/* hard-disable interrupts */
+	li	r0,1
+	stb	r0,PACASOFTIRQEN(r13)	/* we'll hard-enable shortly */
+	stb	r0,PACAHARDIRQEN(r13)
 BEGIN_FTR_SECTION
 	DSSALL
 	sync
@@ -38,7 +45,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
 	ld	r8,TI_LOCAL_FLAGS(r9)	/* set napping bit */
 	ori	r8,r8,_TLF_NAPPING	/* so when we take an exception */
 	std	r8,TI_LOCAL_FLAGS(r9)	/* it will return to our caller */
-	mfmsr	r7
 	ori	r7,r7,MSR_EE
 	oris	r7,r7,MSR_POW@h
 1:	sync
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index c3f58f2..d4aa490 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -64,8 +64,9 @@ #include <asm/prom.h>
 #include <asm/ptrace.h>
 #include <asm/machdep.h>
 #include <asm/udbg.h>
-#ifdef CONFIG_PPC_ISERIES
+#ifdef CONFIG_PPC64
 #include <asm/paca.h>
+#include <asm/firmware.h>
 #endif
 
 int __irq_offset_value;
@@ -95,6 +96,27 @@ #ifdef CONFIG_PPC64
 EXPORT_SYMBOL(irq_desc);
 
 int distribute_irqs = 1;
+
+void local_irq_restore(unsigned long en)
+{
+	get_paca()->soft_enabled = en;
+	if (!en)
+		return;
+
+	if (firmware_has_feature(FW_FEATURE_ISERIES)) {
+		if (get_paca()->lppaca_ptr->int_dword.any_int)
+			iseries_handle_interrupts();
+		return;
+	}
+
+	if (get_paca()->hard_enabled)
+		return;
+	/* need to hard-enable interrupts here */
+	get_paca()->hard_enabled = en;
+	if ((int)mfspr(SPRN_DEC) < 0)
+		mtspr(SPRN_DEC, 1);
+	hard_irq_enable();
+}
 #endif /* CONFIG_PPC64 */
 
 int show_interrupts(struct seq_file *p, void *v)
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index 807193a..9179f07 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -49,6 +49,10 @@ #ifdef  CONFIG_8xx
 #include <asm/commproc.h>
 #endif
 
+#ifdef CONFIG_PPC64
+EXPORT_SYMBOL(local_irq_restore);
+#endif
+
 #ifdef CONFIG_PPC32
 extern void transfer_to_handler(void);
 extern void do_IRQ(struct pt_regs *regs);
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 4b2e32e..b1b0cda 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -223,8 +223,8 @@ void early_setup_secondary(void)
 {
 	struct paca_struct *lpaca = get_paca();
 
-	/* Mark enabled in PACA */
-	lpaca->proc_enabled = 0;
+	/* Mark interrupts enabled in PACA */
+	lpaca->soft_enabled = 0;
 
 	/* Initialize hash table for that CPU */
 	htab_initialize_secondary();
diff --git a/arch/powerpc/platforms/iseries/ksyms.c b/arch/powerpc/platforms/iseries/ksyms.c
index a220084..2430848 100644
--- a/arch/powerpc/platforms/iseries/ksyms.c
+++ b/arch/powerpc/platforms/iseries/ksyms.c
@@ -19,9 +19,3 @@ EXPORT_SYMBOL(HvCall4);
 EXPORT_SYMBOL(HvCall5);
 EXPORT_SYMBOL(HvCall6);
 EXPORT_SYMBOL(HvCall7);
-
-#ifdef CONFIG_SMP
-EXPORT_SYMBOL(local_get_flags);
-EXPORT_SYMBOL(local_irq_disable);
-EXPORT_SYMBOL(local_irq_restore);
-#endif
diff --git a/arch/powerpc/platforms/iseries/misc.S b/arch/powerpc/platforms/iseries/misc.S
index 7641fc7..2c6ff0f 100644
--- a/arch/powerpc/platforms/iseries/misc.S
+++ b/arch/powerpc/platforms/iseries/misc.S
@@ -19,39 +19,8 @@ #include <asm/ppc_asm.h>
 
 	.text
 
-/* unsigned long local_save_flags(void) */
-_GLOBAL(local_get_flags)
-	lbz	r3,PACAPROCENABLED(r13)
-	blr
-
-/* unsigned long local_irq_disable(void) */
-_GLOBAL(local_irq_disable)
-	lbz	r3,PACAPROCENABLED(r13)
-	li	r4,0
-	stb	r4,PACAPROCENABLED(r13)
-	blr			/* Done */
-
-/* void local_irq_restore(unsigned long flags) */
-_GLOBAL(local_irq_restore)
-	lbz	r5,PACAPROCENABLED(r13)
-	 /* Check if things are setup the way we want _already_. */
-	cmpw	0,r3,r5
-	beqlr
-	/* are we enabling interrupts? */
-	cmpdi	0,r3,0
-	stb	r3,PACAPROCENABLED(r13)
-	beqlr
-	/* Check pending interrupts */
-	/*   A decrementer, IPI or PMC interrupt may have occurred
-	 *   while we were in the hypervisor (which enables) */
-	ld	r4,PACALPPACAPTR(r13)
-	ld	r4,LPPACAANYINT(r4)
-	cmpdi	r4,0
-	beqlr
-
-	/*
-	 * Handle pending interrupts in interrupt context
-	 */
+/* Handle pending interrupts in interrupt context */
+_GLOBAL(iseries_handle_interrupts)
 	li	r0,0x5555
 	sc
 	blr
diff --git a/include/asm-powerpc/hw_irq.h b/include/asm-powerpc/hw_irq.h
index d403592..c4a1ab6 100644
--- a/include/asm-powerpc/hw_irq.h
+++ b/include/asm-powerpc/hw_irq.h
@@ -7,16 +7,30 @@ #define _ASM_POWERPC_HW_IRQ_H
 #ifdef __KERNEL__
 
 #include <linux/errno.h>
+#include <linux/compiler.h>
 #include <asm/ptrace.h>
 #include <asm/processor.h>
 
 extern void timer_interrupt(struct pt_regs *);
 
-#ifdef CONFIG_PPC_ISERIES
+#ifdef CONFIG_PPC64
+#include <asm/paca.h>
+
+static inline unsigned long local_get_flags(void)
+{
+	return get_paca()->soft_enabled;
+}
+
+static inline unsigned long local_irq_disable(void)
+{
+	unsigned long flag = get_paca()->soft_enabled;
+	get_paca()->soft_enabled = 0;
+	barrier();
+	return flag;
+}
 
-extern unsigned long local_get_flags(void);
-extern unsigned long local_irq_disable(void);
 extern void local_irq_restore(unsigned long);
+extern void iseries_handle_interrupts(void);
 
 #define local_irq_enable()	local_irq_restore(1)
 #define local_save_flags(flags)	((flags) = local_get_flags())
@@ -24,17 +38,14 @@ #define local_irq_save(flags)	((flags) =
 
 #define irqs_disabled()		(local_get_flags() == 0)
 
+#define hard_irq_enable()	__mtmsrd(mfmsr() | MSR_EE, 1)
+#define hard_irq_disable()	__mtmsrd(mfmsr() & ~MSR_EE, 1)
+
 #else
 
 #if defined(CONFIG_BOOKE)
 #define SET_MSR_EE(x)	mtmsr(x)
 #define local_irq_restore(flags)	__asm__ __volatile__("wrtee %0" : : "r" (flags) : "memory")
-#elif defined(__powerpc64__)
-#define SET_MSR_EE(x)	__mtmsrd(x, 1)
-#define local_irq_restore(flags) do { \
-	__asm__ __volatile__("": : :"memory"); \
-	__mtmsrd((flags), 1); \
-} while(0)
 #else
 #define SET_MSR_EE(x)	mtmsr(x)
 #define local_irq_restore(flags)	mtmsr(flags)
@@ -81,7 +92,7 @@ #define local_save_flags(flags)	((flags)
 #define local_irq_save(flags)	local_irq_save_ptr(&flags)
 #define irqs_disabled()		((mfmsr() & MSR_EE) == 0)
 
-#endif /* CONFIG_PPC_ISERIES */
+#endif /* CONFIG_PPC64 */
 
 #define mask_irq(irq)						\
 	({							\
diff --git a/include/asm-powerpc/paca.h b/include/asm-powerpc/paca.h
index 0a4e5c9..0d3adc0 100644
--- a/include/asm-powerpc/paca.h
+++ b/include/asm-powerpc/paca.h
@@ -93,7 +93,8 @@ #endif /* CONFIG_PPC_ISERIES */
 	u64 stab_rr;			/* stab/slb round-robin counter */
 	u64 saved_r1;			/* r1 save for RTAS calls */
 	u64 saved_msr;			/* MSR saved here by enter_rtas */
-	u8 proc_enabled;		/* irq soft-enable flag */
+	u8 soft_enabled;		/* irq soft-enable flag */
+	u8 hard_enabled;		/* set if irqs are enabled in MSR */
 	u8 io_sync;			/* writel() needs spin_unlock sync */
 
 	/* Stuff for accurate time accounting */

^ permalink raw reply related

* RE : platform flash for Xilinx ML403
From: alayrac @ 2006-10-04  7:24 UTC (permalink / raw)
  To: 'Aleck Lin', linuxppc-embedded
In-Reply-To: <003001c6e75c$3ad7da70$800101df@monstertop>

Hi Aleck,

As far as I understand Platform Flash can Only handel bistream for FPGA.
If your code is small enough to fit in internal BRAM then you can embed
you application in the bistream making your project as "Mark to
initialize BRAM's". Then when you will build the project XPS will update
BRAM memory content with your application.

I don't think that after bitsream load the PPC405 can access the
PlatformFlash in order to start Uboot from that place, and I'm afraid
that U-boot is to big to fit in FPGA internal BRAM.

If you have a quick look to ML403 schematics (page 8/24) you will see
that XCF32P as no Read signal. The parallel bus is just use to load
bitstream in parallel mode. Furthermore there is no interface for that
plateform Flash in the XPS project (you can't find it in the System
Assembly).

You should try to open a WebCase from Xilinx website and look in the faq
to confirm that point.


Cheers

Chris

CRESITT INDUSTRIE
Email : christophe.alayrac@cresitt.com=20
Web : http://www.cresitt.com


<----> -----Message d'origine-----
<----> De=A0: linuxppc-embedded-
<----> bounces+christophe.alayrac=3Dcresitt.com@ozlabs.org
[mailto:linuxppc-
<----> embedded-bounces+christophe.alayrac=3Dcresitt.com@ozlabs.org] De =
la
<----> part de Aleck Lin
<----> Envoy=E9=A0: mercredi 4 octobre 2006 04:24
<----> =C0=A0: linuxppc-embedded@ozlabs.org
<----> Objet=A0: platform flash for Xilinx ML403
<---->=20
<----> Hello,
<---->=20
<----> Can anyone help with my questions on platform flash for Xilinx
ML403?
<---->=20
<----> >From what I understand, I can use platform flash to store my
FPGA
<----> bitstream
<----> file and my software application elf file, so it's like using an
ACE
<----> file
<----> through the CompactFlash, except I just need to set the
configuration
<----> address through DIP switch and then push the PROG button on the
board
<----> (provided it's set to Platform Flash mode) and then the software
<----> application
<----> would start running. Is this correct?
<---->=20
<----> If it's correct, then how would I be able to program the Platform
<----> Flash? Do
<----> I program separate bit file and elf file, or do I program an ace
file
<----> or ??
<----> I have the ML40x Getting Started Tutorial in which there's a
section
<----> on how
<----> to program my own flash image. But I couldn't really understand
some
<----> things
<----> in it, such as a PROM file, or adding file to Revision no. and
etc.
<----> Can
<----> someone help or point out a more detailed document?
<---->=20
<----> My eventual goal is to be able to use the platform flash to start
u-
<----> boot and
<----> then boot linux image, which will be stored in linear flash. I
think
<----> I have
<----> all the parts ready (u-boot image, uImage, and hardware
bitstream),
<----> but just
<----> lack of the understanding to put in this particular
configuration.
<---->=20
<----> Any help would be appreciated!
<---->=20
<----> Thanks,
<---->=20
<----> Aleck
<----> _______________________________________________
<----> Linuxppc-embedded mailing list
<----> Linuxppc-embedded@ozlabs.org
<----> https://ozlabs.org/mailman/listinfo/linuxppc-embedded

^ permalink raw reply

* Re: [PATCH 7/7] [POWERPC] implement BEGIN/END_FW_FTR_SECTION
From: Benjamin Herrenschmidt @ 2006-10-04  7:58 UTC (permalink / raw)
  To: Stephen Rothwell; +Cc: ppc-dev, paulus
In-Reply-To: <20060926134222.9e035cc8.sfr@canb.auug.org.au>


> +/*
> + * do_fw_ftr_fixups - goes through the list of firmware feature fixups
> + * and writes nop's over sections of code that don't apply for this firmware.
> + * r3 = data offset (not changed)
> + */
> +_GLOBAL(do_fw_ftr_fixups)
> +	/* Get firmware features */
> +	LOAD_REG_IMMEDIATE(r6,powerpc_firmware_features)
> +	sub	r6,r6,r3
> +	ld	r4,0(r6)
> +	/* Get the fixup table */
> +	LOAD_REG_IMMEDIATE(r6,__start___fw_ftr_fixup)
> +	sub	r6,r6,r3
> +	LOAD_REG_IMMEDIATE(r7,__stop___fw_ftr_fixup)
> +	sub	r7,r7,r3
> +	/* Do the fixup */
> +1:	cmpld	r6,r7
> +	bgelr

 .../...

I'd rather have a single apply_ftr_fixups() that takes the start/stop of
the fixup table and the value to compare against. That could then be
called for fw fixups at boot, fw fixups from modules, cpu fixups at
boot, cpu fixups from modules, and possibly fixups in the vdso's is a
feature I've been thinking of, and which would be easier with just a
single function like that.

Ben.
 

^ permalink raw reply

* Re: booting 2.6 kernel on ML403
From: Ameet Patil @ 2006-10-04  8:00 UTC (permalink / raw)
  To: Pradeep Sampath; +Cc: linuxppc-embedded
In-Reply-To: <20061003214641.48214.qmail@web83210.mail.mud.yahoo.com>

Pradeep Sampath wrote:
> Hi Ameet,
> Thanks for the instant reply. I changed root parameter to xsa as you 
> suggested root=/dev/xsa2. But i still get the same failure.
>  
> [    3.093694] TCP bic registered
> [    3.129458] NET: Registered protocol family 8
> [    3.181412] NET: Registered protocol family 20
> [    3.236744] VFS: Cannot open root device "xsa2" or unknown-block(0,0)
> [    3.313092] Please append a correct "root=" boot option
> [    3.375552] Kernel panic - not syncing: VFS: Unable to mount root 
> fs on unkno
> wn-block(0,0)
> [    3.474504]  <0>Rebooting in 180 seconds..
>
>  
> On the CF i created the following block and character device files
> # mknod -m 660 console c 5 1
> # mknod -m 660 xsa b 254 0
> # mknod -m 660 xsa1 b 254 1
> # mknod -m 660 xsa2 b 254 2
> # mknod -m 660 xsa3 b 254 3
> mkdir tts
> # mknod -m 660 0 c 4 64
>
> > Problem 2:
> > - Untar the kernel 2.6.17.1
> > - Applied the 5 TEMAC patches
> > - Applied Ameet's Sysace patch
> which patch did you apply? For TEMAC... apply the following patch:
> http://www.cs.york.ac.uk/rtslab/demos/amos/xupv2pro/patches/linuxppc-2.6.17.1-sysace-1.2-after-TEMAC.patch
> Yes, i have applied *only* after-TEMAC.patch. But looks like it blows 
> away the configuration and results in kernel hang.
>  
> Any further suggestions on where i should look at.
>  
> regards.
> Pradeep
Please could send me all the boot messages until the point where it 
stops. This will help me better identify the problem.

Thanks,
-Ameet

^ permalink raw reply

* Re: [PATCH 3/7] [POWERPC] modify PCI code for a merged kernel
From: Benjamin Herrenschmidt @ 2006-10-04  8:02 UTC (permalink / raw)
  To: Stephen Rothwell; +Cc: ppc-dev, paulus
In-Reply-To: <20060926133651.897ad602.sfr@canb.auug.org.au>

On Tue, 2006-09-26 at 13:36 +1000, Stephen Rothwell wrote:
> -#ifndef CONFIG_PPC_ISERIES
>  void __devinit pcibios_claim_one_bus(struct pci_bus *b)
>  {
>  	struct pci_dev *dev;
> @@ -238,10 +238,12 @@ static void __init pcibios_claim_of_setu
>  {
>  	struct pci_bus *b;
>  
> +	if (firmware_has_feature(FW_FEATURE_ISERIES))
> +		return;
> +
>  	list_for_each_entry(b, &pci_root_buses, node)
>  		pcibios_claim_one_bus(b);
>  }
> -#endif

Is the above actually needed ? That is, what kind of problem iseries
would expect if pcibios_claim_one_bus() was called ?

>  #ifdef CONFIG_PPC_MULTIPLATFORM
>  static u32 get_int_prop(struct device_node *np, const char *name, u32 def)
> @@ -554,9 +556,8 @@ static int __init pcibios_init(void)
>  	 */
>  	ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot;
>  
> -#ifdef CONFIG_PPC_ISERIES
> -	iSeries_pcibios_init(); 
> -#endif
> +	if (firmware_has_feature(FW_FEATURE_ISERIES))
> +		iSeries_pcibios_init();

Why not do like all other platforms and allocate create the PHBs
setup_arch ? That would avoid an iSeries specific call in generic code.

>  	printk(KERN_DEBUG "PCI: Probing PCI hardware\n");
>  
> @@ -566,15 +567,15 @@ #endif
>  		pci_bus_add_devices(hose->bus);
>  	}
>  
> -#ifndef CONFIG_PPC_ISERIES
> -	if (pci_probe_only)
> -		pcibios_claim_of_setup();
> -	else
> -		/* FIXME: `else' will be removed when
> -		   pci_assign_unassigned_resources() is able to work
> -		   correctly with [partially] allocated PCI tree. */
> -		pci_assign_unassigned_resources();
> -#endif /* !CONFIG_PPC_ISERIES */
> +	if (!firmware_has_feature(FW_FEATURE_ISERIES)) {
> +		if (pci_probe_only)
> +			pcibios_claim_of_setup();
> +		else
> +			/* FIXME: `else' will be removed when
> +			   pci_assign_unassigned_resources() is able to work
> +			   correctly with [partially] allocated PCI tree. */
> +			pci_assign_unassigned_resources();
> +	}

What happens if you don't do the above and set pci_probe_only to 1 ?

>  	/* Call machine dependent final fixup */
>  	if (ppc_md.pcibios_fixup)
> @@ -586,8 +587,9 @@ #endif /* !CONFIG_PPC_ISERIES */
>  		printk(KERN_DEBUG "ISA bridge at %s\n", pci_name(ppc64_isabridge_dev));
>  
>  #ifdef CONFIG_PPC_MULTIPLATFORM
> -	/* map in PCI I/O space */
> -	phbs_remap_io();
> +	if (!firmware_has_feature(FW_FEATURE_ISERIES))
> +		/* map in PCI I/O space */
> +		phbs_remap_io();
>  #endif

IO space mapping is dodgy with iSeries... I suppose that is correct for
now though we might want to do something a bit nastier like actually
mapping it to unaccessible memory and SEGV'ing on access or stuff like
that if IO is really not supported....

>  	printk(KERN_DEBUG "PCI: Probing PCI hardware done\n");
> @@ -637,13 +639,13 @@ int pcibios_enable_device(struct pci_dev
>   */
>  int pci_domain_nr(struct pci_bus *bus)
>  {
> -#ifdef CONFIG_PPC_ISERIES
> -	return 0;
> -#else
> -	struct pci_controller *hose = pci_bus_to_host(bus);
> +	if (firmware_has_feature(FW_FEATURE_ISERIES))
> +		return 0;
> +	else {
> +		struct pci_controller *hose = pci_bus_to_host(bus);
>  
> -	return hose->global_number;
> -#endif
> +		return hose->global_number;
> +	}
>  }

Any reason why the above is useful at all ? Especially since it seems
you -can- have multiple busses and thus -want- the domain numbers to be
exposed.
 
>  EXPORT_SYMBOL(pci_domain_nr);
> @@ -651,12 +653,12 @@ EXPORT_SYMBOL(pci_domain_nr);
>  /* Decide whether to display the domain number in /proc */
>  int pci_proc_domain(struct pci_bus *bus)
>  {
> -#ifdef CONFIG_PPC_ISERIES
> -	return 0;
> -#else
> -	struct pci_controller *hose = pci_bus_to_host(bus);
> -	return hose->buid;
> -#endif
> +	if (firmware_has_feature(FW_FEATURE_ISERIES))
> +		return 0;
> +	else {
> +		struct pci_controller *hose = pci_bus_to_host(bus);
> +		return hose->buid;
> +	}
>  }

Same question. Why do that at all ?
 
Cheers,
Ben.

^ permalink raw reply

* Re: booting 2.6 kernel on ML403
From: Ming Liu @ 2006-10-04  8:11 UTC (permalink / raw)
  To: pradeepsampath; +Cc: linuxppc-embedded
In-Reply-To: <20061003214641.48214.qmail@web83210.mail.mud.yahoo.com>

Hi,

>   [    3.093694] TCP bic registered
>[    3.129458] NET: Registered protocol family 8
>[    3.181412] NET: Registered protocol family 20
>[    3.236744] VFS: Cannot open root device "xsa2" or unknown-block(0,0)
>[    3.313092] Please append a correct "root=" boot option

It looks that some errors still exist in the parameters you passed to 
"root=". Please double check it, or post it in the maillist for deep 
analysis. 

Regards
Ming

_________________________________________________________________
享用世界上最大的电子邮件系统― MSN Hotmail。  http://www.hotmail.com  

^ permalink raw reply

* Re: [PATCH 7/7] [POWERPC] implement BEGIN/END_FW_FTR_SECTION
From: Stephen Rothwell @ 2006-10-04  8:26 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: ppc-dev, paulus
In-Reply-To: <1159948683.13323.74.camel@localhost.localdomain>

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

Hi Ben,

On Wed, 04 Oct 2006 17:58:03 +1000 Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
>
> I'd rather have a single apply_ftr_fixups() that takes the start/stop of
> the fixup table and the value to compare against. That could then be
> called for fw fixups at boot, fw fixups from modules, cpu fixups at
> boot, cpu fixups from modules, and possibly fixups in the vdso's is a
> feature I've been thinking of, and which would be easier with just a
> single function like that.

I agree entirely, but my PowerPC assembly skills are not up to it :-(

--
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: booting 2.6 kernel on ML403
From: Ameet Patil @ 2006-10-04  8:35 UTC (permalink / raw)
  To: Ming Liu; +Cc: linuxppc-embedded
In-Reply-To: <BAY110-F1626C56882856AE74835E5B21D0@phx.gbl>

Ming Liu wrote:
> Hi,
>
>> [ 3.093694] TCP bic registered
>> [ 3.129458] NET: Registered protocol family 8
>> [ 3.181412] NET: Registered protocol family 20
>> [ 3.236744] VFS: Cannot open root device "xsa2" or unknown-block(0,0)
>> [ 3.313092] Please append a correct "root=" boot option
>
> It looks that some errors still exist in the parameters you passed to
> "root=". Please double check it, or post it in the maillist for deep
> analysis.
> Regards
> Ming
>
> _________________________________________________________________
> 享用世界上最大的电子邮件系统― MSN Hotmail。 http://www.hotmail.com
> ------------------------------------------------------------------------
>
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
Hi Ming,
IIRC, you are or were using the TEMAC driver along with my System Ace
driver, isn't it? Does my driver patch ***-after-TEMAC.patch work for
you? I ask this because Pradeep is having some problems using it (see
Problem 2 in his email). Could you please update on this?

Thanks,
-Ameet

^ permalink raw reply

* Re: booting 2.6 kernel on ML403
From: Ming Liu @ 2006-10-04  8:42 UTC (permalink / raw)
  To: ammubhai; +Cc: linuxppc-embedded
In-Reply-To: <4523723B.5030809@gmail.com>

Hello Ameet,
I am using that driver very well now. There is only one problem. It seems 
that the driver for TEMAC only support Gigabit Enet, not 10/100/1000M 
adapted. But because I want to use the Gigabit enet, I don't care that. So 
it's OK, at lease for 1Gbit/s.

So I don't think Pradeep's problem is caused by Temac. I still suspect that 
he didn't pass a right parameter to "root=", just like what I posted 
before.

Regards
Ming


>From: Ameet Patil <ammubhai@gmail.com>
>To: Ming Liu <eemingliu@hotmail.com>
>CC: pradeepsampath@yahoo.com,  linuxppc-embedded@ozlabs.org
>Subject: Re: booting 2.6 kernel on ML403
>Date: Wed, 04 Oct 2006 09:35:07 +0100
>
>Ming Liu wrote:
> > Hi,
> >
> >> [ 3.093694] TCP bic registered
> >> [ 3.129458] NET: Registered protocol family 8
> >> [ 3.181412] NET: Registered protocol family 20
> >> [ 3.236744] VFS: Cannot open root device "xsa2" or unknown-block(0,0)
> >> [ 3.313092] Please append a correct "root=" boot option
> >
> > It looks that some errors still exist in the parameters you passed to
> > "root=". Please double check it, or post it in the maillist for deep
> > analysis.
> > Regards
> > Ming
> >
> > _________________________________________________________________
> > 享用世界上最大的电子邮件系统― MSN Hotmail。 http://www.hotmail.com
> > 
------------------------------------------------------------------------
> >
> > _______________________________________________
> > Linuxppc-embedded mailing list
> > Linuxppc-embedded@ozlabs.org
> > https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>Hi Ming,
>IIRC, you are or were using the TEMAC driver along with my System Ace
>driver, isn't it? Does my driver patch ***-after-TEMAC.patch work for
>you? I ask this because Pradeep is having some problems using it (see
>Problem 2 in his email). Could you please update on this?
>
>Thanks,
>-Ameet

_________________________________________________________________
与联机的朋友进行交流,请使用 MSN Messenger:  http://messenger.msn.com/cn  

^ permalink raw reply

* uboot-1.1.4 linux-2.6.10: Image bootproblems
From: Armin Steck @ 2006-10-04  9:04 UTC (permalink / raw)
  To: linuxppc-embedded

Hello,

i have ported uboot1.1.4 for my board.
When i would like to boot linux-kernel-2.6.10 the system hang after decompressing.
can anybody help me? 

Flash: 0x00000000 uboot
       0x00020000 ubootenvironment
       0x00040000 kernel uImage

uImage: gzip -9 < zImage > Image.gz
	/elinux/kernel2.6Richard/Richard/linux-2.6.10/scripts/mkuboot.sh 
          -A arm -O linux -T kernel -C gzip -a 0xa0008000 -e 0xa0008000 -n
          'Linux-2.6.10' -d Image.gz uImage

U-BOOT output:
RAM Configuration:
Bank #0: a0000000 32 MB
Flash #0: 00000000 16 MB
In:    serial
Out:   serial
Err:   serial
Hit any key to stop autoboot: 1
uboot==> bootm 0x00040000
## Booting image at 00040000 ...
   Image Name:   Linux-2.6.10
   Image Type:   ARM Linux Kernel Image (gzip compressed)
   Data Size:    756009 Bytes = 738.3 kB
   Load Address: a0008000
   Entry Point:  a0008000
   Verifying Checksum ... OK
   Uncompressing Kernel Image ... OK

Starting kernel ...

Uncompressing Linux................................................... done, booting the kernel.

69052D06:0000001B:00001078          #Kernel-Debug-Information
A00DC914-A0259594>A0008000
A0259594


-- 
Der GMX SmartSurfer hilft bis zu 70% Ihrer Onlinekosten zu sparen! 
Ideal für Modem und ISDN: http://www.gmx.net/de/go/smartsurfer

^ permalink raw reply

* Re: [PATCH 7/7] [POWERPC] implement BEGIN/END_FW_FTR_SECTION
From: Benjamin Herrenschmidt @ 2006-10-04 10:08 UTC (permalink / raw)
  To: Stephen Rothwell; +Cc: ppc-dev, paulus
In-Reply-To: <20061004182652.a8600f11.sfr@canb.auug.org.au>

On Wed, 2006-10-04 at 18:26 +1000, Stephen Rothwell wrote:
> Hi Ben,
> 
> On Wed, 04 Oct 2006 17:58:03 +1000 Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
> >
> > I'd rather have a single apply_ftr_fixups() that takes the start/stop of
> > the fixup table and the value to compare against. That could then be
> > called for fw fixups at boot, fw fixups from modules, cpu fixups at
> > boot, cpu fixups from modules, and possibly fixups in the vdso's is a
> > feature I've been thinking of, and which would be easier with just a
> > single function like that.
> 
> I agree entirely, but my PowerPC assembly skills are not up to it :-(

Ok, I'll do that with you later this week

Ben.

^ permalink raw reply

* Re: Linuxppc-embedded Digest, Vol 25, Issue 60
From: hpchen @ 2006-10-04  9:21 UTC (permalink / raw)
  To: linuxppc-embedded

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

Dear Matthias:
  I am also using SM722 and accessing it with 8245, but I can't
access the SM722's register under mpc8245 at all. Would you mind
giving me any advice on it? Thank you!

> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of Linuxppc-embedded digest..."
>    2. SM722 (Lynx3DM+) framebuffer driver (Matthias Fuchs)

> Message: 2
> Date: Wed, 27 Sep 2006 12:26:06 +0200
> From: Matthias Fuchs <matthias.fuchs@esd-electronics.com>
> Subject: SM722 (Lynx3DM+) framebuffer driver
> To: Linuxppc-embedded@ozlabs.org
> Message-ID: <200609271226.06115.matthias.fuchs@esd-electronics.com>
> Content-Type: text/plain;  charset="us-ascii"
> 
> Hi,
> 
> does anyone know about a Silicon Motion SM722 framebuffer driver for recent 
> 2.6 kernels? I found some old and dusty code for the Silicon Motion parts but 
> either only for the SM712 or for 2.4 kernels.
> 
> Is anyone using that part in a PowerPC system?
> 
> Matthias
 
 
 


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

^ permalink raw reply

* [PATCH] uninorth: Add module param 'aperture' for aperture size
From: Michel Dänzer @ 2006-10-04 10:44 UTC (permalink / raw)
  To: Dave Jones; +Cc: linuxppc-dev
In-Reply-To: <1156285033.21752.107.camel@localhost.localdomain>

In contrast to most if not all PC BIOSes, OpenFirmware (OF) on PowerMacs with
UniNorth bridges does not allow changing the aperture size. The size set up by
OF is usually 16 MB, which is too low for graphics intensive environments.
Hence, add a module parameter that allows changing the aperture size at driver
initialization time. When the parameter is not specified, the default is 32 MB.

Signed-off-by: Michel Dänzer <michel@tungstengraphics.com>
---

Any (N)ACKs on this would be much appreciated.

Note that I made the default size 32 MB (instead of 64 MB as discussed on the
linuxppc-dev list) to make this patch independent of the other uninorth patch I
sent out.

 drivers/char/agp/uninorth-agp.c |   54 +++++++++++++++++++++++++--------------
 1 files changed, 35 insertions(+), 19 deletions(-)

diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c
index 78c8cb2..4770187 100644
--- a/drivers/char/agp/uninorth-agp.c
+++ b/drivers/char/agp/uninorth-agp.c
@@ -27,32 +27,42 @@ #include "agp.h"
 static int uninorth_rev;
 static int is_u3;
 
+static char __devinitdata *aperture = NULL;
 
 static int uninorth_fetch_size(void)
 {
-	int i;
-	u32 temp;
-	struct aper_size_info_32 *values;
-
-	pci_read_config_dword(agp_bridge->dev, UNI_N_CFG_GART_BASE, &temp);
-	temp &= ~(0xfffff000);
-	values = A_SIZE_32(agp_bridge->driver->aperture_sizes);
-
-	for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
-		if (temp == values[i].size_value) {
-			agp_bridge->previous_size =
-			    agp_bridge->current_size = (void *) (values + i);
-			agp_bridge->aperture_size_idx = i;
-			return values[i].size;
+	int i, size = 0;
+	struct aper_size_info_32 *values =
+	    A_SIZE_32(agp_bridge->driver->aperture_sizes);
+
+	if (aperture) {
+		char *save = aperture;
+
+		size = memparse(aperture, &aperture) >> 20;
+		aperture = save;
+
+		for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++)
+			if (size == values[i].size)
+				break;
+
+		if (i == agp_bridge->driver->num_aperture_sizes) {
+			printk(KERN_ERR PFX "Invalid aperture size, using"
+			       " default\n");
+			size = 0;
+			aperture = NULL;
 		}
 	}
 
-	agp_bridge->previous_size =
-	    agp_bridge->current_size = (void *) (values + 1);
-	agp_bridge->aperture_size_idx = 1;
-	return values[1].size;
+	if (!size) {
+		for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++)
+			if (32 == values[i].size)
+				break;
+	}
 
-	return 0;
+	agp_bridge->previous_size =
+	    agp_bridge->current_size = (void *)(values + i);
+	agp_bridge->aperture_size_idx = i;
+	return values[i].size;
 }
 
 static void uninorth_tlbflush(struct agp_memory *mem)
@@ -668,5 +678,11 @@ static void __exit agp_uninorth_cleanup(
 module_init(agp_uninorth_init);
 module_exit(agp_uninorth_cleanup);
 
+module_param(aperture, charp, 0);
+MODULE_PARM_DESC(aperture,
+		 "Aperture size, must be power of two between 4MB and an\n"
+		 "\t\tupper limit specific to the UniNorth revision.\n"
+		 "\t\tDefault: 32M");
+
 MODULE_AUTHOR("Ben Herrenschmidt & Paul Mackerras");
 MODULE_LICENSE("GPL");
-- 
1.4.1.1



-- 
Earthling Michel Dänzer           |          http://tungstengraphics.com
Libre software enthusiast         |          Debian, X and DRI developer

^ permalink raw reply related

* Re: [PATCH] uninorth: Add module param 'aperture' for aperture size
From: Andreas Schwab @ 2006-10-04 12:24 UTC (permalink / raw)
  To: Michel Dänzer; +Cc: Dave Jones, linuxppc-dev
In-Reply-To: <1159958670.23084.217.camel@thor.lorrainebruecke.local>

Michel Dänzer <michel@tungstengraphics.com> writes:

> +			if (32 == values[i].size)

variable == value, please.

Andreas.

-- 
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
PGP key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply

* [PATCH] uninorth: Add module param 'aperture' for aperture size
From: Michel Dänzer @ 2006-10-04 12:56 UTC (permalink / raw)
  To: Dave Jones; +Cc: linuxppc-dev

In contrast to most if not all PC BIOSes, OpenFirmware (OF) on PowerMacs with
UniNorth bridges does not allow changing the aperture size. The size set up by
OF is usually 16 MB, which is too low for graphics intensive environments.
Hence, add a module parameter that allows changing the aperture size at driver
initialization time. When the parameter is not specified, the default is 32 MB.

Signed-off-by: Michel Dänzer <michel@tungstengraphics.com>
---

Reversed a 'value == variable' test, as suggested by Andreas Schwab (thanks!).

 drivers/char/agp/uninorth-agp.c |   54 +++++++++++++++++++++++++--------------
 1 files changed, 35 insertions(+), 19 deletions(-)

diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c
index 78c8cb2..c2b6f7d 100644
--- a/drivers/char/agp/uninorth-agp.c
+++ b/drivers/char/agp/uninorth-agp.c
@@ -27,32 +27,42 @@ #include "agp.h"
 static int uninorth_rev;
 static int is_u3;
 
+static char __devinitdata *aperture = NULL;
 
 static int uninorth_fetch_size(void)
 {
-	int i;
-	u32 temp;
-	struct aper_size_info_32 *values;
-
-	pci_read_config_dword(agp_bridge->dev, UNI_N_CFG_GART_BASE, &temp);
-	temp &= ~(0xfffff000);
-	values = A_SIZE_32(agp_bridge->driver->aperture_sizes);
-
-	for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
-		if (temp == values[i].size_value) {
-			agp_bridge->previous_size =
-			    agp_bridge->current_size = (void *) (values + i);
-			agp_bridge->aperture_size_idx = i;
-			return values[i].size;
+	int i, size = 0;
+	struct aper_size_info_32 *values =
+	    A_SIZE_32(agp_bridge->driver->aperture_sizes);
+
+	if (aperture) {
+		char *save = aperture;
+
+		size = memparse(aperture, &aperture) >> 20;
+		aperture = save;
+
+		for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++)
+			if (size == values[i].size)
+				break;
+
+		if (i == agp_bridge->driver->num_aperture_sizes) {
+			printk(KERN_ERR PFX "Invalid aperture size, using"
+			       " default\n");
+			size = 0;
+			aperture = NULL;
 		}
 	}
 
-	agp_bridge->previous_size =
-	    agp_bridge->current_size = (void *) (values + 1);
-	agp_bridge->aperture_size_idx = 1;
-	return values[1].size;
+	if (!size) {
+		for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++)
+			if (values[i].size == 32)
+				break;
+	}
 
-	return 0;
+	agp_bridge->previous_size =
+	    agp_bridge->current_size = (void *)(values + i);
+	agp_bridge->aperture_size_idx = i;
+	return values[i].size;
 }
 
 static void uninorth_tlbflush(struct agp_memory *mem)
@@ -668,5 +678,11 @@ static void __exit agp_uninorth_cleanup(
 module_init(agp_uninorth_init);
 module_exit(agp_uninorth_cleanup);
 
+module_param(aperture, charp, 0);
+MODULE_PARM_DESC(aperture,
+		 "Aperture size, must be power of two between 4MB and an\n"
+		 "\t\tupper limit specific to the UniNorth revision.\n"
+		 "\t\tDefault: 32M");
+
 MODULE_AUTHOR("Ben Herrenschmidt & Paul Mackerras");
 MODULE_LICENSE("GPL");
-- 
1.4.2.1


-- 
Earthling Michel Dänzer           |          http://tungstengraphics.com
Libre software enthusiast         |          Debian, X and DRI developer

^ permalink raw reply related

* Please pull powerpc.git 'master' branch
From: Paul Mackerras @ 2006-10-04 13:01 UTC (permalink / raw)
  To: torvalds; +Cc: linuxppc-dev

Linus,

Please do:

git pull \
git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc.git

to get some more PowerPC updates.

This includes a series from Leo Li and Kim Phillips adding support for
devices on the Freescale 83xx chips, a series from Stephen Rothwell
that means we can include support for legacy iSeries along with other
64-bit platforms, a series from Vitaly Bordug adding support for the
mpc8272ads board, and various bug fixes and cleanups.

Thanks,
Paul.

 Documentation/powerpc/booting-without-of.txt |  252 ++++++
 arch/powerpc/Kconfig                         |   21 -
 arch/powerpc/boot/dts/mpc8272ads.dts         |  223 ++++++
 arch/powerpc/boot/dts/mpc8360emds.dts        |  375 ++++++++++
 arch/powerpc/boot/zImage.coff.lds.S          |    1 
 arch/powerpc/configs/mpc8360emds_defconfig   | 1018 ++++++++++++++++++++++++++
 arch/powerpc/kernel/cputable.c               |   15 
 arch/powerpc/kernel/entry_64.S               |   18 
 arch/powerpc/kernel/head_64.S                |   28 +
 arch/powerpc/kernel/misc_64.S                |   46 +
 arch/powerpc/kernel/pci_64.c                 |   58 +
 arch/powerpc/kernel/setup-common.c           |   25 -
 arch/powerpc/kernel/setup_32.c               |    8 
 arch/powerpc/kernel/setup_64.c               |   12 
 arch/powerpc/kernel/vmlinux.lds.S            |    8 
 arch/powerpc/mm/pgtable_64.c                 |   29 -
 arch/powerpc/mm/slb_low.S                    |    3 
 arch/powerpc/platforms/82xx/Kconfig          |   21 +
 arch/powerpc/platforms/82xx/Makefile         |    5 
 arch/powerpc/platforms/82xx/m82xx_pci.h      |   19 
 arch/powerpc/platforms/82xx/mpc82xx.c        |  111 +++
 arch/powerpc/platforms/82xx/mpc82xx_ads.c    |  661 +++++++++++++++++
 arch/powerpc/platforms/82xx/pq2ads.h         |   67 ++
 arch/powerpc/platforms/83xx/Kconfig          |   13 
 arch/powerpc/platforms/83xx/mpc832x_mds.c    |  215 +++++
 arch/powerpc/platforms/83xx/mpc832x_mds.h    |   19 
 arch/powerpc/platforms/83xx/mpc8360e_pb.c    |  219 ++++++
 arch/powerpc/platforms/cell/interrupt.c      |  235 ++++--
 arch/powerpc/platforms/cell/interrupt.h      |   97 ++
 arch/powerpc/platforms/cell/spider-pic.c     |    9 
 arch/powerpc/platforms/cell/spu_base.c       |   19 
 arch/powerpc/platforms/iseries/pci.c         |    8 
 arch/powerpc/platforms/iseries/setup.c       |   16 
 arch/powerpc/platforms/powermac/udbg_scc.c   |   14 
 arch/powerpc/platforms/pseries/setup.c       |    2 
 arch/powerpc/sysdev/Makefile                 |    1 
 arch/powerpc/sysdev/cpm2_pic.c               |    2 
 arch/powerpc/sysdev/cpm2_pic.h               |    2 
 arch/powerpc/sysdev/fsl_soc.c                |   62 +-
 arch/powerpc/sysdev/qe_lib/Kconfig           |   30 +
 arch/powerpc/sysdev/qe_lib/Makefile          |    8 
 arch/powerpc/sysdev/qe_lib/qe.c              |  353 +++++++++
 arch/powerpc/sysdev/qe_lib/qe_ic.c           |  555 ++++++++++++++
 arch/powerpc/sysdev/qe_lib/qe_ic.h           |  106 +++
 arch/powerpc/sysdev/qe_lib/qe_io.c           |  226 ++++++
 arch/powerpc/sysdev/qe_lib/ucc.c             |  251 ++++++
 arch/powerpc/sysdev/qe_lib/ucc_fast.c        |  396 ++++++++++
 arch/powerpc/sysdev/qe_lib/ucc_slow.c        |  404 ++++++++++
 arch/powerpc/xmon/xmon.c                     |   35 +
 drivers/block/swim3.c                        |    4 
 drivers/char/hvc_iseries.c                   |    8 
 drivers/char/hvc_vio.c                       |    4 
 include/asm-powerpc/firmware.h               |   67 +-
 include/asm-powerpc/immap_qe.h               |  477 ++++++++++++
 include/asm-powerpc/qe.h                     |  457 ++++++++++++
 include/asm-powerpc/qe_ic.h                  |   64 ++
 include/asm-powerpc/system.h                 |    4 
 include/asm-powerpc/ucc.h                    |   84 ++
 include/asm-powerpc/ucc_fast.h               |  243 ++++++
 include/asm-powerpc/ucc_slow.h               |  289 +++++++
 include/asm-powerpc/xmon.h                   |   26 -
 include/linux/fsl_devices.h                  |   65 +-
 62 files changed, 7809 insertions(+), 304 deletions(-)
 create mode 100644 arch/powerpc/boot/dts/mpc8272ads.dts
 create mode 100644 arch/powerpc/boot/dts/mpc8360emds.dts
 create mode 100644 arch/powerpc/configs/mpc8360emds_defconfig
 create mode 100644 arch/powerpc/platforms/82xx/Kconfig
 create mode 100644 arch/powerpc/platforms/82xx/Makefile
 create mode 100644 arch/powerpc/platforms/82xx/m82xx_pci.h
 create mode 100644 arch/powerpc/platforms/82xx/mpc82xx.c
 create mode 100644 arch/powerpc/platforms/82xx/mpc82xx_ads.c
 create mode 100644 arch/powerpc/platforms/82xx/pq2ads.h
 create mode 100644 arch/powerpc/platforms/83xx/mpc832x_mds.c
 create mode 100644 arch/powerpc/platforms/83xx/mpc832x_mds.h
 create mode 100644 arch/powerpc/platforms/83xx/mpc8360e_pb.c
 create mode 100644 arch/powerpc/sysdev/qe_lib/Kconfig
 create mode 100644 arch/powerpc/sysdev/qe_lib/Makefile
 create mode 100644 arch/powerpc/sysdev/qe_lib/qe.c
 create mode 100644 arch/powerpc/sysdev/qe_lib/qe_ic.c
 create mode 100644 arch/powerpc/sysdev/qe_lib/qe_ic.h
 create mode 100644 arch/powerpc/sysdev/qe_lib/qe_io.c
 create mode 100644 arch/powerpc/sysdev/qe_lib/ucc.c
 create mode 100644 arch/powerpc/sysdev/qe_lib/ucc_fast.c
 create mode 100644 arch/powerpc/sysdev/qe_lib/ucc_slow.c
 create mode 100644 include/asm-powerpc/immap_qe.h
 create mode 100644 include/asm-powerpc/qe.h
 create mode 100644 include/asm-powerpc/qe_ic.h
 create mode 100644 include/asm-powerpc/ucc.h
 create mode 100644 include/asm-powerpc/ucc_fast.h
 create mode 100644 include/asm-powerpc/ucc_slow.h

Benjamin Herrenschmidt:
      [POWERPC] Cell interrupt rework
      [POWERPC] Fix zImage.coff on oldworld PowerMac
      [POWERPC] Get default baud rate in udbg_scc

Kim Phillips:
      [POWERPC] Add initial support for the e300c2 core
      [POWERPC] Add support for the mpc832x mds board

Li Yang:
      [POWERPC] Add QE device tree node definition
      [POWERPC] Add QUICC Engine (QE) infrastructure
      [POWERPC] Add MPC8360EMDS board support
      [POWERPC] Add MPC8360EMDS default dts file

Michael Ellerman:
      [POWERPC] Cleanup include/asm-powerpc/xmon.h
      [POWERPC] Fix xmon=off and cleanup xmon initialisation
      [POWERPC] Fix a printk in pseries_mpic_init_IRQ

Olaf Hering:
      [POWERPC] Update swim3 printk after blkdev.h change

Paul Mackerras:
      [POWERPC] Don't try to just continue if xmon has no input device

Stephen Rothwell:
      [POWERPC] iSeries: set FW_FEATURE_ISERIES earlier
      [POWERPC] The two vio HVC backends clash
      [POWERPC] modify PCI code for a merged kernel
      [POWERPC] fix ioremap for a combined kernel
      [POWERPC] Allow combined iSeries and MULTIPLATFORM build
      [POWERPC] iSeries does not need pcibios_fixup_resources
      [POWERPC] implement BEGIN/END_FW_FTR_SECTION
      [POWERPC] iSeries has no legacy I/O

Vitaly Bordug:
      POWERPC: Added devicetree for mpc8272ads board
      POWERPC: 8272ads merge to powerpc: common stuff
      POWERPC: mpc82xx merge: board-specific/platform stuff(resend)

^ permalink raw reply

* Problem of "Connecting to BDI loader failed (-1201)"
From: Zhou Rui @ 2006-10-04 13:33 UTC (permalink / raw)
  To: linuxppc-dev

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

Hello,
I am a newbie for BDI2000. Today I tried to setup BDI2000 for PPC405EP PPChameleonEVB board. I did the initial setup based on the manual:
1. make (to compile the executable "bdisetup")
2. ./bdisetup -u -p/dev/ttyS0 -b57 -aGDB -tPPC400
3. ./bdisetup -c -p/dev/ttyS0 -b57 -i192.168.1.123 -h192.168.1.104 -m255.255.255.0 -g192.168.1.239 -foctobus.cfg
4. ./bdisetup -v -p/dev/ttyS0 -b57 -s
5. telnet 192.168.1.123
Then the telnet ran well. But after I quitted from telnet and tried to run "./bdisetup -v -p/dev/ttyS0 -b57", I got "Connecting to BDI loader failed (-1201)Connecting to BDI loader failed (-1201)". And I got the same results when I tried others parameters such as -u, -c, -e. So would anyone give me some advice about this? Thanks a lot.

Best wishes


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: 1109 bytes --]

^ permalink raw reply

* Re: [PATCH 10/11] Add MPC8360EMDS board support
From: Dan Malek @ 2006-10-04 13:53 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: Olof Johansson, linuxppc-dev
In-Reply-To: <17699.769.632098.479906@cargo.ozlabs.ibm.com>


On Oct 3, 2006, at 8:40 PM, Paul Mackerras wrote:

> ....   That means that ifdefs
> are evil, because they obfuscate the code....

This is not an #ifdefs discussion.  We've had those
discussions many years ago and have done many
things to eliminate that :-)

It's just a discussion about the purpose of placing
things that are quite static about a board port in
the board specific include file with a #define, rather
than trying to add it as a device tree node.

If I:
	#define MY_BOARD_BCSR 0xf00

and then,

	bcsr = ioremap(MY_BOARD_BCSR);

I think it's pretty clear what I'm doing.
In all of my experience, something like a BCSR
is quite board specific and I honestly don't
see any "generic BCSR code" that's going
to exist and actually take advantage of
representing this in a device tree.


> The device-tree concept offers a way to make drivers more readable and
> reusable, by separating out the board-specific configuration
> information (thus reducing ifdefs) and by encouraging the style of
> code that naturally copes with any number of device instances.

Again, it's not a discussion of #ifdefs.  Most of the
drivers we are discussing that take advantage of this
have long since been properly written to use board
specific information without them.  Initially, we just
used #defines in a board specific file, then we had
platform data, now we have device tree.  That "progress"
didn't make a driver any more readable or reusable,
it's just someone's personal preference for yet another
implementation to do the same thing.  The people with
the most time to waste on this are just able to push
that in over the rest of us that don't.

> How does the "internal memory map" differ from "everything addressable
> in the system"?

By quite a bit.  If you look at the Freescale SOC parts,
many have the very same or quite similar functional
units, they may just appear at different addresses
in the memory map for the different variants of
processor.  Again, proper use of #defines in a board
specific file or platform data solved this problem just
as nicely as device tree.  The real progress was using
the smaller addressable units individually rather than
dereference from the large structure.  The way we get
those addresses and information (#defines, platform
data, device tree) wasn't the enabler to this flexibility.

When you venture off the SOC, you not only have
board specific addresses, but also the register
format and even the logic to access these devices
varies greatly from one board to another.  Yeah,
the BCSR address and maybe something about its
size is in the device tree....BFD, what do I do with it?

As we have seen in some e-mail exchanges already,
people have tracking down "bugs" that eventually
ended up in an improper device tree configuration.
I don't see how this makes board ports any easier,
it's just a different way of representing the information
that has been needed all along.....  and adding
additional steps to the process.

> Leo Li had an interesting idea, which is a preprocessor that would
> take kernel code ...

Ummmm,  I'm going to pretend I didn't even hear this
suggestion :-)  Please, no, I really don't see any value
in this.  Talk about obfuscation......  At least I have a
chance at finding my way though #ifdefs :-)

I'm not against using the device tree (or platform data
or #defines) when it's appropriate to do so.  I think our
obsession to represent everything there is what is
creating the complexity.  If a #define in a board
specific port file makes sense, then just do that,
even if it is a BSCR address.  The device tree just
seems like the new toy that everyone wants to play
with, and we are forgetting that the old fashioned way
of just writing some C code may be the way
to implement what we need.

Thanks.

	-- Dan

^ permalink raw reply

* Re: [PATCH 10/11] Add MPC8360EMDS board support
From: Dan Malek @ 2006-10-04 14:48 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: Olof Johansson, linuxppc-dev, Paul Mackerras
In-Reply-To: <1159942128.13323.21.camel@localhost.localdomain>


On Oct 4, 2006, at 2:08 AM, Benjamin Herrenschmidt wrote:

> It's not that complex and the single binary is not necessarily the  
> main
> objective (it's a good practice as it enforce avoiding ugly #ifdef  
> hacks

Would you guys please get off of this #ifdefs discussion! :-)
That's not what this is about.

> There is fundamentally little difference between the OCP tables we had
> before and the device-tree.

Exactly!  So why has it become such a desire to represent
stuff in the device tree that was never necessary to represent
in other table formats before?

> The new device-tree model provides a more flexible and richer semantic
> for adding all sort of driver or BSP private infos, and for dealing  
> with
> address mapping and interrupt mapping.

Not really, we had all of this before.....  and in a way
that I didn't have to learn a new syntax to represent.

> When done right, it does simplify the matter. An example that I've  
> seen
> internally is embedded boards with all sorts of variety of dodgy
> interrupt controllers cascaded on each other.

Good example.  Cascaded interrupt controllers are always
a challenge.  :-)  It doesn't matter how you present the
information about their configuration if you don't have
the code written properly to manage them.  It's the
_code_ you write the solves the problem, not the
device tree.

> It simplifies the code, both on the driver and the platform side,

I don't see that.  If I look at drivers we've had around for
a while that have survived all of these evolutions, the
core of them hasn't changed one bit.  The initialization
functions have gone from simply stuffing an information
data structure with #defined board information to lengthy
process of performing (the once hated) OF searches
and conversion of information, to stuff into the data
structures.


> ....   doing so
> makes it simpler for your own code/driver to retreive informations  
> such
> as base addresses, interrupts (see above), and all sort of auxilliary
> infos you may which to pass to a given driver (MAC address, serial
> number, default clock, whatever).

It doesn't really make it any simpler for the driver, because
they have always retrieved that information in some way that
has been consistent, usually from the old board descriptor
or platform data.  The method of converting that information,
usually a concern of the boot rom or the boot wrapper or
compiled in, is what we are changing now.

> There is a great flexibility of putting whatever you want in  
> there... or
> not.

It's the 'or not' part that I am worried about.  Things like
you mention above make sense.  I'm starting to worry about
some of this other stuff, and the bscr example is what
woke me up :-)  I think that's an example of things that
should be considered not necessary.

> It's up to the embedded developper to use that tool, it can be used
> in a bloated way, or in a smart way, we aren't enforcing any direction
> here.

Not really.  To use a particular driver you are going to have
to provide the proper amount of information.  It's not up to
me as a consumer of something already written.  I can
only control that if I'm the developer of the code.

> I think you are a bit too dismissive here. The approach has always  
> been
> to provide the choice,

There isn't a choice.  If I want to use a particular driver
I have to provide the proper and necessary information
using a device tree, period.  If I want to change my
board design for some reason that is advantageous
to me, and the driver doesn't support it, no possible
convolution of device tree information is going to make
that happen.

> ...  is hopefully an easier way to create the BSP in the first place,

Sorry, but I don't see that.  You are either skilled at
creating a BSP or you are not.  The device tree just adds
another dimension of information in a syntax and structure
that you have to learn.

> .... The -ability- to build multi-board
> kernels is made mandatory for code to be merged upstream,

Why?  When are people going to realize that the
ratio of Linux on custom embedded systems to a standard
workstation is about a million to one?  So what if I
can boot the same kernel on a couple of obsolete
PowerPC workstations using drivers that aren't used
anywhere else?  Or, on a couple of embedded eval
boards that don't represent how people build products?
Hell, I tried to build an x86 kernel the other day
for a PC and still don't have one that boots.  I can't
seem to figure out what processor configuration
options or compiler options to use.  Linux doesn't
even support this on a "standard" PC. :-)

> ... as it enforces
> a certain level of quality,

That's BS and you know it :-)


> ....  In fact, you client may be happy, once it's done rev 3 of the
> board with a 3rd type of wifi chip or a 2nd type of ethernet HUB to  
> have
> the ability to easily build, maintain, distribute and test a single
> kernel image,

That's not very important.  For high volume products that
are already in the field, the way the binary image is created
or if they need different ones on different versions, isn't
important.  The whole process of tracking, testing, distributing,
installing, upgrading, reverting makes our development
tools insignificant to them.  All that is desired is an image
that when upgraded doesn't turn a million boxes into
bricks.  If it does, our cleverness to use a device tree to
support multiple boards better not be the problem, because
if it is it will never be used again.

Thanks.

	-- Dan

^ permalink raw reply

* Re: [PATCH 10/11] Add MPC8360EMDS board support
From: Dan Malek @ 2006-10-04 14:57 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <1159941148.13323.6.camel@localhost.localdomain>


On Oct 4, 2006, at 1:52 AM, Benjamin Herrenschmidt wrote:

> I don't see how a mecanism of feature call at the board support  
> level is
> in any way incompatible with the device-tree thing.

It isn't.

> ...  I'm happy mixing
> both on powermac :)

I know.  This was just an opportunity to make people
realize that a board port does require the writing of
some board specific code.  Using the feature call is
an excellent model of portability and flexibility.  My
point was that any BCSR access is necessary to be
hidden behind such a function, because it is truly
board specific.  You can't require the drivers to
have this kind of logic in them, they must call out
to board support functions for assistance.

Just like the powermac ports, embedded drivers
will need a feature call at some points during
their processing (set up clock routing, IO pin
configuration, board specific bus connections,
power management, etc).  Some board ports
may do nothing, others may do lots of work.

Therefore, I see no reason why a BSCR address
and all of it's associated format can't simply
be a #define in a board specific file.  There is no
need for this in the device tree.


	-- Dan

^ permalink raw reply

* [PATCH 00/14] spufs/cell updates for 2.6.19
From: Arnd Bergmann @ 2006-10-04 15:26 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev, cbe-oss-dev, linux-kernel

I've finally updated the important patches for spufs to the powerpc.git
master branch. These include a number of changes to spufs, some of
which have been pending for a long time now.

Please merge them into 2.6.19.

	Arnd <><

--

^ permalink raw reply

* [PATCH 01/14] spufs: cell spu problem state mapping updates
From: Arnd Bergmann @ 2006-10-04 15:26 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: Arnd Bergmann, linuxppc-dev, cbe-oss-dev, linux-kernel
In-Reply-To: <20061004152610.151599000@dyn-9-152-242-103.boeblingen.de.ibm.com>

From: Benjamin Herrenschmidt <benh@kernel.crashing.org>

This patch adds a new "psmap" file to spufs that allows mmap of all of
the problem state mapping of SPEs. It is compatible with 64k pages. In
addition, it removes mmap ability of individual files when using 64k
pages, with the exception of signal1 and signal2 which will both map the
entire 64k page holding both registers. It also removes
CONFIG_SPUFS_MMAP as there is no point in not building mmap support in
spufs.

It goes along a separate patch to libspe implementing usage of that new
file to access problem state registers.

Another patch will follow up to fix races opened up by accessing
the 'runcntl' register directly, which is made possible with this
patch.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>

Index: linux-2.6/arch/powerpc/platforms/cell/spufs/file.c
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/cell/spufs/file.c
+++ linux-2.6/arch/powerpc/platforms/cell/spufs/file.c
@@ -36,6 +36,8 @@
 
 #include "spufs.h"
 
+#define SPUFS_MMAP_4K (PAGE_SIZE == 0x1000)
+
 
 static int
 spufs_mem_open(struct inode *inode, struct file *file)
@@ -88,7 +90,6 @@ spufs_mem_write(struct file *file, const
 	return ret;
 }
 
-#ifdef CONFIG_SPUFS_MMAP
 static struct page *
 spufs_mem_mmap_nopage(struct vm_area_struct *vma,
 		      unsigned long address, int *type)
@@ -133,22 +134,19 @@ spufs_mem_mmap(struct file *file, struct
 	vma->vm_ops = &spufs_mem_mmap_vmops;
 	return 0;
 }
-#endif
 
 static struct file_operations spufs_mem_fops = {
 	.open	 = spufs_mem_open,
 	.read    = spufs_mem_read,
 	.write   = spufs_mem_write,
 	.llseek  = generic_file_llseek,
-#ifdef CONFIG_SPUFS_MMAP
 	.mmap    = spufs_mem_mmap,
-#endif
 };
 
-#ifdef CONFIG_SPUFS_MMAP
 static struct page *spufs_ps_nopage(struct vm_area_struct *vma,
 				    unsigned long address,
-				    int *type, unsigned long ps_offs)
+				    int *type, unsigned long ps_offs,
+				    unsigned long ps_size)
 {
 	struct page *page = NOPAGE_SIGBUS;
 	int fault_type = VM_FAULT_SIGBUS;
@@ -158,7 +156,7 @@ static struct page *spufs_ps_nopage(stru
 	int ret;
 
 	offset += vma->vm_pgoff << PAGE_SHIFT;
-	if (offset >= 0x4000)
+	if (offset >= ps_size)
 		goto out;
 
 	ret = spu_acquire_runnable(ctx);
@@ -179,10 +177,11 @@ static struct page *spufs_ps_nopage(stru
 	return page;
 }
 
+#if SPUFS_MMAP_4K
 static struct page *spufs_cntl_mmap_nopage(struct vm_area_struct *vma,
 					   unsigned long address, int *type)
 {
-	return spufs_ps_nopage(vma, address, type, 0x4000);
+	return spufs_ps_nopage(vma, address, type, 0x4000, 0x1000);
 }
 
 static struct vm_operations_struct spufs_cntl_mmap_vmops = {
@@ -191,17 +190,12 @@ static struct vm_operations_struct spufs
 
 /*
  * mmap support for problem state control area [0x4000 - 0x4fff].
- * Mapping this area requires that the application have CAP_SYS_RAWIO,
- * as these registers require special care when read/writing.
  */
 static int spufs_cntl_mmap(struct file *file, struct vm_area_struct *vma)
 {
 	if (!(vma->vm_flags & VM_SHARED))
 		return -EINVAL;
 
-	if (!capable(CAP_SYS_RAWIO))
-		return -EPERM;
-
 	vma->vm_flags |= VM_RESERVED;
 	vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
 				     | _PAGE_NO_CACHE | _PAGE_GUARDED);
@@ -209,7 +203,9 @@ static int spufs_cntl_mmap(struct file *
 	vma->vm_ops = &spufs_cntl_mmap_vmops;
 	return 0;
 }
-#endif
+#else /* SPUFS_MMAP_4K */
+#define spufs_cntl_mmap NULL
+#endif /* !SPUFS_MMAP_4K */
 
 static int spufs_cntl_open(struct inode *inode, struct file *file)
 {
@@ -242,9 +238,7 @@ static struct file_operations spufs_cntl
 	.open = spufs_cntl_open,
 	.read = spufs_cntl_read,
 	.write = spufs_cntl_write,
-#ifdef CONFIG_SPUFS_MMAP
 	.mmap = spufs_cntl_mmap,
-#endif
 };
 
 static int
@@ -657,11 +651,19 @@ static ssize_t spufs_signal1_write(struc
 	return 4;
 }
 
-#ifdef CONFIG_SPUFS_MMAP
 static struct page *spufs_signal1_mmap_nopage(struct vm_area_struct *vma,
 					      unsigned long address, int *type)
 {
-	return spufs_ps_nopage(vma, address, type, 0x14000);
+#if PAGE_SIZE == 0x1000
+	return spufs_ps_nopage(vma, address, type, 0x14000, 0x1000);
+#elif PAGE_SIZE == 0x10000
+	/* For 64k pages, both signal1 and signal2 can be used to mmap the whole
+	 * signal 1 and 2 area
+	 */
+	return spufs_ps_nopage(vma, address, type, 0x10000, 0x10000);
+#else
+#error unsupported page size
+#endif
 }
 
 static struct vm_operations_struct spufs_signal1_mmap_vmops = {
@@ -680,15 +682,12 @@ static int spufs_signal1_mmap(struct fil
 	vma->vm_ops = &spufs_signal1_mmap_vmops;
 	return 0;
 }
-#endif
 
 static struct file_operations spufs_signal1_fops = {
 	.open = spufs_signal1_open,
 	.read = spufs_signal1_read,
 	.write = spufs_signal1_write,
-#ifdef CONFIG_SPUFS_MMAP
 	.mmap = spufs_signal1_mmap,
-#endif
 };
 
 static int spufs_signal2_open(struct inode *inode, struct file *file)
@@ -743,11 +742,20 @@ static ssize_t spufs_signal2_write(struc
 	return 4;
 }
 
-#ifdef CONFIG_SPUFS_MMAP
+#if SPUFS_MMAP_4K
 static struct page *spufs_signal2_mmap_nopage(struct vm_area_struct *vma,
 					      unsigned long address, int *type)
 {
-	return spufs_ps_nopage(vma, address, type, 0x1c000);
+#if PAGE_SIZE == 0x1000
+	return spufs_ps_nopage(vma, address, type, 0x1c000, 0x1000);
+#elif PAGE_SIZE == 0x10000
+	/* For 64k pages, both signal1 and signal2 can be used to mmap the whole
+	 * signal 1 and 2 area
+	 */
+	return spufs_ps_nopage(vma, address, type, 0x10000, 0x10000);
+#else
+#error unsupported page size
+#endif
 }
 
 static struct vm_operations_struct spufs_signal2_mmap_vmops = {
@@ -767,15 +775,15 @@ static int spufs_signal2_mmap(struct fil
 	vma->vm_ops = &spufs_signal2_mmap_vmops;
 	return 0;
 }
-#endif
+#else /* SPUFS_MMAP_4K */
+#define spufs_signal2_mmap NULL
+#endif /* !SPUFS_MMAP_4K */
 
 static struct file_operations spufs_signal2_fops = {
 	.open = spufs_signal2_open,
 	.read = spufs_signal2_read,
 	.write = spufs_signal2_write,
-#ifdef CONFIG_SPUFS_MMAP
 	.mmap = spufs_signal2_mmap,
-#endif
 };
 
 static void spufs_signal1_type_set(void *data, u64 val)
@@ -824,11 +832,11 @@ static u64 spufs_signal2_type_get(void *
 DEFINE_SIMPLE_ATTRIBUTE(spufs_signal2_type, spufs_signal2_type_get,
 					spufs_signal2_type_set, "%llu");
 
-#ifdef CONFIG_SPUFS_MMAP
+#if SPUFS_MMAP_4K
 static struct page *spufs_mss_mmap_nopage(struct vm_area_struct *vma,
 					   unsigned long address, int *type)
 {
-	return spufs_ps_nopage(vma, address, type, 0x0000);
+	return spufs_ps_nopage(vma, address, type, 0x0000, 0x1000);
 }
 
 static struct vm_operations_struct spufs_mss_mmap_vmops = {
@@ -837,17 +845,12 @@ static struct vm_operations_struct spufs
 
 /*
  * mmap support for problem state MFC DMA area [0x0000 - 0x0fff].
- * Mapping this area requires that the application have CAP_SYS_RAWIO,
- * as these registers require special care when read/writing.
  */
 static int spufs_mss_mmap(struct file *file, struct vm_area_struct *vma)
 {
 	if (!(vma->vm_flags & VM_SHARED))
 		return -EINVAL;
 
-	if (!capable(CAP_SYS_RAWIO))
-		return -EPERM;
-
 	vma->vm_flags |= VM_RESERVED;
 	vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
 				     | _PAGE_NO_CACHE | _PAGE_GUARDED);
@@ -855,7 +858,9 @@ static int spufs_mss_mmap(struct file *f
 	vma->vm_ops = &spufs_mss_mmap_vmops;
 	return 0;
 }
-#endif
+#else /* SPUFS_MMAP_4K */
+#define spufs_mss_mmap NULL
+#endif /* !SPUFS_MMAP_4K */
 
 static int spufs_mss_open(struct inode *inode, struct file *file)
 {
@@ -867,17 +872,54 @@ static int spufs_mss_open(struct inode *
 
 static struct file_operations spufs_mss_fops = {
 	.open	 = spufs_mss_open,
-#ifdef CONFIG_SPUFS_MMAP
 	.mmap	 = spufs_mss_mmap,
-#endif
+};
+
+static struct page *spufs_psmap_mmap_nopage(struct vm_area_struct *vma,
+					   unsigned long address, int *type)
+{
+	return spufs_ps_nopage(vma, address, type, 0x0000, 0x20000);
+}
+
+static struct vm_operations_struct spufs_psmap_mmap_vmops = {
+	.nopage = spufs_psmap_mmap_nopage,
+};
+
+/*
+ * mmap support for full problem state area [0x00000 - 0x1ffff].
+ */
+static int spufs_psmap_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	if (!(vma->vm_flags & VM_SHARED))
+		return -EINVAL;
+
+	vma->vm_flags |= VM_RESERVED;
+	vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
+				     | _PAGE_NO_CACHE | _PAGE_GUARDED);
+
+	vma->vm_ops = &spufs_psmap_mmap_vmops;
+	return 0;
+}
+
+static int spufs_psmap_open(struct inode *inode, struct file *file)
+{
+	struct spufs_inode_info *i = SPUFS_I(inode);
+
+	file->private_data = i->i_ctx;
+	return nonseekable_open(inode, file);
+}
+
+static struct file_operations spufs_psmap_fops = {
+	.open	 = spufs_psmap_open,
+	.mmap	 = spufs_psmap_mmap,
 };
 
 
-#ifdef CONFIG_SPUFS_MMAP
+#if SPUFS_MMAP_4K
 static struct page *spufs_mfc_mmap_nopage(struct vm_area_struct *vma,
 					   unsigned long address, int *type)
 {
-	return spufs_ps_nopage(vma, address, type, 0x3000);
+	return spufs_ps_nopage(vma, address, type, 0x3000, 0x1000);
 }
 
 static struct vm_operations_struct spufs_mfc_mmap_vmops = {
@@ -886,17 +928,12 @@ static struct vm_operations_struct spufs
 
 /*
  * mmap support for problem state MFC DMA area [0x0000 - 0x0fff].
- * Mapping this area requires that the application have CAP_SYS_RAWIO,
- * as these registers require special care when read/writing.
  */
 static int spufs_mfc_mmap(struct file *file, struct vm_area_struct *vma)
 {
 	if (!(vma->vm_flags & VM_SHARED))
 		return -EINVAL;
 
-	if (!capable(CAP_SYS_RAWIO))
-		return -EPERM;
-
 	vma->vm_flags |= VM_RESERVED;
 	vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
 				     | _PAGE_NO_CACHE | _PAGE_GUARDED);
@@ -904,7 +941,9 @@ static int spufs_mfc_mmap(struct file *f
 	vma->vm_ops = &spufs_mfc_mmap_vmops;
 	return 0;
 }
-#endif
+#else /* SPUFS_MMAP_4K */
+#define spufs_mfc_mmap NULL
+#endif /* !SPUFS_MMAP_4K */
 
 static int spufs_mfc_open(struct inode *inode, struct file *file)
 {
@@ -1194,9 +1233,7 @@ static struct file_operations spufs_mfc_
 	.flush	 = spufs_mfc_flush,
 	.fsync	 = spufs_mfc_fsync,
 	.fasync	 = spufs_mfc_fasync,
-#ifdef CONFIG_SPUFS_MMAP
 	.mmap	 = spufs_mfc_mmap,
-#endif
 };
 
 static void spufs_npc_set(void *data, u64 val)
@@ -1368,5 +1405,6 @@ struct tree_descr spufs_dir_contents[] =
 	{ "event_mask", &spufs_event_mask_ops, 0666, },
 	{ "srr0", &spufs_srr0_ops, 0666, },
 	{ "phys-id", &spufs_id_ops, 0666, },
+	{ "psmap", &spufs_psmap_fops, 0666, },
 	{},
 };
Index: linux-2.6/arch/powerpc/platforms/cell/Kconfig
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/cell/Kconfig
+++ linux-2.6/arch/powerpc/platforms/cell/Kconfig
@@ -16,11 +16,6 @@ config SPU_BASE
 	bool
 	default n
 
-config SPUFS_MMAP
-	bool
-	depends on SPU_FS && SPARSEMEM
-	default y
-
 config CBE_RAS
 	bool "RAS features for bare metal Cell BE"
 	default y

--

^ permalink raw reply

* [PATCH 02/14] spufs: scheduler support for NUMA.
From: Arnd Bergmann @ 2006-10-04 15:26 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: Arnd Bergmann, linuxppc-dev, cbe-oss-dev, linux-kernel
In-Reply-To: <20061004152610.151599000@dyn-9-152-242-103.boeblingen.de.ibm.com>

From: Mark Nutter <mnutter@us.ibm.com>

This patch adds NUMA support to the the spufs scheduler.

The new arch/powerpc/platforms/cell/spufs/sched.c is greatly
simplified, in an attempt to reduce complexity while adding
support for NUMA scheduler domains.  SPUs are allocated starting 
from the calling thread's node, moving to others as supported by 
current->cpus_allowed.  Preemption is gone as it was buggy, but 
should be re-enabled in another patch when stable.

The new arch/powerpc/platforms/cell/spu_base.c maintains idle 
lists on a per-node basis, and allows caller to specify which
node(s) an SPU should be allocated from, while passing -1 tells
spu_alloc() that any node is allowed.

Since the patch removes the currently implemented preemptive
scheduling, it is technically a regression, but practically
all users have since migrated to this version, as it is
part of the IBM SDK and the yellowdog distribution, so there
is not much point holding it back while the new preemptive
scheduling patch gets delayed further.

Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>

Index: linux-2.6/arch/powerpc/platforms/cell/spu_base.c
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/cell/spu_base.c
+++ linux-2.6/arch/powerpc/platforms/cell/spu_base.c
@@ -317,7 +317,7 @@ static void spu_free_irqs(struct spu *sp
 		free_irq(spu->irqs[2], spu);
 }
 
-static LIST_HEAD(spu_list);
+static struct list_head spu_list[MAX_NUMNODES];
 static DEFINE_MUTEX(spu_mutex);
 
 static void spu_init_channels(struct spu *spu)
@@ -354,32 +354,42 @@ static void spu_init_channels(struct spu
 	}
 }
 
-struct spu *spu_alloc(void)
+struct spu *spu_alloc_node(int node)
 {
-	struct spu *spu;
+	struct spu *spu = NULL;
 
 	mutex_lock(&spu_mutex);
-	if (!list_empty(&spu_list)) {
-		spu = list_entry(spu_list.next, struct spu, list);
+	if (!list_empty(&spu_list[node])) {
+		spu = list_entry(spu_list[node].next, struct spu, list);
 		list_del_init(&spu->list);
-		pr_debug("Got SPU %x %d\n", spu->isrc, spu->number);
-	} else {
-		pr_debug("No SPU left\n");
-		spu = NULL;
+		pr_debug("Got SPU %x %d %d\n",
+			 spu->isrc, spu->number, spu->node);
+		spu_init_channels(spu);
 	}
 	mutex_unlock(&spu_mutex);
 
-	if (spu)
-		spu_init_channels(spu);
+	return spu;
+}
+EXPORT_SYMBOL_GPL(spu_alloc_node);
+
+struct spu *spu_alloc(void)
+{
+	struct spu *spu = NULL;
+	int node;
+
+	for (node = 0; node < MAX_NUMNODES; node++) {
+		spu = spu_alloc_node(node);
+		if (spu)
+			break;
+	}
 
 	return spu;
 }
-EXPORT_SYMBOL_GPL(spu_alloc);
 
 void spu_free(struct spu *spu)
 {
 	mutex_lock(&spu_mutex);
-	list_add_tail(&spu->list, &spu_list);
+	list_add_tail(&spu->list, &spu_list[spu->node]);
 	mutex_unlock(&spu_mutex);
 }
 EXPORT_SYMBOL_GPL(spu_free);
@@ -712,7 +722,7 @@ static int __init create_spu(struct devi
 	if (ret)
 		goto out_free_irqs;
 
-	list_add(&spu->list, &spu_list);
+	list_add(&spu->list, &spu_list[spu->node]);
 	mutex_unlock(&spu_mutex);
 
 	pr_debug(KERN_DEBUG "Using SPE %s %02x %p %p %p %p %d\n",
@@ -745,9 +755,13 @@ static void destroy_spu(struct spu *spu)
 static void cleanup_spu_base(void)
 {
 	struct spu *spu, *tmp;
+	int node;
+
 	mutex_lock(&spu_mutex);
-	list_for_each_entry_safe(spu, tmp, &spu_list, list)
-		destroy_spu(spu);
+	for (node = 0; node < MAX_NUMNODES; node++) {
+		list_for_each_entry_safe(spu, tmp, &spu_list[node], list)
+			destroy_spu(spu);
+	}
 	mutex_unlock(&spu_mutex);
 	sysdev_class_unregister(&spu_sysdev_class);
 }
@@ -756,13 +770,16 @@ module_exit(cleanup_spu_base);
 static int __init init_spu_base(void)
 {
 	struct device_node *node;
-	int ret;
+	int i, ret;
 
 	/* create sysdev class for spus */
 	ret = sysdev_class_register(&spu_sysdev_class);
 	if (ret)
 		return ret;
 
+	for (i = 0; i < MAX_NUMNODES; i++)
+		INIT_LIST_HEAD(&spu_list[i]);
+
 	ret = -ENODEV;
 	for (node = of_find_node_by_type(NULL, "spe");
 			node; node = of_find_node_by_type(node, "spe")) {
Index: linux-2.6/arch/powerpc/platforms/cell/spufs/sched.c
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/cell/spufs/sched.c
+++ linux-2.6/arch/powerpc/platforms/cell/spufs/sched.c
@@ -3,11 +3,7 @@
  * Copyright (C) IBM 2005
  * Author: Mark Nutter <mnutter@us.ibm.com>
  *
- * SPU scheduler, based on Linux thread priority.  For now use
- * a simple "cooperative" yield model with no preemption.  SPU
- * scheduling will eventually be preemptive: When a thread with
- * a higher static priority gets ready to run, then an active SPU
- * context will be preempted and returned to the waitq.
+ * 2006-03-31	NUMA domains added.
  *
  * 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
@@ -37,6 +33,8 @@
 #include <linux/smp_lock.h>
 #include <linux/stddef.h>
 #include <linux/unistd.h>
+#include <linux/numa.h>
+#include <linux/mutex.h>
 
 #include <asm/io.h>
 #include <asm/mmu_context.h>
@@ -49,125 +47,38 @@
 
 #define SPU_BITMAP_SIZE (((MAX_PRIO+BITS_PER_LONG)/BITS_PER_LONG)+1)
 struct spu_prio_array {
-	atomic_t nr_blocked;
 	unsigned long bitmap[SPU_BITMAP_SIZE];
 	wait_queue_head_t waitq[MAX_PRIO];
+	struct list_head active_list[MAX_NUMNODES];
+	struct mutex active_mutex[MAX_NUMNODES];
 };
 
-/* spu_runqueue - This is the main runqueue data structure for SPUs. */
-struct spu_runqueue {
-	struct semaphore sem;
-	unsigned long nr_active;
-	unsigned long nr_idle;
-	unsigned long nr_switches;
-	struct list_head active_list;
-	struct list_head idle_list;
-	struct spu_prio_array prio;
-};
-
-static struct spu_runqueue *spu_runqueues = NULL;
-
-static inline struct spu_runqueue *spu_rq(void)
-{
-	/* Future: make this a per-NODE array,
-	 * and use cpu_to_node(smp_processor_id())
-	 */
-	return spu_runqueues;
-}
-
-static inline struct spu *del_idle(struct spu_runqueue *rq)
-{
-	struct spu *spu;
-
-	BUG_ON(rq->nr_idle <= 0);
-	BUG_ON(list_empty(&rq->idle_list));
-	/* Future: Move SPU out of low-power SRI state. */
-	spu = list_entry(rq->idle_list.next, struct spu, sched_list);
-	list_del_init(&spu->sched_list);
-	rq->nr_idle--;
-	return spu;
-}
-
-static inline void del_active(struct spu_runqueue *rq, struct spu *spu)
-{
-	BUG_ON(rq->nr_active <= 0);
-	BUG_ON(list_empty(&rq->active_list));
-	list_del_init(&spu->sched_list);
-	rq->nr_active--;
-}
-
-static inline void add_idle(struct spu_runqueue *rq, struct spu *spu)
-{
-	/* Future: Put SPU into low-power SRI state. */
-	list_add_tail(&spu->sched_list, &rq->idle_list);
-	rq->nr_idle++;
-}
-
-static inline void add_active(struct spu_runqueue *rq, struct spu *spu)
-{
-	rq->nr_active++;
-	rq->nr_switches++;
-	list_add_tail(&spu->sched_list, &rq->active_list);
-}
-
-static void prio_wakeup(struct spu_runqueue *rq)
-{
-	if (atomic_read(&rq->prio.nr_blocked) && rq->nr_idle) {
-		int best = sched_find_first_bit(rq->prio.bitmap);
-		if (best < MAX_PRIO) {
-			wait_queue_head_t *wq = &rq->prio.waitq[best];
-			wake_up_interruptible_nr(wq, 1);
-		}
-	}
-}
-
-static void prio_wait(struct spu_runqueue *rq, struct spu_context *ctx,
-		      u64 flags)
-{
-	int prio = current->prio;
-	wait_queue_head_t *wq = &rq->prio.waitq[prio];
-	DEFINE_WAIT(wait);
-
-	__set_bit(prio, rq->prio.bitmap);
-	atomic_inc(&rq->prio.nr_blocked);
-	prepare_to_wait_exclusive(wq, &wait, TASK_INTERRUPTIBLE);
-	if (!signal_pending(current)) {
-		up(&rq->sem);
-		up_write(&ctx->state_sema);
-		pr_debug("%s: pid=%d prio=%d\n", __FUNCTION__,
-			 current->pid, current->prio);
-		schedule();
-		down_write(&ctx->state_sema);
-		down(&rq->sem);
-	}
-	finish_wait(wq, &wait);
-	atomic_dec(&rq->prio.nr_blocked);
-	if (!waitqueue_active(wq))
-		__clear_bit(prio, rq->prio.bitmap);
-}
+static struct spu_prio_array *spu_prio;
 
-static inline int is_best_prio(struct spu_runqueue *rq)
+static inline int node_allowed(int node)
 {
-	int best_prio;
+	cpumask_t mask;
 
-	best_prio = sched_find_first_bit(rq->prio.bitmap);
-	return (current->prio < best_prio) ? 1 : 0;
+	if (!nr_cpus_node(node))
+		return 0;
+	mask = node_to_cpumask(node);
+	if (!cpus_intersects(mask, current->cpus_allowed))
+		return 0;
+	return 1;
 }
 
 static inline void mm_needs_global_tlbie(struct mm_struct *mm)
 {
+	int nr = (NR_CPUS > 1) ? NR_CPUS : NR_CPUS + 1;
+
 	/* Global TLBIE broadcast required with SPEs. */
-#if (NR_CPUS > 1)
-	__cpus_setall(&mm->cpu_vm_mask, NR_CPUS);
-#else
-	__cpus_setall(&mm->cpu_vm_mask, NR_CPUS+1); /* is this ok? */
-#endif
+	__cpus_setall(&mm->cpu_vm_mask, nr);
 }
 
 static inline void bind_context(struct spu *spu, struct spu_context *ctx)
 {
-	pr_debug("%s: pid=%d SPU=%d\n", __FUNCTION__, current->pid,
-		 spu->number);
+	pr_debug("%s: pid=%d SPU=%d NODE=%d\n", __FUNCTION__, current->pid,
+		 spu->number, spu->node);
 	spu->ctx = ctx;
 	spu->flags = 0;
 	ctx->flags = 0;
@@ -185,12 +96,13 @@ static inline void bind_context(struct s
 	spu_unmap_mappings(ctx);
 	spu_restore(&ctx->csa, spu);
 	spu->timestamp = jiffies;
+	spu_cpu_affinity_set(spu, raw_smp_processor_id());
 }
 
 static inline void unbind_context(struct spu *spu, struct spu_context *ctx)
 {
-	pr_debug("%s: unbind pid=%d SPU=%d\n", __FUNCTION__,
-		 spu->pid, spu->number);
+	pr_debug("%s: unbind pid=%d SPU=%d NODE=%d\n", __FUNCTION__,
+		 spu->pid, spu->number, spu->node);
 	spu_unmap_mappings(ctx);
 	spu_save(&ctx->csa, spu);
 	spu->timestamp = jiffies;
@@ -209,163 +121,148 @@ static inline void unbind_context(struct
 	spu->ctx = NULL;
 }
 
-static void spu_reaper(void *data)
+static inline void spu_add_wq(wait_queue_head_t * wq, wait_queue_t * wait,
+			      int prio)
 {
-	struct spu_context *ctx = data;
-	struct spu *spu;
-
-	down_write(&ctx->state_sema);
-	spu = ctx->spu;
-	if (spu && test_bit(SPU_CONTEXT_PREEMPT, &ctx->flags)) {
-		if (atomic_read(&spu->rq->prio.nr_blocked)) {
-			pr_debug("%s: spu=%d\n", __func__, spu->number);
-			ctx->ops->runcntl_stop(ctx);
-			spu_deactivate(ctx);
-			wake_up_all(&ctx->stop_wq);
-		} else {
-			clear_bit(SPU_CONTEXT_PREEMPT, &ctx->flags);
-		}
-	}
-	up_write(&ctx->state_sema);
-	put_spu_context(ctx);
+	prepare_to_wait_exclusive(wq, wait, TASK_INTERRUPTIBLE);
+	set_bit(prio, spu_prio->bitmap);
 }
 
-static void schedule_spu_reaper(struct spu_runqueue *rq, struct spu *spu)
+static inline void spu_del_wq(wait_queue_head_t * wq, wait_queue_t * wait,
+			      int prio)
 {
-	struct spu_context *ctx = get_spu_context(spu->ctx);
-	unsigned long now = jiffies;
-	unsigned long expire = spu->timestamp + SPU_MIN_TIMESLICE;
+	u64 flags;
 
-	set_bit(SPU_CONTEXT_PREEMPT, &ctx->flags);
-	INIT_WORK(&ctx->reap_work, spu_reaper, ctx);
-	if (time_after(now, expire))
-		schedule_work(&ctx->reap_work);
-	else
-		schedule_delayed_work(&ctx->reap_work, expire - now);
-}
+	__set_current_state(TASK_RUNNING);
 
-static void check_preempt_active(struct spu_runqueue *rq)
-{
-	struct list_head *p;
-	struct spu *worst = NULL;
+	spin_lock_irqsave(&wq->lock, flags);
 
-	list_for_each(p, &rq->active_list) {
-		struct spu *spu = list_entry(p, struct spu, sched_list);
-		struct spu_context *ctx = spu->ctx;
-		if (!test_bit(SPU_CONTEXT_PREEMPT, &ctx->flags)) {
-			if (!worst || (spu->prio > worst->prio)) {
-				worst = spu;
-			}
-		}
-	}
-	if (worst && (current->prio < worst->prio))
-		schedule_spu_reaper(rq, worst);
+	remove_wait_queue_locked(wq, wait);
+	if (list_empty(&wq->task_list))
+		clear_bit(prio, spu_prio->bitmap);
+
+	spin_unlock_irqrestore(&wq->lock, flags);
 }
 
-static struct spu *get_idle_spu(struct spu_context *ctx, u64 flags)
+static void spu_prio_wait(struct spu_context *ctx, u64 flags)
 {
-	struct spu_runqueue *rq;
-	struct spu *spu = NULL;
+	int prio = current->prio;
+	wait_queue_head_t *wq = &spu_prio->waitq[prio];
+	DEFINE_WAIT(wait);
 
-	rq = spu_rq();
-	down(&rq->sem);
-	for (;;) {
-		if (rq->nr_idle > 0) {
-			if (is_best_prio(rq)) {
-				/* Fall through. */
-				spu = del_idle(rq);
-				break;
-			} else {
-				prio_wakeup(rq);
-				up(&rq->sem);
-				yield();
-				if (signal_pending(current)) {
-					return NULL;
-				}
-				rq = spu_rq();
-				down(&rq->sem);
-				continue;
-			}
-		} else {
-			check_preempt_active(rq);
-			prio_wait(rq, ctx, flags);
-			if (signal_pending(current)) {
-				prio_wakeup(rq);
-				spu = NULL;
-				break;
-			}
-			continue;
-		}
+	if (ctx->spu)
+		return;
+
+	spu_add_wq(wq, &wait, prio);
+
+	if (!signal_pending(current)) {
+		up_write(&ctx->state_sema);
+		pr_debug("%s: pid=%d prio=%d\n", __FUNCTION__,
+			 current->pid, current->prio);
+		schedule();
+		down_write(&ctx->state_sema);
 	}
-	up(&rq->sem);
-	return spu;
+
+	spu_del_wq(wq, &wait, prio);
 }
 
-static void put_idle_spu(struct spu *spu)
+static void spu_prio_wakeup(void)
 {
-	struct spu_runqueue *rq = spu->rq;
-
-	down(&rq->sem);
-	add_idle(rq, spu);
-	prio_wakeup(rq);
-	up(&rq->sem);
+	int best = sched_find_first_bit(spu_prio->bitmap);
+	if (best < MAX_PRIO) {
+		wait_queue_head_t *wq = &spu_prio->waitq[best];
+		wake_up_interruptible_nr(wq, 1);
+	}
 }
 
 static int get_active_spu(struct spu *spu)
 {
-	struct spu_runqueue *rq = spu->rq;
-	struct list_head *p;
+	int node = spu->node;
 	struct spu *tmp;
 	int rc = 0;
 
-	down(&rq->sem);
-	list_for_each(p, &rq->active_list) {
-		tmp = list_entry(p, struct spu, sched_list);
+	mutex_lock(&spu_prio->active_mutex[node]);
+	list_for_each_entry(tmp, &spu_prio->active_list[node], list) {
 		if (tmp == spu) {
-			del_active(rq, spu);
+			list_del_init(&spu->list);
 			rc = 1;
 			break;
 		}
 	}
-	up(&rq->sem);
+	mutex_unlock(&spu_prio->active_mutex[node]);
 	return rc;
 }
 
 static void put_active_spu(struct spu *spu)
 {
-	struct spu_runqueue *rq = spu->rq;
+	int node = spu->node;
 
-	down(&rq->sem);
-	add_active(rq, spu);
-	up(&rq->sem);
+	mutex_lock(&spu_prio->active_mutex[node]);
+	list_add_tail(&spu->list, &spu_prio->active_list[node]);
+	mutex_unlock(&spu_prio->active_mutex[node]);
 }
 
-/* Lock order:
- *	spu_activate() & spu_deactivate() require the
- *	caller to have down_write(&ctx->state_sema).
+static struct spu *spu_get_idle(struct spu_context *ctx, u64 flags)
+{
+	struct spu *spu = NULL;
+	int node = cpu_to_node(raw_smp_processor_id());
+	int n;
+
+	for (n = 0; n < MAX_NUMNODES; n++, node++) {
+		node = (node < MAX_NUMNODES) ? node : 0;
+		if (!node_allowed(node))
+			continue;
+		spu = spu_alloc_node(node);
+		if (spu)
+			break;
+	}
+	return spu;
+}
+
+static inline struct spu *spu_get(struct spu_context *ctx, u64 flags)
+{
+	/* Future: spu_get_idle() if possible,
+	 * otherwise try to preempt an active
+	 * context.
+	 */
+	return spu_get_idle(ctx, flags);
+}
+
+/* The three externally callable interfaces
+ * for the scheduler begin here.
  *
- *	The rq->sem is breifly held (inside or outside a
- *	given ctx lock) for list management, but is never
- *	held during save/restore.
+ *	spu_activate	- bind a context to SPU, waiting as needed.
+ *	spu_deactivate	- unbind a context from its SPU.
+ *	spu_yield	- yield an SPU if others are waiting.
  */
 
 int spu_activate(struct spu_context *ctx, u64 flags)
 {
 	struct spu *spu;
+	int ret = 0;
 
-	if (ctx->spu)
-		return 0;
-	spu = get_idle_spu(ctx, flags);
-	if (!spu)
-		return (signal_pending(current)) ? -ERESTARTSYS : -EAGAIN;
-	bind_context(spu, ctx);
-	/*
-	 * We're likely to wait for interrupts on the same
-	 * CPU that we are now on, so send them here.
-	 */
-	spu_cpu_affinity_set(spu, raw_smp_processor_id());
-	put_active_spu(spu);
-	return 0;
+	for (;;) {
+		if (ctx->spu)
+			return 0;
+		spu = spu_get(ctx, flags);
+		if (spu != NULL) {
+			if (ctx->spu != NULL) {
+				spu_free(spu);
+				spu_prio_wakeup();
+				break;
+			}
+			bind_context(spu, ctx);
+			put_active_spu(spu);
+			break;
+		}
+		spu_prio_wait(ctx, flags);
+		if (signal_pending(current)) {
+			ret = -ERESTARTSYS;
+			spu_prio_wakeup();
+			break;
+		}
+	}
+	return ret;
 }
 
 void spu_deactivate(struct spu_context *ctx)
@@ -378,8 +275,10 @@ void spu_deactivate(struct spu_context *
 		return;
 	needs_idle = get_active_spu(spu);
 	unbind_context(spu, ctx);
-	if (needs_idle)
-		put_idle_spu(spu);
+	if (needs_idle) {
+		spu_free(spu);
+		spu_prio_wakeup();
+	}
 }
 
 void spu_yield(struct spu_context *ctx)
@@ -387,77 +286,60 @@ void spu_yield(struct spu_context *ctx)
 	struct spu *spu;
 	int need_yield = 0;
 
-	down_write(&ctx->state_sema);
-	spu = ctx->spu;
-	if (spu && (sched_find_first_bit(spu->rq->prio.bitmap) < MAX_PRIO)) {
-		pr_debug("%s: yielding SPU %d\n", __FUNCTION__, spu->number);
-		spu_deactivate(ctx);
-		ctx->state = SPU_STATE_SAVED;
-		need_yield = 1;
-	} else if (spu) {
-		spu->prio = MAX_PRIO;
+	if (down_write_trylock(&ctx->state_sema)) {
+		if ((spu = ctx->spu) != NULL) {
+			int best = sched_find_first_bit(spu_prio->bitmap);
+			if (best < MAX_PRIO) {
+				pr_debug("%s: yielding SPU %d NODE %d\n",
+					 __FUNCTION__, spu->number, spu->node);
+				spu_deactivate(ctx);
+				ctx->state = SPU_STATE_SAVED;
+				need_yield = 1;
+			} else {
+				spu->prio = MAX_PRIO;
+			}
+		}
+		up_write(&ctx->state_sema);
 	}
-	up_write(&ctx->state_sema);
 	if (unlikely(need_yield))
 		yield();
 }
 
 int __init spu_sched_init(void)
 {
-	struct spu_runqueue *rq;
-	struct spu *spu;
 	int i;
 
-	rq = spu_runqueues = kmalloc(sizeof(struct spu_runqueue), GFP_KERNEL);
-	if (!rq) {
-		printk(KERN_WARNING "%s: Unable to allocate runqueues.\n",
+	spu_prio = kzalloc(sizeof(struct spu_prio_array), GFP_KERNEL);
+	if (!spu_prio) {
+		printk(KERN_WARNING "%s: Unable to allocate priority queue.\n",
 		       __FUNCTION__);
 		return 1;
 	}
-	memset(rq, 0, sizeof(struct spu_runqueue));
-	init_MUTEX(&rq->sem);
-	INIT_LIST_HEAD(&rq->active_list);
-	INIT_LIST_HEAD(&rq->idle_list);
-	rq->nr_active = 0;
-	rq->nr_idle = 0;
-	rq->nr_switches = 0;
-	atomic_set(&rq->prio.nr_blocked, 0);
 	for (i = 0; i < MAX_PRIO; i++) {
-		init_waitqueue_head(&rq->prio.waitq[i]);
-		__clear_bit(i, rq->prio.bitmap);
+		init_waitqueue_head(&spu_prio->waitq[i]);
+		__clear_bit(i, spu_prio->bitmap);
 	}
-	__set_bit(MAX_PRIO, rq->prio.bitmap);
-	for (;;) {
-		spu = spu_alloc();
-		if (!spu)
-			break;
-		pr_debug("%s: adding SPU[%d]\n", __FUNCTION__, spu->number);
-		add_idle(rq, spu);
-		spu->rq = rq;
-		spu->timestamp = jiffies;
-	}
-	if (!rq->nr_idle) {
-		printk(KERN_WARNING "%s: No available SPUs.\n", __FUNCTION__);
-		kfree(rq);
-		return 1;
+	__set_bit(MAX_PRIO, spu_prio->bitmap);
+	for (i = 0; i < MAX_NUMNODES; i++) {
+		mutex_init(&spu_prio->active_mutex[i]);
+		INIT_LIST_HEAD(&spu_prio->active_list[i]);
 	}
 	return 0;
 }
 
 void __exit spu_sched_exit(void)
 {
-	struct spu_runqueue *rq = spu_rq();
-	struct spu *spu;
+	struct spu *spu, *tmp;
+	int node;
 
-	if (!rq) {
-		printk(KERN_WARNING "%s: no runqueues!\n", __FUNCTION__);
-		return;
-	}
-	while (rq->nr_idle > 0) {
-		spu = del_idle(rq);
-		if (!spu)
-			break;
-		spu_free(spu);
+	for (node = 0; node < MAX_NUMNODES; node++) {
+		mutex_lock(&spu_prio->active_mutex[node]);
+		list_for_each_entry_safe(spu, tmp, &spu_prio->active_list[node],
+					 list) {
+			list_del_init(&spu->list);
+			spu_free(spu);
+		}
+		mutex_unlock(&spu_prio->active_mutex[node]);
 	}
-	kfree(rq);
+	kfree(spu_prio);
 }
Index: linux-2.6/include/asm-powerpc/spu.h
===================================================================
--- linux-2.6.orig/include/asm-powerpc/spu.h
+++ linux-2.6/include/asm-powerpc/spu.h
@@ -147,6 +147,7 @@ struct spu {
 };
 
 struct spu *spu_alloc(void);
+struct spu *spu_alloc_node(int node);
 void spu_free(struct spu *spu);
 int spu_irq_class_0_bottom(struct spu *spu);
 int spu_irq_class_1_bottom(struct spu *spu);

--

^ 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