All of lore.kernel.org
 help / color / mirror / Atom feed
* nonzero phys_base
@ 2004-03-16 11:41 Stefan Holst
  2004-03-16 16:55 ` Keith M Wesolowski
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Stefan Holst @ 2004-03-16 11:41 UTC (permalink / raw)
  To: sparclinux

hello,

since konrad eisele has discontinued his work on leon2-support in linux,
i'm currently busy maintaining a updated patchset for newer kernel
versions. you will find some info about my patchset (and the patches
itself of course) here:

http://www.ra.informatik.uni-stuttgart.de/~holstsn/

what i have done yet besides some fixes is a big cleanup and make the
patches as least invasive as possible. my long term goal is to merge
them into mainstream kernel to finally get linux run on this free
processor core.
for those who are not familiar with leon2, see www.gaisler.com and/or
the archive of this list.

the whole patchset isn't yet ready for merging. but there is a feature
leon depends on and currently maked as broken in kernel: phys_base != 0.
the following small patch tries to fix this issue. the is completely
independent from leon support and changes as far as i see nothing, if
phys_base is zero.

how do you think about this fix? any chances to get this into the
kernel? if yes, how? this is the first time i send kernel patches,
so hints and comments are very welcome :).


diff -urN a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c
--- a/arch/sparc/mm/init.c	2004-02-29 23:35:40.000000000 +0100
+++ b/arch/sparc/mm/init.c	2004-03-15 23:57:23.593256720 +0100
@@ -134,7 +134,7 @@
 unsigned long calc_max_low_pfn(void)
 {
 	int i;
-	unsigned long tmp = (SRMMU_MAXMEM >> PAGE_SHIFT);
+	unsigned long tmp = ((phys_base + SRMMU_MAXMEM) >> PAGE_SHIFT);
 	unsigned long curr_pfn, last_pfn;
 
 	last_pfn = (sp_banks[0].base_addr + sp_banks[0].num_bytes) >> PAGE_SHIFT;
@@ -189,9 +189,6 @@
 	 */
 	start_pfn  = (unsigned long)__pa(PAGE_ALIGN((unsigned long) &_end));
 
-	/* Adjust up to the physical address where the kernel begins. */
-	start_pfn += phys_base;
-
 	/* Now shift down to get the real physical page frame number. */
 	start_pfn >>= PAGE_SHIFT;
 
@@ -202,7 +199,7 @@
 	max_low_pfn = max_pfn;
 	highstart_pfn = highend_pfn = max_pfn;
 
-	if (max_low_pfn > (SRMMU_MAXMEM >> PAGE_SHIFT)) {
+	if (max_low_pfn > ((phys_base + SRMMU_MAXMEM) >> PAGE_SHIFT)) {
 		highstart_pfn = (SRMMU_MAXMEM >> PAGE_SHIFT);
 		max_low_pfn = calc_max_low_pfn();
 		printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",
@@ -267,8 +264,8 @@
 		reserve_bootmem(initrd_start, size);
 		*pages_avail -= PAGE_ALIGN(size) >> PAGE_SHIFT;
 
-		initrd_start += PAGE_OFFSET;
-		initrd_end += PAGE_OFFSET;
+		initrd_start = (initrd_start - phys_base) + PAGE_OFFSET;
+		initrd_end = (initrd_end - phys_base) + PAGE_OFFSET;		
 	}
 #endif
 	/* Reserve the kernel text/data/bss. */
@@ -477,7 +474,7 @@
 		unsigned long page;
 		struct page *p;
 
-		page = addr + phys_base;
+		page = addr;
 		p = virt_to_page(page);
 
 		ClearPageReserved(p);
diff -urN a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
--- a/arch/sparc/mm/srmmu.c	2004-03-11 11:32:58.000000000 +0100
+++ b/arch/sparc/mm/srmmu.c	2004-03-15 23:57:23.992196072 +0100
@@ -213,7 +213,7 @@
  * and a page entry and page directory to the page they refer to.
  */
 static pte_t srmmu_mk_pte(struct page *page, pgprot_t pgprot)
-{ return __pte(((page - mem_map) << (PAGE_SHIFT-4)) | pgprot_val(pgprot)); }
+{ return __pte((page_to_pfn(page) << (PAGE_SHIFT-4)) | pgprot_val(pgprot)); }
 
 static pte_t srmmu_mk_pte_phys(unsigned long page, pgprot_t pgprot)
 { return __pte(((page) >> 4) | pgprot_val(pgprot)); }
@@ -245,7 +245,7 @@
 	unsigned long ptp;	/* Physical address, shifted right by 4 */
 	int i;
 
-	ptp = (ptep - mem_map) << (PAGE_SHIFT-4);	/* watch for overflow */
+	ptp = page_to_pfn(ptep) << (PAGE_SHIFT-4);	/* watch for overflow */
 	for (i = 0; i < SRMMU_PTRS_PER_PTE_SOFT/SRMMU_PTRS_PER_PTE; i++) {
 		srmmu_set_pte((pte_t *)&pmdp->pmdv[i], SRMMU_ET_PTD | ptp);
 		ptp += (SRMMU_PTRS_PER_PTE*sizeof(pte_t) >> 4);
@@ -480,7 +480,7 @@
 
 	if ((pte = (unsigned long)srmmu_pte_alloc_one_kernel(mm, address)) = 0)
 		return NULL;
-	return mem_map + (__nocache_pa(pte) >> PAGE_SHIFT);
+	return pfn_to_page( __nocache_pa(pte) >> PAGE_SHIFT );
 }
 
 static void srmmu_free_pte_fast(pte_t *pte)
@@ -495,7 +495,7 @@
 	p = (unsigned long)page_address(pte);	/* Cached address (for test) */
 	if (p = 0)
 		BUG();
-	p = ((pte - mem_map) << PAGE_SHIFT);	/* Physical address */
+	p = page_to_pfn(pte) << PAGE_SHIFT;	/* Physical address */
 	p = (unsigned long) __nocache_va(p);	/* Nocached virtual */
 	srmmu_free_nocache(p, SRMMU_PTE_SZ_SOFT);
 }
@@ -1331,10 +1331,6 @@
 				    phys_base >> PAGE_SHIFT, zholes_size);
 		mem_map = contig_page_data.node_mem_map;
 	}
-
-/* P3: easy to fix, todo. Current code is utterly broken, though. */
-	if (phys_base != 0)
-		panic("phys_base nonzero");
 }
 
 static void srmmu_mmu_info(struct seq_file *m)
diff -urN a/include/asm-sparc/page.h b/include/asm-sparc/page.h
--- a/include/asm-sparc/page.h	2004-02-29 23:35:48.000000000 +0100
+++ b/include/asm-sparc/page.h	2004-03-15 23:57:23.993195920 +0100
@@ -156,17 +156,22 @@
 #define PAGE_ALIGN(addr)  (((addr)+PAGE_SIZE-1)&PAGE_MASK)
 
 #define PAGE_OFFSET	0xf0000000
-#define __pa(x)                 ((unsigned long)(x) - PAGE_OFFSET)
-#define __va(x)                 ((void *)((unsigned long) (x) + PAGE_OFFSET))
+#ifndef __ASSEMBLY__
+extern unsigned long phys_base;
+#endif
+#define __pa(x)			((unsigned long)(x) - PAGE_OFFSET + phys_base)
+#define __va(x)			((void *)((unsigned long) (x) - phys_base + PAGE_OFFSET))
 
 #define virt_to_phys(x)		__pa((unsigned long)(x))
 #define phys_to_virt(x)		__va((unsigned long)(x))
 
-#define pfn_to_page(pfn)        (mem_map + (pfn))
-#define page_to_pfn(page)       ((unsigned long)((page) - mem_map))
-#define virt_to_page(kaddr)	(mem_map + (__pa(kaddr) >> PAGE_SHIFT))
-#define pfn_valid(pfn)		((pfn) < max_mapnr)
-#define virt_addr_valid(kaddr)	pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
+#define PFN(x)			((x) >> PAGE_SHIFT)
+#define PADDR(x)		((x) << PAGE_SHIFT)
+#define pfn_to_page(pfn)	(mem_map + (((unsigned long)pfn) - PFN(phys_base)))
+#define page_to_pfn(page)	(((unsigned long)((page) - mem_map)) + PFN(phys_base))
+#define virt_to_page(kaddr)	pfn_to_page(PFN(__pa(kaddr)))
+#define pfn_valid(pfn)		(((pfn) >= PFN(phys_base)) && (((pfn)-PFN(phys_base)) < max_mapnr))
+#define virt_addr_valid(kaddr)	pfn_valid(PFN(__pa(kaddr)))
 
 #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
 				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)



-- 
RY  Stefan
+-----------------+----------------+
| mail@s-holst.de | www.s-holst.de |
+-----------------+----------------+

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: nonzero phys_base
  2004-03-16 11:41 nonzero phys_base Stefan Holst
@ 2004-03-16 16:55 ` Keith M Wesolowski
  2004-03-16 17:10 ` Pete Zaitcev
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Keith M Wesolowski @ 2004-03-16 16:55 UTC (permalink / raw)
  To: sparclinux

On Tue, Mar 16, 2004 at 12:41:21PM +0100, Stefan Holst wrote:

> how do you think about this fix? any chances to get this into the
> kernel? if yes, how? this is the first time i send kernel patches,
> so hints and comments are very welcome :).

Yes, I'll consider this for inclusion.  You get patches into the
kernel by sending them to this list, so you're off to a good start
there.

Please use pfn_base the way sparc64 does.  Shifting every time this is
used is unnecessarily expensive.  It would be nice if we could also
dispense with making __va and __pa nonconstant, but unlike sparc64 we
don't have the luxury of huge space to map into.

Otherwise this looks pretty good at first glance.

Thanks for doing this, Stefan.

-- 
Keith M Wesolowski

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: nonzero phys_base
  2004-03-16 11:41 nonzero phys_base Stefan Holst
  2004-03-16 16:55 ` Keith M Wesolowski
@ 2004-03-16 17:10 ` Pete Zaitcev
  2004-03-17 23:58 ` Stefan Holst
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Pete Zaitcev @ 2004-03-16 17:10 UTC (permalink / raw)
  To: sparclinux

On Tue, 16 Mar 2004 12:41:21 +0100
Stefan Holst <mail@s-holst.de> wrote:

Looks good on the whole, especially in that you accepted a correct
relationship between PFN and indexing into mem_map.

The only little problem is:

> +#define __pa(x)			((unsigned long)(x) - PAGE_OFFSET + phys_base)
> +#define __va(x)			((void *)((unsigned long) (x) - phys_base + PAGE_OFFSET))

This, obviously, overflows on highmem systems.
Do we have any users for __pa, __va, virt_to_phys and phys_to_virt?
It would be helpful if you enumerated all of them and perhaps
removed some.

> -#define virt_to_page(kaddr)	(mem_map + (__pa(kaddr) >> PAGE_SHIFT))
> +#define virt_to_page(kaddr)	pfn_to_page(PFN(__pa(kaddr)))

This was correct before, because of the way mem_map was placed,
its physical address never overflowed. But with nonzero phys_base,
it is not correct anymore.

In fact you do not need this, just use

 mem_map + ((unsigned long)(x) - PAGE_OFFSET)

> +#define virt_addr_valid(kaddr)	pfn_valid(PFN(__pa(kaddr)))

Ditto

-- Pete

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: nonzero phys_base
  2004-03-16 11:41 nonzero phys_base Stefan Holst
  2004-03-16 16:55 ` Keith M Wesolowski
  2004-03-16 17:10 ` Pete Zaitcev
@ 2004-03-17 23:58 ` Stefan Holst
  2004-03-18  0:09 ` Stefan Holst
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Stefan Holst @ 2004-03-17 23:58 UTC (permalink / raw)
  To: sparclinux

On 03/16, Pete Zaitcev wrote:
> On Tue, 16 Mar 2004 12:41:21 +0100
> Stefan Holst <mail@s-holst.de> wrote:
> 
> Looks good on the whole, especially in that you accepted a correct
> relationship between PFN and indexing into mem_map.
> 
> The only little problem is:
> 
> > +#define __pa(x)			((unsigned long)(x) - PAGE_OFFSET + phys_base)
> > +#define __va(x)			((void *)((unsigned long) (x) - phys_base + PAGE_OFFSET))
> 
> This, obviously, overflows on highmem systems.

hmm, never thought about highmem support... i'm working on 4mb here - for
everything ;). i have no idea how to handle this issue yet.

> Do we have any users for __pa, __va, virt_to_phys and phys_to_virt?
> It would be helpful if you enumerated all of them and perhaps
> removed some.

greped a bit and saw that the number of users for these macros are almost
equal.

> 
> > -#define virt_to_page(kaddr)	(mem_map + (__pa(kaddr) >> PAGE_SHIFT))
> > +#define virt_to_page(kaddr)	pfn_to_page(PFN(__pa(kaddr)))
> 
> This was correct before, because of the way mem_map was placed,
> its physical address never overflowed. But with nonzero phys_base,
> it is not correct anymore.
> 
> In fact you do not need this, just use
> 
>  mem_map + ((unsigned long)(x) - PAGE_OFFSET)
> 
> > +#define virt_addr_valid(kaddr)	pfn_valid(PFN(__pa(kaddr)))

thanks for the hints.
revised patch below, now also with pfn_base as keith suggested.


diff -ur a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c
--- a/arch/sparc/kernel/setup.c	2004-03-11 11:32:58.000000000 +0100
+++ b/arch/sparc/kernel/setup.c	2004-03-17 23:57:08.993044448 +0100
@@ -330,6 +330,7 @@
 		if (highest_paddr < top)
 			highest_paddr = top;
 	}
+	pfn_base = phys_base >> PAGE_SHIFT;
 
 	if (!root_flags)
 		root_mountflags &= ~MS_RDONLY;
diff -ur a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c
--- a/arch/sparc/kernel/sparc_ksyms.c	2004-03-11 11:32:58.000000000 +0100
+++ b/arch/sparc/kernel/sparc_ksyms.c	2004-03-17 23:57:09.005042624 +0100
@@ -145,6 +145,7 @@
 
 EXPORT_SYMBOL(sparc_valid_addr_bitmap);
 EXPORT_SYMBOL(phys_base);
+EXPORT_SYMBOL(pfn_base);
 
 /* Atomic operations. */
 EXPORT_SYMBOL(___atomic24_add);
diff -ur a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c
--- a/arch/sparc/mm/init.c	2004-02-29 23:35:40.000000000 +0100
+++ b/arch/sparc/mm/init.c	2004-03-17 23:57:09.006042472 +0100
@@ -39,6 +39,8 @@
 
 unsigned long phys_base;
 
+unsigned long pfn_base;
+
 unsigned long page_kernel;
 
 struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS+1];
@@ -134,7 +136,7 @@
 unsigned long calc_max_low_pfn(void)
 {
 	int i;
-	unsigned long tmp = (SRMMU_MAXMEM >> PAGE_SHIFT);
+	unsigned long tmp = ((phys_base + SRMMU_MAXMEM) >> PAGE_SHIFT);
 	unsigned long curr_pfn, last_pfn;
 
 	last_pfn = (sp_banks[0].base_addr + sp_banks[0].num_bytes) >> PAGE_SHIFT;
@@ -189,9 +191,6 @@
 	 */
 	start_pfn  = (unsigned long)__pa(PAGE_ALIGN((unsigned long) &_end));
 
-	/* Adjust up to the physical address where the kernel begins. */
-	start_pfn += phys_base;
-
 	/* Now shift down to get the real physical page frame number. */
 	start_pfn >>= PAGE_SHIFT;
 
@@ -202,7 +201,7 @@
 	max_low_pfn = max_pfn;
 	highstart_pfn = highend_pfn = max_pfn;
 
-	if (max_low_pfn > (SRMMU_MAXMEM >> PAGE_SHIFT)) {
+	if (max_low_pfn > ((phys_base + SRMMU_MAXMEM) >> PAGE_SHIFT)) {
 		highstart_pfn = (SRMMU_MAXMEM >> PAGE_SHIFT);
 		max_low_pfn = calc_max_low_pfn();
 		printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",
@@ -267,8 +266,8 @@
 		reserve_bootmem(initrd_start, size);
 		*pages_avail -= PAGE_ALIGN(size) >> PAGE_SHIFT;
 
-		initrd_start += PAGE_OFFSET;
-		initrd_end += PAGE_OFFSET;
+		initrd_start = (initrd_start - phys_base) + PAGE_OFFSET;
+		initrd_end = (initrd_end - phys_base) + PAGE_OFFSET;		
 	}
 #endif
 	/* Reserve the kernel text/data/bss. */
@@ -432,7 +431,7 @@
 
 	taint_real_pages();
 
-	max_mapnr = last_valid_pfn - (phys_base >> PAGE_SHIFT);
+	max_mapnr = last_valid_pfn - pfn_base;
 	high_memory = __va(max_low_pfn << PAGE_SHIFT);
 
 	num_physpages = totalram_pages = free_all_bootmem();
@@ -477,7 +476,7 @@
 		unsigned long page;
 		struct page *p;
 
-		page = addr + phys_base;
+		page = addr;
 		p = virt_to_page(page);
 
 		ClearPageReserved(p);
diff -ur a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
--- a/arch/sparc/mm/srmmu.c	2004-03-11 11:32:58.000000000 +0100
+++ b/arch/sparc/mm/srmmu.c	2004-03-17 23:56:24.168858760 +0100
@@ -213,7 +213,7 @@
  * and a page entry and page directory to the page they refer to.
  */
 static pte_t srmmu_mk_pte(struct page *page, pgprot_t pgprot)
-{ return __pte(((page - mem_map) << (PAGE_SHIFT-4)) | pgprot_val(pgprot)); }
+{ return __pte((page_to_pfn(page) << (PAGE_SHIFT-4)) | pgprot_val(pgprot)); }
 
 static pte_t srmmu_mk_pte_phys(unsigned long page, pgprot_t pgprot)
 { return __pte(((page) >> 4) | pgprot_val(pgprot)); }
@@ -245,7 +245,7 @@
 	unsigned long ptp;	/* Physical address, shifted right by 4 */
 	int i;
 
-	ptp = (ptep - mem_map) << (PAGE_SHIFT-4);	/* watch for overflow */
+	ptp = page_to_pfn(ptep) << (PAGE_SHIFT-4);	/* watch for overflow */
 	for (i = 0; i < SRMMU_PTRS_PER_PTE_SOFT/SRMMU_PTRS_PER_PTE; i++) {
 		srmmu_set_pte((pte_t *)&pmdp->pmdv[i], SRMMU_ET_PTD | ptp);
 		ptp += (SRMMU_PTRS_PER_PTE*sizeof(pte_t) >> 4);
@@ -480,7 +480,7 @@
 
 	if ((pte = (unsigned long)srmmu_pte_alloc_one_kernel(mm, address)) = 0)
 		return NULL;
-	return mem_map + (__nocache_pa(pte) >> PAGE_SHIFT);
+	return pfn_to_page( __nocache_pa(pte) >> PAGE_SHIFT );
 }
 
 static void srmmu_free_pte_fast(pte_t *pte)
@@ -495,7 +495,7 @@
 	p = (unsigned long)page_address(pte);	/* Cached address (for test) */
 	if (p = 0)
 		BUG();
-	p = ((pte - mem_map) << PAGE_SHIFT);	/* Physical address */
+	p = page_to_pfn(pte) << PAGE_SHIFT;	/* Physical address */
 	p = (unsigned long) __nocache_va(p);	/* Nocached virtual */
 	srmmu_free_nocache(p, SRMMU_PTE_SZ_SOFT);
 }
@@ -1331,10 +1331,6 @@
 				    phys_base >> PAGE_SHIFT, zholes_size);
 		mem_map = contig_page_data.node_mem_map;
 	}
-
-/* P3: easy to fix, todo. Current code is utterly broken, though. */
-	if (phys_base != 0)
-		panic("phys_base nonzero");
 }
 
 static void srmmu_mmu_info(struct seq_file *m)
diff -ur a/include/asm-sparc/page.h b/include/asm-sparc/page.h
--- a/include/asm-sparc/page.h	2004-02-29 23:35:48.000000000 +0100
+++ b/include/asm-sparc/page.h	2004-03-17 23:57:09.006042472 +0100
@@ -156,17 +156,22 @@
 #define PAGE_ALIGN(addr)  (((addr)+PAGE_SIZE-1)&PAGE_MASK)
 
 #define PAGE_OFFSET	0xf0000000
-#define __pa(x)                 ((unsigned long)(x) - PAGE_OFFSET)
-#define __va(x)                 ((void *)((unsigned long) (x) + PAGE_OFFSET))
+#ifndef __ASSEMBLY__
+extern unsigned long phys_base;
+extern unsigned long pfn_base;
+#endif
+#define __pa(x)			((unsigned long)(x) - PAGE_OFFSET + phys_base)
+#define __va(x)			((void *)((unsigned long) (x) - phys_base + PAGE_OFFSET))
+
+#define virt_to_phys		__pa
+#define phys_to_virt		__va
+
+#define pfn_to_page(pfn)	(mem_map + ((pfn)-(pfn_base)))
+#define page_to_pfn(page)	((unsigned long)(((page) - mem_map) + pfn_base))
+#define virt_to_page(kaddr)	(mem_map + ((((unsigned long)(kaddr)-PAGE_OFFSET)>>PAGE_SHIFT)))
 
-#define virt_to_phys(x)		__pa((unsigned long)(x))
-#define phys_to_virt(x)		__va((unsigned long)(x))
-
-#define pfn_to_page(pfn)        (mem_map + (pfn))
-#define page_to_pfn(page)       ((unsigned long)((page) - mem_map))
-#define virt_to_page(kaddr)	(mem_map + (__pa(kaddr) >> PAGE_SHIFT))
-#define pfn_valid(pfn)		((pfn) < max_mapnr)
-#define virt_addr_valid(kaddr)	pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
+#define pfn_valid(pfn)		(((pfn) >= (pfn_base)) && (((pfn)-(pfn_base)) < max_mapnr))
+#define virt_addr_valid(kaddr)	((((unsigned long)(kaddr)-PAGE_OFFSET)>>PAGE_SHIFT) < max_mapnr)
 
 #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
 				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
diff -ur a/include/asm-sparc/pgtable.h b/include/asm-sparc/pgtable.h
--- a/include/asm-sparc/pgtable.h	2004-02-29 23:36:24.000000000 +0100
+++ b/include/asm-sparc/pgtable.h	2004-03-17 23:57:09.039037456 +0100
@@ -181,6 +181,7 @@
  * hit for all __pa()/__va() operations.
  */
 extern unsigned long phys_base;
+extern unsigned long pfn_base;
 
 /*
  * BAD_PAGETABLE is used when we need a bogus page-table, while

-- 
RY  Stefan
+-----------------+----------------+
| mail@s-holst.de | www.s-holst.de |
+-----------------+----------------+

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: nonzero phys_base
  2004-03-16 11:41 nonzero phys_base Stefan Holst
                   ` (2 preceding siblings ...)
  2004-03-17 23:58 ` Stefan Holst
@ 2004-03-18  0:09 ` Stefan Holst
  2004-03-18  2:45 ` Keith M Wesolowski
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Stefan Holst @ 2004-03-18  0:09 UTC (permalink / raw)
  To: sparclinux

On 03/16, Keith M Wesolowski wrote:
> On Tue, Mar 16, 2004 at 12:41:21PM +0100, Stefan Holst wrote:
> 
> > how do you think about this fix? any chances to get this into the
> > kernel? if yes, how? this is the first time i send kernel patches,
> > so hints and comments are very welcome :).
> 
> Yes, I'll consider this for inclusion.  You get patches into the
> kernel by sending them to this list, so you're off to a good start
> there.
> 
> Please use pfn_base the way sparc64 does.  Shifting every time this is
> used is unnecessarily expensive.  It would be nice if we could also

done, see patch in other post.

> dispense with making __va and __pa nonconstant, but unlike sparc64 we
> don't have the luxury of huge space to map into.

if phys_base is known at compile time, it could be a macro, at least 
in __pa and __va to make them constant. would that be an option?

> 
> Otherwise this looks pretty good at first glance.
> 
> Thanks for doing this, Stefan.

thanks :)
but that was not entirely my work. i just tied up to konrad's at
the moment.

-- 
RY  Stefan
+-----------------+----------------+
| mail@s-holst.de | www.s-holst.de |
+-----------------+----------------+

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: nonzero phys_base
  2004-03-16 11:41 nonzero phys_base Stefan Holst
                   ` (3 preceding siblings ...)
  2004-03-18  0:09 ` Stefan Holst
@ 2004-03-18  2:45 ` Keith M Wesolowski
  2004-03-18  3:36 ` Pete Zaitcev
  2004-03-21 22:51 ` Keith M Wesolowski
  6 siblings, 0 replies; 8+ messages in thread
From: Keith M Wesolowski @ 2004-03-18  2:45 UTC (permalink / raw)
  To: sparclinux

On Tue, Mar 16, 2004 at 09:10:56AM -0800, Pete Zaitcev wrote:

> > +#define __pa(x)			((unsigned long)(x) - PAGE_OFFSET + phys_base)
> > +#define __va(x)			((void *)((unsigned long) (x) - phys_base + PAGE_OFFSET))
> 
> This, obviously, overflows on highmem systems.
> Do we have any users for __pa, __va, virt_to_phys and phys_to_virt?
> It would be helpful if you enumerated all of them and perhaps
> removed some.

Pete, this has always been true for highmem.  How does his patch make
this worse?

-- 
Keith M Wesolowski

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: nonzero phys_base
  2004-03-16 11:41 nonzero phys_base Stefan Holst
                   ` (4 preceding siblings ...)
  2004-03-18  2:45 ` Keith M Wesolowski
@ 2004-03-18  3:36 ` Pete Zaitcev
  2004-03-21 22:51 ` Keith M Wesolowski
  6 siblings, 0 replies; 8+ messages in thread
From: Pete Zaitcev @ 2004-03-18  3:36 UTC (permalink / raw)
  To: sparclinux

On Wed, 17 Mar 2004 18:45:17 -0800
Keith M Wesolowski <wesolows@foobazco.org> wrote:

> On Tue, Mar 16, 2004 at 09:10:56AM -0800, Pete Zaitcev wrote:
> 
> > > +#define __pa(x)			((unsigned long)(x) - PAGE_OFFSET + phys_base)
> > > +#define __va(x)			((void *)((unsigned long) (x) - phys_base + PAGE_OFFSET))
> > 
> > This, obviously, overflows on highmem systems.
> > Do we have any users for __pa, __va, virt_to_phys and phys_to_virt?
> > It would be helpful if you enumerated all of them and perhaps
> > removed some.
> 
> Pete, this has always been true for highmem.  How does his patch make
> this worse?

The patch is not making anything worse, but having nonzero phys_base
allows for the first SIMM bank or DIMM to be missing. They always
overflowed, but the box would not boot far enough for this to be
noticeable regarding the calculation of index into mem_map.

The changed assumption is that everything that is low mem (mapped)
has a small physical address.

Actually, I meant to note it before, but perhaps phys_base should be
eliminated completely in favor of pfn_base.

-- Pete

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: nonzero phys_base
  2004-03-16 11:41 nonzero phys_base Stefan Holst
                   ` (5 preceding siblings ...)
  2004-03-18  3:36 ` Pete Zaitcev
@ 2004-03-21 22:51 ` Keith M Wesolowski
  6 siblings, 0 replies; 8+ messages in thread
From: Keith M Wesolowski @ 2004-03-21 22:51 UTC (permalink / raw)
  To: sparclinux

On Thu, Mar 18, 2004 at 12:58:29AM +0100, Stefan Holst wrote:

> hmm, never thought about highmem support... i'm working on 4mb here - for
> everything ;). i have no idea how to handle this issue yet.

There was actually just one crucial bit wrong that broke highmem;
highstart_pfn was miscalculated.  The assumption that low memory means
low addresses doesn't seem to be used anywhere.

Some Sun systems won't even boot to prom without memory in slot 0;
ss4/5 seem to be this way.  I did test ss20 with and without slot 0
filled, with and without highmem and it seems ok.  I'd still recommend
filling slot 0 on Sun systems.

After fixing that and eliminating a few more useless shifts, I applied
the below patch.  Thanks Stefan.

# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2004/03/21 14:43:40-08:00 wesolows@foobazco.org 
#   [SPARC32]: Support memory starting at physical address other than 0
#   
#   From: Stefan Holst <mail@s-holst.de>
#   
#   Allow physical memory to start at almost arbitrary addresses.  LEON
#   needs it, so do SPARCstation 10/20 without slot 0 populated.  Although
#   Sun do not support this configuration, at least some such systems can
#   boot with this patch.
#   
#   Physical memory starting at or above 0xF4000000 is not supported.
# 
# include/asm-sparc/pgtable.h
#   2004/03/21 14:43:34-08:00 wesolows@foobazco.org +1 -0
#   [SPARC32]: Support memory starting at physical address other than 0
# 
# include/asm-sparc/page.h
#   2004/03/21 14:43:34-08:00 wesolows@foobazco.org +14 -9
#   [SPARC32]: Support memory starting at physical address other than 0
# 
# arch/sparc/mm/sun4c.c
#   2004/03/21 14:43:34-08:00 wesolows@foobazco.org +2 -2
#   [SPARC32]: Support memory starting at physical address other than 0
# 
# arch/sparc/mm/srmmu.c
#   2004/03/21 14:43:34-08:00 wesolows@foobazco.org +6 -10
#   [SPARC32]: Support memory starting at physical address other than 0
# 
# arch/sparc/mm/init.c
#   2004/03/21 14:43:34-08:00 wesolows@foobazco.org +10 -13
#   [SPARC32]: Support memory starting at physical address other than 0
# 
# arch/sparc/kernel/sparc_ksyms.c
#   2004/03/21 14:43:34-08:00 wesolows@foobazco.org +1 -0
#   [SPARC32]: Support memory starting at physical address other than 0
# 
# arch/sparc/kernel/setup.c
#   2004/03/21 14:43:34-08:00 wesolows@foobazco.org +1 -0
#   [SPARC32]: Support memory starting at physical address other than 0
# 
diff -Nru a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c
--- a/arch/sparc/kernel/setup.c	Sun Mar 21 14:44:13 2004
+++ b/arch/sparc/kernel/setup.c	Sun Mar 21 14:44:13 2004
@@ -331,6 +331,7 @@
 		if (highest_paddr < top)
 			highest_paddr = top;
 	}
+	pfn_base = phys_base >> PAGE_SHIFT;
 
 	if (!root_flags)
 		root_mountflags &= ~MS_RDONLY;
diff -Nru a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c
--- a/arch/sparc/kernel/sparc_ksyms.c	Sun Mar 21 14:44:13 2004
+++ b/arch/sparc/kernel/sparc_ksyms.c	Sun Mar 21 14:44:13 2004
@@ -145,6 +145,7 @@
 
 EXPORT_SYMBOL(sparc_valid_addr_bitmap);
 EXPORT_SYMBOL(phys_base);
+EXPORT_SYMBOL(pfn_base);
 
 /* Atomic operations. */
 EXPORT_SYMBOL(___atomic24_add);
diff -Nru a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c
--- a/arch/sparc/mm/init.c	Sun Mar 21 14:44:13 2004
+++ b/arch/sparc/mm/init.c	Sun Mar 21 14:44:13 2004
@@ -38,6 +38,7 @@
 unsigned long *sparc_valid_addr_bitmap;
 
 unsigned long phys_base;
+unsigned long pfn_base;
 
 unsigned long page_kernel;
 
@@ -134,7 +135,7 @@
 unsigned long calc_max_low_pfn(void)
 {
 	int i;
-	unsigned long tmp = (SRMMU_MAXMEM >> PAGE_SHIFT);
+	unsigned long tmp = pfn_base + (SRMMU_MAXMEM >> PAGE_SHIFT);
 	unsigned long curr_pfn, last_pfn;
 
 	last_pfn = (sp_banks[0].base_addr + sp_banks[0].num_bytes) >> PAGE_SHIFT;
@@ -189,9 +190,6 @@
 	 */
 	start_pfn  = (unsigned long)__pa(PAGE_ALIGN((unsigned long) &_end));
 
-	/* Adjust up to the physical address where the kernel begins. */
-	start_pfn += phys_base;
-
 	/* Now shift down to get the real physical page frame number. */
 	start_pfn >>= PAGE_SHIFT;
 
@@ -202,8 +200,8 @@
 	max_low_pfn = max_pfn;
 	highstart_pfn = highend_pfn = max_pfn;
 
-	if (max_low_pfn > (SRMMU_MAXMEM >> PAGE_SHIFT)) {
-		highstart_pfn = (SRMMU_MAXMEM >> PAGE_SHIFT);
+	if (max_low_pfn > pfn_base + (SRMMU_MAXMEM >> PAGE_SHIFT)) {
+		highstart_pfn = pfn_base + (SRMMU_MAXMEM >> PAGE_SHIFT);
 		max_low_pfn = calc_max_low_pfn();
 		printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",
 		    calc_highpages() >> (20 - PAGE_SHIFT));
@@ -230,7 +228,8 @@
 	}
 #endif	
 	/* Initialize the boot-time allocator. */
-	bootmap_size = init_bootmem_node(NODE_DATA(0), bootmap_pfn, phys_base>>PAGE_SHIFT, max_low_pfn);
+	bootmap_size = init_bootmem_node(NODE_DATA(0), bootmap_pfn, pfn_base,
+					 max_low_pfn);
 
 	/* Now register the available physical memory with the
 	 * allocator.
@@ -267,8 +266,8 @@
 		reserve_bootmem(initrd_start, size);
 		*pages_avail -= PAGE_ALIGN(size) >> PAGE_SHIFT;
 
-		initrd_start += PAGE_OFFSET;
-		initrd_end += PAGE_OFFSET;
+		initrd_start = (initrd_start - phys_base) + PAGE_OFFSET;
+		initrd_end = (initrd_end - phys_base) + PAGE_OFFSET;		
 	}
 #endif
 	/* Reserve the kernel text/data/bss. */
@@ -432,7 +431,7 @@
 
 	taint_real_pages();
 
-	max_mapnr = last_valid_pfn - (phys_base >> PAGE_SHIFT);
+	max_mapnr = last_valid_pfn - pfn_base;
 	high_memory = __va(max_low_pfn << PAGE_SHIFT);
 
 	num_physpages = totalram_pages = free_all_bootmem();
@@ -474,11 +473,9 @@
 
 	addr = (unsigned long)(&__init_begin);
 	for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
-		unsigned long page;
 		struct page *p;
 
-		page = addr + phys_base;
-		p = virt_to_page(page);
+		p = virt_to_page(addr);
 
 		ClearPageReserved(p);
 		set_page_count(p, 1);
diff -Nru a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
--- a/arch/sparc/mm/srmmu.c	Sun Mar 21 14:44:13 2004
+++ b/arch/sparc/mm/srmmu.c	Sun Mar 21 14:44:13 2004
@@ -213,7 +213,7 @@
  * and a page entry and page directory to the page they refer to.
  */
 static pte_t srmmu_mk_pte(struct page *page, pgprot_t pgprot)
-{ return __pte(((page - mem_map) << (PAGE_SHIFT-4)) | pgprot_val(pgprot)); }
+{ return __pte((page_to_pfn(page) << (PAGE_SHIFT-4)) | pgprot_val(pgprot)); }
 
 static pte_t srmmu_mk_pte_phys(unsigned long page, pgprot_t pgprot)
 { return __pte(((page) >> 4) | pgprot_val(pgprot)); }
@@ -245,7 +245,7 @@
 	unsigned long ptp;	/* Physical address, shifted right by 4 */
 	int i;
 
-	ptp = (ptep - mem_map) << (PAGE_SHIFT-4);	/* watch for overflow */
+	ptp = page_to_pfn(ptep) << (PAGE_SHIFT-4);	/* watch for overflow */
 	for (i = 0; i < SRMMU_PTRS_PER_PTE_SOFT/SRMMU_PTRS_PER_PTE; i++) {
 		srmmu_set_pte((pte_t *)&pmdp->pmdv[i], SRMMU_ET_PTD | ptp);
 		ptp += (SRMMU_PTRS_PER_PTE*sizeof(pte_t) >> 4);
@@ -480,7 +480,7 @@
 
 	if ((pte = (unsigned long)srmmu_pte_alloc_one_kernel(mm, address)) = 0)
 		return NULL;
-	return mem_map + (__nocache_pa(pte) >> PAGE_SHIFT);
+	return pfn_to_page( __nocache_pa(pte) >> PAGE_SHIFT );
 }
 
 static void srmmu_free_pte_fast(pte_t *pte)
@@ -495,7 +495,7 @@
 	p = (unsigned long)page_address(pte);	/* Cached address (for test) */
 	if (p = 0)
 		BUG();
-	p = ((pte - mem_map) << PAGE_SHIFT);	/* Physical address */
+	p = page_to_pfn(pte) << PAGE_SHIFT;	/* Physical address */
 	p = (unsigned long) __nocache_va(p);	/* Nocached virtual */
 	srmmu_free_nocache(p, SRMMU_PTE_SZ_SOFT);
 }
@@ -1316,7 +1316,7 @@
 		for (znum = 0; znum < MAX_NR_ZONES; znum++)
 			zones_size[znum] = zholes_size[znum] = 0;
 
-		npages = max_low_pfn - (phys_base >> PAGE_SHIFT);
+		npages = max_low_pfn - pfn_base;
 
 		zones_size[ZONE_DMA] = npages;
 		zholes_size[ZONE_DMA] = npages - pages_avail;
@@ -1326,13 +1326,9 @@
 		zholes_size[ZONE_HIGHMEM] = npages - calc_highpages();
 
 		free_area_init_node(0, &contig_page_data, NULL, zones_size,
-				    phys_base >> PAGE_SHIFT, zholes_size);
+				    pfn_base, zholes_size);
 		mem_map = contig_page_data.node_mem_map;
 	}
-
-/* P3: easy to fix, todo. Current code is utterly broken, though. */
-	if (phys_base != 0)
-		panic("phys_base nonzero");
 }
 
 static void srmmu_mmu_info(struct seq_file *m)
diff -Nru a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c
--- a/arch/sparc/mm/sun4c.c	Sun Mar 21 14:44:13 2004
+++ b/arch/sparc/mm/sun4c.c	Sun Mar 21 14:44:13 2004
@@ -2088,7 +2088,7 @@
 		for (znum = 0; znum < MAX_NR_ZONES; znum++)
 			zones_size[znum] = zholes_size[znum] = 0;
 
-		npages = max_low_pfn - (phys_base >> PAGE_SHIFT);
+		npages = max_low_pfn - pfn_base;
 
 		zones_size[ZONE_DMA] = npages;
 		zholes_size[ZONE_DMA] = npages - pages_avail;
@@ -2098,7 +2098,7 @@
 		zholes_size[ZONE_HIGHMEM] = npages - calc_highpages();
 
 		free_area_init_node(0, &contig_page_data, NULL, zones_size,
-				    phys_base >> PAGE_SHIFT, zholes_size);
+				    pfn_base, zholes_size);
 		mem_map = contig_page_data.node_mem_map;
 	}
 
diff -Nru a/include/asm-sparc/page.h b/include/asm-sparc/page.h
--- a/include/asm-sparc/page.h	Sun Mar 21 14:44:13 2004
+++ b/include/asm-sparc/page.h	Sun Mar 21 14:44:13 2004
@@ -156,17 +156,22 @@
 #define PAGE_ALIGN(addr)  (((addr)+PAGE_SIZE-1)&PAGE_MASK)
 
 #define PAGE_OFFSET	0xf0000000
-#define __pa(x)                 ((unsigned long)(x) - PAGE_OFFSET)
-#define __va(x)                 ((void *)((unsigned long) (x) + PAGE_OFFSET))
+#ifndef __ASSEMBLY__
+extern unsigned long phys_base;
+extern unsigned long pfn_base;
+#endif
+#define __pa(x)			((unsigned long)(x) - PAGE_OFFSET + phys_base)
+#define __va(x)			((void *)((unsigned long) (x) - phys_base + PAGE_OFFSET))
 
-#define virt_to_phys(x)		__pa((unsigned long)(x))
-#define phys_to_virt(x)		__va((unsigned long)(x))
+#define virt_to_phys		__pa
+#define phys_to_virt		__va
 
-#define pfn_to_page(pfn)        (mem_map + (pfn))
-#define page_to_pfn(page)       ((unsigned long)((page) - mem_map))
-#define virt_to_page(kaddr)	(mem_map + (__pa(kaddr) >> PAGE_SHIFT))
-#define pfn_valid(pfn)		((pfn) < max_mapnr)
-#define virt_addr_valid(kaddr)	pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
+#define pfn_to_page(pfn)	(mem_map + ((pfn)-(pfn_base)))
+#define page_to_pfn(page)	((unsigned long)(((page) - mem_map) + pfn_base))
+#define virt_to_page(kaddr)	(mem_map + ((((unsigned long)(kaddr)-PAGE_OFFSET)>>PAGE_SHIFT)))
+
+#define pfn_valid(pfn)		(((pfn) >= (pfn_base)) && (((pfn)-(pfn_base)) < max_mapnr))
+#define virt_addr_valid(kaddr)	((((unsigned long)(kaddr)-PAGE_OFFSET)>>PAGE_SHIFT) < max_mapnr)
 
 #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
 				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
diff -Nru a/include/asm-sparc/pgtable.h b/include/asm-sparc/pgtable.h
--- a/include/asm-sparc/pgtable.h	Sun Mar 21 14:44:13 2004
+++ b/include/asm-sparc/pgtable.h	Sun Mar 21 14:44:13 2004
@@ -181,6 +181,7 @@
  * hit for all __pa()/__va() operations.
  */
 extern unsigned long phys_base;
+extern unsigned long pfn_base;
 
 /*
  * BAD_PAGETABLE is used when we need a bogus page-table, while


-- 
Keith M Wesolowski

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2004-03-21 22:51 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-03-16 11:41 nonzero phys_base Stefan Holst
2004-03-16 16:55 ` Keith M Wesolowski
2004-03-16 17:10 ` Pete Zaitcev
2004-03-17 23:58 ` Stefan Holst
2004-03-18  0:09 ` Stefan Holst
2004-03-18  2:45 ` Keith M Wesolowski
2004-03-18  3:36 ` Pete Zaitcev
2004-03-21 22:51 ` Keith M Wesolowski

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.