diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2004-08-02 22:16:44 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2004-08-02 22:16:44 +0000 |
commit | 68541f1fd2757160a5aaa3523688b417f79ae346 (patch) | |
tree | 29a51b1ae541c9ab6bcb2a419cd3263350c13277 | |
parent | 16864ab061f41f531e180c37b7fda194da118cbf (diff) |
On MVME188 systems with 4:1 or 8:1 CMMU pairings, make sure the exception
handling code checks the error status of the correct CMMUs and really
reports an error code.
This gets us closer to getting these modules to work, at the expense of
sanity and some code readability.
-rw-r--r-- | sys/arch/mvme88k/mvme88k/eh.S | 228 |
1 files changed, 176 insertions, 52 deletions
diff --git a/sys/arch/mvme88k/mvme88k/eh.S b/sys/arch/mvme88k/mvme88k/eh.S index 21219937ead..7a85abbf6a4 100644 --- a/sys/arch/mvme88k/mvme88k/eh.S +++ b/sys/arch/mvme88k/mvme88k/eh.S @@ -1,4 +1,4 @@ -/* $OpenBSD: eh.S,v 1.58 2004/08/02 08:35:00 miod Exp $ */ +/* $OpenBSD: eh.S,v 1.59 2004/08/02 22:16:43 miod Exp $ */ /* * Mach Operating System * Copyright (c) 1993-1991 Carnegie Mellon University @@ -32,7 +32,10 @@ * Save Pbus fault status register from data and inst CMMU. */ -/* Single-processor SBC version (MVME187, MVME8120) */ +/* + * Single-processor SBC version (MVME187, MVME8120) + */ + #ifdef MVME187 #include <machine/mvme187.h> #define PFSR_SAVE_187 \ @@ -46,68 +49,25 @@ #define PFSR_SAVE_187 #endif -/* MVME188 version */ +/* + * MVME188 version (see pfsr188 below) + */ #ifdef MVME188 -#include <machine/mvme188.h> #define PFSR_SAVE_188 \ - extu TMP, FLAGS, FLAG_CPU_FIELD_WIDTH<0>; /* TMP = cpu# */ \ - cmp TMP2, TMP, 0x0; /* CPU0 ? */ \ - bb1 eq, TMP2, 1f; \ - cmp TMP2, TMP, 0x1; /* CPU1 ? */ \ - bb1 eq, TMP2, 2f; \ - cmp TMP2, TMP, 0x2; /* CPU2 ? */ \ - bb1 eq, TMP2, 3f; \ - br 4f; \ - /* XXX WHAT ABOUT MODULES WITH SPLIT U/S CMMUS ??? */ \ -1: \ - /* must be CPU0 */ \ - or.u TMP, r0, hi16(VME_CMMU_I0); \ - ld TMP2, TMP, lo16(VME_CMMU_I0) + 0x108; \ - st TMP2, r31, REG_OFF(EF_IPFSR); \ - or.u TMP, r0, hi16(VME_CMMU_D0); \ - ld TMP2, TMP, lo16(VME_CMMU_D0) + 0x108; \ - br.n _ASM_LABEL(pfsr_done); \ - st TMP2, r31, REG_OFF(EF_DPFSR); \ -2: \ - /* must be CPU1 */ \ - or.u TMP, r0, hi16(VME_CMMU_I1); \ - ld TMP2, TMP, lo16(VME_CMMU_I1) + 0x108; \ - st TMP2, r31, REG_OFF(EF_IPFSR); \ - or.u TMP, r0, hi16(VME_CMMU_D1); \ - ld TMP2, TMP, lo16(VME_CMMU_D1) + 0x108; \ - br.n _ASM_LABEL(pfsr_done); \ - st TMP2, r31, REG_OFF(EF_DPFSR); \ -3: \ - /* must be CPU2 */ \ - or.u TMP, r0, hi16(VME_CMMU_I2); \ - ld TMP2, TMP, lo16(VME_CMMU_I2) + 0x108; \ - st TMP2, r31, REG_OFF(EF_IPFSR); \ - or.u TMP, r0, hi16(VME_CMMU_D2); \ - ld TMP2, TMP, lo16(VME_CMMU_D2) + 0x108; \ - br.n _ASM_LABEL(pfsr_done); \ - st TMP2, r31, REG_OFF(EF_DPFSR); \ -4: \ - /* must be CPU3 */ \ - or.u TMP, r0, hi16(VME_CMMU_I3); \ - ld TMP2, TMP, lo16(VME_CMMU_I3) + 0x108; \ - st TMP2, r31, REG_OFF(EF_IPFSR); \ - or.u TMP, r0, hi16(VME_CMMU_D3); \ - ld TMP2, TMP, lo16(VME_CMMU_D3) + 0x108; \ - br.n _ASM_LABEL(pfsr_done); \ - st TMP2, r31, REG_OFF(EF_DPFSR); + br _ASM_LABEL(pfsr188); #else #define PFSR_SAVE_188 #endif + #if defined(MVME187) && defined(MVME188) #define PFSR_SAVE \ /* check if it's a mvme188 */ \ or.u TMP, r0, hi16(_C_LABEL(brdtyp)); \ ld TMP2, TMP, lo16(_C_LABEL(brdtyp)); \ cmp TMP, TMP2, BRD_188; \ - bb1 ne, TMP, 9f; \ - PFSR_SAVE_188 \ -9: PFSR_SAVE_187 + bb1 eq, TMP, _ASM_LABEL(pfsr188); \ + PFSR_SAVE_187 #else #define PFSR_SAVE \ PFSR_SAVE_188 \ @@ -115,3 +75,167 @@ #endif #include <m88k/m88k/eh_common.S> + +#ifdef MVME188 +#include <machine/mvme188.h> +/* + * Handling faults can be very tricky, as it is necessary to check all + * the CMMUs of the faulting processor. + * + * This implementation tries to favor, speedwise: + * - simple (2 CMMUs per CPU) configurations over any other configuration; + * - faults on CPU0 over the other CPUs. + */ + text + +ASLOCAL(pfsr188) + or.u TMP, r0, hi16(_C_LABEL(cmmu_shift)) + ld TMP, TMP, lo16(_C_LABEL(cmmu_shift)) + cmp TMP2, TMP, 2 + bb1.n lt, TMP2, _ASM_LABEL(pfsr188_straight) + extu TMP, FLAGS, FLAG_CPU_FIELD_WIDTH<0> /* TMP = cpu# */ + bb1 eq, TMP2, _ASM_LABEL(pfsr188_double) + +ASLOCAL(pfsr188_quad) + /* + * We're in configuration 2 (1 CPU, 8 CMMU). + * + * Reading the MVME188 error register could tell us which + * CMMU faulted, but it's easier to check every one until + * we find the first fault. + * + * If two or more CMMU faulted simultaneously, restarting from + * the trap will fault again, and we'll handle the remaining + * exceptions here. + * + * XXX It will probably be worth changing this so that we can + * handle a bunch of CMMU faults at once in trap.c. + */ + or.u TMP, r0, hi16(VME_CMMU_I0) + ld TMP2, TMP, lo16(VME_CMMU_I0) + 0x108 + extu TMP, TMP2, 3<16> + bcnd ne0, TMP, 1f + or.u TMP, r0, hi16(VME_CMMU_I1) + ld TMP2, TMP, lo16(VME_CMMU_I1) + 0x108 + extu TMP, TMP2, 3<16> + bcnd ne0, TMP, 1f + or.u TMP, r0, hi16(VME_CMMU_I2) + ld TMP2, TMP, lo16(VME_CMMU_I2) + 0x108 + extu TMP, TMP2, 3<16> + bcnd ne0, TMP, 1f + or.u TMP, r0, hi16(VME_CMMU_I3) + ld TMP2, TMP, lo16(VME_CMMU_I3) + 0x108 +1: + st TMP2, r31, REG_OFF(EF_IPFSR) + + or.u TMP, r0, hi16(VME_CMMU_D0) + ld TMP2, TMP, lo16(VME_CMMU_D0) + 0x108 + extu TMP, TMP2, 3<16> + bcnd ne0, TMP, 2f + or.u TMP, r0, hi16(VME_CMMU_D1) + ld TMP2, TMP, lo16(VME_CMMU_D1) + 0x108 + extu TMP, TMP2, 3<16> + bcnd ne0, TMP, 2f + or.u TMP, r0, hi16(VME_CMMU_D2) + ld TMP2, TMP, lo16(VME_CMMU_D2) + 0x108 + extu TMP, TMP2, 3<16> + bcnd ne0, TMP, 2f + or.u TMP, r0, hi16(VME_CMMU_D3) + ld TMP2, TMP, lo16(VME_CMMU_D3) + 0x108 +2: + br.n _ASM_LABEL(pfsr_done) + st TMP2, r31, REG_OFF(EF_DPFSR) + +ASLOCAL(pfsr188_double) + /* + * 4 CMMUs per CPU. Almost as simple as the 2 CMMUs per CPU + * situation... + */ + bcnd ne0, TMP, 5f + + /* CPU 0 -> CMMU 0 and 1 */ + or.u TMP, r0, hi16(VME_CMMU_I0) + ld TMP2, TMP, lo16(VME_CMMU_I0) + 0x108 + extu TMP, TMP2, 3<16> + bcnd ne0, TMP, 1f + or.u TMP, r0, hi16(VME_CMMU_I1) + ld TMP2, TMP, lo16(VME_CMMU_I1) + 0x108 +1: + st TMP2, r31, REG_OFF(EF_IPFSR) + + or.u TMP, r0, hi16(VME_CMMU_D0) + ld TMP2, TMP, lo16(VME_CMMU_D0) + 0x108 + extu TMP, TMP2, 3<16> + bcnd ne0, TMP, 2f + or.u TMP, r0, hi16(VME_CMMU_D1) + ld TMP2, TMP, lo16(VME_CMMU_D1) + 0x108 +2: + br.n _ASM_LABEL(pfsr_done) + st TMP2, r31, REG_OFF(EF_DPFSR) + +5: + /* CPU 1 -> CMMU 2 and 3 */ + or.u TMP, r0, hi16(VME_CMMU_I2) + ld TMP2, TMP, lo16(VME_CMMU_I2) + 0x108 + extu TMP, TMP2, 3<16> + bcnd ne0, TMP, 1f + or.u TMP, r0, hi16(VME_CMMU_I3) + ld TMP2, TMP, lo16(VME_CMMU_I3) + 0x108 +1: + st TMP2, r31, REG_OFF(EF_IPFSR) + + or.u TMP, r0, hi16(VME_CMMU_D2) + ld TMP2, TMP, lo16(VME_CMMU_D2) + 0x108 + extu TMP, TMP2, 3<16> + bcnd ne0, TMP, 2f + or.u TMP, r0, hi16(VME_CMMU_D3) + ld TMP2, TMP, lo16(VME_CMMU_D3) + 0x108 +2: + br.n _ASM_LABEL(pfsr_done) + st TMP2, r31, REG_OFF(EF_DPFSR) + +ASLOCAL(pfsr188_straight) + /* + * We have the simple 2 CMMUs per CPU mapping. Pick our couple. + */ + bcnd eq0, TMP, 1f /* CPU0 */ + cmp TMP2, TMP, 0x2 + bb1 lt, TMP2, 2f /* CPU1 */ + bb1 eq, TMP2, 3f /* CPU2 */ + + /* must be CPU3 */ + or.u TMP, r0, hi16(VME_CMMU_I3) + ld TMP2, TMP, lo16(VME_CMMU_I3) + 0x108 + st TMP2, r31, REG_OFF(EF_IPFSR) + or.u TMP, r0, hi16(VME_CMMU_D3) + ld TMP2, TMP, lo16(VME_CMMU_D3) + 0x108 + br.n _ASM_LABEL(pfsr_done) + st TMP2, r31, REG_OFF(EF_DPFSR) +1: + /* must be CPU0 */ + or.u TMP, r0, hi16(VME_CMMU_I0) + ld TMP2, TMP, lo16(VME_CMMU_I0) + 0x108 + st TMP2, r31, REG_OFF(EF_IPFSR) + or.u TMP, r0, hi16(VME_CMMU_D0) + ld TMP2, TMP, lo16(VME_CMMU_D0) + 0x108 + br.n _ASM_LABEL(pfsr_done) + st TMP2, r31, REG_OFF(EF_DPFSR) +2: + /* must be CPU1 */ + or.u TMP, r0, hi16(VME_CMMU_I1) + ld TMP2, TMP, lo16(VME_CMMU_I1) + 0x108 + st TMP2, r31, REG_OFF(EF_IPFSR) + or.u TMP, r0, hi16(VME_CMMU_D1) + ld TMP2, TMP, lo16(VME_CMMU_D1) + 0x108 + br.n _ASM_LABEL(pfsr_done) + st TMP2, r31, REG_OFF(EF_DPFSR) +3: + /* must be CPU2 */ + or.u TMP, r0, hi16(VME_CMMU_I2) + ld TMP2, TMP, lo16(VME_CMMU_I2) + 0x108 + st TMP2, r31, REG_OFF(EF_IPFSR) + or.u TMP, r0, hi16(VME_CMMU_D2) + ld TMP2, TMP, lo16(VME_CMMU_D2) + 0x108 + br.n _ASM_LABEL(pfsr_done) + st TMP2, r31, REG_OFF(EF_DPFSR) +#endif |