xref: /netbsd-src/sys/arch/mips/pmon/pmon32.S (revision 7788a0781fe6ff2cce37368b4578a7ade0850cb1)
1/*	$NetBSD: pmon32.S,v 1.1 2011/08/27 13:34:29 bouyer Exp $ */
2/*	OpenBSD: pmon32.S,v 1.4 2010/02/18 18:53:33 miod Exp 	*/
3
4/*
5 * Copyright (c) 2009 Miodrag Vallat.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20/*
21 * Wrapper routines to invoke PMON2000 functions from 64-bit code.
22 *
23 * PMON is compiled as 64 bit code, using the gcc o64 ABI (similar to the o32
24 * ABI, but using 64 bit registers).
25 *
26 * As a result, only up to four arguments to functions will be passed through
27 * registers.  It's up to the caller to never invoke pmon_printf() with more
28 * than four arguments; other functions are not affected.
29 */
30
31#include <machine/param.h>
32#include <machine/asm.h>
33
34#ifndef _STANDALONE
35#include "assym.h"
36#endif
37
38	.set	mips3
39
40	.data
41	.globl	pmon_callvec
42pmon_callvec:
43	.word	0
44
45	.text
46#define PMON_CALLFRAME_SIZ (CALLFRAME_SIZ)
47/*
48 * Note that we need to provide a PMON_CALLFRAME_SIZ untouched area above sp,
49 * or we'll risk our stack being corrupted upon return.
50 */
51
52#define FRAMESZ(sz)     (((sz) + ALSK) & ~ALSK)
53
54#define	PMON_WRAP(name, index) \
55	NNON_LEAF(name, FRAMESZ(PMON_CALLFRAME_SIZ + 11 * SZREG),  ra); \
56	PTR_SUBU sp, sp, FRAMESZ(PMON_CALLFRAME_SIZ + 11 * SZREG); \
57	REG_S	ra, (10 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
58	.mask	0xc0ff0000, (CALLFRAME_RA - FRAMESZ(PMON_CALLFRAME_SIZ + 10 * SZREG)); \
59	REG_S	s0, (0 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
60	REG_S	s1, (1 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
61	REG_S	s2, (2 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
62	REG_S	s3, (3 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
63	REG_S	s4, (4 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
64	REG_S	s5, (5 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
65	REG_S	s6, (6 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
66	REG_S	s7, (7 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
67	REG_S	s8, (8 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
68	REG_S	t8, (9 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
69	lw	t0, pmon_callvec; \
70	lw	t0, (index) * 4 (t0); \
71	jalr	t0; \
72	nop; \
73	REG_L	t8, (9 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
74	REG_L	s8, (8 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
75	REG_L	s7, (7 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
76	REG_L	s6, (6 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
77	REG_L	s5, (5 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
78	REG_L	s4, (4 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
79	REG_L	s3, (3 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
80	REG_L	s2, (2 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
81	REG_L	s1, (1 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
82	REG_L	s0, (0 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
83	REG_L	ra, (10 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
84	PTR_ADDU sp, sp, FRAMESZ(PMON_CALLFRAME_SIZ + 11 * SZREG); \
85	jr	ra; \
86	nop; \
87	END(name)
88
89PMON_WRAP(pmon_printf, 5)
90PMON_WRAP(pmon_gets, 7)
91#ifdef _STANDALONE
92PMON_WRAP(pmon_open, 0)
93PMON_WRAP(pmon_close, 1)
94PMON_WRAP(pmon_read, 2)
95PMON_WRAP(pmon_lseek, 4)
96PMON_WRAP(pmon_cacheflush, 6)
97#endif
98#if 0	/* unused */
99PMON_WRAP(pmon_write, 3)
100#endif
101