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