A few more m68k patches
Subsystems (4)
Geert Uytterhoeven
maintainercover 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
Geert Uytterhoeven
maintainerPATCH 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 *sechdint 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 TorvaldsAndrew Morton
maintainerRe: [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);
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_Ehdrinclude/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 :)
Geert Uytterhoeven
maintainerRe: [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_Ehdrinclude/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
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."
Re: [patch 1/2] m68k: runtime patching infrastructure
In reply to Geert UytterhoevenOn 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
Geert Uytterhoeven
maintainerRe: [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
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
Re: [patch 1/2] m68k: runtime patching infrastructure
In reply to Geert UytterhoevenQuoted 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
Re: [patch 1/2] m68k: runtime patching infrastructure
In reply to Andrew MortonOn 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.
Geert Uytterhoeven
maintainerPATCH 2/2 m68k: Discontinuous memory support
In reply to Geert UytterhoevenFrom: 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, stcase 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(cvoid __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(preturn (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) 0extern 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 TorvaldsAndrew Morton
maintainerRe: [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 ; + }
Andrew Morton
maintainerRe: [patch 2/2] m68k: Discontinuous memory support
In reply to Geert Uytterhoeveninclude/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.