* Re: [PATCH] SLB shadow buffer
From: Michael Neuling @ 2006-08-07 5:55 UTC (permalink / raw)
To: Milton Miller; +Cc: linuxppc-dev, paulus
In-Reply-To: <111547573996b8b45671.846930886.miltonm@bga.com>
> > +#define SHADOW_SLB_BOLTED_LAST_ESID \
> > + (SLBSHADOW_SAVEAREA + 0x10*(SLB_NUM_BOLTED-1))
> > +#define SHADOW_SLB_BOLTED_LAST_VSID \
> > + (SLBSHADOW_SAVEAREA + 0x10*(SLB_NUM_BOLTED-1) + 8)
>
> It's not because it's the last one but that it's the one with the stack.
Yep changed to SHADOW_SLB_BOLTED_STACK_<blah>
> > + std r12,SHADOW_SLB_BOLTED_LAST_ESID(r9) /* Clear ESID */
> > + std r7,SHADOW_SLB_BOLTED_LAST_VSID(r9) /* Save VSID */
> > + std r0,SHADOW_SLB_BOLTED_LAST_ESID(r9) /* Save ESID */
> > +
>
> Tabs not spaces please
Oops.. done
> > +/*
> > + * 3 persistent SLBs are registered here. The buffer will be zero
> > + * initially, hence will all be invaild until we actually write them.
> > + */
> > +struct slb_shadow_buffer slb_shadow_buffer[] = {
> > + [0 ... (NR_CPUS-1)] = {
> > + .persistent = SLB_NUM_BOLTED,
> > + .buffer_length = sizeof(struct slb_shadow_buffer),
> > + },
> > +};
>
> How about making this per-cpu and setting the paca pointer at runtime?
> It would save NR_CPUS-1 cachelines of data. Otherwise, put in
> cacheline_aligned will potentially save some space.
The PAPR requirement is that it's cache aligned so I've added the
necessary __cacheline_aligned foo.
I did some experiments and without the alignment. Alignment costs
around 8KB when NR_CPUS=128 so there is some space to be saved if we
play around.
I also tried putting the structure directly in the PACA but I couldn't
get any savings. I tired in a few different locations in the paca
struct, but it didn't make any difference. I may have been doing
something stupid though :-)
>
> > +
> > /* The Paca is an array with one entry per processor. Each contains an
> > * lppaca, which contains the information shared between the
> > * hypervisor and Linux.
> > @@ -59,7 +71,8 @@ struct lppaca lppaca[] = {
> > .lock_token = 0x8000, \
> > .paca_index = (number), /* Paca Index */ \
> > .kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL, \
> > - .hw_cpu_id = 0xffff,
> > + .hw_cpu_id = 0xffff, \
> > + .slb_shadow_buffer_ptr = &slb_shadow_buffer[number]
>
> Trailing , (yeah, still have to add the \ )
Oops.. done
>
> >
> > #ifdef CONFIG_PPC_ISERIES
> > #define PACA_INIT_ISERIES(number) \
> > Index: linux-2.6-ozlabs/arch/powerpc/mm/slb.c
> > ===================================================================
> > --- linux-2.6-ozlabs.orig/arch/powerpc/mm/slb.c
> > +++ linux-2.6-ozlabs/arch/powerpc/mm/slb.c
> > @@ -22,6 +22,8 @@
> > #include <asm/paca.h>
> > #include <asm/cputable.h>
> > #include <asm/cacheflush.h>
> > +#include <asm/smp.h>
> > +#include <linux/compiler.h>
> >
> > #ifdef DEBUG
> > #define DBG(fmt...) udbg_printf(fmt)
> > @@ -50,9 +52,29 @@ static inline unsigned long mk_vsid_data
> > return (get_kernel_vsid(ea) << SLB_VSID_SHIFT) | flags;
> > }
> >
> > +static inline void slb_shadow_update(unsigned long esid, unsigned long vsi
d,
> > + unsigned long entry)
> > +{
> > + /* Clear the ESID first so the entry is not valid while we are
> > + * updating it. Then write the VSID before the real ESID. */
>
> Multi-line comments get the */ on it's own line
Ok... (most comments in that file are like this though)
> > + get_slb_shadow_buffer()->save_area[2*entry] = 0;
> > + barrier();
> > + get_slb_shadow_buffer()->save_area[2*entry+1] = vsid;
> > + barrier();
> > + get_slb_shadow_buffer()->save_area[2*entry] = esid;
> > +
> > +}
>
> This 2* seems magic. How about an array of structs?
OK, that's two people I've confused. Changed.
>
> > +
> > static inline void create_slbe(unsigned long ea, unsigned long flags,
> > unsigned long entry)
>
> Should we rename to create_shadowed_slbe?
Good point. Changed
> > + slb_shadow_update(mk_esid_data(ea, entry),
> > + mk_vsid_data(ea, flags),
> > + entry);
>
> Do we need the third line?
Nope.
>
> > +
> > asm volatile("slbmte %0,%1" :
> > : "r" (mk_vsid_data(ea, flags)),
> > "r" (mk_esid_data(ea, entry))
>
> Hopefully the compiler only calculates these once.
I've been keeping all my fingers and toes crossed...
> > @@ -77,6 +99,11 @@ void slb_flush_and_rebolt(void)
> > if ((ksp_esid_data & ESID_MASK) == PAGE_OFFSET)
> > ksp_esid_data &= ~SLB_ESID_V;
> >
> > + /* Only second entry may change here so only resave that */
> > + slb_shadow_update(ksp_esid_data,
> > + mk_vsid_data(ksp_esid_data, lflags),
> > + 2);
> > +
>
> 1) it's the third entry 2) it's the stack slot
Yep. Updated comment.
>
> > asm volatile("isync\n"
> > Index: linux-2.6-ozlabs/arch/powerpc/platforms/pseries/lpar.c
> > ===================================================================
> > --- linux-2.6-ozlabs.orig/arch/powerpc/platforms/pseries/lpar.c
> > +++ linux-2.6-ozlabs/arch/powerpc/platforms/pseries/lpar.c
> > @@ -254,18 +254,32 @@ out:
> > void vpa_init(int cpu)
> > {
> > int hwcpu = get_hard_smp_processor_id(cpu);
> > - unsigned long vpa = __pa(&lppaca[cpu]);
> > + unsigned long vpa;
>
> This is used for something other than vpa, rename.
Another complaint about this, I'll changed.
BTW It's called vpa in the PAPR for both calls.
> > +/* SLB shadow buffer structure as defined in the PAPR. The save_area
> > + * contains adjacent ESID and VSID pairs for each shadowed SLB. The
> > + * ESID is stored in the lower 64bits, then the VSID. NOTE: This
> > + * structure is 0x40 bytes long (with 3 bolted SLBs), but PHYP
> > + * complaints if we're not 0x80 (cache line?) aligned. */
>
> Own line
>
> Less explaination needed with array of structs.
Yep and yep.
>
> > +struct slb_shadow_buffer {
> > + u32 persistent; // Number of persistent SLBs x00-x03
> > + u32 buffer_length; // Total shadow buffer length x04-x07
> > + u64 reserved; // Alignment x08-x0f
> > + u64 save_area[SLB_NUM_BOLTED * 2]; // x10-x40
> > +} __attribute__((__aligned__(0x80)));
> > +
> > +extern struct slb_shadow_buffer slb_shadow_buffer[];
> > +
>
> Remove buffer from these names? They seem quite long for linux.
Ok. Changed.
> > u64 user_time; /* accumulated usermode TB ticks */
> > u64 system_time; /* accumulated system TB ticks */
> > u64 startpurr; /* PURR/TB value snapshot */
> > +
> > + /* Pointer to SLB shadow buffer */
> > + struct slb_shadow_buffer *slb_shadow_buffer_ptr;
> > };
>
> With the long name the comment doesn't add much.
True. The comment was only there since most other items in that struct
were documented.
Thanks for the review. I'll repost the updated patch.
Mikey
^ permalink raw reply
* [PATCH] SLB shadow buffer
From: Michael Neuling @ 2006-08-07 6:19 UTC (permalink / raw)
To: linuxppc-dev; +Cc: paulus, anton, miltonm
This adds a shadow buffer for the SLBs and regsiters it with PHYP.
Only the bolted SLB entries (top 3) are shadowed.
Signed-off-by: Michael Neuling <mikey@neuling.org>
---
Updated with comments from Milton.
arch/powerpc/kernel/asm-offsets.c | 2 +
arch/powerpc/kernel/entry_64.S | 13 ++++++++
arch/powerpc/kernel/paca.c | 15 +++++++++
arch/powerpc/mm/slb.c | 37 +++++++++++++++++++++---
arch/powerpc/platforms/pseries/lpar.c | 24 ++++++++++++---
arch/powerpc/platforms/pseries/plpar_wrappers.h | 10 ++++++
arch/powerpc/platforms/pseries/setup.c | 12 ++++++-
include/asm-powerpc/lppaca.h | 19 ++++++++++++
include/asm-powerpc/paca.h | 3 +
9 files changed, 124 insertions(+), 11 deletions(-)
Index: linux-2.6-ozlabs/arch/powerpc/kernel/asm-offsets.c
===================================================================
--- linux-2.6-ozlabs.orig/arch/powerpc/kernel/asm-offsets.c
+++ linux-2.6-ozlabs/arch/powerpc/kernel/asm-offsets.c
@@ -135,11 +135,13 @@ int main(void)
DEFINE(PACA_STARTPURR, offsetof(struct paca_struct, startpurr));
DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time));
DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time));
+ DEFINE(PACA_SLBSHADOWPTR, offsetof(struct paca_struct, slb_shadow_ptr));
DEFINE(LPPACASRR0, offsetof(struct lppaca, saved_srr0));
DEFINE(LPPACASRR1, offsetof(struct lppaca, saved_srr1));
DEFINE(LPPACAANYINT, offsetof(struct lppaca, int_dword.any_int));
DEFINE(LPPACADECRINT, offsetof(struct lppaca, int_dword.fields.decr_int));
+ DEFINE(SLBSHADOW_SAVEAREA, offsetof(struct slb_shadow, save_area));
#endif /* CONFIG_PPC64 */
/* RTAS */
Index: linux-2.6-ozlabs/arch/powerpc/kernel/entry_64.S
===================================================================
--- linux-2.6-ozlabs.orig/arch/powerpc/kernel/entry_64.S
+++ linux-2.6-ozlabs/arch/powerpc/kernel/entry_64.S
@@ -323,6 +323,11 @@ _GLOBAL(ret_from_fork)
* The code which creates the new task context is in 'copy_thread'
* in arch/powerpc/kernel/process.c
*/
+#define SHADOW_SLB_BOLTED_STACK_ESID \
+ (SLBSHADOW_SAVEAREA + 0x10*(SLB_NUM_BOLTED-1))
+#define SHADOW_SLB_BOLTED_STACK_VSID \
+ (SLBSHADOW_SAVEAREA + 0x10*(SLB_NUM_BOLTED-1) + 8)
+
.align 7
_GLOBAL(_switch)
mflr r0
@@ -375,6 +380,14 @@ BEGIN_FTR_SECTION
ld r7,KSP_VSID(r4) /* Get new stack's VSID */
oris r0,r6,(SLB_ESID_V)@h
ori r0,r0,(SLB_NUM_BOLTED-1)@l
+
+ /* Update the last bolted SLB */
+ ld r9,PACA_SLBSHADOWPTR(r13)
+ li r12,0
+ std r12,SHADOW_SLB_BOLTED_STACK_ESID(r9) /* Clear ESID */
+ std r7,SHADOW_SLB_BOLTED_STACK_VSID(r9) /* Save VSID */
+ std r0,SHADOW_SLB_BOLTED_STACK_ESID(r9) /* Save ESID */
+
slbie r6
slbie r6 /* Workaround POWER5 < DD2.1 issue */
slbmte r7,r0
Index: linux-2.6-ozlabs/arch/powerpc/kernel/paca.c
===================================================================
--- linux-2.6-ozlabs.orig/arch/powerpc/kernel/paca.c
+++ linux-2.6-ozlabs/arch/powerpc/kernel/paca.c
@@ -17,6 +17,7 @@
#include <asm/lppaca.h>
#include <asm/iseries/it_lp_reg_save.h>
#include <asm/paca.h>
+#include <asm/mmu.h>
/* This symbol is provided by the linker - let it fill in the paca
@@ -45,6 +46,17 @@ struct lppaca lppaca[] = {
},
};
+/*
+ * 3 persistent SLBs are registered here. The buffer will be zero
+ * initially, hence will all be invaild until we actually write them.
+ */
+struct slb_shadow slb_shadow[] __cacheline_aligned = {
+ [0 ... (NR_CPUS-1)] = {
+ .persistent = SLB_NUM_BOLTED,
+ .buffer_length = sizeof(struct slb_shadow),
+ },
+};
+
/* The Paca is an array with one entry per processor. Each contains an
* lppaca, which contains the information shared between the
* hypervisor and Linux.
@@ -59,7 +71,8 @@ struct lppaca lppaca[] = {
.lock_token = 0x8000, \
.paca_index = (number), /* Paca Index */ \
.kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL, \
- .hw_cpu_id = 0xffff,
+ .hw_cpu_id = 0xffff, \
+ .slb_shadow_ptr = &slb_shadow[number],
#ifdef CONFIG_PPC_ISERIES
#define PACA_INIT_ISERIES(number) \
Index: linux-2.6-ozlabs/arch/powerpc/mm/slb.c
===================================================================
--- linux-2.6-ozlabs.orig/arch/powerpc/mm/slb.c
+++ linux-2.6-ozlabs/arch/powerpc/mm/slb.c
@@ -22,6 +22,8 @@
#include <asm/paca.h>
#include <asm/cputable.h>
#include <asm/cacheflush.h>
+#include <asm/smp.h>
+#include <linux/compiler.h>
#ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt)
@@ -50,9 +52,32 @@ static inline unsigned long mk_vsid_data
return (get_kernel_vsid(ea) << SLB_VSID_SHIFT) | flags;
}
-static inline void create_slbe(unsigned long ea, unsigned long flags,
- unsigned long entry)
+static inline void slb_shadow_update(unsigned long esid, unsigned long vsid,
+ unsigned long entry)
{
+ /*
+ * Clear the ESID first so the entry is not valid while we are
+ * updating it.
+ */
+ get_slb_shadow()->save_area[entry].esid = 0;
+ barrier();
+ get_slb_shadow()->save_area[entry].vsid = vsid;
+ barrier();
+ get_slb_shadow()->save_area[entry].esid = esid;
+
+}
+
+static inline void create_shadowed_slbe(unsigned long ea, unsigned long flags,
+ unsigned long entry)
+{
+ /*
+ * Updating the shadow buffer before writing the SLB ensures
+ * we don't get a stale entry here if we get preempted by PHYP
+ * between these two statements.
+ */
+ slb_shadow_update(mk_esid_data(ea, entry), mk_vsid_data(ea, flags),
+ entry);
+
asm volatile("slbmte %0,%1" :
: "r" (mk_vsid_data(ea, flags)),
"r" (mk_esid_data(ea, entry))
@@ -77,6 +102,10 @@ void slb_flush_and_rebolt(void)
if ((ksp_esid_data & ESID_MASK) == PAGE_OFFSET)
ksp_esid_data &= ~SLB_ESID_V;
+ /* Only third entry (stack) may change here so only resave that */
+ slb_shadow_update(ksp_esid_data,
+ mk_vsid_data(ksp_esid_data, lflags), 2);
+
/* We need to do this all in asm, so we're sure we don't touch
* the stack between the slbia and rebolting it. */
asm volatile("isync\n"
@@ -209,9 +238,9 @@ void slb_initialize(void)
asm volatile("isync":::"memory");
asm volatile("slbmte %0,%0"::"r" (0) : "memory");
asm volatile("isync; slbia; isync":::"memory");
- create_slbe(PAGE_OFFSET, lflags, 0);
+ create_shadowed_slbe(PAGE_OFFSET, lflags, 0);
- create_slbe(VMALLOC_START, vflags, 1);
+ create_shadowed_slbe(VMALLOC_START, vflags, 1);
/* We don't bolt the stack for the time being - we're in boot,
* so the stack is in the bolted segment. By the time it goes
Index: linux-2.6-ozlabs/arch/powerpc/platforms/pseries/lpar.c
===================================================================
--- linux-2.6-ozlabs.orig/arch/powerpc/platforms/pseries/lpar.c
+++ linux-2.6-ozlabs/arch/powerpc/platforms/pseries/lpar.c
@@ -254,18 +254,34 @@ out:
void vpa_init(int cpu)
{
int hwcpu = get_hard_smp_processor_id(cpu);
- unsigned long vpa = __pa(&lppaca[cpu]);
+ unsigned long addr;
long ret;
if (cpu_has_feature(CPU_FTR_ALTIVEC))
lppaca[cpu].vmxregs_in_use = 1;
- ret = register_vpa(hwcpu, vpa);
+ addr = __pa(&lppaca[cpu]);
+ ret = register_vpa(hwcpu, addr);
- if (ret)
+ if (ret) {
printk(KERN_ERR "WARNING: vpa_init: VPA registration for "
"cpu %d (hw %d) of area %lx returns %ld\n",
- cpu, hwcpu, vpa, ret);
+ cpu, hwcpu, addr, ret);
+ return;
+ }
+ /*
+ * PAPR says this feature is SLB-Buffer but firmware never
+ * reports that. All SPLPAR support SLB shadow buffer.
+ */
+ addr = __pa(&slb_shadow[cpu]);
+ if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
+ ret = register_slb_shadow(hwcpu, addr);
+ if (ret)
+ printk(KERN_ERR
+ "WARNING: vpa_init: SLB shadow buffer "
+ "registration for cpu %d (hw %d) of area %lx "
+ "returns %ld\n", cpu, hwcpu, addr, ret);
+ }
}
long pSeries_lpar_hpte_insert(unsigned long hpte_group,
Index: linux-2.6-ozlabs/arch/powerpc/platforms/pseries/plpar_wrappers.h
===================================================================
--- linux-2.6-ozlabs.orig/arch/powerpc/platforms/pseries/plpar_wrappers.h
+++ linux-2.6-ozlabs/arch/powerpc/platforms/pseries/plpar_wrappers.h
@@ -40,6 +40,16 @@ static inline long register_vpa(unsigned
return vpa_call(0x1, cpu, vpa);
}
+static inline long unregister_slb_shadow(unsigned long cpu, unsigned long vpa)
+{
+ return vpa_call(0x7, cpu, vpa);
+}
+
+static inline long register_slb_shadow(unsigned long cpu, unsigned long vpa)
+{
+ return vpa_call(0x3, cpu, vpa);
+}
+
extern void vpa_init(int cpu);
static inline long plpar_pte_remove(unsigned long flags, unsigned long ptex,
Index: linux-2.6-ozlabs/arch/powerpc/platforms/pseries/setup.c
===================================================================
--- linux-2.6-ozlabs.orig/arch/powerpc/platforms/pseries/setup.c
+++ linux-2.6-ozlabs/arch/powerpc/platforms/pseries/setup.c
@@ -234,9 +234,17 @@ static void pseries_kexec_cpu_down_xics(
{
/* Don't risk a hypervisor call if we're crashing */
if (firmware_has_feature(FW_FEATURE_SPLPAR) && !crash_shutdown) {
- unsigned long vpa = __pa(get_lppaca());
+ unsigned long addr;
- if (unregister_vpa(hard_smp_processor_id(), vpa)) {
+ addr = __pa(get_slb_shadow());
+ if (unregister_slb_shadow(hard_smp_processor_id(), addr))
+ printk("SLB shadow buffer deregistration of "
+ "cpu %u (hw_cpu_id %d) failed\n",
+ smp_processor_id(),
+ hard_smp_processor_id());
+
+ addr = __pa(get_lppaca());
+ if (unregister_vpa(hard_smp_processor_id(), addr)) {
printk("VPA deregistration of cpu %u (hw_cpu_id %d) "
"failed\n", smp_processor_id(),
hard_smp_processor_id());
Index: linux-2.6-ozlabs/include/asm-powerpc/lppaca.h
===================================================================
--- linux-2.6-ozlabs.orig/include/asm-powerpc/lppaca.h
+++ linux-2.6-ozlabs/include/asm-powerpc/lppaca.h
@@ -27,7 +27,9 @@
//
//
//----------------------------------------------------------------------------
+#include <linux/cache.h>
#include <asm/types.h>
+#include <asm/mmu.h>
/* The Hypervisor barfs if the lppaca crosses a page boundary. A 1k
* alignment is sufficient to prevent this */
@@ -133,5 +135,22 @@ struct lppaca {
extern struct lppaca lppaca[];
+/*
+ * SLB shadow buffer structure as defined in the PAPR. The save_area
+ * contains adjacent ESID and VSID pairs for each shadowed SLB. The
+ * ESID is stored in the lower 64bits, then the VSID.
+ */
+struct slb_shadow {
+ u32 persistent; // Number of persistent SLBs x00-x03
+ u32 buffer_length; // Total shadow buffer length x04-x07
+ u64 reserved; // Alignment x08-x0f
+ struct {
+ u64 esid;
+ u64 vsid;
+ } save_area[SLB_NUM_BOLTED]; // x10-x40
+} ____cacheline_aligned;
+
+extern struct slb_shadow slb_shadow[];
+
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_LPPACA_H */
Index: linux-2.6-ozlabs/include/asm-powerpc/paca.h
===================================================================
--- linux-2.6-ozlabs.orig/include/asm-powerpc/paca.h
+++ linux-2.6-ozlabs/include/asm-powerpc/paca.h
@@ -23,6 +23,7 @@
register struct paca_struct *local_paca asm("r13");
#define get_paca() local_paca
#define get_lppaca() (get_paca()->lppaca_ptr)
+#define get_slb_shadow() (get_paca()->slb_shadow_ptr)
struct task_struct;
@@ -98,6 +99,8 @@ struct paca_struct {
u64 user_time; /* accumulated usermode TB ticks */
u64 system_time; /* accumulated system TB ticks */
u64 startpurr; /* PURR/TB value snapshot */
+
+ struct slb_shadow *slb_shadow_ptr;
};
extern struct paca_struct paca[];
^ permalink raw reply
* Re: [RFC] asm code for Hypervisor Call Instrumentation
From: Paul Mackerras @ 2006-08-07 6:26 UTC (permalink / raw)
To: Mike Kravetz; +Cc: linuxppc-dev
In-Reply-To: <20060802175947.GA7489@w-mikek2.ibm.com>
Mike Kravetz writes:
> This patch is built on top of Anton's hcall cleanup patch. One
> remaining issue is 'where should the statistic data structures
> be updated?'. For simplicity, I have the asm code call the
> following C routine to perform the updates.
Hmmm, doing the update in assembly would avoid the need to create a
stack frame, which would be nice... Maybe we need to add some macros
to include/asm-powerpc/percpu.h to make it easier to access per-cpu
variables from assembly code.
Alternatively, we could put a pointer to the hcall_stats array for
each cpu in its paca. That's very easily accessed from assembly code.
Paul.
^ permalink raw reply
* Re: [PATCH 1/6] bootwrapper: arch/powerpc/boot code reorg
From: Paul Mackerras @ 2006-08-07 6:48 UTC (permalink / raw)
To: Mark A. Greer; +Cc: linuxppc-dev
In-Reply-To: <20060803192629.GD25251@mag.az.mvista.com>
Mark A. Greer writes:
> I realize that I didn't really answer your question. Its at least
> possible that the console driver could not be known at link time.
>
> An example I used in another email is a platform that has 4 serial
> ports, 2-16550 and 2-mpsc, say. The /chosen/linux,stdout-path could
> pick any of the four so you would need to compile in a low-level
> serial driver for both and hook the correct one up at runtime.
>
> Same could be said for a serial vs. video console.
OK, that's reasonable. Still would be nice not to have to do the
double dereference though. I think that the platform_ops and the
fw_ops could probably be combined. Also, an init method for the
platform/fw_ops would be useful - it would let us remove the kludge
you have in the OF malloc implementation.
The OF malloc is currently applying a minimum address constraint for
all platforms, where it used to apply it only for 64-bit platforms.
We need to fix that up somehow too.
Regards,
Paul.
^ permalink raw reply
* Who cares about PReP?
From: Paul Mackerras @ 2006-08-07 6:59 UTC (permalink / raw)
To: linuxppc-dev
I started looking at moving the PReP code over to arch/powerpc. I am
struck by how many ifdefs there are in there to set things up for
particular individual PReP implementations. We can do better than
that, I'm sure, but the issue becomes one of testing. The only PReP I
have here is an RS/6000 43p-140.
Who else has a PReP system and would be willing to do some testing and
debugging? If so, what sort of PReP is it?
Paul.
^ permalink raw reply
* [PATCH] Update lppaca offset comments
From: Michael Neuling @ 2006-08-07 7:34 UTC (permalink / raw)
To: paulus; +Cc: linuxppc-dev
Update offset comments. No functional change.
Signed-off-by: Michael Neuling <mikey@neuling.org>
---
include/asm-powerpc/lppaca.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
Index: linux-2.6-ozlabs/include/asm-powerpc/lppaca.h
===================================================================
--- linux-2.6-ozlabs.orig/include/asm-powerpc/lppaca.h
+++ linux-2.6-ozlabs/include/asm-powerpc/lppaca.h
@@ -114,7 +114,7 @@ struct lppaca {
//=============================================================================
-// CACHE_LINE_3 0x0100 - 0x007F: This line is shared with other processors
+// CACHE_LINE_3 0x0100 - 0x017F: This line is shared with other processors
//=============================================================================
// This is the yield_count. An "odd" value (low bit on) means that
// the processor is yielded (either because of an OS yield or a PLIC
@@ -126,7 +126,7 @@ struct lppaca {
u8 reserved6[124]; // Reserved x04-x7F
//=============================================================================
-// CACHE_LINE_4-5 0x0100 - 0x01FF Contains PMC interrupt data
+// CACHE_LINE_4-5 0x0180 - 0x027F Contains PMC interrupt data
//=============================================================================
u8 pmc_save_area[256]; // PMC interrupt Area x00-xFF
} __attribute__((__aligned__(0x400)));
^ permalink raw reply
* Re: XUPV2P, Kernel 2.6.17 boot problem
From: Peter Korsgaard @ 2006-08-07 7:40 UTC (permalink / raw)
To: linuxppc-embedded
In-Reply-To: <44D36940.7050908@dlasys.net>
>>>>> "David" == David H Lynch <dhlii@dlasys.net> writes:
Hi,
David> Have you tried 2.6.18.x to see if your stuff works with it
David> ?
Yes, 2.6.18-rc3 + my zlib fix
(http://thread.gmane.org/gmane.linux.kernel/428436) or -rc4 once it
hits kernel.org works fine on my v2p-based board.
--
Bye, Peter Korsgaard
^ permalink raw reply
* Re: Who cares about PReP?
From: Olaf Hering @ 2006-08-07 7:26 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
In-Reply-To: <17622.58559.879330.496619@cargo.ozlabs.ibm.com>
On Mon, Aug 07, 2006 at 04:59:11PM +1000, Paul Mackerras wrote:
> Who else has a PReP system and would be willing to do some testing and
> debugging? If so, what sort of PReP is it?
I have that also on my list. I have an MTX+, a 43p 130, 43p 140 and a Powerstack.
^ permalink raw reply
* Re: Who cares about PReP?
From: Xavier Grave @ 2006-08-07 9:27 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
In-Reply-To: <17622.58559.879330.496619@cargo.ozlabs.ibm.com>
Hi,
I have motorolla vme boards that seems to me are PreP.
The boards are mvme5100 and mvme5500.
xavier
^ permalink raw reply
* regarding pci vga card output with powerpc
From: urwithsudheer @ 2006-08-07 9:35 UTC (permalink / raw)
To: linuxppc-embedded
[-- Attachment #1: Type: text/plain, Size: 1098 bytes --]
Hello All,
I am working with a pci based vga card. I have connected the vga card
next to the pci slot of my target processor on the baseboard.
I have connected a monitor to the vga card.
When i boot linux from minicom, i could see all the kernel log messages
on both the minicom and vga card monitor. But on the vga monitor, i
could not see any messages after asking for login as below:
.
.
Mounting filesystems
Running depmod
Setting up networking on loopback device:
Setting up networking on eth0:
eth0: PHY is Marvell 88E11x1 (1410cc2)
Adding static route for default gateway to 192.168.3.1:
Setting nameserver to 192.168.0.1 in /etc/resolv.conf:
Starting inetd:
login:
Though i am entering my login and passwd at the minicom, nothing comes
on to the vga monitor. But i am able to write to vga monitor using the
following commands from minicom:
# echo "Hello" > /dev/tty1
# echo "Hi " > /dev/tty1
My requirement is to get on the vga monitor whatever i am typing on the
minicom after logging into the linux like .
ls or pwd commands.
Anyone pl help me.
Thanks & Regards
Sudheer
[-- Attachment #2: Type: text/html, Size: 1606 bytes --]
^ permalink raw reply
* Re: XUPV2P, Kernel 2.6.17 boot problem
From: Benjamin Heyne @ 2006-08-07 9:46 UTC (permalink / raw)
To: linuxppc-embedded
In-Reply-To: <87lkq1uh7l.fsf@sleipner.barco.com>
And so it came to pass, that on Mon, 07 Aug 2006 09:40:14 +0200
Peter Korsgaard <jacmet@sunsite.dk> wrote as thus:
> >>>>> "David" == David H Lynch <dhlii@dlasys.net> writes:
>
> Hi,
>
> David> Have you tried 2.6.18.x to see if your stuff works with it
> David> ?
>
> Yes, 2.6.18-rc3 + my zlib fix
> (http://thread.gmane.org/gmane.linux.kernel/428436) or -rc4 once it
> hits kernel.org works fine on my v2p-based board.
Well, unfortunately I am still getting the inflate error
as soon as the image grows >2MB (about). Have you tried with
images of this size? If the image is smaller, everything works
fine...
Best regards
Benjamin Heyne
^ permalink raw reply
* Reg. Serial and Virtual consoles
From: Selvamuthukumar V @ 2006-08-07 10:07 UTC (permalink / raw)
To: linuxppc-dev
Hello,
I'm working on a MPC8360 board. I've connected a VGA card in a PCI slot.
I modified the kernel commandline console parameters, and now I'm getting
all the kernel messages in both serial port and VGA. I modified the
/etc/inittab file and getting login prompt in VGA(virtual terminal). Is
keyboard is necessary to login via virtual terminal? Is there anyway to
select serial port as the input to the virtual terminal? I want to login
to the virtual terminal and want a shell in VGA. Please guide me in this
regard.
-Selva
^ permalink raw reply
* XUPV2P, which kernel 2.6. device drivers are available?
From: Benjamin Heyne @ 2006-08-07 15:22 UTC (permalink / raw)
To: linuxppc-embedded
In-Reply-To: <20060801100220.26176938@bob.dt.e-technik.uni-dortmund.de>
Hi all,
despite having problems with zlib, I'd like to know which
device drivers for the XUPV2P have already been ported
to the 2.6 kernel? - I don't want to do work twice ;-).
For practicing, I just ported the original Xilinx ENET 100MBit
driver (seems to work in FIFO mode, including MII - At least I
can mount and use a NFS root file system)...but that has probably
already been done elsewhere. I saw that work is going on for
the SystemACE. - So what about VGA, AC97, PS/2, SATA?
Best regards
Benjamin Heyne
^ permalink raw reply
* Re: XUPV2P, which kernel 2.6. device drivers are available?
From: Ameet Patil @ 2006-08-07 16:03 UTC (permalink / raw)
To: Benjamin Heyne; +Cc: linuxppc-embedded
In-Reply-To: <20060807172251.1d4e81bd@bob.dt.e-technik.uni-dortmund.de>
Hi Benjamin,
I had ported the ENET driver but it was a bit buggy. Could you send
me your driver patch so I can test it?
Thanks,
-Ameet
Benjamin Heyne wrote:
> Hi all,
> despite having problems with zlib, I'd like to know which
> device drivers for the XUPV2P have already been ported
> to the 2.6 kernel? - I don't want to do work twice ;-).
>
> For practicing, I just ported the original Xilinx ENET 100MBit
> driver (seems to work in FIFO mode, including MII - At least I
> can mount and use a NFS root file system)...but that has probably
> already been done elsewhere. I saw that work is going on for
> the SystemACE. - So what about VGA, AC97, PS/2, SATA?
>
> Best regards
> Benjamin Heyne
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>
^ permalink raw reply
* Re: [PATCH] Fix powerpc 44x_mmu build
From: Matt Porter @ 2006-08-05 13:11 UTC (permalink / raw)
To: Josh Boyer; +Cc: linuxppc-dev
In-Reply-To: <1154740342.2847.6.camel@vader.jdub.homelinux.org>
On Fri, Aug 04, 2006 at 08:12:22PM -0500, Josh Boyer wrote:
> On Fri, 2006-08-04 at 11:44 -0500, Matt Porter wrote:
> > The PIN_SIZE definition name changed, update 44x_mmu.c accordingly.
>
> As far as I know, 4xx still builds as ARCH=ppc... is this patch just
> something you noticed, or is it a hint that you're working on moving 4xx
> to arch/powerpc?
Yes, working on moving 4xx to arch/powerpc.
> Just curious, since I've been poking at this a bit and would rather not
> duplicate effort.
Sounds great. In fact, I talked to BenH and tgall at ols about this
and they mentioned you were doing some work. These patches are
just some obvious basic things to get started.
Since there's a lot of work here, what aspect are you working on?
I haven't seen anything publicly but hear plenty of talk of people
working on dt soc definitions for 4xx i/o blocks.
I'm currently looking at merging ocotea but am using it to focus
on a few fundamental things like merging over a version of the
non-coherent DMA API implementation. The plan here is to get
a serial-only port merged and then sync with whoever is working
on the definitions and driver changes for the essential drivers
(obviously emac first from my POV).
-Matt`
^ permalink raw reply
* ELDK 3.1.1 support for x86_64 host architecture
From: Michael Carey @ 2006-08-07 17:22 UTC (permalink / raw)
To: linuxppc-embedded
Thanks for the help, your clue about linux32 was the key.
I simply used the command:
linux32 ./install -d /opt/eldk
and it worked.
I will continue to look for any missing components in my distribution =
install so I wont run into
this type of problem again.
Regards,
Michael Carey
^ permalink raw reply
* [RFC] Debugging with a HW probe.
From: Jimi Xenidis @ 2006-08-06 14:42 UTC (permalink / raw)
To: linuxppc-dev
On the XenPPC project we've been playing around with using GDB to
source debug Linux (and Xen) using a RiscWatch HW probe.
On IBM POWER4 and greater processors (and possibly POWER3 and *Star)
there is an instruction called ATTN (asm (".long 0x200")) that will
have the process call out to the HW probe. This instruction is used
by RiscWatch software to set "soft breakpoints".
We have found it useful to teach xmon to make this call so we can then
debug the SW thru the probe. Is this useful to anyone else?
Below is a quick attempt at a formalized patch, tho' I am torn between
making it ATTN specific or just making a generic HW Probe Service.
All comments welcome.
BTW: We even have some python that will let GDB "talk to" a RiscWatch
probe and fully source-level debug a Linux kernel (even the
initial relocatable parts with a few tricks), this code is
currently part of the our Xen tree (you need mercurial to get
it):
http://xenbits.xensource.com/ext/xenppc-unstable.hg
The python is self contained and in:
tools/gpproxy
-JX
----
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index 8d48e9e..b84f03d 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -82,6 +82,13 @@ config XMON_DEFAULT
xmon is normally disabled unless booted with 'xmon=on'.
Use 'xmon=off' to disable xmon init during runtime.
+config XMON_ATTN
+ bool "Use Support Processor Attention Instruction"
+ depends on XMON && PPC64
+ help
+ If you have a hardware probe attached to your processor you
+ can 'contact' it with a the 'A' command at the xmon prompt.
+
config IRQSTACKS
bool "Use separate kernel stacks when processing interrupts"
depends on PPC64
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 4735b41..ea1d732 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -37,6 +37,7 @@ #include <asm/cputable.h>
#include <asm/rtas.h>
#include <asm/sstep.h>
#include <asm/bug.h>
+#include <asm/firmware.h>
#ifdef CONFIG_PPC64
#include <asm/hvcall.h>
@@ -175,7 +176,12 @@ #define isalnum(c) (('0' <= (c) && (c) <
#define isspace(c) (c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0)
static char *help_string = "\
-Commands:\n\
+Commands:\n"
+#ifdef CONFIG_XMON_ATTN
+ "\
+ A Get the attention of the hardware probe, assuming you have one\n"
+#endif
+ "\
b show breakpoints\n\
bd set data breakpoint\n\
bi set instruction breakpoint\n\
@@ -223,6 +229,70 @@ #endif
static struct pt_regs *xmon_regs;
+#ifdef CONFIG_XMON_ATTN
+static int xmon_hw_probe_enabled;
+/* try to keep this funtion from being inlined so its easier to move
+ * around the ATTN instruction */
+static noinline void xmon_hw_probe(void)
+{
+ if (!xmon_hw_probe_enabled)
+ return;
+ ATTN();
+}
+static void xmon_en_hw_probe(int enable)
+{
+ ulong hid0;
+ int threaded = 0;
+
+ /* hopefully the hypervisor has set us up */
+ if (firmware_has_feature(FW_FEATURE_LPAR))
+ return;
+ /* should this be a feature? */
+ switch (PVR_VER(mfspr(SPRN_PVR))) {
+ default:
+ return;
+
+ case PV_POWER4:
+ case PV_POWER4p:
+ case PV_POWER5:
+ case PV_POWER5p:
+ case PV_BE:
+ /* stop both threads */
+ threaded = 1;
+ case PV_SSTAR:
+ case PV_970:
+ case PV_970FX:
+ case PV_970MP:
+ break;
+ }
+ hid0 = mfspr(SPRN_HID0);
+ if (enable) {
+ /* make sure that on threaded processors we stop both
+ * threads */
+ hid0 |= HID0_ATTN | (threaded ? HID0_QATTN : 0);
+ xmon_hw_probe_enabled = 1;
+ } else {
+ /* only turn the feature off */
+ hid0 &= ~HID0_ATTN;
+ xmon_hw_probe_enabled = 0;
+ }
+ /* many processors require the following sequence */
+ asm volatile(
+ "sync\n"
+ "mtspr %1, %0\n"
+ "mfspr %0, %1\n"
+ "mfspr %0, %1\n"
+ "mfspr %0, %1\n"
+ "mfspr %0, %1\n"
+ "mfspr %0, %1\n"
+ "mfspr %0, %1\n"
+ "isync" : "=&r" (hid0) : "i" (SPRN_HID0), "0" (hid0):
+ "memory");
+}
+#else
+#define xmon_en_hw_probe(x)
+#endif
+
static inline void sync(void)
{
asm volatile("sync; isync");
@@ -834,6 +904,11 @@ #ifdef CONFIG_PPC_STD_MMU
dump_segments();
break;
#endif
+#ifdef CONFIG_XMON_ATTN
+ case 'A':
+ xmon_hw_probe();
+ break;
+#endif
default:
printf("Unrecognized command: ");
do {
@@ -2565,6 +2640,7 @@ void xmon_init(int enable)
__debugger_dabr_match = NULL;
__debugger_fault_handler = NULL;
}
+ xmon_en_hw_probe(enable);
xmon_map_scc();
}
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index 2ea66ac..33a7922 100644
diff --git a/include/asm-powerpc/reg.h b/include/asm-powerpc/reg.h
index bd467bf..ce82965 100644
--- a/include/asm-powerpc/reg.h
+++ b/include/asm-powerpc/reg.h
@@ -207,6 +207,8 @@ #define SPRN_EAR 0x11A /* External Addr
#define SPRN_HASH1 0x3D2 /* Primary Hash Address Register */
#define SPRN_HASH2 0x3D3 /* Secondary Hash Address Resgister */
#define SPRN_HID0 0x3F0 /* Hardware Implementation Register 0 */
+#define HID0_QATTN (1UL<<35) /* Sup. Proc. attn insn all threads */
+#define HID0_ATTN (1UL<<32) /* Sup. Proc. attn insn */
#define HID0_EMCP (1<<31) /* Enable Machine Check pin */
#define HID0_EBA (1<<29) /* Enable Bus Address Parity */
#define HID0_EBD (1<<28) /* Enable Bus Data Parity */
diff --git a/include/asm-powerpc/xmon.h b/include/asm-powerpc/xmon.h
index 43f7129..cd8f48e 100644
--- a/include/asm-powerpc/xmon.h
+++ b/include/asm-powerpc/xmon.h
@@ -8,5 +8,12 @@ extern int xmon(struct pt_regs *excp);
extern void xmon_printf(const char *fmt, ...);
extern void xmon_init(int);
+/*
+ * Support Processor Attention Instruction introduced in POWER
+ * architecture processors as of RS64, tho may not be supported by
+ * POWER 3.
+ */
+#define ATTN() asm volatile(".long 0x00000200; nop")
+
#endif
#endif
^ permalink raw reply related
* [RFC] consolidated libdt proposal
From: Hollis Blanchard @ 2006-08-07 21:58 UTC (permalink / raw)
To: Mark A. Greer
Cc: Pantelis Antoniou, xen-ppc-devel@lists.xensource.com,
linuxppc-dev, linuxppc-embedded
In-Reply-To: <1154911082.27074.104.camel@diesel>
[-- Attachment #1: Type: text/plain, Size: 1206 bytes --]
On Sun, 2006-08-06 at 19:38 -0500, Hollis Blanchard wrote:
>
> Hmm, so we'll have at least three copies of this code: uboot, kernel,
> and Xen. Would it make sense to put this stuff into a libdt.a?
> Technically, dtc has a "libdt" already, but it's absurdly incomplete
> (I don't even know why it's there), so we could just replace it.
Mark, I had a look at the code Pantelis wrote for u-boot, and it was
pretty easy to adapt to meet Xen's (userspace-based) needs. I've
attached my version below (and see ft_setup() at the bottom of the
file). Does it meet your requirements for the kernel bootwrapper?
One limitation of the attached code is that it doesn't support changing
the *size* of properties, though I don't think that would be too
difficult to add if needed.
Haren, what about using this in kexec-tools?
If everybody can use this (I expect small modifications would be
needed), I think we should turn it into a library in the dtc source
tree. The various projects using it could then include snapshots (to
avoid dependencies). In general I'd like to avoid everybody writing and
maintaining their own version of this stuff (myself included).
--
Hollis Blanchard
IBM Linux Technology Center
[-- Attachment #2: ft_build.c --]
[-- Type: text/x-csrc, Size: 14053 bytes --]
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include <asm/errno.h>
#include "ft_build.h"
#define _ALIGN(addr,size) (((addr)+(size)-1)&(~((size)-1)))
static void ft_put_word(struct ft_cxt *cxt, u32 v)
{
if (cxt->overflow) /* do nothing */
return;
/* check for overflow */
if (cxt->p + 4 > cxt->pstr) {
cxt->overflow = 1;
return;
}
*(u32 *) cxt->p = cpu_to_be32(v);
cxt->p += 4;
}
static inline void ft_put_bin(struct ft_cxt *cxt, const void *data, int sz)
{
char *p;
if (cxt->overflow) /* do nothing */
return;
/* next pointer pos */
p = (char *) _ALIGN((unsigned long)cxt->p + sz, 4);
/* check for overflow */
if (p > cxt->pstr) {
cxt->overflow = 1;
return;
}
memcpy(cxt->p, data, sz);
if ((sz & 3) != 0)
memset(cxt->p + sz, 0, 4 - (sz & 3));
cxt->p = p;
}
void ft_begin_node(struct ft_cxt *cxt, const char *name)
{
ft_put_word(cxt, OF_DT_BEGIN_NODE);
ft_put_bin(cxt, name, strlen(name) + 1);
}
void ft_end_node(struct ft_cxt *cxt)
{
ft_put_word(cxt, OF_DT_END_NODE);
}
void ft_nop(struct ft_cxt *cxt)
{
ft_put_word(cxt, OF_DT_NOP);
}
static int lookup_string(struct ft_cxt *cxt, const char *name)
{
char *p;
p = cxt->pstr;
while (p < cxt->pstr_begin) {
if (strcmp(p, (char *)name) == 0)
return p - cxt->p_begin;
p += strlen(p) + 1;
}
return -1;
}
void ft_prop(struct ft_cxt *cxt, const char *name, const void *data, int sz)
{
int len, off;
if (cxt->overflow)
return;
len = strlen(name) + 1;
off = lookup_string(cxt, name);
if (off == -1) {
/* check if we have space */
if (cxt->p + 12 + sz + len > cxt->pstr) {
cxt->overflow = 1;
return;
}
cxt->pstr -= len;
memcpy(cxt->pstr, name, len);
off = cxt->pstr - cxt->p_begin;
}
/* now put offset from beginning of *STRUCTURE* */
/* will be fixed up at the end */
ft_put_word(cxt, OF_DT_PROP);
ft_put_word(cxt, sz);
ft_put_word(cxt, off);
ft_put_bin(cxt, data, sz);
}
void ft_prop_str(struct ft_cxt *cxt, const char *name, const char *str)
{
ft_prop(cxt, name, str, strlen(str) + 1);
}
void ft_prop_int(struct ft_cxt *cxt, const char *name, int val)
{
u32 v = cpu_to_be32((u32) val);
ft_prop(cxt, name, &v, 4);
}
/* start construction of the flat OF tree */
void ft_begin(struct ft_cxt *cxt, void *blob, int max_size)
{
struct boot_param_header *bph = blob;
u32 off;
/* clear the cxt */
memset(cxt, 0, sizeof(*cxt));
cxt->bph = bph;
cxt->max_size = max_size;
/* zero everything in the header area */
memset(bph, 0, sizeof(*bph));
bph->magic = cpu_to_be32(OF_DT_HEADER);
bph->version = cpu_to_be32(0x10);
bph->last_comp_version = cpu_to_be32(0x10);
/* start pointers */
cxt->pres_begin = (char *) _ALIGN((unsigned long)(bph + 1), 8);
cxt->pres = cxt->pres_begin;
off = (unsigned long)cxt->pres_begin - (unsigned long)bph;
bph->off_mem_rsvmap = cpu_to_be32(off);
((u64 *) cxt->pres)[0] = 0; /* phys = 0, size = 0, terminate */
((u64 *) cxt->pres)[1] = 0;
cxt->p_anchor = cxt->pres + 16; /* over the terminator */
}
/* add a reserver physical area to the rsvmap */
void ft_add_rsvmap(struct ft_cxt *cxt, u64 physaddr, u64 size)
{
((u64 *) cxt->pres)[0] = cpu_to_be64(physaddr); /* phys = 0, size = 0, terminate */
((u64 *) cxt->pres)[1] = cpu_to_be64(size);
cxt->pres += 18; /* advance */
((u64 *) cxt->pres)[0] = 0; /* phys = 0, size = 0, terminate */
((u64 *) cxt->pres)[1] = 0;
/* keep track of size */
cxt->res_size = cxt->pres + 16 - cxt->pres_begin;
cxt->p_anchor = cxt->pres + 16; /* over the terminator */
}
void ft_begin_tree(struct ft_cxt *cxt)
{
cxt->p_begin = cxt->p_anchor;
cxt->pstr_begin = (char *)cxt->bph + cxt->max_size; /* point at the end */
cxt->p = cxt->p_begin;
cxt->pstr = cxt->pstr_begin;
}
int ft_end_tree(struct ft_cxt *cxt)
{
struct boot_param_header *bph = cxt->bph;
int off, sz, sz1;
u32 tag, v;
char *p;
ft_put_word(cxt, OF_DT_END);
if (cxt->overflow)
return -ENOMEM;
/* size of the areas */
cxt->struct_size = cxt->p - cxt->p_begin;
cxt->strings_size = cxt->pstr_begin - cxt->pstr;
/* the offset we must move */
off = (cxt->pstr_begin - cxt->p_begin) - cxt->strings_size;
/* the new strings start */
cxt->pstr_begin = cxt->p_begin + cxt->struct_size;
/* move the whole string area */
memmove(cxt->pstr_begin, cxt->pstr, cxt->strings_size);
/* now perform the fixup of the strings */
p = cxt->p_begin;
while ((tag = be32_to_cpu(*(u32 *) p)) != OF_DT_END) {
p += 4;
if (tag == OF_DT_BEGIN_NODE) {
p = (char *) _ALIGN((unsigned long)p + strlen(p) + 1, 4);
continue;
}
if (tag == OF_DT_END_NODE || tag == OF_DT_NOP)
continue;
if (tag != OF_DT_PROP)
return -EINVAL;
sz = be32_to_cpu(*(u32 *) p);
p += 4;
v = be32_to_cpu(*(u32 *) p);
v -= off;
*(u32 *) p = cpu_to_be32(v); /* move down */
p += 4;
p = (char *) _ALIGN((unsigned long)p + sz, 4);
}
/* fix sizes */
p = (char *)cxt->bph;
sz = (cxt->pstr_begin + cxt->strings_size) - p;
sz1 = _ALIGN(sz, 16); /* align at 16 bytes */
if (sz != sz1)
memset(p + sz, 0, sz1 - sz);
bph->totalsize = cpu_to_be32(sz1);
bph->off_dt_struct = cpu_to_be32(cxt->p_begin - p);
bph->off_dt_strings = cpu_to_be32(cxt->pstr_begin - p);
/* the new strings start */
cxt->pstr_begin = cxt->p_begin + cxt->struct_size;
cxt->pstr = cxt->pstr_begin + cxt->strings_size;
return 0;
}
/**********************************************************************/
static inline int isprint(int c)
{
return c >= 0x20 && c <= 0x7e;
}
static int is_printable_string(const void *data, int len)
{
const char *s = data;
const char *ss;
/* zero length is not */
if (len == 0)
return 0;
/* must terminate with zero */
if (s[len - 1] != '\0')
return 0;
ss = s;
while (*s && isprint(*s))
s++;
/* not zero, or not done yet */
if (*s != '\0' || (s + 1 - ss) < len)
return 0;
return 1;
}
static void print_data(const void *data, int len)
{
int i;
const char *s;
/* no data, don't print */
if (len == 0)
return;
if (is_printable_string(data, len)) {
printf(" = \"%s\"", (char *)data);
return;
}
switch (len) {
case 1: /* byte */
printf(" = <0x%02x>", (*(char *) data) & 0xff);
break;
case 2: /* half-word */
printf(" = <0x%04x>", be16_to_cpu(*(u16 *) data) & 0xffff);
break;
case 4: /* word */
printf(" = <0x%08x>", be32_to_cpu(*(u32 *) data) & 0xffffffffU);
break;
case 8: /* double-word */
printf(" = <0x%16llx>", be64_to_cpu(*(u64 *) data));
break;
default: /* anything else... hexdump */
printf(" = [");
for (i = 0, s = data; i < len; i++)
printf("%02x%s", s[i], i < len - 1 ? " " : "");
printf("]");
break;
}
}
void ft_dump_blob(const void *bphp)
{
const struct boot_param_header *bph = bphp;
const u64 *p_rsvmap = (const u64 *)
((const char *)bph + be32_to_cpu(bph->off_mem_rsvmap));
const u32 *p_struct = (const u32 *)
((const char *)bph + be32_to_cpu(bph->off_dt_struct));
const u32 *p_strings = (const u32 *)
((const char *)bph + be32_to_cpu(bph->off_dt_strings));
u32 tag;
const u32 *p;
const char *s, *t;
int depth, sz, shift;
int i;
u64 addr, size;
if (be32_to_cpu(bph->magic) != OF_DT_HEADER) {
/* not valid tree */
return;
}
depth = 0;
shift = 4;
for (i = 0;; i++) {
addr = be64_to_cpu(p_rsvmap[i * 2]);
size = be64_to_cpu(p_rsvmap[i * 2 + 1]);
if (addr == 0 && size == 0)
break;
printf("/memreserve/ 0x%llx 0x%llx;\n", addr, size);
}
p = p_struct;
while ((tag = be32_to_cpu(*p++)) != OF_DT_END) {
/* printf("tag: 0x%08x (%d)\n", tag, p - p_struct); */
if (tag == OF_DT_BEGIN_NODE) {
s = (const char *)p;
p = (u32 *) _ALIGN((unsigned long)p + strlen(s) + 1, 4);
printf("%*s%s {\n", depth * shift, "", s);
depth++;
continue;
}
if (tag == OF_DT_END_NODE) {
depth--;
printf("%*s};\n", depth * shift, "");
continue;
}
if (tag == OF_DT_NOP) {
printf("%*s[NOP]\n", depth * shift, "");
continue;
}
if (tag != OF_DT_PROP) {
fprintf(stderr, "%*s ** Unknown tag 0x%08x\n",
depth * shift, "", tag);
break;
}
sz = be32_to_cpu(*p++);
s = (const char *)p_strings + be32_to_cpu(*p++);
t = (const char *)p;
p = (const u32 *)_ALIGN((unsigned long)p + sz, 4);
printf("%*s%s", depth * shift, "", s);
print_data(t, sz);
printf(";\n");
}
}
void ft_backtrack_node(struct ft_cxt *cxt)
{
if (be32_to_cpu(*(u32 *) (cxt->p - 4)) != OF_DT_END_NODE)
return; /* XXX only for node */
cxt->p -= 4;
}
/* note that the root node of the blob is "peeled" off */
void ft_merge_blob(struct ft_cxt *cxt, void *blob)
{
struct boot_param_header *bph = (struct boot_param_header *)blob;
u32 *p_struct = (u32 *) ((char *)bph + be32_to_cpu(bph->off_dt_struct));
u32 *p_strings =
(u32 *) ((char *)bph + be32_to_cpu(bph->off_dt_strings));
u32 tag, *p;
char *s, *t;
int depth, sz;
if (be32_to_cpu(*(u32 *) (cxt->p - 4)) != OF_DT_END_NODE)
return; /* XXX only for node */
cxt->p -= 4;
depth = 0;
p = p_struct;
while ((tag = be32_to_cpu(*p++)) != OF_DT_END) {
/* printf("tag: 0x%08x (%d) - %d\n", tag, p - p_struct, depth); */
if (tag == OF_DT_BEGIN_NODE) {
s = (char *)p;
p = (u32 *) _ALIGN((unsigned long)p + strlen(s) + 1, 4);
if (depth++ > 0)
ft_begin_node(cxt, s);
continue;
}
if (tag == OF_DT_END_NODE) {
ft_end_node(cxt);
if (--depth == 0)
break;
continue;
}
if (tag == OF_DT_NOP)
continue;
if (tag != OF_DT_PROP)
break;
sz = be32_to_cpu(*p++);
s = (char *)p_strings + be32_to_cpu(*p++);
t = (char *)p;
p = (u32 *) _ALIGN((unsigned long)p + sz, 4);
ft_prop(cxt, s, t, sz);
}
}
void *ft_get_prop(void *bphp, const char *propname, int *szp)
{
struct boot_param_header *bph = bphp;
u32 *p_struct =
(u32 *) ((char *)bph + be32_to_cpu(bph->off_dt_struct));
u32 *p_strings =
(u32 *) ((char *)bph + be32_to_cpu(bph->off_dt_strings));
u32 version = be32_to_cpu(bph->version);
u32 tag;
u32 *p;
char *s, *t;
char *ss;
int sz;
static char path[256], prop[256];
path[0] = '\0';
p = p_struct;
while ((tag = be32_to_cpu(*p++)) != OF_DT_END) {
if (tag == OF_DT_BEGIN_NODE) {
s = (char *)p;
p = (u32 *) _ALIGN((unsigned long)p + strlen(s) +
1, 4);
strcat(path, s);
strcat(path, "/");
continue;
}
if (tag == OF_DT_END_NODE) {
path[strlen(path) - 1] = '\0';
ss = strrchr(path, '/');
if (ss != NULL)
ss[1] = '\0';
continue;
}
if (tag == OF_DT_NOP)
continue;
if (tag != OF_DT_PROP)
break;
sz = be32_to_cpu(*p++);
s = (char *)p_strings + be32_to_cpu(*p++);
if (version < 0x10 && sz >= 8)
p = (u32 *) _ALIGN((unsigned long)p, 8);
t = (char *)p;
p = (u32 *) _ALIGN((unsigned long)p + sz, 4);
strcpy(prop, path);
strcat(prop, s);
if (strcmp(prop, propname) == 0) {
*szp = sz;
return t;
}
}
return NULL;
}
/********************************************************************/
#if 0
extern unsigned char oftree_dtb[];
extern unsigned int oftree_dtb_len;
void ft_setup(void *blob, int size, bd_t * bd)
{
DECLARE_GLOBAL_DATA_PTR;
char *end;
u32 *p;
int len;
struct ft_cxt cxt;
int i, k, nxt;
static char tmpenv[256];
char *s, *lval, *rval;
ulong clock;
u32 v;
/* disable OF tree; booting old kernel */
if (getenv("disable_of") != NULL) {
memcpy(blob, bd, sizeof(*bd));
return;
}
ft_begin(&cxt, blob, size);
/* fs_add_rsvmap not used */
ft_begin_tree(&cxt);
ft_begin_node(&cxt, "");
ft_end_node(&cxt);
/* copy RO tree */
ft_merge_blob(&cxt, oftree_dtb);
/* back into root */
ft_backtrack_node(&cxt);
ft_begin_node(&cxt, "u-boot-env");
for (i = 0; env_get_char(i) != '\0'; i = nxt + 1) {
for (nxt = i; env_get_char(nxt) != '\0'; ++nxt) ;
s = tmpenv;
for (k = i; k < nxt && s < &tmpenv[sizeof(tmpenv) - 1]; ++k)
*s++ = env_get_char(k);
*s++ = '\0';
lval = tmpenv;
s = strchr(tmpenv, '=');
if (s != NULL) {
*s++ = '\0';
rval = s;
} else
continue;
ft_prop_str(&cxt, lval, rval);
}
ft_end_node(&cxt);
ft_begin_node(&cxt, "chosen");
ft_prop_str(&cxt, "name", "chosen");
ft_prop_str(&cxt, "bootargs", getenv("bootargs"));
ft_prop_int(&cxt, "linux,platform", 0x600); /* what is this? */
ft_end_node(&cxt);
ft_end_node(&cxt); /* end root */
ft_end_tree(&cxt);
/*
printf("merged OF-tree\n");
ft_dump_blob(blob);
*/
/* paste the bd_t at the end of the flat tree */
end = (char *)blob +
be32_to_cpu(((struct boot_param_header *)blob)->totalsize);
memcpy(end, bd, sizeof(*bd));
#ifdef CONFIG_PPC
for (i = 0; i < sizeof(bd_map)/sizeof(bd_map[0]); i++) {
sprintf(tmpenv, "/bd_t/%s", bd_map[i].name);
v = *(u32 *)((char *)bd + bd_map[i].offset);
p = ft_get_prop(blob, tmpenv, &len);
if (p != NULL)
*p = cpu_to_be32(v);
}
p = ft_get_prop(blob, "/bd_t/enetaddr", &len);
if (p != NULL)
memcpy(p, bd->bi_enetaddr, 6);
p = ft_get_prop(blob, "/bd_t/ethspeed", &len);
if (p != NULL)
*p = cpu_to_be32((u32) bd->bi_ethspeed);
clock = bd->bi_intfreq;
p = ft_get_prop(blob, "/cpus/" OF_CPU "/clock-frequency", &len);
if (p != NULL)
*p = cpu_to_be32(clock);
#ifdef OF_TBCLK
clock = OF_TBCLK;
p = ft_get_prop(blob, "/cpus/" OF_CPU "/timebase-frequency", &len);
if (p != NULL)
*p = cpu_to_be32(OF_TBCLK);
#endif
#endif /* __powerpc__ */
/*
printf("final OF-tree\n");
ft_dump_blob(blob);
*/
}
#endif
[-- Attachment #3: ft_build.h --]
[-- Type: text/x-chdr, Size: 4308 bytes --]
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef FT_BUILD_H
#define FT_BUILD_H
#include <endian.h>
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long long u64;
static inline u16 swab16(u16 x)
{
return (((u16)(x) & (u16)0x00ffU) << 8) |
(((u16)(x) & (u16)0xff00U) >> 8);
}
static inline u32 swab32(u32 x)
{
return (((u32)(x) & (u32)0x000000ffUL) << 24) |
(((u32)(x) & (u32)0x0000ff00UL) << 8) |
(((u32)(x) & (u32)0x00ff0000UL) >> 8) |
(((u32)(x) & (u32)0xff000000UL) >> 24);
}
static inline u64 swab64(u64 x)
{
return (u64)(((u64)(x) & (u64)0x00000000000000ffULL) << 56) |
(u64)(((u64)(x) & (u64)0x000000000000ff00ULL) << 40) |
(u64)(((u64)(x) & (u64)0x0000000000ff0000ULL) << 24) |
(u64)(((u64)(x) & (u64)0x00000000ff000000ULL) << 8) |
(u64)(((u64)(x) & (u64)0x000000ff00000000ULL) >> 8) |
(u64)(((u64)(x) & (u64)0x0000ff0000000000ULL) >> 24) |
(u64)(((u64)(x) & (u64)0x00ff000000000000ULL) >> 40) |
(u64)(((u64)(x) & (u64)0xff00000000000000ULL) >> 56);
}
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define cpu_to_be16(x) swab16(x)
#define be16_to_cpu(x) swab16(x)
#define cpu_to_be32(x) swab32(x)
#define be32_to_cpu(x) swab32(x)
#define cpu_to_be64(x) swab64(x)
#define be64_to_cpu(x) swab64(x)
#else
#define cpu_to_be16(x) (x)
#define be16_to_cpu(x) (x)
#define cpu_to_be32(x) (x)
#define be32_to_cpu(x) (x)
#define cpu_to_be64(x) (x)
#define be64_to_cpu(x) (x)
#endif
/* Definitions used by the flattened device tree */
#define OF_DT_HEADER 0xd00dfeed /* marker */
#define OF_DT_BEGIN_NODE 0x1 /* Start of node, full name */
#define OF_DT_END_NODE 0x2 /* End node */
#define OF_DT_PROP 0x3 /* Property: name off, size, content */
#define OF_DT_NOP 0x4 /* nop */
#define OF_DT_END 0x9
#define OF_DT_VERSION 0x10
struct boot_param_header {
u32 magic; /* magic word OF_DT_HEADER */
u32 totalsize; /* total size of DT block */
u32 off_dt_struct; /* offset to structure */
u32 off_dt_strings; /* offset to strings */
u32 off_mem_rsvmap; /* offset to memory reserve map */
u32 version; /* format version */
u32 last_comp_version; /* last compatible version */
/* version 2 fields below */
u32 boot_cpuid_phys; /* Physical CPU id we're booting on */
/* version 3 fields below */
u32 dt_strings_size; /* size of the DT strings block */
};
struct ft_cxt {
struct boot_param_header *bph;
int max_size; /* maximum size of tree */
int overflow; /* set when this happens */
char *p, *pstr, *pres; /* running pointers */
char *p_begin, *pstr_begin, *pres_begin; /* starting pointers */
char *p_anchor; /* start of constructed area */
int struct_size, strings_size, res_size;
};
void ft_begin_node(struct ft_cxt *cxt, const char *name);
void ft_end_node(struct ft_cxt *cxt);
void ft_begin_tree(struct ft_cxt *cxt);
int ft_end_tree(struct ft_cxt *cxt);
void ft_nop(struct ft_cxt *cxt);
void ft_prop(struct ft_cxt *cxt, const char *name, const void *data, int sz);
void ft_prop_str(struct ft_cxt *cxt, const char *name, const char *str);
void ft_prop_int(struct ft_cxt *cxt, const char *name, int val);
void ft_begin(struct ft_cxt *cxt, void *blob, int max_size);
void ft_add_rsvmap(struct ft_cxt *cxt, u64 physaddr, u64 size);
void ft_dump_blob(const void *bphp);
void ft_merge_blob(struct ft_cxt *cxt, void *blob);
void *ft_get_prop(void *bphp, const char *propname, int *szp);
void ft_set_prop(void *bphp, const char *propname, void *val, int len);
#endif
^ permalink raw reply
* Re: [RFC] Debugging with a HW probe.
From: Olof Johansson @ 2006-08-07 23:06 UTC (permalink / raw)
To: Jimi Xenidis; +Cc: linuxppc-dev
In-Reply-To: <E1G9jpY-0004Nv-2d@kmac.watson.ibm.com>
Hi,
On Sun, Aug 06, 2006 at 10:42:16AM -0400, Jimi Xenidis wrote:
> On IBM POWER4 and greater processors (and possibly POWER3 and *Star)
> there is an instruction called ATTN (asm (".long 0x200")) that will
> have the process call out to the HW probe. This instruction is used
> by RiscWatch software to set "soft breakpoints".
>
> We have found it useful to teach xmon to make this call so we can then
> debug the SW thru the probe. Is this useful to anyone else?
Being able to correlate software events with the hardware debugger looks
quite useful, yes.
> Below is a quick attempt at a formalized patch, tho' I am torn between
> making it ATTN specific or just making a generic HW Probe Service.
I would say make it generic, maybe with cputables entry or ppc_md
member, especially with the powerpc merge and other platforms coming in,
having it more generic could be useful.
Also, that way you could get rid of the PVR check within xmon.
> All comments welcome.
A couple below.
> +static void xmon_en_hw_probe(int enable)
> +{
> + ulong hid0;
> + int threaded = 0;
> +
> + /* hopefully the hypervisor has set us up */
> + if (firmware_has_feature(FW_FEATURE_LPAR))
> + return;
> + /* should this be a feature? */
> + switch (PVR_VER(mfspr(SPRN_PVR))) {
> + default:
> + return;
> +
> + case PV_POWER4:
> + case PV_POWER4p:
> + case PV_POWER5:
> + case PV_POWER5p:
> + case PV_BE:
> + /* stop both threads */
> + threaded = 1;
POWER4 multithreaded? I don't think so?
> + case PV_SSTAR:
Trailing whitespace. Also, doesn't sstar have HMT?
> + case PV_970:
> + case PV_970FX:
> + case PV_970MP:
> + break;
> + }
> + hid0 = mfspr(SPRN_HID0);
> + if (enable) {
> + /* make sure that on threaded processors we stop both
> + * threads */
> + hid0 |= HID0_ATTN | (threaded ? HID0_QATTN : 0);
> + xmon_hw_probe_enabled = 1;
> + } else {
> + /* only turn the feature off */
> + hid0 &= ~HID0_ATTN;
> + xmon_hw_probe_enabled = 0;
> + }
> + /* many processors require the following sequence */
> + asm volatile(
> + "sync\n"
> + "mtspr %1, %0\n"
> + "mfspr %0, %1\n"
> + "mfspr %0, %1\n"
> + "mfspr %0, %1\n"
> + "mfspr %0, %1\n"
> + "mfspr %0, %1\n"
> + "mfspr %0, %1\n"
> + "isync" : "=&r" (hid0) : "i" (SPRN_HID0), "0" (hid0):
> + "memory");
> +}
> +#else
> +#define xmon_en_hw_probe(x)
> +#endif
> +
> static inline void sync(void)
> {
> asm volatile("sync; isync");
> @@ -834,6 +904,11 @@ #ifdef CONFIG_PPC_STD_MMU
> dump_segments();
> break;
> #endif
> +#ifdef CONFIG_XMON_ATTN
> + case 'A':
> + xmon_hw_probe();
> + break;
> +#endif
> default:
> printf("Unrecognized command: ");
> do {
> @@ -2565,6 +2640,7 @@ void xmon_init(int enable)
> __debugger_dabr_match = NULL;
> __debugger_fault_handler = NULL;
> }
> + xmon_en_hw_probe(enable);
Please only enable this right before the call.
> xmon_map_scc();
> }
>
> diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
> index 2ea66ac..33a7922 100644
> diff --git a/include/asm-powerpc/reg.h b/include/asm-powerpc/reg.h
> index bd467bf..ce82965 100644
> --- a/include/asm-powerpc/reg.h
> +++ b/include/asm-powerpc/reg.h
> @@ -207,6 +207,8 @@ #define SPRN_EAR 0x11A /* External Addr
> #define SPRN_HASH1 0x3D2 /* Primary Hash Address Register */
> #define SPRN_HASH2 0x3D3 /* Secondary Hash Address Resgister */
> #define SPRN_HID0 0x3F0 /* Hardware Implementation Register 0 */
> +#define HID0_QATTN (1UL<<35) /* Sup. Proc. attn insn all threads */
> +#define HID0_ATTN (1UL<<32) /* Sup. Proc. attn insn */
> #define HID0_EMCP (1<<31) /* Enable Machine Check pin */
> #define HID0_EBA (1<<29) /* Enable Bus Address Parity */
> #define HID0_EBD (1<<28) /* Enable Bus Data Parity */
> diff --git a/include/asm-powerpc/xmon.h b/include/asm-powerpc/xmon.h
> index 43f7129..cd8f48e 100644
> --- a/include/asm-powerpc/xmon.h
> +++ b/include/asm-powerpc/xmon.h
> @@ -8,5 +8,12 @@ extern int xmon(struct pt_regs *excp);
> extern void xmon_printf(const char *fmt, ...);
> extern void xmon_init(int);
>
> +/*
> + * Support Processor Attention Instruction introduced in POWER
> + * architecture processors as of RS64, tho may not be supported by
> + * POWER 3.
> + */
> +#define ATTN() asm volatile(".long 0x00000200; nop")
At least my toolchain understands "attn ; nop"?
-Olof
^ permalink raw reply
* Re: [PATCH 1/6] bootwrapper: arch/powerpc/boot code reorg
From: Mark A. Greer @ 2006-08-08 0:16 UTC (permalink / raw)
To: Hollis Blanchard; +Cc: linuxppc-dev, xen-ppc-devel@lists.xensource.com
In-Reply-To: <1154910111.27074.87.camel@diesel>
On Sun, Aug 06, 2006 at 07:21:51PM -0500, Hollis Blanchard wrote:
> On Wed, 2006-07-19 at 16:00 -0700, an unknown sender wrote:
> > diff --git a/arch/powerpc/boot/types.h b/arch/powerpc/boot/types.h
> > new file mode 100644
> > index 0000000..2a2fa2b
> > --- /dev/null
> > +++ b/arch/powerpc/boot/types.h
> > @@ -0,0 +1,29 @@
> > +#ifndef _TYPES_H_
> > +#define _TYPES_H_
> > +
> > +#define COMMAND_LINE_SIZE 512
> > +#define MAX_PATH_LEN 256
> > +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
> > +
> > +typedef unsigned char u8;
> > +typedef unsigned short u16;
> > +typedef unsigned int u32;
> > +#ifdef __powerpc64__
> > +typedef unsigned long u64;
> > +#else
> > +typedef unsigned long long u64;
> > +#endif
>
> As long as we're adding new typedefs, could we please use the stdint.h
> ones (e.g. uint32_t)? For Xen, I need to do flat tree munging in
> userspace, so using real types would help with code reuse.
Sure, I can do that unless someone objects.
Mark
^ permalink raw reply
* Re: [PATCH 1/6] bootwrapper: arch/powerpc/boot code reorg
From: Mark A. Greer @ 2006-08-08 0:15 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
In-Reply-To: <17622.57931.631871.287907@cargo.ozlabs.ibm.com>
On Mon, Aug 07, 2006 at 04:48:43PM +1000, Paul Mackerras wrote:
> Mark A. Greer writes:
>
> > I realize that I didn't really answer your question. Its at least
> > possible that the console driver could not be known at link time.
> >
> > An example I used in another email is a platform that has 4 serial
> > ports, 2-16550 and 2-mpsc, say. The /chosen/linux,stdout-path could
> > pick any of the four so you would need to compile in a low-level
> > serial driver for both and hook the correct one up at runtime.
> >
> > Same could be said for a serial vs. video console.
>
> OK, that's reasonable. Still would be nice not to have to do the
> double dereference though.
Yep, I'll get rid of the double dereference.
> I think that the platform_ops and the
> fw_ops could probably be combined.
Okay.
> Also, an init method for the
> platform/fw_ops would be useful
Hm, I don't understand what you mean here. I already have
'platform_init()' called from start(). Is that not sufficient?
> - it would let us remove the kludge
> you have in the OF malloc implementation.
The OF malloc routine was a straight copy of what was already
in try_claim() in main.c. As I look at try_claim() now, though,
I see that its changed. I can get rid of that code inside the
"#if defined(PROG_START)". Is that the kludge you were referring to?
> The OF malloc is currently applying a minimum address constraint for
> all platforms, where it used to apply it only for 64-bit platforms.
> We need to fix that up somehow too.
Okay.
Mark
^ permalink raw reply
* Re: [PATCH 3/6] bootwrapper: Add device tree ops for flattened device tree
From: Mark A. Greer @ 2006-08-08 0:30 UTC (permalink / raw)
To: Hollis Blanchard; +Cc: linuxppc-dev, xen-ppc-devel@lists.xensource.com
In-Reply-To: <1154911082.27074.104.camel@diesel>
On Sun, Aug 06, 2006 at 07:38:02PM -0500, Hollis Blanchard wrote:
> On Wed, 2006-07-19 at 16:05 -0700, an unknown sender wrote:
> > --- /dev/null
> > +++ b/arch/powerpc/boot/fdt.c
> > @@ -0,0 +1,525 @@
> > +/*
> > + * Simple dtb (binary flattened device tree) search/manipulation routines.
> > + *
> > + * Author: Mark A. Greer <mgreer at mvista.com>
> > + * - The code for strrchr() was copied from lib/string.c and is
> > + * copyrighted by Linus Torvalds.
> > + * - The smarts for fdt_finddevice() were copied with the author's
> > + * permission from u-boot:common/ft_build.c which was written by
> > + * Pantelis Antoniou <pantelis at embeddedalley.com>.
>
> Hmm, so we'll have at least three copies of this code: uboot, kernel,
> and Xen. Would it make sense to put this stuff into a libdt.a?
Yes, it would.
> Technically, dtc has a "libdt" already, but it's absurdly incomplete (I
> don't even know why it's there), so we could just replace it.
Sounds like a plan!
> Xen needs all the finddevice and setprop functionality here, which looks
> like it's about 2/3rds of this code.
Yeah, pretty much.
> > +static void *dtb_start;
> > +static void *dtb_end;
>
> I'd like to avoid the use of globals here. I know it's fine when you're
> running in early boot, but as I mentioned I'd like to copy this code
> elsewhere. Could these be moved into a structure that's passed as a
> function parameter?
Sure.
> > +static void
> > +fdt_modify_prop(u32 *dp, char *datap, u32 *old_prop_sizep, char *buf,
> > + int buflen)
> > +{
> > + u32 old_prop_data_len, new_prop_data_len;
> > +
> > + old_prop_data_len = _ALIGN_UP(*old_prop_sizep, 4);
> > + new_prop_data_len = _ALIGN_UP(buflen, 4);
> > +
> > + /* Check if new prop data fits in old prop data area */
> > + if (new_prop_data_len == old_prop_data_len) {
> > + memcpy(datap, buf, buflen);
> > + *old_prop_sizep = buflen;
> > + }
> > + else { /* Need to alloc new area to put larger or smaller fdt */
> > + struct boot_param_header *old_bph, *new_bph;
> > + u32 *old_tailp, *new_tailp, *new_datap;
> > + u32 old_total_size, new_total_size, head_len, tail_len, diff;
> > + void *new_dtb_start, *new_dtb_end;
> > +
> > + old_bph = fdt_get_bph(dtb_start),
> > + old_total_size = old_bph->totalsize;
> > + head_len = (u32)datap - (u32)dtb_start;
> > + tail_len = old_total_size - (head_len + old_prop_data_len);
> > + old_tailp = (u32 *)((u32)dtb_end - tail_len);
> > + new_total_size = head_len + new_prop_data_len + tail_len;
> > +
> > + if (!(new_dtb_start = malloc(new_total_size))) {
> > + printf("Can't alloc space for new fdt\n\r");
> > + exit();
> > + }
> > +
> > + new_dtb_end = (void *)((u32)new_dtb_start + new_total_size);
> > + new_datap = (u32 *)((u32)new_dtb_start + head_len);
> > + new_tailp = (u32 *)((u32)new_dtb_end - tail_len);
> > +
> > + memcpy(new_dtb_start, dtb_start, head_len);
> > + memcpy(new_datap, buf, buflen);
> > + memcpy(new_tailp, old_tailp, tail_len);
> > + *(new_datap - 2) = buflen;
> > +
> > + new_bph = fdt_get_bph(new_dtb_start),
> > + new_bph->totalsize = new_total_size;
> > +
> > + diff = new_prop_data_len - old_prop_data_len;
> > +
> > + /* Adjust offsets of other sections, if necessary */
> > + if (new_bph->off_dt_strings > new_bph->off_dt_struct)
> > + new_bph->off_dt_strings += diff;
> > +
> > + if (new_bph->off_mem_rsvmap > new_bph->off_dt_struct)
> > + new_bph->off_mem_rsvmap += diff;
> > +
> > + free(dtb_start, old_total_size);
> > +
> > + dtb_start = new_dtb_start;
> > + dtb_end = new_dtb_end;
> > + }
> > +}
>
> I didn't realize the boot wrapper had a full malloc() to work with.
It doesn't (really). I made a standard interface to what may
someday be a real memory allocator. If you look in dink.c,
you'll see I just have a hack malloc() and no free() at all.
Its one of those things that I was hoping someone would chip in
and help with. IIRC, Matt McClintock was looking at that but I'm
not sure how far he got.
> I
> was actually planning to only allow overwriting properties with values
> of the same size, since for the most part I just need to modify some
> small fixed-size data. Do you need more? I guess if the code already
> works...
I know that we need to extend the size of a property because
/chosen/bootargs can be edited and potentially extended.
Mark
^ permalink raw reply
* Re: [PATCH] SLB shadow buffer
From: Milton Miller @ 2006-08-08 1:15 UTC (permalink / raw)
To: mikey, linuxppc-dev; +Cc: paulus, anton, miltonm
On Mon Aug 7 2006 01:19:19 AM CDT, Michael Neuling wrote:
> Updated with comments from Milton.
Better
> +#define SHADOW_SLB_BOLTED_STACK_ESID \
> + (SLBSHADOW_SAVEAREA + 0x10*(SLB_NUM_BOLTED-1))
> +#define SHADOW_SLB_BOLTED_STACK_VSID \
> + (SLBSHADOW_SAVEAREA + 0x10*(SLB_NUM_BOLTED-1) + 8)
> +
Still a bit of magic size, but not likely to change.
Maybe an expicit define for the slot?
> + /* Update the last bolted SLB */
> + ld r9,PACA_SLBSHADOWPTR(r13)
> + li r12,0
> + std r12,SHADOW_SLB_BOLTED_STACK_ESID(r9) /* Clear ESID */
> + std r7,SHADOW_SLB_BOLTED_STACK_VSID(r9) /* Save VSID */
> + std r0,SHADOW_SLB_BOLTED_STACK_ESID(r9) /* Save ESID */
> +
Still some leading spaces hiding
> Index: linux-2.6-ozlabs/include/asm-powerpc/lppaca.h
> @@ -133,5 +135,22 @@ struct > > > lppaca {
>
> extern struct lppaca lppaca[];
>
> +/*
> + * SLB shadow buffer structure as defined in the PAPR. The save_area
> + * contains adjacent ESID and VSID pairs for each shadowed SLB. The
> + * ESID is stored in the lower 64bits, then the VSID.
> + */
> +struct slb_shadow {
> + u32 persistent; // Number of persistent SLBs x00-x03
> + u32 buffer_length; // Total shadow buffer length x04-x07
> + u64 reserved; // Alignment x08-x0f
> + struct {
> + u64 esid;
> + u64 vsid;
> + } save_area[SLB_NUM_BOLTED]; // x10-x40
> +} ____cacheline_aligned;
> +
C comments ... or in the separate cleanup patch
> +extern struct slb_shadow slb_shadow[];
> +
> #endif /* __KERNEL__ */
> #endif /* _ASM_POWERPC_LPPACA_H */
> Index: linux-2.6-ozlabs/include/asm-powerpc/paca.h
> ===================================================================
>
> /* accumulated system TB ticks */
> u64 startpurr; /* PURR/TB value snapshot */
> +
> + struct slb_shadow *slb_shadow_ptr;
> };
Do we need the extra line? (I haven't looked at the result)
milton
^ permalink raw reply
* Re: [PATCH] Update lppaca offset comments
From: Milton Miller @ 2006-08-08 1:22 UTC (permalink / raw)
To: mikey, paulus; +Cc: linuxppc-dev
On Mon Aug 7 2006 02:34:50 AM CDT, Michael Neuling wrote:
> Update offset comments. No functional change.
>
> Signed-off-by: Michael Neuling <mikey@neuling.org>
> ---
> include/asm-powerpc/lppaca.h | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> Index: linux-2.6-ozlabs/include/asm-powerpc/lppaca.h
> ===================================================================
> --- linux-2.6-ozlabs.orig/include/asm-powerpc/lppaca.h
> +++ linux-2.6-ozlabs/include/asm-powerpc/lppaca.h
> @@ -114,7 +114,7 @@ struct lppaca {
>
>
> //=============================================================================
> -// CACHE_LINE_3 0x0100 - 0x007F: This line is shared with other processors
> +// CACHE_LINE_3 0x0100 - 0x017F: This line is shared with other processors
> //=============================================================================
How about taking the opertunity to convert to C comments?
milton
^ permalink raw reply
* [PATCH] Change panic_on_oops message to "Fatal exception"
From: Horms @ 2006-08-08 3:46 UTC (permalink / raw)
To: Russell King, Tony Luck, Paul Mackerras, Anton Blanchard,
Andi Kleen, Chris Zankel, Andrew Morton
Cc: linuxppc-dev, linux-ia64, linux-kernel, discuss
Change panic_on_oops message to "Fatal exception"
Previously the message was "Fatal exception: panic_on_oops", as introduced
in a recent patch whith removed a somewhat dangerous call to ssleep() in
the panic_on_oops path. However, Paul Mackerras suggested that this was
somewhat confusing, leadind people to believe that it was panic_on_oops
that was the root cause of the fatal exception. On his suggestion, this
patch changes the message to simply "Fatal exception". A suitable oops
message should already have been displayed.
Signed-off-by: Simon Horman <horms@verge.net.au>
---
arch/arm/kernel/traps.c | 2 +-
arch/i386/kernel/traps.c | 2 +-
arch/ia64/kernel/traps.c | 2 +-
arch/powerpc/kernel/traps.c | 2 +-
arch/x86_64/kernel/traps.c | 2 +-
arch/xtensa/kernel/traps.c | 2 +-
6 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 4e29dd0..aeeed80 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -233,7 +233,7 @@ NORET_TYPE void die(const char *str, str
spin_unlock_irq(&die_lock);
if (panic_on_oops)
- panic("Fatal exception: panic_on_oops");
+ panic("Fatal exception");
do_exit(SIGSEGV);
}
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index 0d4005d..82e0fd0 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -454,7 +454,7 @@ #endif
panic("Fatal exception in interrupt");
if (panic_on_oops)
- panic("Fatal exception: panic_on_oops");
+ panic("Fatal exception");
oops_exit();
do_exit(SIGSEGV);
diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c
index 5a04204..fffa9e0 100644
--- a/arch/ia64/kernel/traps.c
+++ b/arch/ia64/kernel/traps.c
@@ -118,7 +118,7 @@ die (const char *str, struct pt_regs *re
spin_unlock_irq(&die.lock);
if (panic_on_oops)
- panic("Fatal exception: panic_on_oops");
+ panic("Fatal exception");
do_exit(SIGSEGV);
}
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 2105767..05682a2 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -151,7 +151,7 @@ #endif
panic("Fatal exception in interrupt");
if (panic_on_oops)
- panic("Fatal exception: panic_on_oops");
+ panic("Fatal exception");
do_exit(err);
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
index 4e9938d..14052f0 100644
--- a/arch/x86_64/kernel/traps.c
+++ b/arch/x86_64/kernel/traps.c
@@ -529,7 +529,7 @@ void __kprobes oops_end(unsigned long fl
/* Nest count reaches zero, release the lock. */
spin_unlock_irqrestore(&die_lock, flags);
if (panic_on_oops)
- panic("Fatal exception: panic_on_oops");
+ panic("Fatal exception");
}
void __kprobes __die(const char * str, struct pt_regs * regs, long err)
diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c
index 9734960..ce077d6 100644
--- a/arch/xtensa/kernel/traps.c
+++ b/arch/xtensa/kernel/traps.c
@@ -488,7 +488,7 @@ #endif
panic("Fatal exception in interrupt");
if (panic_on_oops)
- panic("Fatal exception: panic_on_oops");
+ panic("Fatal exception");
do_exit(err);
}
--
1.4.1.gd3ba6
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox