aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mn10300/kernel/module.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2008-02-08 07:19:31 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-08 12:22:30 -0500
commitb920de1b77b72ca9432ac3f97edb26541e65e5dd (patch)
tree40fa9be1470e929c47927dea7eddf184c0204229 /arch/mn10300/kernel/module.c
parentef3d534754f31fed9c3b976fee1ece1b3bc38282 (diff)
mn10300: add the MN10300/AM33 architecture to the kernel
Add architecture support for the MN10300/AM33 CPUs produced by MEI to the kernel. This patch also adds board support for the ASB2303 with the ASB2308 daughter board, and the ASB2305. The only processor supported is the MN103E010, which is an AM33v2 core plus on-chip devices. [akpm@linux-foundation.org: nuke cvs control strings] Signed-off-by: Masakazu Urade <urade.masakazu@jp.panasonic.com> Signed-off-by: Koichi Yasutake <yasutake.koichi@jp.panasonic.com> Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/mn10300/kernel/module.c')
-rw-r--r--arch/mn10300/kernel/module.c206
1 files changed, 206 insertions, 0 deletions
diff --git a/arch/mn10300/kernel/module.c b/arch/mn10300/kernel/module.c
new file mode 100644
index 000000000000..0e4d2f6fa6e8
--- /dev/null
+++ b/arch/mn10300/kernel/module.c
@@ -0,0 +1,206 @@
1/* MN10300 Kernel module helper routines
2 *
3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4 * Written by Mark Salter (msalter@redhat.com)
5 * - Derived from arch/i386/kernel/module.c
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public Licence as published by
9 * the Free Software Foundation; either version 2 of the Licence, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public Licence for more details.
16 *
17 * You should have received a copy of the GNU General Public Licence
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21#include <linux/moduleloader.h>
22#include <linux/elf.h>
23#include <linux/vmalloc.h>
24#include <linux/fs.h>
25#include <linux/string.h>
26#include <linux/kernel.h>
27
28#if 0
29#define DEBUGP printk
30#else
31#define DEBUGP(fmt, ...)
32#endif
33
34/*
35 * allocate storage for a module
36 */
37void *module_alloc(unsigned long size)
38{
39 if (size == 0)
40 return NULL;
41 return vmalloc_exec(size);
42}
43
44/*
45 * free memory returned from module_alloc()
46 */
47void module_free(struct module *mod, void *module_region)
48{
49 vfree(module_region);
50 /* FIXME: If module_region == mod->init_region, trim exception
51 * table entries. */
52}
53
54/*
55 * allow the arch to fix up the section table
56 * - we don't need anything special
57 */
58int module_frob_arch_sections(Elf_Ehdr *hdr,
59 Elf_Shdr *sechdrs,
60 char *secstrings,
61 struct module *mod)
62{
63 return 0;
64}
65
66static uint32_t reloc_get16(uint8_t *p)
67{
68 return p[0] | (p[1] << 8);
69}
70
71static uint32_t reloc_get24(uint8_t *p)
72{
73 return reloc_get16(p) | (p[2] << 16);
74}
75
76static uint32_t reloc_get32(uint8_t *p)
77{
78 return reloc_get16(p) | (reloc_get16(p+2) << 16);
79}
80
81static void reloc_put16(uint8_t *p, uint32_t val)
82{
83 p[0] = val & 0xff;
84 p[1] = (val >> 8) & 0xff;
85}
86
87static void reloc_put24(uint8_t *p, uint32_t val)
88{
89 reloc_put16(p, val);
90 p[2] = (val >> 16) & 0xff;
91}
92
93static void reloc_put32(uint8_t *p, uint32_t val)
94{
95 reloc_put16(p, val);
96 reloc_put16(p+2, val >> 16);
97}
98
99/*
100 * apply a REL relocation
101 */
102int apply_relocate(Elf32_Shdr *sechdrs,
103 const char *strtab,
104 unsigned int symindex,
105 unsigned int relsec,
106 struct module *me)
107{
108 printk(KERN_ERR "module %s: RELOCATION unsupported\n",
109 me->name);
110 return -ENOEXEC;
111}
112
113/*
114 * apply a RELA relocation
115 */
116int apply_relocate_add(Elf32_Shdr *sechdrs,
117 const char *strtab,
118 unsigned int symindex,
119 unsigned int relsec,
120 struct module *me)
121{
122 unsigned int i;
123 Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr;
124 Elf32_Sym *sym;
125 Elf32_Addr relocation;
126 uint8_t *location;
127 uint32_t value;
128
129 DEBUGP("Applying relocate section %u to %u\n",
130 relsec, sechdrs[relsec].sh_info);
131
132 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
133 /* this is where to make the change */
134 location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
135 + rel[i].r_offset;
136
137 /* this is the symbol the relocation is referring to (note that
138 * all undefined symbols have been resolved by the caller) */
139 sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
140 + ELF32_R_SYM(rel[i].r_info);
141
142 /* this is the adjustment to be made */
143 relocation = sym->st_value + rel[i].r_addend;
144
145 switch (ELF32_R_TYPE(rel[i].r_info)) {
146 /* for the first four relocation types, we add the
147 * adjustment into the value at the location given */
148 case R_MN10300_32:
149 value = reloc_get32(location);
150 value += relocation;
151 reloc_put32(location, value);
152 break;
153 case R_MN10300_24:
154 value = reloc_get24(location);
155 value += relocation;
156 reloc_put24(location, value);
157 break;
158 case R_MN10300_16:
159 value = reloc_get16(location);
160 value += relocation;
161 reloc_put16(location, value);
162 break;
163 case R_MN10300_8:
164 *location += relocation;
165 break;
166
167 /* for the next three relocation types, we write the
168 * adjustment with the address subtracted over the
169 * value at the location given */
170 case R_MN10300_PCREL32:
171 value = relocation - (uint32_t) location;
172 reloc_put32(location, value);
173 break;
174 case R_MN10300_PCREL16:
175 value = relocation - (uint32_t) location;
176 reloc_put16(location, value);
177 break;
178 case R_MN10300_PCREL8:
179 *location = relocation - (uint32_t) location;
180 break;
181
182 default:
183 printk(KERN_ERR "module %s: Unknown relocation: %u\n",
184 me->name, ELF32_R_TYPE(rel[i].r_info));
185 return -ENOEXEC;
186 }
187 }
188 return 0;
189}
190
191/*
192 * finish loading the module
193 */
194int module_finalize(const Elf_Ehdr *hdr,
195 const Elf_Shdr *sechdrs,
196 struct module *me)
197{
198 return 0;
199}
200
201/*
202 * finish clearing the module
203 */
204void module_arch_cleanup(struct module *mod)
205{
206}