aboutsummaryrefslogtreecommitdiffstats
path: root/arch/unicore32/kernel
diff options
context:
space:
mode:
authorGuanXuetao <gxt@mprc.pku.edu.cn>2011-01-15 05:13:50 -0500
committerGuanXuetao <gxt@mprc.pku.edu.cn>2011-03-16 21:19:05 -0400
commit87c1a3fb7c07322dfd63a63dd6d42339ad52ddee (patch)
treec090cce270aa4ca455bbfadb975f35f3eb01ccab /arch/unicore32/kernel
parent790edb61c0d87d1f1daafcaaa8f7c66b7b82bdad (diff)
unicore32 core architecture: generic elf and ksyms stuff
This patch includes some generic stuff including elf and ksyms. Because all one-line asm-generic headers are auto-generated by ASM_GENERIC_HEADERS in arch/unicore32/Makefile, so the rest seems very little. ELF handling functions and module handling functions are also here. Signed-off-by: Guan Xuetao <gxt@mprc.pku.edu.cn> Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch/unicore32/kernel')
-rw-r--r--arch/unicore32/kernel/asm-offsets.c112
-rw-r--r--arch/unicore32/kernel/elf.c38
-rw-r--r--arch/unicore32/kernel/ksyms.c99
-rw-r--r--arch/unicore32/kernel/ksyms.h15
-rw-r--r--arch/unicore32/kernel/module.c152
5 files changed, 416 insertions, 0 deletions
diff --git a/arch/unicore32/kernel/asm-offsets.c b/arch/unicore32/kernel/asm-offsets.c
new file mode 100644
index 00000000000..ffcbe7536ca
--- /dev/null
+++ b/arch/unicore32/kernel/asm-offsets.c
@@ -0,0 +1,112 @@
1/*
2 * linux/arch/unicore32/kernel/asm-offsets.c
3 *
4 * Code specific to PKUnity SoC and UniCore ISA
5 *
6 * Copyright (C) 2001-2010 GUAN Xue-tao
7 *
8 * Generate definitions needed by assembly language modules.
9 * This code generates raw asm output which is post-processed to extract
10 * and format the required data.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16#include <linux/sched.h>
17#include <linux/mm.h>
18#include <linux/dma-mapping.h>
19#include <linux/kbuild.h>
20#include <linux/suspend.h>
21#include <linux/thread_info.h>
22#include <asm/memory.h>
23#include <asm/suspend.h>
24
25/*
26 * GCC 3.0, 3.1: general bad code generation.
27 * GCC 3.2.0: incorrect function argument offset calculation.
28 * GCC 3.2.x: miscompiles NEW_AUX_ENT in fs/binfmt_elf.c
29 * (http://gcc.gnu.org/PR8896) and incorrect structure
30 * initialisation in fs/jffs2/erase.c
31 */
32#if (__GNUC__ < 4)
33#error Your compiler should upgrade to uc4
34#error Known good compilers: 4.2.2
35#endif
36
37int main(void)
38{
39 DEFINE(TSK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
40 BLANK();
41 DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
42 DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
43 DEFINE(TI_ADDR_LIMIT, offsetof(struct thread_info, addr_limit));
44 DEFINE(TI_TASK, offsetof(struct thread_info, task));
45 DEFINE(TI_EXEC_DOMAIN, offsetof(struct thread_info, exec_domain));
46 DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
47 DEFINE(TI_CPU_SAVE, offsetof(struct thread_info, cpu_context));
48 DEFINE(TI_USED_CP, offsetof(struct thread_info, used_cp));
49#ifdef CONFIG_UNICORE_FPU_F64
50 DEFINE(TI_FPSTATE, offsetof(struct thread_info, fpstate));
51#endif
52 BLANK();
53 DEFINE(S_R0, offsetof(struct pt_regs, UCreg_00));
54 DEFINE(S_R1, offsetof(struct pt_regs, UCreg_01));
55 DEFINE(S_R2, offsetof(struct pt_regs, UCreg_02));
56 DEFINE(S_R3, offsetof(struct pt_regs, UCreg_03));
57 DEFINE(S_R4, offsetof(struct pt_regs, UCreg_04));
58 DEFINE(S_R5, offsetof(struct pt_regs, UCreg_05));
59 DEFINE(S_R6, offsetof(struct pt_regs, UCreg_06));
60 DEFINE(S_R7, offsetof(struct pt_regs, UCreg_07));
61 DEFINE(S_R8, offsetof(struct pt_regs, UCreg_08));
62 DEFINE(S_R9, offsetof(struct pt_regs, UCreg_09));
63 DEFINE(S_R10, offsetof(struct pt_regs, UCreg_10));
64 DEFINE(S_R11, offsetof(struct pt_regs, UCreg_11));
65 DEFINE(S_R12, offsetof(struct pt_regs, UCreg_12));
66 DEFINE(S_R13, offsetof(struct pt_regs, UCreg_13));
67 DEFINE(S_R14, offsetof(struct pt_regs, UCreg_14));
68 DEFINE(S_R15, offsetof(struct pt_regs, UCreg_15));
69 DEFINE(S_R16, offsetof(struct pt_regs, UCreg_16));
70 DEFINE(S_R17, offsetof(struct pt_regs, UCreg_17));
71 DEFINE(S_R18, offsetof(struct pt_regs, UCreg_18));
72 DEFINE(S_R19, offsetof(struct pt_regs, UCreg_19));
73 DEFINE(S_R20, offsetof(struct pt_regs, UCreg_20));
74 DEFINE(S_R21, offsetof(struct pt_regs, UCreg_21));
75 DEFINE(S_R22, offsetof(struct pt_regs, UCreg_22));
76 DEFINE(S_R23, offsetof(struct pt_regs, UCreg_23));
77 DEFINE(S_R24, offsetof(struct pt_regs, UCreg_24));
78 DEFINE(S_R25, offsetof(struct pt_regs, UCreg_25));
79 DEFINE(S_R26, offsetof(struct pt_regs, UCreg_26));
80 DEFINE(S_FP, offsetof(struct pt_regs, UCreg_fp));
81 DEFINE(S_IP, offsetof(struct pt_regs, UCreg_ip));
82 DEFINE(S_SP, offsetof(struct pt_regs, UCreg_sp));
83 DEFINE(S_LR, offsetof(struct pt_regs, UCreg_lr));
84 DEFINE(S_PC, offsetof(struct pt_regs, UCreg_pc));
85 DEFINE(S_PSR, offsetof(struct pt_regs, UCreg_asr));
86 DEFINE(S_OLD_R0, offsetof(struct pt_regs, UCreg_ORIG_00));
87 DEFINE(S_FRAME_SIZE, sizeof(struct pt_regs));
88 BLANK();
89 DEFINE(VMA_VM_MM, offsetof(struct vm_area_struct, vm_mm));
90 DEFINE(VMA_VM_FLAGS, offsetof(struct vm_area_struct, vm_flags));
91 BLANK();
92 DEFINE(VM_EXEC, VM_EXEC);
93 BLANK();
94 DEFINE(PAGE_SZ, PAGE_SIZE);
95 BLANK();
96 DEFINE(SYS_ERROR0, 0x9f0000);
97 BLANK();
98 DEFINE(PBE_ADDRESS, offsetof(struct pbe, address));
99 DEFINE(PBE_ORIN_ADDRESS, offsetof(struct pbe, orig_address));
100 DEFINE(PBE_NEXT, offsetof(struct pbe, next));
101 DEFINE(SWSUSP_CPU, offsetof(struct swsusp_arch_regs, \
102 cpu_context));
103#ifdef CONFIG_UNICORE_FPU_F64
104 DEFINE(SWSUSP_FPSTATE, offsetof(struct swsusp_arch_regs, \
105 fpstate));
106#endif
107 BLANK();
108 DEFINE(DMA_BIDIRECTIONAL, DMA_BIDIRECTIONAL);
109 DEFINE(DMA_TO_DEVICE, DMA_TO_DEVICE);
110 DEFINE(DMA_FROM_DEVICE, DMA_FROM_DEVICE);
111 return 0;
112}
diff --git a/arch/unicore32/kernel/elf.c b/arch/unicore32/kernel/elf.c
new file mode 100644
index 00000000000..0a176734fef
--- /dev/null
+++ b/arch/unicore32/kernel/elf.c
@@ -0,0 +1,38 @@
1/*
2 * linux/arch/unicore32/kernel/elf.c
3 *
4 * Code specific to PKUnity SoC and UniCore ISA
5 *
6 * Copyright (C) 2001-2010 GUAN Xue-tao
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12#include <linux/module.h>
13#include <linux/sched.h>
14#include <linux/personality.h>
15#include <linux/binfmts.h>
16#include <linux/elf.h>
17
18int elf_check_arch(const struct elf32_hdr *x)
19{
20 /* Make sure it's an UniCore executable */
21 if (x->e_machine != EM_UNICORE)
22 return 0;
23
24 /* Make sure the entry address is reasonable */
25 if (x->e_entry & 3)
26 return 0;
27
28 return 1;
29}
30EXPORT_SYMBOL(elf_check_arch);
31
32void elf_set_personality(const struct elf32_hdr *x)
33{
34 unsigned int personality = PER_LINUX;
35
36 set_personality(personality);
37}
38EXPORT_SYMBOL(elf_set_personality);
diff --git a/arch/unicore32/kernel/ksyms.c b/arch/unicore32/kernel/ksyms.c
new file mode 100644
index 00000000000..a8970809428
--- /dev/null
+++ b/arch/unicore32/kernel/ksyms.c
@@ -0,0 +1,99 @@
1/*
2 * linux/arch/unicore32/kernel/ksyms.c
3 *
4 * Code specific to PKUnity SoC and UniCore ISA
5 *
6 * Copyright (C) 2001-2010 GUAN Xue-tao
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12#include <linux/module.h>
13#include <linux/sched.h>
14#include <linux/string.h>
15#include <linux/cryptohash.h>
16#include <linux/delay.h>
17#include <linux/in6.h>
18#include <linux/syscalls.h>
19#include <linux/uaccess.h>
20#include <linux/io.h>
21
22#include <asm/checksum.h>
23#include <asm/system.h>
24
25#include "ksyms.h"
26
27EXPORT_SYMBOL(__uc32_find_next_zero_bit);
28EXPORT_SYMBOL(__uc32_find_next_bit);
29
30EXPORT_SYMBOL(__backtrace);
31
32 /* platform dependent support */
33EXPORT_SYMBOL(__udelay);
34EXPORT_SYMBOL(__const_udelay);
35
36 /* networking */
37EXPORT_SYMBOL(csum_partial);
38EXPORT_SYMBOL(csum_partial_copy_from_user);
39EXPORT_SYMBOL(csum_partial_copy_nocheck);
40EXPORT_SYMBOL(__csum_ipv6_magic);
41
42 /* io */
43#ifndef __raw_readsb
44EXPORT_SYMBOL(__raw_readsb);
45#endif
46#ifndef __raw_readsw
47EXPORT_SYMBOL(__raw_readsw);
48#endif
49#ifndef __raw_readsl
50EXPORT_SYMBOL(__raw_readsl);
51#endif
52#ifndef __raw_writesb
53EXPORT_SYMBOL(__raw_writesb);
54#endif
55#ifndef __raw_writesw
56EXPORT_SYMBOL(__raw_writesw);
57#endif
58#ifndef __raw_writesl
59EXPORT_SYMBOL(__raw_writesl);
60#endif
61
62 /* string / mem functions */
63EXPORT_SYMBOL(strchr);
64EXPORT_SYMBOL(strrchr);
65EXPORT_SYMBOL(memset);
66EXPORT_SYMBOL(memcpy);
67EXPORT_SYMBOL(memmove);
68EXPORT_SYMBOL(memchr);
69
70 /* user mem (segment) */
71EXPORT_SYMBOL(__strnlen_user);
72EXPORT_SYMBOL(__strncpy_from_user);
73
74EXPORT_SYMBOL(copy_page);
75
76EXPORT_SYMBOL(__copy_from_user);
77EXPORT_SYMBOL(__copy_to_user);
78EXPORT_SYMBOL(__clear_user);
79
80EXPORT_SYMBOL(__get_user_1);
81EXPORT_SYMBOL(__get_user_2);
82EXPORT_SYMBOL(__get_user_4);
83
84EXPORT_SYMBOL(__put_user_1);
85EXPORT_SYMBOL(__put_user_2);
86EXPORT_SYMBOL(__put_user_4);
87EXPORT_SYMBOL(__put_user_8);
88
89EXPORT_SYMBOL(__ashldi3);
90EXPORT_SYMBOL(__ashrdi3);
91EXPORT_SYMBOL(__divsi3);
92EXPORT_SYMBOL(__lshrdi3);
93EXPORT_SYMBOL(__modsi3);
94EXPORT_SYMBOL(__muldi3);
95EXPORT_SYMBOL(__ucmpdi2);
96EXPORT_SYMBOL(__udivsi3);
97EXPORT_SYMBOL(__umodsi3);
98EXPORT_SYMBOL(__bswapsi2);
99
diff --git a/arch/unicore32/kernel/ksyms.h b/arch/unicore32/kernel/ksyms.h
new file mode 100644
index 00000000000..185cdc712d0
--- /dev/null
+++ b/arch/unicore32/kernel/ksyms.h
@@ -0,0 +1,15 @@
1/*
2 * libgcc functions - functions that are used internally by the
3 * compiler... (prototypes are not correct though, but that
4 * doesn't really matter since they're not versioned).
5 */
6extern void __ashldi3(void);
7extern void __ashrdi3(void);
8extern void __divsi3(void);
9extern void __lshrdi3(void);
10extern void __modsi3(void);
11extern void __muldi3(void);
12extern void __ucmpdi2(void);
13extern void __udivsi3(void);
14extern void __umodsi3(void);
15extern void __bswapsi2(void);
diff --git a/arch/unicore32/kernel/module.c b/arch/unicore32/kernel/module.c
new file mode 100644
index 00000000000..3e5a38d71a1
--- /dev/null
+++ b/arch/unicore32/kernel/module.c
@@ -0,0 +1,152 @@
1/*
2 * linux/arch/unicore32/kernel/module.c
3 *
4 * Code specific to PKUnity SoC and UniCore ISA
5 *
6 * Copyright (C) 2001-2010 GUAN Xue-tao
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12#include <linux/module.h>
13#include <linux/moduleloader.h>
14#include <linux/kernel.h>
15#include <linux/mm.h>
16#include <linux/elf.h>
17#include <linux/vmalloc.h>
18#include <linux/fs.h>
19#include <linux/string.h>
20#include <linux/gfp.h>
21
22#include <asm/pgtable.h>
23#include <asm/sections.h>
24
25void *module_alloc(unsigned long size)
26{
27 struct vm_struct *area;
28
29 size = PAGE_ALIGN(size);
30 if (!size)
31 return NULL;
32
33 area = __get_vm_area(size, VM_ALLOC, MODULES_VADDR, MODULES_END);
34 if (!area)
35 return NULL;
36
37 return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC);
38}
39
40void module_free(struct module *module, void *region)
41{
42 vfree(region);
43}
44
45int module_frob_arch_sections(Elf_Ehdr *hdr,
46 Elf_Shdr *sechdrs,
47 char *secstrings,
48 struct module *mod)
49{
50 return 0;
51}
52
53int
54apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
55 unsigned int relindex, struct module *module)
56{
57 Elf32_Shdr *symsec = sechdrs + symindex;
58 Elf32_Shdr *relsec = sechdrs + relindex;
59 Elf32_Shdr *dstsec = sechdrs + relsec->sh_info;
60 Elf32_Rel *rel = (void *)relsec->sh_addr;
61 unsigned int i;
62
63 for (i = 0; i < relsec->sh_size / sizeof(Elf32_Rel); i++, rel++) {
64 unsigned long loc;
65 Elf32_Sym *sym;
66 s32 offset;
67
68 offset = ELF32_R_SYM(rel->r_info);
69 if (offset < 0 || offset >
70 (symsec->sh_size / sizeof(Elf32_Sym))) {
71 printk(KERN_ERR "%s: bad relocation, "
72 "section %d reloc %d\n",
73 module->name, relindex, i);
74 return -ENOEXEC;
75 }
76
77 sym = ((Elf32_Sym *)symsec->sh_addr) + offset;
78
79 if (rel->r_offset < 0 || rel->r_offset >
80 dstsec->sh_size - sizeof(u32)) {
81 printk(KERN_ERR "%s: out of bounds relocation, "
82 "section %d reloc %d offset %d size %d\n",
83 module->name, relindex, i, rel->r_offset,
84 dstsec->sh_size);
85 return -ENOEXEC;
86 }
87
88 loc = dstsec->sh_addr + rel->r_offset;
89
90 switch (ELF32_R_TYPE(rel->r_info)) {
91 case R_UNICORE_NONE:
92 /* ignore */
93 break;
94
95 case R_UNICORE_ABS32:
96 *(u32 *)loc += sym->st_value;
97 break;
98
99 case R_UNICORE_PC24:
100 case R_UNICORE_CALL:
101 case R_UNICORE_JUMP24:
102 offset = (*(u32 *)loc & 0x00ffffff) << 2;
103 if (offset & 0x02000000)
104 offset -= 0x04000000;
105
106 offset += sym->st_value - loc;
107 if (offset & 3 ||
108 offset <= (s32)0xfe000000 ||
109 offset >= (s32)0x02000000) {
110 printk(KERN_ERR
111 "%s: relocation out of range, section "
112 "%d reloc %d sym '%s'\n", module->name,
113 relindex, i, strtab + sym->st_name);
114 return -ENOEXEC;
115 }
116
117 offset >>= 2;
118
119 *(u32 *)loc &= 0xff000000;
120 *(u32 *)loc |= offset & 0x00ffffff;
121 break;
122
123 default:
124 printk(KERN_ERR "%s: unknown relocation: %u\n",
125 module->name, ELF32_R_TYPE(rel->r_info));
126 return -ENOEXEC;
127 }
128 }
129 return 0;
130}
131
132int
133apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab,
134 unsigned int symindex, unsigned int relsec,
135 struct module *module)
136{
137 printk(KERN_ERR "module %s: ADD RELOCATION unsupported\n",
138 module->name);
139 return -ENOEXEC;
140}
141
142int
143module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs,
144 struct module *module)
145{
146 return 0;
147}
148
149void
150module_arch_cleanup(struct module *mod)
151{
152}