1#!/usr/bin/env python 2# 3# Copyright 2017, Data61 4# Commonwealth Scientific and Industrial Research Organisation (CSIRO) 5# ABN 41 687 119 230. 6# 7# This software may be distributed and modified according to the terms of 8# the BSD 2-Clause license. Note that NO WARRANTY is provided. 9# See "LICENSE_BSD2.txt" for details. 10# 11# @TAG(DATA61_BSD) 12# 13 14# seL4 Invocation ID Generator 15# ============================ 16 17from __future__ import print_function 18import argparse 19import sys 20import xml.dom.minidom 21import pkg_resources; 22# We require jinja2 to be at least version 2.10 as we use the 'namespace' feature from 23# that version 24pkg_resources.require("jinja2>=2.10") 25from jinja2 import Environment, BaseLoader 26 27 28COMMON_HEADER = """ 29{%- if libsel4 -%} 30/* 31 * Copyright 2017, Data61 32 * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 33 * ABN 41 687 119 230. 34 * 35 * This software may be distributed and modified according to the terms of 36 * the BSD 2-Clause license. Note that NO WARRANTY is provided. 37 * See "LICENSE_BSD2.txt" for details. 38 * 39 * @TAG(DATA61_BSD) 40 */ 41{%- else -%} 42/* 43 * Copyright 2014, General Dynamics C4 Systems 44 * 45 * This software may be distributed and modified according to the terms of 46 * the GNU General Public License version 2. Note that NO WARRANTY is provided. 47 * See "LICENSE_GPLv2.txt" for details. 48 * 49 * @TAG(GD_GPL) 50 */ 51{%- endif %} 52 53/* This header was generated by kernel/tools/invocation_header_gen.py. 54 * 55 * To add an invocation call number, edit libsel4/include/interfaces/sel4.xml. 56 * 57 */""" 58 59INVOCATION_TEMPLATE = COMMON_HEADER + """ 60#ifndef __{{header_title}}_INVOCATION_H 61#define __{{header_title}}_INVOCATION_H 62 63enum invocation_label { 64 InvalidInvocation, 65 {%- for label, condition in invocations %} 66 {%- if condition %} 67#if {{condition}} 68 {%- endif %} 69 {{label}}, 70 {%- if condition %} 71#endif 72 {%- endif %} 73 {%- endfor %} 74 nInvocationLabels 75}; 76 77{%- if libsel4 %} 78#include <sel4/sel4_arch/invocation.h> 79#include <sel4/arch/invocation.h> 80{%- endif %} 81 82#endif /* __{{header_title}}_INVOCATION_H */ 83 84""" 85 86SEL4_ARCH_INVOCATION_TEMPLATE = COMMON_HEADER + """ 87#ifndef __{{header_title}}_SEL4_ARCH_INVOCATION_H 88#define __{{header_title}}_SEL4_ARCH_INVOCATION_H 89 90{%- if not libsel4 %} 91#include <api/invocation.h> 92{%- endif %} 93 94{%- set ns = namespace(first=True) %} 95enum sel4_arch_invocation_label { 96 {%- for label, condition in invocations %} 97 {%- if condition %} 98 {%- if ns.first %} 99#error "First sel4_arch invocation label cannot be conditional" 100 {%- endif %} 101#if {{condition}} 102 {%- endif %} 103 {%- if ns.first %} 104 {%- set ns.first = False %} 105 {{label}} = nInvocationLabels, 106 {%- else %} 107 {{label}}, 108 {%- endif %} 109 {%- if condition %} 110#endif 111 {%- endif %} 112 {%- endfor %} 113 {%- if ns.first %} 114 nSeL4ArchInvocationLabels = nInvocationLabels 115 {%- else %} 116 nSeL4ArchInvocationLabels 117 {%- endif %} 118}; 119 120#endif /* __{{header_title}}_SEL4_ARCH_INVOCATION_H */ 121 122""" 123 124ARCH_INVOCATION_TEMPLATE = COMMON_HEADER + """ 125#ifndef __{{header_title}}_ARCH_INVOCATION_H 126#define __{{header_title}}_ARCH_INVOCATION_H 127 128{%- if not libsel4 %} 129#include <arch/api/sel4_invocation.h> 130{%- endif %} 131 132{%- set ns = namespace(first=1) %} 133enum arch_invocation_label { 134 {%- for label, condition in invocations %} 135 {%- if condition %} 136 {%- if ns.first %} 137#error "First arch invocation label cannot be conditional" 138 {%- endif %} 139#if {{condition}} 140 {%- endif %} 141 {%- if ns.first %} 142 {{label}} = nSeL4ArchInvocationLabels, 143 {%- set ns.first = False %} 144 {%- else %} 145 {{label}}, 146 {%- endif %} 147 {%- if condition %} 148#endif 149 {%- endif %} 150 {%- endfor %} 151 {%- if ns.first %} 152 nArchInvocationLabels = nSeL4ArchInvocationLabels 153 {%- else %} 154 nArchInvocationLabels 155 {%- endif %} 156}; 157 158#endif /* __{{header_title}}_ARCH_INVOCATION_H */ 159 160""" 161 162def parse_args(): 163 parser = argparse.ArgumentParser(description='Generate seL4 invocation API \ 164 constants and header files') 165 parser.add_argument('--xml', type=argparse.FileType('r'), 166 help='Name of xml file with invocation definitions', required=True) 167 parser.add_argument('--dest', type=argparse.FileType('w'), 168 help='Name of file to create', required=True) 169 parser.add_argument('--libsel4', action='store_true', 170 help='Is this being generated for libsel4?') 171 group = parser.add_mutually_exclusive_group() 172 group.add_argument('--arch', action='store_true', 173 help='Is this being generated for the arch layer?') 174 group.add_argument('--sel4_arch', action='store_true', 175 help='Is this being generated for the seL4 arch layer?') 176 177 return parser.parse_args() 178 179def parse_xml(xml_file): 180 try: 181 doc = xml.dom.minidom.parse(xml_file) 182 except: 183 print("Error: invalid xml file", file=sys.stderr) 184 sys.exit(-1) 185 186 invocation_labels = [] 187 for method in doc.getElementsByTagName("method"): 188 invocation_labels.append((str(method.getAttribute("id")), str(method.getAttribute("condition")))) 189 190 return invocation_labels 191 192def generate(args, invocations): 193 194 header_title = "API" 195 if args.libsel4: 196 header_title = "LIBSEL4" 197 198 if args.arch: 199 template = Environment(loader=BaseLoader).from_string(ARCH_INVOCATION_TEMPLATE) 200 201 elif args.sel4_arch: 202 template = Environment(loader=BaseLoader).from_string(SEL4_ARCH_INVOCATION_TEMPLATE) 203 else: 204 template = Environment(loader=BaseLoader).from_string(INVOCATION_TEMPLATE) 205 206 data = template.render({'header_title': header_title, 'libsel4' : args.libsel4, 'invocations' : invocations, 'num_invocations' : len(invocations)}) 207 args.dest.write(data) 208 209 args.dest.close() 210 211if __name__ == "__main__": 212 args = parse_args() 213 214 invocations = parse_xml(args.xml) 215 args.xml.close() 216 217 generate(args, invocations) 218 219