Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 18 Feb 2010 05:49:53 +0000 (UTC)
From:      Neel Natu <neel@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r204031 - in head: share/mk sys/conf sys/kern sys/mips/mips
Message-ID:  <201002180549.o1I5nruS072838@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 (ray@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);
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201002180549.o1I5nruS072838>