Skip to contentSkip to conversation

A few more m68k patches

PATCH In review Geert Uytterhoeven 7 participants 14 messages May 28, 2007 – Jun 3, 2007

Subsystems (4)
lore
Share & tools
lore

Geert Uytterhoeven

author maintainer
#0 lore raw

cover A few more m68k patches

Hi Linus, Andrew,

Here are two more patches, after which mainline compiles (and runs!) again on m68k.

Thanks for applying!

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

author maintainer
#1 lore raw

PATCH 1/2 m68k: runtime patching infrastructure

From: Roman Zippel <[email protected]>

Add the basic infrastructure to allow runtime patching of kernel and modules to optimize a few functions with parameters, which are only calculated once during bootup and are otherwise constant. Use this for the conversion between virtual and physical addresses.

---
 arch/m68k/Makefile                |    1 +
 arch/m68k/kernel/Makefile         |    3 +--
 arch/m68k/kernel/module.c         |   28 +++++++++++++++++++++++++++-
 arch/m68k/kernel/module.lds       |    7 +++++++
 arch/m68k/kernel/vmlinux-std.lds  |    5 +++++
 arch/m68k/kernel/vmlinux-sun3.lds |    5 +++++
 arch/m68k/mm/motorola.c           |    3 +++
 include/asm-m68k/module.h         |   33 ++++++++++++++++++++++++++++++++-
 include/asm-m68k/page.h           |   29 ++++++++++++++++++++++++++---
 9 files changed, 107 insertions(+), 7 deletions(-)
arch/m68k/Makefile +1 -0
@@ -19,6 +19,7 @@ COMPILE_ARCH = $(shell uname -m)
 # override top level makefile
 AS += -m68020
 LDFLAGS := -m m68kelf
+LDFLAGS_MODULE += -T $(srctree)/arch/m68k/kernel/module.lds
 ifneq ($(COMPILE_ARCH),$(ARCH))
 	# prefix for cross-compiling binaries
 	CROSS_COMPILE = m68k-linux-gnu-
arch/m68k/kernel/Makefile +1 -2
@@ -9,13 +9,12 @@ else
 endif
 extra-y	+= vmlinux.lds
 
-obj-y	:= entry.o process.o traps.o ints.o signal.o ptrace.o \
+obj-y	:= entry.o process.o traps.o ints.o signal.o ptrace.o module.o \
 	   sys_m68k.o time.o semaphore.o setup.o m68k_ksyms.o devres.o
 
 devres-y = ../../../kernel/irq/devres.o
 
 obj-$(CONFIG_PCI)	+= bios32.o
-obj-$(CONFIG_MODULES)	+= module.o
 obj-y$(CONFIG_MMU_SUN3) += dma.o	# no, it's not a typo
 
 EXTRA_AFLAGS := -traditional
arch/m68k/kernel/module.c +27 -1
@@ -1,3 +1,9 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
 #include <linux/moduleloader.h>
 #include <linux/elf.h>
 #include <linux/vmalloc.h>
@@ -11,6 +17,8 @@
 #define DEBUGP(fmt...)
 #endif
 
+#ifdef CONFIG_MODULES
+
 void *module_alloc(unsigned long size)
 {
 	if (size == 0)
@@ -118,11 +126,29 @@ int apply_relocate_add(Elf32_Shdr *sechd
 
 int module_finalize(const Elf_Ehdr *hdr,
 		    const Elf_Shdr *sechdrs,
-		    struct module *me)
+		    struct module *mod)
 {
+	module_fixup(mod, mod->arch.fixup_start, mod->arch.fixup_end);
+
 	return 0;
 }
 
 void module_arch_cleanup(struct module *mod)
 {
 }
+
+#endif /* CONFIG_MODULES */
+
+void module_fixup(struct module *mod, struct m68k_fixup_info *start,
+		  struct m68k_fixup_info *end)
+{
+	struct m68k_fixup_info *fixup;
+
+	for (fixup = start; fixup < end; fixup++) {
+		switch (fixup->type) {
+		case m68k_fixup_memoffset:
+			*(u32 *)fixup->addr = m68k_memoffset;
+			break;
+		}
+	}
+}
arch/m68k/kernel/module.lds new file +7 -0
@@ -0,0 +1,7 @@
+SECTIONS {
+	.m68k_fixup : {
+		__start_fixup = .;
+		*(.m68k_fixup)
+		__stop_fixup = .;
+	}
+}
arch/m68k/kernel/vmlinux-std.lds +5 -0
@@ -60,6 +60,11 @@ SECTIONS
   __con_initcall_start = .;
   .con_initcall.init : { *(.con_initcall.init) }
   __con_initcall_end = .;
+  .m68k_fixup : {
+	__start_fixup = .;
+	*(.m68k_fixup)
+	__stop_fixup = .;
+  }
   SECURITY_INIT
 #ifdef CONFIG_BLK_DEV_INITRD
   . = ALIGN(8192);
arch/m68k/kernel/vmlinux-sun3.lds +5 -0
@@ -54,6 +54,11 @@ __init_begin = .;
 	__con_initcall_start = .;
 	.con_initcall.init : { *(.con_initcall.init) }
 	__con_initcall_end = .;
+	.m68k_fixup : {
+		__start_fixup = .;
+		*(.m68k_fixup)
+		__stop_fixup = .;
+	}
 	SECURITY_INIT
 #ifdef CONFIG_BLK_DEV_INITRD
 	. = ALIGN(8192);
arch/m68k/mm/motorola.c +3 -0
@@ -222,6 +222,9 @@ void __init paging_init(void)
 			pgprot_val(protection_map[i]) |= _PAGE_CACHE040;
 	}
 
+	module_fixup(NULL, __start_fixup, __stop_fixup);
+	flush_icache();
+
 	/*
 	 * Map the physical memory available into the kernel virtual
 	 * address space.  It may allocate some memory for page
include/asm-m68k/module.h +32 -1
@@ -1,7 +1,38 @@
 #ifndef _ASM_M68K_MODULE_H
 #define _ASM_M68K_MODULE_H
-struct mod_arch_specific { };
+
+struct mod_arch_specific {
+	struct m68k_fixup_info *fixup_start, *fixup_end;
+};
+
+#define MODULE_ARCH_INIT {				\
+	.fixup_start		= __start_fixup,	\
+	.fixup_end		= __stop_fixup,		\
+}
+
 #define Elf_Shdr Elf32_Shdr
 #define Elf_Sym Elf32_Sym
 #define Elf_Ehdr Elf32_Ehdr
+
+
+enum m68k_fixup_type {
+	m68k_fixup_memoffset,
+};
+
+struct m68k_fixup_info {
+	enum m68k_fixup_type type;
+	void *addr;
+};
+
+#define m68k_fixup(type, addr)			\
+	"	.section \".m68k_fixup\",\"aw\"\n"	\
+	"	.long " #type "," #addr "\n"	\
+	"	.previous\n"
+
+extern struct m68k_fixup_info __start_fixup[], __stop_fixup[];
+
+struct module;
+extern void module_fixup(struct module *mod, struct m68k_fixup_info *start,
+			 struct m68k_fixup_info *end);
+
 #endif /* _ASM_M68K_MODULE_H */
include/asm-m68k/page.h +26 -3
@@ -27,6 +27,8 @@
 
 #ifndef __ASSEMBLY__
 
+#include <asm/module.h>
+
 #define get_user_page(vaddr)		__get_free_page(GFP_KERNEL)
 #define free_user_page(page, addr)	free_page(addr)
 
@@ -114,14 +116,35 @@ typedef struct { unsigned long pgprot; }
 
 #ifndef __ASSEMBLY__
 
+extern unsigned long m68k_memoffset;
+
 #ifndef CONFIG_SUN3
 
 #define WANT_PAGE_VIRTUAL
 #ifdef CONFIG_SINGLE_MEMORY_CHUNK
-extern unsigned long m68k_memoffset;
 
-#define __pa(vaddr)		((unsigned long)(vaddr)+m68k_memoffset)
-#define __va(paddr)		((void *)((unsigned long)(paddr)-m68k_memoffset))
+static inline unsigned long ___pa(void *vaddr)
+{
+	unsigned long paddr;
+	asm (
+		"1:	addl #0,%0\n"
+		m68k_fixup(%c2, 1b+2)
+		: "=r" (paddr)
+		: "0" (vaddr), "i" (m68k_fixup_memoffset));
+	return paddr;
+}
+#define __pa(vaddr)    ___pa((void *)(vaddr))
+static inline void *__va(unsigned long paddr)
+{
+	void *vaddr;
+	asm (
+		"1:	subl #0,%0\n"
+		m68k_fixup(%c2, 1b+2)
+		: "=r" (vaddr)
+		: "0" (paddr), "i" (m68k_fixup_memoffset));
+	return vaddr;
+}
+
 #else
 #define __pa(vaddr)		virt_to_phys((void *)(vaddr))
 #define __va(paddr)		phys_to_virt((unsigned long)(paddr))
Signature · 10 lines
Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
							    -- Linus Torvalds
maintainer
#2 lore raw

Re: [patch 1/2] m68k: runtime patching infrastructure

include/asm-m68k/module.h line 6

Quoted 10 lines · On Mon, 28 May 2007 21:16:31 +0200 Geert Uytterhoeven <[email protected]>…
include/asm-m68k/module.h +4 -1
@@ -1,7 +1,38 @@
 #ifndef _ASM_M68K_MODULE_H
 #define _ASM_M68K_MODULE_H
-struct mod_arch_specific { };
+
+struct mod_arch_specific {
+	struct m68k_fixup_info *fixup_start, *fixup_end;
+};

Here we use struct m68k_fixup_info.

Quoted 8 lines
include/asm-m68k/module.h +5 -0
+#define MODULE_ARCH_INIT {				\
+	.fixup_start		= __start_fixup,	\
+	.fixup_end		= __stop_fixup,		\
+}
+
 #define Elf_Shdr Elf32_Shdr
 #define Elf_Sym Elf32_Sym
 #define Elf_Ehdr Elf32_Ehdr

include/asm-m68k/module.h line 25

Quoted 10 lines
include/asm-m68k/module.h +10 -0
+
+
+enum m68k_fixup_type {
+	m68k_fixup_memoffset,
+};
+
+struct m68k_fixup_info {
+	enum m68k_fixup_type type;
+	void *addr;
+};

and later we define it.

How come it doesn't spit warnings?

I think it could be tightened up even if it happens not to warn?

Quoted 10 lines
include/asm-m68k/module.h +10 -0
+#define m68k_fixup(type, addr)			\
+	"	.section \".m68k_fixup\",\"aw\"\n"	\
+	"	.long " #type "," #addr "\n"	\
+	"	.previous\n"
+
+extern struct m68k_fixup_info __start_fixup[], __stop_fixup[];
+
+struct module;
+extern void module_fixup(struct module *mod, struct m68k_fixup_info *start,
+			 struct m68k_fixup_info *end);
#3 lore raw

Re: [patch 1/2] m68k: runtime patching infrastructure

Quoted 37 lines · Andrew Morton

include/asm-m68k/module.h line 6

Quoted 10 lines · On Mon, 28 May 2007 21:16:31 +0200 Geert Uytterhoeven <[email protected]>…
include/asm-m68k/module.h +4 -1
@@ -1,7 +1,38 @@
 #ifndef _ASM_M68K_MODULE_H
 #define _ASM_M68K_MODULE_H
-struct mod_arch_specific { };
+
+struct mod_arch_specific {
+	struct m68k_fixup_info *fixup_start, *fixup_end;
+};

Here we use struct m68k_fixup_info.

Quoted 8 lines
include/asm-m68k/module.h +5 -0
+#define MODULE_ARCH_INIT {				\
+	.fixup_start		= __start_fixup,	\
+	.fixup_end		= __stop_fixup,		\
+}
+
 #define Elf_Shdr Elf32_Shdr
 #define Elf_Sym Elf32_Sym
 #define Elf_Ehdr Elf32_Ehdr

include/asm-m68k/module.h line 25

Quoted 10 lines
include/asm-m68k/module.h +10 -0
+
+
+enum m68k_fixup_type {
+	m68k_fixup_memoffset,
+};
+
+struct m68k_fixup_info {
+	enum m68k_fixup_type type;
+	void *addr;
+};

and later we define it.

Quoted 3 lines

How come it doesn't spit warnings?

I think it could be tightened up even if it happens not to warn?

struct a {
	struct not_yet_defined *start, *end;
};
struct not_yet_defined {
	void *foo;
};

Is a valid and gives no warnings.

Still I didnt tried to compile a m68k kernel, so I guess I shouldnt speak here :)

author maintainer
#4 lore raw

Re: [patch 1/2] m68k: runtime patching infrastructure

Quoted 47 lines · Eric Dumazet

Andrew Morton a �crit :

Quoted 37 lines

include/asm-m68k/module.h line 6

Quoted 10 lines · On Mon, 28 May 2007 21:16:31 +0200 Geert Uytterhoeven <[email protected]>…
include/asm-m68k/module.h +4 -1
@@ -1,7 +1,38 @@
 #ifndef _ASM_M68K_MODULE_H
 #define _ASM_M68K_MODULE_H
-struct mod_arch_specific { };
+
+struct mod_arch_specific {
+	struct m68k_fixup_info *fixup_start, *fixup_end;
+};

Here we use struct m68k_fixup_info.

Quoted 8 lines
include/asm-m68k/module.h +5 -0
+#define MODULE_ARCH_INIT {				\
+	.fixup_start		= __start_fixup,	\
+	.fixup_end		= __stop_fixup,		\
+}
+
 #define Elf_Shdr Elf32_Shdr
 #define Elf_Sym Elf32_Sym
 #define Elf_Ehdr Elf32_Ehdr

include/asm-m68k/module.h line 25

Quoted 10 lines
include/asm-m68k/module.h +10 -0
+
+
+enum m68k_fixup_type {
+	m68k_fixup_memoffset,
+};
+
+struct m68k_fixup_info {
+	enum m68k_fixup_type type;
+	void *addr;
+};

and later we define it.

Quoted 3 lines

How come it doesn't spit warnings?

I think it could be tightened up even if it happens not to warn?

struct a {
	struct not_yet_defined *start, *end;
};
Quoted 5 lines
struct not_yet_defined {
	void *foo;
};

Is a valid and gives no warnings.

I was puzzled by this as well, as there were no compiler warnings...

Apparently you get a warning only if the _first_ occurrence of a struct is declared inside a parameter list of a function.

So even

    struct a {
	struct not_yet_defined *start, *end;
    };

    extern void f(struct not_yet_defined *start);

    struct not_yet_defined {
	void *foo;
    };

doesn't give a warning, because the first occurence is inside the definition of struct a.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

#5 lore raw

Re: [patch 1/2] m68k: runtime patching infrastructure

Quoted 4 lines · Geert Uytterhoeven

I was puzzled by this as well, as there were no compiler warnings...

Apparently you get a warning only if the _first_ occurrence of a struct is declared inside a parameter list of a function.

The parameter list has its own scope.

Andreas.

Signature · 4 lines
Andreas Schwab, SuSE Labs, [email protected]
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
PGP key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."
#6 lore raw

Re: [patch 1/2] m68k: runtime patching infrastructure

In reply to Geert Uytterhoeven

On Wed, May 30, 2007 at 09:06:08AM +0200, Geert Uytterhoeven wrote:
[...]

Quoted 8 lines
Quoted 8 lines
Quoted 2 lines

I think it could be tightened up even if it happens not to warn?

struct a {
	struct not_yet_defined *start, *end;
};
Quoted 7 lines
Quoted 5 lines
struct not_yet_defined {
	void *foo;
};

Is a valid and gives no warnings.

I was puzzled by this as well, as there were no compiler warnings...

Pointers are (at least on m68k) of known size, so the compiler knows how much space the struct occupies.

Type checking is by definition futile with void * pointer, but for all other cases the compiler has all types and sizes it needs at this point.

The actual dereferencing of the symbol table is done by the linker, which also knows all locations and sizes it needs.

Actually, this is the only way to define circular referencing structures.

A one-pass-compiler-linker would run into problems.

Joerg, trying to recall compiler construction lessons

author maintainer
#7 lore raw

Re: [patch 1/2] m68k: runtime patching infrastructure

Quoted 18 lines · Joerg Dorchain

On Wed, May 30, 2007 at 09:06:08AM +0200, Geert Uytterhoeven wrote:
[...]

Quoted 8 lines
Quoted 8 lines
Quoted 2 lines

I think it could be tightened up even if it happens not to warn?

struct a {
	struct not_yet_defined *start, *end;
};
Quoted 7 lines
Quoted 5 lines
struct not_yet_defined {
	void *foo;
};

Is a valid and gives no warnings.

I was puzzled by this as well, as there were no compiler warnings...

Quoted 8 lines

Pointers are (at least on m68k) of known size, so the compiler knows how much space the struct occupies.

Type checking is by definition futile with void * pointer, but for all other cases the compiler has all types and sizes it needs at this point.

The actual dereferencing of the symbol table is done by the linker, which also knows all locations and sizes it needs.

True.

Quoted 2 lines

Actually, this is the only way to define circular referencing structures.

No, you have forward declarations for that. These are missing here.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

#8 lore raw

Re: [patch 1/2] m68k: runtime patching infrastructure

Quoted 5 lines · Geert Uytterhoeven
Quoted 3 lines

Actually, this is the only way to define circular referencing structures.

No, you have forward declarations for that. These are missing here.

I am no gcc expert, but might this be considred an implicit declaration? IIRC the compiler warns if later the type does noch match. Does it keep quiet when it matches?

Bye,

Joerg

#9 lore raw

Re: [patch 1/2] m68k: runtime patching infrastructure

In reply to Geert Uytterhoeven
Quoted 3 lines · Geert Uytterhoeven

Apparently you get a warning only if the _first_ occurrence of a struct is declared inside a parameter list of a function.

This is normal C behaviour (and afaik, the "inside a parameter list" part is actually just _modern_ C, not traditional C. I _think_ traditional C had a single global namespace for struct names, and no scoping at all).

You can use a _pointer_ to a structure without declaring the structure itself, and this is totally standard C behaviour. The very use of the pointer will tell the C compiler that such a structure exists, and since you only use the pointer, the compiler doesn't care what the struct _looks_ like. It just adds it to its list of known structures.

In fact, you can often use such a pointer without _ever_ declaring the structure at all. The structure may not even _exist_. It may be just a way to get type safety, and every time you want to actually use the pointer, you have to explicitly cast it to something else.

(Example: in <stdio.h> you can do

	typedef struct dummy_made_up_struct FILE;

and make sure that everybody ever uses a "FILE *f", and trying to create a "FILE f" would be a compile-time error, because that "struct dummy_made_up_struct" simply doesn't even exist, and all the real users will cast it to some internal thing)

The reason the "inside a parameter list" is special is that modern C (I think through some obscure C++ reason, but I'm not sure) considers the function parameter list to be inside function scope, and that includes the types, not just the parameter names.

So when you do

	extern function(struct hello *);

without (forward-)declaring "struch hello" earlier, then the compiler will still create a "struct hello" internally, but since the scope of that declaration is purely just that function prototype itself, it will be forgotten immediately afterwards, and a subsequent use of "struct hello" will be considered a _different_ "struct hello", since it's in different scope.

So you generally never need to forward-declare structures, unless you only then use them inside function prototypes. In which case you would just do

	struct hello;

to tell the compiler that you have a "struct hello" that you haven't actually declared yet, and now it's in scope _outside_ the function prototype, and everybody is happy and agrees that they are using the same "struct hello".

Linus

#10 lore raw

Re: [patch 1/2] m68k: runtime patching infrastructure

In reply to Andrew Morton

On Tue, May 29, 2007 at 05:38:18PM -0700, Andrew Morton wrote:
[...]

Quoted 5 lines

include/asm-m68k/module.h line 6

Quoted 3 lines
include/asm-m68k/module.h +3 -0
+struct mod_arch_specific {
+	struct m68k_fixup_info *fixup_start, *fixup_end;
+};

Here we use struct m68k_fixup_info.

[...]

Quoted 8 lines

include/asm-m68k/module.h line 25

Quoted 4 lines
include/asm-m68k/module.h +4 -0
+struct m68k_fixup_info {
+	enum m68k_fixup_type type;
+	void *addr;
+};

and later we define it.

How come it doesn't spit warnings?

Because otherwise you couldn't create linked lists:

struct foo {
void* data;
struct foo* next;
};

At that point it hasn't been defined yet but it is being used. This is legal, so the compiler can't create a warning for that.

Which is not to say that it's a nice coding style, but that's a different matter.

Signature · 3 lines
Shaw's Principle:
	Build a system that even a fool can use, and only a fool will
	want to use it.
author maintainer
#11 lore raw

PATCH 2/2 m68k: Discontinuous memory support

In reply to Geert Uytterhoeven

From: Roman Zippel <[email protected]>

Fix support for discontinuous memory

---
 arch/m68k/Kconfig                   |   13 +++
 arch/m68k/kernel/module.c           |    3 
 arch/m68k/kernel/setup.c            |   37 ++---------
 arch/m68k/mm/init.c                 |  119 +++++++++++++++++++++++-------------
 arch/m68k/mm/memory.c               |   73 ----------------------
 arch/m68k/mm/motorola.c             |  101 ++++++++++++++++++++----------
 arch/m68k/sun3/config.c             |    2 
 include/asm-m68k/mmzone.h           |    9 ++
 include/asm-m68k/module.h           |    1 
 include/asm-m68k/motorola_pgtable.h |   10 +--
 include/asm-m68k/page.h             |   52 ++++++++++++---
 include/asm-m68k/pgalloc.h          |    3 
 include/asm-m68k/pgtable.h          |   17 -----
 include/asm-m68k/sun3_pgtable.h     |    4 -
 include/asm-m68k/virtconvert.h      |   48 +++-----------
 mm/page_alloc.c                     |    2 
 16 files changed, 246 insertions(+), 248 deletions(-)
arch/m68k/Kconfig +11 -2
@@ -355,8 +355,9 @@ config RMW_INSNS
 	  adventurous.
 
 config SINGLE_MEMORY_CHUNK
-	bool "Use one physical chunk of memory only"
-	depends on ADVANCED && !SUN3
+	bool "Use one physical chunk of memory only" if ADVANCED && !SUN3
+	default y if SUN3
+	select NEED_MULTIPLE_NODES
 	help
 	  Ignore all but the first contiguous chunk of physical memory for VM
 	  purposes.  This will save a few bytes kernel size and may speed up
@@ -377,6 +378,14 @@ config 060_WRITETHROUGH
 	  is hardwired on.  The 53c710 SCSI driver is known to suffer from
 	  this problem.
 
+config ARCH_DISCONTIGMEM_ENABLE
+	def_bool !SINGLE_MEMORY_CHUNK
+
+config NODES_SHIFT
+	int
+	default "3"
+	depends on !SINGLE_MEMORY_CHUNK
+
 source "mm/Kconfig"
 
 endmenu
arch/m68k/kernel/module.c +3 -0
@@ -149,6 +149,9 @@ void module_fixup(struct module *mod, st
 		case m68k_fixup_memoffset:
 			*(u32 *)fixup->addr = m68k_memoffset;
 			break;
+		case m68k_fixup_vnode_shift:
+			*(u16 *)fixup->addr += m68k_virt_to_node_shift;
+			break;
 		}
 	}
 }
arch/m68k/kernel/setup.c +8 -29
@@ -60,14 +60,12 @@ extern unsigned long availmem;
 int m68k_num_memory;
 int m68k_realnum_memory;
 EXPORT_SYMBOL(m68k_realnum_memory);
-#ifdef CONFIG_SINGLE_MEMORY_CHUNK
 unsigned long m68k_memoffset;
 EXPORT_SYMBOL(m68k_memoffset);
-#endif
 struct mem_info m68k_memory[NUM_MEMINFO];
 EXPORT_SYMBOL(m68k_memory);
 
-static struct mem_info m68k_ramdisk;
+struct mem_info m68k_ramdisk;
 
 static char m68k_command_line[CL_SIZE];
 
@@ -208,9 +206,6 @@ static void __init m68k_parse_bootinfo(c
 void __init setup_arch(char **cmdline_p)
 {
 	extern int _etext, _edata, _end;
-#ifndef CONFIG_SUN3
-	unsigned long endmem, startmem;
-#endif
 	int i;
 
 	/* The bootinfo is located right after the kernel bss */
@@ -320,30 +315,16 @@ void __init setup_arch(char **cmdline_p)
 		panic("No configuration setup");
 	}
 
-#ifndef CONFIG_SUN3
-	startmem= m68k_memory[0].addr;
-	endmem = startmem + m68k_memory[0].size;
-	high_memory = (void *)PAGE_OFFSET;
-	for (i = 0; i < m68k_num_memory; i++) {
-		m68k_memory[i].size &= MASK_256K;
-		if (m68k_memory[i].addr < startmem)
-			startmem = m68k_memory[i].addr;
-		if (m68k_memory[i].addr+m68k_memory[i].size > endmem)
-			endmem = m68k_memory[i].addr+m68k_memory[i].size;
-		high_memory += m68k_memory[i].size;
-	}
-
-	availmem += init_bootmem_node(NODE_DATA(0), availmem >> PAGE_SHIFT,
-				      startmem >> PAGE_SHIFT, endmem >> PAGE_SHIFT);
-
-	for (i = 0; i < m68k_num_memory; i++)
-		free_bootmem(m68k_memory[i].addr, m68k_memory[i].size);
-
-	reserve_bootmem(m68k_memory[0].addr, availmem - m68k_memory[0].addr);
+	paging_init();
 
+#ifndef CONFIG_SUN3
+	for (i = 1; i < m68k_num_memory; i++)
+		free_bootmem_node(NODE_DATA(i), m68k_memory[i].addr,
+				  m68k_memory[i].size);
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (m68k_ramdisk.size) {
-		reserve_bootmem(m68k_ramdisk.addr, m68k_ramdisk.size);
+		reserve_bootmem_node(__virt_to_node(phys_to_virt(m68k_ramdisk.addr)),
+				     m68k_ramdisk.addr, m68k_ramdisk.size);
 		initrd_start = (unsigned long)phys_to_virt(m68k_ramdisk.addr);
 		initrd_end = initrd_start + m68k_ramdisk.size;
 		printk("initrd: %08lx - %08lx\n", initrd_start, initrd_end);
@@ -362,8 +343,6 @@ void __init setup_arch(char **cmdline_p)
 
 #endif /* !CONFIG_SUN3 */
 
-	paging_init();
-
 /* set ISA defs early as possible */
 #if defined(CONFIG_ISA) && defined(MULTI_ISA)
 #if defined(CONFIG_Q40)
arch/m68k/mm/init.c +78 -41

168 lines not on this page · raw message

arch/m68k/mm/memory.c +0 -73

82 lines not on this page · raw message

arch/m68k/mm/motorola.c +69 -32

158 lines not on this page · raw message

arch/m68k/sun3/config.c +2 -0
@@ -21,6 +21,7 @@
 #include <asm/contregs.h>
 #include <asm/movs.h>
 #include <asm/pgtable.h>
+#include <asm/pgalloc.h>
 #include <asm/sun3-head.h>
 #include <asm/sun3mmu.h>
 #include <asm/rtc.h>
@@ -127,6 +128,7 @@ void __init sun3_bootmem_alloc(unsigned 
 	high_memory = (void *)memory_end;
 	availmem = memory_start;
 
+	m68k_setup_node(0);
 	availmem += init_bootmem_node(NODE_DATA(0), start_page, 0, num_pages);
 	availmem = (availmem + (PAGE_SIZE-1)) & PAGE_MASK;
 
include/asm-m68k/mmzone.h new file +9 -0
@@ -0,0 +1,9 @@
+#ifndef _ASM_M68K_MMZONE_H_
+#define _ASM_M68K_MMZONE_H_
+
+extern pg_data_t pg_data_map[];
+
+#define NODE_DATA(nid)		(&pg_data_map[nid])
+#define NODE_MEM_MAP(nid)	(NODE_DATA(nid)->node_mem_map)
+
+#endif /* _ASM_M68K_MMZONE_H_ */
include/asm-m68k/module.h +1 -0
@@ -17,6 +17,7 @@ struct mod_arch_specific {
 
 enum m68k_fixup_type {
 	m68k_fixup_memoffset,
+	m68k_fixup_vnode_shift,
 };
 
 struct m68k_fixup_info {
include/asm-m68k/motorola_pgtable.h +5 -5
@@ -130,7 +130,7 @@ static inline void pgd_set(pgd_t *pgdp, 
 #define pte_present(pte)	(pte_val(pte) & (_PAGE_PRESENT | _PAGE_PROTNONE))
 #define pte_clear(mm,addr,ptep)		({ pte_val(*(ptep)) = 0; })
 
-#define pte_page(pte)		(mem_map + ((unsigned long)(__va(pte_val(pte)) - PAGE_OFFSET) >> PAGE_SHIFT))
+#define pte_page(pte)		virt_to_page(__va(pte_val(pte)))
 #define pte_pfn(pte)		(pte_val(pte) >> PAGE_SHIFT)
 #define pfn_pte(pfn, prot)	__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
 
@@ -143,7 +143,7 @@ static inline void pgd_set(pgd_t *pgdp, 
 	while (--__i >= 0)			\
 		*__ptr++ = 0;			\
 })
-#define pmd_page(pmd)		(mem_map + ((unsigned long)(__va(pmd_val(pmd)) - PAGE_OFFSET) >> PAGE_SHIFT))
+#define pmd_page(pmd)		virt_to_page(__va(pmd_val(pmd)))
 
 
 #define pgd_none(pgd)		(!pgd_val(pgd))
@@ -223,10 +223,10 @@ static inline pte_t *pte_offset_kernel(p
 	return (pte_t *)__pmd_page(*pmdp) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
 }
 
-#define pte_offset_map(pmdp,address) ((pte_t *)kmap(pmd_page(*pmdp)) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)))
+#define pte_offset_map(pmdp,address) ((pte_t *)__pmd_page(*pmdp) + (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)))
 #define pte_offset_map_nested(pmdp, address) pte_offset_map(pmdp, address)
-#define pte_unmap(pte) kunmap(pte)
-#define pte_unmap_nested(pte) kunmap(pte)
+#define pte_unmap(pte)		((void)0)
+#define pte_unmap_nested(pte)	((void)0)
 
 /*
  * Allocate and free page tables. The xxx_kernel() versions are
include/asm-m68k/page.h +41 -11

77 lines not on this page · raw message

include/asm-m68k/pgalloc.h +2 -1
@@ -8,11 +8,12 @@
 #include <asm/virtconvert.h>
 
 
-
 #ifdef CONFIG_SUN3
 #include <asm/sun3_pgalloc.h>
 #else
 #include <asm/motorola_pgalloc.h>
 #endif
 
+extern void m68k_setup_node(int node);
+
 #endif /* M68K_PGALLOC_H */
include/asm-m68k/pgtable.h +1 -16
@@ -107,22 +107,7 @@ extern void *empty_zero_page;
 /* 64-bit machines, beware!  SRB. */
 #define SIZEOF_PTR_LOG2			       2
 
-/*
- * Check if the addr/len goes up to the end of a physical
- * memory chunk.  Used for DMA functions.
- */
-#ifdef CONFIG_SINGLE_MEMORY_CHUNK
-/*
- * It makes no sense to consider whether we cross a memory boundary if
- * we support just one physical chunk of memory.
- */
-static inline int mm_end_of_chunk(unsigned long addr, int len)
-{
-	return 0;
-}
-#else
-int mm_end_of_chunk (unsigned long addr, int len);
-#endif
+#define mm_end_of_chunk(addr, len)	0
 
 extern void kernel_set_cachemode(void *addr, unsigned long size, int cmode);
 
include/asm-m68k/sun3_pgtable.h +2 -2
@@ -132,8 +132,8 @@ static inline void pte_clear (struct mm_
 #define pfn_pte(pfn, pgprot) \
 ({ pte_t __pte; pte_val(__pte) = pfn | pgprot_val(pgprot); __pte; })
 
-#define pte_page(pte)		(mem_map+((__pte_page(pte) - PAGE_OFFSET) >> PAGE_SHIFT))
-#define pmd_page(pmd)		(mem_map+((__pmd_page(pmd) - PAGE_OFFSET) >> PAGE_SHIFT))
+#define pte_page(pte)		virt_to_page(__pte_page(pte))
+#define pmd_page(pmd)		virt_to_page(__pmd_page(pmd))
 
 
 static inline int pmd_none2 (pmd_t *pmd) { return !pmd_val (*pmd); }
include/asm-m68k/virtconvert.h +13 -35

69 lines not on this page · raw message

mm/page_alloc.c +1 -1
@@ -2689,7 +2689,7 @@ static void __init_refok alloc_node_mem_
 			map = alloc_bootmem_node(pgdat, size);
 		pgdat->node_mem_map = map + (pgdat->node_start_pfn - start);
 	}
-#ifdef CONFIG_FLATMEM
+#ifndef CONFIG_NEED_MULTIPLE_NODES
 	/*
 	 * With no DISCONTIG, the global mem_map is just set as node 0's
 	 */
Signature · 10 lines
Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
							    -- Linus Torvalds
maintainer
#12 lore raw

Re: [patch 2/2] m68k: Discontinuous memory support

arch/m68k/mm/init.c void *empty_zero_page; · line 92

Quoted 10 lines · On Mon, 28 May 2007 21:16:32 +0200 Geert Uytterhoeven <[email protected]>…
arch/m68k/mm/init.c +10 -0
+	for_each_online_pgdat(pgdat) {
+		for (i = 0; i < pgdat->node_spanned_pages; i++) {
+			struct page *page = pgdat->node_mem_map + i;
+			total++;
+			if (PageReserved(page))
+				reserved++;
+			else if (PageSwapCache(page))
+				cached++;
+			else if (!page_count(page))
+				free++;

This isn't really true. Callers of the page allocator don't _have_ to use page_count(): they can internally perform their own refcounting. One such caller is slab, so this "free" count can end up being grossly wrong.

Quoted 3 lines
arch/m68k/mm/init.c +3 -0
+			else
+				shared += page_count(page) - 1;
+		}
maintainer
#13 lore raw

Re: [patch 2/2] m68k: Discontinuous memory support

In reply to Geert Uytterhoeven

include/asm-m68k/virtconvert.h line 38

Quoted 12 lines · On Mon, 28 May 2007 21:16:32 +0200 Geert Uytterhoeven <[email protected]>…
include/asm-m68k/virtconvert.h +10 -2
-#define __page_address(page)	(PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))
-#define page_to_phys(page)	virt_to_phys((void *)__page_address(page))
+#ifdef CONFIG_SINGLE_MEMORY_CHUNK
+#define page_to_phys(page) \
+	__pa(PAGE_OFFSET + (((page) - pg_data_map[0].node_mem_map) << PAGE_SHIFT))
+#else
+#define page_to_phys(page) ({						\
+	struct pglist_data *pgdat;					\
+	pgdat = pg_data_table[page_to_nid(page)];			\
+	page_to_pfn(page) << PAGE_SHIFT;				\
+})
+#endif

macros which evaluate their args more than once are dangerous.