Home | History | Annotate | Line # | Download | only in sh3
      1 /*	$NetBSD: sh3_machdep.c,v 1.114 2025/03/16 15:34:59 riastradh Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 1996, 1997, 1998, 2002 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace
      9  * Simulation Facility, NASA Ames Research Center.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions and the following disclaimer.
     16  * 2. Redistributions in binary form must reproduce the above copyright
     17  *    notice, this list of conditions and the following disclaimer in the
     18  *    documentation and/or other materials provided with the distribution.
     19  *
     20  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     30  * POSSIBILITY OF SUCH DAMAGE.
     31  */
     32 
     33 /*-
     34  * Copyright (c) 1982, 1987, 1990 The Regents of the University of California.
     35  * All rights reserved.
     36  *
     37  * This code is derived from software contributed to Berkeley by
     38  * William Jolitz.
     39  *
     40  * Redistribution and use in source and binary forms, with or without
     41  * modification, are permitted provided that the following conditions
     42  * are met:
     43  * 1. Redistributions of source code must retain the above copyright
     44  *    notice, this list of conditions and the following disclaimer.
     45  * 2. Redistributions in binary form must reproduce the above copyright
     46  *    notice, this list of conditions and the following disclaimer in the
     47  *    documentation and/or other materials provided with the distribution.
     48  * 3. Neither the name of the University nor the names of its contributors
     49  *    may be used to endorse or promote products derived from this software
     50  *    without specific prior written permission.
     51  *
     52  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     53  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     54  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     55  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     56  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     57  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     58  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     59  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     60  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     61  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     62  * SUCH DAMAGE.
     63  *
     64  *	@(#)machdep.c	7.4 (Berkeley) 6/3/91
     65  */
     66 
     67 #include <sys/cdefs.h>
     68 __KERNEL_RCSID(0, "$NetBSD: sh3_machdep.c,v 1.114 2025/03/16 15:34:59 riastradh Exp $");
     69 
     70 #include "opt_ddb.h"
     71 #include "opt_kgdb.h"
     72 #include "opt_memsize.h"
     73 #include "opt_kstack_debug.h"
     74 #include "opt_ptrace.h"
     75 
     76 #include <sys/param.h>
     77 #include <sys/systm.h>
     78 
     79 #include <sys/buf.h>
     80 #include <sys/exec.h>
     81 #include <sys/kernel.h>
     82 #include <sys/mount.h>
     83 #include <sys/proc.h>
     84 #include <sys/signalvar.h>
     85 #include <sys/ras.h>
     86 #include <sys/syscallargs.h>
     87 #include <sys/ucontext.h>
     88 #include <sys/cpu.h>
     89 #include <sys/bus.h>
     90 
     91 #ifdef KGDB
     92 #include <sys/kgdb.h>
     93 #ifndef KGDB_DEVNAME
     94 #define	KGDB_DEVNAME "nodev"
     95 #endif
     96 const char kgdb_devname[] = KGDB_DEVNAME;
     97 #endif /* KGDB */
     98 
     99 #include <uvm/uvm.h>
    100 
    101 #include <sh3/cache.h>
    102 #include <sh3/clock.h>
    103 #include <sh3/exception.h>
    104 #include <sh3/locore.h>
    105 #include <sh3/mmu.h>
    106 #include <sh3/pcb.h>
    107 #include <sh3/intr.h>
    108 #include <sh3/ubcreg.h>
    109 
    110 /* Our exported CPU info; we can have only one. */
    111 struct cpu_info cpu_info_store;
    112 int cpu_arch;
    113 int cpu_product;
    114 
    115 struct vm_map *phys_map;
    116 
    117 struct pcb *curpcb;
    118 
    119 #if !defined(IOM_RAM_BEGIN)
    120 #error "define IOM_RAM_BEGIN"
    121 #elif (IOM_RAM_BEGIN & SH3_P1SEG_BASE) != 0
    122 #error "IOM_RAM_BEGIN is physical address. not P1 address."
    123 #endif
    124 
    125 #define	VBR	(uint8_t *)SH3_PHYS_TO_P1SEG(IOM_RAM_BEGIN)
    126 vaddr_t ram_start = SH3_PHYS_TO_P1SEG(IOM_RAM_BEGIN);
    127 /* exception handler holder (sh3/sh3/exception_vector.S) */
    128 extern char sh_vector_generic[], sh_vector_generic_end[];
    129 extern char sh_vector_interrupt[], sh_vector_interrupt_end[];
    130 #ifdef SH3
    131 extern char sh3_vector_tlbmiss[], sh3_vector_tlbmiss_end[];
    132 #endif
    133 #ifdef SH4
    134 extern char sh4_vector_tlbmiss[], sh4_vector_tlbmiss_end[];
    135 #endif
    136 /*
    137  * These variables are needed by /sbin/savecore
    138  */
    139 uint32_t dumpmag = 0x8fca0101;	/* magic number */
    140 int dumpsize;			/* pages */
    141 long dumplo;	 		/* blocks */
    142 
    143 
    144 void
    145 sh_cpu_init(int arch, int product)
    146 {
    147 	/* CPU type */
    148 	cpu_arch = arch;
    149 	cpu_product = product;
    150 
    151 #if defined(SH3) && defined(SH4)
    152 	/* Set register addresses */
    153 	sh_devreg_init();
    154 #endif
    155 	/* Cache access ops. */
    156 	sh_cache_init();
    157 
    158 	/* MMU access ops. */
    159 	sh_mmu_init();
    160 
    161 	/* Hardclock, RTC initialize. */
    162 	machine_clock_init();
    163 
    164 	/* ICU initialize. */
    165 	curcpu()->ci_idepth = -1;
    166 	intc_init();
    167 
    168 	/* Exception vector. */
    169 	memcpy(VBR + 0x100, sh_vector_generic,
    170 	    sh_vector_generic_end - sh_vector_generic);
    171 #ifdef SH3
    172 	if (CPU_IS_SH3)
    173 		memcpy(VBR + 0x400, sh3_vector_tlbmiss,
    174 		    sh3_vector_tlbmiss_end - sh3_vector_tlbmiss);
    175 #endif
    176 #ifdef SH4
    177 	if (CPU_IS_SH4)
    178 		memcpy(VBR + 0x400, sh4_vector_tlbmiss,
    179 		    sh4_vector_tlbmiss_end - sh4_vector_tlbmiss);
    180 #endif
    181 	memcpy(VBR + 0x600, sh_vector_interrupt,
    182 	    sh_vector_interrupt_end - sh_vector_interrupt);
    183 
    184 	if (!SH_HAS_UNIFIED_CACHE)
    185 		sh_icache_sync_all();
    186 
    187 	__asm volatile("ldc %0, vbr" :: "r"(VBR));
    188 
    189 	/* kernel stack setup */
    190 	__sh_switch_resume = CPU_IS_SH3 ? sh3_switch_resume : sh4_switch_resume;
    191 
    192 	uvm_md_init();
    193 	/* setup UBC channel A for single-stepping */
    194 #if defined(PTRACE_HOOKS) || defined(DDB)
    195 	_reg_write_2(SH_(BBRA), 0); /* disable channel A */
    196 	_reg_write_2(SH_(BBRB), 0); /* disable channel B */
    197 
    198 #ifdef SH3
    199 	if (CPU_IS_SH3) {
    200 		/* A: break after execution, ignore ASID */
    201 		_reg_write_4(SH3_BRCR, (UBC_CTL_A_AFTER_INSN
    202 					| SH3_UBC_CTL_A_MASK_ASID));
    203 
    204 		/* A: compare all address bits */
    205 		_reg_write_4(SH3_BAMRA, 0x00000000);
    206 	}
    207 #endif	/* SH3 */
    208 
    209 #ifdef SH4
    210 	if (CPU_IS_SH4) {
    211 		/* A: break after execution */
    212 		_reg_write_2(SH4_BRCR, UBC_CTL_A_AFTER_INSN);
    213 
    214 		/* A: compare all address bits, ignore ASID */
    215 		_reg_write_1(SH4_BAMRA, SH4_UBC_MASK_NONE | SH4_UBC_MASK_ASID);
    216 	}
    217 #endif	/* SH4 */
    218 #endif
    219 }
    220 
    221 
    222 /*
    223  * void sh_proc0_init(void):
    224  *	Setup proc0 u-area.
    225  */
    226 void
    227 sh_proc0_init(void)
    228 {
    229 	struct switchframe *sf;
    230 	vaddr_t u;
    231 
    232 	/* Steal process0 u-area */
    233 	u = uvm_pageboot_alloc(USPACE);
    234 	memset((void *)u, 0, USPACE);
    235 
    236 	/* Setup uarea for lwp0 */
    237 	uvm_lwp_setuarea(&lwp0, u);
    238 
    239 	/*
    240 	 * u-area map:
    241 	 * |pcb| .... | .................. |
    242 	 * | PAGE_SIZE | USPACE - PAGE_SIZE |
    243          *        frame bot        stack bot
    244 	 * current frame ... r6_bank
    245 	 * stack bottom  ... r7_bank
    246 	 * current stack ... r15
    247 	 */
    248 	curpcb = lwp_getpcb(&lwp0);
    249 	lwp0.l_md.md_pcb = curpcb;
    250 
    251 	sf = &curpcb->pcb_sf;
    252 
    253 #ifdef KSTACK_DEBUG
    254 	memset((char *)(u + sizeof(struct pcb)), 0x5a,
    255 	    PAGE_SIZE - sizeof(struct pcb));
    256 	memset((char *)(u + PAGE_SIZE), 0xa5, USPACE - PAGE_SIZE);
    257 	memset(sf, 0xb4, sizeof(struct switchframe));
    258 #endif /* KSTACK_DEBUG */
    259 
    260 	sf->sf_r6_bank = u + PAGE_SIZE;
    261 	sf->sf_r7_bank = sf->sf_r15 = u + USPACE;
    262 	__asm volatile("ldc %0, r6_bank" :: "r"(sf->sf_r6_bank));
    263 	__asm volatile("ldc %0, r7_bank" :: "r"(sf->sf_r7_bank));
    264 
    265 	lwp0.l_md.md_regs = (struct trapframe *)sf->sf_r6_bank - 1;
    266 }
    267 
    268 void
    269 sh_startup(void)
    270 {
    271 	vaddr_t minaddr, maxaddr;
    272 	char pbuf[9];
    273 	const char *model = cpu_getmodel();
    274 
    275 	printf("%s%s", copyright, version);
    276 	if (*model != '\0')
    277 		printf("%s\n", model);
    278 #ifdef DEBUG
    279 	printf("general exception handler:\t%d byte\n",
    280 	    sh_vector_generic_end - sh_vector_generic);
    281 	printf("TLB miss exception handler:\t%d byte\n",
    282 #if defined(SH3) && defined(SH4)
    283 	    CPU_IS_SH3 ? sh3_vector_tlbmiss_end - sh3_vector_tlbmiss :
    284 	    sh4_vector_tlbmiss_end - sh4_vector_tlbmiss
    285 #elif defined(SH3)
    286 	    sh3_vector_tlbmiss_end - sh3_vector_tlbmiss
    287 #elif defined(SH4)
    288 	    sh4_vector_tlbmiss_end - sh4_vector_tlbmiss
    289 #endif
    290 	    );
    291 	printf("interrupt exception handler:\t%d byte\n",
    292 	    sh_vector_interrupt_end - sh_vector_interrupt);
    293 #endif /* DEBUG */
    294 
    295 	format_bytes(pbuf, sizeof(pbuf), ctob(physmem));
    296 	printf("total memory = %s\n", pbuf);
    297 
    298 	minaddr = 0;
    299 
    300 	/*
    301 	 * Allocate a submap for physio
    302 	 */
    303 	phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
    304 	    VM_PHYS_SIZE, 0, false, NULL);
    305 
    306 	format_bytes(pbuf, sizeof(pbuf), ptoa(uvm_availmem(false)));
    307 	printf("avail memory = %s\n", pbuf);
    308 }
    309 
    310 /*
    311  * This is called by main to set dumplo and dumpsize.
    312  * Dumps always skip the first CLBYTES of disk space
    313  * in case there might be a disk label stored there.
    314  * If there is extra space, put dump at the end to
    315  * reduce the chance that swapping trashes it.
    316  */
    317 void
    318 cpu_dumpconf(void)
    319 {
    320 }
    321 
    322 void
    323 dumpsys(void)
    324 {
    325 }
    326 
    327 /*
    328  * Get the base address of the signal frame either on the lwp's stack
    329  * or on the signal stack and set *onstack accordingly.  Caller then
    330  * just subtracts the size of appropriate struct sigframe_foo.
    331  */
    332 void *
    333 getframe(const struct lwp *l, int sig, int *onstack)
    334 {
    335 	const struct proc *p = l->l_proc;
    336 	const stack_t *sigstk = &l->l_sigstk;
    337 
    338 	/* Do we need to jump onto the signal stack? */
    339 	*onstack = (sigstk->ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0
    340 		&& (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0;
    341 
    342 	if (*onstack)
    343 		return ((char *)sigstk->ss_sp + sigstk->ss_size);
    344 	else
    345 		return ((void *)l->l_md.md_regs->tf_r15);
    346 }
    347 
    348 void
    349 sendsig_siginfo(const ksiginfo_t *ksi, const sigset_t *mask)
    350 {
    351 	struct lwp *l = curlwp;
    352 	struct proc *p = l->l_proc;
    353 	struct sigacts *ps = p->p_sigacts;
    354 	struct trapframe *tf = l->l_md.md_regs;
    355 	int sig = ksi->ksi_signo, error;
    356 	sig_t catcher = SIGACTION(p, sig).sa_handler;
    357 	struct sigframe_siginfo *fp, frame;
    358 	int onstack;
    359 
    360 	fp = getframe(l, sig, &onstack);
    361 	--fp;
    362 
    363 	memset(&frame, 0, sizeof(frame));
    364 	frame.sf_si._info = ksi->ksi_info;
    365 	frame.sf_uc.uc_link = l->l_ctxlink;
    366 	frame.sf_uc.uc_sigmask = *mask;
    367 	frame.sf_uc.uc_flags = _UC_SIGMASK;
    368 	frame.sf_uc.uc_flags |= (l->l_sigstk.ss_flags & SS_ONSTACK)
    369 		? _UC_SETSTACK : _UC_CLRSTACK;
    370 	sendsig_reset(l, sig);
    371 	mutex_exit(p->p_lock);
    372 	cpu_getmcontext(l, &frame.sf_uc.uc_mcontext, &frame.sf_uc.uc_flags);
    373 	error = copyout(&frame, fp, sizeof(frame));
    374 	mutex_enter(p->p_lock);
    375 
    376 	if (error != 0) {
    377 		/*
    378 		 * Process has trashed its stack; give it an illegal
    379 		 * instruction to halt it in its tracks.
    380 		 */
    381 		sigexit(l, SIGILL);
    382 		/* NOTREACHED */
    383 	}
    384 
    385 	tf->tf_r4 = sig;		/* "signum" argument for handler */
    386 	tf->tf_r5 = (int)&fp->sf_si;	/* "sip" argument for handler */
    387 	tf->tf_r6 = (int)&fp->sf_uc;	/* "ucp" argument for handler */
    388  	tf->tf_spc = (int)catcher;
    389 	tf->tf_r15 = (int)fp;
    390 	tf->tf_pr = (int)ps->sa_sigdesc[sig].sd_tramp;
    391 
    392 	/* Remember if we're now on the signal stack. */
    393 	if (onstack)
    394 		l->l_sigstk.ss_flags |= SS_ONSTACK;
    395 }
    396 
    397 void
    398 cpu_getmcontext(struct lwp *l, mcontext_t *mcp, unsigned int *flags)
    399 {
    400 	const struct trapframe *tf = l->l_md.md_regs;
    401 	__greg_t *gr = mcp->__gregs;
    402 	__greg_t ras_pc;
    403 
    404 	/* Save register context. */
    405 	gr[_REG_GBR]    = tf->tf_gbr;
    406 	gr[_REG_PC]     = tf->tf_spc;
    407 	gr[_REG_SR]     = tf->tf_ssr;
    408 	gr[_REG_MACL]   = tf->tf_macl;
    409 	gr[_REG_MACH]   = tf->tf_mach;
    410 	gr[_REG_PR]     = tf->tf_pr;
    411 	gr[_REG_R14]    = tf->tf_r14;
    412 	gr[_REG_R13]    = tf->tf_r13;
    413 	gr[_REG_R12]    = tf->tf_r12;
    414 	gr[_REG_R11]    = tf->tf_r11;
    415 	gr[_REG_R10]    = tf->tf_r10;
    416 	gr[_REG_R9]     = tf->tf_r9;
    417 	gr[_REG_R8]     = tf->tf_r8;
    418 	gr[_REG_R7]     = tf->tf_r7;
    419 	gr[_REG_R6]     = tf->tf_r6;
    420 	gr[_REG_R5]     = tf->tf_r5;
    421 	gr[_REG_R4]     = tf->tf_r4;
    422 	gr[_REG_R3]     = tf->tf_r3;
    423 	gr[_REG_R2]     = tf->tf_r2;
    424 	gr[_REG_R1]     = tf->tf_r1;
    425 	gr[_REG_R0]     = tf->tf_r0;
    426 	gr[_REG_R15]    = tf->tf_r15;
    427 
    428 	if ((ras_pc = (__greg_t)ras_lookup(l->l_proc,
    429 	    (void *) gr[_REG_PC])) != -1)
    430 		gr[_REG_PC] = ras_pc;
    431 
    432 	*flags |= (_UC_CPU|_UC_TLSBASE);
    433 
    434 	/* FPU context is currently not handled by the kernel. */
    435 	memset(&mcp->__fpregs, 0, sizeof (mcp->__fpregs));
    436 }
    437 
    438 int
    439 cpu_mcontext_validate(struct lwp *l, const mcontext_t *mcp)
    440 {
    441 	struct trapframe *tf = l->l_md.md_regs;
    442 	const __greg_t *gr = mcp->__gregs;
    443 
    444 	if (((tf->tf_ssr ^ gr[_REG_SR]) & PSL_USERSTATIC) != 0)
    445 		return EINVAL;
    446 
    447 	return 0;
    448 }
    449 
    450 int
    451 cpu_setmcontext(struct lwp *l, const mcontext_t *mcp, unsigned int flags)
    452 {
    453 	struct trapframe *tf = l->l_md.md_regs;
    454 	const __greg_t *gr = mcp->__gregs;
    455 	struct proc *p = l->l_proc;
    456 	int error;
    457 
    458 	/* Restore register context, if any. */
    459 	if ((flags & _UC_CPU) != 0) {
    460 		/* Check for security violations. */
    461 		error = cpu_mcontext_validate(l, mcp);
    462 		if (error)
    463 			return error;
    464 
    465 		/* done in lwp_setprivate */
    466 		/* tf->tf_gbr    = gr[_REG_GBR];  */
    467 		tf->tf_spc    = gr[_REG_PC];
    468 		tf->tf_ssr    = gr[_REG_SR];
    469 		tf->tf_macl   = gr[_REG_MACL];
    470 		tf->tf_mach   = gr[_REG_MACH];
    471 		tf->tf_pr     = gr[_REG_PR];
    472 		tf->tf_r14    = gr[_REG_R14];
    473 		tf->tf_r13    = gr[_REG_R13];
    474 		tf->tf_r12    = gr[_REG_R12];
    475 		tf->tf_r11    = gr[_REG_R11];
    476 		tf->tf_r10    = gr[_REG_R10];
    477 		tf->tf_r9     = gr[_REG_R9];
    478 		tf->tf_r8     = gr[_REG_R8];
    479 		tf->tf_r7     = gr[_REG_R7];
    480 		tf->tf_r6     = gr[_REG_R6];
    481 		tf->tf_r5     = gr[_REG_R5];
    482 		tf->tf_r4     = gr[_REG_R4];
    483 		tf->tf_r3     = gr[_REG_R3];
    484 		tf->tf_r2     = gr[_REG_R2];
    485 		tf->tf_r1     = gr[_REG_R1];
    486 		tf->tf_r0     = gr[_REG_R0];
    487 		tf->tf_r15    = gr[_REG_R15];
    488 
    489 		if (flags & _UC_TLSBASE)
    490 			lwp_setprivate(l, (void *)(uintptr_t)gr[_REG_GBR]);
    491 	}
    492 
    493 #if 0
    494 	/* XXX: FPU context is currently not handled by the kernel. */
    495 	if (flags & _UC_FPU) {
    496 		/* TODO */;
    497 	}
    498 #endif
    499 
    500 	mutex_enter(p->p_lock);
    501 	if (flags & _UC_SETSTACK)
    502 		l->l_sigstk.ss_flags |= SS_ONSTACK;
    503 	if (flags & _UC_CLRSTACK)
    504 		l->l_sigstk.ss_flags &= ~SS_ONSTACK;
    505 	mutex_exit(p->p_lock);
    506 
    507 	return (0);
    508 }
    509 
    510 /*
    511  * Clear registers on exec
    512  */
    513 void
    514 setregs(struct lwp *l, struct exec_package *pack, vaddr_t stack)
    515 {
    516 	struct trapframe *tf;
    517 
    518 	l->l_md.md_flags &= ~(MDL_USEDFPU | MDL_SSTEP);
    519 
    520 	tf = l->l_md.md_regs;
    521 	memset(tf, 0, sizeof(*tf));
    522 
    523 	tf->tf_ssr = PSL_USERSET;
    524 	tf->tf_spc = pack->ep_entry;
    525 	tf->tf_pr = 0;
    526 
    527 	tf->tf_gbr = 0;
    528 	tf->tf_macl = 0;
    529 	tf->tf_mach = 0;
    530 
    531 	tf->tf_r0 = 0;
    532 	tf->tf_r1 = 0;
    533 	tf->tf_r2 = 0;
    534 	tf->tf_r3 = 0;
    535 	if (ufetch_int((void *)stack, (u_int *)&tf->tf_r4) != 0) /* argc */
    536 		tf->tf_r4 = -1;
    537 	tf->tf_r5 = stack + 4;			/* argv */
    538 	tf->tf_r6 = stack + 4 * tf->tf_r4 + 8;	/* envp */
    539 	tf->tf_r7 = 0;
    540 	tf->tf_r8 = 0;
    541 	tf->tf_r9 = l->l_proc->p_psstrp;
    542 	tf->tf_r10 = 0;
    543 	tf->tf_r11 = 0;
    544 	tf->tf_r12 = 0;
    545 	tf->tf_r13 = 0;
    546 	tf->tf_r14 = 0;
    547 	tf->tf_r15 = stack;
    548 }
    549 
    550 /*
    551  * Jump to reset vector.
    552  */
    553 void
    554 cpu_reset(void)
    555 {
    556 
    557 	_cpu_exception_suspend();
    558 	_reg_write_4(SH_(EXPEVT), EXPEVT_RESET_MANUAL);
    559 
    560 #ifndef __lint__
    561 	goto *(void *)0xa0000000;
    562 #endif
    563 	/* NOTREACHED */
    564 }
    565 
    566 int
    567 cpu_lwp_setprivate(lwp_t *l, void *addr)
    568 {
    569 
    570 	l->l_md.md_regs->tf_gbr = (int)addr;
    571 	return 0;
    572 }
    573 
    574