diff options
author | Roman Zippel <zippel@linux-m68k.org> | 2007-05-31 03:40:50 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-31 10:58:13 -0400 |
commit | fbe9c9612930e0604dc99ef2da7e063fa3278817 (patch) | |
tree | b11a5a03edd4a61fc5c71b2b38402cdfe914de22 /include | |
parent | 1fc799e1b4efdbc405d87d9f154d64d9bc299e5c (diff) |
m68k: runtime patching infrastructure
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.
Signed-off-by: Roman Zippel <zippel@linux-m68k.org>
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include')
-rw-r--r-- | include/asm-m68k/module.h | 33 | ||||
-rw-r--r-- | include/asm-m68k/page.h | 29 |
2 files changed, 58 insertions, 4 deletions
diff --git a/include/asm-m68k/module.h b/include/asm-m68k/module.h index c6d75af2d8d3..71a1f76ac891 100644 --- a/include/asm-m68k/module.h +++ b/include/asm-m68k/module.h | |||
@@ -1,7 +1,38 @@ | |||
1 | #ifndef _ASM_M68K_MODULE_H | 1 | #ifndef _ASM_M68K_MODULE_H |
2 | #define _ASM_M68K_MODULE_H | 2 | #define _ASM_M68K_MODULE_H |
3 | struct mod_arch_specific { }; | 3 | |
4 | struct mod_arch_specific { | ||
5 | struct m68k_fixup_info *fixup_start, *fixup_end; | ||
6 | }; | ||
7 | |||
8 | #define MODULE_ARCH_INIT { \ | ||
9 | .fixup_start = __start_fixup, \ | ||
10 | .fixup_end = __stop_fixup, \ | ||
11 | } | ||
12 | |||
4 | #define Elf_Shdr Elf32_Shdr | 13 | #define Elf_Shdr Elf32_Shdr |
5 | #define Elf_Sym Elf32_Sym | 14 | #define Elf_Sym Elf32_Sym |
6 | #define Elf_Ehdr Elf32_Ehdr | 15 | #define Elf_Ehdr Elf32_Ehdr |
16 | |||
17 | |||
18 | enum m68k_fixup_type { | ||
19 | m68k_fixup_memoffset, | ||
20 | }; | ||
21 | |||
22 | struct m68k_fixup_info { | ||
23 | enum m68k_fixup_type type; | ||
24 | void *addr; | ||
25 | }; | ||
26 | |||
27 | #define m68k_fixup(type, addr) \ | ||
28 | " .section \".m68k_fixup\",\"aw\"\n" \ | ||
29 | " .long " #type "," #addr "\n" \ | ||
30 | " .previous\n" | ||
31 | |||
32 | extern struct m68k_fixup_info __start_fixup[], __stop_fixup[]; | ||
33 | |||
34 | struct module; | ||
35 | extern void module_fixup(struct module *mod, struct m68k_fixup_info *start, | ||
36 | struct m68k_fixup_info *end); | ||
37 | |||
7 | #endif /* _ASM_M68K_MODULE_H */ | 38 | #endif /* _ASM_M68K_MODULE_H */ |
diff --git a/include/asm-m68k/page.h b/include/asm-m68k/page.h index fcc165ddd09e..7650b99dcae6 100644 --- a/include/asm-m68k/page.h +++ b/include/asm-m68k/page.h | |||
@@ -27,6 +27,8 @@ | |||
27 | 27 | ||
28 | #ifndef __ASSEMBLY__ | 28 | #ifndef __ASSEMBLY__ |
29 | 29 | ||
30 | #include <asm/module.h> | ||
31 | |||
30 | #define get_user_page(vaddr) __get_free_page(GFP_KERNEL) | 32 | #define get_user_page(vaddr) __get_free_page(GFP_KERNEL) |
31 | #define free_user_page(page, addr) free_page(addr) | 33 | #define free_user_page(page, addr) free_page(addr) |
32 | 34 | ||
@@ -114,14 +116,35 @@ typedef struct { unsigned long pgprot; } pgprot_t; | |||
114 | 116 | ||
115 | #ifndef __ASSEMBLY__ | 117 | #ifndef __ASSEMBLY__ |
116 | 118 | ||
119 | extern unsigned long m68k_memoffset; | ||
120 | |||
117 | #ifndef CONFIG_SUN3 | 121 | #ifndef CONFIG_SUN3 |
118 | 122 | ||
119 | #define WANT_PAGE_VIRTUAL | 123 | #define WANT_PAGE_VIRTUAL |
120 | #ifdef CONFIG_SINGLE_MEMORY_CHUNK | 124 | #ifdef CONFIG_SINGLE_MEMORY_CHUNK |
121 | extern unsigned long m68k_memoffset; | ||
122 | 125 | ||
123 | #define __pa(vaddr) ((unsigned long)(vaddr)+m68k_memoffset) | 126 | static inline unsigned long ___pa(void *vaddr) |
124 | #define __va(paddr) ((void *)((unsigned long)(paddr)-m68k_memoffset)) | 127 | { |
128 | unsigned long paddr; | ||
129 | asm ( | ||
130 | "1: addl #0,%0\n" | ||
131 | m68k_fixup(%c2, 1b+2) | ||
132 | : "=r" (paddr) | ||
133 | : "0" (vaddr), "i" (m68k_fixup_memoffset)); | ||
134 | return paddr; | ||
135 | } | ||
136 | #define __pa(vaddr) ___pa((void *)(vaddr)) | ||
137 | static inline void *__va(unsigned long paddr) | ||
138 | { | ||
139 | void *vaddr; | ||
140 | asm ( | ||
141 | "1: subl #0,%0\n" | ||
142 | m68k_fixup(%c2, 1b+2) | ||
143 | : "=r" (vaddr) | ||
144 | : "0" (paddr), "i" (m68k_fixup_memoffset)); | ||
145 | return vaddr; | ||
146 | } | ||
147 | |||
125 | #else | 148 | #else |
126 | #define __pa(vaddr) virt_to_phys((void *)(vaddr)) | 149 | #define __pa(vaddr) virt_to_phys((void *)(vaddr)) |
127 | #define __va(paddr) phys_to_virt((unsigned long)(paddr)) | 150 | #define __va(paddr) phys_to_virt((unsigned long)(paddr)) |