- kernel boot flag 'd' now means "enter DDB asap" like as other ports.
- bump cpu_model[] length as the longest name occupies over 30 characters. - place machine_arch[] beside machine[] for clearity. - nuke useless #include directives. - small scale cleanup in vm_machdep.c
This commit is contained in:
parent
cf9a8a5a53
commit
78aedb2cd3
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: mips_machdep.c,v 1.28 1998/07/14 03:19:17 mhitch Exp $ */
|
||||
/* $NetBSD: mips_machdep.c,v 1.29 1998/09/02 06:41:22 nisimura 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.28 1998/07/14 03:19:17 mhitch Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: mips_machdep.c,v 1.29 1998/09/02 06:41:22 nisimura Exp $");
|
||||
|
||||
#include "opt_uvm.h"
|
||||
|
||||
|
@ -90,7 +90,6 @@ __KERNEL_RCSID(0, "$NetBSD: mips_machdep.c,v 1.28 1998/07/14 03:19:17 mhitch Exp
|
|||
#include <uvm/uvm_extern.h>
|
||||
#endif
|
||||
|
||||
#include <mips/cpu.h> /* declaration of of cpu_id */
|
||||
#include <mips/regnum.h> /* symbolic register indices */
|
||||
#include <mips/locore.h>
|
||||
#include <mips/vmparam.h> /* USRSTACK */
|
||||
|
@ -103,6 +102,9 @@ int cpu_dumpsize __P((void));
|
|||
u_long cpu_dump_mempagecnt __P((void));
|
||||
int cpu_dump __P((void));
|
||||
|
||||
void mips1_vector_init __P((void));
|
||||
void mips3_vector_init __P((void));
|
||||
|
||||
mips_locore_jumpvec_t mips_locore_jumpvec = {
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL,
|
||||
|
@ -128,22 +130,18 @@ int cpu_mhz;
|
|||
|
||||
struct user *proc0paddr;
|
||||
struct proc nullproc; /* for use by switch_exit() */
|
||||
struct proc *fpcurproc;
|
||||
struct pcb *curpcb;
|
||||
|
||||
caddr_t msgbufaddr;
|
||||
|
||||
/*
|
||||
* Forward declarations
|
||||
* XXX should be in a header file so each mips port can include it.
|
||||
* XXX will be declared in mips/include/cpu.h XXX
|
||||
*/
|
||||
extern void cpu_identify __P((void));
|
||||
extern void mips_vector_init __P((void));
|
||||
extern void savefpregs __P((struct proc *)); /* lcoore */
|
||||
|
||||
void mips1_vector_init __P((void));
|
||||
void mips3_vector_init __P((void));
|
||||
|
||||
/* the following is used externally (sysctl_hw) */
|
||||
char machine_arch[] = MACHINE_ARCH; /* cpu "architecture" */
|
||||
extern void savefpregs __P((struct proc *));
|
||||
|
||||
#ifdef MIPS1 /* r2000 family (mips-I cpu) */
|
||||
/*
|
||||
|
@ -177,15 +175,15 @@ mips1_vector_init()
|
|||
*/
|
||||
if (mips1_UTLBMissEnd - mips1_UTLBMiss > 0x80)
|
||||
panic("startup: UTLB code too large");
|
||||
bcopy(mips1_UTLBMiss, (char *)MIPS_UTLB_MISS_EXC_VEC,
|
||||
memcpy((void *)MIPS_UTLB_MISS_EXC_VEC, mips1_UTLBMiss,
|
||||
mips1_UTLBMissEnd - mips1_UTLBMiss);
|
||||
bcopy(mips1_exception, (char *)MIPS1_GEN_EXC_VEC,
|
||||
memcpy((void *)MIPS1_GEN_EXC_VEC, mips1_exception,
|
||||
mips1_exceptionEnd - mips1_exception);
|
||||
|
||||
/*
|
||||
* Copy locore-function vector.
|
||||
*/
|
||||
bcopy(&mips1_locore_vec, &mips_locore_jumpvec,
|
||||
memcpy(&mips_locore_jumpvec, &mips1_locore_vec,
|
||||
sizeof(mips_locore_jumpvec_t));
|
||||
|
||||
/*
|
||||
|
@ -242,16 +240,16 @@ mips3_vector_init()
|
|||
if (mips3_TLBMissEnd - mips3_TLBMiss > 0x80)
|
||||
panic("startup: UTLB code too large");
|
||||
#endif
|
||||
bcopy(mips3_TLBMiss, (char *)MIPS_UTLB_MISS_EXC_VEC,
|
||||
memcpy((void *)MIPS_UTLB_MISS_EXC_VEC, mips3_TLBMiss,
|
||||
mips3_TLBMissEnd - mips3_TLBMiss);
|
||||
|
||||
bcopy(mips3_exception, (char *)MIPS3_GEN_EXC_VEC,
|
||||
memcpy((void *)MIPS3_GEN_EXC_VEC, mips3_exception,
|
||||
mips3_exceptionEnd - mips3_exception);
|
||||
|
||||
/*
|
||||
* Copy locore-function vector.
|
||||
*/
|
||||
bcopy(&mips3_locore_vec, &mips_locore_jumpvec,
|
||||
memcpy(&mips_locore_jumpvec, &mips3_locore_vec,
|
||||
sizeof(mips_locore_jumpvec_t));
|
||||
|
||||
/*
|
||||
|
@ -348,7 +346,6 @@ cpu_identify()
|
|||
printf("MIPS R2000 CPU");
|
||||
break;
|
||||
case MIPS_R3000:
|
||||
|
||||
/*
|
||||
* XXX
|
||||
* R2000A silicion has an r3000 core and shows up here.
|
||||
|
@ -366,7 +363,6 @@ cpu_identify()
|
|||
case MIPS_R6000:
|
||||
printf("MIPS R6000 CPU");
|
||||
break;
|
||||
|
||||
case MIPS_R4000:
|
||||
if(mips_L1InstCacheSize == 16384)
|
||||
printf("MIPS R4400 CPU");
|
||||
|
@ -403,8 +399,6 @@ cpu_identify()
|
|||
case MIPS_R3NKK:
|
||||
printf("NKK R3000 based CPU");
|
||||
break;
|
||||
case MIPS_UNKC1:
|
||||
case MIPS_UNKC2:
|
||||
default:
|
||||
printf("Unknown CPU type (0x%x)",cpu_id.cpu.cp_imp);
|
||||
break;
|
||||
|
@ -464,7 +458,6 @@ cpu_identify()
|
|||
case MIPS_R3NKK:
|
||||
printf("NKK R3000 based FPC");
|
||||
break;
|
||||
case MIPS_UNKF1:
|
||||
default:
|
||||
printf("Unknown FPU type (0x%x)", fpu_id.cpu.cp_imp);
|
||||
break;
|
||||
|
@ -494,14 +487,14 @@ cpu_identify()
|
|||
*/
|
||||
void
|
||||
setregs(p, pack, stack)
|
||||
register struct proc *p;
|
||||
struct proc *p;
|
||||
struct exec_package *pack;
|
||||
u_long stack;
|
||||
{
|
||||
extern struct proc *fpcurproc;
|
||||
|
||||
bzero((caddr_t)p->p_md.md_regs, sizeof(struct frame));
|
||||
bzero((caddr_t)&p->p_addr->u_pcb.pcb_fpregs, sizeof(struct fpreg));
|
||||
bzero(p->p_md.md_regs, sizeof(struct frame));
|
||||
bzero(&p->p_addr->u_pcb.pcb_fpregs, sizeof(struct fpreg));
|
||||
p->p_md.md_regs[SP] = stack;
|
||||
p->p_md.md_regs[PC] = pack->ep_entry & ~3;
|
||||
p->p_md.md_regs[T9] = pack->ep_entry & ~3; /* abicall requirement */
|
||||
|
@ -554,10 +547,10 @@ sendsig(catcher, sig, mask, code)
|
|||
int sig, mask;
|
||||
u_long code;
|
||||
{
|
||||
register struct proc *p = curproc;
|
||||
register struct sigframe *fp;
|
||||
register int *regs;
|
||||
register struct sigacts *psp = p->p_sigacts;
|
||||
struct proc *p = curproc;
|
||||
struct sigframe *fp;
|
||||
int *regs;
|
||||
struct sigacts *psp = p->p_sigacts;
|
||||
int oonstack, fsize;
|
||||
struct sigcontext ksc;
|
||||
extern char sigcode[], esigcode[];
|
||||
|
@ -602,7 +595,7 @@ sendsig(catcher, sig, mask, code)
|
|||
ksc.mullo = regs[MULLO];
|
||||
ksc.mulhi = regs[MULHI];
|
||||
ksc.sc_regs[ZERO] = 0xACEDBADE; /* magic number */
|
||||
bcopy((caddr_t)®s[1], (caddr_t)&ksc.sc_regs[1],
|
||||
memcpy(&ksc.sc_regs[1], ®s[1],
|
||||
sizeof(ksc.sc_regs) - sizeof(ksc.sc_regs[0]));
|
||||
ksc.sc_fpused = p->p_md.md_flags & MDP_FPUSED;
|
||||
if (ksc.sc_fpused) {
|
||||
|
@ -613,7 +606,7 @@ sendsig(catcher, sig, mask, code)
|
|||
savefpregs(p);
|
||||
*(struct fpreg *)ksc.sc_fpregs = p->p_addr->u_pcb.pcb_fpregs;
|
||||
}
|
||||
if (copyout((caddr_t)&ksc, (caddr_t)&fp->sf_sc, sizeof(ksc))) {
|
||||
if (copyout(&ksc, &fp->sf_sc, sizeof(ksc))) {
|
||||
/*
|
||||
* Process has trashed its stack; give it an illegal
|
||||
* instruction to halt it in its tracks.
|
||||
|
@ -669,8 +662,8 @@ sys_sigreturn(p, v, retval)
|
|||
struct sys_sigreturn_args /* {
|
||||
syscallarg(struct sigcontext *) sigcntxp;
|
||||
} */ *uap = v;
|
||||
register struct sigcontext *scp;
|
||||
register int *regs;
|
||||
struct sigcontext *scp;
|
||||
int *regs;
|
||||
struct sigcontext ksc;
|
||||
int error;
|
||||
|
||||
|
@ -684,7 +677,7 @@ sys_sigreturn(p, v, retval)
|
|||
* Test and fetch the context structure.
|
||||
* We grab it all at once for speed.
|
||||
*/
|
||||
error = copyin((caddr_t)scp, (caddr_t)&ksc, sizeof(ksc));
|
||||
error = copyin(scp, &ksc, sizeof(ksc));
|
||||
if (error || ksc.sc_regs[ZERO] != 0xACEDBADE) {
|
||||
#ifdef DEBUG
|
||||
if (!(sigdebug & SDB_FOLLOW))
|
||||
|
@ -709,7 +702,7 @@ sys_sigreturn(p, v, retval)
|
|||
regs[PC] = scp->sc_pc;
|
||||
regs[MULLO] = scp->mullo;
|
||||
regs[MULHI] = scp->mulhi;
|
||||
bcopy((caddr_t)&scp->sc_regs[1], (caddr_t)®s[1],
|
||||
memcpy(®s[1], &scp->sc_regs[1],
|
||||
sizeof(scp->sc_regs) - sizeof(scp->sc_regs[0]));
|
||||
if (scp->sc_fpused)
|
||||
p->p_addr->u_pcb.pcb_fpregs = *(struct fpreg *)scp->sc_fpregs;
|
||||
|
@ -1129,7 +1122,7 @@ mips_init_proc0(space)
|
|||
nullproc.p_addr = (struct user *)(space + (UPAGES * PAGE_SIZE));
|
||||
nullproc.p_md.md_regs = nullproc.p_addr->u_pcb.pcb_regs;
|
||||
|
||||
bcopy("nullproc", nullproc.p_comm, sizeof("nullproc"));
|
||||
memcpy(nullproc.p_comm, "nullproc", sizeof("nullproc"));
|
||||
|
||||
pa = MIPS_KSEG0_TO_PHYS(nullproc.p_addr);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: vm_machdep.c,v 1.26 1998/07/28 18:34:55 thorpej Exp $ */
|
||||
/* $NetBSD: vm_machdep.c,v 1.27 1998/09/02 06:41:22 nisimura Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988 University of Utah.
|
||||
|
@ -43,7 +43,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
|
||||
__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.26 1998/07/28 18:34:55 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.27 1998/09/02 06:41:22 nisimura Exp $");
|
||||
|
||||
#include "opt_uvm.h"
|
||||
|
||||
|
@ -69,9 +69,10 @@ __KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.26 1998/07/28 18:34:55 thorpej Exp
|
|||
#include <mips/pte.h>
|
||||
#include <machine/cpu.h>
|
||||
|
||||
extern struct proc *fpcurproc; /* trap.c */
|
||||
|
||||
/* XXX will be declared in mips/include/cpu.h XXX */
|
||||
extern struct proc *fpcurproc;
|
||||
extern void savefpregs __P((struct proc *));
|
||||
extern void child_return __P((void));
|
||||
|
||||
extern vm_offset_t kvtophys __P((vm_offset_t kva)); /* XXX */
|
||||
|
||||
|
@ -84,35 +85,29 @@ cpu_fork(p1, p2)
|
|||
{
|
||||
struct pcb *pcb;
|
||||
pt_entry_t *pte;
|
||||
struct frame *tf;
|
||||
int i;
|
||||
extern void child_return __P((void)); /* trap.c */
|
||||
int i, x;
|
||||
|
||||
tf = (struct frame *)(KERNELSTACK - 24);
|
||||
p2->p_md.md_regs = p2->p_addr->u_pcb.pcb_regs;
|
||||
p2->p_md.md_flags = p1->p_md.md_flags & MDP_FPUSED;
|
||||
x = (CPUISMIPS3) ? (MIPS3_PG_G|MIPS3_PG_RO|MIPS3_PG_WIRED) : MIPS1_PG_G;
|
||||
pte = kvtopte(p2->p_addr);
|
||||
for (i = 0; i < UPAGES; i++)
|
||||
p2->p_md.md_upte[i] = pte[i].pt_entry &~ x;
|
||||
|
||||
#ifdef MIPS3
|
||||
if (CPUISMIPS3)
|
||||
mips3_HitFlushDCache((vm_offset_t)p2->p_addr, UPAGES * NBPG);
|
||||
mips3_HitFlushDCache((vm_offset_t)p2->p_addr, USPACE);
|
||||
#endif
|
||||
|
||||
/* XXX save pte mask outside loop ? */
|
||||
for (i = 0, pte = kvtopte(p2->p_addr); i < UPAGES; i++, pte++) {
|
||||
if (CPUISMIPS3)
|
||||
p2->p_md.md_upte[i] = pte->pt_entry &
|
||||
~(MIPS3_PG_G | MIPS3_PG_RO | MIPS3_PG_WIRED);
|
||||
else
|
||||
p2->p_md.md_upte[i] = pte->pt_entry &~ MIPS1_PG_G;
|
||||
}
|
||||
|
||||
pcb = &p2->p_addr->u_pcb;
|
||||
if (p1 == fpcurproc)
|
||||
savefpregs(p1);
|
||||
*pcb = p1->p_addr->u_pcb;
|
||||
|
||||
p2->p_addr->u_pcb = p1->p_addr->u_pcb;
|
||||
pcb = &p2->p_addr->u_pcb;
|
||||
pcb->pcb_segtab = (void *)p2->p_vmspace->vm_map.pmap->pm_segtab;
|
||||
pcb->pcb_context[10] = (int)proc_trampoline; /* RA */
|
||||
pcb->pcb_context[8] = (int)tf; /* SP */
|
||||
pcb->pcb_context[8] = (int)pcb + USPACE; /* SP */
|
||||
pcb->pcb_context[8] = (int)KERNELSTACK; /* SP */ /* XXX */
|
||||
pcb->pcb_context[0] = (int)child_return; /* S0 */
|
||||
pcb->pcb_context[1] = (int)p2; /* S1 */
|
||||
}
|
||||
|
@ -132,26 +127,20 @@ cpu_set_kpc(p, pc)
|
|||
*/
|
||||
void
|
||||
cpu_swapin(p)
|
||||
register struct proc *p;
|
||||
struct proc *p;
|
||||
{
|
||||
register struct user *up = p->p_addr;
|
||||
register pt_entry_t *pte;
|
||||
register int i;
|
||||
pt_entry_t *pte;
|
||||
int i, x;
|
||||
|
||||
/*
|
||||
* Cache the PTEs for the user area in the machine dependent
|
||||
* part of the proc struct so cpu_switch() can quickly map in
|
||||
* the user struct and kernel stack.
|
||||
*/
|
||||
pte = kvtopte(up);
|
||||
for (i = 0; i < UPAGES; i++) {
|
||||
if (CPUISMIPS3)
|
||||
p->p_md.md_upte[i] = pte->pt_entry &
|
||||
~(MIPS3_PG_G | MIPS3_PG_RO | MIPS3_PG_WIRED);
|
||||
else
|
||||
p->p_md.md_upte[i] = pte->pt_entry & ~MIPS1_PG_G;
|
||||
pte++;
|
||||
}
|
||||
x = (CPUISMIPS3) ? (MIPS3_PG_G|MIPS3_PG_RO|MIPS3_PG_WIRED) : MIPS1_PG_G;
|
||||
pte = kvtopte(p->p_addr);
|
||||
for (i = 0; i < UPAGES; i++)
|
||||
p->p_md.md_upte[i] = pte[i].pt_entry &~ x;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: machdep.c,v 1.119 1998/07/08 04:43:19 thorpej Exp $ */
|
||||
/* $NetBSD: machdep.c,v 1.120 1998/09/02 06:41:22 nisimura Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988 University of Utah.
|
||||
|
@ -43,7 +43,7 @@
|
|||
|
||||
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
|
||||
|
||||
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.119 1998/07/08 04:43:19 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.120 1998/09/02 06:41:22 nisimura Exp $");
|
||||
|
||||
/* from: Utah Hdr: machdep.c 1.63 91/04/24 */
|
||||
|
||||
|
@ -86,10 +86,6 @@ __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.119 1998/07/08 04:43:19 thorpej Exp $"
|
|||
|
||||
#include <ufs/mfs/mfs_extern.h> /* mfs_initminiroot() */
|
||||
|
||||
#include <dev/tc/tcvar.h>
|
||||
#include <dev/tc/ioasicreg.h> /* cycl-counter on kn03 stepping */
|
||||
#include <dev/tc/ioasicvar.h>
|
||||
|
||||
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/reg.h>
|
||||
|
@ -110,27 +106,16 @@ __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.119 1998/07/08 04:43:19 thorpej Exp $"
|
|||
|
||||
#include <pmax/stand/dec_prom.h>
|
||||
|
||||
#include <pmax/dev/ascreg.h>
|
||||
|
||||
#include <pmax/pmax/clockreg.h>
|
||||
#include <pmax/pmax/kn01.h>
|
||||
#include <pmax/pmax/kn02.h>
|
||||
#include <pmax/pmax/kmin.h>
|
||||
#include <pmax/pmax/maxine.h>
|
||||
#include <pmax/pmax/kn03.h>
|
||||
#include <pmax/pmax/turbochannel.h>
|
||||
#include <pmax/pmax/pmaxtype.h>
|
||||
#include <pmax/pmax/maxine.h>
|
||||
#include <dev/tc/tcvar.h>
|
||||
#include <dev/tc/ioasicreg.h> /* cycl-counter on kn03 stepping */
|
||||
#include <dev/tc/ioasicvar.h>
|
||||
#include <pmax/dev/promiovar.h> /* prom console I/O vector */
|
||||
|
||||
#include <pmax/pmax/machdep.h> /* splXXX() function pointer hack */
|
||||
|
||||
#include "pm.h"
|
||||
#include "cfb.h"
|
||||
#include "mfb.h"
|
||||
#include "xcfb.h"
|
||||
#include "sfb.h"
|
||||
#include "dtop.h"
|
||||
#include "scc.h"
|
||||
#include "le_ioasic.h"
|
||||
|
||||
/* Motherboard or system-specific initialization vector */
|
||||
|
@ -166,7 +151,8 @@ struct platform platform = {
|
|||
|
||||
/* the following is used externally (sysctl_hw) */
|
||||
char machine[] = MACHINE; /* from <machine/param.h> */
|
||||
char cpu_model[30];
|
||||
char machine_arch[] = MACHINE_ARCH; /* from <machine/param.h> */
|
||||
char cpu_model[40];
|
||||
|
||||
/* maps for VM objects */
|
||||
|
||||
|
@ -318,18 +304,6 @@ mach_init(argc, argv, code, cv)
|
|||
*/
|
||||
mips_vector_init();
|
||||
|
||||
#ifdef DDB
|
||||
/*
|
||||
* Initialize machine-dependent DDB commands, in case of early panic.
|
||||
*/
|
||||
db_machine_init();
|
||||
/* init symbols if present */
|
||||
if (esym)
|
||||
ddb_init(*(int *)&end, ((int *)&end) + 1, (int*)esym);
|
||||
if (boothowto & RB_KDB)
|
||||
Debugger();
|
||||
#endif
|
||||
|
||||
/* look at argv[0] and compute bootdev */
|
||||
makebootdev(argv[0]);
|
||||
|
||||
|
@ -340,7 +314,6 @@ mach_init(argc, argv, code, cv)
|
|||
#ifdef KADB
|
||||
boothowto |= RB_KDB;
|
||||
#endif
|
||||
if (argc > 1) {
|
||||
for (i = 1; i < argc; i++) {
|
||||
for (cp = argv[i]; *cp; cp++) {
|
||||
switch (*cp) {
|
||||
|
@ -348,8 +321,8 @@ mach_init(argc, argv, code, cv)
|
|||
boothowto &= ~RB_SINGLE;
|
||||
break;
|
||||
|
||||
case 'd': /* use compiled in default root */
|
||||
boothowto |= RB_DFLTROOT;
|
||||
case 'd': /* break into the kernel debugger ASAP */
|
||||
boothowto |= RB_KDB;
|
||||
break;
|
||||
|
||||
case 'm': /* mini root present in memory */
|
||||
|
@ -365,7 +338,6 @@ mach_init(argc, argv, code, cv)
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MFS
|
||||
/*
|
||||
|
@ -378,6 +350,18 @@ mach_init(argc, argv, code, cv)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef DDB
|
||||
/*
|
||||
* Initialize machine-dependent DDB commands, in case of early panic.
|
||||
*/
|
||||
db_machine_init();
|
||||
/* init symbols if present */
|
||||
if (esym)
|
||||
ddb_init(*(int *)&end, ((int *)&end) + 1, (int*)esym);
|
||||
if (boothowto & RB_KDB)
|
||||
Debugger();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Init mapping for u page(s) for proc0, pm_tlbpid 1.
|
||||
* This also initializes nullproc for switch_exit().
|
||||
|
|
Loading…
Reference in New Issue