1: #! /usr/bin/perl
2: #
3: # ----------------------------------------------------------------------
4: # T2EX Software Package
5: #
6: # Copyright 2012 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 2012/12/12.
11: # Modified by T-Engine Forum at 2013/02/20.
12: # Modified by TRON Forum(http://www.tron.org/) at 2015/06/04.
13: #
14: # ----------------------------------------------------------------------
15: #
16:
17: #
18: # This software package is available for use, modification,
19: # and redistribution in accordance with the terms of the attached
20: # T-License 2.x.
21: # If you want to redistribute the source code, you need to attach
22: # the T-License 2.x document.
23: # There's no obligation to publish the content, and no obligation
24: # to disclose it to the TRON Forum if you have modified the
25: # software package.
26: # You can also distribute the modified source code. In this case,
27: # please register the modification to T-Kernel traceability service.
28: # People can know the history of modifications by the service,
29: # and can be sure that the version you have inherited some
30: # modification of a particular version or not.
31: #
32: # http://trace.tron.org/tk/?lang=en
33: # http://trace.tron.org/tk/?lang=ja
34: #
35: # As per the provisions of the T-License 2.x, TRON Forum ensures that
36: # the portion of the software that is copyrighted by Ken Sakamura or
37: # the TRON Forum does not infringe the copyrights of a third party.
38: # However, it does not make any warranty other than this.
39: # DISCLAIMER: TRON Forum and Ken Sakamura shall not be held
40: # responsible for any consequences or damages caused directly or
41: # indirectly by the use of this software package.
42: #
43: # The source codes in bsd_source.tar.gz in this software package are
44: # derived from NetBSD or OpenBSD and not covered under T-License 2.x.
45: # They need to be changed or redistributed according to the
46: # representation of each source header.
47: #
48:
49: #
50: # mkt2exsvc
51: #
52: # T2EX SVC interface library generation script (common)
53: #
54:
55: $usage = 'usage: mkt2exsvc [-deps] machine infile';
56:
57: $makedeps = 0;
58: $infile = ""; # input file
59:
60: $copyright_c = <<EndOfCopyright;
61: /*
62: *----------------------------------------------------------------------
63: * T2EX Software Package
64: *
65: * Copyright 2012 by Ken Sakamura.
66: * This software is distributed under the latest version of T-License 2.x.
67: *----------------------------------------------------------------------
68: *
69: * Released by T-Engine Forum(http://www.t-engine.org/) at 2012/12/12.
70: * Modified by TRON Forum(http://www.tron.org/) at 2015/06/04.
71: *
72: *----------------------------------------------------------------------
73: */
74: /*
75: * This software package is available for use, modification,
76: * and redistribution in accordance with the terms of the attached
77: * T-License 2.x.
78: * If you want to redistribute the source code, you need to attach
79: * the T-License 2.x document.
80: * There's no obligation to publish the content, and no obligation
81: * to disclose it to the TRON Forum if you have modified the
82: * software package.
83: * You can also distribute the modified source code. In this case,
84: * please register the modification to T-Kernel traceability service.
85: * People can know the history of modifications by the service,
86: * and can be sure that the version you have inherited some
87: * modification of a particular version or not.
88: *
89: * http://trace.tron.org/tk/?lang=en
90: * http://trace.tron.org/tk/?lang=ja
91: *
92: * As per the provisions of the T-License 2.x, TRON Forum ensures that
93: * the portion of the software that is copyrighted by Ken Sakamura or
94: * the TRON Forum does not infringe the copyrights of a third party.
95: * However, it does not make any warranty other than this.
96: * DISCLAIMER: TRON Forum and Ken Sakamura shall not be held
97: * responsible for any consequences or damages caused directly or
98: * indirectly by the use of this software package.
99: *
100: * The source codes in bsd_source.tar.gz in this software package are
101: * derived from NetBSD or OpenBSD and not covered under T-License 2.x.
102: * They need to be changed or redistributed according to the
103: * representation of each source header.
104: */
105: EndOfCopyright
106:
107: #
108: # analyze command line parameter
109: #
110: if ( $ARGV[0] eq "-deps" ) {
111: $makedeps = 1;
112: shift(@ARGV);
113: }
114:
115: $machine = $ARGV[0];
116: $infile = $ARGV[1];
117:
118: if ( $machine eq "" ) {
119: print STDERR "$usage\n";
120: exit(1);
121: }
122: if ( $infile eq "" ) {
123: print STDERR "Too few arguments\n";
124: exit(1);
125: }
126:
127: $mkifsvc = "$ENV{'BD'}/etc/sysdepend/cpu/$machine/makeift2ex.pl";
128:
129: chop($infile_base = `basename $infile`);
130: @infile_elem = split(/_|\./, $infile_base);
131: $infile_base = $infile_elem[0];
132:
133: #
134: # parse definition file
135: #
136: open(IN, "$infile") || die "can not open $infile\n";
137:
138: $ignore = 1;
139: $if_h = "if${infile_base}.h";
140: $fn_h = "fn${infile_base}.h";
141: $incfile = "<${infile_base}.h>";
142:
143: while ( <IN> ) {
144:
145: # skip to definition line
146: if ( $ignore != 0 ) {
147: $ignore = 0 if ( /^(#|\/\*\*).*\bDEFINE_IFLIB\b/ );
148: next;
149: }
150:
151: chop;
152: s/^\s//; # trim space code
153:
154: next if ( /^$/ ); # skip empty line
155: next if ( /^#/ ); # skip comment line
156:
157: # input data type
158: if ( /^(\/\*\s+)*\[/ ) {
159: ( $inp ) = /\[(.*)\]/;
160: next;
161: }
162:
163: # clear input data type
164: if ( /^\*\*/ ) {
165: $inp = "";
166: next;
167: }
168:
169: # scan data
170: if ( $inp =~ /^(LIBRARY HEADER FILE)$/i ) {
171: $if_h = $_;
172: }
173: if ( $inp =~ /^(FNUMBER HEADER FILE)$/i ) {
174: $fn_h = $_;
175: }
176: if ( $inp =~ /^(INCLUDE FILE)$/i ) {
177: $incfile = $_;
178: }
179: if ( $inp =~ /^(PREFIX)$/i ) {
180: $prefix = $_;
181: }
182: if ( $inp =~ /^(SVC NO)$/i ) {
183: $svcno = $_;
184: }
185: if ( $inp =~ /^(BEGIN SYSCALLS)$/i ) {
186: s/\s+/ /g; # delete extra space code
187:
188: $syscalls[$#syscalls+1] = $_ if ( /^IMPORT/ );
189:
190: $syscalls[$#syscalls+1] = "" if ( /RESERVE_NO/ );
191:
192: if ( ( $no ) = /ALIGN_NO (0x[0-9a-zA-Z]+|[0-9]+)\b/ ) {
193: $no = oct($no) if ( $no =~ /^0/ );
194: if ( $no > 0 ) {
195: $i = $no - ($#syscalls + 1) % $no;
196: if ( $i > 1 && $i < $no ) {
197: $syscalls[$#syscalls+$i-1] = "";
198: } elsif ( $no > 1 && $#syscalls < 0 ) {
199: $syscalls[$no-2] = "";
200: }
201: }
202: }
203: if ( ( $no ) = /ORIGIN_NO (0x[0-9a-zA-Z]+|[0-9]+)\b/ ) {
204: $no = oct($no) if ( $no =~ /^0/ );
205: if ( $no > $#syscalls + 2 ) {
206: $syscalls[$no-2] = "";
207: }
208: }
209: }
210: }
211:
212: close(IN);
213:
214: if ( $#syscalls < 0 ) {
215: print stderr "There is no definition of a system call.\n";
216: exit(1);
217: }
218:
219: # ----------------------------------------------------------------------------
220: #
221: # dependency (-deps) mode
222: #
223: if ( $makedeps ) {
224: @svcsrc = ();
225:
226: for ( $i = 0; $i <= $#syscalls; $i++ ) {
227: next if ( $syscalls[$i] eq "" );
228:
229: $syscall = $syscalls[$i];
230: ( $Func, $func, $ret, @para ) = &split_func($syscall);
231:
232: $fname = $func;
233: $fname =~ tr/A-Z/a-z/; # to lower case
234:
235: print "\$(IFSRC)/$fname.S: $infile\n";
236: push(@svcsrc, "$fname.S");
237: }
238:
239: print "SRC_SVC += ".join(" ", @svcsrc)."\n" if ( @svcsrc );
240: exit(0);
241: }
242:
243: # ----------------------------------------------------------------------------
244: #
245: # generate function code definition file
246: #
247: open(FN_H, ">$fn_h") || die "can not open $fn_h\n";
248:
249: ### create header part ###
250: print FN_H <<EndOfFnHeader;
251: $copyright_c
252: /*
253: * T2EX SVC function code
254: *
255: * (generated automatically)
256: */
257:
258: #include <t2ex/ssid.h>
259:
260: EndOfFnHeader
261:
262: ### generate extended SVC number ###
263: $svc = "${prefix}_SVC";
264: if ( $svcno ne "" ) {
265:
266: print FN_H <<EndOfSVCNo;
267: /*
268: * Extended SVC number
269: */
270: #ifndef ${svc}
271: #define ${svc} $svcno
272: #endif
273:
274: EndOfSVCNo
275: }
276:
277: ### generate function number ###
278: for ( $i = 0; $i <= $#syscalls; $i++ ) {
279: next if ( $syscalls[$i] eq "" );
280:
281: ( $Func, $func, $ret, @para ) = &split_func($syscalls[$i]);
282: $fno = (($i + 1) << 16) + (($#para + 1) << 8);
283: printf FN_H "#define ${prefix}_${Func}_FN\t(0x%08x | ${svc})\n", $fno;
284: }
285: print FN_H "\n";
286:
287: close(FN_H);
288:
289: # ----------------------------------------------------------------------------
290: #
291: # create header file (if*.h)
292: #
293: open(IF_H, ">$if_h") || die "can not open $if_h\n";
294:
295: ### generate header part ###
296: print IF_H <<EndOfIfHeader;
297: $copyright_c
298: /*
299: * T2EX SVC parameter packet
300: *
301: * (generated automatically)
302: */
303:
304: #include <basic.h>
305: #include ${incfile}
306: #include <sys/str_align.h>
307: #include "${fn_h}"
308:
309: EndOfIfHeader
310:
311: ### generate parameter packet ###
312: for ( $i = 0; $i <= $#syscalls; $i++ ) {
313: next if ( $syscalls[$i] eq "" );
314:
315: ( $Func, $func, $ret, @para ) = &split_func($syscalls[$i]);
316:
317: # expect for void parameter
318: next if ( $#para < 0 );
319:
320: print IF_H "typedef struct {\n";
321: for ( $j = 0; $j <= $#para; $j++ ) {
322: ( $xp, $pad ) = &stack_packet($para[$j]);
323: print IF_H "\t_pad_b($pad)\n" if ( $pad > 0 );
324: print IF_H "\t$xp; _align64\n";
325: print IF_H "\t_pad_l($pad)\n" if ( $pad > 0 );
326: }
327: print IF_H "} ${prefix}_${Func}_PARA;\n\n";
328: }
329:
330: close(IF_H);
331:
332: # ----------------------------------------------------------------------------
333: #
334: # create extended SVC interface function
335: #
336:
337: for ( $i = 0; $i <= $#syscalls; $i++ ) {
338: next if ( $syscalls[$i] eq "" );
339:
340: $syscall = $syscalls[$i];
341: ( $Func, $func, $ret, @para ) = &split_func($syscall);
342:
343: $fname = $func;
344: $fname =~ tr/A-Z/a-z/; # to lower case
345:
346: # open library source file
347: open(LIB, ">$fname.S") || die "can not open $fname.S\n";
348:
349: print LIB <<EndOfIfLibHeader;
350: $copyright_c
351: /*
352: * T2EX SVC interface library ($machine)
353: *
354: * (generated automatically)
355: */
356:
357: EndOfIfLibHeader
358:
359: # system dependencies
360: require($mkifsvc);
361: &makeift2ex();
362:
363: close(LIB);
364: }
365:
366: exit(0);
367:
368: # ============================================================================
369:
370: #
371: # split definition of function
372: #
373: sub split_func
374: {
375: local($syscall) = @_;
376: local($Func, $func, $ret, @para, $p);
377:
378: ( $ret, $func, $p ) =
379: ( $syscall =~ /IMPORT\s+(\w+)\s+(\w+)\s*\((.*)\)\s*;/ );
380:
381: $p =~ s/^\s*//; # trim space code
382: $p =~ s/\s*$//;
383:
384: @para = split(/\s*,\s*/, $p); # split parameters
385:
386: if ( $#para == 0 && $para[0] =~ /^void$/i ) {
387: # no params (void)
388: @para = ();
389: }
390:
391: if ( $ret =~ /^void$/i ) {
392: # return type is "void"
393: $ret = "";
394: }
395:
396: $Func = $func;
397: $Func =~ s/^tkse_//; # delete "tkse_"
398: $Func =~ tr/a-z/A-Z/; # to upper case
399:
400: return ( $Func, $func, $ret, @para );
401: }
402:
403: #
404: # split parameter
405: #
406: sub split_para
407: {
408: local($para) = @_;
409: local($type, $vname, @token);
410:
411: # get variable name
412: $vname = $para;
413: $vname =~ s/\[[^\]]*\]//g;
414: if ( $vname =~ /\(/ ) {
415: $vname =~ s/^[^\(]*\(/\(/;
416: $vname =~ y/()*/ /s;
417: $vname =~ s/^\s*//;
418: @token = split(/ +/, $vname);
419: $vname = $token[0];
420: } else {
421: $vname =~ y/*/ /s;
422: @token = split(/ +/, $vname);
423: $vname = $token[$#token];
424: }
425:
426: # get variable type
427: $type = $para;
428: $type =~ s/\b$vname\b//;
429: $type =~ s/^\s*//;
430: $type =~ s/\s*$//;
431:
432: # convert variable type from array to pointer
433: if ( $para =~ s/\[[^\]]*\]// ) {
434: $para =~ s/\b($vname)\b/(*\1)/;
435: } else {
436: if ( &isMatrix($type) ) {
437: $para =~ s/\b($vname)\b/*\1/;
438: }
439: }
440:
441: return ( $type, $vname, $para );
442: }
443:
444: #
445: # create parameter packet members
446: #
447: sub stack_packet
448: {
449: local($para) = @_;
450: local($type, $vname, $pad);
451:
452: ( $type, $vname, $para ) = &split_para($para);
453:
454: # padding size to INT
455: $pad = &isShort($type);
456:
457: return ( $para, $pad );
458: }
459:
460: #
461: # return TRUE if variable is array
462: #
463: sub isMatrix
464: {
465: local($type) = @_;
466:
467: return ( $type =~ /^(KeyMap)$/ );
468: }
469:
470: #
471: # return sizeof(INT) - sizeof(variable type)
472: #
473: sub isShort
474: {
475: local($type) = @_;
476:
477: return 24 if ( $type =~ /^(B|UB|CHAR)$/ );
478: return 16 if ( $type =~ /^(H|UH|TC|CH|TLANG|SCRIPT)$/ );
479:
480: return 0;
481: }