mirror of
https://github.com/seL4/seL4.git
synced 2026-04-04 22:39:54 +00:00
Update all scripts and build system to call python3, given python2's upcoming doom. Use sys.maxsize instead of sys.maxint in one script (maxint does not exist in python3).
251 lines
7.0 KiB
Python
Executable File
251 lines
7.0 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
#
|
|
# Copyright 2017, Data61
|
|
# Commonwealth Scientific and Industrial Research Organisation (CSIRO)
|
|
# ABN 41 687 119 230.
|
|
#
|
|
# This software may be distributed and modified according to the terms of
|
|
# the BSD 2-Clause license. Note that NO WARRANTY is provided.
|
|
# See "LICENSE_BSD2.txt" for details.
|
|
#
|
|
# @TAG(DATA61_BSD)
|
|
#
|
|
|
|
# seL4 System Call ID Generator
|
|
# ==============================
|
|
|
|
from __future__ import print_function
|
|
from jinja2 import Environment, BaseLoader
|
|
import argparse
|
|
import re
|
|
import sys
|
|
import xml.dom.minidom
|
|
import pkg_resources
|
|
# We require jinja2 to be at least version 2.10 as we use the 'namespace' feature from
|
|
# that version
|
|
pkg_resources.require("jinja2>=2.10")
|
|
|
|
|
|
COMMON_HEADER = """
|
|
/* This header was generated by kernel/tools/syscall_header_gen.py.
|
|
*
|
|
* To add a system call number, edit kernel/include/api/syscall.xml
|
|
*
|
|
*/"""
|
|
|
|
KERNEL_HEADER_TEMPLATE = """/*
|
|
* Copyright 2014, General Dynamics C4 Systems
|
|
*
|
|
* This software may be distributed and modified according to the terms of
|
|
* the GNU General Public License version 2. Note that NO WARRANTY is provided.
|
|
* See "LICENSE_GPLv2.txt" for details.
|
|
*
|
|
* @TAG(GD_GPL)
|
|
*/
|
|
""" + COMMON_HEADER + """
|
|
#ifndef __ARCH_API_SYSCALL_H
|
|
#define __ARCH_API_SYSCALL_H
|
|
|
|
#ifdef __ASSEMBLER__
|
|
|
|
/* System Calls */
|
|
{%- set ns = namespace(syscall_number=-1) -%}
|
|
{%- for condition, list in assembler -%}
|
|
{%- for syscall in list %}
|
|
#define SYSCALL_{{upper(syscall)}} ({{ns.syscall_number}})
|
|
{%- set ns.syscall_number = ns.syscall_number -1 -%}
|
|
{%- endfor %}
|
|
{%- endfor %}
|
|
|
|
#endif
|
|
|
|
#define SYSCALL_MAX (-1)
|
|
#define SYSCALL_MIN ({{ns.syscall_number+ 1}})
|
|
|
|
#ifndef __ASSEMBLER__
|
|
|
|
enum syscall {
|
|
{%- set ns.syscall_number = -1 -%}
|
|
{% for condition, list in enum %}
|
|
{%- if condition | length > 0 %}
|
|
#if {{condition}}
|
|
{%- endif %}
|
|
{%- for syscall in list %}
|
|
Sys{{syscall}} = {{ns.syscall_number}},
|
|
{%- set ns.syscall_number = ns.syscall_number -1 -%}
|
|
{%- endfor %}
|
|
{%- if condition | length > 0 %}
|
|
#endif /* {{condition}} */
|
|
{%- endif %}
|
|
{%- endfor %}
|
|
};
|
|
typedef word_t syscall_t;
|
|
|
|
/* System call names */
|
|
#ifdef CONFIG_DEBUG_BUILD
|
|
static char *syscall_names[] UNUSED = {
|
|
{%- set ns.syscall_number = 1 -%}
|
|
{%- for condition, list in assembler %}
|
|
{%- for syscall in list %}
|
|
[{{ns.syscall_number}}] = "{{syscall}}",
|
|
{%- set ns.syscall_number = ns.syscall_number +1 -%}
|
|
{%- endfor %}
|
|
{%- endfor %}
|
|
};
|
|
#endif /* CONFIG_DEBUG_BUILD */
|
|
#endif
|
|
|
|
#endif /* __ARCH_API_SYSCALL_H */
|
|
|
|
"""
|
|
|
|
LIBSEL4_HEADER_TEMPLATE = """/*
|
|
* Copyright 2017, Data61
|
|
* Commonwealth Scientific and Industrial Research Organisation (CSIRO)
|
|
* ABN 41 687 119 230.
|
|
*
|
|
* This software may be distributed and modified according to the terms of
|
|
* the BSD 2-Clause license. Note that NO WARRANTY is provided.
|
|
* See "LICENSE_BSD2.txt" for details.
|
|
*
|
|
*
|
|
* @TAG(DATA61_BSD)
|
|
*/
|
|
|
|
""" + COMMON_HEADER + """
|
|
#ifndef __LIBSEL4_SYSCALL_H
|
|
#define __LIBSEL4_SYSCALL_H
|
|
|
|
#include <autoconf.h>
|
|
|
|
typedef enum {
|
|
{%- set ns = namespace(syscall_number=-1) -%}
|
|
{%- for condition, list in enum %}
|
|
{%- if condition | length > 0 %}
|
|
#if {{condition}}
|
|
{%- endif %}
|
|
{%- for syscall in list %}
|
|
seL4_Sys{{syscall}} = {{ns.syscall_number}},
|
|
{%- set ns.syscall_number = ns.syscall_number - 1 -%}
|
|
{%- endfor %}
|
|
{%- if condition | length > 0 %}
|
|
#endif /* {{condition}} */
|
|
{%- endif %}
|
|
{%- endfor %}
|
|
SEL4_FORCE_LONG_ENUM(seL4_Syscall_ID)
|
|
} seL4_Syscall_ID;
|
|
|
|
#endif /* __ARCH_API_SYSCALL_H */
|
|
|
|
"""
|
|
|
|
|
|
def parse_args():
|
|
parser = argparse.ArgumentParser(description="""Generate seL4 syscall API constants
|
|
and associated header files""")
|
|
parser.add_argument('--xml', type=argparse.FileType('r'),
|
|
help='Name of xml file with syscall name definitions', required=True)
|
|
parser.add_argument('--kernel_header', type=argparse.FileType('w'),
|
|
help='Name of file to generate for kernel')
|
|
parser.add_argument('--libsel4_header', type=argparse.FileType('w'),
|
|
help='Name of file to generate for libsel4')
|
|
|
|
result = parser.parse_args()
|
|
|
|
if result.kernel_header is None and result.libsel4_header is None:
|
|
print("Error: must provide either kernel_header or libsel4_header",
|
|
file=sys.stderr)
|
|
parser.print_help()
|
|
exit(-1)
|
|
|
|
return result
|
|
|
|
|
|
def parse_syscall_list(element):
|
|
syscalls = []
|
|
for config in element.getElementsByTagName("config"):
|
|
config_condition = config.getAttribute("condition")
|
|
config_syscalls = []
|
|
for syscall in config.getElementsByTagName("syscall"):
|
|
name = str(syscall.getAttribute("name"))
|
|
config_syscalls.append(name)
|
|
syscalls.append((config_condition, config_syscalls))
|
|
|
|
# sanity check
|
|
assert len(syscalls) != 0
|
|
|
|
return syscalls
|
|
|
|
|
|
def parse_xml(xml_file):
|
|
# first check if the file is valid xml
|
|
try:
|
|
doc = xml.dom.minidom.parse(xml_file)
|
|
except:
|
|
print("Error: invalid xml file.", file=sys.stderr)
|
|
sys.exit(-1)
|
|
|
|
api = doc.getElementsByTagName("api")
|
|
if len(api) != 1:
|
|
print("Error: malformed xml. Only one api element allowed",
|
|
file=sys.stderr)
|
|
sys.exit(-1)
|
|
|
|
configs = api[0].getElementsByTagName("config")
|
|
if len(configs) != 1:
|
|
print("Error: api element only supports 1 config element",
|
|
file=sys.stderr)
|
|
sys.exit(-1)
|
|
|
|
if len(configs[0].getAttribute("name")) != 0:
|
|
print("Error: api element config only supports an empty name",
|
|
file=sys.stderr)
|
|
sys.exit(-1)
|
|
|
|
# debug elements are optional
|
|
debug = doc.getElementsByTagName("debug")
|
|
if len(debug) != 1:
|
|
debug_element = None
|
|
else:
|
|
debug_element = debug[0]
|
|
|
|
api_elements = parse_syscall_list(api[0])
|
|
debug = parse_syscall_list(debug_element)
|
|
|
|
return (api_elements, debug)
|
|
|
|
|
|
def convert_to_assembler_format(s):
|
|
words = re.findall('[A-Z][A-Z]?[^A-Z]*', s)
|
|
return '_'.join(words).upper()
|
|
|
|
|
|
def generate_kernel_file(kernel_header, api, debug):
|
|
template = Environment(loader=BaseLoader, trim_blocks=False,
|
|
lstrip_blocks=False).from_string(KERNEL_HEADER_TEMPLATE)
|
|
data = template.render({'assembler': api, 'enum': api + debug,
|
|
'upper': convert_to_assembler_format})
|
|
kernel_header.write(data)
|
|
|
|
|
|
def generate_libsel4_file(libsel4_header, syscalls):
|
|
template = Environment(loader=BaseLoader, trim_blocks=False,
|
|
lstrip_blocks=False).from_string(LIBSEL4_HEADER_TEMPLATE)
|
|
data = template.render({'enum': syscalls})
|
|
libsel4_header.write(data)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
args = parse_args()
|
|
|
|
(api, debug) = parse_xml(args.xml)
|
|
args.xml.close()
|
|
|
|
if (args.kernel_header is not None):
|
|
generate_kernel_file(args.kernel_header, api, debug)
|
|
args.kernel_header.close()
|
|
|
|
if (args.libsel4_header is not None):
|
|
generate_libsel4_file(args.libsel4_header, api + debug)
|
|
args.libsel4_header.close()
|