diff options
| author | Doug Rabson <dfr@FreeBSD.org> | 2000-09-30 17:48:44 +0000 |
|---|---|---|
| committer | Doug Rabson <dfr@FreeBSD.org> | 2000-09-30 17:48:44 +0000 |
| commit | 431f3cb41dd33d61b63016f3374b99f550be23d8 (patch) | |
| tree | e77d8d618e90ddf3849fd5780eaa9d10203f1bc7 /sys/ia64 | |
| parent | 534f2a9dad783255926c89ab03551abe0180ea20 (diff) | |
Notes
Diffstat (limited to 'sys/ia64')
| -rw-r--r-- | sys/ia64/ia64/clock.c | 35 | ||||
| -rw-r--r-- | sys/ia64/ia64/exception.S | 8 | ||||
| -rw-r--r-- | sys/ia64/ia64/exception.s | 8 | ||||
| -rw-r--r-- | sys/ia64/ia64/genassym.c | 18 | ||||
| -rw-r--r-- | sys/ia64/ia64/locore.S | 152 | ||||
| -rw-r--r-- | sys/ia64/ia64/locore.s | 152 | ||||
| -rw-r--r-- | sys/ia64/ia64/machdep.c | 29 | ||||
| -rw-r--r-- | sys/ia64/ia64/pal.S | 12 | ||||
| -rw-r--r-- | sys/ia64/ia64/pal.s | 12 | ||||
| -rw-r--r-- | sys/ia64/ia64/pmap.c | 6 | ||||
| -rw-r--r-- | sys/ia64/ia64/ssc.c | 15 | ||||
| -rw-r--r-- | sys/ia64/ia64/support.S | 614 | ||||
| -rw-r--r-- | sys/ia64/ia64/support.s | 614 | ||||
| -rw-r--r-- | sys/ia64/ia64/swtch.s | 75 | ||||
| -rw-r--r-- | sys/ia64/ia64/vm_machdep.c | 101 | ||||
| -rw-r--r-- | sys/ia64/include/asm.h | 34 | ||||
| -rw-r--r-- | sys/ia64/include/ia64_cpu.h | 25 | ||||
| -rw-r--r-- | sys/ia64/include/pcb.h | 12 | ||||
| -rw-r--r-- | sys/ia64/include/proc.h | 1 |
19 files changed, 810 insertions, 1113 deletions
diff --git a/sys/ia64/ia64/clock.c b/sys/ia64/ia64/clock.c index 06a7f0c618f1..eb763129a66e 100644 --- a/sys/ia64/ia64/clock.c +++ b/sys/ia64/ia64/clock.c @@ -87,7 +87,7 @@ static struct timecounter ia64_timecounter = { 0, /* no poll_pps */ ~0u, /* counter_mask */ 0, /* frequency */ - "alpha" /* name */ + "IA64 ITC" /* name */ }; SYSCTL_OPAQUE(_debug, OID_AUTO, ia64_timecounter, CTLFLAG_RD, @@ -158,9 +158,15 @@ cpu_initclocks() { u_int32_t freq; +#if 0 if (clockdev == NULL) panic("cpu_initclocks: no clock attached"); +#endif + /* + * We use cr.itc and cr.itm to implement a 1024hz clock. + */ + hz = 1024; tick = 1000000 / hz; /* number of microseconds between interrupts */ tickfix = 1000000 - (hz * tick); if (tickfix) { @@ -172,19 +178,14 @@ cpu_initclocks() } /* - * Establish the clock interrupt; it's a special case. - * - * We establish the clock interrupt this late because if - * we do it at clock attach time, we may have never been at - * spl0() since taking over the system. Some versions of - * PALcode save a clock interrupt, which would get delivered - * when we spl0() in autoconf.c. If established the clock - * interrupt handler earlier, that interrupt would go to - * hardclock, which would then fall over because p->p_stats - * isn't set at that time. + * XXX we should call SAL_FREQ_BASE_INTERVAL_TIMER here. */ + cycles_per_sec = 700000000; + ia64_set_itm(ia64_get_itc() + (cycles_per_sec + hz/2) / hz); + + freq = cycles_per_sec; - last_time = ia64_read_itc(); + last_time = ia64_get_itc(); scaled_ticks_per_cycle = ((u_int64_t)hz << FIX_SHIFT) / freq; max_cycles_per_tick = 2*freq / hz; @@ -193,10 +194,12 @@ cpu_initclocks() stathz = 128; +#if 0 /* * Get the clock started. */ CLOCK_INIT(clockdev); +#endif } static u_int32_t @@ -222,7 +225,7 @@ calibrate_clocks(u_int32_t firmware_freq) } /* Start keeping track of the PCC. */ - start_pcc = ia64_read_itc(); + start_pcc = ia64_get_itc(); /* * Wait for the mc146818A seconds counter to change. @@ -238,7 +241,7 @@ calibrate_clocks(u_int32_t firmware_freq) /* * Read the PCC again to work out frequency. */ - stop_pcc = ia64_read_itc(); + stop_pcc = ia64_get_itc(); if (bootverbose) { printf("PCC clock: %u Hz (firmware %u Hz)\n", @@ -256,7 +259,7 @@ fail: static void handleclock(void* arg) { - u_int32_t now = ia64_read_itc(); + u_int32_t now = ia64_get_itc(); u_int32_t delta = now - last_time; last_time = now; @@ -432,7 +435,7 @@ resettodr() static unsigned ia64_get_timecount(struct timecounter* tc) { - return ia64_read_itc(); + return ia64_get_itc(); } int diff --git a/sys/ia64/ia64/exception.S b/sys/ia64/ia64/exception.S index 9cf8b9eb226d..812bba43d3ba 100644 --- a/sys/ia64/ia64/exception.S +++ b/sys/ia64/ia64/exception.S @@ -48,6 +48,7 @@ movl r17=exception_return; \ mov out0=_n_; \ mov out1=sp;; \ + add sp=-16,sp;; \ mov rp=r17; \ br.call.sptk.few b6=trap @@ -780,15 +781,16 @@ ia64_vhpt: .quad 0 * exception_return: restore interrupted state * * Arguments: - * sp trapframe pointer + * sp+16 trapframe pointer * */ LEAF(exception_return, 0) rsm psr.ic|psr.dt // disable interrupt collection and vm + add r3=16,sp; ;; srlz.d - dep r3=0,sp,61,3 // physical address + dep r3=0,r3,61,3 // physical address ;; add r1=SIZEOF_TRAPFRAME-16,r3 // r1=&tf_f[FRAME_F15] add r2=SIZEOF_TRAPFRAME-32,r3 // r2=&tf_f[FRAME_F14] @@ -805,7 +807,7 @@ LEAF(exception_return, 0) ldf.fill f9=[r1],-32 // r1=&tf_f[FRAME_F7] ldf.fill f8=[r2],-32 // r2=&tf_f[FRAME_F6] ;; - ldf.fill f7=[r1],-24 // r1=&tf_r[FRAME_R31] + ldf.fill f7=[r1],-32 // r1=&tf_r[FRAME_R31] ldf.fill f6=[r2],-24 // r2=&tf_r[FRAME_R30] ;; ld8.fill r31=[r1],-16 // r1=&tf_r[FRAME_R29] diff --git a/sys/ia64/ia64/exception.s b/sys/ia64/ia64/exception.s index 9cf8b9eb226d..812bba43d3ba 100644 --- a/sys/ia64/ia64/exception.s +++ b/sys/ia64/ia64/exception.s @@ -48,6 +48,7 @@ movl r17=exception_return; \ mov out0=_n_; \ mov out1=sp;; \ + add sp=-16,sp;; \ mov rp=r17; \ br.call.sptk.few b6=trap @@ -780,15 +781,16 @@ ia64_vhpt: .quad 0 * exception_return: restore interrupted state * * Arguments: - * sp trapframe pointer + * sp+16 trapframe pointer * */ LEAF(exception_return, 0) rsm psr.ic|psr.dt // disable interrupt collection and vm + add r3=16,sp; ;; srlz.d - dep r3=0,sp,61,3 // physical address + dep r3=0,r3,61,3 // physical address ;; add r1=SIZEOF_TRAPFRAME-16,r3 // r1=&tf_f[FRAME_F15] add r2=SIZEOF_TRAPFRAME-32,r3 // r2=&tf_f[FRAME_F14] @@ -805,7 +807,7 @@ LEAF(exception_return, 0) ldf.fill f9=[r1],-32 // r1=&tf_f[FRAME_F7] ldf.fill f8=[r2],-32 // r2=&tf_f[FRAME_F6] ;; - ldf.fill f7=[r1],-24 // r1=&tf_r[FRAME_R31] + ldf.fill f7=[r1],-32 // r1=&tf_r[FRAME_R31] ldf.fill f6=[r2],-24 // r2=&tf_r[FRAME_R30] ;; ld8.fill r31=[r1],-16 // r1=&tf_r[FRAME_R29] diff --git a/sys/ia64/ia64/genassym.c b/sys/ia64/ia64/genassym.c index e94a2ab8d4e5..a05bcb49c592 100644 --- a/sys/ia64/ia64/genassym.c +++ b/sys/ia64/ia64/genassym.c @@ -67,6 +67,13 @@ #include <nfs/nfs.h> #include <nfs/nfsdiskless.h> +ASSYM(GD_CURPROC, offsetof(struct globaldata, gd_curproc)); +ASSYM(GD_FPCURPROC, offsetof(struct globaldata, gd_fpcurproc)); +ASSYM(GD_CURPCB, offsetof(struct globaldata, gd_curpcb)); +ASSYM(GD_SWITCHTIME, offsetof(struct globaldata, gd_switchtime)); +ASSYM(GD_CPUNO, offsetof(struct globaldata, gd_cpuno)); +ASSYM(GD_ASTPENDING, offsetof(struct globaldata, gd_astpending)); + ASSYM(MTX_LOCK, offsetof(struct mtx, mtx_lock)); ASSYM(MTX_RECURSE, offsetof(struct mtx, mtx_recurse)); ASSYM(MTX_SAVEPSR, offsetof(struct mtx, mtx_savepsr)); @@ -74,7 +81,6 @@ ASSYM(MTX_UNOWNED, MTX_UNOWNED); ASSYM(P_ADDR, offsetof(struct proc, p_addr)); ASSYM(P_MD_FLAGS, offsetof(struct proc, p_md.md_flags)); -ASSYM(P_MD_PCBPADDR, offsetof(struct proc, p_md.md_pcbpaddr)); ASSYM(VM_MAXUSER_ADDRESS, VM_MAXUSER_ADDRESS); @@ -90,6 +96,13 @@ ASSYM(U_PCB_F3, offsetof(struct user, u_pcb.pcb_f3)); ASSYM(U_PCB_F4, offsetof(struct user, u_pcb.pcb_f4)); ASSYM(U_PCB_F5, offsetof(struct user, u_pcb.pcb_f5)); +ASSYM(U_PCB_B0, offsetof(struct user, u_pcb.pcb_b0)); +ASSYM(U_PCB_B1, offsetof(struct user, u_pcb.pcb_b1)); +ASSYM(U_PCB_B2, offsetof(struct user, u_pcb.pcb_b2)); +ASSYM(U_PCB_B3, offsetof(struct user, u_pcb.pcb_b3)); +ASSYM(U_PCB_B4, offsetof(struct user, u_pcb.pcb_b4)); +ASSYM(U_PCB_B5, offsetof(struct user, u_pcb.pcb_b5)); + ASSYM(U_PCB_OLD_UNAT, offsetof(struct user, u_pcb.pcb_old_unat)); ASSYM(U_PCB_SP, offsetof(struct user, u_pcb.pcb_sp)); ASSYM(U_PCB_PFS, offsetof(struct user, u_pcb.pcb_pfs)); @@ -98,7 +111,8 @@ ASSYM(U_PCB_BSPSTORE, offsetof(struct user, u_pcb.pcb_bspstore)); ASSYM(U_PCB_UNAT, offsetof(struct user, u_pcb.pcb_unat)); ASSYM(U_PCB_RNAT, offsetof(struct user, u_pcb.pcb_rnat)); ASSYM(U_PCB_PR, offsetof(struct user, u_pcb.pcb_pr)); -ASSYM(U_PCB_IIP, offsetof(struct user, u_pcb.pcb_iip)); + +ASSYM(U_PCB_ONFAULT, offsetof(struct user, u_pcb.pcb_onfault)); ASSYM(UC_MCONTEXT_MC_AR_BSP, offsetof(ucontext_t, uc_mcontext.mc_ar_bsp)); ASSYM(UC_MCONTEXT_MC_AR_RNAT, offsetof(ucontext_t, uc_mcontext.mc_ar_rnat)); diff --git a/sys/ia64/ia64/locore.S b/sys/ia64/ia64/locore.S index 8e38d4011ee9..5045d0bac282 100644 --- a/sys/ia64/ia64/locore.S +++ b/sys/ia64/ia64/locore.S @@ -63,17 +63,6 @@ #include <machine/intrcnt.h> #endif -/* - * Perform actions necessary to switch to a new context. The - * hwpcb should be in a0. - */ -#define SWITCH_CONTEXT \ - /* Make a note of the context we're running on. */ \ - stq a0, curpcb ; \ - \ - /* Swap in the new context. */ \ - call_pal PAL_OSF1_swpctx - .text /* @@ -81,8 +70,8 @@ */ LEAF(locorestart, 1) - movl r8=ia64_vector_table /* set up IVT early */ - movl r9=ia64_vhpt+(1<<8)+(15<<2)+1 /* and VHPT */ + movl r8=ia64_vector_table // set up IVT early + movl r9=ia64_vhpt+(1<<8)+(15<<2)+1 // and VHPT ;; mov cr.iva=r8 mov cr.pta=r9 @@ -91,87 +80,30 @@ LEAF(locorestart, 1) ;; srlz.d ;; - movl gp=__gp /* find kernel globals */ + movl gp=__gp // find kernel globals ;; br.call.sptk.many rp=ia64_init - /* XXX switch to proc0 here */ - movl r16=proc0 - ;; - add r16=P_ADDR,r16 - ;; - ld8 r16=[r16] + /* + * switch to proc0 and then initialise the rest of the kernel. + */ + alloc r16=ar.pfs,0,0,1,0 ;; - add r17=SIZEOF_USER,r16 /* address of backing store */ - add r18=U_PCB_SP,r16 /* stack pointer */ + movl out0=proc0 ;; - ld8 r18=[r18] - mov ar.rsc=0 - cover - ;; - flushrs - ;; - mov ar.bspstore=r17 - mov sp=r18 + add out0=P_ADDR,out0 ;; - loadrs - mov ar.rsc=3 + ld8 out0=[out0] ;; - alloc r16=ar.pfs,0,0,0,0 + add r16=U_PCB_B0,out0 // return to mi_startup + movl r17=mi_startup + ;; + st8 [r16]=r17 ;; - br.call.sptk.many rp=mi_startup + br.call.sptk.many rp=restorectx /* NOTREACHED */ -#if 0 - /* Load KGP with current GP. */ - or a0,zero,s0 /* save pfn */ - or gp,zero,a0 - call_pal PAL_OSF1_wrkgp /* clobbers a0, t0, t8-t11 */ - or s0,zero,a0 /* restore pfn */ - - /* - * Call alpha_init() to do pre-main initialization. - * alpha_init() gets the arguments we were called with, - * which are already in a0, a1, a2, a3, and a4. - */ - CALL(alpha_init) - - /* Set up the virtual page table pointer. */ - ldiq a0, VPTBASE - call_pal PAL_OSF1_wrvptptr /* clobbers a0, t0, t8-t11 */ - - /* - * Switch to proc0's PCB, which is at U_PCB off of proc0paddr. - */ - lda t0,proc0 /* get phys addr of pcb */ - ldq a0,P_MD_PCBPADDR(t0) - SWITCH_CONTEXT - - /* - * We've switched to a new page table base, so invalidate the TLB - * and I-stream. This happens automatically everywhere but here. - */ - ldiq a0, -2 /* TBIA */ - call_pal PAL_OSF1_tbi - call_pal PAL_imb - - /* - * Construct a fake trap frame, so execve() can work normally. - * Note that setregs() is responsible for setting its contents - * to 'reasonable' values. - */ - lda sp,-(FRAME_SIZE * 8)(sp) /* space for struct trapframe */ - mov sp, a0 /* arg is frame ptr */ - CALL(mi_startup) /* go to mi_startup()! */ - - /* - * Call exception_return, to simulate return from (fake) - * exception to user-land, running process 1, init! - */ - jmp zero, exception_return /* "And that's all she wrote." */ - -#endif END(locorestart) @@ -187,48 +119,48 @@ LEAF(locorestart, 1) * r16 pointer to signal context frame (scp) * r17 address of handler function descriptor * r18 address of new backing store (if any) - * sp pointer to sigframe + * sp+16 pointer to sigframe */ LEAF(sigcode,0) - ld8 r8=[r17],8 /* function address */ + ld8 r8=[r17],8 // function address ;; - ld8 gp=[r17] /* function's gp value */ - mov b6=r8 /* transfer to a branch register */ + ld8 gp=[r17] // function's gp value + mov b6=r8 // transfer to a branch register cover ;; - alloc r5=ar.pfs,0,0,3,0 /* register frame for call */ + alloc r5=ar.pfs,0,0,3,0 // register frame for call ;; - mov out0=r14 /* signal number */ - add r8=UC_MCONTEXT_MC_AR_BSP,r16 /* address or mc_ar_bsp */ - mov r9=ar.bsp /* save ar.bsp */ + mov out0=r14 // signal number + add r8=UC_MCONTEXT_MC_AR_BSP,r16 // address or mc_ar_bsp + mov r9=ar.bsp // save ar.bsp ;; st8 [r8]=r9 - cmp.eq p1,p0=r0,r18 /* check for new bs */ -(p1) br.cond.sptk.few 1f /* branch if not switching */ - flushrs /* flush out to old bs */ - mov ar.rsc=0 /* switch off RSE */ - add r8=UC_MCONTEXT_MC_AR_RNAT,r16 /* address of mc_ar_rnat */ + cmp.eq p1,p0=r0,r18 // check for new bs +(p1) br.cond.sptk.few 1f // branch if not switching + flushrs // flush out to old bs + mov ar.rsc=0 // switch off RSE + add r8=UC_MCONTEXT_MC_AR_RNAT,r16 // address of mc_ar_rnat ;; - mov r9=ar.rnat /* value of ar.rnat after flush */ - mov ar.bspstore=r18 /* point at new bs */ + mov r9=ar.rnat // value of ar.rnat after flush + mov ar.bspstore=r18 // point at new bs ;; - st8 [r8]=r9 /* remember ar.rnat */ - mov ar.rsc=15 /* XXX bogus value - check */ + st8 [r8]=r9 // remember ar.rnat + mov ar.rsc=15 // XXX bogus value - check invala ;; -1: mov out1=r15 /* siginfo */ - mov out2=r16 /* ucontext */ - mov r4=r17 /* save ucontext pointer from call */ - br.call.sptk.few rp=b6 /* call the signal handler */ -(p1) br.cond.sptk.few 2f /* note: p1 is preserved */ +1: mov out1=r15 // siginfo + mov out2=r16 // ucontext + mov r4=r17 // save ucontext pointer from call + br.call.sptk.few rp=b6 // call the signal handler +(p1) br.cond.sptk.few 2f // note: p1 is preserved flushrs mov ar.rsc=0 - add r8=UC_MCONTEXT_MC_AR_RNAT,r4 /* address of mc_ar_rnat */ + add r8=UC_MCONTEXT_MC_AR_RNAT,r4 // address of mc_ar_rnat ;; ld8 r9=[r8] ;; - add r8=UC_MCONTEXT_MC_AR_BSP,r4 /* address of mc_ar_bsp */ + add r8=UC_MCONTEXT_MC_AR_BSP,r4 // address of mc_ar_bsp ;; ld8 r10=[r8] ;; @@ -237,9 +169,9 @@ LEAF(sigcode,0) mov ar.rnat=r9 mov ar.rsc=15 2: - CALLSYS_NOERROR(sigreturn) /* and call sigreturn() with it. */ - mov out0=ret0 /* if that failed, get error code */ - CALLSYS_NOERROR(exit) /* and call exit() with it. */ + CALLSYS_NOERROR(sigreturn) // and call sigreturn() with it. + mov out0=ret0 // if that failed, get error code + CALLSYS_NOERROR(exit) // and call exit() with it. XLEAF(esigcode) END(sigcode) diff --git a/sys/ia64/ia64/locore.s b/sys/ia64/ia64/locore.s index 8e38d4011ee9..5045d0bac282 100644 --- a/sys/ia64/ia64/locore.s +++ b/sys/ia64/ia64/locore.s @@ -63,17 +63,6 @@ #include <machine/intrcnt.h> #endif -/* - * Perform actions necessary to switch to a new context. The - * hwpcb should be in a0. - */ -#define SWITCH_CONTEXT \ - /* Make a note of the context we're running on. */ \ - stq a0, curpcb ; \ - \ - /* Swap in the new context. */ \ - call_pal PAL_OSF1_swpctx - .text /* @@ -81,8 +70,8 @@ */ LEAF(locorestart, 1) - movl r8=ia64_vector_table /* set up IVT early */ - movl r9=ia64_vhpt+(1<<8)+(15<<2)+1 /* and VHPT */ + movl r8=ia64_vector_table // set up IVT early + movl r9=ia64_vhpt+(1<<8)+(15<<2)+1 // and VHPT ;; mov cr.iva=r8 mov cr.pta=r9 @@ -91,87 +80,30 @@ LEAF(locorestart, 1) ;; srlz.d ;; - movl gp=__gp /* find kernel globals */ + movl gp=__gp // find kernel globals ;; br.call.sptk.many rp=ia64_init - /* XXX switch to proc0 here */ - movl r16=proc0 - ;; - add r16=P_ADDR,r16 - ;; - ld8 r16=[r16] + /* + * switch to proc0 and then initialise the rest of the kernel. + */ + alloc r16=ar.pfs,0,0,1,0 ;; - add r17=SIZEOF_USER,r16 /* address of backing store */ - add r18=U_PCB_SP,r16 /* stack pointer */ + movl out0=proc0 ;; - ld8 r18=[r18] - mov ar.rsc=0 - cover - ;; - flushrs - ;; - mov ar.bspstore=r17 - mov sp=r18 + add out0=P_ADDR,out0 ;; - loadrs - mov ar.rsc=3 + ld8 out0=[out0] ;; - alloc r16=ar.pfs,0,0,0,0 + add r16=U_PCB_B0,out0 // return to mi_startup + movl r17=mi_startup + ;; + st8 [r16]=r17 ;; - br.call.sptk.many rp=mi_startup + br.call.sptk.many rp=restorectx /* NOTREACHED */ -#if 0 - /* Load KGP with current GP. */ - or a0,zero,s0 /* save pfn */ - or gp,zero,a0 - call_pal PAL_OSF1_wrkgp /* clobbers a0, t0, t8-t11 */ - or s0,zero,a0 /* restore pfn */ - - /* - * Call alpha_init() to do pre-main initialization. - * alpha_init() gets the arguments we were called with, - * which are already in a0, a1, a2, a3, and a4. - */ - CALL(alpha_init) - - /* Set up the virtual page table pointer. */ - ldiq a0, VPTBASE - call_pal PAL_OSF1_wrvptptr /* clobbers a0, t0, t8-t11 */ - - /* - * Switch to proc0's PCB, which is at U_PCB off of proc0paddr. - */ - lda t0,proc0 /* get phys addr of pcb */ - ldq a0,P_MD_PCBPADDR(t0) - SWITCH_CONTEXT - - /* - * We've switched to a new page table base, so invalidate the TLB - * and I-stream. This happens automatically everywhere but here. - */ - ldiq a0, -2 /* TBIA */ - call_pal PAL_OSF1_tbi - call_pal PAL_imb - - /* - * Construct a fake trap frame, so execve() can work normally. - * Note that setregs() is responsible for setting its contents - * to 'reasonable' values. - */ - lda sp,-(FRAME_SIZE * 8)(sp) /* space for struct trapframe */ - mov sp, a0 /* arg is frame ptr */ - CALL(mi_startup) /* go to mi_startup()! */ - - /* - * Call exception_return, to simulate return from (fake) - * exception to user-land, running process 1, init! - */ - jmp zero, exception_return /* "And that's all she wrote." */ - -#endif END(locorestart) @@ -187,48 +119,48 @@ LEAF(locorestart, 1) * r16 pointer to signal context frame (scp) * r17 address of handler function descriptor * r18 address of new backing store (if any) - * sp pointer to sigframe + * sp+16 pointer to sigframe */ LEAF(sigcode,0) - ld8 r8=[r17],8 /* function address */ + ld8 r8=[r17],8 // function address ;; - ld8 gp=[r17] /* function's gp value */ - mov b6=r8 /* transfer to a branch register */ + ld8 gp=[r17] // function's gp value + mov b6=r8 // transfer to a branch register cover ;; - alloc r5=ar.pfs,0,0,3,0 /* register frame for call */ + alloc r5=ar.pfs,0,0,3,0 // register frame for call ;; - mov out0=r14 /* signal number */ - add r8=UC_MCONTEXT_MC_AR_BSP,r16 /* address or mc_ar_bsp */ - mov r9=ar.bsp /* save ar.bsp */ + mov out0=r14 // signal number + add r8=UC_MCONTEXT_MC_AR_BSP,r16 // address or mc_ar_bsp + mov r9=ar.bsp // save ar.bsp ;; st8 [r8]=r9 - cmp.eq p1,p0=r0,r18 /* check for new bs */ -(p1) br.cond.sptk.few 1f /* branch if not switching */ - flushrs /* flush out to old bs */ - mov ar.rsc=0 /* switch off RSE */ - add r8=UC_MCONTEXT_MC_AR_RNAT,r16 /* address of mc_ar_rnat */ + cmp.eq p1,p0=r0,r18 // check for new bs +(p1) br.cond.sptk.few 1f // branch if not switching + flushrs // flush out to old bs + mov ar.rsc=0 // switch off RSE + add r8=UC_MCONTEXT_MC_AR_RNAT,r16 // address of mc_ar_rnat ;; - mov r9=ar.rnat /* value of ar.rnat after flush */ - mov ar.bspstore=r18 /* point at new bs */ + mov r9=ar.rnat // value of ar.rnat after flush + mov ar.bspstore=r18 // point at new bs ;; - st8 [r8]=r9 /* remember ar.rnat */ - mov ar.rsc=15 /* XXX bogus value - check */ + st8 [r8]=r9 // remember ar.rnat + mov ar.rsc=15 // XXX bogus value - check invala ;; -1: mov out1=r15 /* siginfo */ - mov out2=r16 /* ucontext */ - mov r4=r17 /* save ucontext pointer from call */ - br.call.sptk.few rp=b6 /* call the signal handler */ -(p1) br.cond.sptk.few 2f /* note: p1 is preserved */ +1: mov out1=r15 // siginfo + mov out2=r16 // ucontext + mov r4=r17 // save ucontext pointer from call + br.call.sptk.few rp=b6 // call the signal handler +(p1) br.cond.sptk.few 2f // note: p1 is preserved flushrs mov ar.rsc=0 - add r8=UC_MCONTEXT_MC_AR_RNAT,r4 /* address of mc_ar_rnat */ + add r8=UC_MCONTEXT_MC_AR_RNAT,r4 // address of mc_ar_rnat ;; ld8 r9=[r8] ;; - add r8=UC_MCONTEXT_MC_AR_BSP,r4 /* address of mc_ar_bsp */ + add r8=UC_MCONTEXT_MC_AR_BSP,r4 // address of mc_ar_bsp ;; ld8 r10=[r8] ;; @@ -237,9 +169,9 @@ LEAF(sigcode,0) mov ar.rnat=r9 mov ar.rsc=15 2: - CALLSYS_NOERROR(sigreturn) /* and call sigreturn() with it. */ - mov out0=ret0 /* if that failed, get error code */ - CALLSYS_NOERROR(exit) /* and call exit() with it. */ + CALLSYS_NOERROR(sigreturn) // and call sigreturn() with it. + mov out0=ret0 // if that failed, get error code + CALLSYS_NOERROR(exit) // and call exit() with it. XLEAF(esigcode) END(sigcode) diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c index 051f941094e2..e3f99825e2d4 100644 --- a/sys/ia64/ia64/machdep.c +++ b/sys/ia64/ia64/machdep.c @@ -87,8 +87,6 @@ struct cpuhead cpuhead; struct mtx sched_lock; struct mtx Giant; -struct user *proc0paddr; - char machine[] = "ia64"; SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, ""); @@ -573,7 +571,7 @@ ia64_init() /* * Init mapping for u page(s) for proc 0 */ - proc0.p_addr = proc0paddr = + proc0.p_addr = (struct user *)pmap_steal_memory(UPAGES * PAGE_SIZE); /* @@ -593,20 +591,18 @@ ia64_init() pmap_bootstrap(); /* - * Initialize the rest of proc 0's PCB, and cache its physical - * address. - */ - proc0.p_md.md_pcbpaddr = - (struct pcb *)IA64_RR_MASK((vm_offset_t)&proc0paddr->u_pcb); - - /* + * Initialize the rest of proc 0's PCB. + * * Set the kernel sp, reserving space for an (empty) trapframe, * and make proc0's trapframe pointer point to it for sanity. + * Initialise proc0's backing store to start after u area. */ - proc0paddr->u_pcb.pcb_sp = - (u_int64_t)proc0paddr + USPACE - sizeof(struct trapframe); + proc0.p_addr->u_pcb.pcb_sp = + (u_int64_t)proc0.p_addr + USPACE - sizeof(struct trapframe) - 16; + proc0.p_addr->u_pcb.pcb_bspstore = (u_int64_t) (proc0.p_addr + 1); proc0.p_md.md_tf = - (struct trapframe *)proc0paddr->u_pcb.pcb_sp; + (struct trapframe *)(proc0.p_addr->u_pcb.pcb_sp + 16); + PCPU_SET(curproc, &proc0); /* @@ -711,6 +707,11 @@ ia64_init() } /* + * Force verbose mode for a while. + */ + bootverbose = 1; + + /* * Initialize debuggers, and break into them if appropriate. */ #ifdef DDB @@ -898,7 +899,7 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) frame->tf_r[FRAME_R3] = (u_int64_t)&(sfp->sf_uc); frame->tf_r[FRAME_R4] = (u_int64_t)catcher; frame->tf_r[FRAME_R5] = sbs; - frame->tf_r[FRAME_SP] = (unsigned long)sfp; + frame->tf_r[FRAME_SP] = (u_int64_t)sfp - 16; #ifdef DEBUG if (sigdebug & SDB_FOLLOW) diff --git a/sys/ia64/ia64/pal.S b/sys/ia64/ia64/pal.S index 081117cd9a5c..78e7db62d289 100644 --- a/sys/ia64/ia64/pal.S +++ b/sys/ia64/ia64/pal.S @@ -34,17 +34,21 @@ BSS(ia64_pal_entry, 8) * struct ia64_pal_result ia64_call_pal_static(u_int64_t proc, u_int64_t arg1, u_int64_t arg2, u_int64_t arg3) */ - NESTED(ia64_call_pal_static, 4, 5, 0, r39, r40) + NESTED(ia64_call_pal_static, 4) + .regstk 4,5,0,0 palret = loc0 entry = loc1 rpsave = loc2 pfssave = loc3 psrsave = loc4 + alloc pfssave=ar.pfs,4,5,0,0 + ;; + mov rpsave=rp + movl entry=ia64_pal_entry 1: mov palret=ip // for return address - mov rpsave=rp ;; mov psrsave=psr mov r28=in0 // procedure number @@ -62,10 +66,10 @@ psrsave = loc4 ;; br.cond.sptk b1 // call into firmware 2: mov psr.l=psrsave - mov b0=rpsave + mov rp=rpsave mov ar.pfs=pfssave ;; srlz.d - br.ret.sptk b0 + br.ret.sptk rp END(ia64_call_pal_static)
\ No newline at end of file diff --git a/sys/ia64/ia64/pal.s b/sys/ia64/ia64/pal.s index 081117cd9a5c..78e7db62d289 100644 --- a/sys/ia64/ia64/pal.s +++ b/sys/ia64/ia64/pal.s @@ -34,17 +34,21 @@ BSS(ia64_pal_entry, 8) * struct ia64_pal_result ia64_call_pal_static(u_int64_t proc, u_int64_t arg1, u_int64_t arg2, u_int64_t arg3) */ - NESTED(ia64_call_pal_static, 4, 5, 0, r39, r40) + NESTED(ia64_call_pal_static, 4) + .regstk 4,5,0,0 palret = loc0 entry = loc1 rpsave = loc2 pfssave = loc3 psrsave = loc4 + alloc pfssave=ar.pfs,4,5,0,0 + ;; + mov rpsave=rp + movl entry=ia64_pal_entry 1: mov palret=ip // for return address - mov rpsave=rp ;; mov psrsave=psr mov r28=in0 // procedure number @@ -62,10 +66,10 @@ psrsave = loc4 ;; br.cond.sptk b1 // call into firmware 2: mov psr.l=psrsave - mov b0=rpsave + mov rp=rpsave mov ar.pfs=pfssave ;; srlz.d - br.ret.sptk b0 + br.ret.sptk rp END(ia64_call_pal_static)
\ No newline at end of file diff --git a/sys/ia64/ia64/pmap.c b/sys/ia64/ia64/pmap.c index a8534454e504..f080f1b6f0d9 100644 --- a/sys/ia64/ia64/pmap.c +++ b/sys/ia64/ia64/pmap.c @@ -667,12 +667,6 @@ pmap_swapin_proc(p) vm_page_wakeup(m); vm_page_flag_set(m, PG_MAPPED | PG_WRITEABLE); } - - /* - * The pcb may be at a different physical address now so cache the - * new address. - */ - p->p_md.md_pcbpaddr = (void*) vtophys((vm_offset_t) &p->p_addr->u_pcb); } /*************************************************** diff --git a/sys/ia64/ia64/ssc.c b/sys/ia64/ia64/ssc.c index ad6e4ed9b3dd..efc6683a0e75 100644 --- a/sys/ia64/ia64/ssc.c +++ b/sys/ia64/ia64/ssc.c @@ -97,7 +97,7 @@ ssc(u_int64_t in0, u_int64_t in1, u_int64_t in2, u_int64_t in3, int which) return ret0; } -void +static void ssccnputc(dev_t dev, int c) { ssc(c, 0, 0, 0, SSC_PUTCHAR); @@ -106,13 +106,22 @@ ssccnputc(dev_t dev, int c) static int ssccngetc(dev_t dev) { - return -1; + int c; + do { + c = ssc(0, 0, 0, 0, SSC_GETCHAR); + } while (c == 0); + + return c; } static int ssccncheckc(dev_t dev) { - return -1; + int c; + c = ssc(0, 0, 0, 0, SSC_GETCHAR); + if (!c) + return -1; + return c; } static int diff --git a/sys/ia64/ia64/support.S b/sys/ia64/ia64/support.S index 91e3856fde72..a5b5db79d70f 100644 --- a/sys/ia64/ia64/support.S +++ b/sys/ia64/ia64/support.S @@ -63,7 +63,7 @@ * fu{byte,word} : fetch a byte (word) from user memory */ - LEAF(suword, 1) +LEAF(suword, 1) #if 0 LDGP(pv) @@ -83,9 +83,9 @@ mov zero, v0 RET #endif - END(suword) +END(suword) - LEAF(subyte, 1) +LEAF(subyte, 1) #if 0 LDGP(pv) @@ -110,9 +110,9 @@ mov zero, v0 RET #endif - END(subyte) +END(subyte) - LEAF(fuword, 1) +LEAF(fuword, 1) #if 0 LDGP(pv) @@ -131,9 +131,9 @@ RET #endif - END(fuword) +END(fuword) - LEAF(fubyte, 1) +LEAF(fubyte, 1) #if 0 LDGP(pv) @@ -153,9 +153,9 @@ RET #endif - END(fubyte) +END(fubyte) - LEAF(suibyte, 2) +LEAF(suibyte, 2) #if 0 ldiq v0, -1 RET @@ -170,7 +170,7 @@ ldiq v0, -1 RET #endif - END(fusufault) +END(fusufault) LEAF(fswintrberr, 0) XLEAF(fuswintr) /* XXX what is a 'word'? */ @@ -180,7 +180,7 @@ XLEAF(suswintr) /* XXX what is a 'word'? */ ldiq v0, -1 RET #endif - END(fswintrberr) +END(fswintrberr) /**************************************************************************/ @@ -191,406 +191,266 @@ XLEAF(suswintr) /* XXX what is a 'word'? */ * int copystr(char *from, char *to, size_t len, size_t *lenp); */ LEAF(copystr, 4) -#if 0 - LDGP(pv) - - mov a2, t0 /* t0 = i = len */ - beq a2, Lcopystr2 /* if (len == 0), bail out */ - -Lcopystr1: - ldq_u t1, 0(a0) /* t1 = *from */ - extbl t1, a0, t1 - ldq_u t3, 0(a1) /* set up t2 with quad around *to */ - insbl t1, a1, t2 - mskbl t3, a1, t3 - or t3, t2, t3 /* add *from to quad around *to */ - stq_u t3, 0(a1) /* write out that quad */ + mov r14=in2 // r14 = i = len + cmp.eq p6,p0=r0,in2 +(p6) br.cond.spnt.few 2f // if (len == 0), bail out - subl a2, 1, a2 /* len-- */ - beq t1, Lcopystr2 /* if (*from == 0), bail out */ - addq a1, 1, a1 /* to++ */ - addq a0, 1, a0 /* from++ */ - bne a2, Lcopystr1 /* if (len != 0) copy more */ +1: ld1 r15=[in0],1 // read one byte + ;; + st1 [in1]=r15,1 // write that byte + add in2=-1,in2 // len-- + ;; + cmp.eq p6,p0=r0,r15 + cmp.ne p7,p0=r0,in2 + ;; +(p6) br.cond.spnt.few 2f // if (*from == 0), bail out +(p7) br.cond.sptk.few 1b // if (len != 0) copy more -Lcopystr2: - beq a3, Lcopystr3 /* if (lenp != NULL) */ - subl t0, a2, t0 /* *lenp = (i - len) */ - stq t0, 0(a3) -Lcopystr3: - beq t1, Lcopystr4 /* *from == '\0'; leave quietly */ - - ldiq v0, ENAMETOOLONG /* *from != '\0'; error. */ - RET - -Lcopystr4: - mov zero, v0 /* return 0. */ - RET -#endif - END(copystr) - -LEAF(copyinstr, 4) -#if 0 - LDGP(pv) - lda sp, -16(sp) /* set up stack frame */ - stq ra, (16-8)(sp) /* save ra */ - ldiq t0, VM_MAXUSER_ADDRESS /* make sure that src addr */ - cmpult a0, t0, t1 /* is in user space. */ - beq t1, copyerr /* if it's not, error out. */ - lda v0, copyerr /* set up fault handler. */ - .set noat - ldq at_reg, curproc - ldq at_reg, P_ADDR(at_reg) - stq v0, U_PCB_ONFAULT(at_reg) - .set at - CALL(copystr) /* do the copy. */ - .set noat - ldq at_reg, curproc /* kill the fault handler. */ - ldq at_reg, P_ADDR(at_reg) - stq zero, U_PCB_ONFAULT(at_reg) - .set at - ldq ra, (16-8)(sp) /* restore ra. */ - lda sp, 16(sp) /* kill stack frame. */ - RET /* v0 left over from copystr */ -#endif - END(copyinstr) +2: cmp.eq p6,p0=r0,in3 +(p6) br.cond.dpnt.few 3f // if (lenp != NULL) + sub r14=in2,r14 // *lenp = (i - len) + ;; + st8 [in3]=r14 + +3: cmp.eq p6,p0=r0,r15 +(p6) br.cond.spnt.few 4f // *from == '\0'; leave quietly -LEAF(copyoutstr, 4) -#if 0 - LDGP(pv) - lda sp, -16(sp) /* set up stack frame */ - stq ra, (16-8)(sp) /* save ra */ - ldiq t0, VM_MAXUSER_ADDRESS /* make sure that dest addr */ - cmpult a1, t0, t1 /* is in user space. */ - beq t1, copyerr /* if it's not, error out. */ - lda v0, copyerr /* set up fault handler. */ - .set noat - ldq at_reg, curproc - ldq at_reg, P_ADDR(at_reg) - stq v0, U_PCB_ONFAULT(at_reg) - .set at - CALL(copystr) /* do the copy. */ - .set noat - ldq at_reg, curproc /* kill the fault handler. */ - ldq at_reg, P_ADDR(at_reg) - stq zero, U_PCB_ONFAULT(at_reg) - .set at - ldq ra, (16-8)(sp) /* restore ra. */ - lda sp, 16(sp) /* kill stack frame. */ - RET /* v0 left over from copystr */ -#endif - END(copyoutstr) + mov ret0=ENAMETOOLONG // *from != '\0'; error. + br.ret.sptk.few rp -/* - * Alternative memory mover - */ - LEAF(memcpy,3) -#if 0 - mov a0,t0 - mov a1,a0 - mov t0,a1 - br bcopy -#endif - END(memcpy) +4: mov ret0=0 // return 0. + br.ret.sptk.few rp -/* - * Copy a bytes within the kernel's address space. - * - * In the kernel, bcopy() doesn't have to handle the overlapping - * case; that's that ovbcopy() is for. However, it doesn't hurt - * to do both in bcopy, and it does provide a measure of safety. - * - * void bcopy(char *from, char *to, size_t len); - * void ovbcopy(char *from, char *to, size_t len); - */ -LEAF(bcopy,3) -XLEAF(ovbcopy) -#if 0 - /* Check for negative length */ - ble a2,bcopy_done +END(copystr) - /* Check for overlap */ - subq a1,a0,t5 - cmpult t5,a2,t5 - bne t5,bcopy_overlap +NESTED(copyinstr, 4) + alloc loc0=ar.pfs,4,3,4,0 + mov loc1=rp - /* a3 = end address */ - addq a0,a2,a3 + movl loc2=VM_MAXUSER_ADDRESS // make sure that src addr + ;; + cmp.ltu p6,p0=in0,loc2 // is in user space. + ;; +(p6) br.cond.spnt.few copyerr // if it's not, error out. + movl r14=copyerr // set up fault handler. + add r15=GD_CURPROC,r13 // find curproc + ;; + ld8 r15=[r15] + ;; + add r15=P_ADDR,r15 // find pcb + ;; + ld8 r15=[r15] + ;; + add loc2=U_PCB_ONFAULT,r15 + ;; + st8 [loc2]=r14 + ;; + mov out0=in0 + mov out1=in1 + mov out2=in2 + mov out3=in3 + ;; + br.call.sptk.few rp=copystr // do the copy. + st8 [loc2]=r0 // kill the fault handler. + mov rp=loc1 // restore ra. + br.ret.sptk.few rp // ret0 left over from copystr - /* Get the first word */ - ldq_u t2,0(a0) +END(copyinstr) - /* Do they have the same alignment? */ - xor a0,a1,t0 - and t0,7,t0 - and a1,7,t1 - bne t0,bcopy_different_alignment +NESTED(copyoutstr, 4) + alloc loc0=ar.pfs,4,3,4,0 + mov loc1=rp - /* src & dst have same alignment */ - beq t1,bcopy_all_aligned + movl loc2=VM_MAXUSER_ADDRESS // make sure that dest addr + ;; + cmp.ltu p6,p0=in1,loc2 // is in user space. + ;; +(p6) br.cond.spnt.few copyerr // if it's not, error out. + movl r14=copyerr // set up fault handler. + add r15=GD_CURPROC,r13 // find curproc + ;; + ld8 r15=[r15] + ;; + add r15=P_ADDR,r15 // find pcb + ;; + ld8 r15=[r15] + ;; + add loc2=U_PCB_ONFAULT,r15 + ;; + st8 [loc2]=r14 + ;; + mov out0=in0 + mov out1=in1 + mov out2=in2 + mov out3=in3 + ;; + br.call.sptk.few rp=copystr // do the copy. + st8 [loc2]=r0 // kill the fault handler. + mov rp=loc1 // restore ra. + br.ret.sptk.few rp // ret0 left over from copystr - ldq_u t3,0(a1) - addq a2,t1,a2 - mskqh t2,a0,t2 - mskql t3,a0,t3 - or t2,t3,t2 +END(copyoutstr) - /* Dst is 8-byte aligned */ - -bcopy_all_aligned: - /* If less than 8 bytes,skip loop */ - subq a2,1,t0 - and a2,7,a2 - bic t0,7,t0 - beq t0,bcopy_samealign_lp_end +/* + * Not the fastest bcopy in the world. + */ +LEAF(bcopy, 3) +XLEAF(ovbcopy) -bcopy_samealign_lp: - stq_u t2,0(a1) - addq a1,8,a1 - ldq_u t2,8(a0) - subq t0,8,t0 - addq a0,8,a0 - bne t0,bcopy_samealign_lp + mov ret0=r0 // return zero for copy{in,out} + ;; + cmp.le p6,p0=in2,r0 // bail if len <= 0 +(p6) br.ret.spnt.few rp -bcopy_samealign_lp_end: - /* If we're done, exit */ - bne a2,bcopy_small_left - stq_u t2,0(a1) - RET + sub r14=in1,in0 ;; // check for overlap + cmp.ltu p6,p0=r14,in2 // dst-src < len +(p6) br.cond.spnt.few 5f -bcopy_small_left: - mskql t2,a2,t4 - ldq_u t3,0(a1) - mskqh t3,a2,t3 - or t4,t3,t4 - stq_u t4,0(a1) - RET + extr.u r14=in0,0,3 // src & 7 + extr.u r15=in1,0,3 ;; // dst & 7 + cmp.eq p6,p0=r14,r15 // different alignment? +(p6) br.cond.spnt.few 2f // branch if same alignment -bcopy_different_alignment: - /* - * this is the fun part - */ - addq a0,a2,a3 - cmpule a2,8,t0 - bne t0,bcopy_da_finish +1: ld1 r14=[in0],1 ;; // copy bytewise + st1 [in1]=r14,1 + add in2=-1,in2 ;; // len-- + cmp.ne p6,p0=r0,in2 +(p6) br.cond.dptk.few 1b // loop + br.ret.sptk.few rp // done - beq t1,bcopy_da_noentry +2: cmp.eq p6,p0=r14,r0 // aligned? +(p6) br.cond.sptk.few 4f - /* Do the initial partial word */ - subq zero,a1,t0 - and t0,7,t0 - ldq_u t3,7(a0) - extql t2,a0,t2 - extqh t3,a0,t3 - or t2,t3,t5 - insql t5,a1,t5 - ldq_u t6,0(a1) - mskql t6,a1,t6 - or t5,t6,t5 - stq_u t5,0(a1) - addq a0,t0,a0 - addq a1,t0,a1 - subq a2,t0,a2 - ldq_u t2,0(a0) +3: ld1 r14=[in0],1 ;; // copy bytewise + st1 [in1]=r14,1 + extr.u r15=in0,0,3 // src & 7 + add in2=-1,in2 ;; // len-- + cmp.eq p6,p0=r0,in2 // done? + cmp.eq p7,p0=r0,r15 ;; // aligned now? +(p6) br.ret.spnt.few rp // return if done +(p7) br.cond.spnt.few 4f // go to main copy + br.cond.sptk.few 3b // more bytes to copy -bcopy_da_noentry: - subq a2,1,t0 - bic t0,7,t0 - and a2,7,a2 - beq t0,bcopy_da_finish2 + // At this point, in2 is non-zero -bcopy_da_lp: - ldq_u t3,7(a0) - addq a0,8,a0 - extql t2,a0,t4 - extqh t3,a0,t5 - subq t0,8,t0 - or t4,t5,t5 - stq t5,0(a1) - addq a1,8,a1 - beq t0,bcopy_da_finish1 - ldq_u t2,7(a0) - addq a0,8,a0 - extql t3,a0,t4 - extqh t2,a0,t5 - subq t0,8,t0 - or t4,t5,t5 - stq t5,0(a1) - addq a1,8,a1 - bne t0,bcopy_da_lp +4: mov r14=8 ;; + cmp.ltu p6,p0=in2,r14 ;; // len < 8? +(p6) br.cond.spnt.few 1b // byte copy the end + ld8 r15=[in0],8 ;; // copy word + st8 [in1]=r15,8 + add in2=-8,in2 ;; // len -= 8 + cmp.ne p6,p0=r0,in2 // done? +(p6) br.cond.spnt.few 4b // again -bcopy_da_finish2: - /* Do the last new word */ - mov t2,t3 + br.ret.sptk.few rp // return -bcopy_da_finish1: - /* Do the last partial word */ - ldq_u t2,-1(a3) - extql t3,a0,t3 - extqh t2,a0,t2 - or t2,t3,t2 - br zero,bcopy_samealign_lp_end + // Don't bother optimising overlap case -bcopy_da_finish: - /* Do the last word in the next source word */ - ldq_u t3,-1(a3) - extql t2,a0,t2 - extqh t3,a0,t3 - or t2,t3,t2 - insqh t2,a1,t3 - insql t2,a1,t2 - lda t4,-1(zero) - mskql t4,a2,t5 - cmovne t5,t5,t4 - insqh t4,a1,t5 - insql t4,a1,t4 - addq a1,a2,a4 - ldq_u t6,0(a1) - ldq_u t7,-1(a4) - bic t6,t4,t6 - bic t7,t5,t7 - and t2,t4,t2 - and t3,t5,t3 - or t2,t6,t2 - or t3,t7,t3 - stq_u t3,-1(a4) - stq_u t2,0(a1) - RET +5: add in0=in0,in2 + add in1=in1,in2 ;; + add in0=-1,in0 + add in1=-1,in1 ;; -bcopy_overlap: - /* - * Basically equivalent to previous case, only backwards. - * Not quite as highly optimized - */ - addq a0,a2,a3 - addq a1,a2,a4 +6: ld1 r14=[in0],-1 ;; + st1 [in1]=r14,-1 + add in2=-1,in2 ;; + cmp.ne p6,p0=r0,in2 +(p6) br.cond.spnt.few 6b - /* less than 8 bytes - don't worry about overlap */ - cmpule a2,8,t0 - bne t0,bcopy_ov_short + br.ret.sptk.few rp - /* Possibly do a partial first word */ - and a4,7,t4 - beq t4,bcopy_ov_nostart2 - subq a3,t4,a3 - subq a4,t4,a4 - ldq_u t1,0(a3) - subq a2,t4,a2 - ldq_u t2,7(a3) - ldq t3,0(a4) - extql t1,a3,t1 - extqh t2,a3,t2 - or t1,t2,t1 - mskqh t3,t4,t3 - mskql t1,t4,t1 - or t1,t3,t1 - stq t1,0(a4) +END(bcopy) -bcopy_ov_nostart2: - bic a2,7,t4 - and a2,7,a2 - beq t4,bcopy_ov_lp_end +LEAF(memcpy,3) + + mov r14=in0 ;; + mov in0=in1 ;; + mov in1=r14 + br.cond.sptk.few bcopy + +END(memcpy) + +NESTED(copyin, 3) + + alloc loc0=ar.pfs,3,3,3,0 + mov loc1=rp -bcopy_ov_lp: - /* This could be more pipelined, but it doesn't seem worth it */ - ldq_u t0,-8(a3) - subq a4,8,a4 - ldq_u t1,-1(a3) - subq a3,8,a3 - extql t0,a3,t0 - extqh t1,a3,t1 - subq t4,8,t4 - or t0,t1,t0 - stq t0,0(a4) - bne t4,bcopy_ov_lp + movl loc2=VM_MAXUSER_ADDRESS // make sure that src addr + ;; + cmp.ltu p6,p0=in0,loc2 // is in user space. + ;; +(p6) br.cond.spnt.few copyerr // if it's not, error out. + movl r14=copyerr // set up fault handler. + add r15=GD_CURPROC,r13 // find curproc + ;; + ld8 r15=[r15] + ;; + add r15=P_ADDR,r15 // find pcb + ;; + ld8 r15=[r15] + ;; + add loc2=U_PCB_ONFAULT,r15 + ;; + st8 [loc2]=r14 + ;; + mov out0=in0 + mov out1=in1 + mov out2=in2 + ;; + br.call.sptk.few rp=bcopy // do the copy. + st8 [loc2]=r0 // kill the fault handler. + mov rp=loc1 // restore ra. + br.ret.sptk.few rp // ret0 left over from bcopy + +END(copyin) -bcopy_ov_lp_end: - beq a2,bcopy_done +NESTED(copyout, 3) + + alloc loc0=ar.pfs,3,3,3,0 + mov loc1=rp - ldq_u t0,0(a0) - ldq_u t1,7(a0) - ldq_u t2,0(a1) - extql t0,a0,t0 - extqh t1,a0,t1 - or t0,t1,t0 - insql t0,a1,t0 - mskql t2,a1,t2 - or t2,t0,t2 - stq_u t2,0(a1) + movl loc2=VM_MAXUSER_ADDRESS // make sure that dest addr + ;; + cmp.ltu p6,p0=in1,loc2 // is in user space. + ;; +(p6) br.cond.spnt.few copyerr // if it's not, error out. + movl r14=copyerr // set up fault handler. + add r15=GD_CURPROC,r13 // find curproc + ;; + ld8 r15=[r15] + ;; + add r15=P_ADDR,r15 // find pcb + ;; + ld8 r15=[r15] + ;; + add loc2=U_PCB_ONFAULT,r15 + ;; + st8 [loc2]=r14 + ;; + mov out0=in0 + mov out1=in1 + mov out2=in2 + ;; + br.call.sptk.few rp=bcopy // do the copy. + st8 [loc2]=r0 // kill the fault handler. + mov rp=loc1 // restore ra. + br.ret.sptk.few rp // ret0 left over from bcopy + +END(copyout) -bcopy_done: - RET +LEAF(copyerr, 0) -bcopy_ov_short: - ldq_u t2,0(a0) - br zero,bcopy_da_finish -#endif - END(bcopy) + add r14=GD_CURPROC,r13 ;; // find curproc + ld8 r14=[r14] ;; + add r14=P_ADDR,r14 ;; // curproc->p_addr + ld8 r14=[r14] ;; + add r14=U_PCB_ONFAULT,r14 ;; // &curproc->p_addr->u_pcb.pcb_onfault + st8 [r14]=r0 // reset fault handler -LEAF(copyin, 3) -#if 0 - LDGP(pv) - lda sp, -16(sp) /* set up stack frame */ - stq ra, (16-8)(sp) /* save ra */ - ldiq t0, VM_MAXUSER_ADDRESS /* make sure that src addr */ - cmpult a0, t0, t1 /* is in user space. */ - beq t1, copyerr /* if it's not, error out. */ - lda v0, copyerr /* set up fault handler. */ - .set noat - ldq at_reg, curproc - ldq at_reg, P_ADDR(at_reg) - stq v0, U_PCB_ONFAULT(at_reg) - .set at - CALL(bcopy) /* do the copy. */ - .set noat - ldq at_reg, curproc /* kill the fault handler. */ - ldq at_reg, P_ADDR(at_reg) - stq zero, U_PCB_ONFAULT(at_reg) - .set at - ldq ra, (16-8)(sp) /* restore ra. */ - lda sp, 16(sp) /* kill stack frame. */ - mov zero, v0 /* return 0. */ - RET -#endif - END(copyin) - -LEAF(copyout, 3) -#if 0 - LDGP(pv) - lda sp, -16(sp) /* set up stack frame */ - stq ra, (16-8)(sp) /* save ra */ - ldiq t0, VM_MAXUSER_ADDRESS /* make sure that dest addr */ - cmpult a1, t0, t1 /* is in user space. */ - beq t1, copyerr /* if it's not, error out. */ - lda v0, copyerr /* set up fault handler. */ - .set noat - ldq at_reg, curproc - ldq at_reg, P_ADDR(at_reg) - stq v0, U_PCB_ONFAULT(at_reg) - .set at - CALL(bcopy) /* do the copy. */ - .set noat - ldq at_reg, curproc /* kill the fault handler. */ - ldq at_reg, P_ADDR(at_reg) - stq zero, U_PCB_ONFAULT(at_reg) - .set at - ldq ra, (16-8)(sp) /* restore ra. */ - lda sp, 16(sp) /* kill stack frame. */ - mov zero, v0 /* return 0. */ - RET -#endif - END(copyout) + mov ret0=EFAULT // return EFAULT + br.ret.sptk.few rp -LEAF(copyerr, 0) -#if 0 - ldq t0, curproc - ldq t0, P_ADDR(t0) - stq zero, U_PCB_ONFAULT(t0) /* reset fault handler. */ - ldq ra, (16-8)(sp) /* restore ra. */ - lda sp, 16(sp) /* kill stack frame. */ - ldiq v0, EFAULT /* return EFAULT. */ - RET -#endif - END(copyerr) +END(copyerr) /**************************************************************************/ diff --git a/sys/ia64/ia64/support.s b/sys/ia64/ia64/support.s index 91e3856fde72..a5b5db79d70f 100644 --- a/sys/ia64/ia64/support.s +++ b/sys/ia64/ia64/support.s @@ -63,7 +63,7 @@ * fu{byte,word} : fetch a byte (word) from user memory */ - LEAF(suword, 1) +LEAF(suword, 1) #if 0 LDGP(pv) @@ -83,9 +83,9 @@ mov zero, v0 RET #endif - END(suword) +END(suword) - LEAF(subyte, 1) +LEAF(subyte, 1) #if 0 LDGP(pv) @@ -110,9 +110,9 @@ mov zero, v0 RET #endif - END(subyte) +END(subyte) - LEAF(fuword, 1) +LEAF(fuword, 1) #if 0 LDGP(pv) @@ -131,9 +131,9 @@ RET #endif - END(fuword) +END(fuword) - LEAF(fubyte, 1) +LEAF(fubyte, 1) #if 0 LDGP(pv) @@ -153,9 +153,9 @@ RET #endif - END(fubyte) +END(fubyte) - LEAF(suibyte, 2) +LEAF(suibyte, 2) #if 0 ldiq v0, -1 RET @@ -170,7 +170,7 @@ ldiq v0, -1 RET #endif - END(fusufault) +END(fusufault) LEAF(fswintrberr, 0) XLEAF(fuswintr) /* XXX what is a 'word'? */ @@ -180,7 +180,7 @@ XLEAF(suswintr) /* XXX what is a 'word'? */ ldiq v0, -1 RET #endif - END(fswintrberr) +END(fswintrberr) /**************************************************************************/ @@ -191,406 +191,266 @@ XLEAF(suswintr) /* XXX what is a 'word'? */ * int copystr(char *from, char *to, size_t len, size_t *lenp); */ LEAF(copystr, 4) -#if 0 - LDGP(pv) - - mov a2, t0 /* t0 = i = len */ - beq a2, Lcopystr2 /* if (len == 0), bail out */ - -Lcopystr1: - ldq_u t1, 0(a0) /* t1 = *from */ - extbl t1, a0, t1 - ldq_u t3, 0(a1) /* set up t2 with quad around *to */ - insbl t1, a1, t2 - mskbl t3, a1, t3 - or t3, t2, t3 /* add *from to quad around *to */ - stq_u t3, 0(a1) /* write out that quad */ + mov r14=in2 // r14 = i = len + cmp.eq p6,p0=r0,in2 +(p6) br.cond.spnt.few 2f // if (len == 0), bail out - subl a2, 1, a2 /* len-- */ - beq t1, Lcopystr2 /* if (*from == 0), bail out */ - addq a1, 1, a1 /* to++ */ - addq a0, 1, a0 /* from++ */ - bne a2, Lcopystr1 /* if (len != 0) copy more */ +1: ld1 r15=[in0],1 // read one byte + ;; + st1 [in1]=r15,1 // write that byte + add in2=-1,in2 // len-- + ;; + cmp.eq p6,p0=r0,r15 + cmp.ne p7,p0=r0,in2 + ;; +(p6) br.cond.spnt.few 2f // if (*from == 0), bail out +(p7) br.cond.sptk.few 1b // if (len != 0) copy more -Lcopystr2: - beq a3, Lcopystr3 /* if (lenp != NULL) */ - subl t0, a2, t0 /* *lenp = (i - len) */ - stq t0, 0(a3) -Lcopystr3: - beq t1, Lcopystr4 /* *from == '\0'; leave quietly */ - - ldiq v0, ENAMETOOLONG /* *from != '\0'; error. */ - RET - -Lcopystr4: - mov zero, v0 /* return 0. */ - RET -#endif - END(copystr) - -LEAF(copyinstr, 4) -#if 0 - LDGP(pv) - lda sp, -16(sp) /* set up stack frame */ - stq ra, (16-8)(sp) /* save ra */ - ldiq t0, VM_MAXUSER_ADDRESS /* make sure that src addr */ - cmpult a0, t0, t1 /* is in user space. */ - beq t1, copyerr /* if it's not, error out. */ - lda v0, copyerr /* set up fault handler. */ - .set noat - ldq at_reg, curproc - ldq at_reg, P_ADDR(at_reg) - stq v0, U_PCB_ONFAULT(at_reg) - .set at - CALL(copystr) /* do the copy. */ - .set noat - ldq at_reg, curproc /* kill the fault handler. */ - ldq at_reg, P_ADDR(at_reg) - stq zero, U_PCB_ONFAULT(at_reg) - .set at - ldq ra, (16-8)(sp) /* restore ra. */ - lda sp, 16(sp) /* kill stack frame. */ - RET /* v0 left over from copystr */ -#endif - END(copyinstr) +2: cmp.eq p6,p0=r0,in3 +(p6) br.cond.dpnt.few 3f // if (lenp != NULL) + sub r14=in2,r14 // *lenp = (i - len) + ;; + st8 [in3]=r14 + +3: cmp.eq p6,p0=r0,r15 +(p6) br.cond.spnt.few 4f // *from == '\0'; leave quietly -LEAF(copyoutstr, 4) -#if 0 - LDGP(pv) - lda sp, -16(sp) /* set up stack frame */ - stq ra, (16-8)(sp) /* save ra */ - ldiq t0, VM_MAXUSER_ADDRESS /* make sure that dest addr */ - cmpult a1, t0, t1 /* is in user space. */ - beq t1, copyerr /* if it's not, error out. */ - lda v0, copyerr /* set up fault handler. */ - .set noat - ldq at_reg, curproc - ldq at_reg, P_ADDR(at_reg) - stq v0, U_PCB_ONFAULT(at_reg) - .set at - CALL(copystr) /* do the copy. */ - .set noat - ldq at_reg, curproc /* kill the fault handler. */ - ldq at_reg, P_ADDR(at_reg) - stq zero, U_PCB_ONFAULT(at_reg) - .set at - ldq ra, (16-8)(sp) /* restore ra. */ - lda sp, 16(sp) /* kill stack frame. */ - RET /* v0 left over from copystr */ -#endif - END(copyoutstr) + mov ret0=ENAMETOOLONG // *from != '\0'; error. + br.ret.sptk.few rp -/* - * Alternative memory mover - */ - LEAF(memcpy,3) -#if 0 - mov a0,t0 - mov a1,a0 - mov t0,a1 - br bcopy -#endif - END(memcpy) +4: mov ret0=0 // return 0. + br.ret.sptk.few rp -/* - * Copy a bytes within the kernel's address space. - * - * In the kernel, bcopy() doesn't have to handle the overlapping - * case; that's that ovbcopy() is for. However, it doesn't hurt - * to do both in bcopy, and it does provide a measure of safety. - * - * void bcopy(char *from, char *to, size_t len); - * void ovbcopy(char *from, char *to, size_t len); - */ -LEAF(bcopy,3) -XLEAF(ovbcopy) -#if 0 - /* Check for negative length */ - ble a2,bcopy_done +END(copystr) - /* Check for overlap */ - subq a1,a0,t5 - cmpult t5,a2,t5 - bne t5,bcopy_overlap +NESTED(copyinstr, 4) + alloc loc0=ar.pfs,4,3,4,0 + mov loc1=rp - /* a3 = end address */ - addq a0,a2,a3 + movl loc2=VM_MAXUSER_ADDRESS // make sure that src addr + ;; + cmp.ltu p6,p0=in0,loc2 // is in user space. + ;; +(p6) br.cond.spnt.few copyerr // if it's not, error out. + movl r14=copyerr // set up fault handler. + add r15=GD_CURPROC,r13 // find curproc + ;; + ld8 r15=[r15] + ;; + add r15=P_ADDR,r15 // find pcb + ;; + ld8 r15=[r15] + ;; + add loc2=U_PCB_ONFAULT,r15 + ;; + st8 [loc2]=r14 + ;; + mov out0=in0 + mov out1=in1 + mov out2=in2 + mov out3=in3 + ;; + br.call.sptk.few rp=copystr // do the copy. + st8 [loc2]=r0 // kill the fault handler. + mov rp=loc1 // restore ra. + br.ret.sptk.few rp // ret0 left over from copystr - /* Get the first word */ - ldq_u t2,0(a0) +END(copyinstr) - /* Do they have the same alignment? */ - xor a0,a1,t0 - and t0,7,t0 - and a1,7,t1 - bne t0,bcopy_different_alignment +NESTED(copyoutstr, 4) + alloc loc0=ar.pfs,4,3,4,0 + mov loc1=rp - /* src & dst have same alignment */ - beq t1,bcopy_all_aligned + movl loc2=VM_MAXUSER_ADDRESS // make sure that dest addr + ;; + cmp.ltu p6,p0=in1,loc2 // is in user space. + ;; +(p6) br.cond.spnt.few copyerr // if it's not, error out. + movl r14=copyerr // set up fault handler. + add r15=GD_CURPROC,r13 // find curproc + ;; + ld8 r15=[r15] + ;; + add r15=P_ADDR,r15 // find pcb + ;; + ld8 r15=[r15] + ;; + add loc2=U_PCB_ONFAULT,r15 + ;; + st8 [loc2]=r14 + ;; + mov out0=in0 + mov out1=in1 + mov out2=in2 + mov out3=in3 + ;; + br.call.sptk.few rp=copystr // do the copy. + st8 [loc2]=r0 // kill the fault handler. + mov rp=loc1 // restore ra. + br.ret.sptk.few rp // ret0 left over from copystr - ldq_u t3,0(a1) - addq a2,t1,a2 - mskqh t2,a0,t2 - mskql t3,a0,t3 - or t2,t3,t2 +END(copyoutstr) - /* Dst is 8-byte aligned */ - -bcopy_all_aligned: - /* If less than 8 bytes,skip loop */ - subq a2,1,t0 - and a2,7,a2 - bic t0,7,t0 - beq t0,bcopy_samealign_lp_end +/* + * Not the fastest bcopy in the world. + */ +LEAF(bcopy, 3) +XLEAF(ovbcopy) -bcopy_samealign_lp: - stq_u t2,0(a1) - addq a1,8,a1 - ldq_u t2,8(a0) - subq t0,8,t0 - addq a0,8,a0 - bne t0,bcopy_samealign_lp + mov ret0=r0 // return zero for copy{in,out} + ;; + cmp.le p6,p0=in2,r0 // bail if len <= 0 +(p6) br.ret.spnt.few rp -bcopy_samealign_lp_end: - /* If we're done, exit */ - bne a2,bcopy_small_left - stq_u t2,0(a1) - RET + sub r14=in1,in0 ;; // check for overlap + cmp.ltu p6,p0=r14,in2 // dst-src < len +(p6) br.cond.spnt.few 5f -bcopy_small_left: - mskql t2,a2,t4 - ldq_u t3,0(a1) - mskqh t3,a2,t3 - or t4,t3,t4 - stq_u t4,0(a1) - RET + extr.u r14=in0,0,3 // src & 7 + extr.u r15=in1,0,3 ;; // dst & 7 + cmp.eq p6,p0=r14,r15 // different alignment? +(p6) br.cond.spnt.few 2f // branch if same alignment -bcopy_different_alignment: - /* - * this is the fun part - */ - addq a0,a2,a3 - cmpule a2,8,t0 - bne t0,bcopy_da_finish +1: ld1 r14=[in0],1 ;; // copy bytewise + st1 [in1]=r14,1 + add in2=-1,in2 ;; // len-- + cmp.ne p6,p0=r0,in2 +(p6) br.cond.dptk.few 1b // loop + br.ret.sptk.few rp // done - beq t1,bcopy_da_noentry +2: cmp.eq p6,p0=r14,r0 // aligned? +(p6) br.cond.sptk.few 4f - /* Do the initial partial word */ - subq zero,a1,t0 - and t0,7,t0 - ldq_u t3,7(a0) - extql t2,a0,t2 - extqh t3,a0,t3 - or t2,t3,t5 - insql t5,a1,t5 - ldq_u t6,0(a1) - mskql t6,a1,t6 - or t5,t6,t5 - stq_u t5,0(a1) - addq a0,t0,a0 - addq a1,t0,a1 - subq a2,t0,a2 - ldq_u t2,0(a0) +3: ld1 r14=[in0],1 ;; // copy bytewise + st1 [in1]=r14,1 + extr.u r15=in0,0,3 // src & 7 + add in2=-1,in2 ;; // len-- + cmp.eq p6,p0=r0,in2 // done? + cmp.eq p7,p0=r0,r15 ;; // aligned now? +(p6) br.ret.spnt.few rp // return if done +(p7) br.cond.spnt.few 4f // go to main copy + br.cond.sptk.few 3b // more bytes to copy -bcopy_da_noentry: - subq a2,1,t0 - bic t0,7,t0 - and a2,7,a2 - beq t0,bcopy_da_finish2 + // At this point, in2 is non-zero -bcopy_da_lp: - ldq_u t3,7(a0) - addq a0,8,a0 - extql t2,a0,t4 - extqh t3,a0,t5 - subq t0,8,t0 - or t4,t5,t5 - stq t5,0(a1) - addq a1,8,a1 - beq t0,bcopy_da_finish1 - ldq_u t2,7(a0) - addq a0,8,a0 - extql t3,a0,t4 - extqh t2,a0,t5 - subq t0,8,t0 - or t4,t5,t5 - stq t5,0(a1) - addq a1,8,a1 - bne t0,bcopy_da_lp +4: mov r14=8 ;; + cmp.ltu p6,p0=in2,r14 ;; // len < 8? +(p6) br.cond.spnt.few 1b // byte copy the end + ld8 r15=[in0],8 ;; // copy word + st8 [in1]=r15,8 + add in2=-8,in2 ;; // len -= 8 + cmp.ne p6,p0=r0,in2 // done? +(p6) br.cond.spnt.few 4b // again -bcopy_da_finish2: - /* Do the last new word */ - mov t2,t3 + br.ret.sptk.few rp // return -bcopy_da_finish1: - /* Do the last partial word */ - ldq_u t2,-1(a3) - extql t3,a0,t3 - extqh t2,a0,t2 - or t2,t3,t2 - br zero,bcopy_samealign_lp_end + // Don't bother optimising overlap case -bcopy_da_finish: - /* Do the last word in the next source word */ - ldq_u t3,-1(a3) - extql t2,a0,t2 - extqh t3,a0,t3 - or t2,t3,t2 - insqh t2,a1,t3 - insql t2,a1,t2 - lda t4,-1(zero) - mskql t4,a2,t5 - cmovne t5,t5,t4 - insqh t4,a1,t5 - insql t4,a1,t4 - addq a1,a2,a4 - ldq_u t6,0(a1) - ldq_u t7,-1(a4) - bic t6,t4,t6 - bic t7,t5,t7 - and t2,t4,t2 - and t3,t5,t3 - or t2,t6,t2 - or t3,t7,t3 - stq_u t3,-1(a4) - stq_u t2,0(a1) - RET +5: add in0=in0,in2 + add in1=in1,in2 ;; + add in0=-1,in0 + add in1=-1,in1 ;; -bcopy_overlap: - /* - * Basically equivalent to previous case, only backwards. - * Not quite as highly optimized - */ - addq a0,a2,a3 - addq a1,a2,a4 +6: ld1 r14=[in0],-1 ;; + st1 [in1]=r14,-1 + add in2=-1,in2 ;; + cmp.ne p6,p0=r0,in2 +(p6) br.cond.spnt.few 6b - /* less than 8 bytes - don't worry about overlap */ - cmpule a2,8,t0 - bne t0,bcopy_ov_short + br.ret.sptk.few rp - /* Possibly do a partial first word */ - and a4,7,t4 - beq t4,bcopy_ov_nostart2 - subq a3,t4,a3 - subq a4,t4,a4 - ldq_u t1,0(a3) - subq a2,t4,a2 - ldq_u t2,7(a3) - ldq t3,0(a4) - extql t1,a3,t1 - extqh t2,a3,t2 - or t1,t2,t1 - mskqh t3,t4,t3 - mskql t1,t4,t1 - or t1,t3,t1 - stq t1,0(a4) +END(bcopy) -bcopy_ov_nostart2: - bic a2,7,t4 - and a2,7,a2 - beq t4,bcopy_ov_lp_end +LEAF(memcpy,3) + + mov r14=in0 ;; + mov in0=in1 ;; + mov in1=r14 + br.cond.sptk.few bcopy + +END(memcpy) + +NESTED(copyin, 3) + + alloc loc0=ar.pfs,3,3,3,0 + mov loc1=rp -bcopy_ov_lp: - /* This could be more pipelined, but it doesn't seem worth it */ - ldq_u t0,-8(a3) - subq a4,8,a4 - ldq_u t1,-1(a3) - subq a3,8,a3 - extql t0,a3,t0 - extqh t1,a3,t1 - subq t4,8,t4 - or t0,t1,t0 - stq t0,0(a4) - bne t4,bcopy_ov_lp + movl loc2=VM_MAXUSER_ADDRESS // make sure that src addr + ;; + cmp.ltu p6,p0=in0,loc2 // is in user space. + ;; +(p6) br.cond.spnt.few copyerr // if it's not, error out. + movl r14=copyerr // set up fault handler. + add r15=GD_CURPROC,r13 // find curproc + ;; + ld8 r15=[r15] + ;; + add r15=P_ADDR,r15 // find pcb + ;; + ld8 r15=[r15] + ;; + add loc2=U_PCB_ONFAULT,r15 + ;; + st8 [loc2]=r14 + ;; + mov out0=in0 + mov out1=in1 + mov out2=in2 + ;; + br.call.sptk.few rp=bcopy // do the copy. + st8 [loc2]=r0 // kill the fault handler. + mov rp=loc1 // restore ra. + br.ret.sptk.few rp // ret0 left over from bcopy + +END(copyin) -bcopy_ov_lp_end: - beq a2,bcopy_done +NESTED(copyout, 3) + + alloc loc0=ar.pfs,3,3,3,0 + mov loc1=rp - ldq_u t0,0(a0) - ldq_u t1,7(a0) - ldq_u t2,0(a1) - extql t0,a0,t0 - extqh t1,a0,t1 - or t0,t1,t0 - insql t0,a1,t0 - mskql t2,a1,t2 - or t2,t0,t2 - stq_u t2,0(a1) + movl loc2=VM_MAXUSER_ADDRESS // make sure that dest addr + ;; + cmp.ltu p6,p0=in1,loc2 // is in user space. + ;; +(p6) br.cond.spnt.few copyerr // if it's not, error out. + movl r14=copyerr // set up fault handler. + add r15=GD_CURPROC,r13 // find curproc + ;; + ld8 r15=[r15] + ;; + add r15=P_ADDR,r15 // find pcb + ;; + ld8 r15=[r15] + ;; + add loc2=U_PCB_ONFAULT,r15 + ;; + st8 [loc2]=r14 + ;; + mov out0=in0 + mov out1=in1 + mov out2=in2 + ;; + br.call.sptk.few rp=bcopy // do the copy. + st8 [loc2]=r0 // kill the fault handler. + mov rp=loc1 // restore ra. + br.ret.sptk.few rp // ret0 left over from bcopy + +END(copyout) -bcopy_done: - RET +LEAF(copyerr, 0) -bcopy_ov_short: - ldq_u t2,0(a0) - br zero,bcopy_da_finish -#endif - END(bcopy) + add r14=GD_CURPROC,r13 ;; // find curproc + ld8 r14=[r14] ;; + add r14=P_ADDR,r14 ;; // curproc->p_addr + ld8 r14=[r14] ;; + add r14=U_PCB_ONFAULT,r14 ;; // &curproc->p_addr->u_pcb.pcb_onfault + st8 [r14]=r0 // reset fault handler -LEAF(copyin, 3) -#if 0 - LDGP(pv) - lda sp, -16(sp) /* set up stack frame */ - stq ra, (16-8)(sp) /* save ra */ - ldiq t0, VM_MAXUSER_ADDRESS /* make sure that src addr */ - cmpult a0, t0, t1 /* is in user space. */ - beq t1, copyerr /* if it's not, error out. */ - lda v0, copyerr /* set up fault handler. */ - .set noat - ldq at_reg, curproc - ldq at_reg, P_ADDR(at_reg) - stq v0, U_PCB_ONFAULT(at_reg) - .set at - CALL(bcopy) /* do the copy. */ - .set noat - ldq at_reg, curproc /* kill the fault handler. */ - ldq at_reg, P_ADDR(at_reg) - stq zero, U_PCB_ONFAULT(at_reg) - .set at - ldq ra, (16-8)(sp) /* restore ra. */ - lda sp, 16(sp) /* kill stack frame. */ - mov zero, v0 /* return 0. */ - RET -#endif - END(copyin) - -LEAF(copyout, 3) -#if 0 - LDGP(pv) - lda sp, -16(sp) /* set up stack frame */ - stq ra, (16-8)(sp) /* save ra */ - ldiq t0, VM_MAXUSER_ADDRESS /* make sure that dest addr */ - cmpult a1, t0, t1 /* is in user space. */ - beq t1, copyerr /* if it's not, error out. */ - lda v0, copyerr /* set up fault handler. */ - .set noat - ldq at_reg, curproc - ldq at_reg, P_ADDR(at_reg) - stq v0, U_PCB_ONFAULT(at_reg) - .set at - CALL(bcopy) /* do the copy. */ - .set noat - ldq at_reg, curproc /* kill the fault handler. */ - ldq at_reg, P_ADDR(at_reg) - stq zero, U_PCB_ONFAULT(at_reg) - .set at - ldq ra, (16-8)(sp) /* restore ra. */ - lda sp, 16(sp) /* kill stack frame. */ - mov zero, v0 /* return 0. */ - RET -#endif - END(copyout) + mov ret0=EFAULT // return EFAULT + br.ret.sptk.few rp -LEAF(copyerr, 0) -#if 0 - ldq t0, curproc - ldq t0, P_ADDR(t0) - stq zero, U_PCB_ONFAULT(t0) /* reset fault handler. */ - ldq ra, (16-8)(sp) /* restore ra. */ - lda sp, 16(sp) /* kill stack frame. */ - ldiq v0, EFAULT /* return EFAULT. */ - RET -#endif - END(copyerr) +END(copyerr) /**************************************************************************/ diff --git a/sys/ia64/ia64/swtch.s b/sys/ia64/ia64/swtch.s index b7f4de1316bb..b447772eea38 100644 --- a/sys/ia64/ia64/swtch.s +++ b/sys/ia64/ia64/swtch.s @@ -30,8 +30,6 @@ #include <machine/mutex.h> #include "assym.s" -/**************************************************************************/ - /* * savectx: save process context, i.e. callee-saved registers * @@ -45,16 +43,20 @@ */ LEAF(savectx, 1) - alloc r2=ar.pfs,1,0,0,0 - ;; flushrs // push out caller's dirty regs mov r3=ar.unat // caller's value for ar.unat ;; - mov ar.rsc=r0 // stop the RSE after the flush + mov ar.rsc=0 // stop the RSE after the flush ;; mov r16=ar.rnat // read RSE's NaT collection mov r17=in0 mov r18=ar.bspstore + mov r19=b0 + mov r20=b1 + mov r21=b2 + mov r22=b3 + mov r23=b4 + mov r24=b5 ;; st8.spill [r17]=r4,8 ;; // save r4..r6 st8.spill [r17]=r5,8 ;; // and accumulate NaT bits @@ -65,10 +67,16 @@ LEAF(savectx, 1) stf.spill [r17]=f3,16 ;; stf.spill [r17]=f4,16 ;; stf.spill [r17]=f5,16 ;; + + st8 [r17]=r19,8 ;; // save b0..b5 + st8 [r17]=r20,8 ;; + st8 [r17]=r21,8 ;; + st8 [r17]=r22,8 ;; + st8 [r17]=r23,8 ;; + st8 [r17]=r24,8 ;; mov r19=ar.unat // NaT bits for r4..r6 mov r20=pr - mov r21=rp mov ret0=r0 // return zero st8 [r17]=r3,8 ;; // save caller's ar.unat @@ -78,7 +86,6 @@ LEAF(savectx, 1) st8 [r17]=r19,8 ;; // our NaT bits st8 [r17]=r16,8 ;; // ar.rnat st8 [r17]=r20,8 ;; // pr - st8 [r17]=r21,8 ;; // return address mov ar.rsc=3 // turn RSE back on @@ -97,21 +104,35 @@ LEAF(savectx, 1) */ LEAF(restorectx, 1) - alloc r2=ar.pfs,1,0,0,0 - add r3=U_PCB_UNAT,in0 // point at NaT for r4..r7 - mov ar.rsc=r0 ;; // switch off the RSE + mov ar.rsc=0 ;; // switch off the RSE ld8 r16=[r3] // load NaT for r4..r7 ;; + mov ar.unat=r16 + ;; ld8.fill r4=[in0],8 ;; // restore r4 ld8.fill r5=[in0],8 ;; // restore r5 ld8.fill r6=[in0],8 ;; // restore r6 ld8.fill r7=[in0],8 ;; // restore r7 - ldf.fill f2=[in0],8 ;; // restore f2 - ldf.fill f3=[in0],8 ;; // restore f3 - ldf.fill f4=[in0],8 ;; // restore f4 - ldf.fill f5=[in0],8 ;; // restore f5 + ldf.fill f2=[in0],16 ;; // restore f2 + ldf.fill f3=[in0],16 ;; // restore f3 + ldf.fill f4=[in0],16 ;; // restore f4 + ldf.fill f5=[in0],16 ;; // restore f5 + + ld8 r16=[in0],8 ;; // restore b0 + ld8 r17=[in0],8 ;; // restore b1 + ld8 r18=[in0],8 ;; // restore b2 + ld8 r19=[in0],8 ;; // restore b3 + ld8 r20=[in0],8 ;; // restore b4 + ld8 r21=[in0],8 ;; // restore b5 + + mov b0=r16 + mov b1=r17 + mov b2=r18 + mov b3=r19 + mov b4=r20 + mov b5=r21 ld8 r16=[in0],8 ;; // caller's ar.unat ld8 sp=[in0],8 ;; // stack pointer @@ -119,37 +140,39 @@ LEAF(restorectx, 1) ld8 r18=[in0],16 ;; // ar.bspstore, skip ar.unat ld8 r19=[in0],8 ;; // ar.rnat ld8 r20=[in0],8 ;; // pr - ld8 r21=[in0],8 ;; // iip mov ar.unat=r16 mov ar.pfs=r17 mov ar.bspstore=r18 ;; mov ar.rnat=r19 mov pr=r20,0x1ffff - mov rp=r21 - mov ret0=r21 // non-zero return + mov ret0=r18 // non-zero return ;; loadrs mov ar.rsc=3 // restart RSE + invala ;; br.ret.sptk.few rp END(restorectx) -/**************************************************************************/ - -IMPORT(want_resched, 4) - /* * switch_trampoline() * * Arrange for a function to be invoked neatly, after a cpu_switch(). * - * Invokes the function specified by the s0 register with the return - * address specified by the s1 register and with one argument, a - * pointer to the executing process's proc structure. + * Invokes the function specified by the r4 register with the return + * address specified by the r5 register and with one argument, taken + * from r6. */ LEAF(switch_trampoline, 0) - MTX_EXIT(sched_lock#, r14, r15) - /* XXX write this */ + MTX_EXIT(sched_lock, r14, r15) + + alloc r16=ar.pfs,0,0,1,0 + mov b7=r4 + mov b0=r5 + mov out0=r6 + ;; + br.call.sptk.few b6=b7 + END(switch_trampoline) diff --git a/sys/ia64/ia64/vm_machdep.c b/sys/ia64/ia64/vm_machdep.c index 53682b77421d..134511325915 100644 --- a/sys/ia64/ia64/vm_machdep.c +++ b/sys/ia64/ia64/vm_machdep.c @@ -127,12 +127,6 @@ cpu_fork(p1, p2, flags) p2->p_md.md_flags = p1->p_md.md_flags & (MDP_FPUSED | MDP_UAC_MASK); /* - * Cache the physical address of the pcb, so we can - * swap to it easily. - */ - p2->p_md.md_pcbpaddr = (void*)vtophys((vm_offset_t)&p2->p_addr->u_pcb); - - /* * Copy floating point state from the FP chip to the PCB * if this process has state stored there. */ @@ -145,10 +139,6 @@ cpu_fork(p1, p2, flags) * new process has FEN disabled. */ p2->p_addr->u_pcb = p1->p_addr->u_pcb; -#if 0 - p2->p_addr->u_pcb.pcb_hw.apcb_usp = ia64_pal_rdusp(); - p2->p_addr->u_pcb.pcb_hw.apcb_flags &= ~IA64_PCB_FLAGS_FEN; -#endif /* * Set the floating point state. @@ -179,6 +169,7 @@ cpu_fork(p1, p2, flags) { struct user *up = p2->p_addr; struct trapframe *p2tf; + u_int64_t bspstore, *p1bs, *p2bs, rnatloc, rnat; /* * Pick a stack pointer, leaving room for a trapframe; @@ -193,27 +184,77 @@ cpu_fork(p1, p2, flags) /* * Set up return-value registers as fork() libc stub expects. */ -#if 0 - p2tf->tf_regs[FRAME_V0] = 0; /* child's pid (linux) */ - p2tf->tf_regs[FRAME_A3] = 0; /* no error */ - p2tf->tf_regs[FRAME_A4] = 1; /* is child (FreeBSD) */ + p2tf->tf_r[FRAME_R8] = 0; /* child's pid (linux) */ + p2tf->tf_r[FRAME_R9] = 0; /* no error */ + p2tf->tf_r[FRAME_R10] = 1; /* is child (FreeBSD) */ + + /* + * Turn off RSE for a moment and work out our current + * ar.bspstore. This assumes that p1==curproc. Also + * flush dirty regs to ensure that the user's stacked + * regs are written out to backing store. + * + * We could cope with p1!=curproc by digging values + * out of its PCB but I don't see the point since + * current usage never allows it. + */ + __asm __volatile("mov ar.rsc=0;;"); + __asm __volatile("flushrs;;" ::: "memory"); + __asm __volatile("mov %0=ar.bspstore" : "=r"(bspstore)); + + p1bs = (u_int64_t *) (p1->p_addr + 1); + p2bs = (u_int64_t *) (p2->p_addr + 1); + + /* + * Copy enough of p1's backing store to include all + * the user's stacked regs. + */ + bcopy(p1bs, p2bs, (p1->p_md.md_tf->tf_ar_bsp + - p1->p_md.md_tf->tf_ar_bspstore)); + + /* + * To calculate the ar.rnat for p2, we need to decide + * if p1's ar.bspstore has advanced past the place + * where the last ar.rnat which covers the user's + * saved registers would be placed. If so, we read + * that one from memory, otherwise we take p1's + * current ar.rnat. + */ + rnatloc = (u_int64_t) + (p1bs + (p1->p_md.md_tf->tf_ar_bsp + - p1->p_md.md_tf->tf_ar_bspstore)); + rnatloc |= 0x1f8; + if (bspstore > rnatloc) + rnat = *(u_int64_t *) rnatloc; + else + __asm __volatile("mov %0=ar.rnat;;" : "=r"(rnat)); + + /* + * Switch the RSE back on. + */ + __asm __volatile("mov ar.rsc=3;;"); + + /* + * Setup the child's pcb so that its ar.bspstore + * starts just above the region which we copied. This + * should work since the child will normally return + * straight into exception_return. + */ + up->u_pcb.pcb_bspstore = (u_int64_t) + (p2bs + (p1->p_md.md_tf->tf_ar_bsp + - p1->p_md.md_tf->tf_ar_bspstore)); + up->u_pcb.pcb_rnat = rnat; /* * Arrange for continuation at child_return(), which * will return to exception_return(). Note that the child * process doesn't stay in the kernel for long! - * - * This is an inlined version of cpu_set_kpc. */ - up->u_pcb.pcb_hw.apcb_ksp = (u_int64_t)p2tf; - up->u_pcb.pcb_context[0] = - (u_int64_t)child_return; /* s0: pc */ - up->u_pcb.pcb_context[1] = - (u_int64_t)exception_return; /* s1: ra */ - up->u_pcb.pcb_context[2] = (u_long) p2; /* s2: a0 */ - up->u_pcb.pcb_context[7] = - (u_int64_t)switch_trampoline; /* ra: assembly magic */ -#endif + up->u_pcb.pcb_sp = (u_int64_t)p2tf - 16; + up->u_pcb.pcb_r4 = (u_int64_t)child_return; + up->u_pcb.pcb_r5 = (u_int64_t)exception_return; + up->u_pcb.pcb_r6 = (u_int64_t)p2; + up->u_pcb.pcb_b0 = (u_int64_t)switch_trampoline; } } @@ -229,14 +270,8 @@ cpu_set_fork_handler(p, func, arg) void (*func) __P((void *)); void *arg; { -#if 0 - /* - * Note that the trap frame follows the args, so the function - * is really called like this: func(arg, frame); - */ - p->p_addr->u_pcb.pcb_context[0] = (u_long) func; - p->p_addr->u_pcb.pcb_context[2] = (u_long) arg; -#endif + p->p_addr->u_pcb.pcb_r4 = (u_int64_t) func; + p->p_addr->u_pcb.pcb_r6 = (u_int64_t) arg; } /* diff --git a/sys/ia64/include/asm.h b/sys/ia64/include/asm.h index 4d20be3355da..3e7f2f934a1b 100644 --- a/sys/ia64/include/asm.h +++ b/sys/ia64/include/asm.h @@ -114,33 +114,27 @@ _name_: * A nested function calls other functions and needs * to use alloc to save registers. */ -#define NESTED(_name_,_n_args_,_n_locals_,_n_outputs_, \ - _pfs_reg_,_rp_reg_) \ - .globl _name_; \ - .proc _name_; \ -_name_:; \ - alloc _pfs_reg_=ar.pfs,_n_args_,_n_locals_,_n_outputs_,0;; \ - mov _rp_reg_=rp \ +#define NESTED(_name_,_n_args_) \ + .globl _name_; \ + .proc _name_; \ +_name_:; \ + .regstk _n_args_, 0, 0, 0 \ MCOUNT -#define NESTED_NOPROFILE(_name_,_n_args_,_n_locals_,_n_outputs_, \ - _pfs_reg_,_rp_reg_) \ - .globl _name_; \ - .proc _name_; \ -_name_:; \ - alloc _pfs_reg_=ar.pfs,_n_args_,_n_locals_,_n_outputs_,0;; \ - mov _rp_reg_=rp +#define NESTED_NOPROFILE(_name_,_n_args_) \ + .globl _name_; \ + .proc _name_; \ +_name_:; \ + .regstk _n_args_, 0, 0, 0 /* * STATIC_NESTED * Declare a local nested function. */ -#define STATIC_NESTED(_name_,_n_args_,_n_locals_,_n_outputs_, \ - _pfs_reg_,_rp_reg_) \ - .proc _name_; \ -_name_:; \ - alloc _pfs_reg_=ar.pfs,_n_args_,_n_locals_,_n_outputs_,0;; \ - mov _rp_reg_=rp;; \ +#define STATIC_NESTED(_name_,_n_args_) \ + .proc _name_; \ +_name_:; \ + .regstk _n_args_, 0, 0, 0 \ MCOUNT /* diff --git a/sys/ia64/include/ia64_cpu.h b/sys/ia64/include/ia64_cpu.h index ca205c278499..4de99383458f 100644 --- a/sys/ia64/include/ia64_cpu.h +++ b/sys/ia64/include/ia64_cpu.h @@ -186,13 +186,36 @@ ia64_tpa(u_int64_t va) * Read the value of ar.itc. */ static __inline u_int64_t -ia64_read_itc(void) +ia64_get_itc(void) { u_int64_t result; __asm __volatile("mov %0=ar.itc" : "=r" (result)); return result; } +/* + * Read the value of ar.itm. + */ +static __inline u_int64_t +ia64_get_itm(void) +{ + u_int64_t result; + __asm __volatile("mov %0=cr.itm" : "=r" (result)); + return result; +} + +/* + * Write the value of ar.itm. + */ +static __inline void +ia64_set_itm(u_int64_t v) +{ + __asm __volatile("mov cr.itm=%0" :: "r" (v)); +} + +/* + * Write a region register. + */ static __inline void ia64_set_rr(u_int64_t rrbase, u_int64_t v) { diff --git a/sys/ia64/include/pcb.h b/sys/ia64/include/pcb.h index 41c37771dffd..d8679ca8d4fe 100644 --- a/sys/ia64/include/pcb.h +++ b/sys/ia64/include/pcb.h @@ -43,6 +43,13 @@ struct pcb { struct ia64_fpreg pcb_f4; struct ia64_fpreg pcb_f5; + u_int64_t pcb_b0; /* really restart address */ + u_int64_t pcb_b1; + u_int64_t pcb_b2; + u_int64_t pcb_b3; + u_int64_t pcb_b4; + u_int64_t pcb_b5; + u_int64_t pcb_old_unat; /* caller's ar.unat */ u_int64_t pcb_sp; u_int64_t pcb_pfs; @@ -51,10 +58,9 @@ struct pcb { u_int64_t pcb_unat; /* ar.unat for r4..r7 */ u_int64_t pcb_rnat; u_int64_t pcb_pr; /* predicates */ - u_int64_t pcb_iip; /* address to restart */ - unsigned long pcb_onfault; /* for copy faults */ - unsigned long pcb_accessaddr; /* for [fs]uswintr */ + u_int64_t pcb_onfault; /* for copy faults */ + u_int64_t pcb_accessaddr; /* for [fs]uswintr */ }; /* diff --git a/sys/ia64/include/proc.h b/sys/ia64/include/proc.h index a2e97164a5ea..226aa9497447 100644 --- a/sys/ia64/include/proc.h +++ b/sys/ia64/include/proc.h @@ -38,7 +38,6 @@ struct mdproc { u_long md_flags; struct trapframe *md_tf; /* trap/syscall registers */ - struct pcb *md_pcbpaddr; /* phys addr of the pcb */ }; #define MDP_FPUSED 0x0001 /* Process used the FPU */ |
