diff options
author | Michael Shalayeff <mickey@cvs.openbsd.org> | 2004-06-30 18:18:55 +0000 |
---|---|---|
committer | Michael Shalayeff <mickey@cvs.openbsd.org> | 2004-06-30 18:18:55 +0000 |
commit | 7039e43dd9bf0a037f340ffa979cb82b9f98a3ea (patch) | |
tree | 887f4a72624d9d8712799eecd0e7c2c0dcfd8844 /sys/arch | |
parent | 62f80b5f2a8e2e1b93cd93565a4e0d1cc5f9039f (diff) |
allow forced fpu emulation through a sysctl
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/hppa/hppa/locore.S | 12 | ||||
-rw-r--r-- | sys/arch/hppa/hppa/machdep.c | 26 | ||||
-rw-r--r-- | sys/arch/hppa/include/cpu.h | 6 |
3 files changed, 33 insertions, 11 deletions
diff --git a/sys/arch/hppa/hppa/locore.S b/sys/arch/hppa/hppa/locore.S index 218c95974b2..2d0f2a225fa 100644 --- a/sys/arch/hppa/hppa/locore.S +++ b/sys/arch/hppa/hppa/locore.S @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.S,v 1.134 2004/06/13 21:49:14 niklas Exp $ */ +/* $OpenBSD: locore.S,v 1.135 2004/06/30 18:18:54 mickey Exp $ */ /* * Copyright (c) 1998-2004 Michael Shalayeff @@ -158,6 +158,7 @@ cpu_itmr /* itmr value at the most recent clk int */ BSS(fpu_curpcb, 4) /* pcb of the fpu owner */ .export fpu_enable, data BSS(fpu_enable, 4) /* bits to set in the ccr to enable fpu */ + BSS(cpu_fpuena, 4) /* enable FPU, otherwise force emulate */ BSS(fpu_scratch, 16) /* FPU scratch space, enough for a quad */ .export hppa_vtop, data BSS(hppa_vtop, 4) /* a vtop translation table addr (pa=va) */ @@ -1062,14 +1063,19 @@ ENTRY(TLABEL(emu),0) * or the trap will be generted later. */ + ldil L%cpu_fpuena, r1 + ldw R%cpu_fpuena(r1), r9 + comib,= 0, r9, $fpusw_emu + ldil L%fpu_curpcb, r1 + /* if we are already enabled and hit again, emulate */ mfctl ccr, r1 extru,<> r1, 25, 2, r0 b,n $fpusw_set nop +$fpusw_emu mtctl r0, ccr /* cause a reload after exception */ - ldil L%fpu_curpcb, r1 stw r0, R%fpu_curpcb(r1) #if 0 /* here we emulate the fld/fst */ @@ -1317,7 +1323,7 @@ $tlbd_l ldw 0(r17), r24 VTAG sub,<> r16, r24, r0 - stw r25, 4(r17) + stw r0, 0(r17) #endif TLB_STATS_AFT(tlbd) rfir diff --git a/sys/arch/hppa/hppa/machdep.c b/sys/arch/hppa/hppa/machdep.c index 6fca2b95b01..e4c871a034d 100644 --- a/sys/arch/hppa/hppa/machdep.c +++ b/sys/arch/hppa/hppa/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.130 2004/05/13 15:09:19 mickey Exp $ */ +/* $OpenBSD: machdep.c,v 1.131 2004/06/30 18:18:54 mickey Exp $ */ /* * Copyright (c) 1999-2003 Michael Shalayeff @@ -436,6 +436,7 @@ cpuid() extern u_int trap_ep_T_ITLBMISSNA[]; extern u_int fpu_enable; + extern int cpu_fpuena; struct pdc_cpuid pdc_cpuid PDC_ALIGNMENT; const struct hppa_cpu_typed *p = NULL; u_int cpu_features; @@ -469,12 +470,14 @@ cpuid() /* locate coprocessors and SFUs */ bzero(&pdc_coproc, sizeof(pdc_coproc)); if ((error = pdc_call((iodcio_t)pdc, 0, PDC_COPROC, PDC_COPROC_DFLT, - &pdc_coproc, 0, 0, 0, 0)) < 0) + &pdc_coproc, 0, 0, 0, 0)) < 0) { printf("WARNING: PDC_COPROC error %d\n", error); - else { + cpu_fpuena = 0; + } else { printf("pdc_coproc: 0x%x, 0x%x\n", pdc_coproc.ccr_enable, pdc_coproc.ccr_present); fpu_enable = pdc_coproc.ccr_enable & CCR_MASK; + cpu_fpuena = 1; } /* BTLB params */ @@ -527,9 +530,11 @@ cpuid() printf("WARNING: UNKNOWN CPU TYPE; GOOD LUCK " "(type 0x%x, features 0x%x)\n", cpu_type, cpu_features); p = cpu_types; - } else if ((p->type == hpcxl || p->type == hpcxl2) && !fpu_enable) + } else if ((p->type == hpcxl || p->type == hpcxl2) && !fpu_enable) { /* we know PCXL and PCXL2 do not exist w/o FPU */ fpu_enable = 0xc0; + cpu_fpuena = 1; + } /* * TODO: HPT on 7200 is not currently supported @@ -1216,10 +1221,9 @@ setregs(p, pack, stack, retval) fdcache(HPPA_SID_KERNEL, (vaddr_t)pcb->pcb_fpregs, 8 * 4); if (tf->tf_cr30 == fpu_curpcb) { fpu_curpcb = 0; - /* force an fpu ctxsw, we'll not be hugged by the cpu_switch */ + /* force an fpu ctxsw, we won't be hugged by the cpu_switch */ mtctl(0, CR_CCR); } - retval[1] = 0; } @@ -1459,7 +1463,10 @@ cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) size_t newlen; struct proc *p; { + extern paddr_t fpu_curpcb; /* from locore.S */ + extern int cpu_fpuena; dev_t consdev; + /* all sysctl names at this level are terminal */ if (namelen != 1) return (ENOTDIR); /* overloaded */ @@ -1471,6 +1478,13 @@ cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) consdev = NODEV; return (sysctl_rdstruct(oldp, oldlenp, newp, &consdev, sizeof consdev)); + case CPU_FPU: + if (fpu_curpcb) { + fpu_save(fpu_curpcb); + fpu_curpcb = 0; + mtctl(0, CR_CCR); + } + return (sysctl_int(oldp, oldlenp, newp, newlen, &cpu_fpuena)); default: return (EOPNOTSUPP); } diff --git a/sys/arch/hppa/include/cpu.h b/sys/arch/hppa/include/cpu.h index 5eb720ab0e9..629f346bacb 100644 --- a/sys/arch/hppa/include/cpu.h +++ b/sys/arch/hppa/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.43 2004/06/13 21:49:14 niklas Exp $ */ +/* $OpenBSD: cpu.h,v 1.44 2004/06/30 18:18:54 mickey Exp $ */ /* * Copyright (c) 2000-2004 Michael Shalayeff @@ -164,11 +164,13 @@ int cpu_dump(void); * CTL_MACHDEP definitions. */ #define CPU_CONSDEV 1 /* dev_t: console terminal device */ -#define CPU_MAXID 2 /* number of valid machdep ids */ +#define CPU_FPU 2 /* int: fpu present/enabled */ +#define CPU_MAXID 3 /* number of valid machdep ids */ #define CTL_MACHDEP_NAMES { \ { 0, 0 }, \ { "console_device", CTLTYPE_STRUCT }, \ + { "fpu", CTLTYPE_INT }, \ } #endif |