diff --git a/sys/ia64/ia64/locore.S b/sys/ia64/ia64/locore.S index 9bb108e3607c..8452c5792d3a 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 9bb108e3607c..8452c5792d3a 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 417439bdbada..51483d9a7c7f 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); /*