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