summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2011-03-18 22:45:43 +0000
committermarcel <marcel@FreeBSD.org>2011-03-18 22:45:43 +0000
commit2fa9bafa3d14acd46f44fd431a79517a58115202 (patch)
treec3ed519ae4102f3431bd05326bf44abb72da1b59
parent1e701a660ae9ebb71c723cf9bb71348b656b63bf (diff)
downloadFreeBSD-src-2fa9bafa3d14acd46f44fd431a79517a58115202.zip
FreeBSD-src-2fa9bafa3d14acd46f44fd431a79517a58115202.tar.gz
o Move the IVT and supporting functions to the front of the text
segment so that it's always mapped by the loader. o Change the alternate fault handlers to account for PBVM. Since currently the region is handled by the VHPT, no alternate faults will be generated for it.
-rw-r--r--sys/conf/ldscript.ia6450
-rw-r--r--sys/ia64/ia64/exception.S84
-rw-r--r--sys/ia64/ia64/genassym.c5
-rw-r--r--sys/ia64/ia64/locore.S16
4 files changed, 100 insertions, 55 deletions
diff --git a/sys/conf/ldscript.ia64 b/sys/conf/ldscript.ia64
index 57b17d6..5d31ff4 100644
--- a/sys/conf/ldscript.ia64
+++ b/sys/conf/ldscript.ia64
@@ -9,6 +9,22 @@ SECTIONS
/* Read-only sections, merged into text segment: */
. = kernel_text + SIZEOF_HEADERS;
.interp : { *(.interp) }
+
+ PROVIDE (btext = .);
+ .ivt : { *(.ivt) }
+ .text :
+ {
+ *(.text.ivt)
+ *(.text .stub .text.* .gnu.linkonce.t.*)
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ } = 0x00300000010070000002000001000400
+ .init : { *(.init) } = 0x00300000010070000002000001000400
+ .plt : { *(.plt) }
+ .fini : { *(.fini) } = 0x00300000010070000002000001000400
+ _etext = .;
+ PROVIDE (etext = .);
+
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
@@ -30,37 +46,23 @@ SECTIONS
.rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
.rela.plt : { *(.rela.plt) }
.rela.IA_64.pltoff : { *(.rela.IA_64.pltoff) }
- PROVIDE (btext = .);
- .init :
- {
- *(.init)
- } =0x00300000010070000002000001000400
- .plt : { *(.plt) }
- .text :
- {
- *(.text .stub .text.* .gnu.linkonce.t.*)
- /* .gnu.warning sections are handled specially by elf32.em. */
- *(.gnu.warning)
- } =0x00300000010070000002000001000400
- .fini :
- {
- *(.fini)
- } =0x00300000010070000002000001000400
- _etext = .;
- PROVIDE (etext = .);
+
+ .IA_64.unwind_info : { *(.IA_64.unwind_info* .gnu.linkonce.ia64unwi.*) }
+ .IA_64.unwind : { *(.IA_64.unwind* .gnu.linkonce.ia64unw.*) }
+
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
.rodata1 : { *(.rodata1) }
.sdata2 : { *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) }
.sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) }
.opd : { *(.opd) }
- .IA_64.unwind_info : { *(.IA_64.unwind_info* .gnu.linkonce.ia64unwi.*) }
- .IA_64.unwind : { *(.IA_64.unwind* .gnu.linkonce.ia64unw.*) }
- /* Adjust the address for the data segment. We want to adjust up to
- the same address within the page on the next page up. */
- . = . + 8192;
+
+ /* Adjust the address for the data segment. We want to start in the next
+ page in the loader virtual memory. */
+ . = ALIGN(65536);
+
.data :
{
- *(.data.proc0 .data .data.* .gnu.linkonce.d.*)
+ *(.data.kstack .data .data.* .gnu.linkonce.d.*)
SORT(CONSTRUCTORS)
}
.data1 : { *(.data1) }
diff --git a/sys/ia64/ia64/exception.S b/sys/ia64/ia64/exception.S
index bbfa738..cd1b155 100644
--- a/sys/ia64/ia64/exception.S
+++ b/sys/ia64/ia64/exception.S
@@ -101,7 +101,7 @@ xhead: data8 xtrace
#endif
- .text
+ .section .text.ivt, "ax"
/*
* exception_save: save interrupted state
@@ -725,7 +725,7 @@ ivt_##name: \
* bundles per vector and 48 slots with 16 bundles per vector.
*/
- .section .text.ivt,"ax"
+ .section .ivt, "ax"
.align 32768
.global ia64_vector_table
@@ -812,7 +812,7 @@ IVT_ENTRY(Instruction_TLB, 0x0400)
3: add r20=24,r20 // next in chain
;;
ld8 r20=[r20] // read chain
- br.cond.sptk.few 2b // loop
+ br.sptk 2b // loop
;;
9: ssm psr.dt
mov pr=r17,0x1ffff // restore predicates
@@ -898,7 +898,7 @@ IVT_ENTRY(Data_TLB, 0x0800)
3: add r20=24,r20 // next in chain
;;
ld8 r20=[r20] // read chain
- br.cond.sptk.few 2b // loop
+ br.sptk 2b // loop
;;
9: ssm psr.dt
mov pr=r17,0x1ffff // restore predicates
@@ -913,25 +913,40 @@ IVT_ENTRY(Alternate_Instruction_TLB, 0x0c00)
mov r18=pr // save predicates
;;
extr.u r17=r16,61,3 // get region number
+ mov r19=PTE_PRESENT+PTE_ACCESSED+PTE_DIRTY+PTE_PL_KERN+PTE_AR_RWX
;;
- cmp.ge p13,p0=5,r17 // RR0-RR5?
- cmp.eq p15,p14=7,r17 // RR7->p15, RR6->p14
-(p13) br.spnt 9f
+ cmp.eq p13,p0=4,r17 // RR4?
+(p13) br.cond.sptk.few 4f
;;
-(p15) movl r17=PTE_PRESENT+PTE_MA_WB+PTE_ACCESSED+PTE_DIRTY+PTE_PL_KERN+ \
- PTE_AR_RX+PTE_ED
-(p14) movl r17=PTE_PRESENT+PTE_MA_UC+PTE_ACCESSED+PTE_DIRTY+PTE_PL_KERN+ \
- PTE_AR_RX
+ cmp.ge p13,p0=5,r17 // RR0-RR5?
+ cmp.eq p14,p15=7,r17 // RR7?
+(p13) br.cond.spnt.few 9f
;;
- dep r16=0,r16,50,14 // clear bits above PPN
+(p14) add r19=PTE_MA_WB,r19
+(p15) add r19=PTE_MA_UC,r19
+ dep r17=0,r16,50,14 // clear bits above PPN
;;
- dep r16=r17,r16,0,12 // put pte bits in 0..11
+1: dep r16=r19,r17,0,12 // put pte bits in 0..11
;;
itc.i r16
mov pr=r18,0x1ffff // restore predicates
;;
rfi
;;
+4:
+ add r19=PTE_MA_WB,r19
+ movl r17=IA64_PBVM_BASE
+ ;;
+ sub r17=r16,r17
+ movl r16=IA64_PBVM_PGTBL
+ ;;
+ extr.u r17=r17,IA64_PBVM_PAGE_SHIFT,61-IA64_PBVM_PAGE_SHIFT
+ ;;
+ shladd r16=r17,3,r16
+ ;;
+ ld8 r17=[r16]
+ br.sptk 1b
+ ;;
9: mov pr=r18,0x1ffff // restore predicates
CALL(trap, 3, cr.ifa)
IVT_END(Alternate_Instruction_TLB)
@@ -941,25 +956,40 @@ IVT_ENTRY(Alternate_Data_TLB, 0x1000)
mov r18=pr // save predicates
;;
extr.u r17=r16,61,3 // get region number
+ mov r19=PTE_PRESENT+PTE_ACCESSED+PTE_DIRTY+PTE_PL_KERN+PTE_AR_RWX
;;
- cmp.ge p13,p0=5,r17 // RR0-RR5?
- cmp.eq p15,p14=7,r17 // RR7->p15, RR6->p14
-(p13) br.spnt 9f
+ cmp.eq p13,p0=4,r17 // RR4?
+(p13) br.cond.sptk.few 4f
;;
-(p15) movl r17=PTE_PRESENT+PTE_MA_WB+PTE_ACCESSED+PTE_DIRTY+PTE_PL_KERN+ \
- PTE_AR_RW+PTE_ED
-(p14) movl r17=PTE_PRESENT+PTE_MA_UC+PTE_ACCESSED+PTE_DIRTY+PTE_PL_KERN+ \
- PTE_AR_RW
+ cmp.ge p13,p0=5,r17 // RR0-RR5?
+ cmp.eq p14,p15=7,r17 // RR7?
+(p13) br.cond.spnt.few 9f
;;
- dep r16=0,r16,50,14 // clear bits above PPN
+(p14) add r19=PTE_MA_WB,r19
+(p15) add r19=PTE_MA_UC,r19
+ dep r17=0,r16,50,14 // clear bits above PPN
;;
- dep r16=r17,r16,0,12 // put pte bits in 0..11
+1: dep r16=r19,r17,0,12 // put pte bits in 0..11
;;
itc.d r16
mov pr=r18,0x1ffff // restore predicates
;;
rfi
;;
+4:
+ add r19=PTE_MA_WB,r19
+ movl r17=IA64_PBVM_BASE
+ ;;
+ sub r17=r16,r17
+ movl r16=IA64_PBVM_PGTBL
+ ;;
+ extr.u r17=r17,IA64_PBVM_PAGE_SHIFT,61-IA64_PBVM_PAGE_SHIFT
+ ;;
+ shladd r16=r17,3,r16
+ ;;
+ ld8 r17=[r16]
+ br.sptk 1b
+ ;;
9: mov pr=r18,0x1ffff // restore predicates
CALL(trap, 4, cr.ifa)
IVT_END(Alternate_Data_TLB)
@@ -1045,13 +1075,13 @@ IVT_ENTRY(Data_Nested_TLB, 0x1400)
{ .mib
srlz.d
cmp.eq p13,p0=r29,r27
-(p12) br.sptk exception_save_restart
+(p12) br.cond.sptk.few exception_save_restart
;;
}
{ .mib
nop 0
nop 0
-(p13) br.sptk exception_restore_restart
+(p13) br.cond.sptk.few exception_restore_restart
;;
}
{ .mlx
@@ -1147,7 +1177,7 @@ IVT_ENTRY(Dirty_Bit, 0x2000)
2: add r20=24,r20 // next in chain
;;
ld8 r20=[r20] // read chain
- br.cond.sptk.few 1b // loop
+ br.sptk 1b // loop
;;
9: ssm psr.dt
mov pr=r17,0x1ffff // restore predicates
@@ -1221,7 +1251,7 @@ IVT_ENTRY(Instruction_Access_Bit, 0x2400)
2: add r20=24,r20 // next in chain
;;
ld8 r20=[r20] // read chain
- br.cond.sptk.few 1b // loop
+ br.sptk 1b // loop
;;
9: ssm psr.dt
mov pr=r17,0x1ffff // restore predicates
@@ -1295,7 +1325,7 @@ IVT_ENTRY(Data_Access_Bit, 0x2800)
2: add r20=24,r20 // next in chain
;;
ld8 r20=[r20] // read chain
- br.cond.sptk.few 1b // loop
+ br.sptk 1b // loop
;;
9: ssm psr.dt
mov pr=r17,0x1ffff // restore predicates
diff --git a/sys/ia64/ia64/genassym.c b/sys/ia64/ia64/genassym.c
index 9312dbe..c8899a6 100644
--- a/sys/ia64/ia64/genassym.c
+++ b/sys/ia64/ia64/genassym.c
@@ -79,6 +79,11 @@ ASSYM(FRAME_SYSCALL, FRAME_SYSCALL);
ASSYM(IA64_ID_PAGE_SHIFT, IA64_ID_PAGE_SHIFT);
+ASSYM(IA64_PBVM_BASE, IA64_PBVM_BASE);
+ASSYM(IA64_PBVM_PAGE_SHIFT, IA64_PBVM_PAGE_SHIFT);
+ASSYM(IA64_PBVM_PGTBL, IA64_PBVM_PGTBL);
+ASSYM(IA64_PBVM_RR, IA64_PBVM_RR);
+
ASSYM(KSTACK_PAGES, KSTACK_PAGES);
ASSYM(MC_PRESERVED, offsetof(mcontext_t, mc_preserved));
diff --git a/sys/ia64/ia64/locore.S b/sys/ia64/ia64/locore.S
index ce66dca..b7b981c 100644
--- a/sys/ia64/ia64/locore.S
+++ b/sys/ia64/ia64/locore.S
@@ -34,10 +34,18 @@
#include <machine/intrcnt.h>
#include <assym.s>
- .section .data.proc0,"aw"
- .global kstack
+/*
+ * The Altix 350 needs more than the architected 16KB (8KB for stack and
+ * 8KB for RSE backing store) when calling EFI to setup virtual mode.
+ */
+#define FW_STACK_SIZE 3*PAGE_SIZE
+
+ .section .data.kstack, "aw"
.align PAGE_SIZE
-kstack: .space KSTACK_PAGES * PAGE_SIZE
+ .global kstack
+kstack: .space FW_STACK_SIZE
+ .global kstack_top
+kstack_top:
.text
@@ -64,7 +72,7 @@ ENTRY_NOPROFILE(__start, 1)
srlz.i
;;
ssm IA64_PSR_DFH
- mov r17=KSTACK_PAGES*PAGE_SIZE-SIZEOF_PCB-SIZEOF_TRAPFRAME-16
+ mov r17=FW_STACK_SIZE-16
;;
}
{ .mlx
OpenPOWER on IntegriCloud