Author: neel
Date: Thu Feb 18 05:49:52 2010
New Revision: 204031
URL: http://svn.freebsd.org/changeset/base/204031

Log:
  Kernel module support for mips.
  
  Reviewed by: gonzo
  
  Tested by: Alexandr Rybalko (r...@dlink.ua)

Modified:
  head/share/mk/bsd.cpu.mk
  head/sys/conf/files.mips
  head/sys/conf/kmod.mk
  head/sys/kern/link_elf_obj.c
  head/sys/mips/mips/elf_machdep.c

Modified: head/share/mk/bsd.cpu.mk
==============================================================================
--- head/share/mk/bsd.cpu.mk    Thu Feb 18 05:14:36 2010        (r204030)
+++ head/share/mk/bsd.cpu.mk    Thu Feb 18 05:49:52 2010        (r204031)
@@ -203,11 +203,9 @@ LD += -EB
 .if ${MACHINE_ARCH} == "mips" 
 . if defined(TARGET_BIG_ENDIAN)
 CFLAGS += -EB
-LDFLAGS += -Wl,-EB
 LD += -EB
 . else
 CFLAGS += -EL
-LDFLAGS += -Wl,-EL
 LD += -EL
 . endif
 CFLAGS += -msoft-float -G0 -mno-dsp -mabicalls

Modified: head/sys/conf/files.mips
==============================================================================
--- head/sys/conf/files.mips    Thu Feb 18 05:14:36 2010        (r204030)
+++ head/sys/conf/files.mips    Thu Feb 18 05:49:52 2010        (r204031)
@@ -89,6 +89,8 @@ libkern/umoddi3.c             optional        isa_mips32
 #libkern/mips/strcmp.S         standard
 #libkern/mips/strncmp.S                standard
 
+kern/link_elf_obj.c            standard
+
 dev/cfe/cfe_api.c              optional        cfe
 dev/cfe/cfe_console.c          optional        cfe_console
 dev/cfe/cfe_env.c              optional        cfe_env

Modified: head/sys/conf/kmod.mk
==============================================================================
--- head/sys/conf/kmod.mk       Thu Feb 18 05:14:36 2010        (r204030)
+++ head/sys/conf/kmod.mk       Thu Feb 18 05:49:52 2010        (r204031)
@@ -128,6 +128,10 @@ CFLAGS+=   -fno-omit-frame-pointer
 CFLAGS+=       -mlongcall -fno-omit-frame-pointer
 .endif
 
+.if ${MACHINE_ARCH} == "mips"
+CFLAGS+=       -G0 -fno-pic -mno-abicalls -mlong-calls
+.endif
+
 .if defined(FIRMWS)
 .if !exists(@)
 ${KMOD:S/$/.c/}: @
@@ -174,7 +178,7 @@ ${PROG}.symbols: ${FULLPROG}
        ${OBJCOPY} --only-keep-debug ${FULLPROG} ${.TARGET}
 .endif
 
-.if ${MACHINE_ARCH} != amd64
+.if ${MACHINE_ARCH} != amd64 && ${MACHINE_ARCH} != mips
 ${FULLPROG}: ${KMOD}.kld
        ${LD} -Bshareable ${LDFLAGS} -o ${.TARGET} ${KMOD}.kld
 .if !defined(DEBUG_FLAGS)
@@ -187,7 +191,7 @@ EXPORT_SYMS?=       NO
 CLEANFILES+=   export_syms
 .endif
 
-.if ${MACHINE_ARCH} != amd64
+.if ${MACHINE_ARCH} != amd64 && ${MACHINE_ARCH} != mips
 ${KMOD}.kld: ${OBJS}
 .else
 ${FULLPROG}: ${OBJS}
@@ -206,7 +210,8 @@ ${FULLPROG}: ${OBJS}
            export_syms | xargs -J% ${OBJCOPY} % ${.TARGET}
 .endif
 .endif
-.if !defined(DEBUG_FLAGS) && ${MACHINE_ARCH} == amd64
+.if !defined(DEBUG_FLAGS) && \
+    (${MACHINE_ARCH} == amd64 || ${MACHINE_ARCH} == mips)
        ${OBJCOPY} --strip-debug ${.TARGET}
 .endif
 

Modified: head/sys/kern/link_elf_obj.c
==============================================================================
--- head/sys/kern/link_elf_obj.c        Thu Feb 18 05:14:36 2010        
(r204030)
+++ head/sys/kern/link_elf_obj.c        Thu Feb 18 05:49:52 2010        
(r204031)
@@ -853,8 +853,8 @@ link_elf_load_file(linker_class_t cls, c
                panic("lost relatab");
        if (mapbase != (vm_offset_t)ef->address + mapsize)
                panic("mapbase 0x%lx != address %p + mapsize 0x%lx (0x%lx)\n",
-                   mapbase, ef->address, mapsize,
-                   (vm_offset_t)ef->address + mapsize);
+                   (u_long)mapbase, ef->address, (u_long)mapsize,
+                   (u_long)(vm_offset_t)ef->address + mapsize);
 
        /* Local intra-module relocations */
        link_elf_reloc_local(lf);

Modified: head/sys/mips/mips/elf_machdep.c
==============================================================================
--- head/sys/mips/mips/elf_machdep.c    Thu Feb 18 05:14:36 2010        
(r204030)
+++ head/sys/mips/mips/elf_machdep.c    Thu Feb 18 05:49:52 2010        
(r204031)
@@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
 
 #include <machine/elf.h>
 #include <machine/md_var.h>
+#include <machine/cache.h>
 
 #ifdef __mips_n64
 struct sysentvec elf64_freebsd_sysvec = {
@@ -163,7 +164,12 @@ elf_reloc_internal(linker_file_t lf, Elf
        Elf_Addr addend = (Elf_Addr)0;
        Elf_Word rtype = (Elf_Word)0, symidx;
        const Elf_Rel *rel;
-       const Elf_Rela *rela;
+
+       /*
+        * Stash R_MIPS_HI16 info so we can use it when processing R_MIPS_LO16
+        */
+       static Elf_Addr ahl;
+       static Elf_Addr *where_hi16;
 
        switch (type) {
        case ELF_RELOC_REL:
@@ -173,108 +179,63 @@ elf_reloc_internal(linker_file_t lf, Elf
                rtype = ELF_R_TYPE(rel->r_info);
                symidx = ELF_R_SYM(rel->r_info);
                break;
-       case ELF_RELOC_RELA:
-               rela = (const Elf_Rela *)data;
-               where = (Elf_Addr *) (relocbase + rela->r_offset);
-               addend = rela->r_addend;
-               rtype = ELF_R_TYPE(rela->r_info);
-               symidx = ELF_R_SYM(rela->r_info);
-               break;
        default:
                panic("unknown reloc type %d\n", type);
        }
 
-       if (local) {
-#if 0 /* TBD  */
-               if (rtype == R_386_RELATIVE) {  /* A + B */
-                       addr = elf_relocaddr(lf, relocbase + addend);
-                       if (*where != addr)
-                               *where = addr;
-               }
-               return (0);
-#endif
-       }
-
        switch (rtype) {
+       case R_MIPS_NONE:       /* none */
+               break;
 
-               case R_MIPS_NONE:       /* none */
-                       break;
+       case R_MIPS_32:         /* S + A */
+               addr = lookup(lf, symidx, 1);
+               if (addr == 0)
+                       return (-1);
+               addr += addend;
+               if (*where != addr)
+                       *where = addr;
+               break;
 
-               case R_MIPS_16:     /* S + sign-extend(A) */
-                       /*
-                        * There shouldn't be R_MIPS_16 relocs in kernel 
objects.
-                        */
-                       printf("kldload: unexpected R_MIPS_16 relocation\n");
-                       return -1;
-                       break;
-
-               case R_MIPS_32: /* S + A - P */
-                       addr = lookup(lf, symidx, 1);
-                       if (addr == 0)
-                               return -1;
-                       addr += addend;
-                       if (*where != addr)
-                               *where = addr;
-                       break;
-
-               case R_MIPS_REL32:              /* A - EA + S */
-                       /*
-                        * There shouldn't be R_MIPS_REL32 relocs in kernel 
objects?
-                        */
-                       printf("kldload: unexpected R_MIPS_REL32 relocation\n");
-                       return -1;
-                       break;
-
-               case R_MIPS_26:      /* ((A << 2) | (P & 0xf0000000) + S) >> 2 
*/
-                       break;
-
-               case R_MIPS_HI16:
-                       /* extern/local: ((AHL + S) - ((short)(AHL + S)) >> 16 
*/
-                       /* _gp_disp: ((AHL + GP - P) - (short)(AHL + GP - P)) 
>> 16 */
-                       break;
-
-               case R_MIPS_LO16:
-                       /* extern/local: AHL + S */
-                       /* _gp_disp: AHL + GP - P + 4 */
-                       break;
-
-               case R_MIPS_GPREL16:
-                       /* extern/local: ((AHL + S) - ((short)(AHL + S)) >> 16 
*/
-                       /* _gp_disp: ((AHL + GP - P) - (short)(AHL + GP - P)) 
>> 16 */
-                       break;
-
-               case R_MIPS_LITERAL: /* sign-extend(A) + L */
-                       break;
-
-               case R_MIPS_GOT16: /* external: G */
-                       /* local: tbd */
-                       break;
-
-               case R_MIPS_PC16: /* sign-extend(A) + S - P */
-                       break;
-
-               case R_MIPS_CALL16: /* G */
-                       break;
-
-               case R_MIPS_GPREL32: /* A + S + GP0 - GP */
-                       break;
-
-               case R_MIPS_GOTHI16: /* (G - (short)G) >> 16 + A */
-                       break;
-
-               case R_MIPS_GOTLO16: /* G & 0xffff */
-                       break;
-
-               case R_MIPS_CALLHI16: /* (G - (short)G) >> 16 + A */
-                       break;
-
-               case R_MIPS_CALLLO16: /* G & 0xffff */
-                       break;
-
-               default:
-                       printf("kldload: unexpected relocation type %d\n",
-                           rtype);
+       case R_MIPS_26:         /* ((A << 2) | (P & 0xf0000000) + S) >> 2 */
+               addr = lookup(lf, symidx, 1);
+               if (addr == 0)
                        return (-1);
+
+               addend &= 0x03ffffff;
+               addend <<= 2;
+
+               addr += ((Elf_Addr)where & 0xf0000000) | addend;
+               addr >>= 2;
+
+               *where &= ~0x03ffffff;
+               *where |= addr & 0x03ffffff;
+               break;
+
+       case R_MIPS_HI16:       /* ((AHL + S) - ((short)(AHL + S)) >> 16 */
+               ahl = addend << 16;
+               where_hi16 = where;
+               break;
+
+       case R_MIPS_LO16:       /* AHL + S */
+               ahl += (int16_t)addend;
+               addr = lookup(lf, symidx, 1);
+               if (addr == 0)
+                       return (-1);
+
+               addend &= 0xffff0000;
+               addend |= (uint16_t)(ahl + addr);
+               *where = addend;
+
+               addend = *where_hi16;
+               addend &= 0xffff0000;
+               addend |= ((ahl + addr) - (int16_t)(ahl + addr)) >> 16;
+               *where_hi16 = addend;
+               break;
+
+       default:
+               printf("kldload: unexpected relocation type %d\n",
+                       rtype);
+               return (-1);
        }
        return(0);
 }
@@ -299,6 +260,11 @@ int
 elf_cpu_load_file(linker_file_t lf __unused)
 {
 
+       /*
+        * Sync the I and D caches to make sure our relocations are visible.
+        */
+       mips_icache_sync_all();
+
        return (0);
 }
 
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to