OpenCores
URL https://opencores.org/ocsvn/openarty/openarty/trunk

Subversion Repositories openarty

[/] [openarty/] [trunk/] [sw/] [board/] [syscall.h] - Blame information for rev 52

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 52 dgisselq
////////////////////////////////////////////////////////////////////////////////
2
//
3
// Filename:    syscall.h
4
//
5
// Project:     OpenArty, an entirely open SoC based upon the Arty platform
6
//
7
// Purpose:     User programs often need O/S support.  To get such support, they
8
//              call O/S functions, often named "system calls".  These functions
9
//      run at a different privilege level, and often even within a different
10
//      address space.  Therefore, making a system call usually takes a touch
11
//      of hardware support.  From a hardware standpoint, asking to switch to
12
//      a higher privilege level is called a "TRAP".
13
//
14
//      For the ZipCPU, a system call is as simple as executing the "TRAP"
15
//      instruction--one that just clears the GIE bit in the CC register.  This
16
//      can be as simple as "MOV 0,CC", or even "AND ~GIE,CC".  Of course, this
17
//      only works from user mode where the GIE bit is set in the first place.
18
//      This then transitions the CPU from user to supervisor mode, in a fashion
19
//      where the supervisor can now examine the user process and tell that it
20
//      was a trap that caused the return to supervisor mode.  To turn this
21
//      concept into a system call with arguments set and a potential value
22
//      returned, we place up to four arguments into registers R1-R4, and
23
//      expect R1 to have any return value.
24
//
25
//      Getting the compiler to do this (place four values into R1-R4 and issue
26
//      a trap instruction), however, was a nightmare.  So, instead, call a
27
//      function that accepts the same number of arguments (forcing GCC to
28
//      place them into the registers R1-R4), and we set that function up so
29
//      that it just does the system call assembly command listed above,
30
//      followed by a "JMP R0" to return from the system call.  This function,
31
//      because it is so tightly integrated with the compiler and system, is
32
//      implemented within zipsys as the assembly language routine, system().
33
//
34
//      Here, we just specify what system calls the kernel knows about, what
35
//      their calling conventions are, etc.  In particular, we use R1 (i.e. the
36
//      first argument) to reference a system call number (a.k.a. trap ID),
37
//      and the next three arguments can be understood in the context of the
38
//      system call number.
39
//
40
// Creator:     Dan Gisselquist, Ph.D.
41
//              Gisselquist Technology, LLC
42
//
43
////////////////////////////////////////////////////////////////////////////////
44
//
45
// Copyright (C) 2015-2016, Gisselquist Technology, LLC
46
//
47
// This program is free software (firmware): you can redistribute it and/or
48
// modify it under the terms of  the GNU General Public License as published
49
// by the Free Software Foundation, either version 3 of the License, or (at
50
// your option) any later version.
51
//
52
// This program is distributed in the hope that it will be useful, but WITHOUT
53
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
54
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
55
// for more details.
56
//
57
// You should have received a copy of the GNU General Public License along
58
// with this program.  (It's in the $(ROOT)/doc directory, run make with no
59
// target there if the PDF file isn't present.)  If not, see
60
// <http://www.gnu.org/licenses/> for a copy.
61
//
62
// License:     GPL, v3, as defined and found on www.gnu.org,
63
//              http://www.gnu.org/licenses/gpl.html
64
//
65
//
66
////////////////////////////////////////////////////////////////////////////////
67
//
68
//
69
#ifndef SYSCALL_H
70
#define SYSCALL_H
71
 
72
typedef enum {
73
        // First two deal with interrupts:
74
        //      syscall(TRAPID_WAIT, intmask, timeout, ?)
75
        //              returns when an interrupt in intmask has taken place.
76
        //              May return immediately if such an interrupt has
77
        //              occurred between the last such syscall and this one
78
        //              If timeout is != 0, specifies the maximum amount of
79
        //                      time to wait for the event to occurr.
80
        //              If intmask = 0, then the task will wait for a timeout
81
        //                      alone.
82
        //              If the task is stalled for another reason, it may wake
83
        //                      early from the trap when the timeout is up.
84
        //      syscall(TRAPID_CLEAR, intmask, timeout, ?)
85
        //              Same thing, except this returns immediately after
86
        //              clearing any potentially pending interrupts
87
        //              If the timeout < 0, clears any pending timeout wakeup
88
        //              If the timeout > 0, sets a pending timeout wakeup and
89
        //                      returns.
90
        //              If the timeout == 0, it does nothing with the timeout.
91
        //      syscall(TRAPID_POST, intmask, ?, ?)
92
        //              "Posts" the events in intmask, allowing software
93
        //              "interrupts" to be created.  That is, if another
94
        //              piece of software is waiting on an event/interrupt,
95
        //              this can be used to wake up all such pieces of software.
96
        //
97
        TRAPID_WAIT, TRAPID_CLEAR, TRAPID_POST,
98
        //
99
        // Yield: Yields the processor until the next scheduled time slice.
100
        //      Takes no arguments.
101
        TRAPID_YIELD,
102
        //
103
        // Read/write: Implemented in much the same fashion as the Unix/Posix
104
        //      read/write system calls.
105
        TRAPID_READ, TRAPID_WRITE,
106
        //
107
        // Time: Get the 
108
        TRAPID_TIME,
109
        //
110
        // kreturn: Return from a kernel system call.  This is necessary if
111
        // ever an exception triggers a system call.  In such cases, it will be
112
        // impossible to return the caller back to his context in a pristine
113
        // manner ... without help.
114
        // TRAPID_KRETURN,
115
        //
116
        // Semaphore ID's.  These allow us to run the rest of the trap
117
        // stuffs in kernel space
118
        TRAPID_SEMGET, TRAPID_SEMPUT, TRAPID_SEMNEW,
119
        //
120
        TRAPID_RECV, TRAPID_SEND,
121
        //
122
        // Malloc--since we're using a system level malloc, from a system
123
        // heap for everything, malloc/free require system calls
124
        // Eventually, this call should be replaced with an sbrk() POSIX
125
        // system call, but not until a full MMU is implemented and passes
126
        // testing.
127
        TRAPID_MALLOC, TRAPID_FREE,
128
        // EXIT -- end a task
129
        TRAPID_EXIT
130
} TRAPID;
131
 
132
extern  int     syscall(const int id, const int a, const int b, const int c);
133
 
134
static inline int       read(int fid, void *buf, int ln) {
135
        return syscall(TRAPID_READ, fid,(int)buf,ln);
136
} static inline int     write(int fid, const void *buf, int ln) {
137
        return syscall(TRAPID_WRITE, fid, (int)buf, ln);
138
}
139
 
140
static inline unsigned  time(void) {
141
        return syscall1(TRAPID_TIME);
142
}
143
 
144
static inline   void    yield(void) {
145
        syscall(TRAPID_YIELD, 0, 0, 0);
146
} static inline int     wait(unsigned event_mask, int timeout) {
147
        return syscall(TRAPID_WAIT, (int)event_mask, timeout, 0);
148
} static inline int     clear(unsigned event, int timeout) {
149
        return syscall(TRAPID_CLEAR, (int)event, timeout, 0);
150
} static inline void    post(unsigned event) {
151
        syscall2(TRAPID_POST, (int)event);
152
}
153
 
154
 
155
// PORTS:
156
//      Raw ethernet
157
//              Just gets sent
158
//      Raw internet
159
//              (Needs to MAC via ARP, then IP)
160
//      UDP ports
161
//              Adds IP header (sip/dip/dport/sport/etc), sends to raw internet
162
//      TCP ports
163
//              Adds IP header (sip/dip/dport/sport/etc), sends to raw internet
164
//
165
static inline len       recv(unsigned port, int buflen, unsigned *buf,
166
                        int timeout) {
167
        // Timeout =  0 -> wait forever
168
        // Port    = -1 -> system task, receive *any*/all packets
169
        return syscall5(TRAPID_RECV, port, buflen, buf, timeout);
170
}
171
 
172
static inline void      send(unsigned port, int buflen, unsigned *buf) {
173
        syscall(TRAPID_SEND, port, buflen, buf);
174
}
175
 
176
static inline   void *malloc(unsigned nbytes) {
177
        return (void *)syscall2(TRAPID_MALLOC, (int)nbytes0, 0);
178
} static inline void    free(void *buf) {
179
        syscall2(TRAPID_FREE,(int)buf);
180
}
181
 
182
static inline void      exit(int status) {
183
        syscall2(TRAPID_EXIT,status);
184
}
185
 
186
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.