-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsyscalls.h
More file actions
291 lines (241 loc) · 13.7 KB
/
syscalls.h
File metadata and controls
291 lines (241 loc) · 13.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
/*********************************************************************
syscalls.h
This include file is used by only the OS502.
Revision History:
1.0 August 1990: Initial release
1.1 Jan 1991: Make system calls portable
by using union of pointer
and long. Add incls for
scheduler_printer.
1.2 Dec 1991; Allow interrupts to occur
in user code and in CALL
statements.
1.5 Aug 1993; Add READ_MODIFY &
DEFINE_SHARED_AREA support.
2.0 Jan 2000; Small changes
2.1 May 2001; Fix STEP macro. DISK macros.
2.2 Jul 2002; Make code appropriate for undergrads.
2.3 Aug 2004; Modify Memory defines to work in kernel
3.1 Aug 2004: hardware interrupt runs on separate thread
3.11 Aug 2004: Support for OS level locking
3.30 July 2006: Modify POP_THE_STACK to apply to base only
*********************************************************************/
#include "stdio.h"
/* Definition of System Call numbers */
#define SYSNUM_MEM_READ 0
#define SYSNUM_MEM_WRITE 1
#define SYSNUM_READ_MODIFY 2
#define SYSNUM_GET_TIME_OF_DAY 3
#define SYSNUM_SLEEP 4
#define SYSNUM_GET_PROCESS_ID 5
#define SYSNUM_CREATE_PROCESS 6
#define SYSNUM_TERMINATE_PROCESS 7
#define SYSNUM_SUSPEND_PROCESS 8
#define SYSNUM_RESUME_PROCESS 9
#define SYSNUM_CHANGE_PRIORITY 10
#define SYSNUM_SEND_MESSAGE 11
#define SYSNUM_RECEIVE_MESSAGE 12
#define SYSNUM_DISK_READ 13
#define SYSNUM_DISK_WRITE 14
#define SYSNUM_DEFINE_SHARED_AREA 15
extern void charge_time_and_check_events( INT32 );
extern int BaseThread();
#ifndef COST_OF_CALL
#define COST_OF_CALL 2L
#endif
#define CALL( fff ) \
{ \
extern BOOL POP_THE_STACK; \
charge_time_and_check_events( COST_OF_CALL ); \
fff; \
if( POP_THE_STACK && BaseThread() ) \
return; \
} \
/* ZCALL is used only within the hardware - and for calls TO
the hardware. The OS should NOT use this for calls between
its own routines. For it's own calls, use CALL above. */
#define ZCALL( fff ) \
{ \
extern BOOL POP_THE_STACK; \
fff; \
if( POP_THE_STACK && BaseThread() ) \
return; \
} \
/* Macros used to make the test programs more readable */
#ifndef COST_OF_CPU_INSTRUCTION
#define COST_OF_CPU_INSTRUCTION 1L
#endif
/* Some compilers require a short
in a switch statement! */
#define SELECT_STEP switch( (INT16)Z502_PROGRAM_COUNTER )
#define STEP( sss ) \
\
case sss: \
charge_time_and_check_events( COST_OF_CPU_INSTRUCTION ); \
Z502_PROGRAM_COUNTER++;;
#define GO_NEXT_TO( ggg ) Z502_PROGRAM_COUNTER = ggg;
/* Macro expansions for each of the system calls */
#ifdef USER
#define MEM_READ( arg1, arg2 ) \
{ \
SYS_CALL_CALL_TYPE = SYSNUM_MEM_READ; \
Z502_ARG1.VAL = arg1; \
Z502_ARG2.PTR = (void *)arg2; \
return; \
}
#endif
#ifndef USER
#define MEM_READ( arg1, arg2 ) Z502_MEM_READ( arg1, arg2 )
#endif
#ifdef USER
#define MEM_WRITE( arg1, arg2 ) \
{ \
SYS_CALL_CALL_TYPE = SYSNUM_MEM_WRITE; \
Z502_ARG1.VAL = arg1; \
Z502_ARG2.PTR = (void *)arg2; \
return; \
}
#endif
#ifndef USER
#define MEM_WRITE( arg1, arg2 ) Z502_MEM_WRITE( arg1, arg2 );
#endif
#ifdef USER
#define READ_MODIFY( arg1, arg2, arg3, arg4 ) \
{ \
SYS_CALL_CALL_TYPE = SYSNUM_READ_MODIFY; \
Z502_ARG1.VAL = arg1; \
Z502_ARG2.VAL = arg2; \
Z502_ARG3.VAL = arg3; \
Z502_ARG4.PTR = (void *)arg4; \
return; \
}
#endif
#ifndef USER
#define READ_MODIFY( arg1, arg2 ) Z502_READ_MODIFY( arg1, arg2 );
#endif
#define GET_TIME_OF_DAY( arg1 ) \
{ \
SYS_CALL_CALL_TYPE = SYSNUM_GET_TIME_OF_DAY; \
Z502_ARG1.PTR = (void *)arg1; \
return; \
} \
#define SLEEP( arg1 ) \
{ \
SYS_CALL_CALL_TYPE = SYSNUM_SLEEP; \
Z502_ARG1.VAL = arg1; \
return; \
} \
#define CREATE_PROCESS( arg1, arg2, arg3, arg4, arg5 ) \
{ \
SYS_CALL_CALL_TYPE = SYSNUM_CREATE_PROCESS; \
Z502_ARG1.PTR = (void *)arg1; \
Z502_ARG2.PTR = (void *)arg2; \
Z502_ARG3.VAL = arg3; \
Z502_ARG4.PTR = (void *)arg4; \
Z502_ARG5.PTR = (void *)arg5; \
return; \
} \
#define GET_PROCESS_ID( arg1, arg2, arg3 ) \
{ \
SYS_CALL_CALL_TYPE = SYSNUM_GET_PROCESS_ID; \
Z502_ARG1.PTR = (void *)arg1; \
Z502_ARG2.PTR = (void *)arg2; \
Z502_ARG3.PTR = (void *)arg3; \
return; \
} \
#define TERMINATE_PROCESS( arg1, arg2 ) \
{ \
SYS_CALL_CALL_TYPE = SYSNUM_TERMINATE_PROCESS; \
Z502_ARG1.VAL = arg1; \
Z502_ARG2.PTR = (void *)arg2; \
return; \
} \
#define SUSPEND_PROCESS( arg1, arg2 ) \
{ \
SYS_CALL_CALL_TYPE = SYSNUM_SUSPEND_PROCESS; \
Z502_ARG1.VAL = arg1; \
Z502_ARG2.PTR = (void *)arg2; \
return; \
} \
#define RESUME_PROCESS( arg1, arg2 ) \
{ \
SYS_CALL_CALL_TYPE = SYSNUM_RESUME_PROCESS; \
Z502_ARG1.VAL = arg1; \
Z502_ARG2.PTR = (void *)arg2; \
return; \
} \
#define CHANGE_PRIORITY( arg1, arg2, arg3 ) \
{ \
SYS_CALL_CALL_TYPE = SYSNUM_CHANGE_PRIORITY; \
Z502_ARG1.VAL = arg1; \
Z502_ARG2.VAL = arg2; \
Z502_ARG3.PTR = (void *)arg3; \
return; \
} \
#define SEND_MESSAGE( arg1, arg2, arg3, arg4 ) \
{ \
SYS_CALL_CALL_TYPE = SYSNUM_SEND_MESSAGE; \
Z502_ARG1.VAL = arg1; \
Z502_ARG2.PTR = (void *)arg2; \
Z502_ARG3.VAL = arg3; \
Z502_ARG4.PTR = (void *)arg4; \
return; \
} \
#define RECEIVE_MESSAGE( arg1, arg2, arg3, arg4, arg5, arg6 ) \
{ \
SYS_CALL_CALL_TYPE = SYSNUM_RECEIVE_MESSAGE; \
Z502_ARG1.VAL = arg1; \
Z502_ARG2.PTR = (void *)arg2; \
Z502_ARG3.VAL = arg3; \
Z502_ARG4.PTR = (void *)arg4; \
Z502_ARG5.PTR = (void *)arg5; \
Z502_ARG6.PTR = (void *)arg6; \
return; \
} \
#define DISK_READ( arg1, arg2, arg3 ) \
{ \
SYS_CALL_CALL_TYPE = SYSNUM_DISK_READ; \
Z502_ARG1.VAL = arg1; \
Z502_ARG2.VAL = arg2; \
Z502_ARG3.PTR = (void *)arg3; \
return; \
} \
#define DISK_WRITE( arg1, arg2, arg3 ) \
{ \
SYS_CALL_CALL_TYPE = SYSNUM_DISK_WRITE; \
Z502_ARG1.VAL = arg1; \
Z502_ARG2.VAL = arg2; \
Z502_ARG3.PTR = (void *)arg3; \
return; \
} \
#define DEFINE_SHARED_AREA( arg1, arg2, arg3, arg4, arg5 ) \
{ \
SYS_CALL_CALL_TYPE = SYSNUM_DEFINE_SHARED_AREA; \
Z502_ARG1.VAL = arg1; \
Z502_ARG2.VAL = arg2; \
Z502_ARG3.PTR = (void *)arg3; \
Z502_ARG4.PTR = (void *)arg4; \
Z502_ARG5.PTR = (void *)arg5; \
return; \
} \
/* This section includes items needed in the scheduler printer.
It's also useful for those routines that want to communicate
with the scheduler printer. */
#define SP_FILE_MODE (INT16)0
#define SP_TIME_MODE (INT16)1
#define SP_ACTION_MODE (INT16)2
#define SP_TARGET_MODE (INT16)3
#define SP_STATE_MODE_START (INT16)4
#define SP_NEW_MODE (INT16)4
#define SP_RUNNING_MODE (INT16)5
#define SP_READY_MODE (INT16)6
#define SP_WAITING_MODE (INT16)7
#define SP_SUSPENDED_MODE (INT16)8
#define SP_SWAPPED_MODE (INT16)9
#define SP_TERMINATED_MODE (INT16)10
#define SP_NUMBER_OF_STATES SP_TERMINATED_MODE-SP_NEW_MODE+1
#define SP_MAX_NUMBER_OF_PIDS (INT16)10
#define SP_LENGTH_OF_ACTION (INT16)8
/* This string is printed out when requested as the header */
#define SP_HEADER_STRING \
" Time Target Action Run New Done State Populations \n"