summaryrefslogtreecommitdiffstats
path: root/sys/ia64
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2002-03-30 23:25:22 +0000
committermarcel <marcel@FreeBSD.org>2002-03-30 23:25:22 +0000
commit3d34c199201ae64f4f084e4ecb241e24ed857899 (patch)
tree5db51b49297cce8b3c98a9e64850f689849d628c /sys/ia64
parent98d23cf55d66e6dbb4deaacda319e0f6a71b9ae9 (diff)
downloadFreeBSD-src-3d34c199201ae64f4f084e4ecb241e24ed857899.zip
FreeBSD-src-3d34c199201ae64f4f084e4ecb241e24ed857899.tar.gz
Transition to a model where the loader passes the address of the
bootinfo block in register r8. In locore.s we save the address in the global variable 'pa_bootinfo'. In machdep.c we compare this value against the hardwired address, but don't depend on its validity yet (ie: we still expect the bootinfo block to be at the hardwired address). After a small amount of time, we'll flip the switch and depend on the loader to pass us the address. From that moment on the loader is free to put it anywhere it likes, provided the machine itself likes it as well. Add some verbosity to aid in the transition. We emit a message if the loader didn't pass the address and we also emit a message if there's no bootinfo block at the hardwired address. While in locore.s, reduce the number of redundant serialization instructions. A srlz.i is a proper superset of a srlz.d and thus is a valid replacement. Also slightly reorder the movl instructions to improve bundle density.
Diffstat (limited to 'sys/ia64')
-rw-r--r--sys/ia64/ia64/locore.S28
-rw-r--r--sys/ia64/ia64/locore.s28
-rw-r--r--sys/ia64/ia64/machdep.c33
3 files changed, 58 insertions, 31 deletions
diff --git a/sys/ia64/ia64/locore.S b/sys/ia64/ia64/locore.S
index 9bb108e..8452c57 100644
--- a/sys/ia64/ia64/locore.S
+++ b/sys/ia64/ia64/locore.S
@@ -73,27 +73,30 @@ kstack: .space KSTACK_PAGES * PAGE_SIZE
/*
* Not really a leaf but we can't return.
+ * The EFI loader passes the physical address of the bootinfo block in
+ * register r8.
*/
ENTRY(__start, 1)
- movl r8=ia64_vector_table // set up IVT early
- movl r9=ia64_vhpt+(1<<8)+(15<<2)+1 // and VHPT
+ movl r16=ia64_vector_table // set up IVT early
;;
- mov cr.iva=r8
- mov cr.pta=r9
+ mov cr.iva=r16
+ movl r16=ia64_vhpt+(1<<8)+(15<<2)+1 // and VHPT
;;
- movl r11=kstack
+ mov cr.pta=r16
+ movl r16=kstack
;;
srlz.i
;;
- srlz.d
- mov r9=KSTACK_PAGES*PAGE_SIZE-SIZEOF_PCB-SIZEOF_TRAPFRAME-16
- ;;
+ mov r17=KSTACK_PAGES*PAGE_SIZE-SIZEOF_PCB-SIZEOF_TRAPFRAME-16
movl gp=__gp // find kernel globals
- add sp=r9,r11 // proc0's stack
+ ;;
+ add sp=r16,r17 // proc0's stack
mov ar.rsc=0 // turn off rse
;;
- mov ar.bspstore=r11 // switch backing store
+ mov ar.bspstore=r16 // switch backing store
+ movl r16=pa_bootinfo
;;
+ st8 [r16]=r8 // save the PA of the bootinfo block
loadrs // invalidate regs
;;
mov ar.rsc=3 // turn rse back on
@@ -121,7 +124,7 @@ ENTRY(__start, 1)
movl r17=mi_startup_trampoline
;;
st8 [r16]=r17
- ;;
+ ;;
br.call.sptk.many rp=restorectx
/* NOTREACHED */
@@ -161,7 +164,6 @@ ENTRY(os_boot_rendez,0)
srlz.d
rsm IA64_PSR_IC|IA64_PSR_I
;;
- srlz.d
mov r16 = (5<<8)|(PAGE_SHIFT<<2)|1
movl r17 = 5<<61
;;
@@ -189,13 +191,11 @@ ENTRY(os_boot_rendez,0)
ptr.d r17, r18
ptr.i r17, r18
;;
- srlz.d
srlz.i
;;
itr.d dtr[r0] = r16
;;
itr.i itr[r0] = r16
- srlz.d
;;
srlz.i
;;
diff --git a/sys/ia64/ia64/locore.s b/sys/ia64/ia64/locore.s
index 9bb108e..8452c57 100644
--- a/sys/ia64/ia64/locore.s
+++ b/sys/ia64/ia64/locore.s
@@ -73,27 +73,30 @@ kstack: .space KSTACK_PAGES * PAGE_SIZE
/*
* Not really a leaf but we can't return.
+ * The EFI loader passes the physical address of the bootinfo block in
+ * register r8.
*/
ENTRY(__start, 1)
- movl r8=ia64_vector_table // set up IVT early
- movl r9=ia64_vhpt+(1<<8)+(15<<2)+1 // and VHPT
+ movl r16=ia64_vector_table // set up IVT early
;;
- mov cr.iva=r8
- mov cr.pta=r9
+ mov cr.iva=r16
+ movl r16=ia64_vhpt+(1<<8)+(15<<2)+1 // and VHPT
;;
- movl r11=kstack
+ mov cr.pta=r16
+ movl r16=kstack
;;
srlz.i
;;
- srlz.d
- mov r9=KSTACK_PAGES*PAGE_SIZE-SIZEOF_PCB-SIZEOF_TRAPFRAME-16
- ;;
+ mov r17=KSTACK_PAGES*PAGE_SIZE-SIZEOF_PCB-SIZEOF_TRAPFRAME-16
movl gp=__gp // find kernel globals
- add sp=r9,r11 // proc0's stack
+ ;;
+ add sp=r16,r17 // proc0's stack
mov ar.rsc=0 // turn off rse
;;
- mov ar.bspstore=r11 // switch backing store
+ mov ar.bspstore=r16 // switch backing store
+ movl r16=pa_bootinfo
;;
+ st8 [r16]=r8 // save the PA of the bootinfo block
loadrs // invalidate regs
;;
mov ar.rsc=3 // turn rse back on
@@ -121,7 +124,7 @@ ENTRY(__start, 1)
movl r17=mi_startup_trampoline
;;
st8 [r16]=r17
- ;;
+ ;;
br.call.sptk.many rp=restorectx
/* NOTREACHED */
@@ -161,7 +164,6 @@ ENTRY(os_boot_rendez,0)
srlz.d
rsm IA64_PSR_IC|IA64_PSR_I
;;
- srlz.d
mov r16 = (5<<8)|(PAGE_SHIFT<<2)|1
movl r17 = 5<<61
;;
@@ -189,13 +191,11 @@ ENTRY(os_boot_rendez,0)
ptr.d r17, r18
ptr.i r17, r18
;;
- srlz.d
srlz.i
;;
itr.d dtr[r0] = r16
;;
itr.i itr[r0] = r16
- srlz.d
;;
srlz.i
;;
diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c
index 417439b..51483d9 100644
--- a/sys/ia64/ia64/machdep.c
+++ b/sys/ia64/ia64/machdep.c
@@ -90,7 +90,11 @@ u_int64_t processor_frequency;
u_int64_t bus_frequency;
u_int64_t itc_frequency;
int cold = 1;
+
+u_int64_t pa_bootinfo;
+u_int64_t va_bootinfo;
struct bootinfo bootinfo;
+int bootinfo_error; /* XXX temporary ad-hoc error mask to help debugging */
struct mtx sched_lock;
struct mtx Giant;
@@ -401,10 +405,25 @@ ia64_init(u_int64_t arg1, u_int64_t arg2)
/*
* Gross and disgusting hack. The bootinfo is written into
* memory at a fixed address.
+ * To help transitioning to a non-fixed bootinfo block, we
+ * temporarily have to make this more gross and disgusting:
+ * o pa_bootinfo is the physical address of the bootinfo block
+ * as passed to us by the loader (initialized in locore.s)
+ * (EFI loader version 0.3 and up). We only check this value.
+ * We don't actively use it yet.
+ * o va_bootinfo is the hardwired virtual (RR7) address of
+ * the bootinfo block (old loaders). We still use it for the
+ * moment.
*/
- bootinfo = *(struct bootinfo *) 0xe000000000508000;
- if (bootinfo.bi_magic != BOOTINFO_MAGIC
- || bootinfo.bi_version != 1) {
+ va_bootinfo = 0xe000000000508000; /* the fixed RR7 address */
+ if (IA64_PHYS_TO_RR7(pa_bootinfo) != va_bootinfo)
+ bootinfo_error |= 1; /* XXX loader did not set r8 */
+
+ /* copy the bootinfo block */
+ bootinfo = *(struct bootinfo *)va_bootinfo;
+
+ if (bootinfo.bi_magic != BOOTINFO_MAGIC || bootinfo.bi_version != 1) {
+ bootinfo_error |= 2; /* XXX bogus block */
bzero(&bootinfo, sizeof(bootinfo));
bootinfo.bi_kernend = (vm_offset_t) round_page(_end);
}
@@ -478,6 +497,14 @@ ia64_init(u_int64_t arg1, u_int64_t arg2)
/* OUTPUT NOW ALLOWED */
+ if (bootinfo_error & 1)
+ printf("bootinfo: the loader did not not pass the address "
+ "of the block in r8.\n");
+
+ if (bootinfo_error & 2)
+ printf("bootinfo: block not valid; possibly not at hardwired "
+ "address.\n");
+
if (ia64_pal_base != 0) {
ia64_pal_base &= ~((1 << 28) - 1);
/*
OpenPOWER on IntegriCloud