summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeng Fan <van.freenix@gmail.com>2013-07-24 15:49:29 +0800
committerPeng Fan <van.freenix@gmail.com>2013-09-05 13:47:39 +0800
commit400bce45a8532b2377c5692da80666196ce09c64 (patch)
tree950266e0af9ba23ed722bc8ba2996ff71d9a2b08
parent42d16f6d37130a3550b537d35698977f06908234 (diff)
LM32 Support
Signed-off-by: Peng Fan <van.freenix@gmail.com>
-rw-r--r--libbsd/include/arch/lm32/machine/ansi.h0
-rw-r--r--libbsd/include/arch/lm32/machine/asm.h2
-rw-r--r--libbsd/include/arch/lm32/machine/cdefs.h0
-rw-r--r--libbsd/include/arch/lm32/machine/elf_machdep.h34
-rw-r--r--libbsd/include/arch/lm32/machine/int_types.h0
-rw-r--r--libbsd/include/sys/exec_elf.h2
-rw-r--r--rtl-mdreloc-lm32.c120
-rw-r--r--testcase/1.c22
-rw-r--r--testcase/Readme7
-rw-r--r--testcase/wscript11
-rw-r--r--wscript2
11 files changed, 199 insertions, 1 deletions
diff --git a/libbsd/include/arch/lm32/machine/ansi.h b/libbsd/include/arch/lm32/machine/ansi.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libbsd/include/arch/lm32/machine/ansi.h
diff --git a/libbsd/include/arch/lm32/machine/asm.h b/libbsd/include/arch/lm32/machine/asm.h
new file mode 100644
index 0000000..b3a7a95
--- /dev/null
+++ b/libbsd/include/arch/lm32/machine/asm.h
@@ -0,0 +1,2 @@
+
+#define __CONCAT(x,y) x ## y
diff --git a/libbsd/include/arch/lm32/machine/cdefs.h b/libbsd/include/arch/lm32/machine/cdefs.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libbsd/include/arch/lm32/machine/cdefs.h
diff --git a/libbsd/include/arch/lm32/machine/elf_machdep.h b/libbsd/include/arch/lm32/machine/elf_machdep.h
new file mode 100644
index 0000000..29c75b8
--- /dev/null
+++ b/libbsd/include/arch/lm32/machine/elf_machdep.h
@@ -0,0 +1,34 @@
+#define ELF32_MACHDEP_ENDIANNESS ELFDATA2MSB
+
+#define ELF32_MACHDEP_ID_CASES \
+ case EM_LATTICEMICO32: \
+ break;
+
+#define ELF32_MACHDEP_ID EM_LATTICEMICO32
+
+#define EF_MACH32_MACH 0x00000001
+
+//#define EF_BLACKFIN
+
+#define ARCH_ELFSIZE 32
+
+#define R_LM32_NONE 0
+#define R_LM32_8 1
+#define R_LM32_16 2
+#define R_LM32_32 3
+#define R_LM32_HI16 4
+#define R_LM32_LO16 5
+#define R_LM32_GPREL16 6
+#define R_LM32_CALL 7
+#define R_LM32_BRANCH 8
+#define R_LM32_GNU_VTINHERIT 9
+#define R_LM32_GNU_VTENTRY 10
+#define R_LM32_16_GOT 11
+#define R_LM32_GOTOFF_HI16 12
+#define R_LM32_GOTOFF_LO16 13
+#define R_LM32_COPY 14
+#define R_LM32_GLOT_DAT 15
+#define R_LM32_JMP_SLOT 16
+#define R_LM32_RELATIVE 17
+
+#define R_TYPE(name) __CONCAT(R_LM32_,name)
diff --git a/libbsd/include/arch/lm32/machine/int_types.h b/libbsd/include/arch/lm32/machine/int_types.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libbsd/include/arch/lm32/machine/int_types.h
diff --git a/libbsd/include/sys/exec_elf.h b/libbsd/include/sys/exec_elf.h
index 392cd33..19ca7f5 100644
--- a/libbsd/include/sys/exec_elf.h
+++ b/libbsd/include/sys/exec_elf.h
@@ -326,6 +326,8 @@ typedef struct {
#define EM_CE 119 /* Freescale Communication Engine RISC core */
#define EM_M32C 120 /* Renesas M32C series microprocessors */
+#define EM_LATTICEMICO32 138 /* RICS processor for Lattice FPGA architecture */
+
#define EM_MICROBLAZE 189 /* Xilinx MicroBlaze 32-bit RISC soft processor core */
/* Unofficial machine types follow */
diff --git a/rtl-mdreloc-lm32.c b/rtl-mdreloc-lm32.c
new file mode 100644
index 0000000..f6499df
--- /dev/null
+++ b/rtl-mdreloc-lm32.c
@@ -0,0 +1,120 @@
+#include <sys/cdefs.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <rtl.h>
+#include "rtl-elf.h"
+#include "rtl-error.h"
+#include <rtl-trace.h>
+
+bool
+rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
+{
+ return true;
+}
+
+bool
+rtems_rtl_elf_relocate_rela (const rtems_rtl_obj_t* obj,
+ const Elf_Rela* rela,
+ const rtems_rtl_obj_sect_t* sect,
+ const char* symname,
+ const Elf_Byte syminfo,
+ const Elf_Word symvalue)
+{
+ Elf_Addr *where;
+ Elf32_Word tmp;
+ Elf32_Word insn;
+
+
+ where = (Elf_Addr *)(sect->base + rela->r_offset);
+
+ switch (ELF_R_TYPE(rela->r_info)) {
+ case R_TYPE(NONE):
+ break;
+
+ case R_TYPE(HI16):
+ insn = *where;
+ /* orhi/mvhi instruction
+ * 31--------26|25-21|20-16|15----0|
+ * |0 1 1 1 1 0 |rY |rX |imm16 |
+ */
+ if (0x1e == (insn >> 26)) {
+ insn &= 0xffff0000;
+ insn |= ((symvalue + rela->r_addend) >> 16);
+ *where = insn;
+ }
+ break;
+
+ case R_TYPE(LO16):
+ insn = *where;
+ /* ori instruction
+ * 31--------26|25-21|20-16|15----0|
+ * |0 0 1 1 1 0 |rY |rX |imm16 |
+ */
+ if (0xe == (insn >> 26)) {
+ insn &= 0xffff0000;
+ insn |= ((symvalue + rela->r_addend) & 0xffff);
+ *where = insn;
+ }
+ break;
+
+ case R_TYPE(CALL):
+ insn = *where;
+ /*
+ * calli instruction
+ * 31-------26|25---0|
+ * |1 1 1 1 1 0|imm26 |
+ * Syntax: call imm26
+ * Operation: ra = pc + 4; pc = pc + sign_extend(imm26<<2)
+ */
+ if (0x3e == (insn >> 26)) {
+ Elf_Sword imm26 = symvalue +rela->r_addend - (Elf_Addr)where;
+ imm26 = (imm26 >> 2) & 0x3ffffff;
+ insn = 0xf8000000 + imm26;
+ *where = insn;
+ }
+ break;
+
+ case R_TYPE(BRANCH):
+ insn = *where;
+ tmp = symvalue + rela->r_addend - (Elf_Addr)where;
+ tmp = (Elf32_Sword)tmp >> 2;
+ if (((Elf32_Sword)tmp > 0x7fff) || ((Elf32_Sword)tmp < -0x8000)){
+ printf("BRANCH Overflow\n");
+ return false;
+ }
+
+ *where = (*where & 0xffff0000) | (tmp & 0xffff);
+ break;
+
+ case R_TYPE(32):
+ *where = symvalue + rela->r_addend;
+ break;
+
+ default:
+ rtems_rtl_set_error (EINVAL, "rela type record not supported");
+ printf("Unsupported reloc types\n");
+ return false;
+ }
+
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) {
+ printf("rela relocation type is %ld\n", ELF_R_TYPE(rela->r_info));
+ printf("relocated address 0x%08lx\n", (Elf_Addr)where);
+ }
+ return true;
+}
+
+bool
+rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj,
+ const Elf_Rel* rel,
+ const rtems_rtl_obj_sect_t* sect,
+ const char* symname,
+ const Elf_Byte syminfo,
+ const Elf_Word symvalue)
+{
+ rtems_rtl_set_error (EINVAL, "rela type record not supported");
+ return false;
+}
diff --git a/testcase/1.c b/testcase/1.c
index 14f6da2..a643d77 100644
--- a/testcase/1.c
+++ b/testcase/1.c
@@ -242,6 +242,28 @@ int rtems(int argc, char **argv)
"1:\n\t"
"nop\n\t"
);
+#elif defined (__lm32__)
+ __asm__ volatile (
+ "addi sp, sp, -16\n\t"
+ "sw (sp+8), r1\n\t"
+ "sw (sp+4), r0\n\t"
+ "mvhi r1, 1f\n\t"
+ "ori r1, r1, 1f\n\t"
+ "lw r1, (r1+0)\n\t"
+ "mvi r0, 22\n\t"
+ "sw (r1+0), r0\n\t"
+ "bi 2f\n\t"
+ "1:\n\t"
+ ".word global\n\t"
+ "2:\n\t"
+ "nop\n\t"
+ "lw r1, (sp+8)\n\t"
+ "lw r0, (sp+4)\n\t"
+ "addi sp, sp, 16\n\t" : : : "r0", "r1"
+ );
+
+ if (global == 22)
+ printf("R_LM32_32 pass\n");
#else
/* other archs */
#endif
diff --git a/testcase/Readme b/testcase/Readme
index c90ab71..7efb078 100644
--- a/testcase/Readme
+++ b/testcase/Readme
@@ -35,3 +35,10 @@ h8300:
Simulator:
h8sim -i build/h8300-rtems4.11-h8sim/rtld
+
+lm32:
+ configure --rtems=/opt/rtems-4.11 --rtems-tools=/opt/rtems-4.11 --rtems-archs=lm32 --rtems-bsps=lm32/lm32_evr
+
+ Simulator:
+ lm32_evr-gdb build/lm32-rtems4.11-lm32_evr/rtld
+ qemu-system-lm32 -M lm32-evr -nographic -global lm32,sys.enabled=1 -kernel build/lm32-rtems4.11-lm32_evr/rtld
diff --git a/testcase/wscript b/testcase/wscript
index 1a0d0c5..0a42011 100644
--- a/testcase/wscript
+++ b/testcase/wscript
@@ -85,6 +85,17 @@ def build(bld):
'--entry', '_my_main'],
source = ['1.c', '2.c'])
+ elif arch == 'lm32':
+ bld(target = 'test.rap',
+ features = 'c rap',
+ xxxx = 'hello',
+
+ cflags = '-fno-common',
+
+ rtems_linkflags = ['--base', 'rtld.prelink',
+ '--entry', 'my_main'],
+ source = ['1.c', '2.c'])
+
bld(target = '../test.rap',
source = ['test.rap'],
rule = 'cp ${SRC} ${TGT}')
diff --git a/wscript b/wscript
index 4e5974c..a2876f9 100644
--- a/wscript
+++ b/wscript
@@ -66,7 +66,7 @@ def build(bld):
#
# The ARM as special BSP initialise code.
#
- if arch == 'arm' or arch == 'powerpc' or arch == 'mips' or arch == 'bfin' or arch == 'h8300':
+ if arch == 'arm' or arch == 'powerpc' or arch == 'mips' or arch == 'bfin' or arch == 'h8300' or arch == 'lm32':
bld(target = 'bspinit',
features = 'c',
includes = bld.includes,