1/*- 2 * Copyright (c) 2011 The NetBSD Foundation, Inc. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to The NetBSD Foundation 6 * by Matt Thomas of 3am Software Foundry. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30#include <sys/cdefs.h> 31#include <machine/asm.h> 32 33#include "assym.h" 34 35RCSID("$NetBSD: arcbios_calls.S,v 1.4 2020/05/30 03:16:31 tsutsui Exp $") 36 37 .text 38 .set noreorder 39 40#ifdef _LP64 41#define FIX_V0 sll v0, v0, 0 42#else 43#define FIX_V0 /* nothing */ 44#endif 45 46#define CALLFRAME2_SIZ (CALLFRAME_SIZ + 16) 47#define CALLFRAME2_RA (CALLFRAME_RA + 16) 48#define CALLFRAME2_SP (CALLFRAME_SP + 16) 49 50#ifndef _STANDALONE 51NESTED(arcbios_4orless_args, CALLFRAME_SIZ, ra) 52 PTR_SUBU sp, CALLFRAME_SIZ 53 54 REG_S ra, CALLFRAME_RA(sp) 55 REG_S s0, CALLFRAME_SP(sp) 56 57 PTR_L t9, _C_LABEL(ARCBIOS) 58 PTR_ADDU t9, t0 59 INT_L t9, 0(t9) 60 nop 61 62 jalr t9 63 move s0, MIPS_CURLWP 64 65 FIX_V0 66 67 move MIPS_CURLWP, s0 68 69 REG_L ra, CALLFRAME_RA(sp) 70 REG_L s0, CALLFRAME_SP(sp) 71 72 jr ra 73 PTR_ADDU sp, CALLFRAME_SIZ 74END(arcbios_4orless_args) 75 76NESTED(arcbios_5to8_args, CALLFRAME2_SIZ, ra) 77 PTR_SUBU sp, CALLFRAME2_SIZ 78 79 REG_S ra, CALLFRAME2_RA(sp) 80 REG_S s0, CALLFRAME2_SP(sp) 81 82#ifdef __mips_o32 83 INT_L ta0, CALLFRAME2_SIZ+16(sp) # load 5th arg 84 INT_L ta1, CALLFRAME2_SIZ+20(sp) # load 6th arg 85 INT_L ta2, CALLFRAME2_SIZ+24(sp) # load 7th arg 86 INT_L ta3, CALLFRAME2_SIZ+28(sp) # load 8th arg 87 INT_S ta0, 16(sp) # save 5th arg on stack (o32) 88 INT_S ta1, 20(sp) # save 6th arg on stack (o32) 89 INT_S ta2, 24(sp) # save 7th arg on stack (o32) 90 INT_S ta3, 28(sp) # save 8th arg on stack (o32) 91#else 92 INT_S a4, 16(sp) # save 5th arg on stack (o32) 93 INT_S a5, 20(sp) # save 6th arg on stack (o32) 94 INT_S a6, 24(sp) # save 7th arg on stack (o32) 95 INT_S a7, 28(sp) # save 8th arg on stack (o32) 96#endif 97 98 PTR_L t9, _C_LABEL(ARCBIOS) 99 PTR_ADDU t9, t0 100 INT_L t9, 0(t9) 101 nop 102 103 jalr t9 104 move s0, MIPS_CURLWP 105 106 FIX_V0 107 108 move MIPS_CURLWP, s0 109 110 REG_L ra, CALLFRAME2_RA(sp) 111 REG_L s0, CALLFRAME2_SP(sp) 112 113 jr ra 114 PTR_ADDU sp, CALLFRAME2_SIZ 115END(arcbios_5to8_args) 116#endif /* !_STANDALONE */ 117 118#define AFVDIRECT(name) \ 119 .globl __CONCAT(arcbios_,name); \ 120LEAF(__CONCAT(arcbios_,name)); \ 121 PTR_L t9, _C_LABEL(ARCBIOS); \ 122 nop; \ 123 INT_L t9, __CONCAT(AFV_,name)(t9); \ 124 nop; \ 125 jr t9; \ 126 nop; \ 127END(__CONCAT(arcbios_,name)) 128 129#ifdef _STANDALONE 130#define AFV4ORLESS(name) AFVDIRECT(name) 131#define AFV5ORMORE(name) AFVDIRECT(name) 132#else 133#define AFV4ORLESS(name) \ 134 .globl __CONCAT(arcbios_,name); \ 135NESTED(__CONCAT(arcbios_,name), 0, ra); \ 136 b arcbios_4orless_args; \ 137 li t0, __CONCAT(AFV_,name); \ 138END(__CONCAT(arcbios_,name)) 139 140#define AFV5ORMORE(name) \ 141 .globl __CONCAT(arcbios_,name); \ 142NESTED(__CONCAT(arcbios_,name), 0, ra); \ 143 b arcbios_5to8_args; \ 144 li t0, __CONCAT(AFV_,name); \ 145END(__CONCAT(arcbios_,name)) 146#endif 147 148/* 149 * ARC firmware vector 150 */ 151AFV4ORLESS(Load) /* long (*Load)(char *image, u_long top, u_long entry, u_long *low); */ 152AFV5ORMORE(Invoke) /* long (*Invoke)(u_long, u_long, u_long, char **, char **); */ 153AFV4ORLESS(Execute) /* long (*Execute)(char *, u_long, char **, char **); */ 154AFVDIRECT(Halt) /* void (*Halt)(void) __dead; */ 155AFVDIRECT(PowerDown) /* void (*PowerDown)(void) __dead; */ 156AFVDIRECT(Restart) /* void (*Restart)(void) __dead; */ 157AFVDIRECT(Reboot) /* void (*Reboot)(void) __dead; */ 158AFVDIRECT(EnterInteractiveMode) /* void (*EnterInteractiveMode)(void) __dead; */ 159#ifndef sgimips 160AFVDIRECT(ReturnFromMain) /* void (*ReturnFromMain)(void) __dead; */ 161#endif 162AFV4ORLESS(GetPeer) /* void *(*GetPeer)(void *); */ 163AFV4ORLESS(GetChild) /* void *(*GetChild)(void *); */ 164AFV4ORLESS(GetParent) /* void *(*GetParent)(void *); */ 165AFV4ORLESS(GetConfigurationData) /* long (*GetConfigurationData)(void *, void *); */ 166AFV4ORLESS(AddChild) /* void *(*AddChild)(void *, void *); */ 167AFV4ORLESS(DeleteComponent) /* long (*DeleteComponent)(void *component); */ 168AFV4ORLESS(GetComponent) /* void *(*GetComponent)(char *path); */ 169AFV4ORLESS(SaveConfiguration) /* long (*SaveConfiguration)(void); */ 170AFV4ORLESS(GetSystemId) /* void *(*GetSystemId)(void); */ 171AFV4ORLESS(GetMemoryDescriptor) /* void *(*GetMemoryDescriptor)(void *); */ 172#if !defined(sgimips) 173AFV4ORLESS(Signal) /* void (*Signal)(u_long, void *); */ 174#endif 175AFV4ORLESS(GetTime) /* void *(*GetTime)(void); */ 176AFV4ORLESS(GetRelativeTime) /* u_long (*GetRelativeTime)(void); */ 177AFV4ORLESS(GetDirectoryEntry) /* long (*GetDirectoryEntry)(u_long, void *, u_long, u_long *); */ 178AFV4ORLESS(Open) /* long (*Open)(char *, u_long, u_long *); */ 179AFV4ORLESS(Close) /* long (*Close)(u_long); */ 180AFV4ORLESS(Read) /* long (*Read)(u_long, void *, u_long, u_long *); */ 181AFV4ORLESS(GetReadStatus) /* long (*GetReadStatus)(u_long); */ 182AFV4ORLESS(Write) /* long (*Write)(u_long, void *, u_long, u_long *); */ 183AFV4ORLESS(Seek) /* long (*Seek)(u_long, int64_t *, u_long); */ 184AFV4ORLESS(Mount) /* long (*Mount)(char *, u_long); */ 185AFV4ORLESS(GetEnvironmentVariable) /* const char *(*GetEnvironmentVariable)(const char *); */ 186AFV4ORLESS(SetEnvironmentVariable) /* long (*SetEnvironmentVariable)(const char *, const char *); */ 187AFV4ORLESS(GetFileInformation) /* long (*GetFileInformation)(u_long, void *); */ 188AFV4ORLESS(SetFileInformation) /* long (*SetFileInformation)(u_long, u_long, u_long); */ 189AFV4ORLESS(FlushAllCaches) /* void (*FlushAllCaches)(void); */ 190#ifndef sgimips 191AFV4ORLESS(TestUnicode) /* paddr_t (*TestUnicode)(u_long, uint16_t); */ 192AFV4ORLESS(GetDisplayStatus) /* void *(*GetDisplayStatus)(u_long); */ 193#endif 194