LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 02/11] of/flattree: Merge earlyinit_dt_scan_root()
From: Grant Likely @ 2009-11-24  8:18 UTC (permalink / raw)
  To: linuxppc-dev, devicetree-discuss, sparclinux, microblaze-uclinux,
	benh, sfr, davem, monstr
In-Reply-To: <20091124081316.6216.66310.stgit@angua>

Merge common code between PowerPC and Microblaze

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---

 arch/microblaze/kernel/prom.c |   23 -----------------------
 arch/powerpc/kernel/prom.c    |   24 ------------------------
 drivers/of/fdt.c              |   26 ++++++++++++++++++++++++++
 include/linux/of_fdt.h        |    6 ++++++
 4 files changed, 32 insertions(+), 47 deletions(-)

diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c
index 7959495..189179a 100644
--- a/arch/microblaze/kernel/prom.c
+++ b/arch/microblaze/kernel/prom.c
@@ -42,9 +42,6 @@
 #include <asm/sections.h>
 #include <asm/pci-bridge.h>
 
-static int __initdata dt_root_addr_cells;
-static int __initdata dt_root_size_cells;
-
 typedef u32 cell_t;
 
 /* export that to outside world */
@@ -158,26 +155,6 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
 	return 1;
 }
 
-static int __init early_init_dt_scan_root(unsigned long node,
-				const char *uname, int depth, void *data)
-{
-	u32 *prop;
-
-	if (depth != 0)
-		return 0;
-
-	prop = of_get_flat_dt_prop(node, "#size-cells", NULL);
-	dt_root_size_cells = (prop == NULL) ? 1 : *prop;
-	pr_debug("dt_root_size_cells = %x\n", dt_root_size_cells);
-
-	prop = of_get_flat_dt_prop(node, "#address-cells", NULL);
-	dt_root_addr_cells = (prop == NULL) ? 2 : *prop;
-	pr_debug("dt_root_addr_cells = %x\n", dt_root_addr_cells);
-
-	/* break now */
-	return 1;
-}
-
 static u64 __init dt_mem_next_cell(int s, cell_t **cellp)
 {
 	cell_t *p = *cellp;
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 1ecd6c6..78f65a4 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -61,10 +61,6 @@
 #define DBG(fmt...)
 #endif
 
-
-static int __initdata dt_root_addr_cells;
-static int __initdata dt_root_size_cells;
-
 #ifdef CONFIG_PPC64
 int __initdata iommu_is_off;
 int __initdata iommu_force_on;
@@ -436,26 +432,6 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
 	return 1;
 }
 
-static int __init early_init_dt_scan_root(unsigned long node,
-					  const char *uname, int depth, void *data)
-{
-	u32 *prop;
-
-	if (depth != 0)
-		return 0;
-
-	prop = of_get_flat_dt_prop(node, "#size-cells", NULL);
-	dt_root_size_cells = (prop == NULL) ? 1 : *prop;
-	DBG("dt_root_size_cells = %x\n", dt_root_size_cells);
-
-	prop = of_get_flat_dt_prop(node, "#address-cells", NULL);
-	dt_root_addr_cells = (prop == NULL) ? 2 : *prop;
-	DBG("dt_root_addr_cells = %x\n", dt_root_addr_cells);
-	
-	/* break now */
-	return 1;
-}
-
 static u64 __init dt_mem_next_cell(int s, cell_t **cellp)
 {
 	cell_t *p = *cellp;
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 6ad98e8..be200be 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -15,6 +15,9 @@
 #include <linux/of.h>
 #include <linux/of_fdt.h>
 
+int __initdata dt_root_addr_cells;
+int __initdata dt_root_size_cells;
+
 struct boot_param_header *initial_boot_params;
 
 char *find_flat_dt_string(u32 offset)
@@ -407,6 +410,29 @@ inline void early_init_dt_check_for_initrd(unsigned long node)
 #endif /* CONFIG_BLK_DEV_INITRD */
 
 /**
+ * early_init_dt_scan_root - fetch the top level address and size cells
+ */
+int __init early_init_dt_scan_root(unsigned long node, const char *uname,
+				   int depth, void *data)
+{
+	u32 *prop;
+
+	if (depth != 0)
+		return 0;
+
+	prop = of_get_flat_dt_prop(node, "#size-cells", NULL);
+	dt_root_size_cells = (prop == NULL) ? 1 : *prop;
+	pr_debug("dt_root_size_cells = %x\n", dt_root_size_cells);
+
+	prop = of_get_flat_dt_prop(node, "#address-cells", NULL);
+	dt_root_addr_cells = (prop == NULL) ? 2 : *prop;
+	pr_debug("dt_root_addr_cells = %x\n", dt_root_addr_cells);
+
+	/* break now */
+	return 1;
+}
+
+/**
  * unflatten_device_tree - create tree of device_nodes from flat blob
  *
  * unflattens the device-tree passed by the firmware, creating the
diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
index ec2db82..828c3cd 100644
--- a/include/linux/of_fdt.h
+++ b/include/linux/of_fdt.h
@@ -58,6 +58,8 @@ struct boot_param_header {
 };
 
 /* TBD: Temporary export of fdt globals - remove when code fully merged */
+extern int __initdata dt_root_addr_cells;
+extern int __initdata dt_root_size_cells;
 extern struct boot_param_header *initial_boot_params;
 
 /* For scanning the flat device-tree at boot time */
@@ -71,6 +73,10 @@ extern int of_flat_dt_is_compatible(unsigned long node, const char *name);
 extern unsigned long of_get_flat_dt_root(void);
 extern void early_init_dt_check_for_initrd(unsigned long node);
 
+/* Early flat tree scan hooks */
+extern int early_init_dt_scan_root(unsigned long node, const char *uname,
+				   int depth, void *data);
+
 /* Other Prototypes */
 extern void finish_device_tree(void);
 extern void unflatten_device_tree(void);

^ permalink raw reply related

* [PATCH 01/11] of/flattree: Merge early_init_dt_check_for_initrd()
From: Grant Likely @ 2009-11-24  8:17 UTC (permalink / raw)
  To: linuxppc-dev, devicetree-discuss, sparclinux, microblaze-uclinux,
	benh, sfr, davem, monstr
In-Reply-To: <20091124081316.6216.66310.stgit@angua>

Merge common code between PowerPC and Microblaze

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Reviewed-by: Wolfram Sang <w.sang@pengutronix.de>
Tested-by: Michal Simek <monstr@monstr.eu>
---

 arch/microblaze/kernel/prom.c |   32 --------------------------------
 arch/powerpc/kernel/prom.c    |   30 ------------------------------
 drivers/of/fdt.c              |   37 +++++++++++++++++++++++++++++++++++++
 include/linux/of_fdt.h        |    1 +
 4 files changed, 38 insertions(+), 62 deletions(-)

diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c
index a38e373..7959495 100644
--- a/arch/microblaze/kernel/prom.c
+++ b/arch/microblaze/kernel/prom.c
@@ -113,38 +113,6 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
 	return 0;
 }
 
-#ifdef CONFIG_BLK_DEV_INITRD
-static void __init early_init_dt_check_for_initrd(unsigned long node)
-{
-	unsigned long l;
-	u32 *prop;
-
-	pr_debug("Looking for initrd properties... ");
-
-	prop = of_get_flat_dt_prop(node, "linux,initrd-start", &l);
-	if (prop) {
-		initrd_start = (unsigned long)
-					__va((u32)of_read_ulong(prop, l/4));
-
-		prop = of_get_flat_dt_prop(node, "linux,initrd-end", &l);
-		if (prop) {
-			initrd_end = (unsigned long)
-					__va((u32)of_read_ulong(prop, 1/4));
-			initrd_below_start_ok = 1;
-		} else {
-			initrd_start = 0;
-		}
-	}
-
-	pr_debug("initrd_start=0x%lx  initrd_end=0x%lx\n",
-					initrd_start, initrd_end);
-}
-#else
-static inline void early_init_dt_check_for_initrd(unsigned long node)
-{
-}
-#endif /* CONFIG_BLK_DEV_INITRD */
-
 static int __init early_init_dt_scan_chosen(unsigned long node,
 				const char *uname, int depth, void *data)
 {
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 7f88566..1ecd6c6 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -373,36 +373,6 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
 	return 0;
 }
 
-#ifdef CONFIG_BLK_DEV_INITRD
-static void __init early_init_dt_check_for_initrd(unsigned long node)
-{
-	unsigned long l;
-	u32 *prop;
-
-	DBG("Looking for initrd properties... ");
-
-	prop = of_get_flat_dt_prop(node, "linux,initrd-start", &l);
-	if (prop) {
-		initrd_start = (unsigned long)__va(of_read_ulong(prop, l/4));
-
-		prop = of_get_flat_dt_prop(node, "linux,initrd-end", &l);
-		if (prop) {
-			initrd_end = (unsigned long)
-					__va(of_read_ulong(prop, l/4));
-			initrd_below_start_ok = 1;
-		} else {
-			initrd_start = 0;
-		}
-	}
-
-	DBG("initrd_start=0x%lx  initrd_end=0x%lx\n", initrd_start, initrd_end);
-}
-#else
-static inline void early_init_dt_check_for_initrd(unsigned long node)
-{
-}
-#endif /* CONFIG_BLK_DEV_INITRD */
-
 static int __init early_init_dt_scan_chosen(unsigned long node,
 					    const char *uname, int depth, void *data)
 {
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 43d236c..6ad98e8 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -11,6 +11,7 @@
 
 #include <linux/kernel.h>
 #include <linux/lmb.h>
+#include <linux/initrd.h>
 #include <linux/of.h>
 #include <linux/of_fdt.h>
 
@@ -369,6 +370,42 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
 	return mem;
 }
 
+#ifdef CONFIG_BLK_DEV_INITRD
+/**
+ * early_init_dt_check_for_initrd - Decode initrd location from flat tree
+ * @node: reference to node containing initrd location ('chosen')
+ */
+void __init early_init_dt_check_for_initrd(unsigned long node)
+{
+	unsigned long len;
+	u32 *prop;
+
+	pr_debug("Looking for initrd properties... ");
+
+	prop = of_get_flat_dt_prop(node, "linux,initrd-start", &len);
+	if (prop) {
+		initrd_start = (unsigned long)
+				__va(of_read_ulong(prop, len/4));
+
+		prop = of_get_flat_dt_prop(node, "linux,initrd-end", &len);
+		if (prop) {
+			initrd_end = (unsigned long)
+				__va(of_read_ulong(prop, len/4));
+			initrd_below_start_ok = 1;
+		} else {
+			initrd_start = 0;
+		}
+	}
+
+	pr_debug("initrd_start=0x%lx  initrd_end=0x%lx\n",
+		 initrd_start, initrd_end);
+}
+#else
+inline void early_init_dt_check_for_initrd(unsigned long node)
+{
+}
+#endif /* CONFIG_BLK_DEV_INITRD */
+
 /**
  * unflatten_device_tree - create tree of device_nodes from flat blob
  *
diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
index 81231e0..ec2db82 100644
--- a/include/linux/of_fdt.h
+++ b/include/linux/of_fdt.h
@@ -69,6 +69,7 @@ extern void *of_get_flat_dt_prop(unsigned long node, const char *name,
 				 unsigned long *size);
 extern int of_flat_dt_is_compatible(unsigned long node, const char *name);
 extern unsigned long of_get_flat_dt_root(void);
+extern void early_init_dt_check_for_initrd(unsigned long node);
 
 /* Other Prototypes */
 extern void finish_device_tree(void);

^ permalink raw reply related

* [PATCH 00/11] Yet another series of OF merge patches.
From: Grant Likely @ 2009-11-24  8:17 UTC (permalink / raw)
  To: linuxppc-dev, devicetree-discuss, sparclinux, microblaze-uclinux,
	benh, sfr, davem, monstr

Nothing much to say here other than mostly mechanical merging of OF
support code.  Some of it remains a little ugly, but I'm taking the
approach of merging the code first, and refactoring it second.

I've pushed this series out to my test-devicetree branch on my git
server if anyone wants to test.  That branch also includes the
previous 2 patch series that I've sent out.

git://git.secretlab.ca/git/linux-2.6 test-devicetree

Compile tested on: ppc64, ppc32, microblaze, sparc64, sparc32.
Boot tested on mpc5200 (ppc32) platform.

---

Grant Likely (11):
      of: unify phandle name in struct device_node
      microblaze: gut implementation of early_init_dt_scan_cpus()
      of: merge of_attach_node() & of_detach_node()
      of: Merge of_node_get() and of_node_put()
      of: merge machine_is_compatible()
      of/flattree: merge early_init_devtree() and early_init_move_devtree()
      of/flattree: merge early_init_dt_scan_chosen()
      of/flattree: eliminate cell_t typedef
      of/flattree: merge dt_mem_next_cell
      of/flattree: Merge earlyinit_dt_scan_root()
      of/flattree: Merge early_init_dt_check_for_initrd()


 arch/microblaze/include/asm/prom.h           |    4 
 arch/microblaze/kernel/prom.c                |  375 +-------------------------
 arch/powerpc/include/asm/prom.h              |    4 
 arch/powerpc/kernel/prom.c                   |  366 ++-----------------------
 arch/powerpc/platforms/powermac/pfunc_core.c |    2 
 arch/sparc/kernel/devices.c                  |    2 
 arch/sparc/kernel/of_device_32.c             |    2 
 arch/sparc/kernel/of_device_64.c             |    2 
 arch/sparc/kernel/prom_common.c              |    8 -
 arch/sparc/kernel/smp_64.c                   |    2 
 drivers/of/base.c                            |  153 +++++++++++
 drivers/of/fdt.c                             |  204 ++++++++++++++
 drivers/sbus/char/openprom.c                 |   10 -
 drivers/video/aty/atyfb_base.c               |    2 
 include/linux/of.h                           |    7 
 include/linux/of_fdt.h                       |   18 +
 16 files changed, 430 insertions(+), 731 deletions(-)

-- 
Signature

^ permalink raw reply

* [PATCH] PPC: Sync guest visible MMU state
From: Alexander Graf @ 2009-11-24  7:50 UTC (permalink / raw)
  To: kvm; +Cc: kvm-ppc, linuxppc-dev

Currently userspace has no chance to find out which virtual address space we're
in and resolve addresses. While that is a big problem for migration, it's also
unpleasent when debugging, as gdb and the monitor don't work on virtual
addresses.

This patch exports enough of the MMU segment state to userspace to make
debugging work and thus also includes the groundwork for migration.

Signed-off-by: Alexander Graf <agraf@suse.de>
---
 arch/powerpc/include/asm/kvm.h        |   20 ++++++++++++-
 arch/powerpc/include/asm/kvm_asm.h    |    1 +
 arch/powerpc/include/asm/kvm_book3s.h |    3 ++
 arch/powerpc/kvm/book3s.c             |   47 +++++++++++++++++++++++++++++++++
 arch/powerpc/kvm/book3s_64_emulate.c  |   38 ++++++++++++++++----------
 arch/powerpc/kvm/book3s_64_mmu.c      |    2 +
 arch/powerpc/kvm/powerpc.c            |    3 ++
 include/linux/kvm.h                   |    1 +
 8 files changed, 98 insertions(+), 17 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm.h b/arch/powerpc/include/asm/kvm.h
index c9ca97f..bc0aeba 100644
--- a/arch/powerpc/include/asm/kvm.h
+++ b/arch/powerpc/include/asm/kvm.h
@@ -46,8 +46,24 @@ struct kvm_regs {
 };
 
 struct kvm_sregs {
-	__u32 pvr;
-	char pad[1020];
+	union {
+		struct {
+			__u32 pvr;
+			__u64 sdr1;
+			struct {
+				struct {
+					__u64 slbe;
+					__u64 slbv;
+				} slb[64];
+			} ppc64;
+			struct {
+				__u32 sr[16];
+				__u64 ibat[8]; 
+				__u64 dbat[8]; 
+			} ppc32;
+		};
+		__u8 pad[1024];
+	};
 };
 
 struct kvm_fpu {
diff --git a/arch/powerpc/include/asm/kvm_asm.h b/arch/powerpc/include/asm/kvm_asm.h
index 19ddb35..af2abe7 100644
--- a/arch/powerpc/include/asm/kvm_asm.h
+++ b/arch/powerpc/include/asm/kvm_asm.h
@@ -87,6 +87,7 @@
 #define BOOK3S_IRQPRIO_MAX			16
 
 #define BOOK3S_HFLAG_DCBZ32			0x1
+#define BOOK3S_HFLAG_SLB			0x2
 
 #define RESUME_FLAG_NV          (1<<0)  /* Reload guest nonvolatile state? */
 #define RESUME_FLAG_HOST        (1<<1)  /* Resume host? */
diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h
index c601133..74b7369 100644
--- a/arch/powerpc/include/asm/kvm_book3s.h
+++ b/arch/powerpc/include/asm/kvm_book3s.h
@@ -46,6 +46,7 @@ struct kvmppc_sr {
 };
 
 struct kvmppc_bat {
+	u64 raw;
 	u32 bepi;
 	u32 bepi_mask;
 	bool vs;
@@ -113,6 +114,8 @@ extern struct kvmppc_pte *kvmppc_mmu_find_pte(struct kvm_vcpu *vcpu, u64 ea, boo
 extern int kvmppc_ld(struct kvm_vcpu *vcpu, ulong eaddr, int size, void *ptr, bool data);
 extern int kvmppc_st(struct kvm_vcpu *vcpu, ulong eaddr, int size, void *ptr);
 extern void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec);
+extern void kvmppc_set_bat(struct kvm_vcpu *vcpu, struct kvmppc_bat *bat,
+			   bool upper, u32 val);
 
 extern u32 kvmppc_trampoline_lowmem;
 extern u32 kvmppc_trampoline_enter;
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index 42037d4..650ebf8 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -281,6 +281,7 @@ void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu)
 
 void kvmppc_set_pvr(struct kvm_vcpu *vcpu, u32 pvr)
 {
+	vcpu->arch.hflags &= ~BOOK3S_HFLAG_SLB;
 	vcpu->arch.pvr = pvr;
 	if ((pvr >= 0x330000) && (pvr < 0x70330000)) {
 		kvmppc_mmu_book3s_64_init(vcpu);
@@ -762,14 +763,60 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
 int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
                                   struct kvm_sregs *sregs)
 {
+	int i;
+
 	sregs->pvr = vcpu->arch.pvr;
+
+	sregs->sdr1 = to_book3s(vcpu)->sdr1;
+	if (vcpu->arch.hflags & BOOK3S_HFLAG_SLB) {
+		for (i = 0; i < 64; i++) {
+			sregs->ppc64.slb[i].slbe = to_book3s(vcpu)->slb[i].orige | i;
+			sregs->ppc64.slb[i].slbv = to_book3s(vcpu)->slb[i].origv;
+		}
+	} else {
+		for (i = 0; i < 16; i++) {
+			sregs->ppc32.sr[i] = to_book3s(vcpu)->sr[i].raw;
+			sregs->ppc32.sr[i] = to_book3s(vcpu)->sr[i].raw;
+		}
+		for (i = 0; i < 8; i++) {
+			sregs->ppc32.ibat[i] = to_book3s(vcpu)->ibat[i].raw;
+			sregs->ppc32.dbat[i] = to_book3s(vcpu)->dbat[i].raw;
+		}
+	}
 	return 0;
 }
 
 int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
                                   struct kvm_sregs *sregs)
 {
+	int i;
+
 	kvmppc_set_pvr(vcpu, sregs->pvr);
+
+	to_book3s(vcpu)->sdr1 = sregs->sdr1;
+	if (vcpu->arch.hflags & BOOK3S_HFLAG_SLB) {
+		for (i = 0; i < 64; i++) {
+			vcpu->arch.mmu.slbmte(vcpu, sregs->ppc64.slb[i].slbv,
+						    sregs->ppc64.slb[i].slbe);
+		}
+	} else {
+		for (i = 0; i < 16; i++) {
+			vcpu->arch.mmu.mtsrin(vcpu, i, sregs->ppc32.sr[i]);
+		}
+		for (i = 0; i < 8; i++) {
+			kvmppc_set_bat(vcpu, &(to_book3s(vcpu)->ibat[i]), false,
+				       (u32)sregs->ppc32.ibat[i]);
+			kvmppc_set_bat(vcpu, &(to_book3s(vcpu)->ibat[i]), true,
+				       (u32)(sregs->ppc32.ibat[i] >> 32));
+			kvmppc_set_bat(vcpu, &(to_book3s(vcpu)->dbat[i]), false,
+				       (u32)sregs->ppc32.dbat[i]);
+			kvmppc_set_bat(vcpu, &(to_book3s(vcpu)->dbat[i]), true,
+				       (u32)(sregs->ppc32.dbat[i] >> 32));
+		}
+	}
+
+	/* Flush the MMU after messing with the segments */
+	kvmppc_mmu_pte_flush(vcpu, 0, 0);
 	return 0;
 }
 
diff --git a/arch/powerpc/kvm/book3s_64_emulate.c b/arch/powerpc/kvm/book3s_64_emulate.c
index c343e67..1027eac 100644
--- a/arch/powerpc/kvm/book3s_64_emulate.c
+++ b/arch/powerpc/kvm/book3s_64_emulate.c
@@ -185,7 +185,27 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
 	return emulated;
 }
 
-static void kvmppc_write_bat(struct kvm_vcpu *vcpu, int sprn, u64 val)
+void kvmppc_set_bat(struct kvm_vcpu *vcpu, struct kvmppc_bat *bat, bool upper,
+                    u32 val)
+{
+	if (upper) {
+		/* Upper BAT */
+		u32 bl = (val >> 2) & 0x7ff;
+		bat->bepi_mask = (~bl << 17);
+		bat->bepi = val & 0xfffe0000;
+		bat->vs = (val & 2) ? 1 : 0;
+		bat->vp = (val & 1) ? 1 : 0;
+		bat->raw = (bat->raw & 0xffffffff00000000ULL) | val;
+	} else {
+		/* Lower BAT */
+		bat->brpn = val & 0xfffe0000;
+		bat->wimg = (val >> 3) & 0xf;
+		bat->pp = val & 3;
+		bat->raw = (bat->raw & 0x00000000ffffffffULL) | ((u64)val << 32);
+	}
+}
+
+static void kvmppc_write_bat(struct kvm_vcpu *vcpu, int sprn, u32 val)
 {
 	struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
 	struct kvmppc_bat *bat;
@@ -207,19 +227,7 @@ static void kvmppc_write_bat(struct kvm_vcpu *vcpu, int sprn, u64 val)
 		BUG();
 	}
 
-	if (!(sprn % 2)) {
-		/* Upper BAT */
-		u32 bl = (val >> 2) & 0x7ff;
-		bat->bepi_mask = (~bl << 17);
-		bat->bepi = val & 0xfffe0000;
-		bat->vs = (val & 2) ? 1 : 0;
-		bat->vp = (val & 1) ? 1 : 0;
-	} else {
-		/* Lower BAT */
-		bat->brpn = val & 0xfffe0000;
-		bat->wimg = (val >> 3) & 0xf;
-		bat->pp = val & 3;
-	}
+	kvmppc_set_bat(vcpu, bat, !(sprn % 2), val);
 }
 
 int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
@@ -243,7 +251,7 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
 	case SPRN_IBAT4U ... SPRN_IBAT7L:
 	case SPRN_DBAT0U ... SPRN_DBAT3L:
 	case SPRN_DBAT4U ... SPRN_DBAT7L:
-		kvmppc_write_bat(vcpu, sprn, vcpu->arch.gpr[rs]);
+		kvmppc_write_bat(vcpu, sprn, (u32)vcpu->arch.gpr[rs]);
 		/* BAT writes happen so rarely that we're ok to flush
 		 * everything here */
 		kvmppc_mmu_pte_flush(vcpu, 0, 0);
diff --git a/arch/powerpc/kvm/book3s_64_mmu.c b/arch/powerpc/kvm/book3s_64_mmu.c
index a31f9c6..5598f88 100644
--- a/arch/powerpc/kvm/book3s_64_mmu.c
+++ b/arch/powerpc/kvm/book3s_64_mmu.c
@@ -473,4 +473,6 @@ void kvmppc_mmu_book3s_64_init(struct kvm_vcpu *vcpu)
 	mmu->esid_to_vsid = kvmppc_mmu_book3s_64_esid_to_vsid;
 	mmu->ea_to_vp = kvmppc_mmu_book3s_64_ea_to_vp;
 	mmu->is_dcbz32 = kvmppc_mmu_book3s_64_is_dcbz32;
+
+	vcpu->arch.hflags |= BOOK3S_HFLAG_SLB;
 }
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 4c582ed..f06cf93 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -145,6 +145,9 @@ int kvm_dev_ioctl_check_extension(long ext)
 	int r;
 
 	switch (ext) {
+	case KVM_CAP_PPC_SEGSTATE:
+		r = 1;
+		break;
 	case KVM_CAP_COALESCED_MMIO:
 		r = KVM_COALESCED_MMIO_PAGE_OFFSET;
 		break;
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 92045a9..1240fcb 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -492,6 +492,7 @@ struct kvm_ioeventfd {
 #ifdef __KVM_HAVE_VCPU_EVENTS
 #define KVM_CAP_VCPU_EVENTS 41
 #endif
+#define KVM_CAP_PPC_SEGSTATE 42
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
-- 
1.6.0.2

^ permalink raw reply related

* Re: Fix bug in pagetable cache cleanup with CONFIG_PPC_SUBPAGE_PROT
From: Sachin Sant @ 2009-11-24  6:58 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, David Gibson
In-Reply-To: <20091124053114.GD2737@yookeroo>

David Gibson wrote:
> Commit a0668cdc154e54bf0c85182e0535eea237d53146 cleans up the handling
> of kmem_caches for allocating various levels of pagetables.
> Unfortunately, it conflicts badly with CONFIG_PPC_SUBPAGE_PROT, due to
> the latter's cleverly hidden technique of adding some extra allocation
> space to the top level page directory to store the extra information
> it needs.
>
> Since that extra allocation really doesn't fit into the cleaned up
> page directory allocating scheme, this patch alters
> CONFIG_PPC_SUBPAGE_PROT to instead allocate its struct
> subpage_prot_table as part of the mm_context_t.
>
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Thanks David for the patch. With this patch on top of next-20091123
my test machine boots fine. 

Regards
-Sachin

-- 

---------------------------------
Sachin Sant
IBM Linux Technology Center
India Systems and Technology Labs
Bangalore, India
---------------------------------

^ permalink raw reply

* Re: Fix bug in gup_hugepd()
From: Stephen Rothwell @ 2009-11-24  6:25 UTC (permalink / raw)
  To: David Gibson; +Cc: linuxppc-dev
In-Reply-To: <20091124060340.GE2737@yookeroo>

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

Hi David,

On Tue, 24 Nov 2009 17:03:40 +1100 David Gibson <david@gibson.dropbear.id.au> wrote:
>
> Commit a4fe3ce7699bfe1bd88f816b55d42d8fe1dac655 introduced a new

When you quote a SHA1, please also quote the summary line for the commit
so those without git access may find it.

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

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

^ permalink raw reply

* Fix bug in gup_hugepd()
From: David Gibson @ 2009-11-24  6:03 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev

Commit a4fe3ce7699bfe1bd88f816b55d42d8fe1dac655 introduced a new
get_user_pages() path for hugepages on powerpc.  Unfortunately, there
is a bug in it's loop logic, which can cause it to overrun the end of
the intended region.  This came about by copying the logic from the
normal page path, which assumes the address and end parameters have
been pagesize aligned at the top-level.  Since they're not *hugepage*
size aligned, the simplistic logic could step over the end of the gup
region without triggering the loop end condition.

This patch fixes the bug by using the technique that the normal page
path uses in levels above the lowest to truncate the ending address to
something we know we'll match with.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>

Index: working-2.6/arch/powerpc/mm/hugetlbpage.c
===================================================================
--- working-2.6.orig/arch/powerpc/mm/hugetlbpage.c	2009-11-24 14:25:36.488330625 +1100
+++ working-2.6/arch/powerpc/mm/hugetlbpage.c	2009-11-24 15:55:27.296455938 +1100
@@ -436,18 +436,27 @@ static noinline int gup_hugepte(pte_t *p
 	return 1;
 }
 
+static unsigned long hugepte_addr_end(unsigned long addr, unsigned long end,
+				      unsigned long sz)
+{
+	unsigned long __boundary = (addr + sz) & ~(sz-1);
+	return (__boundary - 1 < end - 1) ? __boundary : end;
+}
+
 int gup_hugepd(hugepd_t *hugepd, unsigned pdshift,
 	       unsigned long addr, unsigned long end,
 	       int write, struct page **pages, int *nr)
 {
 	pte_t *ptep;
 	unsigned long sz = 1UL << hugepd_shift(*hugepd);
+	unsigned long next;
 
 	ptep = hugepte_offset(hugepd, addr, pdshift);
 	do {
+		next = hugepte_addr_end(addr, end, sz);
 		if (!gup_hugepte(ptep, sz, addr, end, write, pages, nr))
 			return 0;
-	} while (ptep++, addr += sz, addr != end);
+	} while (ptep++, addr = next, addr != end);
 
 	return 1;
 }


-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

^ permalink raw reply

* Fix bug in pagetable cache cleanup with CONFIG_PPC_SUBPAGE_PROT
From: David Gibson @ 2009-11-24  5:31 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev

Commit a0668cdc154e54bf0c85182e0535eea237d53146 cleans up the handling
of kmem_caches for allocating various levels of pagetables.
Unfortunately, it conflicts badly with CONFIG_PPC_SUBPAGE_PROT, due to
the latter's cleverly hidden technique of adding some extra allocation
space to the top level page directory to store the extra information
it needs.

Since that extra allocation really doesn't fit into the cleaned up
page directory allocating scheme, this patch alters
CONFIG_PPC_SUBPAGE_PROT to instead allocate its struct
subpage_prot_table as part of the mm_context_t.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>

Index: working-2.6/arch/powerpc/include/asm/mmu-hash64.h
===================================================================
--- working-2.6.orig/arch/powerpc/include/asm/mmu-hash64.h	2009-11-24 13:00:07.076303532 +1100
+++ working-2.6/arch/powerpc/include/asm/mmu-hash64.h	2009-11-24 13:37:49.216303709 +1100
@@ -373,6 +373,38 @@ extern void slb_set_size(u16 size);
 
 #ifndef __ASSEMBLY__
 
+#ifdef CONFIG_PPC_SUBPAGE_PROT
+/*
+ * For the sub-page protection option, we extend the PGD with one of
+ * these.  Basically we have a 3-level tree, with the top level being
+ * the protptrs array.  To optimize speed and memory consumption when
+ * only addresses < 4GB are being protected, pointers to the first
+ * four pages of sub-page protection words are stored in the low_prot
+ * array.
+ * Each page of sub-page protection words protects 1GB (4 bytes
+ * protects 64k).  For the 3-level tree, each page of pointers then
+ * protects 8TB.
+ */
+struct subpage_prot_table {
+	unsigned long maxaddr;	/* only addresses < this are protected */
+	unsigned int **protptrs[2];
+	unsigned int *low_prot[4];
+};
+
+#define SBP_L1_BITS		(PAGE_SHIFT - 2)
+#define SBP_L2_BITS		(PAGE_SHIFT - 3)
+#define SBP_L1_COUNT		(1 << SBP_L1_BITS)
+#define SBP_L2_COUNT		(1 << SBP_L2_BITS)
+#define SBP_L2_SHIFT		(PAGE_SHIFT + SBP_L1_BITS)
+#define SBP_L3_SHIFT		(SBP_L2_SHIFT + SBP_L2_BITS)
+
+extern void subpage_prot_free(struct mm_struct *mm);
+extern void subpage_prot_init_new_context(struct mm_struct *mm);
+#else
+static inline void subpage_prot_free(pgd_t *pgd) {}
+static inline void subpage_prot_init_new_context(struct mm_struct *mm) { }
+#endif /* CONFIG_PPC_SUBPAGE_PROT */
+
 typedef unsigned long mm_context_id_t;
 
 typedef struct {
@@ -386,6 +418,9 @@ typedef struct {
 	u16 sllp;		/* SLB page size encoding */
 #endif
 	unsigned long vdso_base;
+#ifdef CONFIG_PPC_SUBPAGE_PROT
+	struct subpage_prot_table spt;
+#endif /* CONFIG_PPC_SUBPAGE_PROT */
 } mm_context_t;
 
 
Index: working-2.6/arch/powerpc/include/asm/pgalloc-64.h
===================================================================
--- working-2.6.orig/arch/powerpc/include/asm/pgalloc-64.h	2009-11-24 12:58:25.616303379 +1100
+++ working-2.6/arch/powerpc/include/asm/pgalloc-64.h	2009-11-24 14:04:25.752332450 +1100
@@ -28,10 +28,6 @@
  */
 #define MAX_PGTABLE_INDEX_SIZE	0xf
 
-#ifndef CONFIG_PPC_SUBPAGE_PROT
-static inline void subpage_prot_free(pgd_t *pgd) {}
-#endif
-
 extern struct kmem_cache *pgtable_cache[];
 #define PGT_CACHE(shift) (pgtable_cache[(shift)-1])
 
@@ -42,7 +38,6 @@ static inline pgd_t *pgd_alloc(struct mm
 
 static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
 {
-	subpage_prot_free(pgd);
 	kmem_cache_free(PGT_CACHE(PGD_INDEX_SIZE), pgd);
 }
 
Index: working-2.6/arch/powerpc/include/asm/pte-hash64-64k.h
===================================================================
--- working-2.6.orig/arch/powerpc/include/asm/pte-hash64-64k.h	2009-11-24 12:58:54.332307997 +1100
+++ working-2.6/arch/powerpc/include/asm/pte-hash64-64k.h	2009-11-24 13:04:10.261303844 +1100
@@ -76,41 +76,4 @@
 	remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE,		\
 			__pgprot(pgprot_val((prot)) | _PAGE_4K_PFN))
 
-
-#ifdef CONFIG_PPC_SUBPAGE_PROT
-/*
- * For the sub-page protection option, we extend the PGD with one of
- * these.  Basically we have a 3-level tree, with the top level being
- * the protptrs array.  To optimize speed and memory consumption when
- * only addresses < 4GB are being protected, pointers to the first
- * four pages of sub-page protection words are stored in the low_prot
- * array.
- * Each page of sub-page protection words protects 1GB (4 bytes
- * protects 64k).  For the 3-level tree, each page of pointers then
- * protects 8TB.
- */
-struct subpage_prot_table {
-	unsigned long maxaddr;	/* only addresses < this are protected */
-	unsigned int **protptrs[2];
-	unsigned int *low_prot[4];
-};
-
-#undef PGD_TABLE_SIZE
-#define PGD_TABLE_SIZE		((sizeof(pgd_t) << PGD_INDEX_SIZE) + \
-				 sizeof(struct subpage_prot_table))
-
-#define SBP_L1_BITS		(PAGE_SHIFT - 2)
-#define SBP_L2_BITS		(PAGE_SHIFT - 3)
-#define SBP_L1_COUNT		(1 << SBP_L1_BITS)
-#define SBP_L2_COUNT		(1 << SBP_L2_BITS)
-#define SBP_L2_SHIFT		(PAGE_SHIFT + SBP_L1_BITS)
-#define SBP_L3_SHIFT		(SBP_L2_SHIFT + SBP_L2_BITS)
-
-extern void subpage_prot_free(pgd_t *pgd);
-
-static inline struct subpage_prot_table *pgd_subpage_prot(pgd_t *pgd)
-{
-	return (struct subpage_prot_table *)(pgd + PTRS_PER_PGD);
-}
-#endif /* CONFIG_PPC_SUBPAGE_PROT */
 #endif	/* __ASSEMBLY__ */
Index: working-2.6/arch/powerpc/mm/subpage-prot.c
===================================================================
--- working-2.6.orig/arch/powerpc/mm/subpage-prot.c	2009-11-24 12:59:27.892303545 +1100
+++ working-2.6/arch/powerpc/mm/subpage-prot.c	2009-11-24 13:38:27.168299565 +1100
@@ -24,9 +24,9 @@
  * Also makes sure that the subpage_prot_table structure is
  * reinitialized for the next user.
  */
-void subpage_prot_free(pgd_t *pgd)
+void subpage_prot_free(struct mm_struct *mm)
 {
-	struct subpage_prot_table *spt = pgd_subpage_prot(pgd);
+	struct subpage_prot_table *spt = &mm->context.spt;
 	unsigned long i, j, addr;
 	u32 **p;
 
@@ -51,6 +51,13 @@ void subpage_prot_free(pgd_t *pgd)
 	spt->maxaddr = 0;
 }
 
+void subpage_prot_init_new_context(struct mm_struct *mm)
+{
+	struct subpage_prot_table *spt = &mm->context.spt;
+
+	memset(spt, 0, sizeof(*spt));
+}
+
 static void hpte_flush_range(struct mm_struct *mm, unsigned long addr,
 			     int npages)
 {
@@ -87,7 +94,7 @@ static void hpte_flush_range(struct mm_s
 static void subpage_prot_clear(unsigned long addr, unsigned long len)
 {
 	struct mm_struct *mm = current->mm;
-	struct subpage_prot_table *spt = pgd_subpage_prot(mm->pgd);
+	struct subpage_prot_table *spt = &mm->context.spt;
 	u32 **spm, *spp;
 	int i, nw;
 	unsigned long next, limit;
@@ -136,7 +143,7 @@ static void subpage_prot_clear(unsigned 
 long sys_subpage_prot(unsigned long addr, unsigned long len, u32 __user *map)
 {
 	struct mm_struct *mm = current->mm;
-	struct subpage_prot_table *spt = pgd_subpage_prot(mm->pgd);
+	struct subpage_prot_table *spt = &mm->context.spt;
 	u32 **spm, *spp;
 	int i, nw;
 	unsigned long next, limit;
Index: working-2.6/arch/powerpc/mm/hash_utils_64.c
===================================================================
--- working-2.6.orig/arch/powerpc/mm/hash_utils_64.c	2009-11-24 13:05:42.620304121 +1100
+++ working-2.6/arch/powerpc/mm/hash_utils_64.c	2009-11-24 13:06:24.709303983 +1100
@@ -835,9 +835,9 @@ void demote_segment_4k(struct mm_struct 
  * Result is 0: full permissions, _PAGE_RW: read-only,
  * _PAGE_USER or _PAGE_USER|_PAGE_RW: no access.
  */
-static int subpage_protection(pgd_t *pgdir, unsigned long ea)
+static int subpage_protection(struct mm_struct *mm, unsigned long ea)
 {
-	struct subpage_prot_table *spt = pgd_subpage_prot(pgdir);
+	struct subpage_prot_table *spt = &mm->context.spt;
 	u32 spp = 0;
 	u32 **sbpm, *sbpp;
 
@@ -865,7 +865,7 @@ static int subpage_protection(pgd_t *pgd
 }
 
 #else /* CONFIG_PPC_SUBPAGE_PROT */
-static inline int subpage_protection(pgd_t *pgdir, unsigned long ea)
+static inline int subpage_protection(struct mm_struct *mm, unsigned long ea)
 {
 	return 0;
 }
Index: working-2.6/arch/powerpc/mm/mmu_context_hash64.c
===================================================================
--- working-2.6.orig/arch/powerpc/mm/mmu_context_hash64.c	2009-11-24 13:18:28.604305720 +1100
+++ working-2.6/arch/powerpc/mm/mmu_context_hash64.c	2009-11-24 14:04:37.544327177 +1100
@@ -76,6 +76,7 @@ int init_new_context(struct task_struct 
 	 */
 	if (slice_mm_new_context(mm))
 		slice_set_user_psize(mm, mmu_virtual_psize);
+	subpage_prot_init_new_context(mm);
 	mm->context.id = index;
 
 	return 0;
@@ -92,5 +93,6 @@ EXPORT_SYMBOL_GPL(__destroy_context);
 void destroy_context(struct mm_struct *mm)
 {
 	__destroy_context(mm->context.id);
+	subpage_prot_free(mm);
 	mm->context.id = NO_CONTEXT;
 }


-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

^ permalink raw reply

* Re: [PATCH 7/8] spi_mpc8xxx: Turn qe_mode into flags
From: Benjamin Herrenschmidt @ 2009-11-24  5:03 UTC (permalink / raw)
  To: Kumar Gala
  Cc: David Brownell, Greg Kroah-Hartman, linux-kernel, linuxppc-dev,
	spi-devel-general, Andrew Morton
In-Reply-To: <3E303C4F-CE29-470F-B34A-3413F31BC23C@kernel.crashing.org>

On Thu, 2009-11-05 at 07:47 -0600, Kumar Gala wrote:
> On Oct 12, 2009, at 11:49 AM, Anton Vorontsov wrote:
> 
> > Soon there will be more flags introduced in subsequent patches, so
> > let's turn qe_mode into flags.
> >
> > Also introduce mpc8xxx_spi_strmode() and print current SPI mode.
> >
> > Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
> > Acked-by: David Brownell <dbrownell@users.sourceforge.net>
> > ---
> > drivers/spi/spi_mpc8xxx.c   |   30 +++++++++++++++++++-----------
> > include/linux/fsl_devices.h |    2 +-
> > 2 files changed, 20 insertions(+), 12 deletions(-)
> 
> applied to next

This patch breaks my 6xx config:

/home/benh/linux-powerpc-test/arch/powerpc/platforms/83xx/mpc832x_rdb.c: In function ‘of_fsl_spi_probe’:
/home/benh/linux-powerpc-test/arch/powerpc/platforms/83xx/mpc832x_rdb.c:77: error: ‘struct fsl_spi_platform_data’ has no member named ‘qe_

The reason is that the mpc832x_rdb.c code still uses the legacy probing
method. The fix is not totally trivial as the new flags are defined inside
spi_mpc8xxx.c so either the flags need to be moved to fsl_devices.h or
mpc832x_rdb.c needs to be converted to new style stuff.

I'll commit (will be up later today in my next branch) a fix moving the
flags over for now so the tree doesn't break building.

If you are going to keep the flags in the .c file you probably also want
to remove the platform device definition from fsl_devices.h anyways as
there's no point exposing to the world a structure with a "flags" member
if the definition of those flags isn't also exposed.

Cheers,
Ben.

^ permalink raw reply

* Re: [PATCH v5 0/4] pseries: Add cede support for cpu-offline
From: Vaidyanathan Srinivasan @ 2009-11-24  5:25 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Peter Zijlstra, Gautham R Shenoy, linux-kernel, Arun R Bharadwaj,
	Andrew Morton, linuxppc-dev, Ingo Molnar
In-Reply-To: <1259033709.16367.110.camel@pasglop>

* Benjamin Herrenschmidt <benh@kernel.crashing.org> [2009-11-24 14:35:09]:

> On Fri, 2009-10-30 at 10:52 +0530, Gautham R Shenoy wrote:
> > Hi,
> > 
> > This is version 5 of patch series that provides a framework to choose the
> > state a pseries CPU must be put to when it is offlined.
> > 
> > Previous versions can be found here:
> > Version 4: http://lkml.org/lkml/2009/10/9/59
> > Version 3: http://lkml.org/lkml/2009/9/15/164
> > Version 2: http://lkml.org/lkml/2009/8/28/102
> > Version 1: http://lkml.org/lkml/2009/8/6/236
> > 
> > Changes from the previous version include:
> > - Rebased against Nathan Fontenot's latest "pseries kernel handling of dynamic
> >   logical paritioning v4" patches found here:
> >   http://lkml.org/lkml/2009/10/21/98
> 
> I can't merge them right now because afaik, Nathan patches are still not
> quite ready. So we need to either get a final version of Nathan patches
> something like tomorrow or you need to rebase your series on current
> -next by the end of the week, or I'm afraid it's going to miss the next
> merge window.

Hi Ben,

I had checked with Nathan earlier and he mentioned that he is working
on an update.  We can post a rebase to -next tomorrow, but this series
depends on Nathan's patch, hence will work with him. This feature is
important for the next merge window.

Thanks,
Vaidy

^ permalink raw reply

* Re: [PATCH] ppc64: re-enable kexec to allow module loads with CONFIG_MODVERSIONS and CONFIG_RELOCATABLE turned on
From: Paul Mackerras @ 2009-11-24  4:05 UTC (permalink / raw)
  To: Neil Horman; +Cc: linuxppc-dev, Rusty Russell
In-Reply-To: <20091119195216.GC11414@hmsreliant.think-freely.org>

Neil Horman writes:

> 	Before anyone flames me for what a oddball solution this is, let me just
> say I'm trying to get the ball rolling here.  I think there may be better
> solutions that can be impemented in reloc_64.S, but I've yet to make any of the
> ones I've tried work successfully.  I'm open to suggestions, but this solution
> is the only one so far that I've been able to get to work. thanks :)

I had thought that the CRCs would be the only things with reloc
addends less than 4G, but it turns out that the toolchain folds
expressions like __pa(&sym) into just a load from a doubleword (in the
TOC) containing the physical address of sym.  That needs to be
relocated and its reloc addend will be less than 4GB.  Hence the
crashes early in boot that you were seeing with my proposed patch to
reloc_64.S.

Given that, your solution seems as reasonable as any.  Should this go
via the modules maintainer, Rusty Russell, perhaps?

In any case,

Acked-by: Paul Mackerras <paulus@samba.org>

> Adjust crcs in __kcrctab_* sections if relocs are used with CONFIG_RELOCATABLE
> 
> When CONFIG_MODVERSIONS and CONFIG_RELOCATABLE are enabled on powerpc platforms,
> kdump has been failing in a rather odd way.  specifically modules will not
> install.  This is because when validating the crcs of symbols that the module
> needs, the crc of the module never matches the crc that is stored in the kernel.
> 
> The underlying cause of this is how CONFIG_MODVERSIONS is implemented, and how
> CONFIG_RELOCATABLE are implemented.  with CONFIG_MODVERSIONS enabled, for every
> exported symbol in the kernel we emit 2 symbols, __crc_#sym which is declared
> extern and __kcrctab_##sym, which is placed in the __kcrctab section of the
> binary.  The latter has its value set equal to the address of the former
> (recalling it is declared extern).  After the object file is built, genksyms is
> run on the processed source, and crcs are computed for each exported symbol.
> genksyms then emits a linker script which defines each of the needed __crc_##sym
> symbols, and sets their addresses euqal to their respective crcs.  This script
> is then used in a secondary link to the previously build object file, so that
> the crcs of the missing symbol can be validated on module insert.
> 
> The problem here is that because __kcrctab_sym is set equal to &__crc_##sym, a
> relocation entry is emitted by the compiler for the __kcrctab__##sym.  Normally
> this is not a problem, since relocation on other arches is done without the aid
> of .rel.dyn sections.  PPC however uses these relocations when
> CONFIG_RELOCATABLE is enabled.  nominally, since addressing starts at 0 for ppc,
> its irrelevant, but if we start at a non-zero address (like we do when booting
> via kexec from reserved crashkernel memory), the ppc boot code iterates over the
> relocation entries, and winds up adding that relocation offset to all symbols,
> including the symbols that are actually the aforementioned crc values in the
> __kcrctab_* sections.  This effectively corrupts the crcs and prevents any
> module loads from happening during a kdump.
> 
> My solution is to 'undo' these relocations prior to boot up.  If
> ARCH_USES_RELOC_ENTRIES is defined, we add a symbol at address zero to the
> linker script for that arch (I call it reloc_start, so that &reloc_start = 0).
> This symbol will then indicate the relocation offset for any given boot.  We
> also add an initcall to the module code that, during boot, scans the __kcrctab_*
> sections and subtracts &reloc_start from every entry in those sections,
> restoring the appropriate crc value.
> 
> I've verified that this allows kexec to work properly on ppc64 systems myself.
> 
> Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
> 
> 
>  arch/powerpc/include/asm/local.h  |    6 ++++++
>  arch/powerpc/kernel/vmlinux.lds.S |    4 ++++
>  kernel/module.c                   |   30 ++++++++++++++++++++++++++++++
>  3 files changed, 40 insertions(+)
> 
> diff --git a/arch/powerpc/include/asm/local.h b/arch/powerpc/include/asm/local.h
> index 84b457a..9cc49e5 100644
> --- a/arch/powerpc/include/asm/local.h
> +++ b/arch/powerpc/include/asm/local.h
> @@ -4,6 +4,12 @@
>  #include <linux/percpu.h>
>  #include <asm/atomic.h>
>  
> +#ifdef CONFIG_MODVERSIONS
> +#define ARCH_USES_RELOC_ENTRIES
> +
> +extern unsigned long reloc_start;
> +#endif
> +
>  typedef struct
>  {
>  	atomic_long_t a;
> diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
> index 27735a7..2b9fb2e 100644
> --- a/arch/powerpc/kernel/vmlinux.lds.S
> +++ b/arch/powerpc/kernel/vmlinux.lds.S
> @@ -38,6 +38,10 @@ jiffies = jiffies_64 + 4;
>  #endif
>  SECTIONS
>  {
> +	. = 0;
> +	reloc_start = .;
> +	. = 0;
> +
>  	. = KERNELBASE;
>  
>  /*
> diff --git a/kernel/module.c b/kernel/module.c
> index 8b7d880..87a4928 100644
> --- a/kernel/module.c
> +++ b/kernel/module.c
> @@ -181,8 +181,11 @@ extern const struct kernel_symbol __stop___ksymtab_gpl_future[];
>  extern const struct kernel_symbol __start___ksymtab_gpl_future[];
>  extern const struct kernel_symbol __stop___ksymtab_gpl_future[];
>  extern const unsigned long __start___kcrctab[];
> +extern const unsigned long __stop___kcrctab[];
>  extern const unsigned long __start___kcrctab_gpl[];
> +extern const unsigned long __stop___kcrctab_gpl[];
>  extern const unsigned long __start___kcrctab_gpl_future[];
> +extern const unsigned long __stop___kcrctab_gpl_future[];
>  #ifdef CONFIG_UNUSED_SYMBOLS
>  extern const struct kernel_symbol __start___ksymtab_unused[];
>  extern const struct kernel_symbol __stop___ksymtab_unused[];
> @@ -3144,3 +3147,30 @@ int module_get_iter_tracepoints(struct tracepoint_iter *iter)
>  	return found;
>  }
>  #endif
> +
> +#ifdef ARCH_USES_RELOC_ENTRIES
> +static __init int adjust_kcrctab(void)
> +{
> +	int i;
> +	int count;
> +	unsigned long  *crc ;
> +
> +	count = __stop___kcrctab - __start___kcrctab;
> +	crc = (unsigned long *)__start___kcrctab;
> +	for (i = 0; i < count; i++) {
> +		crc[i] -= (unsigned long)&reloc_start;
> +	}
> +	count = __stop___kcrctab_gpl - __start___kcrctab_gpl;
> +	crc = (unsigned long *)__start___kcrctab_gpl;
> +	for (i = 0; i < count; i++) {
> +		crc[i] -= (unsigned long)&reloc_start;
> +	}
> +	count = __stop___kcrctab_gpl_future - __start___kcrctab_gpl_future;
> +	crc = (unsigned long *)__start___kcrctab_gpl_future;
> +	for (i = 0; i< count; i++) {
> +                crc[i] -= (unsigned long)&reloc_start;
> +	}
> +	return 0;
> +}
> +early_initcall(adjust_kcrctab);
> +#endif

^ permalink raw reply

* Re: [PATCH v5 0/4] pseries: Add cede support for cpu-offline
From: Benjamin Herrenschmidt @ 2009-11-24  3:35 UTC (permalink / raw)
  To: Gautham R Shenoy
  Cc: Peter Zijlstra, linux-kernel, Arun R Bharadwaj, Andrew Morton,
	linuxppc-dev, Ingo Molnar
In-Reply-To: <20091030052106.25493.42109.stgit@sofia.in.ibm.com>

On Fri, 2009-10-30 at 10:52 +0530, Gautham R Shenoy wrote:
> Hi,
> 
> This is version 5 of patch series that provides a framework to choose the
> state a pseries CPU must be put to when it is offlined.
> 
> Previous versions can be found here:
> Version 4: http://lkml.org/lkml/2009/10/9/59
> Version 3: http://lkml.org/lkml/2009/9/15/164
> Version 2: http://lkml.org/lkml/2009/8/28/102
> Version 1: http://lkml.org/lkml/2009/8/6/236
> 
> Changes from the previous version include:
> - Rebased against Nathan Fontenot's latest "pseries kernel handling of dynamic
>   logical paritioning v4" patches found here:
>   http://lkml.org/lkml/2009/10/21/98

I can't merge them right now because afaik, Nathan patches are still not
quite ready. So we need to either get a final version of Nathan patches
something like tomorrow or you need to rebase your series on current
-next by the end of the week, or I'm afraid it's going to miss the next
merge window.

Cheers,
Ben.

> - Added boot-time option to disable putting the offlined vcpus into an
>   extended H_CEDE state.
> 
> - Addressed Ben's comments regarding the if-else sequencing in
>   pseries_mach_cpu_die().
> 
> - Addition of comments for pseries_cpu_die() to distinguish it from
>   pseries_mach_cpu_die()
> 
> Also,
> 
> - This approach addresses Peter Z's objections regarding layering
>   violations. The user simply offlines the cpu and doesn't worry about what
>   state the CPU should be put into. That part is automatically handled by the
>   kernel.
> 
> - It does not add any additional sysfs interface instead uses the existing
>   sysfs interface to offline CPUs.
> 
> - On platforms which do not have support for ceding the vcpu with a
>   latency specifier value, the offlining mechanism defaults to the current
>   method of calling rtas_stop_self().
> 
> The patchset has been tested on the available pseries platforms and it works
> as per the expectations. I believe that the patch set is ready for inclusion.
> ---
> 
> Gautham R Shenoy (4):
>       pseries: Serialize cpu hotplug operations during deactivate Vs deallocate
>       pseries: Add code to online/offline CPUs of a DLPAR node.
>       pSeries: Add hooks to put the CPU into an appropriate offline state
>       pSeries: extended_cede_processor() helper function.
> 
> 
>  Documentation/cpu-hotplug.txt                   |    6 +
>  arch/powerpc/include/asm/lppaca.h               |    9 +
>  arch/powerpc/platforms/pseries/dlpar.c          |  129 ++++++++++++++++
>  arch/powerpc/platforms/pseries/hotplug-cpu.c    |  182 ++++++++++++++++++++++-
>  arch/powerpc/platforms/pseries/offline_states.h |   18 ++
>  arch/powerpc/platforms/pseries/plpar_wrappers.h |   22 +++
>  arch/powerpc/platforms/pseries/smp.c            |   19 ++
>  arch/powerpc/xmon/xmon.c                        |    3 
>  drivers/base/cpu.c                              |    2 
>  include/linux/cpu.h                             |   13 ++
>  10 files changed, 387 insertions(+), 16 deletions(-)
>  create mode 100644 arch/powerpc/platforms/pseries/offline_states.h
> 

^ permalink raw reply

* Re: [PATCH] zlib: Optimize inffast when copying direct from output
From: Benjamin Herrenschmidt @ 2009-11-24  3:12 UTC (permalink / raw)
  To: Joakim Tjernlund; +Cc: linuxppc-dev@ozlabs.org
In-Reply-To: <1257843644-8496-1-git-send-email-Joakim.Tjernlund@transmode.se>

On Tue, 2009-11-10 at 10:00 +0100, Joakim Tjernlund wrote:
> JFFS2 uses lesser compression ratio and inflate always
> ends up in "copy direct from output" case.
> This patch tries to optimize the direct copy procedure.
> Uses get_unaligned() but only in one place.
> The copy loop just above this one can also use this
> optimization, but I havn't done so as I have not tested if it
> is a win there too.
> On my MPC8321 this is about 17% faster on my JFFS2 root FS
> than the original.
> ---
> 
>  Would like some testing of the PowerPC boot wrapper and
>  a LE target before sending it upstream.

Well, you should probably submit that patch to lkml then :-)

I'm not sure its going to work to use get_unaligned() like that on all
archs .. it might be definitely something to discuss on some more
appropriate mailing list.

Cheers,
Ben.

>  arch/powerpc/boot/Makefile |    4 ++-
>  lib/zlib_inflate/inffast.c |   48 +++++++++++++++++++++++++++++++++----------
>  2 files changed, 40 insertions(+), 12 deletions(-)
> 
> diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
> index 9ae7b7e..98e4c4f 100644
> --- a/arch/powerpc/boot/Makefile
> +++ b/arch/powerpc/boot/Makefile
> @@ -20,7 +20,7 @@
>  all: $(obj)/zImage
>  
>  BOOTCFLAGS    := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
> -		 -fno-strict-aliasing -Os -msoft-float -pipe \
> +		 -fno-strict-aliasing -Os -msoft-float -pipe -D__KERNEL__\
>  		 -fomit-frame-pointer -fno-builtin -fPIC -nostdinc \
>  		 -isystem $(shell $(CROSS32CC) -print-file-name=include)
>  BOOTAFLAGS	:= -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc
> @@ -34,6 +34,8 @@ BOOTCFLAGS	+= -fno-stack-protector
>  endif
>  
>  BOOTCFLAGS	+= -I$(obj) -I$(srctree)/$(obj)
> +BOOTCFLAGS	+= -include include/linux/autoconf.h -Iarch/powerpc/include
> +BOOTCFLAGS	+= -Iinclude
>  
>  DTS_FLAGS	?= -p 1024
>  
> diff --git a/lib/zlib_inflate/inffast.c b/lib/zlib_inflate/inffast.c
> index 8550b0c..0c7fa3d 100644
> --- a/lib/zlib_inflate/inffast.c
> +++ b/lib/zlib_inflate/inffast.c
> @@ -4,6 +4,7 @@
>   */
>  
>  #include <linux/zutil.h>
> +#include <asm/unaligned.h>
>  #include "inftrees.h"
>  #include "inflate.h"
>  #include "inffast.h"
> @@ -24,9 +25,11 @@
>  #ifdef POSTINC
>  #  define OFF 0
>  #  define PUP(a) *(a)++
> +#  define UP_UNALIGNED(a) get_unaligned((a)++)
>  #else
>  #  define OFF 1
>  #  define PUP(a) *++(a)
> +#  define UP_UNALIGNED(a) get_unaligned(++(a))
>  #endif
>  
>  /*
> @@ -239,18 +242,41 @@ void inflate_fast(z_streamp strm, unsigned start)
>                      }
>                  }
>                  else {
> +		    unsigned short *sout;
> +		    unsigned long loops;
> +
>                      from = out - dist;          /* copy direct from output */
> -                    do {                        /* minimum length is three */
> -                        PUP(out) = PUP(from);
> -                        PUP(out) = PUP(from);
> -                        PUP(out) = PUP(from);
> -                        len -= 3;
> -                    } while (len > 2);
> -                    if (len) {
> -                        PUP(out) = PUP(from);
> -                        if (len > 1)
> -                            PUP(out) = PUP(from);
> -                    }
> +                    /* minimum length is three */
> +		    /* Align out addr */
> +		    if (!((long)(out - 1 + OFF)) & 1) {
> +			PUP(out) = PUP(from);
> +			len--;
> +		    }
> +		    sout = (unsigned short *)(out - OFF);
> +		    if (dist > 2 ) {
> +			unsigned short *sfrom;
> +
> +			sfrom = (unsigned short *)(from - OFF);
> +			loops = len >> 1;
> +			do
> +			    PUP(sout) = UP_UNALIGNED(sfrom);
> +			while (--loops);
> +			out = (unsigned char *)sout + OFF;
> +			from = (unsigned char *)sfrom + OFF;
> +		    } else { /* dist == 1 or dist == 2 */
> +			unsigned short pat16;
> +
> +			pat16 = *(sout-2+2*OFF);
> +			if (dist == 1)
> +			    pat16 = (pat16 & 0xff) | ((pat16 & 0xff ) << 8);
> +			loops = len >> 1;
> +			do
> +			    PUP(sout) = pat16;
> +			while (--loops);
> +			out = (unsigned char *)sout + OFF;
> +		    }
> +		    if (len & 1)
> +			PUP(out) = PUP(from);
>                  }
>              }
>              else if ((op & 64) == 0) {          /* 2nd level distance code */

^ permalink raw reply

* Re: [RFC PATCH 10/19] powerpc: gamecube/wii: early debugging using usbgecko
From: Segher Boessenkool @ 2009-11-24  0:54 UTC (permalink / raw)
  To: Albert Herranz; +Cc: linuxppc-dev
In-Reply-To: <1258927311-4340-11-git-send-email-albert_herranz@yahoo.es>

You set up DBAT1 here...

> +setup_usbgecko_bat:
> +	/* prepare a BAT for early io */
> +	lis	r8, 0x0c00
> +	ori	r8, r8, 0x002a	/* uncached, guarded ,rw */
> +	lis	r11, 0xcc00
> +	ori	r11, r11, 0x3	/* 128K */
> +#ifdef CONFIG_WII
> +	oris	r8, r8, 0x0100
> +	oris	r11, r11, 0x0100
> +#endif
> +	mtspr	SPRN_DBAT1L, r8
> +	mtspr	SPRN_DBAT1U, r11
> +	sync
> +	isync
> +	blr

... and again here:

> +void __init udbg_init_usbgecko(void)
> +{
> +	unsigned long vaddr, paddr;
> +
> +#if defined(CONFIG_GAMECUBE)
> +	paddr = 0x0c000000;
> +#elif defined(CONFIG_WII)
> +	paddr = 0x0d000000;
> +#else
> +#error Invalid platform for USB Gecko based early debugging.
> +#endif
> +
> +	vaddr = 0xc0000000 | paddr;
> +	setbat(1, vaddr, paddr, 128*1024, PAGE_KERNEL_NCG);

Do you need to do it twice?

> +	ug_io_base = (void __iomem *)(vaddr | 0x6814);

Oh, hardcoded slot2, now i'm confused which one should be it :-)


Segher

^ permalink raw reply

* Re: [RFC PATCH 09/19] powerpc: gamecube/wii: udbg support for usbgecko
From: Segher Boessenkool @ 2009-11-24  0:49 UTC (permalink / raw)
  To: Albert Herranz; +Cc: linuxppc-dev
In-Reply-To: <1258927311-4340-10-git-send-email-albert_herranz@yahoo.es>

> +	  If you say yes to this option, support will be included for the
> +	  USB Gecko adapter as an udbg console.
> +	  The USB Gecko is a EXI to USB Serial converter that can be plugged
> +	  into a memcard slot in the Nintendo GameCube/Wii.

Not "a" memcard slot, only the first one, you have it hardcoded.

> +#if 0
> +/*
> + * Trasmits a null terminated character string.
> + */
> +static void ug_puts(char *s)
> +{
> +	while (*s)
> +		ug_putc(*s++);
> +}
> +#endif

Remove?

> +	stdout = of_find_node_by_path(path);
> +	if (!stdout) {
> +		udbg_printf("%s: missing path %s", __func__, path);
> +		goto done;
> +	}
> +
> +	for (np = NULL;
> +	    (np = of_find_compatible_node(np, NULL, "usbgecko,usbgecko"));)
> +		if (np == stdout)
> +			break;
> +
> +	of_node_put(stdout);
> +	if (!np) {
> +		udbg_printf("%s: stdout is not an usbgecko", __func__);
> +		goto done;
> +	}

Surely there is something called something like of_node_is_compatible()
you can use here?  You already have the node pointer, there is no need
to look at all other nodes.


Segher

^ permalink raw reply

* Re: [RFC PATCH 06/19] powerpc: gamecube/wii: introduce GAMECUBE_COMMON
From: Segher Boessenkool @ 2009-11-24  0:35 UTC (permalink / raw)
  To: Albert Herranz; +Cc: linuxppc-dev
In-Reply-To: <1258927311-4340-7-git-send-email-albert_herranz@yahoo.es>

> Add a config option GAMECUBE_COMMON to be used as a dependency for all
> options common to the Nintendo GameCube and Wii video game consoles.

Maybe something like GAMECUBE_OR_WII instead?  "COMMON" is so
common it's meaningless.


Segher

^ permalink raw reply

* Re: [RFC PATCH 05/19] powerpc: wii: bootwrapper bits
From: Segher Boessenkool @ 2009-11-24  0:33 UTC (permalink / raw)
  To: Albert Herranz; +Cc: linuxppc-dev
In-Reply-To: <1258927311-4340-6-git-send-email-albert_herranz@yahoo.es>

> + * We enter with an unknown cache, high BATs and MMU status.

What does this mean?  You know the low four BATs on entry and
nothing else?

> +asm ("\n\

Global asm() is evil.

> +	mfmsr	9\n\
> +	andi.	0, 9, (1<<4)|(1<<5) /* MSR_DR|MSR_IR */\n\

> +	andc	9, 9, 0\n\

mfmsr 9 ; rlwinm 9,9,0,~0x30 ?

> +	mtspr	0x01a, 8	/* SRR0 */\n\
> +	mtspr	0x01b, 9	/* SRR1 */\n\

mtsrr0 and mtsrr1

> +	sync\n\
> +	rfi\n\

No need for sync before rfi

> +	mtspr	0x210, 8	/* IBAT0U */\n\
> +	mtspr	0x211, 8	/* IBAT0L */\n\

You only need to set the upper BAT to zero, saves some code.

> +	isync\n\

isync here is cargo cult

> +	li	8, 0x01ff	/* first 16MiB */\n\
> +	li	9, 0x0002	/* rw */\n\
> +	mtspr	0x210, 8	/* IBAT0U */\n\
> +	mtspr	0x211, 9	/* IBAT0L */\n\
> +	mtspr	0x218, 8	/* DBAT0U */\n\
> +	mtspr	0x219, 9	/* DBAT0L */\n\

M=0 for RAM?

>

Also, you should normally write the lower BAT first.  Doesn't matter
here because IR=DR=0 of course.

> +	lis	8, 0xcc00	/* I/O mem */\n\
> +	ori	8, 8, 0x3ff	/* 32MiB */\n\
> +	lis	9, 0x0c00\n\
> +	ori	9, 9, 0x002a	/* uncached, guarded, rw */\n\
> +	mtspr	0x21a, 8	/* DBAT1U */\n\
> +	mtspr	0x21b, 9	/* DBAT1L */\n\

Is there any real reason you don't identity map this?

> +	sync\n\
> +	isync\n\
> +\n\

Don't need these

> +	/* enable high BATs */\n\
> +	lis	8, 0x8200\n\
> +	mtspr	0x3f3, 8	/* HID4 */\n\

You need to use read-modify-write here.  Also, shouldn't you
enable the extra BATs before setting them?

And you _do_ need isync here as far as I can see.

> +	/* enable caches */\n\
> +	mfspr	8, 0x3f0\n\
> +	ori	8, 8, 0xc000\n\
> +	mtspr	0x3f0, 8	/* HID0 */\n\
> +	isync\n\

You need to invalidate the L1 caches at the same time as you enable
them.

> +void platform_init(unsigned long r3, unsigned long r4, unsigned  
> long r5)
> +{
> +	u32 heapsize = 24*1024*1024 - (u32)_end;
> +
> +	simple_alloc_init(_end, heapsize, 32, 64);
> +	fdt_init(_dtb_start);
> +
> +	if (!ug_grab_io_base() && ug_is_adapter_present())

The "!" reads weird.  Can you not make ug_is_adapter_present()
call ug_grab_io_base(), anyway?


Segher

^ permalink raw reply

* Re: [Cbe-oss-dev] [PATCH] spufs: Fix test in spufs_switch_log_read()
From: Jeremy Kerr @ 2009-11-24  0:24 UTC (permalink / raw)
  To: Roel Kluin; +Cc: cbe-oss-dev, Andrew Morton, Arnd Bergmann, linuxppc-dev
In-Reply-To: <4AD5EF0C.9050603@gmail.com>

Roel,

> size_t len cannot be less than 0.
> 
> Signed-off-by: Roel Kluin <roel.kluin@gmail.com>

Acked-by: Jeremy Kerr <jk@ozlabs.org>

Thanks!

Jeremy

^ permalink raw reply

* Re: [RFC PATCH 03/19] powerpc: gamecube: bootwrapper bits
From: Segher Boessenkool @ 2009-11-24  0:08 UTC (permalink / raw)
  To: Albert Herranz; +Cc: linuxppc-dev
In-Reply-To: <1258927311-4340-4-git-send-email-albert_herranz@yahoo.es>

Hi Albert,

> +asm ("\n\


A file scope asm?!  Please don't.

> + * We enter with the cache enabled, the MMU enabled and some known  
> legacy
> + * memory mappings active. xBAT3 is unused

It would be good if you could depend as little as possible on these  
things;
that makes writing another bootloader a lot easier.

> +	/* IBAT3,DBAT3 for first 16Mbytes */\n\
> +	li	8, 0x01ff	/* 16MB */\n\
> +	li      9, 0x0002	/* rw */\n\
> +	mtspr   0x216, 8	/* IBAT3U */\n\
> +	mtspr   0x217, 9	/* IBAT3L */\n\
> +	mtspr   0x21e, 8	/* DBAT3U */\n\
> +	mtspr   0x21f, 9	/* DBAT3L */\n\

WIMG=0000, are you sure?  Not M=1?

> +	bcl-    20,4*cr7+so,1f\n\

Just write  bcl 20,31,1f .


Segher

^ permalink raw reply

* Re: [RFC PATCH 14/19] powerpc: allow ioremap within reserved fake ram  regions
From: Michael Ellerman @ 2009-11-23 23:45 UTC (permalink / raw)
  To: Albert Herranz; +Cc: linuxppc-dev
In-Reply-To: <4B0AED90.6050600@yahoo.es>

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

On Mon, 2009-11-23 at 21:16 +0100, Albert Herranz wrote:
> >>  arch/powerpc/mm/pgtable_32.c |   19 ++++++++++++++++---
> >>  1 files changed, 16 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
> >> index cb96cb2..ba00cb1 100644
> >> --- a/arch/powerpc/mm/pgtable_32.c
> >> +++ b/arch/powerpc/mm/pgtable_32.c
> >> @@ -191,9 +191,22 @@ __ioremap_caller(phys_addr_t addr, unsigned long size, unsigned long flags,
> >>         * Don't allow anybody to remap normal RAM that we're using.
> >>         * mem_init() sets high_memory so only do the check after that.
> >>         */
> >> -       if (mem_init_done && (p < virt_to_phys(high_memory))) {
> >> -               printk("__ioremap(): phys addr 0x%llx is RAM lr %p\n",
> >> -                      (unsigned long long)p, __builtin_return_address(0));
> >> +       if (mem_init_done && (p < virt_to_phys(high_memory))
> >> +#ifdef CONFIG_WII
> >> +               /*
> >> +                * On some systems, though, we may want to remap an area
> >> +                * declared as normal RAM that we have memreserve'd at the
> >> +                * device tree. See wii.dts.
> >> +                * But we can't do that safely if we are using BATs to map
> >> +                * part of that area.
> >> +                */
> >> +           && !__map_without_bats
> >> +#endif
> >> +           ) {
> >> +               printk(KERN_WARNING
> >> +                      "__ioremap(): phys addr 0x%llx is RAM lr %p\n",
> >> +                      (unsigned long long)p,
> >> +                        __builtin_return_address(0));
> > 
> > This could adversely affect multiplatform kernels.  I'd rather get the
> > RAM problem fixed and not hack up common code to work around the hack.
> > 
> > g.
> > 
> 
> Would it be acceptable to create a global var __allow_ioremap_normal_ram that by default would have a value of 0 and would be set _only_ for those platforms needing it?
> 
> The other solutions I see is:
> - add support for discontiguous memory to powerpc 32-bits (which is not something that I can look into now)
> - don't use the precious second 64MB area (which is a waste)

- Implement your own ppc_md.ioremap(), see iseries & cell for example.

Currently that's only called on 64-bit, but you could change that.

If I'm reading your patch right, you should be able to do that check in
your platform's ioremap() and then call the generic implementation to do
the actual work.

cheers

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply

* [PATCH]  [PPC4xx] Fix device tree dts file for katmai board.
From: Pravin Bathija @ 2009-11-23 23:06 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: sr, Pravin Bathija

 Description: Set PCI-E node inbound DMA ranges size to 4GB for correct
 boot up of katmai. Including only changes for PCI-E DMA ranges as
 suggested by Stefan.

Signed-off-by: Pravin Bathija <pbathija@amcc.com>
Acked-by: Feng Kan <fkan@amcc.com>
Acked-by: Prodyut Hazarika <phazarika@amcc.com>
Acked-by: Loc Ho <lho@amcc.com>
Acked-by: Tirumala Reddy Marri <tmarri@amcc.com>
Acked-by: Victor Gallardo <vgallardo@amcc.com>
---
 arch/powerpc/boot/dts/katmai.dts |   22 +++++++++++-----------
 1 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/arch/powerpc/boot/dts/katmai.dts b/arch/powerpc/boot/dts/katmai.dts
index 077819b..d2595b2 100644
--- a/arch/powerpc/boot/dts/katmai.dts
+++ b/arch/powerpc/boot/dts/katmai.dts
@@ -245,8 +245,8 @@
 			ranges = <0x02000000 0x00000000 0x80000000 0x0000000d 0x80000000 0x00000000 0x80000000
 				  0x01000000 0x00000000 0x00000000 0x0000000c 0x08000000 0x00000000 0x00010000>;
 
-			/* Inbound 2GB range starting at 0 */
-			dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>;
+			/* Inbound 4GB range starting at 0 */
+			dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x1 0x00000000>;
 
 			/* This drives busses 0 to 0xf */
 			bus-range = <0x0 0xf>;
@@ -289,10 +289,10 @@
 			ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x00000000 0x00000000 0x80000000
 				  0x01000000 0x00000000 0x00000000 0x0000000f 0x80000000 0x00000000 0x00010000>;
 
-			/* Inbound 2GB range starting at 0 */
-			dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>;
+			/* Inbound 4GB range starting at 0 */
+			dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x1 0x00000000>;
 
-			/* This drives busses 10 to 0x1f */
+			/* This drives busses 0x10 to 0x1f */
 			bus-range = <0x10 0x1f>;
 
 			/* Legacy interrupts (note the weird polarity, the bridge seems
@@ -330,10 +330,10 @@
 			ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x80000000 0x00000000 0x80000000
 				  0x01000000 0x00000000 0x00000000 0x0000000f 0x80010000 0x00000000 0x00010000>;
 
-			/* Inbound 2GB range starting at 0 */
-			dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>;
+			/* Inbound 4GB range starting at 0 */
+			dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x1 0x00000000>;
 
-			/* This drives busses 10 to 0x1f */
+			/* This drives busses 0x20 to 0x2f */
 			bus-range = <0x20 0x2f>;
 
 			/* Legacy interrupts (note the weird polarity, the bridge seems
@@ -371,10 +371,10 @@
 			ranges = <0x02000000 0x00000000 0x80000000 0x0000000f 0x00000000 0x00000000 0x80000000
 				  0x01000000 0x00000000 0x00000000 0x0000000f 0x80020000 0x00000000 0x00010000>;
 
-			/* Inbound 2GB range starting at 0 */
-			dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>;
+			/* Inbound 4GB range starting at 0 */
+			dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x1 0x00000000>;
 
-			/* This drives busses 10 to 0x1f */
+			/* This drives busses 0x30 to 0x3f */
 			bus-range = <0x30 0x3f>;
 
 			/* Legacy interrupts (note the weird polarity, the bridge seems
-- 
1.5.5

^ permalink raw reply related

* [PATCH] powerpc: Fix DEBUG_HIGHMEM build break from d4515646699
From: Becky Bruce @ 2009-11-23 22:28 UTC (permalink / raw)
  To: linuxppc-dev, benh; +Cc: mingo

Code was added to mm/higmem.c that depends on several
kmap types that powerpc does not support.  We add dummy
invalid definitions for KM_NMI, KM_NM_PTE, and KM_IRQ_PTE.

According to list discussion, this fix should not be needed
anymore starting with 2.6.33.  The code is commented to this
effect so hopefully we will remember to remove this.

Signed-off-by: Becky Bruce <beckyb@kernel.crashing.org>
---
 arch/powerpc/include/asm/kmap_types.h |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/include/asm/kmap_types.h b/arch/powerpc/include/asm/kmap_types.h
index b6bac6f..9163695 100644
--- a/arch/powerpc/include/asm/kmap_types.h
+++ b/arch/powerpc/include/asm/kmap_types.h
@@ -29,5 +29,16 @@ enum km_type {
 	KM_TYPE_NR
 };
 
+/*
+ * This is a temporary build fix that (so they say on lkml....) should no longer
+ * be required after 2.6.33, because of changes planned to the kmap code.
+ * Let's try to remove this cruft then.
+ */
+#ifdef CONFIG_DEBUG_HIGHMEM
+#define KM_NMI		(-1)
+#define KM_NMI_PTE	(-1)
+#define KM_IRQ_PTE	(-1)
+#endif
+
 #endif	/* __KERNEL__ */
 #endif	/* _ASM_POWERPC_KMAP_TYPES_H */
-- 
1.6.0.6

^ permalink raw reply related

* Re: [RFC PATCH 10/19] powerpc: gamecube/wii: early debugging using usbgecko
From: Arnd Bergmann @ 2009-11-23 22:13 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Albert Herranz
In-Reply-To: <4B0ADE3F.1070604@yahoo.es>

On Monday 23 November 2009 19:10:55 Albert Herranz wrote:
> 
> Arnd Bergmann wrote:
> > On Sunday 22 November 2009, Albert Herranz wrote:
> >> +#ifdef CONFIG_PPC_EARLY_DEBUG_USBGECKO
> >> +setup_usbgecko_bat:
> >> +    /* prepare a BAT for early io */
> >> +    lis     r8, 0x0c00
> >> +    ori     r8, r8, 0x002a  /* uncached, guarded ,rw */
> >> +    lis     r11, 0xcc00
> >> +    ori     r11, r11, 0x3   /* 128K */
> >> +#ifdef CONFIG_WII
> >> +    oris    r8, r8, 0x0100
> >> +    oris    r11, r11, 0x0100
> >> +#endif
> >> +    mtspr   SPRN_DBAT1L, r8
> >> +    mtspr   SPRN_DBAT1U, r11
> >> +    sync
> >> +    isync
> >> +    blr
> >> +#endif
> > 
> > This will probably break other platforms if CONFIG_PPC_EARLY_DEBUG_USBGECKO
> > is set. In general, we try hard to make it possible to build generic
> > kernels for multiple systems, so it would be better to also add a runtime
> > check here.
> > 
> 
> Ok, I see the point.
> But, what makes CONFIG_PPC_EARLY_DEBUG_USBGECKO case different from CONFIG_PPC_EARLY_DEBUG_CPM case here?
> 

I looked again, and the help text for PPC_EARLY_DEBUG makes it very clear that
are never usable on a production kernel. Just leave your code the way it is here,
but if there are other places that prevent portable kernels, those should be fixed.
I'm not aware of any of those right now.

	Arnd <><

^ permalink raw reply

* Re: [RFC PATCH 04/19] powerpc: wii: device tree
From: Albert Herranz @ 2009-11-23 21:55 UTC (permalink / raw)
  To: Grant Likely; +Cc: linuxppc-dev
In-Reply-To: <fa686aa40911231236i2d49d21me1853d681077a9d1@mail.gmail.com>

Grant Likely wrote:
> This looks pretty good to me.  The documentation format isn't strict,
> just follow the pattern seen in other bindings.  Make sure you post
> new bindings to devicetree-discuss@lists.ozlabs.org for review.  A
> couple of comments below.
> 

Ok. I know it now for the next time :)

>> Documentation/powerpc/dts-bindings/gpio/i2c.txt
>>
>> GPIO-based I2C
>>
>> Required properties:
>> - compatible : should be "virtual,i2c-gpio".
>> - gpios : should specify GPIOs used for SDA and SCL lines, in that order.
>> - sda-is-open-drain : should be non-zero if SDA gpio is open-drain.
>> - sda-enforce-dir : should be non-zero if SDA gpio must be configured for
>>                    input before reading and for output before writing.
>> - scl-is-open-drain : should be non-zero if SCL gpio is open-drain.
>> - scl-is-output-only : should be non-zero if SCL is an output gpio only.
> 
> Instead of looking for a value in these properties, just make them
> empty properties and change behaviour based on whether or not the
> property is present.
> 

It seems reasonable. Thanks.

> Why is the scl-is-output-only property needed?
> 

It is needed to specify that the I2C master can't honour clock stretching done by I2C slave devices, as it cannot read back SCL.

>> - udelay : signal toggle delay. SCL frequency is (500 / udelay) kHz
> 
> You should follow the lead of
> Documentation/powerpc/dts-bindings/fsl/i2c.txt here and specify a
> clock-frequency property.
> 

Ok.

>> - timeout : clock stretching timeout in milliseconds.
> 
> I don't understand what this property means.
> 

It is the maximum time that the I2C master should wait for SCL to go high when a I2C slave is "clock-stretching".

Cheers,
Albert

^ permalink raw reply

* Re: [RFC PATCH 14/19] powerpc: allow ioremap within reserved fake ram regions
From: Grant Likely @ 2009-11-23 20:41 UTC (permalink / raw)
  To: Albert Herranz; +Cc: linuxppc-dev, Becky Bruce
In-Reply-To: <4B0AED90.6050600@yahoo.es>

On Mon, Nov 23, 2009 at 1:16 PM, Albert Herranz <albert_herranz@yahoo.es> w=
rote:
> Grant Likely wrote:
>> On Sun, Nov 22, 2009 at 3:01 PM, Albert Herranz <albert_herranz@yahoo.es=
> wrote:
>>> The Nintendo Wii has two discontiguous RAM memory areas called
>>> MEM1 and MEM2.
>>> MEM1 starts at 0x00000000 and contains 24MB of 1T-SRAM.
>>> MEM2 starts at 0x10000000 and contains 64MB of DDR2 RAM.
>>> Between both memory address ranges there is an address space
>>> where memory-mapped I/O registers are found.
>>>
>>> Currently, Linux 32-bit PowerPC does not support RAM in
>>> discontiguous memory address spaces. Thus, in order to use
>>> both RAM areas, we declare as RAM the range from the start of
>>> MEM1 to the end of useable MEM2 and exclude the needed parts
>>> with /memreserve/ statements, at the expense of wasting a bit
>>> of memory.
>>>
>>> As a side effect, we need to allow ioremapping RAM areas
>>> because the I/O address space sits within the memreserve'd part
>>> of the declared RAM region.
>>> Note that this is not safe if the region ioremapped is covered
>>> by an existing BAT mapping used to map RAM, so this is
>>> specifically banned here.
>>>
>>> Signed-off-by: Albert Herranz <albert_herranz@yahoo.es>
>>> ---
>>> =A0arch/powerpc/mm/pgtable_32.c | =A0 19 ++++++++++++++++---
>>> =A01 files changed, 16 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.=
c
>>> index cb96cb2..ba00cb1 100644
>>> --- a/arch/powerpc/mm/pgtable_32.c
>>> +++ b/arch/powerpc/mm/pgtable_32.c
>>> @@ -191,9 +191,22 @@ __ioremap_caller(phys_addr_t addr, unsigned long s=
ize, unsigned long flags,
>>> =A0 =A0 =A0 =A0 * Don't allow anybody to remap normal RAM that we're us=
ing.
>>> =A0 =A0 =A0 =A0 * mem_init() sets high_memory so only do the check afte=
r that.
>>> =A0 =A0 =A0 =A0 */
>>> - =A0 =A0 =A0 if (mem_init_done && (p < virt_to_phys(high_memory))) {
>>> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 printk("__ioremap(): phys addr 0x%llx is =
RAM lr %p\n",
>>> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(unsigned long long)p, __b=
uiltin_return_address(0));
>>> + =A0 =A0 =A0 if (mem_init_done && (p < virt_to_phys(high_memory))
>>> +#ifdef CONFIG_WII
>>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 /*
>>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* On some systems, though, we may want=
 to remap an area
>>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* declared as normal RAM that we have =
memreserve'd at the
>>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* device tree. See wii.dts.
>>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* But we can't do that safely if we ar=
e using BATs to map
>>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* part of that area.
>>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*/
>>> + =A0 =A0 =A0 =A0 =A0 && !__map_without_bats
>>> +#endif
>>> + =A0 =A0 =A0 =A0 =A0 ) {
>>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 printk(KERN_WARNING
>>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0"__ioremap(): phys addr 0x=
%llx is RAM lr %p\n",
>>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(unsigned long long)p,
>>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0__builtin_return_addre=
ss(0));
>>
>> This could adversely affect multiplatform kernels. =A0I'd rather get the
>> RAM problem fixed and not hack up common code to work around the hack.
>>
>> g.
>>
>
> Would it be acceptable to create a global var __allow_ioremap_normal_ram =
that by default would have a value of 0 and would be set _only_ for those p=
latforms needing it?

I'm not the best one to answer this since I don't dig into the mm code
very often.  Ben?  Kumar?  Becky?  Thoughts?

> The other solutions I see is:
> - add support for discontiguous memory to powerpc 32-bits (which is not s=
omething that I can look into now)

I of course like this option.  :-)

> - don't use the precious second 64MB area (which is a waste)

Not exactly nice, but it might be wise to do this now so that
discussion about how to fix it best won't block getting the bulk of
support into mainline.

g.

--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ 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