LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [RFC/PATCH] [POWERPC] Make lmb support large physical addressing
From: Becky Bruce @ 2008-02-13 22:43 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: sparclinux, davem, linux-kernel

Convert the lmb code to use phys_addr_t instead of unsigned long for
physical addresses and sizes.  This is needed to support large amounts
of RAM on 32-bit systems that support 36-bit physical addressing.

Built/booted on mpc8641; build tested on pasemi and 44x.

Signed-off-by: Becky Bruce <becky.bruce@freescale.com>
---
Folks,

This has been sitting in my tree for a few days, and now it looks like
David M. has submitted a patch that changes the lmb code to be shared
between sparc and powerpc.  Sparc has no notion of a phys_addr_t.
Should we just use u64 everywhere in this code instead?  Thoughts?

Cheers,
Becky

 arch/powerpc/mm/lmb.c     |   92 +++++++++++++++++++++++----------------------
 include/asm-powerpc/lmb.h |   38 +++++++++---------
 2 files changed, 66 insertions(+), 64 deletions(-)

diff --git a/arch/powerpc/mm/lmb.c b/arch/powerpc/mm/lmb.c
index 4ce23bc..31d86ff 100644
--- a/arch/powerpc/mm/lmb.c
+++ b/arch/powerpc/mm/lmb.c
@@ -41,33 +41,34 @@ void lmb_dump_all(void)
 
 	DBG("lmb_dump_all:\n");
 	DBG("    memory.cnt		  = 0x%lx\n", lmb.memory.cnt);
-	DBG("    memory.size		  = 0x%lx\n", lmb.memory.size);
+	DBG("    memory.size		  = 0x%llx\n",
+	    (unsigned long long)lmb.memory.size);
 	for (i=0; i < lmb.memory.cnt ;i++) {
-		DBG("    memory.region[0x%x].base       = 0x%lx\n",
-			    i, lmb.memory.region[i].base);
-		DBG("		      .size     = 0x%lx\n",
-			    lmb.memory.region[i].size);
+		DBG("    memory.region[0x%x].base       = 0x%llx\n",
+		    i, (unsigned long long)lmb.memory.region[i].base);
+		DBG("		      .size     = 0x%llx\n",
+		    (unsigned long long)lmb.memory.region[i].size);
 	}
 
 	DBG("\n    reserved.cnt	  = 0x%lx\n", lmb.reserved.cnt);
 	DBG("    reserved.size	  = 0x%lx\n", lmb.reserved.size);
 	for (i=0; i < lmb.reserved.cnt ;i++) {
-		DBG("    reserved.region[0x%x].base       = 0x%lx\n",
-			    i, lmb.reserved.region[i].base);
-		DBG("		      .size     = 0x%lx\n",
-			    lmb.reserved.region[i].size);
+		DBG("    reserved.region[0x%x].base       = 0x%llx\n",
+		    i, (unsigned long long)lmb.reserved.region[i].base);
+		DBG("		      .size     = 0x%llx\n",
+		    (unsigned long long)lmb.reserved.region[i].size);
 	}
 #endif /* DEBUG */
 }
 
-static unsigned long __init lmb_addrs_overlap(unsigned long base1,
-		unsigned long size1, unsigned long base2, unsigned long size2)
+static unsigned long __init lmb_addrs_overlap(phys_addr_t base1,
+		phys_addr_t size1, phys_addr_t base2, phys_addr_t size2)
 {
 	return ((base1 < (base2+size2)) && (base2 < (base1+size1)));
 }
 
-static long __init lmb_addrs_adjacent(unsigned long base1, unsigned long size1,
-		unsigned long base2, unsigned long size2)
+static long __init lmb_addrs_adjacent(phys_addr_t base1, phys_addr_t size1,
+		phys_addr_t base2, phys_addr_t size2)
 {
 	if (base2 == base1 + size1)
 		return 1;
@@ -80,10 +81,10 @@ static long __init lmb_addrs_adjacent(unsigned long base1, unsigned long size1,
 static long __init lmb_regions_adjacent(struct lmb_region *rgn,
 		unsigned long r1, unsigned long r2)
 {
-	unsigned long base1 = rgn->region[r1].base;
-	unsigned long size1 = rgn->region[r1].size;
-	unsigned long base2 = rgn->region[r2].base;
-	unsigned long size2 = rgn->region[r2].size;
+	phys_addr_t base1 = rgn->region[r1].base;
+	phys_addr_t size1 = rgn->region[r1].size;
+	phys_addr_t base2 = rgn->region[r2].base;
+	phys_addr_t size2 = rgn->region[r2].size;
 
 	return lmb_addrs_adjacent(base1, size1, base2, size2);
 }
@@ -135,16 +136,16 @@ void __init lmb_analyze(void)
 }
 
 /* This routine called with relocation disabled. */
-static long __init lmb_add_region(struct lmb_region *rgn, unsigned long base,
-				  unsigned long size)
+static long __init lmb_add_region(struct lmb_region *rgn, phys_addr_t base,
+				  phys_addr_t size)
 {
 	unsigned long coalesced = 0;
 	long adjacent, i;
 
 	/* First try and coalesce this LMB with another. */
 	for (i=0; i < rgn->cnt; i++) {
-		unsigned long rgnbase = rgn->region[i].base;
-		unsigned long rgnsize = rgn->region[i].size;
+		phys_addr_t rgnbase = rgn->region[i].base;
+		phys_addr_t rgnsize = rgn->region[i].size;
 
 		if ((rgnbase == base) && (rgnsize == size))
 			/* Already have this region, so we're done */
@@ -191,7 +192,7 @@ static long __init lmb_add_region(struct lmb_region *rgn, unsigned long base,
 }
 
 /* This routine may be called with relocation disabled. */
-long __init lmb_add(unsigned long base, unsigned long size)
+long __init lmb_add(phys_addr_t base, phys_addr_t size)
 {
 	struct lmb_region *_rgn = &(lmb.memory);
 
@@ -203,7 +204,7 @@ long __init lmb_add(unsigned long base, unsigned long size)
 
 }
 
-long __init lmb_reserve(unsigned long base, unsigned long size)
+long __init lmb_reserve(phys_addr_t base, phys_addr_t size)
 {
 	struct lmb_region *_rgn = &(lmb.reserved);
 
@@ -212,14 +213,14 @@ long __init lmb_reserve(unsigned long base, unsigned long size)
 	return lmb_add_region(_rgn, base, size);
 }
 
-long __init lmb_overlaps_region(struct lmb_region *rgn, unsigned long base,
-				unsigned long size)
+long __init lmb_overlaps_region(struct lmb_region *rgn, phys_addr_t base,
+				phys_addr_t size)
 {
 	unsigned long i;
 
 	for (i=0; i < rgn->cnt; i++) {
-		unsigned long rgnbase = rgn->region[i].base;
-		unsigned long rgnsize = rgn->region[i].size;
+		phys_addr_t rgnbase = rgn->region[i].base;
+		phys_addr_t rgnsize = rgn->region[i].size;
 		if ( lmb_addrs_overlap(base,size,rgnbase,rgnsize) ) {
 			break;
 		}
@@ -228,30 +229,30 @@ long __init lmb_overlaps_region(struct lmb_region *rgn, unsigned long base,
 	return (i < rgn->cnt) ? i : -1;
 }
 
-unsigned long __init lmb_alloc(unsigned long size, unsigned long align)
+phys_addr_t __init lmb_alloc(phys_addr_t size, phys_addr_t align)
 {
 	return lmb_alloc_base(size, align, LMB_ALLOC_ANYWHERE);
 }
 
-unsigned long __init lmb_alloc_base(unsigned long size, unsigned long align,
-				    unsigned long max_addr)
+phys_addr_t __init lmb_alloc_base(phys_addr_t size, phys_addr_t align,
+				    phys_addr_t max_addr)
 {
-	unsigned long alloc;
+	phys_addr_t alloc;
 
 	alloc = __lmb_alloc_base(size, align, max_addr);
 
 	if (alloc == 0)
-		panic("ERROR: Failed to allocate 0x%lx bytes below 0x%lx.\n",
-				size, max_addr);
+		panic("ERROR: Failed to allocate 0x%llx bytes below 0x%llx.\n",
+		      (unsigned long long)size, (unsigned long long)max_addr);
 
 	return alloc;
 }
 
-unsigned long __init __lmb_alloc_base(unsigned long size, unsigned long align,
-				    unsigned long max_addr)
+phys_addr_t __init __lmb_alloc_base(phys_addr_t size, phys_addr_t align,
+				    phys_addr_t max_addr)
 {
 	long i, j;
-	unsigned long base = 0;
+	phys_addr_t base = 0;
 
 	BUG_ON(0 == size);
 
@@ -261,8 +262,8 @@ unsigned long __init __lmb_alloc_base(unsigned long size, unsigned long align,
 		max_addr = __max_low_memory;
 #endif
 	for (i = lmb.memory.cnt-1; i >= 0; i--) {
-		unsigned long lmbbase = lmb.memory.region[i].base;
-		unsigned long lmbsize = lmb.memory.region[i].size;
+		phys_addr_t lmbbase = lmb.memory.region[i].base;
+		phys_addr_t lmbsize = lmb.memory.region[i].size;
 
 		if (max_addr == LMB_ALLOC_ANYWHERE)
 			base = _ALIGN_DOWN(lmbbase + lmbsize - size, align);
@@ -290,12 +291,12 @@ unsigned long __init __lmb_alloc_base(unsigned long size, unsigned long align,
 }
 
 /* You must call lmb_analyze() before this. */
-unsigned long __init lmb_phys_mem_size(void)
+phys_addr_t __init lmb_phys_mem_size(void)
 {
 	return lmb.memory.size;
 }
 
-unsigned long __init lmb_end_of_DRAM(void)
+phys_addr_t __init lmb_end_of_DRAM(void)
 {
 	int idx = lmb.memory.cnt - 1;
 
@@ -303,9 +304,10 @@ unsigned long __init lmb_end_of_DRAM(void)
 }
 
 /* You must call lmb_analyze() after this. */
-void __init lmb_enforce_memory_limit(unsigned long memory_limit)
+void __init lmb_enforce_memory_limit(phys_addr_t memory_limit)
 {
-	unsigned long i, limit;
+	unsigned long i;
+	phys_addr_t limit;
 	struct lmb_property *p;
 
 	if (! memory_limit)
@@ -343,13 +345,13 @@ void __init lmb_enforce_memory_limit(unsigned long memory_limit)
 	}
 }
 
-int __init lmb_is_reserved(unsigned long addr)
+int __init lmb_is_reserved(phys_addr_t addr)
 {
 	int i;
 
 	for (i = 0; i < lmb.reserved.cnt; i++) {
-		unsigned long upper = lmb.reserved.region[i].base +
-				      lmb.reserved.region[i].size - 1;
+		phys_addr_t upper = lmb.reserved.region[i].base +
+			lmb.reserved.region[i].size - 1;
 		if ((addr >= lmb.reserved.region[i].base) && (addr <= upper))
 			return 1;
 	}
diff --git a/include/asm-powerpc/lmb.h b/include/asm-powerpc/lmb.h
index 5d1dc48..2233f51 100644
--- a/include/asm-powerpc/lmb.h
+++ b/include/asm-powerpc/lmb.h
@@ -20,19 +20,19 @@
 #define MAX_LMB_REGIONS 128
 
 struct lmb_property {
-	unsigned long base;
-	unsigned long size;
+	phys_addr_t base;
+	phys_addr_t size;
 };
 
 struct lmb_region {
 	unsigned long cnt;
-	unsigned long size;
+	phys_addr_t size;
 	struct lmb_property region[MAX_LMB_REGIONS+1];
 };
 
 struct lmb {
 	unsigned long debug;
-	unsigned long rmo_size;
+	phys_addr_t rmo_size;
 	struct lmb_region memory;
 	struct lmb_region reserved;
 };
@@ -41,36 +41,36 @@ extern struct lmb lmb;
 
 extern void __init lmb_init(void);
 extern void __init lmb_analyze(void);
-extern long __init lmb_add(unsigned long base, unsigned long size);
-extern long __init lmb_reserve(unsigned long base, unsigned long size);
-extern unsigned long __init lmb_alloc(unsigned long size, unsigned long align);
-extern unsigned long __init lmb_alloc_base(unsigned long size,
-		unsigned long align, unsigned long max_addr);
-extern unsigned long __init __lmb_alloc_base(unsigned long size,
-		unsigned long align, unsigned long max_addr);
-extern unsigned long __init lmb_phys_mem_size(void);
-extern unsigned long __init lmb_end_of_DRAM(void);
-extern void __init lmb_enforce_memory_limit(unsigned long memory_limit);
-extern int __init lmb_is_reserved(unsigned long addr);
+extern long __init lmb_add(phys_addr_t base, phys_addr_t size);
+extern long __init lmb_reserve(phys_addr_t base, phys_addr_t size);
+extern phys_addr_t __init lmb_alloc(phys_addr_t size, phys_addr_t align);
+extern phys_addr_t __init lmb_alloc_base(phys_addr_t size,
+		phys_addr_t, phys_addr_t max_addr);
+extern phys_addr_t __init __lmb_alloc_base(phys_addr_t size,
+		phys_addr_t align, phys_addr_t max_addr);
+extern phys_addr_t __init lmb_phys_mem_size(void);
+extern phys_addr_t __init lmb_end_of_DRAM(void);
+extern void __init lmb_enforce_memory_limit(phys_addr_t memory_limit);
+extern int __init lmb_is_reserved(phys_addr_t addr);
 
 extern void lmb_dump_all(void);
 
-static inline unsigned long
+static inline phys_addr_t
 lmb_size_bytes(struct lmb_region *type, unsigned long region_nr)
 {
 	return type->region[region_nr].size;
 }
-static inline unsigned long
+static inline phys_addr_t
 lmb_size_pages(struct lmb_region *type, unsigned long region_nr)
 {
 	return lmb_size_bytes(type, region_nr) >> PAGE_SHIFT;
 }
-static inline unsigned long
+static inline phys_addr_t
 lmb_start_pfn(struct lmb_region *type, unsigned long region_nr)
 {
 	return type->region[region_nr].base >> PAGE_SHIFT;
 }
-static inline unsigned long
+static inline phys_addr_t
 lmb_end_pfn(struct lmb_region *type, unsigned long region_nr)
 {
 	return lmb_start_pfn(type, region_nr) +
-- 
1.5.3.8

^ permalink raw reply related

* [RFC/PATCH] Make lmb support large physical addressing
From: Becky Bruce @ 2008-02-13 22:33 UTC (permalink / raw)
  To: linuxppc-dev


Convert the lmb code to use phys_addr_t instead of unsigned long for
physical addresses and sizes.  This is needed to support large amounts
of RAM on 32-bit systems that support 36-bit physical addressing.

Built/booted on mpc8641; build tested on pasemi and 44x.

Signed-off-by: Becky Bruce <becky.bruce@freescale.com>
---
Folks,

This has been sitting in my tree for a few days, and now it looks like
someone has submitted a patch that changes the lmb code to be shared
between sparc and powerpc.  Sparc has no notion of a phys_addr_t.
Should we just use u64 everywhere in this code instead?

Cheers,
Becky

 arch/powerpc/mm/lmb.c     |   92 +++++++++++++++++++++++----------------------
 include/asm-powerpc/lmb.h |   38 +++++++++---------
 2 files changed, 66 insertions(+), 64 deletions(-)

diff --git a/arch/powerpc/mm/lmb.c b/arch/powerpc/mm/lmb.c
index 4ce23bc..31d86ff 100644
--- a/arch/powerpc/mm/lmb.c
+++ b/arch/powerpc/mm/lmb.c
@@ -41,33 +41,34 @@ void lmb_dump_all(void)
 
 	DBG("lmb_dump_all:\n");
 	DBG("    memory.cnt		  = 0x%lx\n", lmb.memory.cnt);
-	DBG("    memory.size		  = 0x%lx\n", lmb.memory.size);
+	DBG("    memory.size		  = 0x%llx\n",
+	    (unsigned long long)lmb.memory.size);
 	for (i=0; i < lmb.memory.cnt ;i++) {
-		DBG("    memory.region[0x%x].base       = 0x%lx\n",
-			    i, lmb.memory.region[i].base);
-		DBG("		      .size     = 0x%lx\n",
-			    lmb.memory.region[i].size);
+		DBG("    memory.region[0x%x].base       = 0x%llx\n",
+		    i, (unsigned long long)lmb.memory.region[i].base);
+		DBG("		      .size     = 0x%llx\n",
+		    (unsigned long long)lmb.memory.region[i].size);
 	}
 
 	DBG("\n    reserved.cnt	  = 0x%lx\n", lmb.reserved.cnt);
 	DBG("    reserved.size	  = 0x%lx\n", lmb.reserved.size);
 	for (i=0; i < lmb.reserved.cnt ;i++) {
-		DBG("    reserved.region[0x%x].base       = 0x%lx\n",
-			    i, lmb.reserved.region[i].base);
-		DBG("		      .size     = 0x%lx\n",
-			    lmb.reserved.region[i].size);
+		DBG("    reserved.region[0x%x].base       = 0x%llx\n",
+		    i, (unsigned long long)lmb.reserved.region[i].base);
+		DBG("		      .size     = 0x%llx\n",
+		    (unsigned long long)lmb.reserved.region[i].size);
 	}
 #endif /* DEBUG */
 }
 
-static unsigned long __init lmb_addrs_overlap(unsigned long base1,
-		unsigned long size1, unsigned long base2, unsigned long size2)
+static unsigned long __init lmb_addrs_overlap(phys_addr_t base1,
+		phys_addr_t size1, phys_addr_t base2, phys_addr_t size2)
 {
 	return ((base1 < (base2+size2)) && (base2 < (base1+size1)));
 }
 
-static long __init lmb_addrs_adjacent(unsigned long base1, unsigned long size1,
-		unsigned long base2, unsigned long size2)
+static long __init lmb_addrs_adjacent(phys_addr_t base1, phys_addr_t size1,
+		phys_addr_t base2, phys_addr_t size2)
 {
 	if (base2 == base1 + size1)
 		return 1;
@@ -80,10 +81,10 @@ static long __init lmb_addrs_adjacent(unsigned long base1, unsigned long size1,
 static long __init lmb_regions_adjacent(struct lmb_region *rgn,
 		unsigned long r1, unsigned long r2)
 {
-	unsigned long base1 = rgn->region[r1].base;
-	unsigned long size1 = rgn->region[r1].size;
-	unsigned long base2 = rgn->region[r2].base;
-	unsigned long size2 = rgn->region[r2].size;
+	phys_addr_t base1 = rgn->region[r1].base;
+	phys_addr_t size1 = rgn->region[r1].size;
+	phys_addr_t base2 = rgn->region[r2].base;
+	phys_addr_t size2 = rgn->region[r2].size;
 
 	return lmb_addrs_adjacent(base1, size1, base2, size2);
 }
@@ -135,16 +136,16 @@ void __init lmb_analyze(void)
 }
 
 /* This routine called with relocation disabled. */
-static long __init lmb_add_region(struct lmb_region *rgn, unsigned long base,
-				  unsigned long size)
+static long __init lmb_add_region(struct lmb_region *rgn, phys_addr_t base,
+				  phys_addr_t size)
 {
 	unsigned long coalesced = 0;
 	long adjacent, i;
 
 	/* First try and coalesce this LMB with another. */
 	for (i=0; i < rgn->cnt; i++) {
-		unsigned long rgnbase = rgn->region[i].base;
-		unsigned long rgnsize = rgn->region[i].size;
+		phys_addr_t rgnbase = rgn->region[i].base;
+		phys_addr_t rgnsize = rgn->region[i].size;
 
 		if ((rgnbase == base) && (rgnsize == size))
 			/* Already have this region, so we're done */
@@ -191,7 +192,7 @@ static long __init lmb_add_region(struct lmb_region *rgn, unsigned long base,
 }
 
 /* This routine may be called with relocation disabled. */
-long __init lmb_add(unsigned long base, unsigned long size)
+long __init lmb_add(phys_addr_t base, phys_addr_t size)
 {
 	struct lmb_region *_rgn = &(lmb.memory);
 
@@ -203,7 +204,7 @@ long __init lmb_add(unsigned long base, unsigned long size)
 
 }
 
-long __init lmb_reserve(unsigned long base, unsigned long size)
+long __init lmb_reserve(phys_addr_t base, phys_addr_t size)
 {
 	struct lmb_region *_rgn = &(lmb.reserved);
 
@@ -212,14 +213,14 @@ long __init lmb_reserve(unsigned long base, unsigned long size)
 	return lmb_add_region(_rgn, base, size);
 }
 
-long __init lmb_overlaps_region(struct lmb_region *rgn, unsigned long base,
-				unsigned long size)
+long __init lmb_overlaps_region(struct lmb_region *rgn, phys_addr_t base,
+				phys_addr_t size)
 {
 	unsigned long i;
 
 	for (i=0; i < rgn->cnt; i++) {
-		unsigned long rgnbase = rgn->region[i].base;
-		unsigned long rgnsize = rgn->region[i].size;
+		phys_addr_t rgnbase = rgn->region[i].base;
+		phys_addr_t rgnsize = rgn->region[i].size;
 		if ( lmb_addrs_overlap(base,size,rgnbase,rgnsize) ) {
 			break;
 		}
@@ -228,30 +229,30 @@ long __init lmb_overlaps_region(struct lmb_region *rgn, unsigned long base,
 	return (i < rgn->cnt) ? i : -1;
 }
 
-unsigned long __init lmb_alloc(unsigned long size, unsigned long align)
+phys_addr_t __init lmb_alloc(phys_addr_t size, phys_addr_t align)
 {
 	return lmb_alloc_base(size, align, LMB_ALLOC_ANYWHERE);
 }
 
-unsigned long __init lmb_alloc_base(unsigned long size, unsigned long align,
-				    unsigned long max_addr)
+phys_addr_t __init lmb_alloc_base(phys_addr_t size, phys_addr_t align,
+				    phys_addr_t max_addr)
 {
-	unsigned long alloc;
+	phys_addr_t alloc;
 
 	alloc = __lmb_alloc_base(size, align, max_addr);
 
 	if (alloc == 0)
-		panic("ERROR: Failed to allocate 0x%lx bytes below 0x%lx.\n",
-				size, max_addr);
+		panic("ERROR: Failed to allocate 0x%llx bytes below 0x%llx.\n",
+		      (unsigned long long)size, (unsigned long long)max_addr);
 
 	return alloc;
 }
 
-unsigned long __init __lmb_alloc_base(unsigned long size, unsigned long align,
-				    unsigned long max_addr)
+phys_addr_t __init __lmb_alloc_base(phys_addr_t size, phys_addr_t align,
+				    phys_addr_t max_addr)
 {
 	long i, j;
-	unsigned long base = 0;
+	phys_addr_t base = 0;
 
 	BUG_ON(0 == size);
 
@@ -261,8 +262,8 @@ unsigned long __init __lmb_alloc_base(unsigned long size, unsigned long align,
 		max_addr = __max_low_memory;
 #endif
 	for (i = lmb.memory.cnt-1; i >= 0; i--) {
-		unsigned long lmbbase = lmb.memory.region[i].base;
-		unsigned long lmbsize = lmb.memory.region[i].size;
+		phys_addr_t lmbbase = lmb.memory.region[i].base;
+		phys_addr_t lmbsize = lmb.memory.region[i].size;
 
 		if (max_addr == LMB_ALLOC_ANYWHERE)
 			base = _ALIGN_DOWN(lmbbase + lmbsize - size, align);
@@ -290,12 +291,12 @@ unsigned long __init __lmb_alloc_base(unsigned long size, unsigned long align,
 }
 
 /* You must call lmb_analyze() before this. */
-unsigned long __init lmb_phys_mem_size(void)
+phys_addr_t __init lmb_phys_mem_size(void)
 {
 	return lmb.memory.size;
 }
 
-unsigned long __init lmb_end_of_DRAM(void)
+phys_addr_t __init lmb_end_of_DRAM(void)
 {
 	int idx = lmb.memory.cnt - 1;
 
@@ -303,9 +304,10 @@ unsigned long __init lmb_end_of_DRAM(void)
 }
 
 /* You must call lmb_analyze() after this. */
-void __init lmb_enforce_memory_limit(unsigned long memory_limit)
+void __init lmb_enforce_memory_limit(phys_addr_t memory_limit)
 {
-	unsigned long i, limit;
+	unsigned long i;
+	phys_addr_t limit;
 	struct lmb_property *p;
 
 	if (! memory_limit)
@@ -343,13 +345,13 @@ void __init lmb_enforce_memory_limit(unsigned long memory_limit)
 	}
 }
 
-int __init lmb_is_reserved(unsigned long addr)
+int __init lmb_is_reserved(phys_addr_t addr)
 {
 	int i;
 
 	for (i = 0; i < lmb.reserved.cnt; i++) {
-		unsigned long upper = lmb.reserved.region[i].base +
-				      lmb.reserved.region[i].size - 1;
+		phys_addr_t upper = lmb.reserved.region[i].base +
+			lmb.reserved.region[i].size - 1;
 		if ((addr >= lmb.reserved.region[i].base) && (addr <= upper))
 			return 1;
 	}
diff --git a/include/asm-powerpc/lmb.h b/include/asm-powerpc/lmb.h
index 5d1dc48..2233f51 100644
--- a/include/asm-powerpc/lmb.h
+++ b/include/asm-powerpc/lmb.h
@@ -20,19 +20,19 @@
 #define MAX_LMB_REGIONS 128
 
 struct lmb_property {
-	unsigned long base;
-	unsigned long size;
+	phys_addr_t base;
+	phys_addr_t size;
 };
 
 struct lmb_region {
 	unsigned long cnt;
-	unsigned long size;
+	phys_addr_t size;
 	struct lmb_property region[MAX_LMB_REGIONS+1];
 };
 
 struct lmb {
 	unsigned long debug;
-	unsigned long rmo_size;
+	phys_addr_t rmo_size;
 	struct lmb_region memory;
 	struct lmb_region reserved;
 };
@@ -41,36 +41,36 @@ extern struct lmb lmb;
 
 extern void __init lmb_init(void);
 extern void __init lmb_analyze(void);
-extern long __init lmb_add(unsigned long base, unsigned long size);
-extern long __init lmb_reserve(unsigned long base, unsigned long size);
-extern unsigned long __init lmb_alloc(unsigned long size, unsigned long align);
-extern unsigned long __init lmb_alloc_base(unsigned long size,
-		unsigned long align, unsigned long max_addr);
-extern unsigned long __init __lmb_alloc_base(unsigned long size,
-		unsigned long align, unsigned long max_addr);
-extern unsigned long __init lmb_phys_mem_size(void);
-extern unsigned long __init lmb_end_of_DRAM(void);
-extern void __init lmb_enforce_memory_limit(unsigned long memory_limit);
-extern int __init lmb_is_reserved(unsigned long addr);
+extern long __init lmb_add(phys_addr_t base, phys_addr_t size);
+extern long __init lmb_reserve(phys_addr_t base, phys_addr_t size);
+extern phys_addr_t __init lmb_alloc(phys_addr_t size, phys_addr_t align);
+extern phys_addr_t __init lmb_alloc_base(phys_addr_t size,
+		phys_addr_t, phys_addr_t max_addr);
+extern phys_addr_t __init __lmb_alloc_base(phys_addr_t size,
+		phys_addr_t align, phys_addr_t max_addr);
+extern phys_addr_t __init lmb_phys_mem_size(void);
+extern phys_addr_t __init lmb_end_of_DRAM(void);
+extern void __init lmb_enforce_memory_limit(phys_addr_t memory_limit);
+extern int __init lmb_is_reserved(phys_addr_t addr);
 
 extern void lmb_dump_all(void);
 
-static inline unsigned long
+static inline phys_addr_t
 lmb_size_bytes(struct lmb_region *type, unsigned long region_nr)
 {
 	return type->region[region_nr].size;
 }
-static inline unsigned long
+static inline phys_addr_t
 lmb_size_pages(struct lmb_region *type, unsigned long region_nr)
 {
 	return lmb_size_bytes(type, region_nr) >> PAGE_SHIFT;
 }
-static inline unsigned long
+static inline phys_addr_t
 lmb_start_pfn(struct lmb_region *type, unsigned long region_nr)
 {
 	return type->region[region_nr].base >> PAGE_SHIFT;
 }
-static inline unsigned long
+static inline phys_addr_t
 lmb_end_pfn(struct lmb_region *type, unsigned long region_nr)
 {
 	return lmb_start_pfn(type, region_nr) +
-- 
1.5.3.8

^ permalink raw reply related

* Re: [PATCH] [POWERPC] Fix initial lmb add region with a non-zero base
From: David Miller @ 2008-02-13 22:33 UTC (permalink / raw)
  To: galak; +Cc: sparclinux, linuxppc-dev, linux-kernel
In-Reply-To: <Pine.LNX.4.64.0802130719330.14428@blarg.am.freescale.net>

From: Kumar Gala <galak@kernel.crashing.org>
Date: Wed, 13 Feb 2008 07:37:27 -0600 (CST)

> If we add to an empty lmb region with a non-zero base we will not coalesce
> the number of regions done to one.  This causes problems on ppc32 for the
> memory region as its assumed to only have one region.
> 
> We can fix this be easily specially casing the initial add to just replace
> the dummy region.
> 
> ---
> 
> Posting this since Dave's looking a pulling the lmb code out into lib/ and
> sharing it between powerpc and sparc.
> 
> (this is my git tree git.kernel.org:/pub/scm/linux/kernel/git/galak/powerpc.git)

I noticed this issue when I use lmb on sparc64 and I intended to bring
it up eventually.  Thanks for fixing it!

^ permalink raw reply

* Re: [GIT]: Make LMB code sharable with sparc64.
From: David Miller @ 2008-02-13 22:24 UTC (permalink / raw)
  To: galak; +Cc: sparclinux, linuxppc-dev, linux-kernel
In-Reply-To: <D846801F-AA6B-4238-9FA4-A712EABFE800@kernel.crashing.org>

From: Kumar Gala <galak@kernel.crashing.org>
Date: Wed, 13 Feb 2008 07:12:26 -0600

> Does sparc have the concept of a phys_addr_t?  We are in the process  
> of expanding the lmb support to deal with 36-bit physical addresses on  
> 32-bit machines.

On sparc64, where I intend to use this, unsigned long's are 64-bit.
If you use some phys_addr_t type instead to help ppc32 along, that
would be perfectly fine with me.

^ permalink raw reply

* [PATCH 6/8] pseries: phyp dump: Invalidate and print dump areas.
From: Manish Ahuja @ 2008-02-13 21:43 UTC (permalink / raw)
  To: linuxppc-dev, paulus; +Cc: mahuja, linasvepstas
In-Reply-To: <47B1483E.8040303@austin.ibm.com>


Changed asm to asm-powerpc.
Hopefully this was the last of them.

-Manish

----------------------------------------
Routines to 
a. invalidate dump 
b. Calculate region that is reserved and needs to be freed. This is 
   exported through sysfs interface.

Unregister has been removed for now as it wasn't being used.

Signed-off-by: Manish Ahuja <mahuja@us.ibm.com>
-----

---
 arch/powerpc/platforms/pseries/phyp_dump.c |   85 +++++++++++++++++++++++++----
 include/asm-powerpc/phyp_dump.h                    |    3 +
 2 files changed, 77 insertions(+), 11 deletions(-)

Index: 2.6.24-rc5/arch/powerpc/platforms/pseries/phyp_dump.c
===================================================================
--- 2.6.24-rc5.orig/arch/powerpc/platforms/pseries/phyp_dump.c	2008-02-13 21:21:00.000000000 -0600
+++ 2.6.24-rc5/arch/powerpc/platforms/pseries/phyp_dump.c	2008-02-13 21:21:48.000000000 -0600
@@ -69,6 +69,10 @@ static struct phyp_dump_header phdr;
 #define DUMP_SOURCE_CPU 0x0001
 #define DUMP_SOURCE_HPTE 0x0002
 #define DUMP_SOURCE_RMO  0x0011
+#define DUMP_ERROR_FLAG 0x2000
+#define DUMP_TRIGGERED 0x4000
+#define DUMP_PERFORMED 0x8000
+
 
 /**
  * init_dump_header() - initialize the header declaring a dump
@@ -180,9 +184,15 @@ static void print_dump_header(const stru
 static void register_dump_area(struct phyp_dump_header *ph, unsigned long addr)
 {
 	int rc;
-	ph->cpu_data.destination_address += addr;
-	ph->hpte_data.destination_address += addr;
-	ph->kernel_data.destination_address += addr;
+
+	/* Add addr value if not initialized before */
+	if (ph->cpu_data.destination_address == 0) {
+		ph->cpu_data.destination_address += addr;
+		ph->hpte_data.destination_address += addr;
+		ph->kernel_data.destination_address += addr;
+	}
+
+	/* ToDo Invalidate kdump and free memory range. */
 
 	do {
 		rc = rtas_call(ibm_configure_kernel_dump, 3, 1, NULL,
@@ -195,6 +205,30 @@ static void register_dump_area(struct ph
 	}
 }
 
+static
+void invalidate_last_dump(struct phyp_dump_header *ph, unsigned long addr)
+{
+	int rc;
+
+	/* Add addr value if not initialized before */
+	if (ph->cpu_data.destination_address == 0) {
+		ph->cpu_data.destination_address += addr;
+		ph->hpte_data.destination_address += addr;
+		ph->kernel_data.destination_address += addr;
+	}
+
+	do {
+		rc = rtas_call(ibm_configure_kernel_dump, 3, 1, NULL,
+		               2, ph, sizeof(struct phyp_dump_header));
+	} while (rtas_busy_delay(rc));
+
+	if (rc) {
+		printk (KERN_ERR "phyp-dump: unexpected error (%d) "
+						"on invalidate\n", rc);
+		print_dump_header(ph);
+	}
+}
+
 /* ------------------------------------------------- */
 /**
  * release_memory_range -- release memory previously lmb_reserved
@@ -205,8 +239,8 @@ static void register_dump_area(struct ph
  * lmb_reserved in early boot. The released memory becomes
  * available for genreal use.
  */
-static void
-release_memory_range(unsigned long start_pfn, unsigned long nr_pages)
+static
+void release_memory_range(unsigned long start_pfn, unsigned long nr_pages)
 {
 	struct page *rpage;
 	unsigned long end_pfn;
@@ -237,8 +271,8 @@ release_memory_range(unsigned long start
  *
  * will release 256MB starting at 1GB.
  */
-static ssize_t
-store_release_region(struct kset *kset, const char *buf, size_t count)
+static
+ssize_t store_release_region(struct kset *kset, const char *buf, size_t count)
 {
 	unsigned long start_addr, length, end_addr;
 	unsigned long start_pfn, nr_pages;
@@ -266,10 +300,23 @@ store_release_region(struct kset *kset, 
 	return count;
 }
 
-static ssize_t
-show_release_region(struct kset * kset, char *buf)
+static ssize_t show_release_region(struct kset * kset, char *buf)
 {
-	return sprintf(buf, "ola\n");
+	u64 second_addr_range;
+
+	/* total reserved size - start of scratch area */
+	second_addr_range = phyp_dump_info->init_reserve_size -
+				phyp_dump_info->reserved_scratch_size;
+	return sprintf(buf, "CPU:0x%lx-0x%lx: HPTE:0x%lx-0x%lx:"
+			    " DUMP:0x%lx-0x%lx, 0x%lx-0x%lx:\n",
+		phdr.cpu_data.destination_address,
+		phdr.cpu_data.length_copied,
+		phdr.hpte_data.destination_address,
+		phdr.hpte_data.length_copied,
+		phdr.kernel_data.destination_address,
+		phdr.kernel_data.length_copied,
+		phyp_dump_info->init_reserve_start,
+		second_addr_range);
 }
 
 static struct subsys_attribute rr = __ATTR(release_region, 0600,
@@ -293,7 +340,6 @@ static int __init phyp_dump_setup(void)
 	if (!phyp_dump_info->phyp_dump_configured) {
 		return -ENOSYS;
 	}
-	print_dump_header(dump_header);
 
 	/* Is there dump data waiting for us? If there isn't,
 	 * then register a new dump area, and release all of
@@ -305,6 +351,7 @@ static int __init phyp_dump_setup(void)
 	rtas = of_find_node_by_path("/rtas");
 	dump_header = of_get_property(rtas, "ibm,kernel-dump", &header_len);
 	of_node_put(rtas);
+	print_dump_header(dump_header);
 
 	dump_area_length = init_dump_header(&phdr);
 	dump_area_start = phyp_dump_info->init_reserve_start & PAGE_MASK; /* align down */
@@ -314,6 +361,22 @@ static int __init phyp_dump_setup(void)
 		return 0;
 	}
 
+	/* re-register the dump area, if old dump was invalid */
+	if ((dump_header) && (dump_header->status & DUMP_ERROR_FLAG)) {
+		invalidate_last_dump(&phdr, dump_area_start);
+		register_dump_area(&phdr, dump_area_start);
+		return 0;
+	}
+
+	if (dump_header) {
+		phyp_dump_info->reserved_scratch_addr =
+				dump_header->cpu_data.destination_address;
+		phyp_dump_info->reserved_scratch_size =
+				dump_header->cpu_data.source_length +
+				dump_header->hpte_data.source_length +
+				dump_header->kernel_data.source_length;
+	}
+
 	/* Should we create a dump_subsys, analogous to s390/ipl.c ? */
 	rc = subsys_create_file(&kernel_subsys, &rr);
 	if (rc)
Index: 2.6.24-rc5/include/asm-powerpc/phyp_dump.h
===================================================================
--- 2.6.24-rc5.orig/include/asm-powerpc/phyp_dump.h	2008-02-13 21:21:00.000000000 -0600
+++ 2.6.24-rc5/include/asm-powerpc/phyp_dump.h	2008-02-13 21:22:10.000000000 -0600
@@ -30,6 +30,9 @@ struct phyp_dump {
 	/* store cpu & hpte size */
 	unsigned long cpu_state_size;
 	unsigned long hpte_region_size;
+	/* previous scratch area values */
+	unsigned long reserved_scratch_addr;
+	unsigned long reserved_scratch_size;
 };
 
 extern struct phyp_dump *phyp_dump_info;

^ permalink raw reply

* Re: [PATCH 2/2] powerpc: create mpc85xx pci err platform device for EDAC
From: Dave Jiang @ 2008-02-13 21:41 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <27AAC964-D9EE-435A-84FD-8A45FF27D448@kernel.crashing.org>

Kumar Gala wrote:
> On Feb 11, 2008, at 2:34 PM, Dave Jiang wrote:
> 
>> Creating a platform device for the PCI error registers in order for  
>> the
>> mpc85xx EDAC driver to pick up proper resources. This is to prevent  
>> the
>> EDAC driver from monopolizing the of_device and thus preventing  
>> future PCI
>> code from using the PCI of_device(s).
>>
>> Signed-off-by: Dave Jiang <djiang@mvista.com>
> 
> I'd rather we didn't add new platform devices, but do this via  
> of_platform in the driver itself.

Kumar,
  Here's the thread of discussion between Arnd Bergmann and I why platform
device is used. The original patch was of_device based....

http://ozlabs.org/pipermail/linuxppc-dev/2007-July/thread.html

Does it still make sense or do I need to go back to of_device?

> 
> Also, we need to 'rename' the compatible field for some of these  
> devices.
> 
> - k
> 


-- 

------------------------------------------------------
Dave Jiang
Software Engineer
MontaVista Software, Inc.
http://www.mvista.com
------------------------------------------------------

^ permalink raw reply

* [2.6 patch] powerpc: free_property() mustn't be __init
From: Adrian Bunk @ 2008-02-13 21:30 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev, linux-kernel, Stephen Rothwell

This patch fixes the following section mismatch:

<--  snip  -->

...
WARNING: vmlinux.o(.text+0x55648): Section mismatch in reference from the function .free_node() to the function .init.text:.free_property()
...

<--  snip  -->

Signed-off-by: Adrian Bunk <bunk@kernel.org>
Acked-by: Stephen Rothwell <sfr@canb.auug.org.au>

---

This patch has been sent on:
- 30 Jan 2008

99e9b48d8f5aba059916540fc69815db2b60b08d 
diff --git a/arch/powerpc/platforms/iseries/vio.c b/arch/powerpc/platforms/iseries/vio.c
index be06cfd..657b72f 100644
--- a/arch/powerpc/platforms/iseries/vio.c
+++ b/arch/powerpc/platforms/iseries/vio.c
@@ -75,7 +75,7 @@ static struct property *new_property(const char *name, int length,
 	return np;
 }
 
-static void __init free_property(struct property *np)
+static void free_property(struct property *np)
 {
 	kfree(np);
 }

^ permalink raw reply related

* [2.6 patch] hvc_rtas_init() must be __init
From: Adrian Bunk @ 2008-02-13 21:30 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev, linux-kernel

This patch fixes the following section mismatch:

<--  snip  -->

...
WARNING: vmlinux.o(.text+0x2fbca8): Section mismatch in reference from the function .hvc_rtas_init() to the function .devinit.text:.hvc_alloc()
...

<--  snip  -->

Signed-off-by: Adrian Bunk <bunk@kernel.org>

---

This patch has been sent on:
- 30 Jan 2008

1cc00c4ad5c881db2fc256ced43f3b5ce5c76e1c 
diff --git a/drivers/char/hvc_rtas.c b/drivers/char/hvc_rtas.c
index bb09413..88590d0 100644
--- a/drivers/char/hvc_rtas.c
+++ b/drivers/char/hvc_rtas.c
@@ -76,7 +76,7 @@ static struct hv_ops hvc_rtas_get_put_ops = {
 	.put_chars = hvc_rtas_write_console,
 };
 
-static int hvc_rtas_init(void)
+static int __init hvc_rtas_init(void)
 {
 	struct hvc_struct *hp;
 

^ permalink raw reply related

* [2.6 patch] powerpc: vdso_do_func_patch{32,64}() must be __init
From: Adrian Bunk @ 2008-02-13 21:30 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev, linux-kernel

This patch fixes the following section mismatches:

<--  snip  -->

...
WARNING: vmlinux.o(.text+0xe49c): Section mismatch in reference from the function .vdso_do_func_patch64() to the function .init.text:.find_symbol64()
WARNING: vmlinux.o(.text+0xe4d0): Section mismatch in reference from the function .vdso_do_func_patch64() to the function .init.text:.find_symbol64()
WARNING: vmlinux.o(.text+0xe56c): Section mismatch in reference from the function .vdso_do_func_patch32() to the function .init.text:.find_symbol32()
WARNING: vmlinux.o(.text+0xe5a0): Section mismatch in reference from the function .vdso_do_func_patch32() to the function .init.text:.find_symbol32()
...

<--  snip  -->

Signed-off-by: Adrian Bunk <bunk@kernel.org>

---

This patch has been sent on:
- 30 Jan 2008

 arch/powerpc/kernel/vdso.c |   12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

1c52ed2049b82e8458d03e50633b01ac5e1dfa40 
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index 3702df7..d3437c4 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -336,9 +336,9 @@ static unsigned long __init find_function32(struct lib32_elfinfo *lib,
 	return sym->st_value - VDSO32_LBASE;
 }
 
-static int vdso_do_func_patch32(struct lib32_elfinfo *v32,
-				struct lib64_elfinfo *v64,
-				const char *orig, const char *fix)
+static int __init vdso_do_func_patch32(struct lib32_elfinfo *v32,
+				       struct lib64_elfinfo *v64,
+				       const char *orig, const char *fix)
 {
 	Elf32_Sym *sym32_gen, *sym32_fix;
 
@@ -433,9 +433,9 @@ static unsigned long __init find_function64(struct lib64_elfinfo *lib,
 #endif
 }
 
-static int vdso_do_func_patch64(struct lib32_elfinfo *v32,
-				struct lib64_elfinfo *v64,
-				const char *orig, const char *fix)
+static int __init vdso_do_func_patch64(struct lib32_elfinfo *v32,
+				       struct lib64_elfinfo *v64,
+				       const char *orig, const char *fix)
 {
 	Elf64_Sym *sym64_gen, *sym64_fix;
 

^ permalink raw reply related

* [PATCH] [POWERPC] Enable correct operation of serial ports with nonzero regshift.
From: Pavel Kiryukhin @ 2008-02-13 21:19 UTC (permalink / raw)
  To: linuxppc-dev

Add regshift reading to serial drivers.
This enables correct operation of serial ports with nonzero regshift.

Signed-off-by: Pavel Kiryukhin <pkiryukhin@ru.mvista.com>
---
 arch/powerpc/kernel/legacy_serial.c |    6 +++++-
 drivers/serial/of_serial.c          |    6 ++++--
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c
index 61dd174..74bd1f3 100644
--- a/arch/powerpc/kernel/legacy_serial.c
+++ b/arch/powerpc/kernel/legacy_serial.c
@@ -50,7 +50,7 @@ static int __init add_legacy_port(struct device_node *np, int want_index,
 				  phys_addr_t taddr, unsigned long irq,
 				  upf_t flags, int irq_check_parent)
 {
-	const u32 *clk, *spd;
+	const u32 *clk, *spd, *regshift;
 	u32 clock = BASE_BAUD * 16;
 	int index;
 
@@ -62,6 +62,9 @@ static int __init add_legacy_port(struct device_node *np, int want_index,
 	/* get default speed if present */
 	spd = of_get_property(np, "current-speed", NULL);
 
+	/* get regshift if present*/
+	regshift = get_property(np, "reg-shift", NULL);
+
 	/* If we have a location index, then try to use it */
 	if (want_index >= 0 && want_index < MAX_LEGACY_SERIAL_PORTS)
 		index = want_index;
@@ -104,6 +107,7 @@ static int __init add_legacy_port(struct device_node *np, int want_index,
 	legacy_serial_ports[index].uartclk = clock;
 	legacy_serial_ports[index].irq = irq;
 	legacy_serial_ports[index].flags = flags;
+	legacy_serial_ports[index].regshift = regshift ? (u8)*regshift : 0;
 	legacy_serial_infos[index].taddr = taddr;
 	legacy_serial_infos[index].np = of_node_get(np);
 	legacy_serial_infos[index].clock = clock;
diff --git a/drivers/serial/of_serial.c b/drivers/serial/of_serial.c
index a64d858..ea9f1e4 100644
--- a/drivers/serial/of_serial.c
+++ b/drivers/serial/of_serial.c
@@ -30,7 +30,7 @@ static int __devinit of_platform_serial_setup(struct of_device *ofdev,
 {
 	struct resource resource;
 	struct device_node *np = ofdev->node;
-	const unsigned int *clk, *spd;
+	const unsigned int *clk, *spd, *regshift;
 	int ret;
 
 	memset(port, 0, sizeof *port);
@@ -40,7 +40,7 @@ static int __devinit of_platform_serial_setup(struct of_device *ofdev,
 		dev_warn(&ofdev->dev, "no clock-frequency property set\n");
 		return -ENODEV;
 	}
-
+	regshift = get_property(np, "reg-shift", NULL);
 	ret = of_address_to_resource(np, 0, &resource);
 	if (ret) {
 		dev_warn(&ofdev->dev, "invalid address\n");
@@ -57,6 +57,8 @@ static int __devinit of_platform_serial_setup(struct of_device *ofdev,
 		| UPF_FIXED_PORT;
 	port->dev = &ofdev->dev;
 	port->custom_divisor = *clk / (16 * (*spd));
+	if (regshift)
+		port->regshift = *regshift;
 
 	return 0;
 }
-- 
1.5.4.1

^ permalink raw reply related

* [PATCH 1/2 rev2] powerpc: publish 85xx cds soc dts entries as of_device
From: Dave Jiang @ 2008-02-13 21:08 UTC (permalink / raw)
  To: galak, linuxppc-dev
In-Reply-To: <20080211203243.GA5331@blade.az.mvista.com>

Publish the devices listed in dts under SOC as of_device for mpc85xx_cds
platforms.

The memory controller, L2 cache-controller, and the PCI controller(s) are
published as of_device so the mpc85xx EDAC driver can claim them for usage.

Signed-off-by: Dave Jiang <djiang@mvista.com>

---
commit 4be72413410c560fe7ad5ef9156d43159003dad3
tree 8890093ee1cff0ec0cc9ce0b9367e134f528eed2
parent 19af35546de68c872dcb687613e0902a602cb20e
author Dave Jiang <djiang@mvista.com> Wed, 13 Feb 2008 14:03:33 -0700
committer Dave Jiang <djiang@blade.(none)> Wed, 13 Feb 2008 14:03:33 -0700

 arch/powerpc/platforms/85xx/mpc85xx_cds.c |   14 ++++++++++++++
 1 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
index 8b1de78..374c9d5 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
@@ -26,6 +26,7 @@
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/fsl_devices.h>
+#include <linux/of_platform.h>
 
 #include <asm/system.h>
 #include <asm/pgtable.h>
@@ -324,6 +325,19 @@ static void mpc85xx_cds_show_cpuinfo(struct seq_file *m)
 	seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
 }
 
+static struct of_device_id __initdata of_bus_ids[] = {
+	{ .name = "soc", },
+	{ .type = "soc", },
+	{},
+};
+
+static int __init declare_of_platform_devices(void)
+{
+	of_platform_bus_probe(NULL, of_bus_ids, NULL);
+
+	return 0;
+}
+machine_device_initcall(mpc85xx_cds, declare_of_platform_devices);
 
 /*
  * Called very early, device-tree isn't unflattened

^ permalink raw reply related

* RE: V4 FX12 and PLB TEMAC: no space for user logic?
From: Mohammad Sadegh Sadri @ 2008-02-13 21:00 UTC (permalink / raw)
  To: llandre; +Cc: linuxppc-embedded
In-Reply-To: <47B2B94A.6090600@dave-tech.it>

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


llandre,

Our tests show that V4 FX 12 is really a small device. The FPGA was completely full with these set of modules:

1- CPU core and related circuits, 2- PLB TEMAC , 3- DDR SDRAM Controller , 4- PLB BRAM IF , 5- Bridges , 6- OPB UART and 7- OPB EMC controller (Used for interfacing to flash chips )

The synthesis tool we used during our tests was : XST
it seems that there are some solutions to have a more optimized implementation on FX-12, personally i visited one of the members here who claimed that he has two PLB TEMACs enabled on one FX-12 FPGA. I believe that this is not possible. may be if one use better synthesis tools such as Synplify he may get slightly better results.

any how, in my idea FX-12 is not suitable for serious projects, it is suitable only for beginning phases of a project and the research phase. 
We are now focusing on ML410, a great board by Xiling, featuring on FX-60 FPGA while keeps costs low.

any questions are welcom,
thanks,
Mohammad.


> Date: Wed, 13 Feb 2008 10:32:58 +0100
> From: r&d2@dave-tech.it
> To: mamsadegh@hotmail.com
> CC: linuxppc-embedded@ozlabs.org
> Subject: V4 FX12 and PLB TEMAC: no space for user logic?
> 
> Hi Mohammad,
> 
> I've just had a look at the messages you generously posted in the ml 
> about your experience with linux on V4 FX12 FPGA.
> I'd like to ask your opinion about FX12 practical usability in this 
> context (gigabit PLB TEMAC/linux).
> In this message
> 
> http://article.gmane.org/gmane.linux.ports.ppc.embedded/16816
> 
> you say the device is completely full. If I understand correctly your 
> system provides just the devices required to run the bandwidth test so 
> it seems there is no room for user logic (I think you did not even add 
> the memory controller required to access the NOR Flash containing 
> bootloader, kernel image and root fs that is clearly mandatory for 
> standalone product). Is that true? If it is, this limits a lot the 
> flexibility of this architecture in this configuration. What do you think?
> 
> 
> 
> Regards,
> llandre
> 
> DAVE Electronics System House - R&D Department
> web:   http://www.dave.eu
> email: r&d2@dave-tech.it

_________________________________________________________________


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

^ permalink raw reply

* Re: [Patch 0/2] powerpc: avoid userspace poking to legacy ioports
From: Benjamin Herrenschmidt @ 2008-02-13 20:42 UTC (permalink / raw)
  To: Christian Krafft; +Cc: parabelboi, linuxppc-dev, linux-kernel
In-Reply-To: <20080213183506.7f3e3145@de.ibm.com>


On Wed, 2008-02-13 at 18:35 +0100, Christian Krafft wrote:
> sensors_detect crashes kernel on PowerPC, as it pokes directly to memory.
> This patch adds a check_legacy_ioports to read_port and write_port.
> It will now return ENXIO, instead of oopsing.
> 
> Signed-off-by: Christian Krafft <krafft@de.ibm.com>

The problem is that this prevents using /proc/ioports to access PCI
IO space, which might be useful.

I hate that sensors_detect.. or for that matter any other userland code
that pokes random ports like that. It should die.

Ben.

> Index: linux.git/drivers/char/mem.c
> ===================================================================
> --- linux.git.orig/drivers/char/mem.c
> +++ linux.git/drivers/char/mem.c
> @@ -566,8 +566,13 @@ static ssize_t read_port(struct file * f
>  	char __user *tmp = buf;
>  
>  	if (!access_ok(VERIFY_WRITE, buf, count))
> -		return -EFAULT; 
> +		return -EFAULT;
> +
>  	while (count-- > 0 && i < 65536) {
> +#ifdef CONFIG_PPC_MERGE
> +		if (check_legacy_ioport(i))
> +			return -ENXIO;
> +#endif
>  		if (__put_user(inb(i),tmp) < 0) 
>  			return -EFAULT;  
>  		i++;
> @@ -585,6 +590,7 @@ static ssize_t write_port(struct file * 
>  
>  	if (!access_ok(VERIFY_READ,buf,count))
>  		return -EFAULT;
> +
>  	while (count-- > 0 && i < 65536) {
>  		char c;
>  		if (__get_user(c, tmp)) {
> @@ -592,6 +598,10 @@ static ssize_t write_port(struct file * 
>  				break;
>  			return -EFAULT; 
>  		}
> +#ifdef CONFIG_PPC_MERGE
> +		if (check_legacy_ioport(i))
> +			return -ENXIO;
> +#endif
>  		outb(c,i);
>  		i++;
>  		tmp++;
> 
> 
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev

^ permalink raw reply

* Re: TLB Miss booting linux kernel on ppc 405
From: David Baird @ 2008-02-13 19:02 UTC (permalink / raw)
  To: linuxppc-embedded
In-Reply-To: <5ee408090802131049u652ef867wff034b4ccb1067f1@mail.gmail.com>

On Feb 13, 2008 11:49 AM, Ricardo Ayres Severo <severo.ricardo@gmail.com> wrote:
> Executing without single step the exception doesn't occurs. But at
> __log_buf I get only trash, even after reseting the processor.
> How can I send some characters to uartlite on asm code?

Great.  This confirms that I am not crazy.  You are having similar
results as I did.  But I still don't yet know why single-step and
memory read can't be used in virtual mode...

To use UARTLite, there are some patches you need.  First thing, you
have to setup your TLBs so that uartlite can be accessed in virtual
mode.  I did something like this:

#define MY_UART_LITE_BASE 0x40000000

 lis r3,MY_UART_LITE_BASE@h
 ori r3,r3,MY_UART_LITE_BASE@l
 mr  r4,r3
 clrrwi  r4,r4,12
 ori r4,r4,(TLB_WR|TLB_I|TLB_M|TLB_G)

 clrrwi  r3,r3,12
 ori r3,r3,(TLB_VALID | TLB_PAGESZ(PAGESZ_16M))

 li  r0,0      /* TLB slot 0 */
 tlbwe r4,r0,TLB_DATA
 tlbwe r3,r0,TLB_TAG

Then, you need to add some C code somewhere.  I chose "setup.c" (in
same directory as head_4xx.S) for this purpose:

// Try to get value for XPAR_RS232_UART_BASEADDR:
#include <platforms/4xx/xparameters/xparameters.h>
#include <platforms/4xx/xparameters/xparameters_ml403.h>

void
serial_putc(unsigned char c)
{
 while (((*(volatile uint32_t*)(XPAR_RS232_UART_BASEADDR + 0x8)) & 0x08) != 0);
 *(volatile uint32_t*)(XPAR_RS232_UART_BASEADDR + 0x4) = c;
}

void
print_A()
{
 serial_putc('A');
}

void
print_B()
{
 serial_putc('B');
}


Now, from assembly, things are easy.  Just do this, I think:

 blr print_A
 blr print_B

If this gives you any trouble, try it first from real mode so that you
can easily debug it.

-David

^ permalink raw reply

* Re: TLB Miss booting linux kernel on ppc 405
From: Ricardo Ayres Severo @ 2008-02-13 18:49 UTC (permalink / raw)
  To: David Baird; +Cc: linuxppc-embedded
In-Reply-To: <440abda90802131032l6e11eef7gbd7eb57352c2ce4@mail.gmail.com>

Executing without single step the exception doesn't occurs. But at
__log_buf I get only trash, even after reseting the processor.
How can I send some characters to uartlite on asm code?

Thanks,

On Feb 13, 2008 4:32 PM, David Baird <dhbaird@gmail.com> wrote:
> On Feb 13, 2008 11:03 AM, Ricardo Ayres Severo <severo.ricardo@gmail.com> wrote:
> > Here are the srr dump:
> >   srr0: c0002218
> >   srr1: 00021030
> >   srr2: 00001154
> >   srr3: 00000000
>
> Okay, SRR0 tells us that you did in fact have an exception at
> 0xc0002218.  And I am willing to bet that is the line you mentioned
> (line 826 of start_here).  You can match this up with your System.map
> or an objdump -d of vmlinux.
>
> Someone who knows more than I do can correct me on this, but I have a
> suspicion.  As soon virtual (translation) mode is entered, I have had
> a hard time using the normal debugging functions (e.g. single
> instruction stepping and reading memory regions).  While in virtual
> mode, it seemed like I had to resort to these techniques:
>
> - Blinking some LEDs
> - Spitting characters out of a uartlite
> - When an exception occurs, the processor switches back into real mode
> and therefore I can set breakpoints on the beginnings of various
> exception handlers and be able to use normal debugging tools again
>
> So, I have another question.  Can you set a breakpoint on 0x1100 (in
> XMD: bps 0x1100 hw), then just let it run (i.e. do not single step!)
> all the way until an exception happens.  When the exception happens,
> can you then paste the SRR0, SRR1, and the ESR (exception syndrome
> register)?
>
> I hope I am not giving you a run-around here....
>
> -David
>
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>



-- 
Ricardo Ayres Severo <severo.ricardo@gmail.com>

^ permalink raw reply

* Re: TLB Miss booting linux kernel on ppc 405
From: David Baird @ 2008-02-13 18:32 UTC (permalink / raw)
  To: linuxppc-embedded
In-Reply-To: <5ee408090802131003m4b8e632cu931769bc77f9b439@mail.gmail.com>

On Feb 13, 2008 11:03 AM, Ricardo Ayres Severo <severo.ricardo@gmail.com> wrote:
> Here are the srr dump:
>   srr0: c0002218
>   srr1: 00021030
>   srr2: 00001154
>   srr3: 00000000

Okay, SRR0 tells us that you did in fact have an exception at
0xc0002218.  And I am willing to bet that is the line you mentioned
(line 826 of start_here).  You can match this up with your System.map
or an objdump -d of vmlinux.

Someone who knows more than I do can correct me on this, but I have a
suspicion.  As soon virtual (translation) mode is entered, I have had
a hard time using the normal debugging functions (e.g. single
instruction stepping and reading memory regions).  While in virtual
mode, it seemed like I had to resort to these techniques:

- Blinking some LEDs
- Spitting characters out of a uartlite
- When an exception occurs, the processor switches back into real mode
and therefore I can set breakpoints on the beginnings of various
exception handlers and be able to use normal debugging tools again

So, I have another question.  Can you set a breakpoint on 0x1100 (in
XMD: bps 0x1100 hw), then just let it run (i.e. do not single step!)
all the way until an exception happens.  When the exception happens,
can you then paste the SRR0, SRR1, and the ESR (exception syndrome
register)?

I hope I am not giving you a run-around here....

-David

^ permalink raw reply

* Re: TLB Miss booting linux kernel on ppc 405
From: Ricardo Ayres Severo @ 2008-02-13 18:03 UTC (permalink / raw)
  Cc: linuxppc-embedded
In-Reply-To: <440abda90802130951h7a23743asc85454bf089c7e55@mail.gmail.com>

Here are the srr dump:
  srr0: c0002218
  srr1: 00021030
  srr2: 00001154
  srr3: 00000000

On Feb 13, 2008 3:51 PM, David Baird <dhbaird@gmail.com> wrote:
> On Feb 13, 2008 10:38 AM, Ricardo Ayres Severo <severo.ricardo@gmail.com> wrote:
> > I tracked the kernel execution using step one instruction (si) on gdb
> > and matching the jumps with the System.map.
> > It is a Data TLB Miss and this is the register dump after the miss occurs:
> >
> >     r1: 00502090
> >     r2: 0000000f
> >     r3: c00003c0
> >     r4: c0000000
> >     r5: 00000000
> >     r6: 00000000
> >     r7: 74747955
> >     r8: 4c302c39
> >     r9: 00000000
> >     pc: 00001100
> >     lr: 00000018
>
> Can you also past the special registers (srrd in XMD)?  I am very
> curious about SRR0 and SRR1 and maybe some of the others.
>
> > Now I'm checking the PPC cache configurations on XPS, because when
> > treating the DTLB Miss Exception a Machine Check Exception occurs when
> > it works with L1. Does this makes sense or am I confusing things?
>
> Too soon for me to tell :-)
>
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>



-- 
Ricardo Ayres Severo <severo.ricardo@gmail.com>

^ permalink raw reply

* Re: TLB Miss booting linux kernel on ppc 405
From: David Baird @ 2008-02-13 17:51 UTC (permalink / raw)
  To: linuxppc-embedded
In-Reply-To: <5ee408090802130938u7d069636g42a496e489fe5b80@mail.gmail.com>

On Feb 13, 2008 10:38 AM, Ricardo Ayres Severo <severo.ricardo@gmail.com> wrote:
> I tracked the kernel execution using step one instruction (si) on gdb
> and matching the jumps with the System.map.
> It is a Data TLB Miss and this is the register dump after the miss occurs:
>
>     r1: 00502090
>     r2: 0000000f
>     r3: c00003c0
>     r4: c0000000
>     r5: 00000000
>     r6: 00000000
>     r7: 74747955
>     r8: 4c302c39
>     r9: 00000000
>     pc: 00001100
>     lr: 00000018

Can you also past the special registers (srrd in XMD)?  I am very
curious about SRR0 and SRR1 and maybe some of the others.

> Now I'm checking the PPC cache configurations on XPS, because when
> treating the DTLB Miss Exception a Machine Check Exception occurs when
> it works with L1. Does this makes sense or am I confusing things?

Too soon for me to tell :-)

^ permalink raw reply

* Re: TLB Miss booting linux kernel on ppc 405
From: Ricardo Ayres Severo @ 2008-02-13 17:38 UTC (permalink / raw)
  To: David Baird; +Cc: linuxppc-embedded
In-Reply-To: <440abda90802130917x79c3c990j6a1fc7c12ba05ed7@mail.gmail.com>

I tracked the kernel execution using step one instruction (si) on gdb
and matching the jumps with the System.map.
It is a Data TLB Miss and this is the register dump after the miss occurs:

    r1: 00502090
    r2: 0000000f
    r3: c00003c0
    r4: c0000000
    r5: 00000000
    r6: 00000000
    r7: 74747955
    r8: 4c302c39
    r9: 00000000
    pc: 00001100
    lr: 00000018

Now I'm checking the PPC cache configurations on XPS, because when
treating the DTLB Miss Exception a Machine Check Exception occurs when
it works with L1. Does this makes sense or am I confusing things?

Thanks,

On Feb 13, 2008 3:17 PM, David Baird <dhbaird@gmail.com> wrote:
> On Feb 13, 2008 9:50 AM, Ricardo Ayres Severo <severo.ricardo@gmail.com> wrote:
> > Hi All,
> >
> > I'm using kernel 2.6.24 and when it comes to line 826 on the file
> > arch/ppc/kernel/head_4xx.S it gives a TLB Miss.
> >
> > arch/ppc/kernel/head_4xx.S
> > 823 start_here:
> > 824
> > 825         /* ptr to current */
> > 826         lis    r2,init_task@h
> > 827         ori    r2,r2,init_task@l
>
> I am just curious: how did you find that you have TLB miss on that
> line?  Is it an Instruction TLB miss or a Data TLB miss?
>
> Can you paste a dump of your registers (in XMD, rrd and srrd)?
>
> I was having TLB misses awhile back due to some other problems, but
> never had any on that line though.
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>



-- 
Ricardo Ayres Severo <severo.ricardo@gmail.com>

^ permalink raw reply

* Re: [Patch 2/2] powerpc: i2c-isa: add access check to legacy ioports
From: Christian Krafft @ 2008-02-13 17:37 UTC (permalink / raw)
  To: linux-kernel; +Cc: parabelboi, linuxppc-dev
In-Reply-To: <20080213182800.5c6940a8@de.ibm.com>

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

when probing i2c-pca-isa writes to legacy ioports, which crashes the kernel
if there is no device at that port.
This patch adds a check_legacy_ioport call, so probe failes gracefully
and thus prevents the oops.

Signed-off-by: Christian Krafft <krafft@de.ibm.com>

Index: linux.git/drivers/i2c/busses/i2c-pca-isa.c
===================================================================
--- linux.git.orig/drivers/i2c/busses/i2c-pca-isa.c
+++ linux.git/drivers/i2c/busses/i2c-pca-isa.c
@@ -125,6 +125,13 @@ static int __devinit pca_isa_probe(struc
 
 	dev_info(dev, "i/o base %#08lx. irq %d\n", base, irq);
 
+#ifdef CONFIG_PPC_MERGE
+	if (check_legacy_ioport(base)) {
+		dev_err(dev, "I/O address %#08lx is not available\n", base);
+		goto out;
+	}
+#endif
+
 	if (!request_region(base, IO_SIZE, "i2c-pca-isa")) {
 		dev_err(dev, "I/O address %#08lx is in use\n", base);
 		goto out;


-- 
Mit freundlichen Gruessen,
kind regards,

Christian Krafft
IBM Systems & Technology Group,
Linux Kernel Development
IT Specialist


Vorsitzender des Aufsichtsrats:	Martin Jetter
Geschaeftsfuehrung:		Herbert Kircher
Sitz der Gesellschaft:		Boeblingen
Registriergericht:		Amtsgericht Stuttgart, HRB 243294

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

^ permalink raw reply

* Re: [Patch 0/2] powerpc: avoid userspace poking to legacy ioports
From: Christian Krafft @ 2008-02-13 17:35 UTC (permalink / raw)
  To: linux-kernel; +Cc: parabelboi, linuxppc-dev
In-Reply-To: <20080213182800.5c6940a8@de.ibm.com>

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

sensors_detect crashes kernel on PowerPC, as it pokes directly to memory.
This patch adds a check_legacy_ioports to read_port and write_port.
It will now return ENXIO, instead of oopsing.

Signed-off-by: Christian Krafft <krafft@de.ibm.com>

Index: linux.git/drivers/char/mem.c
===================================================================
--- linux.git.orig/drivers/char/mem.c
+++ linux.git/drivers/char/mem.c
@@ -566,8 +566,13 @@ static ssize_t read_port(struct file * f
 	char __user *tmp = buf;
 
 	if (!access_ok(VERIFY_WRITE, buf, count))
-		return -EFAULT; 
+		return -EFAULT;
+
 	while (count-- > 0 && i < 65536) {
+#ifdef CONFIG_PPC_MERGE
+		if (check_legacy_ioport(i))
+			return -ENXIO;
+#endif
 		if (__put_user(inb(i),tmp) < 0) 
 			return -EFAULT;  
 		i++;
@@ -585,6 +590,7 @@ static ssize_t write_port(struct file * 
 
 	if (!access_ok(VERIFY_READ,buf,count))
 		return -EFAULT;
+
 	while (count-- > 0 && i < 65536) {
 		char c;
 		if (__get_user(c, tmp)) {
@@ -592,6 +598,10 @@ static ssize_t write_port(struct file * 
 				break;
 			return -EFAULT; 
 		}
+#ifdef CONFIG_PPC_MERGE
+		if (check_legacy_ioport(i))
+			return -ENXIO;
+#endif
 		outb(c,i);
 		i++;
 		tmp++;


-- 
Mit freundlichen Gruessen,
kind regards,

Christian Krafft
IBM Systems & Technology Group,
Linux Kernel Development
IT Specialist


Vorsitzender des Aufsichtsrats:	Martin Jetter
Geschaeftsfuehrung:		Herbert Kircher
Sitz der Gesellschaft:		Boeblingen
Registriergericht:		Amtsgericht Stuttgart, HRB 243294

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

^ permalink raw reply

* [Patch 0/2] add check_legacy_ioport calls to prevent oops
From: Christian Krafft @ 2008-02-13 17:28 UTC (permalink / raw)
  To: linux-kernel; +Cc: parabelboi, linuxppc-dev

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

Hi,

the following two patches prevent kernel from crashing on powerpc.
The surrounding ifdefs will be obsolete, if check_legacy_ioport becomes
generic code.


-- 
Mit freundlichen Gruessen,
kind regards,

Christian Krafft
IBM Systems & Technology Group,
Linux Kernel Development
IT Specialist


Vorsitzender des Aufsichtsrats:	Martin Jetter
Geschaeftsfuehrung:		Herbert Kircher
Sitz der Gesellschaft:		Boeblingen
Registriergericht:		Amtsgericht Stuttgart, HRB 243294

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

^ permalink raw reply

* Re: TLB Miss booting linux kernel on ppc 405
From: David Baird @ 2008-02-13 17:17 UTC (permalink / raw)
  To: linuxppc-embedded
In-Reply-To: <5ee408090802130850w130ce09an507ca5c4d41cc5a8@mail.gmail.com>

On Feb 13, 2008 9:50 AM, Ricardo Ayres Severo <severo.ricardo@gmail.com> wrote:
> Hi All,
>
> I'm using kernel 2.6.24 and when it comes to line 826 on the file
> arch/ppc/kernel/head_4xx.S it gives a TLB Miss.
>
> arch/ppc/kernel/head_4xx.S
> 823 start_here:
> 824
> 825         /* ptr to current */
> 826         lis    r2,init_task@h
> 827         ori    r2,r2,init_task@l

I am just curious: how did you find that you have TLB miss on that
line?  Is it an Instruction TLB miss or a Data TLB miss?

Can you paste a dump of your registers (in XMD, rrd and srrd)?

I was having TLB misses awhile back due to some other problems, but
never had any on that line though.

^ permalink raw reply

* Re: [PATCH] drivers/base: export gpl (un)register_memory_notifier
From: Dave Hansen @ 2008-02-13 17:05 UTC (permalink / raw)
  To: Jan-Bernd Themann
  Cc: Thomas Klein, Themann, Jan-Bernd, netdev, apw, linux-kernel,
	linuxppc-dev, Christoph Raisch, Badari Pulavarty, Greg KH,
	Thomas Klein
In-Reply-To: <200802131617.58646.ossthema@de.ibm.com>

On Wed, 2008-02-13 at 16:17 +0100, Jan-Bernd Themann wrote:
> Constraints imposed by HW / FW:
> - eHEA has own MMU
> - eHEA  Memory Regions (MRs) are used by the eHEA MMU  to translate virtual
>   addresses to absolute addresses (like DMA mapped memory on a PCI bus)
> - The number of MRs is limited (not enough to have one MR per packet)

Are there enough to have one per 16MB section?

> Our current understanding about the current Memory Hotplug System are
> (please correct me if I'm wrong):
> 
> - depends on sparse mem

You're wrong ;).  In mainline, this is true.  There was a version of the
SUSE kernel that did otherwise.  But you can not and should not depend
on this never changing.  But, someone is perfectly free to go out an
implement something better than sparsemem for memory hotplug.  If they
go and do this, your driver may get left behind. 

> - only whole memory sections are added / removed
> - for each section a memory resource is registered

True, and true. (There might be exceptions to the whole sections one,
but that's blatant abuse and should be fixed. :)

> From the driver side we need:
> - some kind of memory notification mechanism.
>   For memory add we can live without any external memory notification
>   event. For memory remove we do need an external trigger (see explanation
>   above).

You can export and use (un)register_memory_notifier.  You just need to
do it in a reasonable way that compiles for randconfig on your
architecture.  Believe me, we don't want to start teaching drivers about
sparsemem.  

> - a way to iterate over all kernel pages and a way to detect holes in the
>   kernel memory layout in order to build up our own ehea_bmap.

Look at kernel/resource.c

But, I'm really not convinced that you can actually keep this map
yourselves.  It's not as simple as you think.  What happens if you get
on an LPAR with two sections, one 256MB@0x0 and another
16MB@0x1000000000000000.  That's quite possible.  I think your vmalloc'd
array will eat all of memory.  

That's why we have SPARSEMEM_EXTREME and SPARSEMEM_VMEMMAP implemented
in the core, so that we can deal with these kinds of problems, once and
*NOT* in every single little driver out there.  

> Functions to use while building ehea_bmap + MRs:
> - Use either the functions that are used by the memory hotplug system as
>   well, that means using the section defines + functions (section_nr_to_pfn,
>   pfn_valid)

Basically, you can't use anything related to sections outside of the
core code.  You can use things like pfn_valid(), or you can create new
interfaces that are properly abstracted.  

> - Use currently other not exported functions in kernel/resource.c, like
>   walk_memory_resource (where we would still need the maximum possible number
>   of pages NR_MEM_SECTIONS)

It isn't the act of exporting that's the problem.  It's making sure that
the exports won't be prone to abuse and that people are using them
properly.  You should assume that you can export and use
walk_memory_resource().

Do you know what other operating systems do with this hardware?

In the future, please make an effort to get review from knowledgeable
people about these kinds of things before using them in your driver.
Your company has many, many resources available, and all you need to do
is ask.  All that you have to do is look to the tops of the files of the
functions you are calling.

-- Dave

^ permalink raw reply

* TLB Miss booting linux kernel on ppc 405
From: Ricardo Ayres Severo @ 2008-02-13 16:50 UTC (permalink / raw)
  To: linuxppc-embedded

Hi All,

I'm using kernel 2.6.24 and when it comes to line 826 on the file
arch/ppc/kernel/head_4xx.S it gives a TLB Miss.

arch/ppc/kernel/head_4xx.S
823 start_here:
824
825         /* ptr to current */
826         lis    r2,init_task@h
827         ori    r2,r2,init_task@l

It seems to have a problem initializing the MMU.

What I could do to solve this?

Thanks,

-- 
Ricardo Ayres Severo <severo.ricardo@gmail.com>

^ 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