summaryrefslogtreecommitdiffstats
path: root/private/ntos/nthals/halr98b/mips/cacherr.s
diff options
context:
space:
mode:
Diffstat (limited to 'private/ntos/nthals/halr98b/mips/cacherr.s')
-rw-r--r--private/ntos/nthals/halr98b/mips/cacherr.s1435
1 files changed, 1435 insertions, 0 deletions
diff --git a/private/ntos/nthals/halr98b/mips/cacherr.s b/private/ntos/nthals/halr98b/mips/cacherr.s
new file mode 100644
index 000000000..bcb23554f
--- /dev/null
+++ b/private/ntos/nthals/halr98b/mips/cacherr.s
@@ -0,0 +1,1435 @@
+// "@(#) NEC cacherr.s 1.2 94/10/17 11:02:44"
+// TITLE("Cache Error Handling")
+//++
+//
+// Copyright (c) 1993-1994 Microsoft Corporation
+//
+// Module Name:
+//
+// cacherr.s
+//
+// Abstract:
+//
+// This module implements cache error handling. It is entered in KSEG1
+// directly from the cache error vector wiht ERL set in the processor
+// state.
+//
+// N.B. All the code in this routine MUST run in KSEG1 and reference
+// data only in KSEG1 until which time as any cache errors have
+// been corrected.
+//
+// N.B. This routine is NOT COMPLETE. All cache errors result in a
+// soft reset.
+//
+// Environment:
+//
+// Kernel mode only.
+//
+// Revision History:
+//
+//--
+
+#include "halmips.h"
+#include "cacherr.h"
+
+//
+// Define local save area for register state.
+//
+
+ .data
+SavedAt:.space 4 // saved integer register at - a3
+SavedV0:.space 4 //
+SavedV1:.space 4 //
+SavedA0:.space 4 //
+SavedA1:.space 4 //
+SavedA2:.space 4 //
+SavedA3:.space 4 //
+
+ SBTTL("Cache Error Handling")
+//++
+//
+// VOID
+// HalpCacheErrorRoutine (
+// VOID
+// )
+//
+// Routine Description:
+//
+// This function is entered from the cache error vector executing
+// in KSEG1. If the error is a single bit ECC error in the second
+// level data cache or the error is in the primary instruction cache,
+// then the error is corrected and execution is continued. Otherwise,
+// a fatal system error has occured and control is transfered to the
+// soft reset vector.
+//
+// N.B. No state has been saved when this routine is entered.
+//
+// Arguments:
+//
+// None.
+//
+// Return Value:
+//
+// None.
+//
+//--
+
+ LEAF_ENTRY(HalpCacheErrorRoutine)
+
+//
+// Save volatile registers needed to fix cache error.
+//
+
+ .set noreorder
+ .set noat
+//K001
+// la k0,SavedAt // get address of register save area
+// li k1,KSEG1_BASE // convert address of KSEG1 address
+// or k0,k0,k1 //
+// sw AT,0(k0) // save registers AT - a3
+// sw v0,4(k0) //
+// sw v1,8(k0) //
+// sw a0,12(k0) //
+// sw a1,16(k0) //
+// sw a2,20(k0) //
+ li k1,0xb9800310 // Get CPU#
+ lw k0,0x0(k1)
+ li k1,0x0f000000
+ and k0,k0,k1
+ srl k0,k0,24
+ li k1,0x4
+ sub k0,k0,k1
+ mtc0 k0,lladdr
+ nop
+ nop
+ nop
+ nop
+ li k1,0xd
+ sll k0,k0,k1
+ la k1,HalpCacheErrorStack
+ add k0,k0,k1
+ add k0,k0,0x2000
+ li k1,KSEG1_BASE
+ or k0,k0,k1
+ subu k0,k0,TrapFrameLength
+#if !defined(NT_40)
+ sw sp,TrIntSp(k0) // save integer register sp
+ move sp,k0 // set new stack pointer
+ cfc1 k1,fsr // get floating status register
+ sw gp,TrIntGp(sp) // save integer register gp
+ sw s8,TrIntS8(sp) // save integer register s8
+ sw k1,TrFsr(sp) // save current FSR
+ mfc0 k0,psr
+ nop
+ nop
+ nop
+ sw k0,TrPsr(sp) // save processor state
+ sw ra,TrIntRa(sp) // save integer register ra
+ move s8,sp
+ sw AT,TrIntAt(s8) // save assembler temporary register
+ sw v0,TrIntV0(s8) // save integer register v0
+ sw v1,TrIntV1(s8) // save integer register v1
+ sw a0,TrIntA0(s8) // save integer registers a0 - a3
+ sw a1,TrIntA1(s8) //
+ sw a2,TrIntA2(s8) //
+ sw a3,TrIntA3(s8) //
+ sw t0,TrIntT0(s8) // save integer registers t0 - t2
+ sw t1,TrIntT1(s8) //
+ sw t2,TrIntT2(s8) //
+ sw t3,TrIntT3(s8) // save integer register t3 - t9
+ sw t4,TrIntT4(s8) //
+ sw t5,TrIntT5(s8) //
+ sw t6,TrIntT6(s8) //
+ sw t7,TrIntT7(s8) //
+ sw t8,TrIntT8(s8) //
+ sw t9,TrIntT9(s8) //
+ mflo t3 // get multiplier/quotient lo and hi
+ mfhi t4 //
+ sw t3,TrIntLo(s8) // save multiplier/quotient lo and hi
+ sw t4,TrIntHi(s8) //
+ mfc0 a2,errorepc
+ nop
+ nop
+ nop
+ sw a2,TrFir(s8) // save exception PC
+#else
+ sd sp,TrXIntSp(k0) // save integer register sp
+ move sp,k0 // set new stack pointer
+ cfc1 k1,fsr // get floating status register
+ sd gp,TrXIntGp(sp) // save integer register gp
+ sd s8,TrXIntS8(sp) // save integer register s8
+ sw k1,TrFsr(sp) // save current FSR
+ mfc0 k0,psr
+ nop
+ nop
+ nop
+ sw k0,TrPsr(sp) // save processor state
+ sd ra,TrXIntRa(sp) // save integer register ra
+ move s8,sp
+ sd AT,TrXIntAt(s8) // save assembler temporary register
+ sd v0,TrXIntV0(s8) // save integer register v0
+ sd v1,TrXIntV1(s8) // save integer register v1
+ sd a0,TrXIntA0(s8) // save integer registers a0 - a3
+ sd a1,TrXIntA1(s8) //
+ sd a2,TrXIntA2(s8) //
+ sd a3,TrXIntA3(s8) //
+ sd t0,TrXIntT0(s8) // save integer registers t0 - t2
+ sd t1,TrXIntT1(s8) //
+ sd t2,TrXIntT2(s8) //
+ sd t3,TrXIntT3(s8) // save integer register t3 - t7
+ sd t4,TrXIntT4(s8) //
+ sd t5,TrXIntT5(s8) //
+ sd t6,TrXIntT6(s8) //
+ sd t7,TrXIntT7(s8) //
+ sd s0,TrXIntS0(s8) // save integer registers s0 - s7
+ sd s1,TrXIntS1(s8) //
+ sd s2,TrXIntS2(s8) //
+ sd s3,TrXIntS3(s8) //
+ sd s4,TrXIntS4(s8) //
+ sd s5,TrXIntS5(s8) //
+ sd s6,TrXIntS6(s8) //
+ sd s7,TrXIntS7(s8) //
+ sd t8,TrXIntT8(s8) // save integer registers t8 - t9
+ sd t9,TrXIntT9(s8) //
+ mflo t3 // get multiplier/quotient lo and hi
+ mfhi t4 //
+ sd t3,TrXIntLo(s8) // save multiplier/quotient lo and hi
+ sd t4,TrXIntHi(s8) //
+ mfc0 a2,errorepc
+ nop
+ nop
+ nop
+ sw a2,TrFir(s8) // save exception PC
+
+#endif
+ move a3,k0
+
+//
+// Get the current processor state and cache error register, and check
+// if the error can be corrected.
+//
+
+ mfc0 a0,lladdr
+ nop
+ nop
+ nop
+ li t1,0x1 // Log Format For FW
+ sll t3,t1,a0
+ li t1,0xb9800388 // NVRAM enable
+ li t0,0x00040000
+ sw t0,0x0(t1)
+ li t0,0xbf09fd64 // NVRAM log For FW
+ lw t1,0x0(t0)
+ or t3,t1,t3
+ sb t3,0x0(t0)
+#if 0
+ li t1,0xb9800388 // NVRAM disable
+ li t0,0x04040000
+ sw t0,0x0(t1)
+#endif
+ mfc0 a1,cacheerr // get cache error state
+ nop
+ nop
+ nop
+ la t1,HalpCacheErrorHwLog
+ li t2,KSEG1_BASE
+ or t1,t1,t2
+//
+// Check CPU
+//
+
+// li a1,0x00000000
+
+ mfc0 t2,prid
+ nop
+ nop
+ nop
+ nop
+ and t2,t2,0xff00 // isolate processor id
+ xor t2,t2,0x0900 // check if r10000 processor
+ beq zero,t2,t5clog // if eq, r10000 processor
+
+
+
+//
+// R4400 log
+//
+
+ addi t2,t1,0x20
+ .set at
+ .set reorder
+
+//
+// ****** temp ******
+//
+// The following code is temporary and will be removed when full cache
+// error support is included.
+//
+// ****** temp ******
+//
+// K001 For cacheErrorLog
+
+// jal HalpCacheErrorLog
+// nop
+//
+// b SoftReset // ****** all error soft rest
+/********************************
+ * cache error routine
+ *
+ * v0 = return code (return value)
+ *
+ * a0 = log field address (argument)
+ * a1 = error code address (argument)
+ * a2 = TagLo reg
+ * a3 = ECC reg
+ * t0 = cache virtual address
+ * t1 = Cache error reg
+ * t2 = d-cache virtual address for s-cache
+ * t3 = xkphs address
+ * t4 - t7 temprary data
+ * t8 = a2(TagLo) save
+ * t9 = return address
+ ********************************/
+//LEAF(che_log)
+
+ .set noreorder
+// DMFC0 (T8, D_ERROREPC)
+ move v1,a0 // CPU #
+
+ move a0,t2 // Data addr
+ move t2,a1
+ move a1,t1 // Header addr
+ move t1,t2 // CacheError REg
+ move t8,a2 // Error Epc
+// mfc0 t7, C0_SR
+ move t7,a3 // PSR
+ mfc0 t6, config
+ mfc0 t5, prid
+// Log
+ sw t8,EPC_cpu(a0)
+ sw t7,Psr_cpu(a0)
+ sw t6,CFG_cpu(a0)
+ sw t5,PRID_cpu(a0)
+ sw t1,CHERR_cpu(a0)
+// mfc0 t1, C0_CACHEERR
+// or t4, t7, (SR_DE | SR_KX | SR_ERL)
+ or t4,t7,(0x1<<PSR_DE)
+ mtc0 t4, psr
+ nop
+ nop
+ nop
+ .set reorder
+
+ and t4, t1, CHERR_EE # sysad parity error?
+ bnez t4, sysad_log
+
+ and t4, t1, CHERR_EC # primary cache error?
+ bnez t4, sche_log
+
+ and t4, t1, CHERR_ER # p-inst cache error?
+ bnez t4, dche_log
+
+/*
+ * primary instruction cache parity error
+ */
+ and t0, t1, CHERR_PIDX # K1(p) address
+// sll t0, t0,CHERR_PSHFT
+// sll t0, t0,12
+ and t4, t1, CHERR_SIDX2
+ or t0, t4
+ or t0, KSEG0_BASE
+
+ .set noreorder
+ cache 4, 0(t0) # I-cache index load tag
+ nop
+ nop
+ nop
+ mfc0 a2, taglo
+ mfc0 a3, ecc
+ .set reorder
+
+ sw t0, CheAdd_p(a0) # save cache address
+ sw a2, TagLo_p(a0) # save TagLo
+ sw a3, ECC_p(a0) # save ECC
+
+ and t4, t1, CHERR_ES # external reference?
+ bnez t4, iche_log_ex # then degrade error
+
+ and t4, t1, CHERR_EB # also occured data error?
+ bnez t4, iche_log_eb # then fatal error
+
+ and t4, t1, CHERR_ET # tag error?
+ bnez t4, iche_log_tag # then fatal error
+
+ and t4, t1, CHERR_ED # data error?
+ bnez t4, iche_log_dat # then degrade error
+
+// li t4, FATAL_ERR # else fatal error
+// sw t4, (a1)
+ li v0, ICHE_UNKNOWN
+ j iche_log_end
+
+iche_log_dat:
+// # li t4, RECOVER_ERR
+// # sw t4, (a1)
+ li v0, ICHE_DAT
+ j iche_log_end
+
+iche_log_tag:
+// # li t4, FATAL_ERR
+// # sw t4, (a1)
+ li v0, ICHE_TAG
+ j iche_log_end
+
+iche_log_eb:
+// li t4, FATAL_ERR
+ sw t4, (a1)
+ li v0, ICHE_EB
+ j iche_log_end
+
+iche_log_ex:
+// # li t4, RECOVER_ERR
+// # sw t4, (a1)
+ li v0, ICHE_EX
+
+iche_log_end:
+ .set noreorder
+ mtc0 zero,taglo
+ nop
+ cache 8, 0(t0) //# I-cache index store tag(invalid)
+ cache 20,0(t0) //# I-cache fill
+ cache 8, 0(t0) //# I-cache index store tag(invalid)
+ .set reorder
+ j che_log_end
+
+/*
+ * primary data cache parity error
+ */
+dche_log:
+ and t0, t1, CHERR_SIDX2 //# K1(p) address
+ or t0, KSEG0_BASE
+
+dche_log_loop:
+ .set noreorder
+ cache 5, 0(t0) //# D-cache index load tag
+ nop
+ nop
+ nop
+ mfc0 a2, taglo
+ mfc0 a3, ecc
+ .set reorder
+
+ sw t0, CheAdd_p(a0) //# save cache address
+ sw a2, TagLo_p(a0) //# save TagLo
+ sw a3, ECC_p(a0) //# save ECC
+
+ and t4, t1, CHERR_ET //# tag error?
+ beqz t4, dche_log_dat //# else data error
+//#
+//# Tag field error
+//#
+ jal tag_parity_chk //# check tag parity
+ bnez v0, dche_tag_parity
+
+ add t0, 0x1000 //# check next PIDX
+ bltu t0, 0x80004000, dche_log_loop
+ //# less than 16K then loop
+// li t4, FATAL_ERR # else fatal error
+// sw t4, (a1)
+ li v0, DCHE_TAG_UNKNOW
+ j che_log_end
+
+dche_tag_parity:
+ and t4, t1, CHERR_ES //# external reference?
+ bnez t4, dche_tag_ex //# then fatal error
+
+ and t4, a2, R4CT_PSTAT_MASK //# dirty?
+ beq t4, R4CT_PSTAT_DRE, dche_tag_dirty
+ beqz t4, dche_tag_clean
+
+ and t4, a2, R4CT_PTAG_MASK //# k1(s) address
+ sll t4, 4
+ and t5, t1, CHERR_SIDX2
+ or t4, t5
+ and t4, CHERR_SIDX
+ or t4, KSEG0_BASE
+
+ .set noreorder
+ cache 7, 0(t4) //# S-cache index load tag
+ nop
+ nop
+ nop
+ mfc0 t5, taglo
+ mfc0 t6, ecc
+ .set reorder
+
+ sw t4, CheAdd_s(a0) //# save cache address
+ sw t5, TagLo_s(a0) //# save TagLo
+ sw t6, ECC_s(a0) //# save ECC
+
+ and t7, t5, R4CT_SSTAT_MASK //# dirty?
+ beq t7, R4CT_SSTAT_DRE, dche_tag_dirty
+
+dche_tag_clean:
+// li t4, RECOVER_ERR
+// sw t4, (a1)
+ li v0, DCHE_TAG_CLEAN
+ j dche_log_end
+
+dche_tag_dirty:
+// li t4, FATAL_ERR
+// sw t4, (a1)
+ li v0, DCHE_TAG_DIRTY
+ j dche_log_end
+
+dche_tag_ex:
+// li t4, FATAL_ERR
+// sw t4, (a1)
+ li v0, DCHE_TAG_EX
+ j dche_log_end
+
+ //#
+ //# Data field error
+// #
+dche_log_dat:
+ and t4, t1, CHERR_ED //# DATA error?
+ bnez t4, dche_dat //# then data error
+
+// li t4, FATAL_ERR //# else fatal error
+// sw t4, (a1)
+ li v0, DCHE_UNKNOWN
+ j che_log_end
+
+dche_dat:
+ and t4, t1, CHERR_ES //# external reference?
+ beqz t4, dche_dat_chk //# else data error check
+
+// li t4, FATAL_ERR //# then fatal error
+// sw t4, (a1)
+ li v0, DCHE_DAT_EX
+ j che_log_end
+
+dche_dat_chk:
+/* For NT
+ and t4, a2, R4CT_PSTAT_MASK //# invalid?
+ beqz t4, dche_dat_next
+
+ move t8, a2 //# save TagLo
+
+ and t3, a2, R4CT_PTAG_MASK //# xkphs cached address
+ DSLL32 (T3, T3, 0)
+ DSRL (T3, T3, 28)
+ and t4, t1, CHERR_SIDX2
+ or t3, t4
+ li t4, XKPHYSEGMENT_HI_CCS
+ DSLL32 (T4, T4, 0)
+ or t3, t4
+
+ LD (A2, 0, T3) # load erronious data
+ SD (T3, xkphs_share, A0)
+ SD (A2, data_s, A0)
+
+ # jal dat_parity_chk # check data parity
+ move a2, t8 # resotore TagLo
+ # bnez v0, dche_dat_parity
+
+ .set noreorder
+ cache 1, 0(t0) # D-cache index writevack invalidate
+ lw zero, (t0) # D-cache dummy load
+ mtc0 zero, C0_TAGLO
+ nop
+ cache 9, 0(t0) # D-cache index store tag(invalid)
+ .set reorder
+
+dche_dat_next:
+ add t0, 0x1000 # check next PIDX
+ bltu t0, 0x80004000, dche_log_loop
+ # less than 16K then loop
+
+ li t4, FATAL_ERR # all D-cache error is fatal
+ sw t4, (a1)
+*/
+ li v0, DCHE_DAT_DIRTY
+ j che_log_end
+
+/* comment out 1993.11.12
+
+ li t4, FATAL_ERR # else fatal error
+ sw t4, (a1)
+ li v0, DCHE_DAT_UNKNOW
+ j che_log_end
+
+dche_dat_parity:
+ and t4, a2, R4CT_PSTAT_MASK # dirty?
+ beq t4, R4CT_PSTAT_DRE, dche_dat_dirty
+ bnez t4, dche_dat_dirty
+
+dche_dat_clean:
+ li t4, RECOVER_ERR
+ sw t4, (a1)
+ li v0, DCHE_DAT_CLEAN
+ j dche_log_end
+
+dche_dat_dirty:
+ li t4, FATAL_ERR
+ sw t4, (a1)
+ li v0, DCHE_DAT_DIRTY
+*/
+
+dche_log_end:
+ .set noreorder
+ mtc0 zero,taglo
+ nop
+ cache 9, 0(t0) # D-cache index store tag(invalid)
+ lw zero, (t0) # D-cache dummy load
+ cache 9, 0(t0) # D-cache index store tag(invalid)
+ .set reorder
+
+ j che_log_end
+
+/*
+ * secondary cache error
+ */
+sche_log:
+ and t2, t1, CHERR_PIDX # K1(p) address
+// sll t2, t2,CHERR_PSHFT
+ sll t2, t2,12
+ and t4, t1, CHERR_SIDX2
+ or t2, t4
+ or t2, KSEG0_BASE
+ sw t2, CheAdd_p(a0) # save cache address
+
+ and t4, t1, CHERR_EI # store miss error?
+ beqz t4, sche_log_tag # else tag error
+
+ .set noreorder
+ mtc0 zero, taglo
+ nop
+ cache 9, 0(t2) # D-cache index store tag(invalid)
+ .set reorder
+
+sche_log_tag:
+ and t0, t1, CHERR_SIDX # K1(s) address
+ or t0, KSEG0_BASE
+
+ .set noreorder
+ cache 7, 0(t0) # S-cache index load tag
+ nop
+ nop
+ nop
+ mfc0 a2, taglo
+ mfc0 a3, ecc
+ .set reorder
+
+ sw t0, CheAdd_s(a0) # save cache address
+ sw a2, TagLo_s(a0) # save TagLo
+ sw a3, ECC_s(a0) # save ECC
+
+ and t4, t1, CHERR_ET # tag error?
+ beqz t4, sche_log_dat # else data error
+
+// #
+// # Tag field error
+// #
+ move k0,v1
+ jal tag_ecc_chk //# check tag ecc
+ sw v1, tag_synd_s(a0)
+ move v1,k0
+ sw a2, Good_TagLo_s(a0)
+ beq v0, SCHE_TAG_1BIT, sche_tag_1bit
+ beq v0, SCHE_TAG_UNKNOW, sche_tag_noerr
+
+sche_tag_2bit:
+ and t2, ~63 # 64byte boundary
+ .set noreorder
+ mtc0 zero, taglo
+ nop
+ cache 9, 0(t2) # D-cache index store tag(invalid)
+ cache 9, 16(t2)
+ cache 9, 32(t2)
+ cache 9, 48(t2)
+ cache 11, 0(t0) # S-cache index store tag(invalid)
+ .set reorder
+
+// li t4, FATAL_ERR
+ j che_log_end
+
+sche_tag_1bit:
+ .set noreorder
+ mtc0 a2, taglo
+ nop
+ cache 11, 0(t0) # S-cache index store tag(modify)
+ .set reorder
+
+sche_tag_noerr:
+ and t4, t1, CHERR_ED # data error?
+ beqz t4, che_log_end # else end
+
+sche_log_dat:
+ and t4, t1, CHERR_ED # data error?
+ bnez t4, sche_dat_0
+
+// li t4, FATAL_ERR # else fatal error
+// sw t4, (a1)
+ li v0, SCHE_UNKNOWN
+ j che_log_end
+
+sche_dat_0:
+ and t4, t1, CHERR_ES # external reference?
+// *tmp*
+// beqz t4, sche_dat_1
+
+// li t4, FATAL_ERR # then fatal error
+// sw t4, (a1)
+// li v0, SCHE_DAT_EX
+ li v0, SCHE_DAT_UNKNOW
+ j sche_log_end
+/*
+sche_dat_1:
+ and t4, a2, R4CT_SSTAT_MASK # dirty?
+ bne t4, R4CT_SSTAT_INV, sche_dat_chk
+
+ li t4, FATAL_ERR # then fatal error
+ sw t4, (a1)
+ li v0, SCHE_DAT_INV
+ j sche_log_end
+
+sche_dat_chk:
+ move t8, a2 # save TagLo
+
+ and t3, a2, R4CT_STAG_MASK # xkphs cached address
+ DSLL32 (T3, T3, 0)
+ DSRL (T3, T3, 28)
+ and t4, t1, CHERR_SIDX
+ or t3, t4
+ li t4, XKPHYSEGMENT_HI_CCS
+ DSLL32 (T4, T4, 0)
+ or t3, t4
+
+ LD (A2, 0, T3) # load erronious data
+ SD (T3, xkphs_share, A0)
+ SD (A2, data_s, A0)
+ jal dat_ecc_chk # check data ecc
+
+ sw v1, data_synd_s(a0)
+ SD (A2, Good_data_s, A0)
+ sw a3, Good_ECC_s(a0)
+ move v1, a2 # save good data
+ move a2, t8 # resotore TagLo
+ beq v0, SCHE_DAT_2BIT_C, sche_dat_2bit
+ beq v0, SCHE_DAT_UNKNOW, sche_dat_unknown
+
+ SD (V1, 0, T3) # modified data
+ j sche_log_end
+
+sche_dat_2bit:
+ and t4, a2, R4CT_SSTAT_MASK # dirty?
+ beq t4, R4CT_SSTAT_DRE, sche_dat_dirty
+
+sche_dat_clean:
+ lw zero, (t0) # dummy read
+
+ li t4, RECOVER_ERR
+ sw t4, (a1)
+ j sche_log_end
+
+sche_dat_dirty:
+ li v0, SCHE_DAT_2BIT_D
+ SD (V1, 0, T3) # rewrite error data
+
+sche_dat_unknown:
+ li t4, FATAL_ERR
+ sw t4, (a1)
+*/
+sche_log_end:
+ and t2, ~63 # 64byte boundary
+
+ .set noreorder
+ cache 1, 0(t2) # D-cache index write back invalidate
+ cache 1, 16(t2)
+ cache 1, 32(t2)
+ cache 1, 48(t2)
+ cache 3, 0(t0) # S-cache index write back invalidate
+ .set reorder
+
+ j che_log_end
+
+/*
+ * System address data parity error
+ */
+sysad_log:
+// li t4, FATAL_ERR
+// sw t4, (a1)
+ li v0, SYSAD_PARITY
+
+che_log_end:
+//For Log Function areg
+ move t0,a0
+ move a0,v1
+/* lw a2,EPC_cpu(t0)
+ lw a1,CHERR_cpu(t0)
+*/
+ move a2,v0
+ j HalpCacheErrorLog
+//tmp lw t5, Status(a0) # load Status
+/*
+ .set noreorder
+ mfc0 t4, cacheerr
+ mtc0 t5, psr
+ nop
+ nop
+ .set reorder
+
+// tmp
+ and t4, CHERR_EW # cache error in chelog?
+ beqz t4, che_log_end2
+
+ li t4, FATAL_ERR
+ sw t4, (a1)
+ li v0, CHER_IN_CHER
+
+che_log_end2:
+ j t9 # return
+*/
+// END(che_log)
+
+//
+// R10000 log
+//
+
+t5clog:
+// Get Log data.
+ .set noreorder
+
+ move v1,a0
+ move a0,t1 # a0 = data address
+
+ move t8,a2 # t8 = ErrorEpc
+ move t7,a3 # t7 = Status
+ mfc0 t6,config # t6 = Config
+ mfc0 t5,prid # t5 = Prid
+ move t1,a1 # t1 = cache error state
+
+ or t4,t7,( 1 << PSR_ERL )
+ mtc0 t4,psr
+ dmfc0 t3,branchdiag
+// mfps t2,$0
+// mfpc t0,$0
+ move t2,zero
+ move t0,zero
+
+ .set reorder
+
+// Set log data.
+ sw t8,R10_ErrEPC(a0) # save ErrEPC
+ sw t7,R10_Status(a0) # save Status
+ sw t6,R10_Config(a0) # save Config
+ sw t5,R10_PRid(a0) # save Prid
+ sw t1,R10_CacheEr(a0) # save CacheErr
+ sw t3,R10_BrDiag_Hi(a0) # save BranchDiag
+ srl t4,t3,16
+ srl t4,t4,16
+ sw t4,R10_BrDiag_Lo(a0)
+ sw t2,R10_PC_Ctrl(a0) # save PC Control
+ sw t0,R10_PC_Count(a0) # save PC Count
+
+ li t0,KSEG0_BASE # t0 = cache address
+
+ li t4,R10CHE_KIND_MASK
+ and t4,t1,t4
+
+// I-cache error
+ li v0,R10_ICHE
+ li t5,R10CHE_KIND_I
+ beq t4,t5,t5_iche_log # I-cache parity error?
+
+// D-cache error
+ li v0,R10_DCHE
+ li t5,R10CHE_KIND_D
+ beq t4,t5,t5_dche_log # D-cache parity error?
+
+// S-cache error
+ li v0,R10_SCHE_2BIT
+ li t5,R10CHE_KIND_S
+ beq t4,t5,t5_sche_log # S-cache ECC error?
+
+// SysAd error
+ li v0,R10_SYSAD_PARITY
+// li t4,R10_FATAL_ERR
+// sw t4,(a1)
+ and t4,t1,(R10CHE_SA | R10CHE_SC | R10CHE_SR)
+ bne t4,zero,t5_log_end # Sys I/F fatal error
+
+
+t5_sche_log:
+// Make cache addr
+ and t4,t1,R10CHE_SIDX_BLK
+ or t0,t4
+ and t4,t1,(R10CHE_D_WAY1 | R10CHE_TA_WAY1)
+ sne t4,0
+ or t0,t4 # t0 = cache way address
+
+// TagHi & TagLo
+ .set noreorder
+ cache IndexLoadTag_S, 0(t0) # load tag
+ mfc0 t4,taghi
+ mfc0 t5,taglo
+ .set reorder
+
+ sw t0,R10_CheAdd(a0) # save cache address
+ sw t4,R10_TagHi(a0) # save TagHi
+ sw t5,R10_TagLo(a0) # save TagLo
+
+// Cache data & ECC
+ addu t3,t0,64 # t3 = cacne address increment
+ addu t7,a0,64 # t7 = data save address increment
+ addu t8,a0,32 # t8 = ECC save address increment
+
+load_Scache_loop:
+ subu t3,8 # new cache address
+ subu t7,8 # new data save address
+ subu t8,4 # new ECC save address
+
+ .set noreorder
+ cache IndexLoadData_S,0(t3) # load data
+ mfc0 t4,taghi
+ mfc0 t5,taglo
+ mfc0 t6,ecc
+ .set reorder
+
+ sw t4,R10_Cache_data0_Hi(t7) # save data high
+ sw t5,R10_Cache_data0_Lo(t7) # save data low
+ sw t6,R10_ECC0(t8) # save ECC
+
+ bne t3,t0,load_Scache_loop # 8 times
+
+ .set noreorder
+ cache IndexWriteBack_S,0(t0)
+ .set reorder
+
+// li t4,R10_FATAL_ERR
+// sw t4,(a1)
+
+ j t5_log_end
+
+
+// I-cache
+t5_iche_log:
+// Make cache addr
+ and t4, t1, R10CHE_PIDX_BLK
+ or t0, t4
+ and t4, t1, (R10CHE_D_WAY1 | R10CHE_TA_WAY1 | R10CHE_TS_WAY1)
+ sne t4, 0
+ or t0, t4 # t0 = cache way address
+
+// TagHi & TagLo
+ .set noreorder
+ cache IndexLoadTag_I, 0(t0) # load tag
+ mfc0 t4,taghi
+ mfc0 t5,taglo
+ .set reorder
+
+ sw t0,R10_CheAdd(a0) # save cache address
+ sw t4,R10_TagHi(a0) # save TagHi
+ sw t5,R10_TagLo(a0) # save TagLo
+
+// Cache data & ECC
+ addu t3,t0,64 # t3 = cacne address increment
+ addu t7,a0,64 # t7 = data save address increment
+ addu t8,a0,32 # t8 = ECC save address increment
+
+load_Icache_loop:
+ subu t3,4 # new cache address
+ subu t7,4 # new data save address
+ subu t8,2 # new ECC save address
+
+ .set noreorder
+ cache IndexLoadData_I,0(t3) # load data
+ mfc0 t4,taghi
+ mfc0 t5,taglo
+ mfc0 t6,ecc
+ .set reorder
+
+ sw t5,R10_Cache_data0_Hi(t7) # save data low
+ sll t4,8
+ or t6,t4
+ sh t6,R10_ECC0(t8) # save ECC
+
+ bne t3,t0,load_Icache_loop # 16 times
+
+// Cache invalidate
+ .set noreorder
+ cache IndexInvalidate_I, 0(t0)
+ .set reorder
+
+// li t4,NORMAL_ERR
+// sw t4,(a1)
+
+ j t5_log_end
+
+
+// D-cache
+t5_dche_log:
+// Make cache addr
+ and t4,t1,R10CHE_PIDX_DW
+ or t0,t4
+ and t4,t1,(R10CHE_D_WAY1|R10CHE_TA_WAY1|R10CHE_TS_WAY1|R10CHE_TM_WAY1)
+ sne t4,0
+ or t0,t4 # t0 = cache way address
+
+// TagHi & TagLo
+ .set noreorder
+ cache IndexLoadTag_D,0(t0) # load tag
+ mfc0 t4,taghi
+ mfc0 t5,taglo
+ .set reorder
+
+ sw t0,R10_CheAdd(a0) # save cache address
+ sw t4,R10_TagHi(a0) # save TagHi
+ sw t5,R10_TagLo(a0) # save TagLo
+
+// Cache data & ECC
+ and t0,0xffffffe1 # 32 bytes boundary block
+ addu t3,t0,32 # t3 = cacne address increment
+ addu t7,a0,64 # t7 = data save address increment
+ addu t8,a0,32 # t8 = ECC save address increment
+
+load_Dcache_loop:
+ subu t3,4 # new cache address
+ subu t7,8 # new data save address
+ subu t8,4 # new ECC save address
+
+ .set noreorder
+ cache IndexLoadData_D,0(t3) # load data
+ mfc0 t5,taglo
+ mfc0 t6,ecc
+ .set reorder
+
+ sw t5,R10_Cache_data0_Lo(t7) # save data low
+ sw t6,R10_ECC0(t8) # save ECC
+
+ bne t3,t0,load_Dcache_loop # 8 times
+
+ .set noreorder
+ cache IndexWriteBack_D,0(t0)
+ .set reorder
+
+// li t4,FATAL_ERR
+// sw t4,(a1)
+
+t5_log_end:
+ .set noreorder
+
+ lw t5,R10_Status(a0) # save Status
+ mfc0 t4,cacheerr
+ mtc0 t5,psr
+ nop
+ nop
+
+ .set reorder
+
+ and t4,R10CHE_EW # cache error in chelog?
+ beqz t4,t5_che_log_end
+
+ li v0,R10_CHER_IN_CHER
+// li t4,FATAL_ERR
+// sw t4,(a1)
+
+t5_che_log_end:
+
+ move a1,a0
+ move a2,v0
+ move a0,v1
+ j HalpCacheErrorLog
+
+ .end HalpCacheErrorRoutine
+
+
+/*********************************
+ * cache psued failure
+ *
+ * a0 = error code (argument)
+ ********************************/
+/*
+//LEAF(psued_che)
+
+ LEAF_ENTRY(psude_che)
+
+ .set noreorder
+ li t0, PSUED_ADDRESS # error address
+ lw t1, (t0)
+ mfc0 t4, psr # save SR
+ sw t1, (t0)
+ li t6, 1
+ or t5, t4, (SR_CE | SR_DE)
+ mtc0 t6, ecc # ECC error
+ mtc0 t5, psr # set CE,DE bit
+ .set reorder
+
+ beqz a0, sche_yellow
+ li t1, 0xbadfaced
+ sw t1,(t0) # D-cache parity error
+ j psued_end
+
+sche_yellow:
+ .set noreorder
+ cache 1, (t0) # S-cache 2bit error
+ nop
+psued_end:
+ mtc0 C0_SR,t4 # restore sr
+ j ra
+ nop
+ .set reorder
+
+ END(psued_che)
+*/
+
+ .set at
+ .set reorder
+
+//
+// ****** temp ******
+/*********************************
+ * 32bit tag parity check
+ *
+ * v0 = return code (return value)
+ * 0 -- no error
+ * 1 -- error
+ *
+ * a0 = log field address (argument) : not used and not broken
+ * a1 = error code address (argument) : not used and not broken
+ * a2 = check data (argument)
+ * t0 = cache virtual address : not used and not broken
+ * t1 = Cache error reg : not used and not broken
+ * t2 = TagLo reg : not used and not broken
+ * t3 = ECC reg : not used and not broken
+ * t4 - t7 temprary data
+ ********************************/
+LEAF_ENTRY(tag_parity_chk)
+ .set reorder
+ li t4, 1 # target check bit
+ move v0, zero # Hparity bit and return value
+
+ptag_chk_loop:
+ and t5, a2, t4
+ sne t5, 0
+ xor v0, t5 # calcurate parity
+ sll t4, 1
+ bnez t4, ptag_chk_loop # loop 31 times
+ j ra
+
+// END(tag_parity_chk)
+ .end tag_parity_chk
+
+/*********************************
+ * 64bit data parity check
+ *
+ * v0 = return code (return value)
+ * 0 -- no error
+ * 1 -- error
+ *
+ * a0 = log field address (argument) : not used and not broken
+ * a1 = error code address (argument) : not used and not broken
+ * a2 = 64bit data (argument)
+ * a3 = 8bit check data (argument)
+ * t0 = cache virtual address : not used and not broken
+ * t1 = Cache error reg : not used and not broken
+ * t2 = TagLo reg : not used and not broken
+ * t3 = ECC reg : not used and not broken
+ * t4 - t7 temprary data
+ ********************************/
+#if 0
+LEAF(dat_parity_chk)
+ .set reorder
+ li t4, 1 # target check bit
+ li t5, 1 # target parity bit
+ li t6, 8 # byte counter
+ move v0, zero # Hparity bit and return value
+
+pdat_chk_loop:
+ and t7, a2, t4
+ sne t7, 0
+ xor v0, t7 # calcurate parity
+ DSLL (T4, T4, 1)
+
+ subu t6, 1 # if 1byte check end?
+ bnez t6, pdat_chk_skip # else skip
+
+ and t7, a3, t5 # then check parity bit
+ sne t7, 0
+ xor v0, t7 # calcurate parity
+ xor v0, 1 # odd parity, not even 1993.11.7
+ sll t5, 1
+ li t6, 8 # reload byte counter
+
+ beqz v0, pdat_chk_skip # if no parity error then continue
+ j ra # else error return
+
+pdat_chk_skip:
+ bnez t4, pdat_chk_loop # loop 63 times
+ j ra
+
+ END(dat_parity_chk)
+#endif
+
+/*********************************
+ * 2nd cache tag ECC check
+ *
+ * v0 = return code (return value)
+ * 0x20 -- SCHE_TAG_1BIT
+ * 0x21 -- SCHE_TAG_2BIT
+ * 0x23 -- SCHE_TAG_UNKNOW
+ * v1 = tag syndrome (return value)
+ *
+ * a0 = log field address (argument) : not used and not broken
+ * a1 = error code address (argument) : not used and not broken
+ * a2 = 2nd Tag erronious data (argument, return value)
+ * t0 = cache virtual address : not used and not broken
+ * t1 = Cache error reg : not used and not broken
+ * t2 = TagLo reg : not used and not broken
+ * t3 = ECC reg : not used and not broken
+ * t4 - t7 temprary data
+ ********************************/
+LEAF_ENTRY(tag_ecc_chk)
+ .set reorder
+ li t4, 1 # target check bit
+ la t5, tag_synd # tag syndrome data
+ move v1, zero # tag syndrome and return value
+
+// # make syndrome data
+tag_ecc_loop1:
+ and t6, a2, t4
+ beqz t6, tag_ecc_skip0
+ lbu t7, (t5) # make syndrome
+ xor v1, t7 #
+tag_ecc_skip0:
+ sll t4, 1
+ addu t5, 1
+ bnez t4, tag_ecc_loop1 # loop 31 times
+
+ bnez v1, tag_ecc_err # if no error
+ li v0, SCHE_TAG_UNKNOW # then unknown error
+ j ra
+
+// # modify data
+tag_ecc_err:
+ li t4, 1 # target check bit
+ la t5, tag_synd # tag syndrome data
+
+tag_ecc_loop2:
+ lbu t7, (t5) # 1bit error
+ beq v1, t7, tag_ecc_1bit # then 1bit error
+
+ sll t4, 1
+ addu t5, 1
+ bnez t4, tag_ecc_loop2 # loop 31 times
+
+ li v0, SCHE_TAG_2BIT # 2bit error
+ j ra
+
+tag_ecc_1bit:
+ xor a2, t4 # modified data
+ li v0, SCHE_TAG_1BIT # 1bit error
+ j ra
+
+tag_synd:
+ .byte 0x01 # ECC 0 (bit 25)
+ .byte 0x02 # ECC 1 (bit 26)
+ .byte 0x04 # ECC 2 (bit 27)
+ .byte 0x08 # ECC 3 (bit 28)
+ .byte 0x10 # ECC 4 (bit 29)
+ .byte 0x20 # ECC 5 (bit 30)
+ .byte 0x40 # ECC 6 (bit 31)
+ .byte 0x45 # Pidx 0 (bit 19)
+ .byte 0x29 # Pidx 1 (bit 20)
+ .byte 0x51 # Pidx 2 (bit 21)
+ .byte 0x13 # CS 0 (bit 22)
+ .byte 0x49 # CS 1 (bit 23)
+ .byte 0x25 # CS 2 (bit 24)
+ .byte 0x07 # STag 00 (bit 00)
+ .byte 0x16 # STag 01 (bit 01)
+ .byte 0x26 # STag 02 (bit 02)
+ .byte 0x46 # STag 03 (bit 03)
+ .byte 0x0d # STag 04 (bit 04)
+ .byte 0x0e # STag 05 (bit 05)
+ .byte 0x1c # STag 06 (bit 06)
+ .byte 0x4c # STag 07 (bit 07)
+ .byte 0x31 # STag 08 (bit 08)
+ .byte 0x32 # STag 09 (bit 09)
+ .byte 0x38 # STag 10 (bit 10)
+ .byte 0x70 # STag 11 (bit 11)
+ .byte 0x61 # STag 12 (bit 12)
+ .byte 0x62 # STag 13 (bit 13)
+ .byte 0x64 # STag 14 (bit 14)
+ .byte 0x68 # STag 15 (bit 15)
+ .byte 0x0b # STag 16 (bit 16)
+ .byte 0x15 # STag 17 (bit 17)
+ .byte 0x23 # STag 18 (bit 18)
+
+// END(tag_ecc_chk)
+ .end tag_ecc_chk
+#if 0
+/*********************************
+ * 2nd cache 64bit data ECC check
+ *
+ * v0 = return code (return value)
+ * 0x26 -- SCHE_DAT_1BIT
+ * 0x27 -- SCHE_DAT_2BIT_C
+ * 0x29 -- SCHE_DAT_UNKNOW
+ * v1 = data syndrome (return value)
+ *
+ * a0 = log field address (argument) : not used and not broken
+ * a1 = error code address (argument) : not used and not broken
+ * a2 = 2nd 64bit data erronious data (argument, return value)
+ * a3 = 8bit ECC data (argument, return value)
+ * t0 = cache virtual address : not used and not broken
+ * t1 = Cache error reg : not used and not broken
+ * t2 = TagLo reg : not used and not broken
+ * t3 = ECC reg : not used and not broken
+ * t4 - t7 temprary data
+ ********************************/
+LEAF(dat_ecc_chk)
+ .set reorder
+ li t4, 1 # target check bit
+ la t5, dat_synd # data syndrome address
+ move v1, zero # data syndrome and return value
+
+ # make syndrome data
+dat_ecc_loop1:
+ and t6, a2, t4
+ beqz t6, dat_ecc_skip0
+ lbu t7, (t5) # make syndrome of data
+ xor v1, t7 #
+dat_ecc_skip0:
+ addu t5, 1
+ DSLL (T4, T4, 1)
+ bnez t4, dat_ecc_loop1 # loop 63 times
+
+ li t4, 1 # target check bit
+dat_ecc_loop2:
+ and t6, a3, t4
+ beqz t6, dat_ecc_skip1
+ lbu t7, (t5) # make syndrome of data
+ xor v1, t7 #
+dat_ecc_skip1:
+ sll t4, 1
+ addu t5, 1
+ bne t4, 0x100, dat_ecc_loop2 # loop 7 times
+
+ bnez v1, dat_ecc_err # if error
+ li v0, SCHE_DAT_UNKNOW # else unknown error
+ j ra
+
+ # modify data
+dat_ecc_err:
+ li t4, 1 # target check bit
+ la t5, dat_synd # tag syndrome data
+
+dat_ecc_loop3:
+ lbu t7, (t5) # 1bit error
+ beq v1, t7, dat_ecc_1bit # then 1bit error
+
+ DSLL (T4, T4, 1)
+ addu t5, 1
+ bnez t4, dat_ecc_loop3 # loop 63 times
+
+ li t4, 1 # target check bit
+
+dat_ecc_loop4:
+ lbu t7, (t5) # 1bit error
+ beq v1, t7, dat_ecc_1bit2 # then 1bit error
+
+ sll t4, 1
+ addu t5, 1
+ bne t4, 0x100, dat_ecc_loop4 # loop 7 times
+
+ li v0, SCHE_DAT_2BIT_C # 2bit error
+ j ra
+
+dat_ecc_1bit2:
+ xor a3, t4 # modified ECC
+ j dat_ecc_1bitend
+
+dat_ecc_1bit:
+ xor a2, t4 # modified data
+dat_ecc_1bitend:
+ li v0, SCHE_DAT_1BIT # 1bit error
+ j ra
+
+dat_synd:
+ .byte 0x13 # Data 00 (bit 00)
+ .byte 0x23 # Data 01 (bit 01)
+ .byte 0x43 # Data 02 (bit 02)
+ .byte 0x83 # Data 03 (bit 03)
+ .byte 0x2f # Data 04 (bit 04)
+ .byte 0xf1 # Data 05 (bit 05)
+ .byte 0x0d # Data 06 (bit 06)
+ .byte 0x07 # Data 07 (bit 07)
+ .byte 0xd0 # Data 08 (bit 08)
+ .byte 0x70 # Data 09 (bit 09)
+ .byte 0x4f # Data 10 (bit 10)
+ .byte 0xf8 # Data 11 (bit 11)
+ .byte 0x61 # Data 12 (bit 12)
+ .byte 0x62 # Data 13 (bit 13)
+ .byte 0x64 # Data 14 (bit 14)
+ .byte 0x68 # Data 15 (bit 15)
+ .byte 0x1c # Data 16 (bit 16)
+ .byte 0x2c # Data 17 (bit 17)
+ .byte 0x4c # Data 18 (bit 18)
+ .byte 0x8c # Data 19 (bit 19)
+ .byte 0x15 # Data 20 (bit 20)
+ .byte 0x25 # Data 21 (bit 21)
+ .byte 0x45 # Data 22 (bit 22)
+ .byte 0x85 # Data 23 (bit 23)
+ .byte 0x19 # Data 24 (bit 24)
+ .byte 0x29 # Data 25 (bit 25)
+ .byte 0x49 # Data 26 (bit 26)
+ .byte 0x89 # Data 27 (bit 27)
+ .byte 0x1a # Data 28 (bit 28)
+ .byte 0x2a # Data 29 (bit 29)
+ .byte 0x4a # Data 30 (bit 30)
+ .byte 0x8a # Data 31 (bit 31)
+ .byte 0x51 # Data 32 (bit 32)
+ .byte 0x52 # Data 33 (bit 33)
+ .byte 0x54 # Data 34 (bit 34)
+ .byte 0x58 # Data 35 (bit 35)
+ .byte 0x91 # Data 36 (bit 36)
+ .byte 0x92 # Data 37 (bit 37)
+ .byte 0x94 # Data 38 (bit 38)
+ .byte 0x98 # Data 39 (bit 39)
+ .byte 0xa1 # Data 40 (bit 40)
+ .byte 0xa2 # Data 41 (bit 41)
+ .byte 0xa4 # Data 42 (bit 42)
+ .byte 0xa8 # Data 43 (bit 43)
+ .byte 0x31 # Data 44 (bit 44)
+ .byte 0x32 # Data 45 (bit 45)
+ .byte 0x34 # Data 46 (bit 46)
+ .byte 0x38 # Data 47 (bit 47)
+ .byte 0x16 # Data 48 (bit 48)
+ .byte 0x26 # Data 49 (bit 49)
+ .byte 0x46 # Data 50 (bit 50)
+ .byte 0x86 # Data 51 (bit 51)
+ .byte 0x1f # Data 52 (bit 52)
+ .byte 0xf2 # Data 53 (bit 53)
+ .byte 0x0b # Data 54 (bit 54)
+ .byte 0x0e # Data 55 (bit 55)
+ .byte 0xb0 # Data 56 (bit 56)
+ .byte 0xe0 # Data 57 (bit 57)
+ .byte 0x8f # Data 58 (bit 58)
+ .byte 0xf4 # Data 59 (bit 59)
+ .byte 0xc1 # Data 60 (bit 60)
+ .byte 0xc2 # Data 61 (bit 61)
+ .byte 0xc4 # Data 62 (bit 62)
+ .byte 0xc8 # Data 63 (bit 63)
+
+ .byte 0x01 # ECC 0 (bit 0)
+ .byte 0x02 # ECC 1 (bit 1)
+ .byte 0x04 # ECC 2 (bit 2)
+ .byte 0x08 # ECC 3 (bit 3)
+ .byte 0x10 # ECC 4 (bit 4)
+ .byte 0x20 # ECC 5 (bit 5)
+ .byte 0x40 # ECC 6 (bit 6)
+ .byte 0x80 # ECC 7 (bit 7)
+
+ END(dat_ecc_chk)
+#endif