summaryrefslogtreecommitdiffstats
path: root/sys/ia64
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2004-09-17 22:19:41 +0000
committermarcel <marcel@FreeBSD.org>2004-09-17 22:19:41 +0000
commitb3e38752b197d930007a2a1b66ec10a926cee8a9 (patch)
treed412e578552e37a924b10ef450fea7390c059799 /sys/ia64
parent07dc724ee08a545628526e5a0799d229b12e8c70 (diff)
downloadFreeBSD-src-b3e38752b197d930007a2a1b66ec10a926cee8a9.zip
FreeBSD-src-b3e38752b197d930007a2a1b66ec10a926cee8a9.tar.gz
Provide our own FPSWA definitions, instead of depending on the Intel
EFI headers and put them all in <machine/fpu.h>. The Intel EFI headers conflict with the Intel ACPI headers (duplicate type definitions), so are being phased out in the kernel.
Diffstat (limited to 'sys/ia64')
-rw-r--r--sys/ia64/ia64/machdep.c9
-rw-r--r--sys/ia64/ia64/trap.c67
-rw-r--r--sys/ia64/include/efi.h1
-rw-r--r--sys/ia64/include/fpu.h28
4 files changed, 55 insertions, 50 deletions
diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c
index 29f8f1b..08c2a74 100644
--- a/sys/ia64/ia64/machdep.c
+++ b/sys/ia64/ia64/machdep.c
@@ -110,7 +110,7 @@ extern u_int64_t ia64_gateway_page[];
extern u_int64_t break_sigtramp[];
extern u_int64_t epc_sigtramp[];
-FPSWA_INTERFACE *fpswa_interface;
+struct fpswa_iface *fpswa_iface;
u_int64_t ia64_pal_base;
u_int64_t ia64_port_base;
@@ -257,12 +257,11 @@ cpu_startup(dummy)
printf("avail memory = %ld (%ld MB)\n", ptoa(cnt.v_free_count),
ptoa(cnt.v_free_count) / 1048576);
- if (fpswa_interface == NULL)
+ if (fpswa_iface == NULL)
printf("Warning: no FPSWA package supplied\n");
else
printf("FPSWA Revision = 0x%lx, Entry = %p\n",
- (long)fpswa_interface->Revision,
- (void *)fpswa_interface->Fpswa);
+ (long)fpswa_iface->if_rev, (void *)fpswa_iface->if_fpswa);
/*
* Set up buffers, so they can be used to read disk labels.
@@ -600,7 +599,7 @@ ia64_init(void)
printf("WARNING: loader(8) metadata is missing!\n");
/* Get FPSWA interface */
- fpswa_interface = (FPSWA_INTERFACE*)IA64_PHYS_TO_RR7(bootinfo.bi_fpswa);
+ fpswa_iface = (struct fpswa_iface *)IA64_PHYS_TO_RR7(bootinfo.bi_fpswa);
/* Init basic tunables, including hz */
init_param1();
diff --git a/sys/ia64/ia64/trap.c b/sys/ia64/ia64/trap.c
index 02a5b3d..d2b5c76 100644
--- a/sys/ia64/ia64/trap.c
+++ b/sys/ia64/ia64/trap.c
@@ -86,29 +86,7 @@ static void ia32_syscall(struct trapframe *tf);
/*
* EFI-Provided FPSWA interface (Floating Point SoftWare Assist)
*/
-
-/* The function entry address */
-extern FPSWA_INTERFACE *fpswa_interface;
-
-/* Copy of the faulting instruction bundle */
-typedef struct {
- u_int64_t bundle_low64;
- u_int64_t bundle_high64;
-} FPSWA_BUNDLE;
-
-/*
- * The fp state descriptor... tell FPSWA where the "true" copy is.
- * We save some registers in the trapframe, so we have to point some of
- * these there. The rest of the registers are "live"
- */
-typedef struct {
- u_int64_t bitmask_low64; /* f63 - f2 */
- u_int64_t bitmask_high64; /* f127 - f64 */
- union _ia64_fpreg *fp_low_preserved; /* f2 - f5 */
- union _ia64_fpreg *fp_low_volatile; /* f6 - f15 */
- union _ia64_fpreg *fp_high_preserved; /* f16 - f31 */
- union _ia64_fpreg *fp_high_volatile; /* f32 - f127 */
-} FP_STATE;
+extern struct fpswa_iface *fpswa_iface;
#ifdef WITNESS
extern char *syscallnames[];
@@ -699,16 +677,17 @@ trap(int vector, struct trapframe *tf)
case IA64_VEC_FLOATING_POINT_FAULT:
case IA64_VEC_FLOATING_POINT_TRAP: {
- FP_STATE fp_state;
- FPSWA_RET fpswa_ret;
- FPSWA_BUNDLE bundle;
+ struct fpswa_bundle bundle;
+ struct fpswa_fpctx fpctx;
+ struct fpswa_ret ret;
char *ip;
+ u_long fault;
/* Always fatal in kernel. Should never happen. */
if (!user)
trap_panic(vector, tf);
- if (fpswa_interface == NULL) {
+ if (fpswa_iface == NULL) {
sig = SIGFPE;
ucode = 0;
break;
@@ -718,7 +697,7 @@ trap(int vector, struct trapframe *tf)
if (vector == IA64_VEC_FLOATING_POINT_TRAP &&
(tf->tf_special.psr & IA64_PSR_RI) == 0)
ip -= 16;
- error = copyin(ip, &bundle, 16);
+ error = copyin(ip, &bundle, sizeof(bundle));
if (error) {
sig = SIGBUS; /* EFAULT, basically */
ucode = 0; /* exception summary */
@@ -726,12 +705,14 @@ trap(int vector, struct trapframe *tf)
}
/* f6-f15 are saved in exception_save */
- fp_state.bitmask_low64 = 0xffc0; /* bits 6 - 15 */
- fp_state.bitmask_high64 = 0x0;
- fp_state.fp_low_preserved = NULL;
- fp_state.fp_low_volatile = &tf->tf_scratch_fp.fr6;
- fp_state.fp_high_preserved = NULL;
- fp_state.fp_high_volatile = NULL;
+ fpctx.mask_low = 0xffc0; /* bits 6 - 15 */
+ fpctx.mask_high = 0;
+ fpctx.fp_low_preserved = NULL;
+ fpctx.fp_low_volatile = &tf->tf_scratch_fp.fr6;
+ fpctx.fp_high_preserved = NULL;
+ fpctx.fp_high_volatile = NULL;
+
+ fault = (vector == IA64_VEC_FLOATING_POINT_FAULT) ? 1 : 0;
/*
* We have the high FP registers disabled while in the
@@ -740,11 +721,10 @@ trap(int vector, struct trapframe *tf)
ia64_enable_highfp();
/* The docs are unclear. Is Fpswa reentrant? */
- fpswa_ret = fpswa_interface->Fpswa(
- (vector == IA64_VEC_FLOATING_POINT_FAULT) ? 1 : 0,
- &bundle, &tf->tf_special.psr, &tf->tf_special.fpsr,
- &tf->tf_special.isr, &tf->tf_special.pr,
- &tf->tf_special.cfm, &fp_state);
+ ret = fpswa_iface->if_fpswa(fault, &bundle,
+ &tf->tf_special.psr, &tf->tf_special.fpsr,
+ &tf->tf_special.isr, &tf->tf_special.pr,
+ &tf->tf_special.cfm, &fpctx);
ia64_disable_highfp();
@@ -752,8 +732,7 @@ trap(int vector, struct trapframe *tf)
* Update ipsr and iip to next instruction. We only
* have to do that for faults.
*/
- if (vector == IA64_VEC_FLOATING_POINT_FAULT &&
- (fpswa_ret.status == 0 || (fpswa_ret.status & 2))) {
+ if (fault && (ret.status == 0 || (ret.status & 2))) {
int ei;
ei = (tf->tf_special.isr >> 41) & 0x03;
@@ -769,11 +748,11 @@ trap(int vector, struct trapframe *tf)
}
}
- if (fpswa_ret.status == 0) {
+ if (ret.status == 0) {
goto out;
- } else if (fpswa_ret.status == -1) {
+ } else if (ret.status == -1) {
printf("FATAL: FPSWA err1 %lx, err2 %lx, err3 %lx\n",
- fpswa_ret.err1, fpswa_ret.err2, fpswa_ret.err3);
+ ret.err1, ret.err2, ret.err3);
panic("fpswa fatal error on fp fault");
} else {
sig = SIGFPE;
diff --git a/sys/ia64/include/efi.h b/sys/ia64/include/efi.h
index 1ac7154..2363812 100644
--- a/sys/ia64/include/efi.h
+++ b/sys/ia64/include/efi.h
@@ -35,7 +35,6 @@
#include <boot/efi/include/efidevp.h>
#include <boot/efi/include/eficon.h>
#include <boot/efi/include/efiapi.h>
-#include <boot/efi/include/efifpswa.h>
extern EFI_SYSTEM_TABLE *ia64_efi_systab;
extern EFI_RUNTIME_SERVICES *ia64_efi_runtime;
diff --git a/sys/ia64/include/fpu.h b/sys/ia64/include/fpu.h
index f9d426c..c24bb67 100644
--- a/sys/ia64/include/fpu.h
+++ b/sys/ia64/include/fpu.h
@@ -78,4 +78,32 @@
| IA64_FPSR_SF(3, (IA64_SF_DEFAULT \
| IA64_SF_TD)))
+struct fpswa_ret {
+ uint64_t status;
+ uint64_t err1;
+ uint64_t err2;
+ uint64_t err3;
+};
+
+struct fpswa_bundle {
+ long double bits; /* Force 16-byte alignment. */
+};
+
+struct fpswa_fpctx {
+ uint64_t mask_low; /* f63 - f2 */
+ uint64_t mask_high; /* f127 - f64 */
+ union _ia64_fpreg *fp_low_preserved; /* f2 - f5 */
+ union _ia64_fpreg *fp_low_volatile; /* f6 - f15 */
+ union _ia64_fpreg *fp_high_preserved; /* f16 - f31 */
+ union _ia64_fpreg *fp_high_volatile; /* f32 - f127 */
+};
+
+struct fpswa_iface {
+ uint32_t if_rev;
+ uint32_t __res;
+ struct fpswa_ret (*if_fpswa)(u_long, struct fpswa_bundle *,
+ uint64_t *, uint64_t *, uint64_t *, uint64_t *, uint64_t *,
+ struct fpswa_fpctx *);
+};
+
#endif /* ! _MACHINE_FPU_H_ */
OpenPOWER on IntegriCloud