Hi Peter, On Sat, 4 Feb 2023 at 02:36, Peter Robinson <pbrobinson@xxxxxxxxx> wrote: > > Hi Simon, > > Does it make sense to devise something that is compatible with the > kernel's pstore [1] mechanism? Possibly...can you please be a little more specific? Regards, Simon > > Peter > > [1] https://lwn.net/Articles/434821/ > > On Sat, Feb 4, 2023 at 12:20 AM Simon Glass <sjg@xxxxxxxxxxxx> wrote: > > > > A common way to detect problems in firmware is to collect logs from > > the firmware, then pass them to the OS for storage and analysis. > > > > Logs can take the form of simple text output, or structured logs where the > > filename and line number, etc. are provided. Timestamps can sometimes be > > useful, too. > > > > Ideally the log can be displayed as simple ASCII without always needing > > a special program to read it. > > > > The firmware consists of various boot phases, any of which can contribute > > log information. It is assumed that these logs are not interleaved, i.e. > > that the phases run one after the other. > > > > The final boot phase (before the OS) is responsible for collecting the > > logs, e.g. from a Transfer List, and placing them in the devicetree. > > > > This binding collects the logs as individual log@n subnodes within a > > /chosen/logs node. > > > > If firmware phases use the devicetree to pass logs between each other, > > then the /chosen node should still be used. The /options node is not > > supported. Subsequent phases must be sure to use the next numbered > > log@n node. > > > > If the log data is sitting in memory somewhere, it is possible to point > > to it, rather than copying the data into a property. For large logs this > > may be more efficient. It must end with a NUL character, so the total > > space for actual log data is one byte less than the allocated size. > > > > If something goes wrong and an incomplete log record is emitted, then the > > next record may appear to be part of it, since there is no LF or ETX > > character at the end of the previous record. > > > > The intent with this binding is to provide a Linux driver which can > > provide access to the log data after booting is complete. > > > > Other things not considered: > > - signalling overflow of a log buffer > > - circular log buffers > > - a single unified log buffer with inline ASCII characters to indicate the > > phase and project > > - log records that contain multiple lines of text > > > > Signed-off-by: Simon Glass <sjg@xxxxxxxxxxxx> > > --- > > > > dtschema/schemas/chosen.yaml | 3 + > > dtschema/schemas/log.yaml | 176 +++++++++++++++++++++++++++++++++++ > > dtschema/schemas/logs.yaml | 30 ++++++ > > test/logs.dts | 47 ++++++++++ > > 4 files changed, 256 insertions(+) > > create mode 100644 dtschema/schemas/log.yaml > > create mode 100644 dtschema/schemas/logs.yaml > > create mode 100644 test/logs.dts > > > > diff --git a/dtschema/schemas/chosen.yaml b/dtschema/schemas/chosen.yaml > > index 86194dd..46cc9fb 100644 > > --- a/dtschema/schemas/chosen.yaml > > +++ b/dtschema/schemas/chosen.yaml > > @@ -236,6 +236,9 @@ properties: > > system. > > > > patternProperties: > > + '^logs$': > > + $ref: logs.yaml# > > + > > "^framebuffer": true > > > > additionalProperties: false > > diff --git a/dtschema/schemas/log.yaml b/dtschema/schemas/log.yaml > > new file mode 100644 > > index 0000000..5218234 > > --- /dev/null > > +++ b/dtschema/schemas/log.yaml > > @@ -0,0 +1,176 @@ > > +# SPDX-License-Identifier: BSD-2-Clause > > +# Copyright 2023 Google LLC > > +%YAML 1.2 > > +--- > > +$id: http://devicetree.org/schemas/log.yaml# > > +$schema: http://devicetree.org/meta-schemas/core.yaml# > > + > > +title: Log-output binding > > + > > +maintainers: > > + - Simon Glass <sjg@xxxxxxxxxxxx> > > + > > +description: > > + This holds a log file or console dump created by a single phase of the boot. > > + It typically consists of plain ASCII text, but it is also possible to > > + add metadata like files and line numbers. > > + > > + Each log node has a hex unit address which indicates the order of progress > > + through the boot phases. The first node must be log@0, followed by > > + log@1, etc. > > + > > +select: false > > + > > +properties: > > + reg: > > + description: > > + Defines a unique log ID for the log represented by the log node. > > + > > + boot-phase: > > + $ref: types.yaml#/definitions/string > > + description: | > > + Indicates the phase of boot which produced this log: > > + > > + - pre-sram: Before SRAM is available > > + - verify: Verification step, which decides which of the available images > > + should be run next > > + - pre-ram: Sets up SDRAM > > + - some-ram: After SDRAM is working but before all of it is available. > > + Some RAM is available but it is limited (e.g. it may be split into > > + two pieces by the location of the running program) because the > > + program code is not yet relocated out of the way. > > + - loader: OS loader, typically the final firmware step > > + > > + pattern: "^pre-sram|verify|pre-ram|some-ram|loader$" > > + > > + project: > > + $ref: types.yaml#/definitions/string > > + description: > > + Indicates the name of the project which produced this log > > + > > + pattern: "^U-Boot|TF-A" > > + > > + time-format: > > + $ref: types.yaml#/definitions/string > > + description: | > > + Indicates the time format used by the log. Options are: > > + > > + usec - a integer number of microseconds since reset was released, > > + expressed in ASCII, e.g. "123" > > + > > + pattern: "^usec$" > > + > > + text-start: > > + oneOf: > > + - $ref: types.yaml#/definitions/uint32 > > + - $ref: types.yaml#/definitions/uint64 > > + description: > > + These properties hold the physical start and end address of the log text > > + if the 'text' property is not used. > > + > > + Note that text-start is inclusive, but text-end is exclusive. > > + > > + The text must be terminated with a NUL character. > > + > > + text-end: > > + oneOf: > > + - $ref: types.yaml#/definitions/uint32 > > + - $ref: types.yaml#/definitions/uint64 > > + description: > > + These properties hold the physical start and end address of the log text > > + if the 'text' property is not used. > > + > > + Note that text-start is inclusive, but text-end is exclusive. > > + > > + The text must be terminated with a NUL character. > > + > > + text: > > + $ref: types.yaml#/definitions/string > > + description: | > > + Contains the log text, if it is not referred to by text-start / text-end. > > + > > + The format is ASCII with US and SOT used to indicate optional fields: > > + > > + [timestamp<US>][level[:category[:filename[:line[:function]]]]]<SOT>]message[<LF>|<ETX>] > > + > > + where: > > + > > + timestamp is the timestamp, according to time-format > > + > > + level is the single-digit log level: > > + 0 - emergency (program is unstable) > > + 1 - alert (action must be taken immediately) > > + 2 - crit (critical conditions) > > + 3 - err (error that prevents something from working > > + 4 - warning (may prevent optimal operation) > > + 5 - notice (normal but significant condition, printf()) > > + 6 - info (general information message) > > + 7 - debug (basic debug-level message) > > + 8 - debug content (debug message showing full message content) > > + 9 - debug I/O (debug message showing hardware I/O access) > > + > > + category is the category name which is project-dependent > > + > > + filename is the relative filename (__FILE__ in C) > > + > > + line is the line number starting from 1 (__LINE__ in C) > > + > > + function is the function name (__func__ in C) > > + > > + message is the message string, which may not contain control > > + characters (beyond those listed above) except for HT and LF. DEL and CR > > + are not permitted. > > + > > + The timestamp is present only if US is in the string. > > + > > + The fields before <SOT> are all optional, but must be listed in order. > > + To omit a field in the middle, use an empty string between two colons. > > + To omit a field at the end, just leave it out along with the colon before > > + it. > > + > > + Typically LF is used as a line delimiter, but if a record does not > > + end with a newline, ETX can be used. This indicates that it is a new > > + log record but without a newline between them. Often (but not always) > > + the 'continuation' does not include the US and SOT information. > > + > > + A log record without a LF or ETX terminator is considered invalid, even > > + if it is the final record. > > + > > + Examples: > > + > > + 123<US>5:tpm:lib/tpm.c:334:tpm_init<SOT>TPM starting...<LF> > > + 23<US>Hello<LF> > > + 2:boot:lib/panic.c:84:panic<SOT>Memory training failed<LF> > > + 7:mmc:::mmc_bind<SOT>Cannot create block device<LF> > > + Net: eth0: host_lo, eth1: host_enp1s0<ETX> > > + > > + ASCII characters: > > + > > + SOT - 0x2 - indicates the start of the message. This is optional if > > + the record has nothing but a message > > + ETX - 0x3 - indicates the end of a log record (without new line) > > + LF - 0xa - indicates the end of a log record (and new line) > > + US - 0x1f - indicates the end of the timestamp (and that it is present > > + in the record) > > + > > + The above format is intended to be unambiguous, while still being fairly > > + readable it just shown on a terminal with all control characters except > > + LF dropped. The CR character is not permitted since it is not needed to > > + signal an end of line and it avoids worrying about what <CR><LF> actually > > + means. > > + > > + The text size is determined by the property size. The last byte must be > > + a NUL character. > > + > > +required: > > + - boot-phase > > + - project > > + > > +anyOf: > > + - required: > > + - text > > + - required: > > + - text-start > > + - text-end > > + > > +additionalProperties: false > > diff --git a/dtschema/schemas/logs.yaml b/dtschema/schemas/logs.yaml > > new file mode 100644 > > index 0000000..76ba2b0 > > --- /dev/null > > +++ b/dtschema/schemas/logs.yaml > > @@ -0,0 +1,30 @@ > > +# SPDX-License-Identifier: BSD-2-Clause > > +# Copyright 2023 Google LLC > > +%YAML 1.2 > > +--- > > +$id: http://devicetree.org/schemas/logs.yaml# > > +$schema: http://devicetree.org/meta-schemas/core.yaml# > > + > > +title: Log information collected during firmware execution > > + > > +maintainers: > > + - Simon Glass <sjg@xxxxxxxxxxxx> > > + > > +description: > > + This holds a set of logs build up during booting of the machine. The > > + collection of logs is described in the "/logs" node. This node in turn > > + contains a number of subnodes representing individual log output from > > + different boot phases. > > + > > +properties: > > + '#address-cells': > > + const: 1 > > + > > + '#size-cells': > > + const: 0 > > + > > +patternProperties: > > + '^log@[0-9a-f]+$': > > + $ref: log.yaml# > > + > > +additionalProperties: false > > diff --git a/test/logs.dts b/test/logs.dts > > new file mode 100644 > > index 0000000..7d044df > > --- /dev/null > > +++ b/test/logs.dts > > @@ -0,0 +1,47 @@ > > +// SPDX-License-Identifier: BSD-2-Clause > > +// Copyright 2023 Google LLC > > + > > +// Used to validate the "logs" node and its child "log" nodes > > + > > +// dtc -O dtb -o test.dtb test/bootphases.dts && tools/dt-validate -s test/schemas -m test.dtb > > + > > + > > +/dts-v1/; > > + > > +/ { > > + model = "none"; > > + compatible = "foo"; > > + > > + #address-cells = <1>; > > + #size-cells = <1>; > > + > > + chosen { > > + logs { > > + #address-cells = <1>; > > + #size-cells = <0>; > > + > > + log@0 { > > + reg = <0>; > > + boot-phase = "pre-ram"; > > + project = "U-Boot"; > > + text = "\nU-Boot SPL 2023.01 (Feb 03 2023 - 14:45:39 -0700)\nTrying to boot from sandbox_image\nTrying to boot from sandbox_file\n"; > > + }; > > + > > + log@1 { > > + reg = <1>; > > + boot-phase = "loader"; > > + project = "U-Boot"; > > + time-format = "usec"; > > + text = "\n\n123\x1f2:boot:lib/display_options.c:43:display_options\x02U-Boot 2023.01 (Feb 03 2023 - 14:45:39 -0700)\n\nReset Status: COLD\nModel: sandbox\nDRAM: 256 MiB\n"; > > + }; > > + > > + log@2 { > > + reg = <2>; > > + boot-phase = "pre-ram"; > > + project = "TF-A"; > > + text-start = <0x103000>; > > + text-end = <0x107000>; > > + }; > > + }; > > + }; > > +}; > > -- > > 2.39.1.519.gcb327c4b5f-goog > >