]>
Commit | Line | Data |
---|---|---|
3a0adfc9 LE |
1 | # -*- Mode: Python -*- |
2 | # | |
3 | # Copyright (C) 2018 Red Hat, Inc. | |
4 | # | |
5 | # Authors: | |
6 | # Daniel P. Berrange <berrange@redhat.com> | |
7 | # Laszlo Ersek <lersek@redhat.com> | |
8 | # | |
9 | # This work is licensed under the terms of the GNU GPL, version 2 or | |
10 | # later. See the COPYING file in the top-level directory. | |
11 | ||
12 | ## | |
13 | # = Firmware | |
14 | ## | |
15 | ||
ffaee83b | 16 | { 'include' : 'machine.json' } |
3a0adfc9 LE |
17 | { 'include' : 'block-core.json' } |
18 | ||
19 | ## | |
20 | # @FirmwareOSInterface: | |
21 | # | |
22 | # Lists the firmware-OS interface types provided by various firmware | |
23 | # that is commonly used with QEMU virtual machines. | |
24 | # | |
25 | # @bios: Traditional x86 BIOS interface. For example, firmware built | |
26 | # from the SeaBIOS project usually provides this interface. | |
27 | # | |
28 | # @openfirmware: The interface is defined by the (historical) IEEE | |
29 | # 1275-1994 standard. Examples for firmware projects that | |
b2ce76a0 | 30 | # provide this interface are: OpenBIOS and SLOF. |
3a0adfc9 LE |
31 | # |
32 | # @uboot: Firmware interface defined by the U-Boot project. | |
33 | # | |
34 | # @uefi: Firmware interface defined by the UEFI specification. For | |
35 | # example, firmware built from the edk2 (EFI Development Kit II) | |
36 | # project usually provides this interface. | |
37 | # | |
38 | # Since: 3.0 | |
39 | ## | |
40 | { 'enum' : 'FirmwareOSInterface', | |
41 | 'data' : [ 'bios', 'openfirmware', 'uboot', 'uefi' ] } | |
42 | ||
43 | ## | |
44 | # @FirmwareDevice: | |
45 | # | |
46 | # Defines the device types that firmware can be mapped into. | |
47 | # | |
48 | # @flash: The firmware executable and its accompanying NVRAM file are to | |
49 | # be mapped into a pflash chip each. | |
50 | # | |
51 | # @kernel: The firmware is to be loaded like a Linux kernel. This is | |
52 | # similar to @memory but may imply additional processing that | |
53 | # is specific to the target architecture and machine type. | |
54 | # | |
55 | # @memory: The firmware is to be mapped into memory. | |
56 | # | |
57 | # Since: 3.0 | |
58 | ## | |
59 | { 'enum' : 'FirmwareDevice', | |
60 | 'data' : [ 'flash', 'kernel', 'memory' ] } | |
61 | ||
62 | ## | |
63 | # @FirmwareTarget: | |
64 | # | |
65 | # Defines the machine types that firmware may execute on. | |
66 | # | |
67 | # @architecture: Determines the emulation target (the QEMU system | |
68 | # emulator) that can execute the firmware. | |
69 | # | |
70 | # @machines: Lists the machine types (known by the emulator that is | |
71 | # specified through @architecture) that can execute the | |
72 | # firmware. Elements of @machines are supposed to be concrete | |
73 | # machine types, not aliases. Glob patterns are understood, | |
74 | # which is especially useful for versioned machine types. | |
75 | # (For example, the glob pattern "pc-i440fx-*" matches | |
76 | # "pc-i440fx-2.12".) On the QEMU command line, "-machine | |
77 | # type=..." specifies the requested machine type (but that | |
78 | # option does not accept glob patterns). | |
79 | # | |
80 | # Since: 3.0 | |
81 | ## | |
82 | { 'struct' : 'FirmwareTarget', | |
83 | 'data' : { 'architecture' : 'SysEmuTarget', | |
84 | 'machines' : [ 'str' ] } } | |
85 | ||
86 | ## | |
87 | # @FirmwareFeature: | |
88 | # | |
89 | # Defines the features that firmware may support, and the platform | |
90 | # requirements that firmware may present. | |
91 | # | |
92 | # @acpi-s3: The firmware supports S3 sleep (suspend to RAM), as defined | |
93 | # in the ACPI specification. On the "pc-i440fx-*" machine | |
94 | # types of the @i386 and @x86_64 emulation targets, S3 can be | |
95 | # enabled with "-global PIIX4_PM.disable_s3=0" and disabled | |
96 | # with "-global PIIX4_PM.disable_s3=1". On the "pc-q35-*" | |
97 | # machine types of the @i386 and @x86_64 emulation targets, S3 | |
98 | # can be enabled with "-global ICH9-LPC.disable_s3=0" and | |
99 | # disabled with "-global ICH9-LPC.disable_s3=1". | |
100 | # | |
101 | # @acpi-s4: The firmware supports S4 hibernation (suspend to disk), as | |
102 | # defined in the ACPI specification. On the "pc-i440fx-*" | |
103 | # machine types of the @i386 and @x86_64 emulation targets, S4 | |
104 | # can be enabled with "-global PIIX4_PM.disable_s4=0" and | |
105 | # disabled with "-global PIIX4_PM.disable_s4=1". On the | |
106 | # "pc-q35-*" machine types of the @i386 and @x86_64 emulation | |
107 | # targets, S4 can be enabled with "-global | |
108 | # ICH9-LPC.disable_s4=0" and disabled with "-global | |
109 | # ICH9-LPC.disable_s4=1". | |
110 | # | |
111 | # @amd-sev: The firmware supports running under AMD Secure Encrypted | |
112 | # Virtualization, as specified in the AMD64 Architecture | |
113 | # Programmer's Manual. QEMU command line options related to | |
114 | # this feature are documented in | |
115 | # "docs/amd-memory-encryption.txt". | |
116 | # | |
117 | # @enrolled-keys: The variable store (NVRAM) template associated with | |
118 | # the firmware binary has the UEFI Secure Boot | |
119 | # operational mode turned on, with certificates | |
120 | # enrolled. | |
121 | # | |
122 | # @requires-smm: The firmware requires the platform to emulate SMM | |
123 | # (System Management Mode), as defined in the AMD64 | |
124 | # Architecture Programmer's Manual, and in the Intel(R)64 | |
125 | # and IA-32 Architectures Software Developer's Manual. On | |
126 | # the "pc-q35-*" machine types of the @i386 and @x86_64 | |
127 | # emulation targets, SMM emulation can be enabled with | |
128 | # "-machine smm=on". (On the "pc-q35-*" machine types of | |
129 | # the @i386 emulation target, @requires-smm presents | |
130 | # further CPU requirements; one combination known to work | |
131 | # is "-cpu coreduo,-nx".) If the firmware is marked as | |
132 | # both @secure-boot and @requires-smm, then write | |
133 | # accesses to the pflash chip (NVRAM) that holds the UEFI | |
134 | # variable store must be restricted to code that executes | |
135 | # in SMM, using the additional option "-global | |
136 | # driver=cfi.pflash01,property=secure,value=on". | |
137 | # Furthermore, a large guest-physical address space | |
138 | # (comprising guest RAM, memory hotplug range, and 64-bit | |
139 | # PCI MMIO aperture), and/or a high VCPU count, may | |
140 | # present high SMRAM requirements from the firmware. On | |
141 | # the "pc-q35-*" machine types of the @i386 and @x86_64 | |
142 | # emulation targets, the SMRAM size may be increased | |
143 | # above the default 16MB with the "-global | |
144 | # mch.extended-tseg-mbytes=uint16" option. As a rule of | |
145 | # thumb, the default 16MB size suffices for 1TB of | |
146 | # guest-phys address space and a few tens of VCPUs; for | |
147 | # every further TB of guest-phys address space, add 8MB | |
148 | # of SMRAM. 48MB should suffice for 4TB of guest-phys | |
149 | # address space and 2-3 hundred VCPUs. | |
150 | # | |
151 | # @secure-boot: The firmware implements the software interfaces for UEFI | |
152 | # Secure Boot, as defined in the UEFI specification. Note | |
153 | # that without @requires-smm, guest code running with | |
154 | # kernel privileges can undermine the security of Secure | |
155 | # Boot. | |
156 | # | |
157 | # @verbose-dynamic: When firmware log capture is enabled, the firmware | |
158 | # logs a large amount of debug messages, which may | |
159 | # impact boot performance. With log capture disabled, | |
160 | # there is no boot performance impact. On the | |
161 | # "pc-i440fx-*" and "pc-q35-*" machine types of the | |
162 | # @i386 and @x86_64 emulation targets, firmware log | |
163 | # capture can be enabled with the QEMU command line | |
164 | # options "-chardev file,id=fwdebug,path=LOGFILEPATH | |
165 | # -device isa-debugcon,iobase=0x402,chardev=fwdebug". | |
166 | # @verbose-dynamic is mutually exclusive with | |
167 | # @verbose-static. | |
168 | # | |
169 | # @verbose-static: The firmware unconditionally produces a large amount | |
170 | # of debug messages, which may impact boot performance. | |
171 | # This feature may typically be carried by certain UEFI | |
172 | # firmware for the "virt-*" machine types of the @arm | |
173 | # and @aarch64 emulation targets, where the debug | |
174 | # messages are written to the first (always present) | |
175 | # PL011 UART. @verbose-static is mutually exclusive | |
176 | # with @verbose-dynamic. | |
177 | # | |
178 | # Since: 3.0 | |
179 | ## | |
180 | { 'enum' : 'FirmwareFeature', | |
181 | 'data' : [ 'acpi-s3', 'acpi-s4', 'amd-sev', 'enrolled-keys', | |
182 | 'requires-smm', 'secure-boot', 'verbose-dynamic', | |
183 | 'verbose-static' ] } | |
184 | ||
185 | ## | |
186 | # @FirmwareFlashFile: | |
187 | # | |
188 | # Defines common properties that are necessary for loading a firmware | |
189 | # file into a pflash chip. The corresponding QEMU command line option is | |
190 | # "-drive file=@filename,format=@format". Note however that the | |
191 | # option-argument shown here is incomplete; it is completed under | |
192 | # @FirmwareMappingFlash. | |
193 | # | |
194 | # @filename: Specifies the filename on the host filesystem where the | |
195 | # firmware file can be found. | |
196 | # | |
197 | # @format: Specifies the block format of the file pointed-to by | |
198 | # @filename, such as @raw or @qcow2. | |
199 | # | |
200 | # Since: 3.0 | |
201 | ## | |
202 | { 'struct' : 'FirmwareFlashFile', | |
203 | 'data' : { 'filename' : 'str', | |
204 | 'format' : 'BlockdevDriver' } } | |
205 | ||
206 | ## | |
207 | # @FirmwareMappingFlash: | |
208 | # | |
209 | # Describes loading and mapping properties for the firmware executable | |
210 | # and its accompanying NVRAM file, when @FirmwareDevice is @flash. | |
211 | # | |
212 | # @executable: Identifies the firmware executable. The firmware | |
213 | # executable may be shared by multiple virtual machine | |
e33763be MA |
214 | # definitions. The preferred corresponding QEMU command |
215 | # line options are | |
216 | # -drive if=none,id=pflash0,readonly=on,file=@executable.@filename,format=@executable.@format | |
217 | # -machine pflash0=pflash0 | |
218 | # or equivalent -blockdev instead of -drive. | |
219 | # With QEMU versions older than 4.0, you have to use | |
220 | # -drive if=pflash,unit=0,readonly=on,file=@executable.@filename,format=@executable.@format | |
3a0adfc9 LE |
221 | # |
222 | # @nvram-template: Identifies the NVRAM template compatible with | |
223 | # @executable. Management software instantiates an | |
224 | # individual copy -- a specific NVRAM file -- from | |
225 | # @nvram-template.@filename for each new virtual | |
226 | # machine definition created. @nvram-template.@filename | |
227 | # itself is never mapped into virtual machines, only | |
228 | # individual copies of it are. An NVRAM file is | |
229 | # typically used for persistently storing the | |
230 | # non-volatile UEFI variables of a virtual machine | |
e33763be MA |
231 | # definition. The preferred corresponding QEMU |
232 | # command line options are | |
233 | # -drive if=none,id=pflash1,readonly=off,file=FILENAME_OF_PRIVATE_NVRAM_FILE,format=@nvram-template.@format | |
234 | # -machine pflash1=pflash1 | |
235 | # or equivalent -blockdev instead of -drive. | |
236 | # With QEMU versions older than 4.0, you have to use | |
237 | # -drive if=pflash,unit=1,readonly=off,file=FILENAME_OF_PRIVATE_NVRAM_FILE,format=@nvram-template.@format | |
3a0adfc9 LE |
238 | # |
239 | # Since: 3.0 | |
240 | ## | |
241 | { 'struct' : 'FirmwareMappingFlash', | |
242 | 'data' : { 'executable' : 'FirmwareFlashFile', | |
243 | 'nvram-template' : 'FirmwareFlashFile' } } | |
244 | ||
245 | ## | |
246 | # @FirmwareMappingKernel: | |
247 | # | |
248 | # Describes loading and mapping properties for the firmware executable, | |
249 | # when @FirmwareDevice is @kernel. | |
250 | # | |
251 | # @filename: Identifies the firmware executable. The firmware executable | |
252 | # may be shared by multiple virtual machine definitions. The | |
253 | # corresponding QEMU command line option is "-kernel | |
254 | # @filename". | |
255 | # | |
256 | # Since: 3.0 | |
257 | ## | |
258 | { 'struct' : 'FirmwareMappingKernel', | |
259 | 'data' : { 'filename' : 'str' } } | |
260 | ||
261 | ## | |
262 | # @FirmwareMappingMemory: | |
263 | # | |
264 | # Describes loading and mapping properties for the firmware executable, | |
265 | # when @FirmwareDevice is @memory. | |
266 | # | |
267 | # @filename: Identifies the firmware executable. The firmware executable | |
268 | # may be shared by multiple virtual machine definitions. The | |
269 | # corresponding QEMU command line option is "-bios | |
270 | # @filename". | |
271 | # | |
272 | # Since: 3.0 | |
273 | ## | |
274 | { 'struct' : 'FirmwareMappingMemory', | |
275 | 'data' : { 'filename' : 'str' } } | |
276 | ||
277 | ## | |
278 | # @FirmwareMapping: | |
279 | # | |
280 | # Provides a discriminated structure for firmware to describe its | |
281 | # loading / mapping properties. | |
282 | # | |
283 | # @device: Selects the device type that the firmware must be mapped | |
284 | # into. | |
285 | # | |
286 | # Since: 3.0 | |
287 | ## | |
288 | { 'union' : 'FirmwareMapping', | |
289 | 'base' : { 'device' : 'FirmwareDevice' }, | |
290 | 'discriminator' : 'device', | |
291 | 'data' : { 'flash' : 'FirmwareMappingFlash', | |
292 | 'kernel' : 'FirmwareMappingKernel', | |
293 | 'memory' : 'FirmwareMappingMemory' } } | |
294 | ||
295 | ## | |
296 | # @Firmware: | |
297 | # | |
298 | # Describes a firmware (or a firmware use case) to management software. | |
299 | # | |
300 | # It is possible for multiple @Firmware elements to match the search | |
301 | # criteria of management software. Applications thus need rules to pick | |
302 | # one of the many matches, and users need the ability to override distro | |
303 | # defaults. | |
304 | # | |
305 | # It is recommended to create firmware JSON files (each containing a | |
306 | # single @Firmware root element) with a double-digit prefix, for example | |
307 | # "50-ovmf.json", "50-seabios-256k.json", etc, so they can be sorted in | |
308 | # predictable order. The firmware JSON files should be searched for in | |
309 | # three directories: | |
310 | # | |
311 | # - /usr/share/qemu/firmware -- populated by distro-provided firmware | |
312 | # packages (XDG_DATA_DIRS covers | |
313 | # /usr/share by default), | |
314 | # | |
315 | # - /etc/qemu/firmware -- exclusively for sysadmins' local additions, | |
316 | # | |
317 | # - $XDG_CONFIG_HOME/qemu/firmware -- exclusively for per-user local | |
318 | # additions (XDG_CONFIG_HOME | |
319 | # defaults to $HOME/.config). | |
320 | # | |
321 | # Top-down, the list of directories goes from general to specific. | |
322 | # | |
323 | # Management software should build a list of files from all three | |
324 | # locations, then sort the list by filename (i.e., last pathname | |
325 | # component). Management software should choose the first JSON file on | |
326 | # the sorted list that matches the search criteria. If a more specific | |
327 | # directory has a file with same name as a less specific directory, then | |
328 | # the file in the more specific directory takes effect. If the more | |
329 | # specific file is zero length, it hides the less specific one. | |
330 | # | |
331 | # For example, if a distro ships | |
332 | # | |
333 | # - /usr/share/qemu/firmware/50-ovmf.json | |
334 | # | |
335 | # - /usr/share/qemu/firmware/50-seabios-256k.json | |
336 | # | |
337 | # then the sysadmin can prevent the default OVMF being used at all with | |
338 | # | |
339 | # $ touch /etc/qemu/firmware/50-ovmf.json | |
340 | # | |
341 | # The sysadmin can replace/alter the distro default OVMF with | |
342 | # | |
343 | # $ vim /etc/qemu/firmware/50-ovmf.json | |
344 | # | |
345 | # or they can provide a parallel OVMF with higher priority | |
346 | # | |
347 | # $ vim /etc/qemu/firmware/10-ovmf.json | |
348 | # | |
349 | # or they can provide a parallel OVMF with lower priority | |
350 | # | |
351 | # $ vim /etc/qemu/firmware/99-ovmf.json | |
352 | # | |
353 | # @description: Provides a human-readable description of the firmware. | |
354 | # Management software may or may not display @description. | |
355 | # | |
356 | # @interface-types: Lists the types of interfaces that the firmware can | |
357 | # expose to the guest OS. This is a non-empty, ordered | |
358 | # list; entries near the beginning of @interface-types | |
359 | # are considered more native to the firmware, and/or | |
360 | # to have a higher quality implementation in the | |
361 | # firmware, than entries near the end of | |
362 | # @interface-types. | |
363 | # | |
364 | # @mapping: Describes the loading / mapping properties of the firmware. | |
365 | # | |
366 | # @targets: Collects the target architectures (QEMU system emulators) | |
367 | # and their machine types that may execute the firmware. | |
368 | # | |
369 | # @features: Lists the features that the firmware supports, and the | |
370 | # platform requirements it presents. | |
371 | # | |
372 | # @tags: A list of auxiliary strings associated with the firmware for | |
373 | # which @description is not appropriate, due to the latter's | |
374 | # possible exposure to the end-user. @tags serves development and | |
375 | # debugging purposes only, and management software shall | |
376 | # explicitly ignore it. | |
377 | # | |
378 | # Since: 3.0 | |
379 | # | |
380 | # Examples: | |
381 | # | |
382 | # { | |
383 | # "description": "SeaBIOS", | |
384 | # "interface-types": [ | |
385 | # "bios" | |
386 | # ], | |
387 | # "mapping": { | |
388 | # "device": "memory", | |
389 | # "filename": "/usr/share/seabios/bios-256k.bin" | |
390 | # }, | |
391 | # "targets": [ | |
392 | # { | |
393 | # "architecture": "i386", | |
394 | # "machines": [ | |
395 | # "pc-i440fx-*", | |
396 | # "pc-q35-*" | |
397 | # ] | |
398 | # }, | |
399 | # { | |
400 | # "architecture": "x86_64", | |
401 | # "machines": [ | |
402 | # "pc-i440fx-*", | |
403 | # "pc-q35-*" | |
404 | # ] | |
405 | # } | |
406 | # ], | |
407 | # "features": [ | |
408 | # "acpi-s3", | |
409 | # "acpi-s4" | |
410 | # ], | |
411 | # "tags": [ | |
412 | # "CONFIG_BOOTSPLASH=n", | |
413 | # "CONFIG_ROM_SIZE=256", | |
414 | # "CONFIG_USE_SMM=n" | |
415 | # ] | |
416 | # } | |
417 | # | |
418 | # { | |
419 | # "description": "OVMF with SB+SMM, empty varstore", | |
420 | # "interface-types": [ | |
421 | # "uefi" | |
422 | # ], | |
423 | # "mapping": { | |
424 | # "device": "flash", | |
425 | # "executable": { | |
426 | # "filename": "/usr/share/OVMF/OVMF_CODE.secboot.fd", | |
427 | # "format": "raw" | |
428 | # }, | |
429 | # "nvram-template": { | |
430 | # "filename": "/usr/share/OVMF/OVMF_VARS.fd", | |
431 | # "format": "raw" | |
432 | # } | |
433 | # }, | |
434 | # "targets": [ | |
435 | # { | |
436 | # "architecture": "x86_64", | |
437 | # "machines": [ | |
438 | # "pc-q35-*" | |
439 | # ] | |
440 | # } | |
441 | # ], | |
442 | # "features": [ | |
443 | # "acpi-s3", | |
444 | # "amd-sev", | |
445 | # "requires-smm", | |
446 | # "secure-boot", | |
447 | # "verbose-dynamic" | |
448 | # ], | |
449 | # "tags": [ | |
450 | # "-a IA32", | |
451 | # "-a X64", | |
452 | # "-p OvmfPkg/OvmfPkgIa32X64.dsc", | |
453 | # "-t GCC48", | |
454 | # "-b DEBUG", | |
455 | # "-D SMM_REQUIRE", | |
456 | # "-D SECURE_BOOT_ENABLE", | |
457 | # "-D FD_SIZE_4MB" | |
458 | # ] | |
459 | # } | |
460 | # | |
461 | # { | |
462 | # "description": "OVMF with SB+SMM, SB enabled, MS certs enrolled", | |
463 | # "interface-types": [ | |
464 | # "uefi" | |
465 | # ], | |
466 | # "mapping": { | |
467 | # "device": "flash", | |
468 | # "executable": { | |
469 | # "filename": "/usr/share/OVMF/OVMF_CODE.secboot.fd", | |
470 | # "format": "raw" | |
471 | # }, | |
472 | # "nvram-template": { | |
473 | # "filename": "/usr/share/OVMF/OVMF_VARS.secboot.fd", | |
474 | # "format": "raw" | |
475 | # } | |
476 | # }, | |
477 | # "targets": [ | |
478 | # { | |
479 | # "architecture": "x86_64", | |
480 | # "machines": [ | |
481 | # "pc-q35-*" | |
482 | # ] | |
483 | # } | |
484 | # ], | |
485 | # "features": [ | |
486 | # "acpi-s3", | |
487 | # "amd-sev", | |
488 | # "enrolled-keys", | |
489 | # "requires-smm", | |
490 | # "secure-boot", | |
491 | # "verbose-dynamic" | |
492 | # ], | |
493 | # "tags": [ | |
494 | # "-a IA32", | |
495 | # "-a X64", | |
496 | # "-p OvmfPkg/OvmfPkgIa32X64.dsc", | |
497 | # "-t GCC48", | |
498 | # "-b DEBUG", | |
499 | # "-D SMM_REQUIRE", | |
500 | # "-D SECURE_BOOT_ENABLE", | |
501 | # "-D FD_SIZE_4MB" | |
502 | # ] | |
503 | # } | |
504 | # | |
505 | # { | |
506 | # "description": "UEFI firmware for ARM64 virtual machines", | |
507 | # "interface-types": [ | |
508 | # "uefi" | |
509 | # ], | |
510 | # "mapping": { | |
511 | # "device": "flash", | |
512 | # "executable": { | |
513 | # "filename": "/usr/share/AAVMF/AAVMF_CODE.fd", | |
514 | # "format": "raw" | |
515 | # }, | |
516 | # "nvram-template": { | |
517 | # "filename": "/usr/share/AAVMF/AAVMF_VARS.fd", | |
518 | # "format": "raw" | |
519 | # } | |
520 | # }, | |
521 | # "targets": [ | |
522 | # { | |
523 | # "architecture": "aarch64", | |
524 | # "machines": [ | |
525 | # "virt-*" | |
526 | # ] | |
527 | # } | |
528 | # ], | |
529 | # "features": [ | |
530 | # | |
531 | # ], | |
532 | # "tags": [ | |
533 | # "-a AARCH64", | |
534 | # "-p ArmVirtPkg/ArmVirtQemu.dsc", | |
535 | # "-t GCC48", | |
536 | # "-b DEBUG", | |
537 | # "-D DEBUG_PRINT_ERROR_LEVEL=0x80000000" | |
538 | # ] | |
539 | # } | |
540 | ## | |
541 | { 'struct' : 'Firmware', | |
542 | 'data' : { 'description' : 'str', | |
543 | 'interface-types' : [ 'FirmwareOSInterface' ], | |
544 | 'mapping' : 'FirmwareMapping', | |
545 | 'targets' : [ 'FirmwareTarget' ], | |
546 | 'features' : [ 'FirmwareFeature' ], | |
547 | 'tags' : [ 'str' ] } } |