All of lore.kernel.org
 help / color / mirror / Atom feed
From: Pete Popov <ppopov@embeddedalley.com>
To: "'linux-mips@linux-mips.org'" <linux-mips@linux-mips.org>
Subject: patch / rfc
Date: Thu, 25 Aug 2005 14:51:21 -0700	[thread overview]
Message-ID: <1125006681.14435.1065.camel@localhost.localdomain> (raw)


This is an experimental (though tested) patch for early ioremap support
on mips, before mem_init runs. Something like this is only needed on
certain SoCs that have all of their I/O on high addresses such that they
can't me ioremapped through kseg1.

I think the CONFIG_64 stuff needs to removed since we don't need it. The
patch was tested on a MIPS32 CPU only. Some of the significant changes:

- trap_init() became early_trap_init() since too much stuff happens
there that is needed to support early ioremap. The old trap_init() is
now empty.

- added plat_setup_late() call. All ports would need to add that call,
or at least a placeholder. Early ioremap is possible only at that point.
However, most of the code in each plat_setup() can be moved to
plat_setup_late()

diff -Naur --exclude=CVS linux-2.6-orig/arch/mips/kernel/setup.c linux-2.6-dev/arch/mips/kernel/setup.c
--- linux-2.6-orig/arch/mips/kernel/setup.c	2005-08-24 17:12:31.000000000 -0700
+++ linux-2.6-dev/arch/mips/kernel/setup.c	2005-08-25 10:56:40.000000000 -0700
@@ -42,7 +42,10 @@
 #include <asm/sections.h>
 #include <asm/setup.h>
 #include <asm/system.h>
+#include <asm/traps.h>
+#include <asm/io.h>
 
+int init_bootmem_done;
 struct cpuinfo_mips cpu_data[NR_CPUS] __read_mostly;
 
 EXPORT_SYMBOL(cpu_data);
@@ -417,6 +420,8 @@
 
 	/* Reserve the bootmap memory.  */
 	reserve_bootmem(PFN_PHYS(first_usable_pfn), bootmap_size);
+
+	init_bootmem_done = 1;
 #endif /* CONFIG_SGI_IP27 */
 
 #ifdef CONFIG_BLK_DEV_INITRD
@@ -511,7 +516,23 @@
 #undef MAXMEM
 #undef MAXMEM_PFN
 
+void __init early_ioremap_init(void)
+{
+#ifdef CONFIG_64BIT
+	ioremap_base = (VMALLOC_START + PTRS_PER_PGD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE);
+#else
+#ifdef CONFIG_HIGHMEM
+	ioremap_base = (PKMAP_BASE-2*PAGE_SIZE);
+#else
+	ioremap_base = (FIXADDR_START-2*PAGE_SIZE);
+#endif
+#endif /* CONFIG_64BIT */
+
+	ioremap_bot = ioremap_base;
+}
+
 extern void plat_setup(void);
+extern void plat_setup_late(void);
 
 void __init setup_arch(char **cmdline_p)
 {
@@ -540,6 +561,11 @@
 	sparse_init();
 	paging_init();
 	resource_init();
+
+	early_trap_init();
+	early_ioremap_init();
+
+	plat_setup_late();	/* safe to do early ioremap */
 }
 
 int __init fpu_disable(char *s)
diff -Naur --exclude=CVS linux-2.6-orig/arch/mips/kernel/traps.c linux-2.6-dev/arch/mips/kernel/traps.c
--- linux-2.6-orig/arch/mips/kernel/traps.c	2005-08-24 17:12:32.000000000 -0700
+++ linux-2.6-dev/arch/mips/kernel/traps.c	2005-08-25 00:39:39.000000000 -0700
@@ -1239,6 +1238,10 @@
 
 void __init trap_init(void)
 {
+}
+
+void __init early_trap_init(void)
+{
 	extern char except_vec3_generic, except_vec3_r4000;
 	extern char except_vec4;
 	unsigned long i;
diff -Naur --exclude=CVS linux-2.6-orig/arch/mips/mm/init.c linux-2.6-dev/arch/mips/mm/init.c
--- linux-2.6-orig/arch/mips/mm/init.c	2005-08-10 18:15:55.000000000 -0700
+++ linux-2.6-dev/arch/mips/mm/init.c	2005-08-25 00:39:40.000000000 -0700
@@ -47,6 +47,8 @@
  * don't have to care about aliases on other CPUs.
  */
 unsigned long empty_zero_page, zero_page_mask;
+int mem_init_done;
+extern int init_bootmem_done;
 
 /*
  * Not static inline because used by IP27 special magic initialization code
@@ -200,6 +202,17 @@
 	return 0;
 }
 
+void __init *early_get_page(void)
+{
+	void *p;
+	if (init_bootmem_done) {
+		p = alloc_bootmem_pages(PAGE_SIZE);
+	} else {
+		p = NULL;
+	}
+	return p;
+}
+
 void __init mem_init(void)
 {
 	unsigned long codesize, reservedpages, datasize, initsize;
@@ -258,6 +271,8 @@
 	       datasize >> 10,
 	       initsize >> 10,
 	       (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10)));
+
+	mem_init_done = 1;
 }
 #endif /* !CONFIG_NEED_MULTIPLE_NODES */
 
diff -Naur --exclude=CVS linux-2.6-orig/arch/mips/mm/ioremap.c linux-2.6-dev/arch/mips/mm/ioremap.c
--- linux-2.6-orig/arch/mips/mm/ioremap.c	2005-08-10 18:15:55.000000000 -0700
+++ linux-2.6-dev/arch/mips/mm/ioremap.c	2005-08-25 13:35:25.045624752 -0700
@@ -15,6 +15,8 @@
 #include <asm/io.h>
 #include <asm/tlbflush.h>
 
+extern int mem_init_done;
+
 static inline void remap_area_pte(pte_t * pte, unsigned long address,
 	phys_t size, phys_t phys_addr, unsigned long flags)
 {
@@ -141,8 +143,9 @@
 
 	/*
 	 * Don't allow anybody to remap normal RAM that we're using..
+	 * mem_init() sets high_memory so only do the check after that.
 	 */
-	if (phys_addr < virt_to_phys(high_memory)) {
+	if (mem_init_done && (phys_addr < virt_to_phys(high_memory))) {
 		char *t_addr, *t_end;
 		struct page *page;
 
@@ -164,12 +167,18 @@
 	/*
 	 * Ok, go for it..
 	 */
-	area = get_vm_area(size, VM_IOREMAP);
-	if (!area)
-		return NULL;
-	addr = area->addr;
+	if (mem_init_done) {
+		area = get_vm_area(size, VM_IOREMAP);
+		if (!area)
+			return NULL;
+		addr = area->addr;
+	}
+	else {
+		addr = (void *)(ioremap_bot -= size);
+	}
 	if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) {
-		vunmap(addr);
+		if (mem_init_done)
+			vunmap(addr);
 		return NULL;
 	}
 
@@ -185,13 +194,15 @@
 	if (IS_KSEG1(addr))
 		return;
 
-	p = remove_vm_area((void *) (PAGE_MASK & (unsigned long __force) addr));
-	if (!p) {
-		printk(KERN_ERR "iounmap: bad address %p\n", addr);
-		return;
-	}
+	if ((unsigned long) addr < ioremap_bot) {
+		p = remove_vm_area((void *) (PAGE_MASK & (unsigned long __force) addr));
+		if (!p) {
+			printk(KERN_ERR "iounmap: bad address %p\n", addr);
+			return;
+		}
 
-        kfree(p);
+		kfree(p);
+	}
 }
 
 EXPORT_SYMBOL(__ioremap);
diff -Naur --exclude=CVS linux-2.6-orig/arch/mips/mm/pgtable-32.c linux-2.6-dev/arch/mips/mm/pgtable-32.c
--- linux-2.6-orig/arch/mips/mm/pgtable-32.c	2005-08-10 18:15:56.000000000 -0700
+++ linux-2.6-dev/arch/mips/mm/pgtable-32.c	2005-08-23 00:46:14.000000000 -0700
@@ -13,6 +13,9 @@
 #include <asm/fixmap.h>
 #include <asm/pgtable.h>
 
+unsigned long ioremap_base;
+unsigned long ioremap_bot;
+
 void pgd_init(unsigned long page)
 {
 	unsigned long *p = (unsigned long *) page;
diff -Naur --exclude=CVS linux-2.6-orig/include/asm-mips/io.h linux-2.6-dev/include/asm-mips/io.h
--- linux-2.6-orig/include/asm-mips/io.h	2005-08-10 18:22:04.000000000 -0700
+++ linux-2.6-dev/include/asm-mips/io.h	2005-08-25 13:35:31.000000000 -0700
@@ -637,4 +637,6 @@
  */
 #define xlate_dev_kmem_ptr(p)	p
 
+extern void early_ioremap_init(void);
+
 #endif /* _ASM_IO_H */
diff -Naur --exclude=CVS linux-2.6-orig/include/asm-mips/pgalloc.h linux-2.6-dev/include/asm-mips/pgalloc.h
--- linux-2.6-orig/include/asm-mips/pgalloc.h	2005-08-10 18:22:02.000000000 -0700
+++ linux-2.6-dev/include/asm-mips/pgalloc.h	2005-08-25 01:49:04.000000000 -0700
@@ -67,8 +67,17 @@
 	unsigned long address)
 {
 	pte_t *pte;
+	extern int mem_init_done;
+	extern void *early_get_page(void);
 
-	pte = (pte_t *) __get_free_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, PTE_ORDER);
+	if (mem_init_done) {
+		pte = (pte_t *) __get_free_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, PTE_ORDER);
+	} else {
+		pte = (pte_t *)early_get_page();
+		if (pte) {
+			clear_page(pte);
+		}
+	}
 
 	return pte;
 }
diff -Naur --exclude=CVS linux-2.6-orig/include/asm-mips/pgtable-32.h linux-2.6-dev/include/asm-mips/pgtable-32.h
--- linux-2.6-orig/include/asm-mips/pgtable-32.h	2005-08-25 13:02:30.000000000 -0700
+++ linux-2.6-dev/include/asm-mips/pgtable-32.h	2005-08-25 01:49:04.000000000 -0700
@@ -19,6 +19,8 @@
 
 #include <asm-generic/pgtable-nopmd.h>
 
+extern unsigned long ioremap_bot, ioremap_base;
+
 /*
  * - add_wired_entry() add a fixed TLB entry, and move wired register
  */
@@ -74,13 +76,9 @@
 #define USER_PTRS_PER_PGD	(0x80000000UL/PGDIR_SIZE)
 #define FIRST_USER_ADDRESS	0
 
-#define VMALLOC_START     MAP_BASE
+#define VMALLOC_START	MAP_BASE
 
-#ifdef CONFIG_HIGHMEM
-# define VMALLOC_END	(PKMAP_BASE-2*PAGE_SIZE)
-#else
-# define VMALLOC_END	(FIXADDR_START-2*PAGE_SIZE)
-#endif
+#define VMALLOC_END	ioremap_bot
 
 #ifdef CONFIG_64BIT_PHYS_ADDR
 #define pte_ERROR(e) \
diff -Naur --exclude=CVS linux-2.6-orig/include/asm-mips/traps.h linux-2.6-dev/include/asm-mips/traps.h
--- linux-2.6-orig/include/asm-mips/traps.h	2005-08-10 18:22:04.000000000 -0700
+++ linux-2.6-dev/include/asm-mips/traps.h	2005-08-25 10:56:01.000000000 -0700
@@ -24,4 +24,6 @@
 extern void (*board_nmi_handler_setup)(void);
 extern void (*board_ejtag_handler_setup)(void);
 
+extern void early_trap_init(void);
+
 #endif /* _ASM_TRAPS_H */

             reply	other threads:[~2005-08-25 21:46 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-08-25 21:51 Pete Popov [this message]
2005-08-26 13:10 ` patch / rfc Maciej W. Rozycki
2005-08-26 15:24   ` Pete Popov
2005-08-26 15:47     ` Dan Malek
2005-08-26 15:53       ` Maciej W. Rozycki
2005-08-26 16:38         ` Dan Malek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1125006681.14435.1065.camel@localhost.localdomain \
    --to=ppopov@embeddedalley.com \
    --cc=linux-mips@linux-mips.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.