1: #! /usr/bin/perl
2: #
3: # ----------------------------------------------------------------------
4: # T-Kernel 2.0 Software Package
5: #
6: # Copyright 2011 by Ken Sakamura.
7: # This software is distributed under the latest version of T-License 2.x.
8: # ----------------------------------------------------------------------
9: #
10: # Released by T-Engine Forum(http://www.t-engine.org/) at 2011/05/17.
11: # Modified by T-Engine Forum at 2014/07/14.
12: # Modified by TRON Forum(http://www.tron.org/) at 2015/06/01.
13: #
14: # ----------------------------------------------------------------------
15: #
16:
17: # mktdsvc
18: #
19: # T-Kernel/DS system call
20: # interface library generation script
21: #
22: #
23:
24: $usage = 'usage: mktdsvc [-deps] cpu infile';
25:
26: $makedeps = 0;
27: $infile = ""; # input file
28:
29: $copyright_c = <<EndOfCopyright;
30: /*
31: *----------------------------------------------------------------------
32: * T-Kernel 2.0 Software Package
33: *
34: * Copyright 2011 by Ken Sakamura.
35: * This software is distributed under the latest version of T-License 2.x.
36: *----------------------------------------------------------------------
37: *
38: * Released by T-Engine Forum(http://www.t-engine.org/) at 2011/05/17.
39: * Modified by TRON Forum(http://www.tron.org/) at 2015/06/01.
40: *
41: *----------------------------------------------------------------------
42: */
43: EndOfCopyright
44:
45: #
46: # analyze command line parameter
47: #
48: if ( $ARGV[0] eq "-deps" ) {
49: $makedeps = 1;
50: shift(@ARGV);
51: }
52:
53: $cpu = $ARGV[0];
54: $infile = $ARGV[1];
55: if ( $cpu eq "" ) {
56: print STDERR "$usage\n";
57: exit(1);
58: }
59: if ( $infile eq "" ) {
60: print STDERR "Too few arguments\n";
61: exit(1);
62: }
63:
64: #
65: # parse definition file
66: #
67: open(IN, "$infile") || die "can not open $infile\n";
68:
69: $ignore = 1;
70: $tb_h = "tdsvctbl.h";
71: $fn_h = "tdfncd.h";
72:
73: while ( <IN> ) {
74:
75: # skip to definition line
76: if ( $ignore != 0 ) {
77: $ignore = 0 if ( /^(#|\/\*\*).*\bDEFINE_TDSVC\b/ );
78: next;
79: }
80:
81: chop;
82: s/^\s//; # trim space code
83:
84: next if ( /^$/ ); # skip empty line
85: next if ( /^#/ ); # skip comment line
86:
87: # input data type
88: if ( /^(\/\*\s+)*\[/ ) {
89: ( $inp ) = /\[(.*)\]/;
90: next;
91: }
92:
93: # clear input data type
94: if ( /^\*\*/ ) {
95: $inp = "";
96: next;
97: }
98:
99: # scan data
100: if ( $inp =~ /^(BRANCH TABLE FILE)$/i ) {
101: $tb_h = $_;
102: }
103: if ( $inp =~ /^(FNUMBER HEADER FILE)$/i ) {
104: $fn_h = $_;
105: }
106: if ( $inp =~ /^(BEGIN SYSCALLS)$/i ) {
107: s/\s+/ /g; # delete extra space code
108:
109: $syscalls[$#syscalls+1] = $_ if ( /^IMPORT/ );
110:
111: $syscalls[$#syscalls+1] = "" if ( /RESERVE_NO/ );
112:
113: if ( ( $align ) = /ALIGN_NO (0x[0-9a-zA-Z]+|[0-9]+)\b/ ) {
114: $align = oct($align) if ( $align =~ /^0/ );
115: if ( $align > 0 ) {
116: $i = $align - ($#syscalls + 1) % $align;
117: if ( $i > 1 && $i < $align ) {
118: $syscalls[$#syscalls+$i-1] = "";
119: } elsif ( $align > 1 && $#syscalls < 0 ) {
120: $syscalls[$align-2] = "";
121: }
122: }
123: }
124: }
125: }
126:
127: close(IN);
128:
129: if ( $#syscalls < 0 ) {
130: print stderr "There is no definition of a system call.\n";
131: exit(1);
132: }
133:
134: # ----------------------------------------------------------------------------
135: #
136: # dependency (-deps) mode
137: #
138: if ( $makedeps ) {
139: @svcsrc = ();
140:
141: for ( $i = 0; $i <= $#syscalls; $i++ ) {
142: next if ( $syscalls[$i] eq "" );
143:
144: $syscall = $syscalls[$i];
145: ( $Func, $func, $ret, @para ) = &split_func($syscall);
146:
147: $fname = $func;
148: $fname =~ tr/A-Z/a-z/; # to lower case
149:
150: print "\$(IFSRC)/$fname.S: $infile\n";
151: push(@svcsrc, "$fname.S");
152: }
153:
154: print "SRC_SVC += ".join(" ", @svcsrc)."\n" if ( @svcsrc );
155: exit(0);
156: }
157:
158: # ----------------------------------------------------------------------------
159: #
160: # generate function code definition file
161: #
162: open(FN_H, ">$ENV{'BD'}/include/sys/svc/$fn_h") || die "can not open $ENV{'BD'}/include/sys/svc/$fn_h\n";
163:
164: ### create header part ###
165: print FN_H <<EndOfFnHeader;
166: $copyright_c
167: /*
168: * T-Kernel/DS function code
169: */
170:
171: EndOfFnHeader
172:
173: ### create function code ###
174: for ( $i = 0; $i <= $#syscalls; $i++ ) {
175: next if ( $syscalls[$i] eq "" );
176:
177: ( $Func, $func, $ret, @para ) = &split_func($syscalls[$i]);
178: $fno = ((($i + 1) << 16) + (($#para + 1) << 8)) | 0x80000000;
179: printf FN_H "#define TDFN_${Func}\t0x%08x\n", $fno;
180: }
181: print FN_H "\n";
182:
183: close(FN_H);
184:
185: # ----------------------------------------------------------------------------
186: #
187: # generate branch table
188: #
189: open(TB_H, ">$ENV{'BD'}/include/sys/svc/$tb_h") || die "can not open $ENV{'BD'}/include/sys/svc/$tb_h\n";
190:
191: ### create header part ###
192: print TB_H <<EndOfTbHeader;
193: $copyright_c
194: /*
195: * T-Kernel/DS system call branch table
196: *
197: * (generated automatically)
198: */
199:
200: #include <machine.h>
201:
202: #define _TDSC_ENTRY(name) .int Csym(_##name)
203:
204: EndOfTbHeader
205:
206: # number of system call
207: printf TB_H "#define N_TDFN %d\n", $#syscalls + 1;
208: printf TB_H "\n";
209:
210: ### create branch table ###
211: for ( $i = 0; $i <= $#syscalls; $i++ ) {
212: if ( $syscalls[$i] eq "" ) {
213: printf TB_H "\t_TDSC_ENTRY(no_support)\n";
214: } else {
215: ( $Func, $func, $ret, @para ) = &split_func($syscalls[$i]);
216: print TB_H "\t_TDSC_ENTRY(${func})\n";
217: }
218: }
219:
220: close(TB_H);
221:
222: # ----------------------------------------------------------------------------
223: #
224: # create SVC interface function
225: #
226:
227: for ( $i = 0; $i <= $#syscalls; $i++ ) {
228: next if ( $syscalls[$i] eq "" );
229:
230: $syscall = $syscalls[$i];
231: ( $Func, $func, $ret, @para ) = &split_func($syscall);
232:
233: $fname = $func;
234: $fname =~ tr/A-Z/a-z/; # to lower case
235:
236: # open library source file
237: open(LIB, ">sysdepend/$cpu/$fname.S") || die "can not open sysdepend/$cpu/$fname.S\n";
238:
239: print LIB <<EndOfIfLibHeader;
240: $copyright_c
241: /*
242: * T-Kernel SVC interface library ($cpu)
243: *
244: * (generated automatically)
245: */
246:
247: EndOfIfLibHeader
248:
249: # system dependencies
250: require("$ENV{'BD'}/etc/sysdepend/cpu/$cpu/makeiftd.pl");
251: &makelib();
252:
253: close(LIB);
254: }
255:
256: exit(0);
257:
258: # ============================================================================
259:
260: #
261: # split definition of function
262: #
263: sub split_func
264: {
265: local($syscall) = @_;
266: local($Func, $func, $ret, @para, $p);
267:
268: ( $ret, $func, $p ) =
269: ( $syscall =~ /IMPORT\s+(\w+)\s+(\w+)\s*\((.*)\)\s*;/ );
270:
271: $p =~ s/^\s*//; # trim space code
272: $p =~ s/\s*$//;
273:
274: @para = split(/\s*,\s*/, $p); # split parameters
275:
276: if ( $#para == 0 && $para[0] =~ /^void$/i ) {
277: # no params (void)
278: @para = ();
279: }
280:
281: if ( $ret =~ /^void$/i ) {
282: # return type is "void"
283: $ret = "";
284: }
285:
286: $Func = $func;
287: $Func =~ s/^td_//; # delete "td_"
288: $Func =~ tr/a-z/A-Z/; # to upper case
289:
290: return ( $Func, $func, $ret, @para );
291: }