From 400bce45a8532b2377c5692da80666196ce09c64 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Wed, 24 Jul 2013 15:49:29 +0800 Subject: LM32 Support Signed-off-by: Peng Fan --- libbsd/include/arch/lm32/machine/ansi.h | 0 libbsd/include/arch/lm32/machine/asm.h | 2 + libbsd/include/arch/lm32/machine/cdefs.h | 0 libbsd/include/arch/lm32/machine/elf_machdep.h | 34 +++++++ libbsd/include/arch/lm32/machine/int_types.h | 0 libbsd/include/sys/exec_elf.h | 2 + rtl-mdreloc-lm32.c | 120 +++++++++++++++++++++++++ testcase/1.c | 22 +++++ testcase/Readme | 7 ++ testcase/wscript | 11 +++ wscript | 2 +- 11 files changed, 199 insertions(+), 1 deletion(-) create mode 100644 libbsd/include/arch/lm32/machine/ansi.h create mode 100644 libbsd/include/arch/lm32/machine/asm.h create mode 100644 libbsd/include/arch/lm32/machine/cdefs.h create mode 100644 libbsd/include/arch/lm32/machine/elf_machdep.h create mode 100644 libbsd/include/arch/lm32/machine/int_types.h create mode 100644 rtl-mdreloc-lm32.c 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 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 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 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 + +#include +#include +#include +#include + +#include +#include "rtl-elf.h" +#include "rtl-error.h" +#include + +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, -- cgit v1.2.3