R5900 support.

COP0_SYNC
	In R5900 mtc0, tlbr, tlbp, tlbwi, tlbwr must be followed by sync.p.
	if defined MIPS3_5900, COP0_SYNC is defined as sync.p. else nothing.
 IPL_ICU_MASK
	mask interrupt directly ICU instead of SR.IM.
	I've added this feature to support software interrupt for R5900.
	and this option may be useful for platform which has cascaded ICU.
This commit is contained in:
uch 2001-10-16 16:31:32 +00:00
parent bc1b53873f
commit d8c8db85ef
17 changed files with 956 additions and 41 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile.mips,v 1.19 2001/10/08 10:14:20 simonb Exp $
# $NetBSD: Makefile.mips,v 1.20 2001/10/16 16:31:32 uch Exp $
# Makefile for NetBSD
#
@ -115,6 +115,9 @@ SYSTEM_OBJ+= locore_mips1.o
.if !empty(IDENT:M-DMIPS3)
SYSTEM_OBJ+= locore_mips3.o
.endif
.if !empty(IDENT:M-DMIPS3_5900)
SYSTEM_OBJ+= locore_r5900.o r5900_machdep.o
.endif
.if empty(IDENT:M-DNOFPU)
SYSTEM_OBJ+= fp.o
.endif
@ -202,6 +205,9 @@ SFILES+=${MIPS}/mips/locore_mips1.S
.if !empty(IDENT:M-DMIPS3)
SFILES+=${MIPS}/mips/locore_mips3.S
.endif
.if !empty(IDENT:M-DMIPS3_5900)
SRCS+= ${MIPS}/mips/r5900/locore_r5900.S ${MIPS}/mips/r5900/r5900_machdep.c
.endif
.if empty(IDENT:M-DNOFPU)
SFILES+=${MIPS}/mips/fp.S
.endif
@ -245,6 +251,12 @@ locore_mips1.o: ${MIPS}/mips/locore_mips1.S assym.h
locore_mips3.o: ${MIPS}/mips/locore_mips3.S assym.h
${NORMAL_S}
locore_r5900.o: ${MIPS}/mips/r5900/locore_r5900.S assym.h
${NORMAL_S}
r5900_machdep.o: ${MIPS}/mips/r5900/r5900_machdep.c
${NORMAL_C}
.if empty(IDENT:M-DNOFPU)
fp.o: ${MIPS}/mips/fp.S assym.h
${NORMAL_S}

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpu.h,v 1.55 2001/09/04 09:23:27 simonb Exp $ */
/* $NetBSD: cpu.h,v 1.56 2001/10/16 16:31:33 uch Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -138,6 +138,7 @@ void cpu_intr __P((u_int32_t, u_int32_t, u_int32_t, u_int32_t));
struct clockframe {
int pc; /* program counter at time of interrupt */
int sr; /* status register at time of interrupt */
int ppl; /* previous priority level at time of interrupt */
};
/*
@ -157,6 +158,10 @@ struct clockframe {
#define MIPS3_CLKF_BASEPRI(framep) \
((~(framep)->sr & (MIPS_INT_MASK | MIPS_SR_INT_IE)) == 0)
#ifdef IPL_ICU_MASK
#define ICU_CLKF_BASEPRI(framep) ((framep)->ppl == 0)
#endif
#define CLKF_PC(framep) ((framep)->pc)
#define CLKF_INTR(framep) (0)
@ -170,6 +175,11 @@ struct clockframe {
#define CLKF_BASEPRI(framep) MIPS1_CLKF_BASEPRI(framep)
#endif
#ifdef IPL_ICU_MASK
#undef CLKF_BASEPRI
#define CLKF_BASEPRI(framep) ICU_CLKF_BASEPRI(framep)
#endif
#if defined(MIPS3) && defined(MIPS1)
#define CLKF_USERMODE(framep) \
((CPUISMIPS3) ? MIPS3_CLKF_USERMODE(framep): MIPS1_CLKF_USERMODE(framep))

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpuregs.h,v 1.46 2001/08/17 07:53:33 simonb Exp $ */
/* $NetBSD: cpuregs.h,v 1.47 2001/10/16 16:31:34 uch Exp $ */
/*
* Copyright (c) 1992, 1993
@ -92,6 +92,8 @@
#define MIPS3_VA_TO_CINDEX(x) \
((unsigned)(x) & 0xffffff | MIPS_KSEG0_START)
/* CPU dependent mtc0 hazard hook */
#define COP0_SYNC /* nothing */
/*
* The bits in the cause register.
@ -670,6 +672,7 @@
#define MIPS_RM7000 0x27 /* QED RM7000 ISA IV */
#define MIPS_RM5200 0x28 /* QED RM5200s ISA IV */
#define MIPS_TX4900 0x2d /* Toshiba TX49 family ISA III */
#define MIPS_R5900 0x2e /* Toshiba R5900 (EECore) ISA --- */
#define MIPS_RC64470 0x30 /* IDT RC64474/RC64475 ISA III */
#define MIPS_R5400 0x54 /* NEC VR5400 ISA IV */
@ -706,5 +709,8 @@
#ifdef ENABLE_MIPS_TX3900
#include <mips/r3900regs.h>
#endif
#ifdef MIPS3_5900
#include <mips/r5900/cpuregs.h>
#endif
#endif /* _MIPS_CPUREGS_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: locore.h,v 1.56 2001/08/18 04:13:28 simonb Exp $ */
/* $NetBSD: locore.h,v 1.57 2001/10/16 16:31:34 uch Exp $ */
/*
* Copyright 1996 The Board of Trustees of The Leland Stanford
@ -235,6 +235,8 @@ struct trapframe {
mips_reg_t tf_mullo;
mips_reg_t tf_mulhi;
mips_reg_t tf_epc; /* may be changed by trap() call */
u_int32_t tf_ppl; /* previous priority level */
int32_t tf_pad; /* for 8 byte aligned */
};
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: pcb.h,v 1.11 2000/09/13 01:53:00 nisimura Exp $ */
/* $NetBSD: pcb.h,v 1.12 2001/10/16 16:31:34 uch Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@ -52,6 +52,7 @@ struct pcb
struct fpreg pcb_fpregs; /* saved floating point registers */
mips_reg_t pcb_context[12]; /* kernel context for resume */
caddr_t pcb_onfault; /* for copyin/copyout faults */
u_int32_t pcb_ppl; /* previous priority level */
};
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: proc.h,v 1.12 2001/01/16 06:01:26 thorpej Exp $ */
/* $NetBSD: proc.h,v 1.13 2001/10/16 16:31:34 uch Exp $ */
/*
* Copyright (c) 1992, 1993
@ -65,6 +65,8 @@ struct mdproc {
*/
struct frame {
mips_reg_t f_regs[38];
u_int32_t f_ppl; /* previous priority level */
int32_t f_pad; /* for 8 byte aligned */
};
#ifdef _KERNEL

View File

@ -0,0 +1,90 @@
/* $NetBSD: cpuregs.h,v 1.1 2001/10/16 16:31:35 uch Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by UCHIYAMA Yasushi.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/* R5900 has Enable Interrupt Enable bit. */
#undef MIPS_SR_INT_IE
#define MIPS_SR_INT_IE 0x00010001 /* EIE + IE */
#undef COP0_SYNC
#define COP0_SYNC sync.p
/*
* R5900 has INT5,1,0 only don't support software interrupt
* MIPS_SOFT_INT_MASK_1 and MIPS_SOFT_INT_MASK_1 are emulated by kernel.
*/
#undef MIPS_INT_MASK
#define MIPS_INT_MASK 0x0c00
#undef MIPS_HARD_INT_MASK
#define MIPS_HARD_INT_MASK 0x0c00
#undef MIPS_COP_0_LLADDR
#undef MIPS_COP_0_WATCH_LO
#undef MIPS_COP_0_WATCH_HI
#undef MIPS_COP_0_TLB_XCONTEXT
#undef MIPS_COP_0_ECC
#undef MIPS_COP_0_CACHE_ERR
#undef MIPS_COP_0_DESAVE
/* Exception vector */
#define R5900_TLB_REFIL_EXC_VEC 0x80000000
#define R5900_COUNTER_EXC_VEC 0x80000080
#define R5900_DEBUG_EXC_VEC 0x80000100
#define R5900_COMMON_EXC_VEC 0x80000180
#define R5900_INTERRUPT_EXC_VEC 0x80000200
/* Cache */
#define R5900_C_SIZE_I 16384
#define R5900_C_SIZE_D 8192
#define R5900_C_LSIZE_I 64
#define R5900_C_LSIZE_D 64
#define R5900_C_IINV_I 0x07 /* INDEX INVALIDATE */
#define R5900_C_IWBINV_D 0x14 /* INDEX WRITE BACK INVALIDATE */
#define R5900_C_ILTG_D 0x10 /* INDEX LOAD TAG */
#define R5900_C_ISTG_D 0x12 /* INDEX STORE TAG */
#define R5900_C_IINV_D 0x16 /* INDEX INVALIDATE */
#define R5900_C_HINV_D 0x1a /* HIT INVALIDATE */
#define R5900_C_HWBINV_D 0x18 /* HIT WRITEBACK INVALIDATE */
#define R5900_C_ILDT_D 0x11 /* INDEX LOAD DATA */
#define R5900_C_ISDT_D 0x13 /* INDEX STORE DATA */
#define R5900_C_HWBWOINV_D 0x1c /* HIT WRITEBACK W/O INVALIDATE */
/* MMU R5900 support 32bit-mode only */
#define dmtc0 mtc0
#define dmfc0 mfc0

View File

@ -0,0 +1,48 @@
/* $NetBSD: locore.h,v 1.1 2001/10/16 16:31:35 uch Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by UCHIYAMA Yasushi.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _LOCORE
extern void r5900_init(void);
extern void r5900_FlushCache(void);
extern void r5900_FlushDCache(vaddr_t, vaddr_t);
extern void r5900_FlushICache(vaddr_t, vaddr_t);
extern void r5900_HitFlushDCache(vaddr_t, vsize_t);
extern void r5900_InvalidateDCache(vaddr_t, vsize_t);
#endif /* !_LOCORE */

View File

@ -1,4 +1,4 @@
/* $NetBSD: fpemu.c,v 1.6 2000/05/31 00:59:28 nisimura Exp $ */
/* $NetBSD: fpemu.c,v 1.7 2001/10/16 16:31:36 uch Exp $ */
/*
* Copyright (c) 1999 Shuichiro URATA. All rights reserved.
@ -92,6 +92,8 @@ update_pc(frame, cause)
frame->f_regs[PC] += 4;
}
#define LWSWC1_MAXLOOP 12
void
MachEmulateLWC1(inst, frame, cause)
u_int32_t inst;
@ -101,6 +103,8 @@ MachEmulateLWC1(inst, frame, cause)
u_int32_t vaddr;
int16_t offset;
void *t;
mips_reg_t pc;
int i;
offset = inst & 0xFFFF;
vaddr = frame->f_regs[(inst>>21)&0x1F] + offset;
@ -118,7 +122,39 @@ MachEmulateLWC1(inst, frame, cause)
return;
}
pc = frame->f_regs[PC];
update_pc(frame, cause);
if (cause & MIPS_CR_BR_DELAY)
return;
for (i = 1; i < LWSWC1_MAXLOOP; i++) {
if (mips_btop(frame->f_regs[PC]) != mips_btop(pc))
return;
inst = fuiword((u_int32_t *)frame->f_regs[PC]);
if (((InstFmt)inst).FRType.op != OP_LWC1)
return;
offset = inst & 0xFFFF;
vaddr = frame->f_regs[(inst>>21)&0x1F] + offset;
/* segment and alignment check */
if (vaddr & 0x80000003) {
send_sigsegv(vaddr, T_ADDR_ERR_LD, frame, cause);
return;
}
t = &(curpcb->pcb_fpregs.r_regs[(inst>>16)&0x1F]);
if (copyin((void *)vaddr, t, 4) != 0) {
send_sigsegv(vaddr, T_TLB_LD_MISS, frame, cause);
return;
}
pc = frame->f_regs[PC];
update_pc(frame, cause);
}
}
void
@ -159,6 +195,8 @@ MachEmulateSWC1(inst, frame, cause)
u_int32_t vaddr;
int16_t offset;
void *t;
mips_reg_t pc;
int i;
offset = inst & 0xFFFF;
vaddr = frame->f_regs[(inst>>21)&0x1F] + offset;
@ -176,7 +214,39 @@ MachEmulateSWC1(inst, frame, cause)
return;
}
pc = frame->f_regs[PC];
update_pc(frame, cause);
if (cause & MIPS_CR_BR_DELAY)
return;
for (i = 1; i < LWSWC1_MAXLOOP; i++) {
if (mips_btop(frame->f_regs[PC]) != mips_btop(pc))
return;
inst = fuiword((u_int32_t *)frame->f_regs[PC]);
if (((InstFmt)inst).FRType.op != OP_SWC1)
return;
offset = inst & 0xFFFF;
vaddr = frame->f_regs[(inst>>21)&0x1F] + offset;
/* segment and alignment check */
if (vaddr & 0x80000003) {
send_sigsegv(vaddr, T_ADDR_ERR_ST, frame, cause);
return;
}
t = &(curpcb->pcb_fpregs.r_regs[(inst>>16)&0x1F]);
if (copyout(t, (void *)vaddr, 4) != 0) {
send_sigsegv(vaddr, T_TLB_ST_MISS, frame, cause);
return;
}
pc = frame->f_regs[PC];
update_pc(frame, cause);
}
}
void

View File

@ -1,4 +1,4 @@
# $NetBSD: genassym.cf,v 1.23 2001/01/16 06:01:26 thorpej Exp $
# $NetBSD: genassym.cf,v 1.24 2001/10/16 16:31:36 uch Exp $
#
# Copyright (c) 1997
# Jonathan Stone. All rights reserved.
@ -70,6 +70,7 @@ define P_MD_SYSCALL offsetof(struct proc, p_md.md_syscall)
define U_PCB_FPREGS offsetof(struct user, u_pcb.pcb_fpregs)
define U_PCB_CONTEXT offsetof(struct user, u_pcb.pcb_context)
define U_PCB_ONFAULT offsetof(struct user, u_pcb.pcb_onfault)
define U_PCB_PPL offsetof(struct user, u_pcb.pcb_ppl)
define VM_MIN_ADDRESS VM_MIN_ADDRESS
define VM_MIN_KERNEL_ADDRESS VM_MIN_KERNEL_ADDRESS
@ -132,6 +133,7 @@ define FRAME_MULHI sizeof(mips_reg_t) * MULHI
define FRAME_BADVADDR sizeof(mips_reg_t) * BADVADDR
define FRAME_CAUSE sizeof(mips_reg_t) * CAUSE
define FRAME_EPC sizeof(mips_reg_t) * PC
define FRAME_PPL offsetof(struct frame, f_ppl)
define FRAME_FSR sizeof(mips_fpreg_t) * 32
define FRAME_FP0 sizeof(mips_fpreg_t) * 0
@ -200,6 +202,7 @@ define TF_REG_SR offsetof(struct trapframe, tf_sr)
define TF_REG_MULLO offsetof(struct trapframe, tf_mullo)
define TF_REG_MULHI offsetof(struct trapframe, tf_mulhi)
define TF_REG_EPC offsetof(struct trapframe, tf_epc)
define TF_PPL offsetof(struct trapframe, tf_ppl)
define CTXSWFRAME_SIZ sizeof(mips_reg_t) * 12
define SF_REG_SR sizeof(mips_reg_t) * 11

View File

@ -1,4 +1,4 @@
/* $NetBSD: locore.S,v 1.123 2001/09/22 21:29:21 manu Exp $ */
/* $NetBSD: locore.S,v 1.124 2001/10/16 16:31:36 uch Exp $ */
/*
* Copyright (c) 1992, 1993
@ -93,8 +93,10 @@ _C_LABEL(kernel_text):
mfc0 v0, MIPS_COP_0_STATUS
and v0, MIPS3_SR_DIAG_BEV
mtc0 v0, MIPS_COP_0_STATUS # Disable interrupts
COP0_SYNC
#else
mtc0 zero, MIPS_COP_0_STATUS # Disable interrupts
COP0_SYNC
#endif
/*
* Initialize stack and call machine startup.
@ -123,12 +125,14 @@ _C_LABEL(kernel_text):
li t1, 0xffffdfff
and t0, t0, t1
mtc0 t0, R3900_COP_0_CONFIG
COP0_SYNC
#ifdef R3900_CACHE_DISABLE
li t0, ~(R3900_CONFIG_ICE|R3900_CONFIG_DCE)
mfc0 t1, R3900_COP_0_CONFIG
and t1, t0, t1
nop
mtc0 t1, R3900_COP_0_CONFIG
COP0_SYNC
nop
#endif /* R3900_CACHE_DISABLE */
#endif /* ENABLE_MIPS_TX3900 */
@ -136,14 +140,17 @@ _C_LABEL(kernel_text):
#ifdef NOFPU /* No FPU; avoid touching FPU registers */
li t0, 0 # Disable interrupts and
mtc0 t0, MIPS_COP_0_STATUS # the fp coprocessor
COP0_SYNC
#ifdef HPCMIPS_L1CACHE_DISABLE
li t0, 0x00018c2 # XXX, KSEG0 is uncached
mtc0 t0, MIPS_COP_0_CONFIG
COP0_SYNC
#endif /* HPCMIPS_L1CACHE_DISABLE */
#else
mfc0 t0, MIPS_COP_0_STATUS
or t0, MIPS_SR_COP_1_BIT # Disable interrupts, and
mtc0 t0, MIPS_COP_0_STATUS # enable the fp coprocessor
COP0_SYNC
#endif
nop
nop
@ -293,9 +300,16 @@ END(remrunqueue)
* profiling.
*/
LEAF(mips_idle)
#ifdef IPL_ICU_MASK
# all interrupts enable.
sw zero, _C_LABEL(md_imask)
jal _C_LABEL(md_imask_update)
nop
#endif
li t0, (MIPS_INT_MASK | MIPS_SR_INT_IE)
DYNAMIC_STATUS_MASK(t0,t1) # machine dependent masking
mtc0 t0, MIPS_COP_0_STATUS # enable all interrupts
COP0_SYNC
nop
sw zero, _C_LABEL(curproc) # set curproc NULL for stats
#if defined(LOCKDEBUG)
@ -316,6 +330,7 @@ LEAF(mips_idle)
li t3, (MIPS_INT_MASK | MIPS_SR_INT_IE)
DYNAMIC_STATUS_MASK(t3,t1) # machine dependent masking
mtc0 t3, MIPS_COP_0_STATUS # enable all interrupts
COP0_SYNC
nop
#endif
lw t0, _C_LABEL(sched_whichqs) # look for non-empty queue
@ -324,6 +339,7 @@ LEAF(mips_idle)
nop
#if defined(LOCKDEBUG)
mtc0 zero, MIPS_COP_0_STATUS # disable all interrupts
COP0_SYNC
nop
nop
nop
@ -335,6 +351,7 @@ LEAF(mips_idle)
nop
#else
mtc0 zero, MIPS_COP_0_STATUS # disable all interrupts
COP0_SYNC
nop
nop
nop
@ -364,6 +381,10 @@ NESTED(cpu_switch, CALLFRAME_SIZ, ra)
REG_S s8, U_PCB_CONTEXT+SF_REG_S8(a0)
REG_S ra, U_PCB_CONTEXT+SF_REG_RA(a0)
REG_S t0, U_PCB_CONTEXT+SF_REG_SR(a0)
#ifdef IPL_ICU_MASK
lw t0, _C_LABEL(md_imask)
sw t0, U_PCB_PPL(a0)
#endif
REG_EPILOGUE
subu sp, sp, CALLFRAME_SIZ
sw ra, CALLFRAME_RA(sp)
@ -384,6 +405,11 @@ cpu_switch_queuescan:
1:
move t3, t0 # t3 = saved whichqs
1:
#if defined(MIPS3_5900) /* work around for branch prediction miss. */
nop
nop
nop
#endif
addu t2, t2, 1
and t1, t0, 1 # bit set?
beq t1, zero, 1b
@ -453,6 +479,14 @@ cpu_switch_queuescan:
sw zero, _C_LABEL(want_resched) # we've context switched
sw a0, _C_LABEL(curpcb)
#ifdef IPL_ICU_MASK
# restore ICU state
lw t0, U_PCB_PPL(a0)
sw t0, _C_LABEL(md_imask)
jal _C_LABEL(md_imask_update)
nop
lw a0, P_ADDR(s7) # restore pcb_context pointer.
#endif /* IPL_ICU_MASK */
REG_PROLOGUE
REG_L v0, U_PCB_CONTEXT+SF_REG_SR(a0)
DYNAMIC_STATUS_MASK(v0,ra) # machine dependent masking
@ -469,6 +503,7 @@ cpu_switch_queuescan:
REG_L s8, U_PCB_CONTEXT+SF_REG_S8(a0)
REG_EPILOGUE
mtc0 v0, MIPS_COP_0_STATUS
COP0_SYNC
j ra
li v0, 1 # possible return to 'savectx()'
END(cpu_switch)
@ -561,6 +596,7 @@ LEAF(longjmp)
REG_L s8, SF_REG_S8(a0)
REG_EPILOGUE
mtc0 v0, MIPS_COP_0_STATUS
COP0_SYNC
j ra
li v0, 1
END(longjmp)
@ -580,9 +616,10 @@ XLEAF(_splraise_noprof) # does not get mcount hooks
and a0, a0, v0 # disable retaining other bits
DYNAMIC_STATUS_MASK(a0,t0) # machine dependent masking
mtc0 a0, MIPS_COP_0_STATUS # store back
nop
j ra
COP0_SYNC
and v0, v0, (MIPS_INT_MASK | MIPS_SR_INT_IE)
j ra
nop
END(_splraise)
LEAF(_spllower)
@ -594,9 +631,10 @@ LEAF(_spllower)
or a0, a0, v1 # disable making other bits on
DYNAMIC_STATUS_MASK(a0,t0) # machine dependent masking
mtc0 a0, MIPS_COP_0_STATUS # store back
nop
j ra
COP0_SYNC
and v0, v0, (MIPS_INT_MASK | MIPS_SR_INT_IE)
j ra
nop
END(_spllower)
LEAF(_splrestore)
@ -607,9 +645,10 @@ LEAF(_splrestore)
or v1, v1, a0 # set old INT bits
DYNAMIC_STATUS_MASK(v1,t0) # machine dependent masking
mtc0 v1, MIPS_COP_0_STATUS # store back
nop
j ra
COP0_SYNC
and v0, v0, MIPS_INT_MASK
j ra
nop
END(_splrestore)
LEAF(_splset)
@ -621,28 +660,32 @@ XLEAF(_splset_noprof) # does not get mcount hooks
or v1, v1, a0 # set old INT bits
DYNAMIC_STATUS_MASK(v1,t0) # machine dependent masking
mtc0 v1, MIPS_COP_0_STATUS # store back
nop
j ra
COP0_SYNC
and v0, v0, (MIPS_INT_MASK | MIPS_SR_INT_IE)
j ra
nop
END(_splset)
LEAF(_splget)
mfc0 v0, MIPS_COP_0_STATUS # fetch status register
nop
j ra
and v0, v0, (MIPS_INT_MASK | MIPS_SR_INT_IE)
j ra
nop
END(_splget)
LEAF(_setsoftintr)
mfc0 v1, MIPS_COP_0_STATUS # save status register
mtc0 zero, MIPS_COP_0_STATUS # disable interrupts (2 cycles)
COP0_SYNC
nop
nop
mfc0 v0, MIPS_COP_0_CAUSE # fetch cause register
nop
or v0, v0, a0 # set soft intr. bits
mtc0 v0, MIPS_COP_0_CAUSE # store back
COP0_SYNC
mtc0 v1, MIPS_COP_0_STATUS # enable interrupts
COP0_SYNC
j ra
nop
END(_setsoftintr)
@ -650,22 +693,27 @@ END(_setsoftintr)
LEAF(_clrsoftintr)
mfc0 v1, MIPS_COP_0_STATUS # save status register
mtc0 zero, MIPS_COP_0_STATUS # disable interrupts (2 cycles)
COP0_SYNC
nop
nop
mfc0 v0, MIPS_COP_0_CAUSE # fetch cause register
nor a0, zero, a0 # bitwise inverse of A0
and v0, v0, a0 # clear soft intr. bits
mtc0 v0, MIPS_COP_0_CAUSE # store back
COP0_SYNC
mtc0 v1, MIPS_COP_0_STATUS # enable interrupts
COP0_SYNC
j ra
nop
END(_clrsoftintr)
LEAF(_splnone)
mtc0 zero, MIPS_COP_0_CAUSE # clear SOFT_INT bits
COP0_SYNC
li v0, (MIPS_INT_MASK | MIPS_SR_INT_IE)
DYNAMIC_STATUS_MASK(v0,t0) # machine dependent masking
mtc0 v0, MIPS_COP_0_STATUS # enable all sources
COP0_SYNC
nop
j ra
nop
@ -1118,6 +1166,7 @@ END(mips_cp0_cause_read)
*/
LEAF(mips_cp0_cause_write)
mtc0 a0, MIPS_COP_0_CAUSE
COP0_SYNC
nop
nop
j ra
@ -1147,6 +1196,7 @@ END(mips_cp0_status_read)
*/
LEAF(mips_cp0_status_write)
mtc0 a0, MIPS_COP_0_STATUS
COP0_SYNC
nop
nop
j ra
@ -1194,6 +1244,7 @@ XNESTED(MachFPTrap)
#ifndef SOFTFLOAT
or t0, t0, MIPS_SR_COP_1_BIT
mtc0 t0, MIPS_COP_0_STATUS
COP0_SYNC
nop
nop
nop # 1st extra nop for r4k
@ -1302,6 +1353,7 @@ FPReturn:
#ifndef SOFTFLOAT
and t0, t0, ~MIPS_SR_COP_1_BIT
mtc0 t0, MIPS_COP_0_STATUS
COP0_SYNC
#else
nop
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: locore_mips3.S,v 1.70 2001/07/24 23:13:33 rafal Exp $ */
/* $NetBSD: locore_mips3.S,v 1.71 2001/10/16 16:31:37 uch Exp $ */
/*
* Copyright (c) 1997 Jonathan Stone (hereinafter referred to as the author)
@ -112,6 +112,11 @@
* mtc0/mfc0 one integer op before and after
* tlbp -- one integer op afterwards
* Obvious solution is to take least common denominator.
*
* For the Toshiba R5900, TX79:
* mtc0 following sync.p
* tlbw[ri], tlbp following sync.p or eret
* for those CPU, define COP0_SYNC as sync.p
*/
/*
@ -194,12 +199,21 @@ VECTOR(mips3_TLBMiss, unknown)
lw k1, 4(k1) #0e: k1=lo1 pte
sll k0, 2 #0f: chop top 2 bits (part 1a)
srl k0, 2 #10: chop top 2 bits (part 1b)
#ifdef MIPS3_5900
mtc0 k0, MIPS_COP_0_TLB_LO0 #11: lo0 is loaded
sync.p #12: R5900 cop0 hazard
sll k1, 2 #13: chop top 2 bits (part 2a)
srl k1, 2 #14: chop top 2 bits (part 2b)
mtc0 k1, MIPS_COP_0_TLB_LO1 #15: lo1 is loaded
sync.p #16: R5900 cop0 hazard
#else /* MIPS3_5900 */
mtc0 k0, MIPS_COP_0_TLB_LO0 #11: lo0 is loaded
sll k1, 2 #12: chop top 2 bits (part 2a)
srl k1, 2 #13: chop top 2 bits (part 2b)
mtc0 k1, MIPS_COP_0_TLB_LO1 #14: lo1 is loaded
nop #15: standard nop
nop #16: extra nop for QED5230
#endif /* MIPS3_5900 */
tlbwr #17: write to tlb
nop #18: standard nop
nop #19: needed by R4000/4400
@ -211,6 +225,8 @@ VECTOR(mips3_TLBMiss, unknown)
nop #1f: branch delay slot
VECTOR_END(mips3_TLBMiss)
.set at
#ifndef MIPS3_5900
/*
* mips3_XTLBMiss routine
*
@ -276,7 +292,7 @@ VECTOR(mips3_cache, unknown)
VECTOR_END(mips3_cache)
.set at
#endif /* !MIPS3_5900 */
/*
*----------------------------------------------------------------------------
@ -422,6 +438,13 @@ NESTED_NOPROFILE(mips3_KernGenException, KERNFRAME_SIZ, ra)
REG_S a3, TF_BASE+TF_REG_EPC(sp)
addu v0, sp, TF_BASE
sw v0, KERNFRAME_ARG5(sp) # 5th arg is p. to trapframe
#ifdef IPL_ICU_MASK
.set at
lw v0, _C_LABEL(md_imask)
sw v0, TF_BASE+TF_PPL(sp)
nop
.set noat
#endif
/*
* Call the trap handler.
*/
@ -430,6 +453,7 @@ NESTED_NOPROFILE(mips3_KernGenException, KERNFRAME_SIZ, ra)
sw v0, KERNFRAME_SP(sp)
#endif
mtc0 zero, MIPS_COP_0_STATUS # Set kernel no error level
COP0_SYNC
nop
nop
nop
@ -440,17 +464,28 @@ NESTED_NOPROFILE(mips3_KernGenException, KERNFRAME_SIZ, ra)
* Restore registers and return from the exception.
*/
mtc0 zero, MIPS_COP_0_STATUS # Make sure int disabled
COP0_SYNC
nop # 3 nop delay
nop
nop
#ifdef IPL_ICU_MASK
.set at
lw a0, TF_BASE+TF_PPL(sp)
sw a0, _C_LABEL(md_imask)
jal _C_LABEL(md_imask_update)
nop
.set noat
#endif
REG_L a0, TF_BASE+TF_REG_SR(sp) # ??? why differs ???
REG_L t0, TF_BASE+TF_REG_MULLO(sp)
REG_L t1, TF_BASE+TF_REG_MULHI(sp)
REG_L k0, TF_BASE+TF_REG_EPC(sp) # might be changed inside trap
mtc0 a0, MIPS_COP_0_STATUS # restore the SR, disable intrs
COP0_SYNC
mtlo t0
mthi t1
dmtc0 k0, MIPS_COP_0_EXC_PC # set return address
COP0_SYNC
REG_L AT, TF_BASE+TF_REG_AST(sp)
REG_L v0, TF_BASE+TF_REG_V0(sp)
REG_L v1, TF_BASE+TF_REG_V1(sp)
@ -544,6 +579,12 @@ NESTED_NOPROFILE(mips3_UserGenException, CALLFRAME_SIZ, ra)
REG_S v0, FRAME_MULLO(k1)
REG_S v1, FRAME_MULHI(k1)
REG_S a3, FRAME_EPC(k1)
#ifdef IPL_ICU_MASK
.set at
lw t0, _C_LABEL(md_imask)
sw t0, FRAME_PPL(k1)
.set noat
#endif
addu sp, k1, -CALLFRAME_SIZ # switch to kernel SP
#ifdef __GP_SUPPORT__
la gp, _C_LABEL(_gp) # switch to kernel GP
@ -558,6 +599,7 @@ NESTED_NOPROFILE(mips3_UserGenException, CALLFRAME_SIZ, ra)
* Call the trap handler.
*/
mtc0 t0, MIPS_COP_0_STATUS
COP0_SYNC
jal _C_LABEL(trap)
sw a3, CALLFRAME_SIZ-4(sp) # for debugging
/*
@ -578,15 +620,26 @@ NESTED_NOPROFILE(mips3_UserGenException, CALLFRAME_SIZ, ra)
* First disable interrupts and set exception level.
*/
mtc0 zero, MIPS_COP_0_STATUS # disable interrupt
COP0_SYNC
nop # 3 clock delay before
nop # exceptions blocked
nop # for R4X
li v0, MIPS_SR_EXL
mtc0 v0, MIPS_COP_0_STATUS # set exception level
COP0_SYNC
nop # 3 nop delay
nop
nop
addu a1, sp, CALLFRAME_SIZ
#ifdef IPL_ICU_MASK
.set at
lw t0, FRAME_PPL(a1)
sw t0, _C_LABEL(md_imask)
jal _C_LABEL(md_imask_update)
nop
addu a1, sp, CALLFRAME_SIZ
.set noat
#endif
# REG_L a0, FRAME_SR(a1)
REG_L t0, FRAME_MULLO(a1)
REG_L t1, FRAME_MULHI(a1)
@ -595,6 +648,7 @@ NESTED_NOPROFILE(mips3_UserGenException, CALLFRAME_SIZ, ra)
mtlo t0
mthi t1
dmtc0 v0, MIPS_COP_0_EXC_PC # set return address
COP0_SYNC
move k1, a1
REG_L AT, FRAME_AST(k1)
@ -629,6 +683,7 @@ NESTED_NOPROFILE(mips3_UserGenException, CALLFRAME_SIZ, ra)
REG_L s8, FRAME_S8(k1)
REG_L ra, FRAME_RA(k1)
mtc0 k0, MIPS_COP_0_STATUS # restore status
COP0_SYNC
nop
nop
eret # return to interrupted point
@ -686,6 +741,12 @@ NESTED_NOPROFILE(mips3_SystemCall, CALLFRAME_SIZ, ra)
REG_S v0, FRAME_MULLO(k1)
REG_S v1, FRAME_MULHI(k1)
REG_S a3, FRAME_EPC(k1)
#ifdef IPL_ICU_MASK
.set at
lw t0, _C_LABEL(md_imask)
sw t0, FRAME_PPL(k1)
.set noat
#endif
addu sp, k1, -CALLFRAME_SIZ
#ifdef __GP_SUPPORT__
la gp, _C_LABEL(_gp) # switch to kernel GP
@ -705,6 +766,7 @@ NESTED_NOPROFILE(mips3_SystemCall, CALLFRAME_SIZ, ra)
* Call the system call handler.
*/
mtc0 t0, MIPS_COP_0_STATUS # re-enable interrupts
COP0_SYNC
jal t1
nop
/*
@ -725,12 +787,14 @@ NESTED_NOPROFILE(mips3_SystemCall, CALLFRAME_SIZ, ra)
* First disable interrupts and set exception level.
*/
mtc0 zero, MIPS_COP_0_STATUS # disable int
COP0_SYNC
nop # 3 op delay
nop
nop
li v0, MIPS_SR_EXL
mtc0 v0, MIPS_COP_0_STATUS # set exception level
COP0_SYNC
nop # 3 op delay
nop
nop
@ -738,6 +802,15 @@ NESTED_NOPROFILE(mips3_SystemCall, CALLFRAME_SIZ, ra)
* Restore user registers and return.
*/
addu a1, sp, CALLFRAME_SIZ
#ifdef IPL_ICU_MASK
.set at
lw t0, FRAME_PPL(a1)
sw t0, _C_LABEL(md_imask)
jal _C_LABEL(md_imask_update)
nop
addu a1, sp, CALLFRAME_SIZ
.set noat
#endif
# REG_L a0, FRAME_SR(a1)
REG_L t0, FRAME_MULLO(a1)
REG_L t1, FRAME_MULHI(a1)
@ -746,6 +819,7 @@ NESTED_NOPROFILE(mips3_SystemCall, CALLFRAME_SIZ, ra)
mtlo t0
mthi t1
dmtc0 v0, MIPS_COP_0_EXC_PC # set return address
COP0_SYNC
move k1, a1
REG_L AT, FRAME_AST(k1)
REG_L v0, FRAME_V0(k1)
@ -779,6 +853,7 @@ NESTED_NOPROFILE(mips3_SystemCall, CALLFRAME_SIZ, ra)
REG_L s8, FRAME_S8(k1)
REG_L ra, FRAME_RA(k1)
mtc0 k0, MIPS_COP_0_STATUS
COP0_SYNC
nop # 3 nops before eret
nop
nop
@ -786,6 +861,7 @@ NESTED_NOPROFILE(mips3_SystemCall, CALLFRAME_SIZ, ra)
.set at
END(mips3_SystemCall)
#ifndef MIPS3_5900
/*
* Panic on cache errors. A lot more could be done to recover
* from some types of errors but it is tricky.
@ -799,11 +875,13 @@ NESTED_NOPROFILE(mips3_cacheException, KERNFRAME_SIZ, ra)
mfc0 a2, MIPS_COP_0_CACHE_ERR # 3rd arg cache error
dmtc0 k0, MIPS_COP_0_ERROR_PC # set return address
COP0_SYNC
mfc0 k0, MIPS_COP_0_STATUS # restore status
li k1, MIPS3_SR_DIAG_PE # ignore further errors
or k0, k1
mtc0 k0, MIPS_COP_0_STATUS # restore status
COP0_SYNC
nop
nop
nop
@ -813,6 +891,7 @@ NESTED_NOPROFILE(mips3_cacheException, KERNFRAME_SIZ, ra)
MSG("cache error @ EPC 0x%x CachErr 0x%x");
.set at
END(mips3_cacheException)
#endif /* !MIPS3_5900 */
/*
* mips3_KernIntr
@ -865,25 +944,43 @@ NESTED_NOPROFILE(mips3_KernIntr, KERNFRAME_SIZ, ra)
move ra, a2
sw ra, KERNFRAME_RA(sp) # for debugging
#endif
#ifdef IPL_ICU_MASK
.set at
lw t0, _C_LABEL(md_imask)
sw t0, TF_BASE+TF_PPL(sp)
.set noat
#endif
mtc0 zero, MIPS_COP_0_STATUS # Reset exl, trap possible.
COP0_SYNC
jal _C_LABEL(cpu_intr)
and a3, a0, a1 # 4th is STATUS & CAUSE
/*
* Restore registers and return from the interrupt.
*/
mtc0 zero, MIPS_COP_0_STATUS # Disable interrupt
COP0_SYNC
nop
nop
nop
#ifdef IPL_ICU_MASK
.set at
lw a0, TF_BASE+TF_PPL(sp)
sw a0, _C_LABEL(md_imask)
jal _C_LABEL(md_imask_update)
nop
.set noat
#endif
REG_L a0, TF_BASE+TF_REG_SR(sp) # ??? why differs ???
DYNAMIC_STATUS_MASK(a0,t0) # machine dependent masking
REG_L t0, TF_BASE+TF_REG_MULLO(sp)
REG_L t1, TF_BASE+TF_REG_MULHI(sp)
REG_L v0, TF_BASE+TF_REG_EPC(sp)
mtc0 a0, MIPS_COP_0_STATUS # restore the SR, disable intrs
COP0_SYNC
mtlo t0
mthi t1
dmtc0 v0, MIPS_COP_0_EXC_PC # set return address
COP0_SYNC
REG_L AT, TF_BASE+TF_REG_AST(sp)
REG_L v0, TF_BASE+TF_REG_V0(sp)
@ -966,6 +1063,12 @@ NESTED_NOPROFILE(mips3_UserIntr, CALLFRAME_SIZ, ra)
REG_S v0, FRAME_MULLO(k1)
REG_S v1, FRAME_MULHI(k1)
REG_S a2, FRAME_EPC(k1)
#ifdef IPL_ICU_MASK
.set at
lw t0, _C_LABEL(md_imask)
sw t0, FRAME_PPL(k1)
.set noat
#endif
addu sp, k1, -CALLFRAME_SIZ # switch to kernel SP
#ifdef __GP_SUPPORT__
la gp, _C_LABEL(_gp) # switch to kernel GP
@ -984,6 +1087,7 @@ NESTED_NOPROFILE(mips3_UserIntr, CALLFRAME_SIZ, ra)
* Call the interrupt handler.
*/
mtc0 t0, MIPS_COP_0_STATUS
COP0_SYNC
jal _C_LABEL(cpu_intr)
and a3, a0, a1 # 4th is STATUS & CAUSE
/*
@ -991,11 +1095,13 @@ NESTED_NOPROFILE(mips3_UserIntr, CALLFRAME_SIZ, ra)
*/
nop
mtc0 zero, MIPS_COP_0_STATUS
COP0_SYNC
nop # 3 nop hazard
nop
nop
li v0, MIPS_SR_EXL
mtc0 v0, MIPS_COP_0_STATUS # set exception level bit.
COP0_SYNC
nop # 3 nop hazard
nop
nop
@ -1021,22 +1127,29 @@ NESTED_NOPROFILE(mips3_UserIntr, CALLFRAME_SIZ, ra)
REG_S s6, FRAME_S6(a1)
REG_S s7, FRAME_S7(a1)
REG_S s8, FRAME_S8(a1)
REG_L a0, FRAME_EPC(a1) # argument is interrupted PC
#ifdef IPL_ICU_MASK
jal _C_LABEL(spllowersofthigh);
nop
#else
li t0, MIPS_HARD_INT_MASK | MIPS_SR_INT_IE
DYNAMIC_STATUS_MASK(t0,t1) # machine dependent masking
jal _C_LABEL(ast)
mtc0 t0, MIPS_COP_0_STATUS # enable interrupts (spl0)
COP0_SYNC
#endif
jal _C_LABEL(ast)
nop
/*
* Restore user registers and return. NOTE: interrupts are enabled.
*/
mtc0 zero, MIPS_COP_0_STATUS
COP0_SYNC
nop # 3 nop delay
nop
nop
li v0, MIPS_SR_EXL
mtc0 v0, MIPS_COP_0_STATUS # set exception level bit.
COP0_SYNC
nop # 3 nop delay
nop
nop
@ -1061,10 +1174,19 @@ NESTED_NOPROFILE(mips3_UserIntr, CALLFRAME_SIZ, ra)
mtlo t0
mthi t1
dmtc0 v0, MIPS_COP_0_EXC_PC # set return address
COP0_SYNC
nop # ??? how much delay ???
nop
move k1, a1
#ifdef IPL_ICU_MASK
.set at
lw t0, FRAME_PPL(k1)
sw t0, _C_LABEL(md_imask)
jal _C_LABEL(md_imask_update)
nop
.set noat
#endif
REG_L AT, FRAME_AST(k1)
REG_L v0, FRAME_V0(k1)
REG_L v1, FRAME_V1(k1)
@ -1088,6 +1210,7 @@ NESTED_NOPROFILE(mips3_UserIntr, CALLFRAME_SIZ, ra)
REG_L sp, FRAME_SP(k1)
REG_L ra, FRAME_RA(k1)
mtc0 k0, MIPS_COP_0_STATUS # restore the SR
COP0_SYNC
nop # required for QED 5230
nop
eret # return to interrupted point
@ -1142,6 +1265,7 @@ LEAF_NOPROFILE(mips3_TLBInvalidException)
sll k0, k0, 2 # compute offset from index
addu k1, k1, k0
tlbp # Probe the invalid entry
COP0_SYNC
and k0, k0, 4 # check even/odd page
nop # required for QED 5230
bne k0, zero, KernTLBIOdd
@ -1155,6 +1279,7 @@ LEAF_NOPROFILE(mips3_TLBInvalidException)
dsll k0, k0, 34 # get rid of "wired" bit
dsrl k0, k0, 34
dmtc0 k0, MIPS_COP_0_TLB_LO0 # load PTE entry
COP0_SYNC
and k0, k0, MIPS3_PG_V # check for valid entry
nop # required for QED5230
beq k0, zero, _C_LABEL(mips3_KernGenException) # PTE invalid
@ -1165,9 +1290,11 @@ LEAF_NOPROFILE(mips3_TLBInvalidException)
sltiu k1, k1, MIPS3_TLB_WIRED_UPAGES # Luckily this is MIPS3_PG_G
or k1, k1, k0
dmtc0 k0, MIPS_COP_0_TLB_LO1 # load PTE entry
COP0_SYNC
nop
nop # required for QED5230
tlbwi # write TLB
COP0_SYNC
nop
nop
nop
@ -1184,6 +1311,7 @@ KernTLBIOdd:
dsll k0, k0, 34 # get rid of wired bit
dsrl k0, k0, 34
dmtc0 k0, MIPS_COP_0_TLB_LO1 # save PTE entry
COP0_SYNC
and k0, k0, MIPS3_PG_V # check for valid entry
nop # required for QED5230
beq k0, zero, _C_LABEL(mips3_KernGenException) # PTE invalid
@ -1194,9 +1322,11 @@ KernTLBIOdd:
sltiu k1, k1, MIPS3_TLB_WIRED_UPAGES # Luckily this is MIPS3_PG_G
or k1, k1, k0
dmtc0 k0, MIPS_COP_0_TLB_LO0 # save PTE entry
COP0_SYNC
nop
nop # required for QED5230
tlbwi # update TLB
COP0_SYNC
nop
nop
nop
@ -1247,12 +1377,15 @@ LEAF_NOPROFILE(mips3_TLBMissException)
dsll k0, k0, 34 # get rid of "wired" bit
dsrl k0, k0, 34
dmtc0 k0, MIPS_COP_0_TLB_LO0 # load PTE entry
COP0_SYNC
dsll k1, k1, 34
dsrl k1, k1, 34
dmtc0 k1, MIPS_COP_0_TLB_LO1 # load PTE entry
COP0_SYNC
nop
nop # required for QED5230
tlbwr # write TLB
COP0_SYNC
nop
nop
nop
@ -1267,6 +1400,7 @@ outofworld:
move a1, sp
sll k0, k0, PGSHIFT
dmtc0 a0, MIPS_COP_0_EXC_PC # return to panic
COP0_SYNC
li k1, VM_MIN_KERNEL_ADDRESS
addu a3, k0, k1
#if defined(DDB)
@ -1309,6 +1443,7 @@ _C_LABEL(mips3_exceptionentry_end):
*/
LEAF(mips3_SetPID)
dmtc0 a0, MIPS_COP_0_TLB_HI # Write the hi reg value
COP0_SYNC
nop # required for QED5230
nop # required for QED5230
j ra
@ -1335,15 +1470,18 @@ END(mips3_SetPID)
LEAF(mips3_TLBUpdate)
mfc0 v1, MIPS_COP_0_STATUS # Save the status register.
mtc0 zero, MIPS_COP_0_STATUS # Disable interrupts
COP0_SYNC
and t1, a0, MIPS3_PG_ODDPG # t1 = Even/Odd flag
li v0, (MIPS3_PG_HVPN | MIPS3_PG_ASID)
and a0, a0, v0
dmfc0 t0, MIPS_COP_0_TLB_HI # Save current PID
dmtc0 a0, MIPS_COP_0_TLB_HI # Init high reg
COP0_SYNC
and a2, a1, MIPS3_PG_G # Copy global bit
nop
nop
tlbp # Probe for the entry.
COP0_SYNC
dsll a1, a1, 34
dsrl a1, a1, 34
bne t1, zero, 2f # Decide even odd
@ -1355,13 +1493,16 @@ LEAF(mips3_TLBUpdate)
nop # required for QED5230
tlbr # update, read entry first
COP0_SYNC
nop
nop
nop
dmtc0 a1, MIPS_COP_0_TLB_LO0 # init low reg0.
COP0_SYNC
nop
nop # required for QED5230
tlbwi # update slot found
COP0_SYNC
nop # required for QED5230
nop # required for QED5230
b 4f
@ -1370,15 +1511,21 @@ LEAF(mips3_TLBUpdate)
#ifdef MIPS3_4100 /* VR4100 core */
lw v0, _C_LABEL(default_pg_mask) # default_pg_mask declared
mtc0 v0, MIPS_COP_0_TLB_PG_MASK # in mips_machdep.c
COP0_SYNC
#else
mtc0 zero, MIPS_COP_0_TLB_PG_MASK # init mask.
COP0_SYNC
#endif
dmtc0 a0, MIPS_COP_0_TLB_HI # init high reg.
COP0_SYNC
dmtc0 a1, MIPS_COP_0_TLB_LO0 # init low reg0.
COP0_SYNC
dmtc0 a2, MIPS_COP_0_TLB_LO1 # init low reg1.
COP0_SYNC
nop
nop # required for QED5230
tlbwr # enter into a random slot
COP0_SYNC
nop # required for QED5230
nop # required for QED5230
b 4f
@ -1391,13 +1538,16 @@ LEAF(mips3_TLBUpdate)
nop # required for QED5230
tlbr # read the entry first
COP0_SYNC
nop
nop
nop
dmtc0 a1, MIPS_COP_0_TLB_LO1 # init low reg1.
COP0_SYNC
nop
nop # required for QED5230
tlbwi # update slot found
COP0_SYNC
nop # required for QED5230
nop # required for QED5230
b 4f
@ -1406,26 +1556,33 @@ LEAF(mips3_TLBUpdate)
#ifdef MIPS3_4100 /* VR4100 core */
lw v0, _C_LABEL(default_pg_mask) # default_pg_mask declared
mtc0 v0, MIPS_COP_0_TLB_PG_MASK # in mips_machdep.c
COP0_SYNC
#else
mtc0 zero, MIPS_COP_0_TLB_PG_MASK # init mask.
COP0_SYNC
#endif
dmtc0 a0, MIPS_COP_0_TLB_HI # init high reg.
COP0_SYNC
dmtc0 a2, MIPS_COP_0_TLB_LO0 # init low reg0.
COP0_SYNC
dmtc0 a1, MIPS_COP_0_TLB_LO1 # init low reg1.
COP0_SYNC
nop
nop # required for QED5230
tlbwr # enter into a random slot
COP0_SYNC
4: # Make shure pipeline
nop # advances before we
nop # uses the tlb.
nop
nop
dmtc0 t0, MIPS_COP_0_TLB_HI # restore PID
COP0_SYNC
nop # required for QED5230
nop # required for QED5230
j ra
mtc0 v1, MIPS_COP_0_STATUS # Restore the status register
COP0_SYNC
END(mips3_TLBUpdate)
/*--------------------------------------------------------------------------
@ -1449,15 +1606,18 @@ END(mips3_TLBUpdate)
LEAF(mips3_TLBRead)
mfc0 v1, MIPS_COP_0_STATUS # Save the status register.
mtc0 zero, MIPS_COP_0_STATUS # Disable interrupts
COP0_SYNC
nop
mfc0 t6, MIPS_COP_0_TLB_PG_MASK # save current pgMask
nop
dmfc0 t0, MIPS_COP_0_TLB_HI # Get current PID
mtc0 a0, MIPS_COP_0_TLB_INDEX # Set the index register
COP0_SYNC
nop
nop # required for QED5230
tlbr # Read from the TLB
COP0_SYNC
nop
nop
nop
@ -1466,11 +1626,14 @@ LEAF(mips3_TLBRead)
dmfc0 t4, MIPS_COP_0_TLB_LO0 # See what we got
dmfc0 t5, MIPS_COP_0_TLB_LO1 # See what we got
dmtc0 t0, MIPS_COP_0_TLB_HI # restore PID
COP0_SYNC
mtc0 t6, MIPS_COP_0_TLB_PG_MASK # restore pgMask
COP0_SYNC
nop
nop
nop # wait for PID active
mtc0 v1, MIPS_COP_0_STATUS # Restore the status register
COP0_SYNC
nop
sw t2, 0(a1)
sw t3, 4(a1)
@ -1479,6 +1642,7 @@ LEAF(mips3_TLBRead)
sw t5, 12(a1)
END(mips3_TLBRead)
#ifndef MIPS3_5900
/*----------------------------------------------------------------------------
*
* mips3_FlushCache --
@ -2092,6 +2256,7 @@ _C_LABEL(VCE_epc):
_C_LABEL(VCE_vaddr):
.word 0
END(mips3_VCED)
#endif /* !MIPS3_5900 */
/*----------------------------------------------------------------------------
*
@ -2134,11 +2299,13 @@ LEAF(mips3_proc_trampoline)
# saved if EXL=1.
#
mtc0 zero, MIPS_COP_0_STATUS # disable int
COP0_SYNC
nop # 3 op delay
nop
nop
li a0, MIPS_SR_EXL # set exception level
mtc0 a0, MIPS_COP_0_STATUS
COP0_SYNC
nop
nop
addu a1, sp, CALLFRAME_SIZ
@ -2149,8 +2316,17 @@ LEAF(mips3_proc_trampoline)
mtlo t0
mthi t1
dmtc0 v0, MIPS_COP_0_EXC_PC
COP0_SYNC
nop
move k1, a1
#ifdef IPL_ICU_MASK
.set at
lw t0, FRAME_PPL(k1)
sw t0, _C_LABEL(md_imask)
jal _C_LABEL(md_imask_update)
nop
.set noat
#endif
REG_L AT, FRAME_AST(k1)
REG_L v0, FRAME_V0(k1)
REG_L v1, FRAME_V1(k1)
@ -2183,12 +2359,14 @@ LEAF(mips3_proc_trampoline)
REG_L ra, FRAME_RA(k1)
REG_L sp, FRAME_SP(k1)
mtc0 k0, MIPS_COP_0_STATUS
COP0_SYNC
nop
nop
eret
.set at
END(mips3_proc_trampoline)
#ifndef MIPS3_5900
/*
* rm52xx_idle:
*
@ -2205,6 +2383,7 @@ LEAF(rm52xx_idle)
li t0, (MIPS_INT_MASK | MIPS_SR_INT_IE)
DYNAMIC_STATUS_MASK(t0,t1) # machine dependent masking
mtc0 t0, MIPS_COP_0_STATUS # enable all interrupts
COP0_SYNC
nop
sw zero, _C_LABEL(curproc) # set curproc NULL for stats
#if defined(LOCKDEBUG)
@ -2225,6 +2404,7 @@ LEAF(rm52xx_idle)
li t3, (MIPS_INT_MASK | MIPS_SR_INT_IE)
DYNAMIC_STATUS_MASK(t3,t1) # machine dependent masking
mtc0 t3, MIPS_COP_0_STATUS # enable all interrupts
COP0_SYNC
nop
#endif
lw t0, _C_LABEL(sched_whichqs) # look for non-empty queue
@ -2240,6 +2420,7 @@ LEAF(rm52xx_idle)
1:
#if defined(LOCKDEBUG)
mtc0 zero, MIPS_COP_0_STATUS # disable all interrupts
COP0_SYNC
nop
nop
nop
@ -2251,6 +2432,7 @@ LEAF(rm52xx_idle)
nop
#else
mtc0 zero, MIPS_COP_0_STATUS # disable all interrupts
COP0_SYNC
nop
nop
nop
@ -2259,6 +2441,7 @@ LEAF(rm52xx_idle)
nop
#endif
END(rm52xx_idle)
#endif /* !MIPS3_5900 */
/*
* void mips3_cpu_switch_resume(struct proc *newproc)
@ -2283,9 +2466,11 @@ LEAF_NOPROFILE(mips3_cpu_switch_resume)
entry0:
dmtc0 v0, MIPS_COP_0_TLB_HI # VPN = va
COP0_SYNC
nop
nop
tlbp # probe VPN
COP0_SYNC
nop
nop
mfc0 s0, MIPS_COP_0_TLB_INDEX
@ -2293,23 +2478,32 @@ entry0:
bltz s0, entry0set
li s0, MIPS_KSEG0_START
dmtc0 s0, MIPS_COP_0_TLB_HI
COP0_SYNC
dmtc0 zero, MIPS_COP_0_TLB_LO0
COP0_SYNC
dmtc0 zero, MIPS_COP_0_TLB_LO1
COP0_SYNC
nop
nop
tlbwi
COP0_SYNC
nop
nop
dmtc0 v0, MIPS_COP_0_TLB_HI # set VPN again
COP0_SYNC
entry0set:
mtc0 zero, MIPS_COP_0_TLB_INDEX # TLB entry #0
COP0_SYNC
or a1, MIPS3_PG_G
dmtc0 a1, MIPS_COP_0_TLB_LO0 # upte[0] | PG_G
COP0_SYNC
or a2, MIPS3_PG_G
dmtc0 a2, MIPS_COP_0_TLB_LO1 # upte[1] | PG_G
COP0_SYNC
nop
nop
tlbwi # set TLB entry #0
COP0_SYNC
nop
nop
@ -2326,15 +2520,18 @@ resume:
LEAF_NOPROFILE(mips3_TBIS)
mfc0 v1, MIPS_COP_0_STATUS # save status register
mtc0 zero, MIPS_COP_0_STATUS # disable interrupts
COP0_SYNC
li v0, (MIPS3_PG_HVPN | MIPS3_PG_ASID)
dmfc0 t0, MIPS_COP_0_TLB_HI # save current ASID
mfc0 t3, MIPS_COP_0_TLB_PG_MASK # save current pgMask
and a0, a0, v0 # make sure valid entryHi
dmtc0 a0, MIPS_COP_0_TLB_HI # look for the vaddr & ASID
COP0_SYNC
nop
nop
tlbp # probe the entry in question
COP0_SYNC
nop
nop
mfc0 v0, MIPS_COP_0_TLB_INDEX # see what we got
@ -2343,21 +2540,29 @@ LEAF_NOPROFILE(mips3_TBIS)
bltz v0, 1f # index < 0 then skip
li t1, MIPS_KSEG0_START # invalid address
dmtc0 t1, MIPS_COP_0_TLB_HI # make entryHi invalid
COP0_SYNC
dmtc0 zero, MIPS_COP_0_TLB_LO0 # zero out entryLo0
COP0_SYNC
dmtc0 zero, MIPS_COP_0_TLB_LO1 # zero out entryLo1
COP0_SYNC
mtc0 zero, MIPS_COP_0_TLB_PG_MASK # zero out pageMask
COP0_SYNC
nop
nop
tlbwi
COP0_SYNC
nop
nop
1:
dmtc0 t0, MIPS_COP_0_TLB_HI # restore current ASID
COP0_SYNC
mtc0 t3, MIPS_COP_0_TLB_PG_MASK # restore pgMask
COP0_SYNC
nop
nop
j ra
mtc0 v1, MIPS_COP_0_STATUS # restore status register
COP0_SYNC
END(mips3_TBIS)
/*
@ -2369,6 +2574,7 @@ LEAF_NOPROFILE(mips3_TBIS)
LEAF_NOPROFILE(mips3_TBIAP)
mfc0 v1, MIPS_COP_0_STATUS # save status register
mtc0 zero, MIPS_COP_0_STATUS # disable interrupts
COP0_SYNC
move t2, a0
mfc0 t1, MIPS_COP_0_TLB_WIRED
@ -2378,9 +2584,11 @@ LEAF_NOPROFILE(mips3_TBIAP)
# do {} while (t1 < t2)
1:
mtc0 t1, MIPS_COP_0_TLB_INDEX # set index
COP0_SYNC
nop
nop
tlbr # obtain an entry
COP0_SYNC
nop
nop
nop
@ -2392,12 +2600,17 @@ LEAF_NOPROFILE(mips3_TBIAP)
nop
dmtc0 v0, MIPS_COP_0_TLB_HI # make entryHi invalid
COP0_SYNC
dmtc0 zero, MIPS_COP_0_TLB_LO0 # zero out entryLo0
COP0_SYNC
dmtc0 zero, MIPS_COP_0_TLB_LO1 # zero out entryLo1
COP0_SYNC
mtc0 zero, MIPS_COP_0_TLB_PG_MASK # zero out mask entry
COP0_SYNC
nop
nop
tlbwi # invalidate the TLB entry
COP0_SYNC
#nop
#nop
2:
@ -2406,10 +2619,12 @@ LEAF_NOPROFILE(mips3_TBIAP)
nop
mtc0 t3, MIPS_COP_0_TLB_PG_MASK # restore pgMask
COP0_SYNC
nop
nop
j ra # new ASID will be set soon
mtc0 v1, MIPS_COP_0_STATUS # restore status register
COP0_SYNC
END(mips3_TBIAP)
/*
@ -2420,6 +2635,7 @@ LEAF_NOPROFILE(mips3_TBIAP)
LEAF_NOPROFILE(mips3_TBIA)
mfc0 v1, MIPS_COP_0_STATUS # save status register
mtc0 zero, MIPS_COP_0_STATUS # disable interrupts
COP0_SYNC
li v0, MIPS_KSEG0_START # invalid address
dmfc0 t0, MIPS_COP_0_TLB_HI # save current ASID
@ -2427,16 +2643,22 @@ LEAF_NOPROFILE(mips3_TBIA)
mfc0 t2, MIPS_COP_0_TLB_PG_MASK # save current pgMask
dmtc0 v0, MIPS_COP_0_TLB_HI # make entryHi invalid
COP0_SYNC
dmtc0 zero, MIPS_COP_0_TLB_LO0 # zero out entryLo0
COP0_SYNC
dmtc0 zero, MIPS_COP_0_TLB_LO1 # zero out entryLo1
COP0_SYNC
mtc0 zero, MIPS_COP_0_TLB_PG_MASK # zero out pageMask
COP0_SYNC
# do {} while (t1 < a0)
1:
mtc0 t1, MIPS_COP_0_TLB_INDEX # set TLBindex
COP0_SYNC
nop
nop
tlbwi # clear the entry
COP0_SYNC
#nop
#nop
addu t1, t1, 1 # increment index
@ -2444,13 +2666,17 @@ LEAF_NOPROFILE(mips3_TBIA)
nop
dmtc0 t0, MIPS_COP_0_TLB_HI # restore ASID
COP0_SYNC
mtc0 t2, MIPS_COP_0_TLB_PG_MASK # restore pgMask
COP0_SYNC
nop
nop
j ra
mtc0 v1, MIPS_COP_0_STATUS # restore status register
COP0_SYNC
END(mips3_TBIA)
#ifndef MIPS3_5900
LEAF(mips3_FetchIcache)
lw t1, mips_L1ICacheSize
lw t2, mips_L1ICacheLSize
@ -2488,7 +2714,7 @@ LEAF(mips3_FetchDcache)
j ra
nop
END(mips3_FetchDcache)
#endif /* !MIPS3_5900 */
/*
* u_int32_t mips3_cp0_compare_read(void)
@ -2508,6 +2734,7 @@ END(mips3_cp0_compare_read)
*/
LEAF(mips3_cp0_compare_write)
mtc0 a0, MIPS_COP_0_COMPARE
COP0_SYNC
nop
nop
j ra
@ -2533,6 +2760,7 @@ END(mips3_cp0_config_read)
*/
LEAF(mips3_cp0_config_write)
mtc0 a0, MIPS_COP_0_CONFIG
COP0_SYNC
nop
nop
j ra
@ -2558,6 +2786,7 @@ END(mips3_cp0_count_read)
*/
LEAF(mips3_cp0_count_write)
mtc0 a0, MIPS_COP_0_COUNT
COP0_SYNC
nop
nop
j ra
@ -2583,6 +2812,7 @@ END(mips3_cp0_wired_read)
*/
LEAF(mips3_cp0_wired_write)
mtc0 a0, MIPS_COP_0_TLB_WIRED
COP0_SYNC
nop
nop
j ra
@ -2600,6 +2830,7 @@ LEAF(mips3_ld)
mfc0 t0, MIPS_COP_0_STATUS # turn of interrupts
and t1, t0, ~(MIPS_SR_INT_IE)
mtc0 t1, MIPS_COP_0_STATUS
COP0_SYNC
nop
nop
nop
@ -2616,6 +2847,7 @@ LEAF(mips3_ld)
#if !defined(_MIPS_BSD_API) || _MIPS_BSD_API == _MIPS_BSD_API_LP32
mtc0 t0, MIPS_COP_0_STATUS # restore intr status.
COP0_SYNC
nop
#endif
@ -2628,6 +2860,7 @@ LEAF(mips3_sd)
mfc0 t0, MIPS_COP_0_STATUS # turn of interrupts
and t1, t0, ~(MIPS_SR_INT_IE)
mtc0 t1, MIPS_COP_0_STATUS
COP0_SYNC
nop
nop
nop
@ -2649,6 +2882,7 @@ LEAF(mips3_sd)
#if !defined(_MIPS_BSD_API) || _MIPS_BSD_API == _MIPS_BSD_API_LP32
mtc0 t0, MIPS_COP_0_STATUS # restore intr status.
COP0_SYNC
nop
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: mips_machdep.c,v 1.118 2001/06/11 23:52:39 thorpej Exp $ */
/* $NetBSD: mips_machdep.c,v 1.119 2001/10/16 16:31:38 uch Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -52,7 +52,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
__KERNEL_RCSID(0, "$NetBSD: mips_machdep.c,v 1.118 2001/06/11 23:52:39 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: mips_machdep.c,v 1.119 2001/10/16 16:31:38 uch Exp $");
#include "opt_compat_netbsd.h"
#include "opt_compat_ultrix.h"
@ -84,6 +84,10 @@ __KERNEL_RCSID(0, "$NetBSD: mips_machdep.c,v 1.118 2001/06/11 23:52:39 thorpej E
#include <mips/pte.h>
#include <machine/cpu.h> /* declaration of of cpu_id */
#ifdef MIPS3_5900
#include <mips/r5900/locore.h>
#endif
/* Internal routines. */
int cpu_dumpsize __P((void));
u_long cpu_dump_mempagecnt __P((void));
@ -93,7 +97,7 @@ int cpu_dump __P((void));
static void mips1_vector_init __P((void));
#endif
#ifdef MIPS3
#if defined(MIPS3) && !defined(MIPS3_5900)
static void mips3_vector_init __P((int));
#endif
@ -174,8 +178,7 @@ mips1_vector_init()
}
#endif /* MIPS1 */
#ifdef MIPS3
#if defined(MIPS3) && !defined(MIPS3_5900)
/*
* MIPS III locore function vector
*/
@ -324,7 +327,7 @@ mips3_vector_init(mips3_csizebase)
/* Clear BEV in SR so we start handling our own exceptions */
mips_cp0_status_write(mips_cp0_status_read() & ~MIPS3_SR_DIAG_BEV);
}
#endif /* MIPS3 */
#endif /* MIPS3 && !MIPS3_5900 */
/*
@ -350,7 +353,7 @@ mips3_vector_init(mips3_csizebase)
void
mips_vector_init()
{
#ifdef MIPS3
#if defined(MIPS3) && !defined(MIPS3_5900)
int mips3_csizebase = MIPS3_CONFIG_C_DEFBASE;
#endif
@ -431,7 +434,13 @@ mips_vector_init()
mips_num_tlb_entries = MIPS3_TLB_NUM_TLB_ENTRIES;
mips3_L1TwoWayCache = 1;
break;
#ifdef MIPS3_5900
case MIPS_R5900:
cpu_arch = CPU_ARCH_MIPS3;
mips_num_tlb_entries = MIPS3_TLB_NUM_TLB_ENTRIES;
mips3_L1TwoWayCache = 1;
break;
#endif
case MIPS_R10000:
case MIPS_R12000:
case MIPS_R14000:
@ -485,6 +494,10 @@ mips_vector_init()
mips3_cp0_wired_write(0);
mips3_TBIA(mips_num_tlb_entries);
mips3_cp0_wired_write(MIPS3_TLB_WIRED_UPAGES);
#ifdef MIPS3_5900
r5900_init();
#else /* MIPS3_5900 */
if (mips3_L1TwoWayCache) {
mips3_locore_vec.flushCache = mips3_FlushCache_2way;
mips3_locore_vec.flushDCache = mips3_FlushDCache_2way;
@ -497,6 +510,7 @@ mips_vector_init()
mips3_HitFlushDCache_2way;
}
mips3_vector_init(mips3_csizebase);
#endif /* MIPS3_5900 */
memcpy(mips_locoresw, mips3_locoresw, sizeof(mips_locoresw));
/*
@ -515,7 +529,7 @@ mips_vector_init()
uvmexp.ncolors >>= 1;
} else
#endif
#endif /* MIPS3 */
{
printf("cpu_arch 0x%x: not supported\n", cpu_arch);
cpu_reboot(RB_HALT, NULL);
@ -564,6 +578,7 @@ struct pridtab cputab[] = {
{ MIPS_RM5200, "QED RM5200 CPU", },
{ MIPS_RC64470, "IDT RC64474/RC64475 CPU", },
{ MIPS_R5400, "NEC VR5400 CPU", },
{ MIPS_R5900, "Toshiba R5900 CPU", },
#if 0 /* ID collisions */
/*
* According to documents from Toshiba and QED, PRid 0x22 is
@ -731,6 +746,7 @@ cpu_identify()
* Install power-saving idle routines.
*/
switch (MIPS_PRID_IMPL(cpu_id)) {
#ifndef MIPS3_5900
#ifdef MIPS3
case MIPS_RM5200:
case MIPS_RM7000:
@ -741,6 +757,7 @@ cpu_identify()
break;
}
#endif /* MIPS3 */
#endif /* MIPS3_5900 */
default:
/* Nothing. */
break;

View File

@ -0,0 +1,236 @@
/* $NetBSD: locore_r5900.S,v 1.1 2001/10/16 16:31:39 uch Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by UCHIYAMA Yasushi.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/* Toshiba R5900 specific functions */
#include <mips/asm.h>
#include <mips/cpuregs.h>
#include <mips/r5900/cpuregs.h>
.set noreorder
.set mips3
.text
.align 6 /* align cache line size (64B) */
LEAF(r5900_FlushCache)
di
li t1, R5900_C_SIZE_I
li t2, R5900_C_SIZE_D
/*
* Flush the instruction cache.
*/
li t0, MIPS_KSEG0_START
srl t1, 1 # Two way set assoc
addu t1, t0, t1 # End address
la v0, 1f
or v0, MIPS_KSEG1_START # Run uncached.
j v0
nop
1:
sync.l
sync.p
1:
# [12:6] ... line
# [0] ... way
# line +0
cache R5900_C_IINV_I, 0(t0);sync.l;sync.p # way 0
cache R5900_C_IINV_I, 1(t0);sync.l;sync.p # way 1
# line +1
cache R5900_C_IINV_I, 64(t0);sync.l;sync.p # way 0
cache R5900_C_IINV_I, 65(t0);sync.l;sync.p # way 1
# line +2
cache R5900_C_IINV_I,128(t0);sync.l;sync.p # way 0
cache R5900_C_IINV_I,129(t0);sync.l;sync.p # way 1
# line +3
cache R5900_C_IINV_I,192(t0);sync.l;sync.p # way 0
cache R5900_C_IINV_I,193(t0);sync.l;sync.p # way 1
addu t0, t0, 256
bne t0, t1, 1b
nop
la v0, 1f # Run cached.
j v0
nop
1:
/*
* Flush the data cache.
*/
li t0, MIPS_KSEG0_START
srl t2, 1 # Two way set assoc
addu t1, t0, t2 # End address
sync.l
sync.p
1:
# line +0
cache R5900_C_IWBINV_D, 0(t0);sync.l;sync.p # way 0
cache R5900_C_IWBINV_D, 1(t0);sync.l;sync.p # way 1
# line +1
cache R5900_C_IWBINV_D, 64(t0);sync.l;sync.p # way 0
cache R5900_C_IWBINV_D, 65(t0);sync.l;sync.p # way 1
# line +2
cache R5900_C_IWBINV_D,128(t0);sync.l;sync.p # way 0
cache R5900_C_IWBINV_D,129(t0);sync.l;sync.p # way 1
# line +3
cache R5900_C_IWBINV_D,192(t0);sync.l;sync.p # way 0
cache R5900_C_IWBINV_D,193(t0);sync.l;sync.p # way 1
addu t0, t0, 256
bne t0, t1, 1b
nop
j ra
ei
END(r5900_FlushCache)
LEAF(r5900_FlushICache)
di
li t0, R5900_C_SIZE_I
li t1, MIPS_KSEG0_START
addu a1, 255 # Align (I $ inval of partials is ok)
srl t0, 1 # Two way set assoc offset
addu t2, t0, -1 # Cache index mask
and a0, a0, t2 # Only keep index bits (avoid KSEG2, way 0)
or a0, a0, t1 # Make KSEG0
srl a1, a1, 8 # Number of unrolled loops
la v0, 1f # Run uncached.
or v0, MIPS_KSEG1_START
j v0
nop
1:
sync.l
sync.p
1:
cache R5900_C_IINV_I, 0(a0);sync.l;sync.p
cache R5900_C_IINV_I, 1(a0);sync.l;sync.p
cache R5900_C_IINV_I, 64(a0);sync.l;sync.p
cache R5900_C_IINV_I, 65(a0);sync.l;sync.p
addu a1, -1
cache R5900_C_IINV_I,128(a0);sync.l;sync.p
cache R5900_C_IINV_I,129(a0);sync.l;sync.p
cache R5900_C_IINV_I,192(a0);sync.l;sync.p
cache R5900_C_IINV_I,193(a0);sync.l;sync.p
bgt a1, zero, 1b
addu a0, 256
la v0, 1f # Run cached.
j v0
nop
1:
j ra
ei
END(r5900_FlushICache)
LEAF(r5900_FlushDCache)
di
li a2, R5900_C_SIZE_D
srl a3, a2, 1 # two way set associative cache
addu a2, a3, -1 # offset mask
and a0, a0, a2 # get index into primary cache
addu a1, a1, a0 # add offset to length
and a0, a0, -256 # block align address
subu a1, a1, a0 # subtract aligned offset -> inc len by align
addu a1, 255 # tail align length
li a2, MIPS_KSEG0_START
addu a0, a0, a2 # K0(vindex)
srl a1, a1, 8 # Compute number of cache blocks
sync.l
sync.p
1:
cache R5900_C_IWBINV_D, 0(a0);sync.l;sync.p
cache R5900_C_IWBINV_D, 1(a0);sync.l;sync.p
cache R5900_C_IWBINV_D, 64(a0);sync.l;sync.p
cache R5900_C_IWBINV_D, 65(a0);sync.l;sync.p
addu a1, -1
cache R5900_C_IWBINV_D,128(a0);sync.l;sync.p
cache R5900_C_IWBINV_D,129(a0);sync.l;sync.p
cache R5900_C_IWBINV_D,192(a0);sync.l;sync.p
cache R5900_C_IWBINV_D,193(a0);sync.l;sync.p
bgtz a1, 1b
addu a0, 256
j ra
ei
END(r5900_FlushDCache)
LEAF(r5900_HitFlushDCache)
di
beq a1, zero, 2f
addu a1, 63 # Branch delay slot; align length
and a0, a0, -64
srl a1, a1, 6 # Compute number of cache lines
sync.l
sync.p
1:
addu a1, -1
cache R5900_C_HWBINV_D, 0(a0)
sync.l
sync.p
bne a1, zero, 1b
addu a0, 64
2:
j ra
ei
END(r5900_HitFlushDCache)
LEAF(r5900_InvalidateDCache)
di
addu a1, a1, a0 # compute ending address
sync.l
sync.p
1:
cache R5900_C_HINV_D,0(a0)
sync.l
sync.p
nop
addu a0, a0, 64
bltu a0, a1, 1b
nop
j ra
ei
END(r5900_InvalidateDCache)
/*
* R5900 don't have virtual coherency exceptions.
*/
LEAF_NOPROFILE(mips3_VCED)
PANIC("unknown exception")
END(mips3_VCED)
LEAF_NOPROFILE(mips3_VCEI)
PANIC("unknown exception")
END(mips3_VCEI)

View File

@ -0,0 +1,117 @@
/* $NetBSD: r5900_machdep.c,v 1.1 2001/10/16 16:31:40 uch Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by UCHIYAMA Yasushi.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/* Toshiba R5900 specific functions */
#include <sys/param.h>
#include <sys/systm.h>
#include <mips/locore.h>
#include <mips/r5900/locore.h>
#include <mips/r5900/cpuregs.h>
mips_locore_jumpvec_t mips3_locore_vec =
{
r5900_FlushCache,
r5900_FlushDCache,
r5900_FlushICache,
r5900_HitFlushDCache,
mips3_SetPID,
mips3_TBIAP,
mips3_TBIS,
mips3_TLBUpdate,
mips3_wbflush,
};
static void r5900_config_cache(void);
/*
* R5900 exception vector
*
* MMU supports 32bit-mode only. no XTLB miss handler.
* vector address is different from ordinaly MIPS3 derivative.
*/
void
r5900_init()
{
extern char mips3_exception[], mips3_exceptionEnd[];
extern char mips3_TLBMiss[], mips3_TLBMissEnd[];
size_t esz = mips3_exceptionEnd - mips3_exception;
size_t tsz = mips3_TLBMissEnd - mips3_TLBMiss;
KDASSERT(tsz <= 0x80);
memcpy((void *)R5900_TLB_REFIL_EXC_VEC, mips3_TLBMiss, tsz);
memcpy((void *)R5900_COUNTER_EXC_VEC, mips3_exception, esz);
memcpy((void *)R5900_DEBUG_EXC_VEC, mips3_exception, esz);
memcpy((void *)R5900_COMMON_EXC_VEC, mips3_exception, esz);
memcpy((void *)R5900_INTERRUPT_EXC_VEC, mips3_exception, esz);
memcpy(&mips_locore_jumpvec, &mips3_locore_vec,
sizeof(mips_locore_jumpvec_t));
r5900_config_cache();
r5900_FlushCache();
/* Clear BEV in SR so we start handling our own exceptions */
mips_cp0_status_write(mips_cp0_status_read() & ~MIPS3_SR_DIAG_BEV);
}
/*
* R5900 cache
* I-cache 16KB/64B 2-way assoc.
* D-cache 8KB/64B 2-way assoc.
* No L2-cache.
*
* and sync.p/sync.l are needed after/before cache instruction.
*
* + don't have IB, DB bit.
*/
void
r5900_config_cache()
{
mips_L1ICacheSize = R5900_C_SIZE_I;
mips_L1DCacheSize = R5900_C_SIZE_D;
mips_L1ICacheLSize = R5900_C_LSIZE_I;
mips_L1DCacheLSize = R5900_C_LSIZE_D;
mips_L2CachePresent = 0;
mips_L2CacheSize = 0;
mips_CacheAliasMask = (mips_L1DCacheSize - 1) & ~(NBPG - 1);
mips_CachePreferMask = MAX(mips_L1DCacheSize,mips_L1ICacheSize) - 1;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: trap.c,v 1.163 2001/06/02 18:09:15 chs Exp $ */
/* $NetBSD: trap.c,v 1.164 2001/10/16 16:31:38 uch Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@ -44,7 +44,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.163 2001/06/02 18:09:15 chs Exp $");
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.164 2001/10/16 16:31:38 uch Exp $");
#include "opt_cputype.h" /* which mips CPU levels do we support? */
#include "opt_ktrace.h"
@ -190,8 +190,13 @@ trap(status, cause, vaddr, opc, frame)
type |= T_USER;
if (status & ((CPUISMIPS3) ? MIPS_SR_INT_IE : MIPS1_SR_INT_ENA_PREV)) {
if (type != T_BREAK)
if (type != T_BREAK) {
#ifdef IPL_ICU_MASK
spllowersofthigh();
#else
_splset((status & MIPS_HARD_INT_MASK) | MIPS_SR_INT_IE);
#endif
}
}
switch (type) {
@ -488,8 +493,15 @@ trap(status, cause, vaddr, opc, frame)
break; /* SIGNAL */
}
case T_RES_INST+T_USER:
#if defined(MIPS3_5900) && defined(SOFTFLOAT)
MachFPInterrupt(status, cause, opc, p->p_md.md_regs);
userret(p);
return; /* GEN */
#else
sig = SIGILL;
break; /* SIGNAL */
#endif
break; /* SIGNAL */
case T_COP_UNUSABLE+T_USER:
#if defined(NOFPU) && !defined(SOFTFLOAT)
sig = SIGILL;

View File

@ -1,4 +1,4 @@
/* $NetBSD: vm_machdep.c,v 1.83 2001/09/10 21:19:18 chris Exp $ */
/* $NetBSD: vm_machdep.c,v 1.84 2001/10/16 16:31:39 uch Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@ -45,7 +45,7 @@
#include "opt_ddb.h"
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.83 2001/09/10 21:19:18 chris Exp $");
__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.84 2001/10/16 16:31:39 uch Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -147,6 +147,9 @@ cpu_fork(p1, p2, stack, stacksize, func, arg)
pcb->pcb_context[0] = (int)func; /* S0 */
pcb->pcb_context[1] = (int)arg; /* S1 */
pcb->pcb_context[11] |= PSL_LOWIPL; /* SR */
#ifdef IPL_ICU_MASK
pcb->pcb_ppl = 0; /* machine depenedend interrupt mask */
#endif
}
/*