blob: 153ee51c581e24b6132e78b9b12faba1ffdc0bb8 [file] [log] [blame]
lowRISC Contributors802543a2019-08-31 12:12:56 +01001# Copyright lowRISC contributors.
2# Licensed under the Apache License, Version 2.0, see LICENSE for details.
3# SPDX-License-Identifier: Apache-2.0
4"""
5Generates the documentation for the register tool
6
7"""
lowRISC Contributors802543a2019-08-31 12:12:56 +01008from reggen import validate
9
10
11def genout(outfile, msg):
12 outfile.write(msg)
13
14
15doc_intro = """
16
Rupert Swarbrick11042032020-11-25 10:32:04 +000017<!-- Start of output generated by `regtool.py --doc` -->
lowRISC Contributors802543a2019-08-31 12:12:56 +010018
19The tables describe each key and the type of the value. The following
20types are used:
21
22Type | Description
23---- | -----------
24"""
25
26swaccess_intro = """
27
28Register fields are tagged using the swaccess key to describe the
29permitted access and side-effects. This key must have one of these
30values:
31
32"""
33
34hwaccess_intro = """
35
36Register fields are tagged using the hwaccess key to describe the
37permitted access from hardware logic and side-effects. This key must
38have one of these values:
39
40"""
41
42top_example = """
43The basic structure of a register definition file is thus:
44
45```hjson
46{
47 name: "GP",
48 regwidth: "32",
49 registers: [
50 // register definitions...
51 ]
52}
53
54```
55
56"""
57
58register_example = """
59
60The basic register definition group will follow this pattern:
61
62```hjson
63 { name: "REGA",
64 desc: "Description of register",
65 swaccess: "rw",
66 resval: "42",
67 fields: [
68 // bit field definitions...
69 ]
70 }
71```
72
73The name and brief description are required. If the swaccess key is
74provided it describes the access pattern that will be used by all
75bitfields in the register that do not override with their own swaccess
76key. This is a useful shortcut because in most cases a register will
77have the same access restrictions for all fields. The reset value of
78the register may also be provided here or in the individual fields. If
79it is provided in both places then they must match, if it is provided
80in neither place then the reset value defaults to zero for all except
81write-only fields when it defaults to x.
82
83"""
84
85field_example = """
86
87Field names should be relatively short because they will be used
88frequently (and need to fit in the register layout picture!) The field
89description is expected to be longer and will most likely make use of
Philipp Wagner14a3fee2019-11-21 10:07:02 +000090the Hjson ability to include multi-line strings. An example with three
lowRISC Contributors802543a2019-08-31 12:12:56 +010091fields:
92
93```hjson
94 fields: [
95 { bits: "15:0",
96 name: "RXS",
97 desc: '''
98 Last 16 oversampled values of RX. These are captured at 16x the baud
99 rate clock. This is a shift register with the most recent bit in
100 bit 0 and the oldest in bit 15. Only valid when ENRXS is set.
101 '''
102 }
103 { bits: "16",
104 name: "ENRXS",
105 desc: '''
106 If this bit is set the receive oversampled data is collected
107 in the RXS field.
108 '''
109 }
110 {bits: "20:19", name: "TXILVL",
111 desc: "Trigger level for TX interrupts",
112 resval: "2",
113 enum: [
114 { value: "0", name: "txlvl1", desc: "1 character" },
115 { value: "1", name: "txlvl4", desc: "4 characters" },
116 { value: "2", name: "txlvl8", desc: "8 characters" },
117 { value: "3", name: "txlvl16", desc: "16 characters" }
118 ]
119 }
120 ]
121```
122
123In all of these the swaccess parameter is inherited from the register
124level, and will be added so this key is always available to the
125backend. The RXS and ENRXS will default to zero reset value (unless
126something different is provided for the register) and will have the
127key added, but TXILVL expicitly sets its reset value as 2.
128
129The missing bits 17 and 18 will be treated as reserved by the tool, as
130will any bits between 21 and the maximum in the register.
131
132The TXILVL is an example using an enumeration to specify all valid
133values for the field. In this case all possible values are described,
134if the list is incomplete then the field is marked with the rsvdenum
135key so the backend can take appropriate action. (If the enum field is
136more than 7 bits then the checking is not done.)
137
138"""
139
140offset_intro = """
141
142"""
143
144multi_intro = """
145
146The multireg expands on the register required fields and will generate
147a list of the generated registers (that contain all required and
148generated keys for an actual register).
149
150"""
151
152window_intro = """
153
154A window defines an open region of the register space that can be used
155for things that are not registers (for example access to a buffer ram).
156
157"""
158
159regwen_intro = """
160
161Registers can protect themselves from software writes by using the
162register attribute regwen. When not an emptry string (the default
163value), regwen indicates that another register must be true in order
164to allow writes to this register. This is useful for the prevention
165of software modification. The register-enable register (call it
166REGWEN) must be one bit in width, and should default to 1 and be rw1c
167for preferred security control. This allows all writes to proceed
168until at some point software disables future modifications by clearing
169REGWEN. An error is reported if REGWEN does not exist, contains more
170than one bit, is not `rw1c` or does not default to 1. One REGWEN can
Scott Johnson3976f9f2020-05-20 13:54:40 -0700171protect multiple registers. The REGWEN register must precede those
172registers that refer to it in the .hjson register list. An example:
lowRISC Contributors802543a2019-08-31 12:12:56 +0100173
174```hjson
175 { name: "REGWEN",
176 desc: "Register write enable for a bank of registers",
177 swaccess: "rw1c",
178 fields: [ { bits: "0", resval: "1" } ]
179 }
180 { name: "REGA",
181 swaccess: "rw",
182 regwen: "REGWEN",
183 ...
184 }
185 { name: "REGB",
186 swaccess: "rw",
187 regwen: "REGWEN",
188 ...
189 }
190```
191"""
192
193doc_tail = """
194
195(end of output generated by `regtool.py --doc`)
196
197"""
198
199
200def doc_tbl_head(outfile, use):
Eunchan Kim0bd75662020-04-24 10:21:18 -0700201 if use is not None:
lowRISC Contributors802543a2019-08-31 12:12:56 +0100202 genout(outfile, "\nKey | Kind | Type | Description of Value\n")
203 genout(outfile, "--- | ---- | ---- | --------------------\n")
204 else:
205 genout(outfile, "\nKey | Description\n")
206 genout(outfile, "--- | -----------\n")
207
208
209def doc_tbl_line(outfile, key, use, desc):
Eunchan Kim0bd75662020-04-24 10:21:18 -0700210 if use is not None:
Rupert Swarbrickc02b52f2020-10-07 15:34:16 +0100211 desc_key, desc_txt = desc
212 val_type = (validate.val_types[desc_key][0]
213 if desc_key is not None else None)
lowRISC Contributors802543a2019-08-31 12:12:56 +0100214 else:
Rupert Swarbrickc02b52f2020-10-07 15:34:16 +0100215 assert isinstance(desc, str)
216 val_type = None
217 desc_txt = desc
218
219 if val_type is not None:
220 genout(outfile,
221 '{} | {} | {} | {}\n'
222 .format(key, validate.key_use[use], val_type, desc_txt))
223 else:
224 genout(outfile, key + " | " + desc_txt + "\n")
lowRISC Contributors802543a2019-08-31 12:12:56 +0100225
226
227def document(outfile):
228 genout(outfile, doc_intro)
229 for x in validate.val_types:
230 genout(
231 outfile,
232 validate.val_types[x][0] + " | " + validate.val_types[x][1] + "\n")
233
234 genout(outfile, swaccess_intro)
235 doc_tbl_head(outfile, None)
236 for x in validate.swaccess_permitted:
237 doc_tbl_line(outfile, x, None, validate.swaccess_permitted[x][0])
238
239 genout(outfile, hwaccess_intro)
240 doc_tbl_head(outfile, None)
241 for x in validate.hwaccess_permitted:
242 doc_tbl_line(outfile, x, None, validate.hwaccess_permitted[x][0])
243
Eunchan Kim0bd75662020-04-24 10:21:18 -0700244 genout(
245 outfile, "\n\nThe top level of the JSON is a group containing "
246 "the following keys:\n")
lowRISC Contributors802543a2019-08-31 12:12:56 +0100247 doc_tbl_head(outfile, 1)
248 for x in validate.top_required:
249 doc_tbl_line(outfile, x, 'r', validate.top_required[x])
250 for x in validate.top_optional:
251 doc_tbl_line(outfile, x, 'o', validate.top_optional[x])
252 for x in validate.top_added:
253 doc_tbl_line(outfile, x, 'a', validate.top_added[x])
254 genout(outfile, top_example)
255
Pirmin Vogel1237a4e2020-06-23 09:07:28 +0200256 genout(
257 outfile, "\n\nThe list of registers includes register definition "
258 "groups containing the following keys:\n")
lowRISC Contributors802543a2019-08-31 12:12:56 +0100259 doc_tbl_head(outfile, 1)
260 for x in validate.reg_required:
261 doc_tbl_line(outfile, x, 'r', validate.reg_required[x])
262 for x in validate.reg_optional:
263 doc_tbl_line(outfile, x, 'o', validate.reg_optional[x])
264 for x in validate.reg_added:
265 doc_tbl_line(outfile, x, 'a', validate.reg_added[x])
266 genout(outfile, register_example)
267
Eunchan Kim0bd75662020-04-24 10:21:18 -0700268 genout(
269 outfile, "\n\nIn the fields list each field definition is a group "
Pirmin Vogel1237a4e2020-06-23 09:07:28 +0200270 "itself containing the following keys:\n")
lowRISC Contributors802543a2019-08-31 12:12:56 +0100271 doc_tbl_head(outfile, 1)
272 for x in validate.field_required:
273 doc_tbl_line(outfile, x, 'r', validate.field_required[x])
274 for x in validate.field_optional:
275 doc_tbl_line(outfile, x, 'o', validate.field_optional[x])
276 for x in validate.field_added:
277 doc_tbl_line(outfile, x, 'a', validate.field_added[x])
278 genout(outfile, field_example)
279
280 genout(outfile, "\n\nDefinitions in an enumeration group contain:\n")
281 doc_tbl_head(outfile, 1)
282 for x in validate.enum_required:
283 doc_tbl_line(outfile, x, 'r', validate.enum_required[x])
284 for x in validate.enum_optional:
285 doc_tbl_line(outfile, x, 'o', validate.enum_optional[x])
286 for x in validate.enum_added:
287 doc_tbl_line(outfile, x, 'a', validate.enum_added[x])
288
289 genout(
Eunchan Kim0bd75662020-04-24 10:21:18 -0700290 outfile, "\n\nThe list of registers may include single entry groups "
291 "to control the offset, open a window or generate registers:\n")
lowRISC Contributors802543a2019-08-31 12:12:56 +0100292 doc_tbl_head(outfile, 1)
293 for x in validate.list_optone:
294 doc_tbl_line(outfile, x, 'o', validate.list_optone[x])
295
296 genout(outfile, offset_intro)
297 genout(outfile, regwen_intro)
298
299 genout(outfile, window_intro)
300 doc_tbl_head(outfile, 1)
301 for x in validate.window_required:
302 doc_tbl_line(outfile, x, 'r', validate.window_required[x])
303 for x in validate.window_optional:
304 doc_tbl_line(outfile, x, 'o', validate.window_optional[x])
305 for x in validate.window_added:
306 doc_tbl_line(outfile, x, 'a', validate.window_added[x])
307
308 genout(outfile, multi_intro)
309 doc_tbl_head(outfile, 1)
310 for x in validate.multireg_required:
311 doc_tbl_line(outfile, x, 'r', validate.multireg_required[x])
312 for x in validate.multireg_optional:
313 doc_tbl_line(outfile, x, 'o', validate.multireg_optional[x])
314 for x in validate.multireg_added:
315 doc_tbl_line(outfile, x, 'a', validate.multireg_added[x])
316
317 genout(outfile, doc_tail)