summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authordfr <dfr@FreeBSD.org>2001-09-13 12:39:15 +0000
committerdfr <dfr@FreeBSD.org>2001-09-13 12:39:15 +0000
commit7b40715e824711834ec0f89ba4f0881f57b4d53a (patch)
treeab02773c4b2a2195943d3ed2c2e6e839872dab3b /sys
parent5903e1d51b427659e37c7d4e10c090e5783f52da (diff)
downloadFreeBSD-src-7b40715e824711834ec0f89ba4f0881f57b4d53a.zip
FreeBSD-src-7b40715e824711834ec0f89ba4f0881f57b4d53a.tar.gz
* Enable dynamically linked kernel. This involves adding a self-relocator
to locore to process the @fptr relocations in the dynamic executable. * Don't initialise the timer until *after* we install the timecounter to avoid a race between timecounter initialisation and hardclock. * Tidy up bootinfo somewhat including adding sanity checks for when the kernel is loaded without a recognisable bootinfo.
Diffstat (limited to 'sys')
-rw-r--r--sys/conf/Makefile.ia642
-rw-r--r--sys/ia64/ia64/clock.c5
-rw-r--r--sys/ia64/ia64/genassym.c12
-rw-r--r--sys/ia64/ia64/locore.S132
-rw-r--r--sys/ia64/ia64/locore.s132
-rw-r--r--sys/ia64/ia64/machdep.c85
-rw-r--r--sys/ia64/include/bootinfo.h6
7 files changed, 300 insertions, 74 deletions
diff --git a/sys/conf/Makefile.ia64 b/sys/conf/Makefile.ia64
index 431ed93..30e4c6e 100644
--- a/sys/conf/Makefile.ia64
+++ b/sys/conf/Makefile.ia64
@@ -105,7 +105,7 @@ SYSTEM_CFILES= vnode_if.c hints.c env.c config.c
SYSTEM_SFILES= $S/$M/$M/locore.s
SYSTEM_DEP= Makefile ${SYSTEM_OBJS}
SYSTEM_OBJS= locore.o vnode_if.o ${OBJS} hints.o env.o config.o \
- # hack.So ski can't cope with dynamic relocs
+ hack.So
SYSTEM_LD= @${LD} ${FMT} -Bdynamic -T $S/conf/ldscript.$M \
-export-dynamic -dynamic-linker /red/herring \
-o ${.TARGET} -X ${SYSTEM_OBJS} vers.o
diff --git a/sys/ia64/ia64/clock.c b/sys/ia64/ia64/clock.c
index 0d686c5..fc3ad07 100644
--- a/sys/ia64/ia64/clock.c
+++ b/sys/ia64/ia64/clock.c
@@ -180,8 +180,6 @@ cpu_initclocks()
* XXX we should call SAL_FREQ_BASE_INTERVAL_TIMER here.
*/
cycles_per_sec = 70000000;
- ia64_set_itm(ia64_get_itc() + (cycles_per_sec + hz/2) / hz);
- ia64_set_itv(240); /* highest priority class */
freq = cycles_per_sec;
last_time = ia64_get_itc();
@@ -191,6 +189,9 @@ cpu_initclocks()
ia64_timecounter.tc_frequency = freq;
tc_init(&ia64_timecounter);
+ ia64_set_itm(ia64_get_itc() + (cycles_per_sec + hz/2) / hz);
+ ia64_set_itv(240); /* highest priority class */
+
stathz = 128;
}
diff --git a/sys/ia64/ia64/genassym.c b/sys/ia64/ia64/genassym.c
index 0984c87..e8084bf 100644
--- a/sys/ia64/ia64/genassym.c
+++ b/sys/ia64/ia64/genassym.c
@@ -52,6 +52,7 @@
#include <sys/ucontext.h>
#include <machine/frame.h>
#include <machine/mutex.h>
+#include <machine/elf.h>
#include <sys/vmmeter.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
@@ -139,3 +140,14 @@ ASSYM(KSTACK_PAGES, KSTACK_PAGES);
ASSYM(SIZEOF_TRAPFRAME, sizeof(struct trapframe));
ASSYM(SIZEOF_PCB, sizeof(struct pcb));
+
+ASSYM(DT_NULL, DT_NULL);
+ASSYM(DT_RELA, DT_RELA);
+ASSYM(DT_RELASZ, DT_RELASZ);
+ASSYM(DT_SYMTAB, DT_SYMTAB);
+ASSYM(DT_SYMENT, DT_SYMENT);
+ASSYM(DT_RELAENT, DT_RELAENT);
+ASSYM(R_IA64_NONE, R_IA64_NONE);
+ASSYM(R_IA64_DIR64LSB, R_IA64_DIR64LSB);
+ASSYM(R_IA64_FPTR64LSB, R_IA64_FPTR64LSB);
+ASSYM(R_IA64_REL64LSB, R_IA64_REL64LSB);
diff --git a/sys/ia64/ia64/locore.S b/sys/ia64/ia64/locore.S
index 55c0816..aaeb184 100644
--- a/sys/ia64/ia64/locore.S
+++ b/sys/ia64/ia64/locore.S
@@ -98,6 +98,12 @@ ENTRY(__start, 1)
;;
mov ar.rsc=3 // turn rse back on
;;
+ alloc r16=ar.pfs,0,0,1,0
+ ;;
+ movl out0=0 // we are linked at the right address
+ ;; // we just need to process fptrs
+ br.call.sptk.many rp=_reloc
+ ;;
br.call.sptk.many rp=ia64_init
/*
@@ -219,3 +225,129 @@ EXPORT(intrcnt)
.fill INTRCNT_COUNT + 1, 8, 0
EXPORT(eintrcnt)
.text
+
+ // in0: image base
+STATIC_ENTRY(_reloc, 1)
+ alloc loc0=ar.pfs,1,2,0,0
+ mov loc1=rp
+ ;;
+ movl r15=@gprel(_DYNAMIC) // find _DYNAMIC etc.
+ movl r2=@gprel(fptr_storage)
+ movl r3=@gprel(fptr_storage_end)
+ ;;
+ add r15=r15,gp // relocate _DYNAMIC etc.
+ add r2=r2,gp
+ add r3=r3,gp
+ ;;
+1: ld8 r16=[r15],8 // read r15->d_tag
+ ;;
+ ld8 r17=[r15],8 // and r15->d_val
+ ;;
+ cmp.eq p6,p0=DT_NULL,r16 // done?
+(p6) br.cond.dpnt.few 2f
+ ;;
+ cmp.eq p6,p0=DT_RELA,r16
+ ;;
+(p6) add r18=r17,in0 // found rela section
+ ;;
+ cmp.eq p6,p0=DT_RELASZ,r16
+ ;;
+(p6) mov r19=r17 // found rela size
+ ;;
+ cmp.eq p6,p0=DT_SYMTAB,r16
+ ;;
+(p6) add r20=r17,in0 // found symbol table
+ ;;
+(p6) setf.sig f8=r20
+ ;;
+ cmp.eq p6,p0=DT_SYMENT,r16
+ ;;
+(p6) setf.sig f9=r17 // found symbol entry size
+ ;;
+ cmp.eq p6,p0=DT_RELAENT,r16
+ ;;
+(p6) mov r22=r17 // found rela entry size
+ ;;
+ br.sptk.few 1b
+
+2:
+ ld8 r15=[r18],8 // read r_offset
+ ;;
+ ld8 r16=[r18],8 // read r_info
+ add r15=r15,in0 // relocate r_offset
+ ;;
+ ld8 r17=[r18],8 // read r_addend
+ sub r19=r19,r22 // update relasz
+
+ extr.u r23=r16,0,32 // ELF64_R_TYPE(r16)
+ ;;
+ cmp.eq p6,p0=R_IA64_NONE,r23
+(p6) br.cond.dpnt.few 3f
+ ;;
+ cmp.eq p6,p0=R_IA64_DIR64LSB,r23
+ ;;
+(p6) br.cond.dptk.few 4f
+ ;;
+ cmp.eq p6,p0=R_IA64_FPTR64LSB,r23
+ ;;
+(p6) br.cond.dptk.few 5f
+ ;;
+ cmp.eq p6,p0=R_IA64_REL64LSB,r23
+ ;;
+(p6) br.cond.dptk.few 4f
+ ;;
+
+3: cmp.ltu p6,p0=0,r19 // more?
+(p6) br.cond.dptk.few 2b // loop
+
+ mov r8=0 // success return value
+ ;;
+ br.cond.sptk.few 9f // done
+
+4:
+ ld8 r16=[r15] // read value
+ ;;
+ add r16=r16,in0 // relocate it
+ ;;
+ st8 [r15]=r16 // and store it back
+ br.cond.sptk.few 3b
+
+5:
+ extr.u r23=r16,32,32 // ELF64_R_SYM(r16)
+ ;;
+ setf.sig f10=r23 // so we can multiply
+ ;;
+ xma.lu f10=f10,f9,f8 // f10=symtab + r_sym*syment
+ ;;
+ getf.sig r16=f10
+ mov r8=1 // failure return value
+ ;;
+ cmp.geu p6,p0=r2,r3 // space left?
+(p6) br.cond.dpnt.few 9f // bail out
+
+ st8 [r15]=r2 // install fptr
+ add r16=8,r16 // address of st_value
+ ;;
+ ld8 r16=[r16] // read symbol value
+ ;;
+ add r16=r16,in0 // relocate symbol value
+ ;;
+ st8 [r2]=r16,8 // write fptr address
+ ;;
+ st8 [r2]=gp,8 // write fptr gp
+ br.cond.sptk.few 3b
+
+9:
+ mov ar.pfs=loc0
+ mov rp=loc1
+ ;;
+ br.ret.sptk.few rp
+
+END(_reloc)
+
+ .data
+ .align 16
+
+fptr_storage:
+ .space 4096*16 // XXX
+fptr_storage_end:
diff --git a/sys/ia64/ia64/locore.s b/sys/ia64/ia64/locore.s
index 55c0816..aaeb184 100644
--- a/sys/ia64/ia64/locore.s
+++ b/sys/ia64/ia64/locore.s
@@ -98,6 +98,12 @@ ENTRY(__start, 1)
;;
mov ar.rsc=3 // turn rse back on
;;
+ alloc r16=ar.pfs,0,0,1,0
+ ;;
+ movl out0=0 // we are linked at the right address
+ ;; // we just need to process fptrs
+ br.call.sptk.many rp=_reloc
+ ;;
br.call.sptk.many rp=ia64_init
/*
@@ -219,3 +225,129 @@ EXPORT(intrcnt)
.fill INTRCNT_COUNT + 1, 8, 0
EXPORT(eintrcnt)
.text
+
+ // in0: image base
+STATIC_ENTRY(_reloc, 1)
+ alloc loc0=ar.pfs,1,2,0,0
+ mov loc1=rp
+ ;;
+ movl r15=@gprel(_DYNAMIC) // find _DYNAMIC etc.
+ movl r2=@gprel(fptr_storage)
+ movl r3=@gprel(fptr_storage_end)
+ ;;
+ add r15=r15,gp // relocate _DYNAMIC etc.
+ add r2=r2,gp
+ add r3=r3,gp
+ ;;
+1: ld8 r16=[r15],8 // read r15->d_tag
+ ;;
+ ld8 r17=[r15],8 // and r15->d_val
+ ;;
+ cmp.eq p6,p0=DT_NULL,r16 // done?
+(p6) br.cond.dpnt.few 2f
+ ;;
+ cmp.eq p6,p0=DT_RELA,r16
+ ;;
+(p6) add r18=r17,in0 // found rela section
+ ;;
+ cmp.eq p6,p0=DT_RELASZ,r16
+ ;;
+(p6) mov r19=r17 // found rela size
+ ;;
+ cmp.eq p6,p0=DT_SYMTAB,r16
+ ;;
+(p6) add r20=r17,in0 // found symbol table
+ ;;
+(p6) setf.sig f8=r20
+ ;;
+ cmp.eq p6,p0=DT_SYMENT,r16
+ ;;
+(p6) setf.sig f9=r17 // found symbol entry size
+ ;;
+ cmp.eq p6,p0=DT_RELAENT,r16
+ ;;
+(p6) mov r22=r17 // found rela entry size
+ ;;
+ br.sptk.few 1b
+
+2:
+ ld8 r15=[r18],8 // read r_offset
+ ;;
+ ld8 r16=[r18],8 // read r_info
+ add r15=r15,in0 // relocate r_offset
+ ;;
+ ld8 r17=[r18],8 // read r_addend
+ sub r19=r19,r22 // update relasz
+
+ extr.u r23=r16,0,32 // ELF64_R_TYPE(r16)
+ ;;
+ cmp.eq p6,p0=R_IA64_NONE,r23
+(p6) br.cond.dpnt.few 3f
+ ;;
+ cmp.eq p6,p0=R_IA64_DIR64LSB,r23
+ ;;
+(p6) br.cond.dptk.few 4f
+ ;;
+ cmp.eq p6,p0=R_IA64_FPTR64LSB,r23
+ ;;
+(p6) br.cond.dptk.few 5f
+ ;;
+ cmp.eq p6,p0=R_IA64_REL64LSB,r23
+ ;;
+(p6) br.cond.dptk.few 4f
+ ;;
+
+3: cmp.ltu p6,p0=0,r19 // more?
+(p6) br.cond.dptk.few 2b // loop
+
+ mov r8=0 // success return value
+ ;;
+ br.cond.sptk.few 9f // done
+
+4:
+ ld8 r16=[r15] // read value
+ ;;
+ add r16=r16,in0 // relocate it
+ ;;
+ st8 [r15]=r16 // and store it back
+ br.cond.sptk.few 3b
+
+5:
+ extr.u r23=r16,32,32 // ELF64_R_SYM(r16)
+ ;;
+ setf.sig f10=r23 // so we can multiply
+ ;;
+ xma.lu f10=f10,f9,f8 // f10=symtab + r_sym*syment
+ ;;
+ getf.sig r16=f10
+ mov r8=1 // failure return value
+ ;;
+ cmp.geu p6,p0=r2,r3 // space left?
+(p6) br.cond.dpnt.few 9f // bail out
+
+ st8 [r15]=r2 // install fptr
+ add r16=8,r16 // address of st_value
+ ;;
+ ld8 r16=[r16] // read symbol value
+ ;;
+ add r16=r16,in0 // relocate symbol value
+ ;;
+ st8 [r2]=r16,8 // write fptr address
+ ;;
+ st8 [r2]=gp,8 // write fptr gp
+ br.cond.sptk.few 3b
+
+9:
+ mov ar.pfs=loc0
+ mov rp=loc1
+ ;;
+ br.ret.sptk.few rp
+
+END(_reloc)
+
+ .data
+ .align 16
+
+fptr_storage:
+ .space 4096*16 // XXX
+fptr_storage_end:
diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c
index e5af476..a956acf 100644
--- a/sys/ia64/ia64/machdep.c
+++ b/sys/ia64/ia64/machdep.c
@@ -387,16 +387,23 @@ ia64_init()
/* OUTPUT NOW ALLOWED */
/*
+ * Gross and disgusting hack. The bootinfo is written into
+ * memory at a fixed address.
+ */
+ bootinfo = *(struct bootinfo *) 0xe000000000508000;
+ if (bootinfo.bi_magic != BOOTINFO_MAGIC
+ || bootinfo.bi_version != 1) {
+ bzero(&bootinfo, sizeof(bootinfo));
+ bootinfo.bi_kernend = (vm_offset_t) round_page(_end);
+ }
+
+ /*
* Find the beginning and end of the kernel.
*/
kernstart = trunc_page(kernel_text);
-#ifdef DDBxx
ksym_start = (void *)bootinfo.bi_symtab;
ksym_end = (void *)bootinfo.bi_esymtab;
kernend = (vm_offset_t)round_page(ksym_end);
-#else
- kernend = (vm_offset_t)round_page(_end);
-#endif
/* But if the bootstrap tells us otherwise, believe it! */
if (bootinfo.bi_kernend)
kernend = round_page(bootinfo.bi_kernend);
@@ -606,74 +613,10 @@ ia64_init()
/*
* Look at arguments passed to us and compute boothowto.
*/
- boothowto = 0;
+ boothowto = bootinfo.bi_boothowto;
#ifdef KADB
boothowto |= RB_KDB;
#endif
-/* boothowto |= RB_KDB | RB_GDB; */
- for (p = bootinfo.bi_flags; p && *p != '\0'; p++) {
- /*
- * Note that we'd really like to differentiate case here,
- * but the Ia64 AXP Architecture Reference Manual
- * says that we shouldn't.
- */
- switch (*p) {
- case 'a': /* autoboot */
- case 'A':
- boothowto &= ~RB_SINGLE;
- break;
-
-#ifdef DEBUG
- case 'c': /* crash dump immediately after autoconfig */
- case 'C':
- boothowto |= RB_DUMP;
- break;
-#endif
-
-#if defined(DDB)
- case 'd': /* break into the kernel debugger ASAP */
- case 'D':
- boothowto |= RB_KDB;
- break;
- case 'g': /* use kernel gdb */
- case 'G':
- boothowto |= RB_GDB;
- break;
-#endif
-
- case 'h': /* always halt, never reboot */
- case 'H':
- boothowto |= RB_HALT;
- break;
-
-#if 0
- case 'm': /* mini root present in memory */
- case 'M':
- boothowto |= RB_MINIROOT;
- break;
-#endif
-
- case 'n': /* askname */
- case 'N':
- boothowto |= RB_ASKNAME;
- break;
-
- case 's': /* single-user (default, supported for sanity) */
- case 'S':
- boothowto |= RB_SINGLE;
- break;
-
- case 'v':
- case 'V':
- boothowto |= RB_VERBOSE;
- bootverbose = 1;
- break;
-
- default:
- printf("Unrecognized boot flag '%c'.\n", *p);
- break;
- }
- }
/*
* Catch case of boot_verbose set in environment.
@@ -681,10 +624,12 @@ ia64_init()
if ((p = getenv("boot_verbose")) != NULL) {
if (strcmp(p, "yes") == 0 || strcmp(p, "YES") == 0) {
boothowto |= RB_VERBOSE;
- bootverbose = 1;
}
}
+ if (boothowto & RB_VERBOSE)
+ bootverbose = 1;
+
/*
* Force single-user for a while.
*/
diff --git a/sys/ia64/include/bootinfo.h b/sys/ia64/include/bootinfo.h
index c148120..d5914f8 100644
--- a/sys/ia64/include/bootinfo.h
+++ b/sys/ia64/include/bootinfo.h
@@ -41,9 +41,13 @@
* (u_long), then the bootinfo
*/
+#define BOOTINFO_MAGIC 0xdeadbeeffeedface
+
struct bootinfo {
- char bi_flags[64]; /* boot flags */
+ u_int64_t bi_magic; /* BOOTINFO_MAGIC */
+ u_int64_t bi_version; /* version 1 */
char bi_kernel[64]; /* name of booted kernel */
+ u_int64_t bi_boothowto; /* value for boothowto */
u_int64_t bi_systab; /* pa of EFI system table */
u_int64_t bi_memmap; /* pa of EFI memory map */
u_int64_t bi_memmap_size; /* size of EFI memory map */
OpenPOWER on IntegriCloud