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