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
|
import sys
try:
from lxml import etree
except ImportError:
sys.stderr.write("You need the lxml python module installed. "
"Preferably version 1.2.1 or later.\n"
"See http://codespeak.net/lxml/\n\n")
raise
rules_ns_ = '{http://nouveau.freedesktop.org/}'
# This really should not be here, but libxml2 does not load
# attribute defaults from the Schema.
rules_defaults_ = {
'reg8:type':'hex',
'reg8:access':'rw',
'reg32:type':'hex',
'reg32:access':'rw',
'array:type':'hex',
'bitfield:type':'hex',
'translation:variant':None
}
def load_xmlfile(fname):
src = open(fname, "r")
doc = etree.parse(src)
src.close()
return doc
def load_schema(fname):
return etree.XMLSchema(load_xmlfile(fname))
def getatt(elem, attrib):
val = elem.get(attrib)
if val is not None:
return val
name = "%s:%s" % ( elem.tag.replace(rules_ns_, ''), attrib )
try:
val = rules_defaults_[name]
except KeyError:
sys.stderr.write("Default value not found for %s.\n" % name)
val = None
return val
class RulesngHandler:
def __init__(self):
self._domain = ""
self._idcnt = 0
def process_children(self, root):
"""For the given element 'root', call dispatch_elem() for its
every child element and collect the return values into a
list, filtering out Nones."""
outs = map(self.dispatch_elem, root.getchildren())
return filter(lambda x: x is not None, outs)
def dispatch_elem(self, elem):
"""Determine the element type and call the proper function,
returning the functions return value."""
if type(elem) == etree._Comment:
return
elname = elem.tag.replace(rules_ns_, "elem_").replace('-', '_')
if hasattr(self, elname):
return getattr(self, elname)(elem)
def temp_array_name(self, oname):
"""Create a unique name for a temporary array.
The returned name can be different on each call."""
self._idcnt += 1
name = oname.replace('/', 's')
return "__%s_%03d" % (name, self._idcnt)
def def_name(self, oname):
"""Mangle object name to create a known private name in C."""
name = oname.replace('/', 's')
return "__%s_def" % name
class RulesngElement:
"""Object to store the complete identity of a register, array
or stripe from Rules-ng. Complete identity includes absolute
address and full name, with applicable variants.
Attributes:
variants a set of variant id strings
base the absolute base address, integer
arrinfo list of (stride, len) tuples from arrays/stripes
prefix name prefix string
elem reference to the lxml element object
parent reference to the parent RulesngElement object
children list of references to child Rulesnglement objects
containers list of container names; groups, bitsets, enums
translation reference to the translation RulesngElement, or None
idnum an arbitrary id number
"""
_id_base = 1000
def __init__(self, elem):
self.variants = set()
self.base = 0
self.arrinfo = []
self.prefix = ""
self.elem = elem
self.parent = None
self.children = []
self.containers = []
self.translation = None
self.idnum = RulesngElement._id_base
RulesngElement._id_base += 1
def copy(self):
"""Create a proper semideep copy; do a deep copy, except for
references to other RulesngElements."""
re = RulesngElement(self.elem)
re.variants = set(self.variants)
re.base = self.base
re.arrinfo = list(self.arrinfo)
re.prefix = self.prefix
re.parent = self.parent
re.children = list(self.children)
re.containers = list(self.containers)
re.translation = self.translation
return re
def getType(self):
"""Returns the name of the XML element as string."""
return self.elem.tag.replace(rules_ns_, '')
def getAddress(self):
"""Returns the absolute address (related to offset
attribute).
"""
return self.base + int(self.elem.get("offset"), 0)
def getStride(self):
return int(self.elem.get("stride"), 0)
def getLength(self):
return int(self.elem.get("length"), 0)
def getName(self):
"""Returns the complete name with prefixes."""
myname = self.elem.get("name")
if myname is not None:
if myname[0] == '/':
return myname[1:]
return self.prefix + myname
else:
return self.prefix
def getAtt(self, attribute):
"""Returns the value of the requested attribute, using
Rules-ng specified defaults if the attribute is not
defined in the lxml object."""
return getatt(self.elem, attribute)
|