From fe07dc98b924b9d831c27b2573d6b65e89343177 Mon Sep 17 00:00:00 2001 From: Derek Hower Date: Fri, 12 Jul 2024 14:34:15 -0700 Subject: [PATCH 1/2] Add CSR schema docs --- arch/README.adoc | 2 +- arch/csr/mstatus.yaml | 2 +- schemas/csr_schema.json | 70 ++++++++++++++++++++++++++++++----------- 3 files changed, 54 insertions(+), 20 deletions(-) diff --git a/arch/README.adoc b/arch/README.adoc index 75d07d4a3..81741bf17 100644 --- a/arch/README.adoc +++ b/arch/README.adoc @@ -234,6 +234,6 @@ CSR fields are given a type, which _does not_ necessarily correspond to the WARL | *RW-RH* | Read-write, only a restricted set of values are allowed, and hardware updates the field |=== -In many cases, the values of CSR and/or CSR field data are configuration dependent. Some of that is covered directly by the data model (_e.g._, with `location_rv32`, `location_rv64`), but some cases are too complex to express with YAML. For this reason, many of the keys can be specified as IDL functions. See the schema documentation and examples in the `arch/csr` folder for more information. +In many cases, the values of CSR and/or CSR field data are configuration dependent. Some of that is covered directly by the data model (_e.g._, with `location_rv32`, `location_rv64`), but some cases are too complex to express with YAML. For this reason, many of the keys can be specified as IDL functions. See the xref:csr/schema.adoc[schema] documentation and examples in the `arch/csr` folder for more information. Some keys that only apply to certain CSRs are not shown above. diff --git a/arch/csr/mstatus.yaml b/arch/csr/mstatus.yaml index 1946daf71..889434d0c 100644 --- a/arch/csr/mstatus.yaml +++ b/arch/csr/mstatus.yaml @@ -10,7 +10,7 @@ mstatus: # MXLEN cannot change dynamically, so this will be converted to an integer # in the genrated, configuration-dependent spec length: MXLEN - + description: The mstatus register tracks and controls the hart's current operating state. definedBy: I fields: diff --git a/schemas/csr_schema.json b/schemas/csr_schema.json index b1a71751f..5b5be2907 100644 --- a/schemas/csr_schema.json +++ b/schemas/csr_schema.json @@ -186,7 +186,7 @@ }, "csr_register": { "type": "object", - "required": ["long_name", "description", "address", "priv_mode", "definedBy"], + "required": ["long_name", "length", "description", "priv_mode", "definedBy"], "properties": { "name": { @@ -199,18 +199,31 @@ "description": "When a CSR is only defined in RV32, or RV64, the base that defines it. When defined in both, this field should be absent." }, "long_name": { - "type": "string" + "type": "string", + "description": "Descriptive name for the CSR" }, "description": { - "type": "string" + "type": "string", + "description": "A full Asciidoc description of the CSR, indended to be used as documentation." }, "definedBy": { - "type": "string", - "pattern": "^([A-WY]|([SXZ][a-z]+))$" + "$ref": "schema_defs.json#/$defs/extension_name", + "description": "The extension that defines this CSR." }, "address": { "type": "integer", - "description": "CSR address" + "minValue": 0, + "maxValue": 4095, + "description": "Address of the CSR, as given to the CSR access instructions of the `Zicsr` extension" + }, + "indirect_address": { + "type": "integer", + "description": "Indirect sddress of the CSR, as given to the indirect CSRs of the `Smcsrind`/`Sscdrind` extensions" + }, + "indirect": { + "type": "boolean", + "default": false, + "description": "Whether or not the CSR is accessible via an indirect address" }, "virtual_address": true, "$comment": "Conditionally required; see below", "priv_mode": { @@ -231,6 +244,7 @@ "$ref": "#/$defs/csr_field" } }, + "description": "fields of this CSR", "additionalProperties": false }, "sw_read()": { @@ -241,20 +255,40 @@ "additionalProperties": false, "$comment": "If mode is VS, then there must be a virtual_address field", - "if": { - "properties": { - "priv_mode": { "const": "VS" } - } - }, - "then": { - "properties": { - "virtual_address": { - "type": "number", - "description": "Address of the CSR viewed from VS-mode" + "allOf": [ + { + "if": { + "properties": { + "priv_mode": { "const": "VS" } + } + }, + "then": { + "properties": { + "virtual_address": { + "type": "number", + "description": "Address of the CSR viewed from VS-mode" + } + }, + "required": ["virtual_address"] } }, - "required": ["virtual_address"] - } + { + "oneOf": [ + { + "properties": { + "indirect": { "const": false } + }, + "required": ["address"] + }, + { + "properties": { + "indirect": { "const": true } + }, + "required": ["indirect_address"] + } + ] + } + ] } }, From 25a73f5b42dd079fab57e7861b59a57e9521a27b Mon Sep 17 00:00:00 2001 From: Derek Hower Date: Fri, 12 Jul 2024 14:35:20 -0700 Subject: [PATCH 2/2] Add the schema doc --- arch/csr/schema.adoc | 221 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 221 insertions(+) create mode 100644 arch/csr/schema.adoc diff --git a/arch/csr/schema.adoc b/arch/csr/schema.adoc new file mode 100644 index 000000000..4d4230ecb --- /dev/null +++ b/arch/csr/schema.adoc @@ -0,0 +1,221 @@ += Schema for CSR defintions + +A CSR defintion is a mapping (_i.e._, hash, dictionary, ...) containing exactly one key +equal to the CSR name, and pointing to an object specified below. For example: + +.CSR object +[source,yaml] +---- +mstatus: + long_name: Machine status + # ... +---- + +The CSR object has the following information: + +Long name:: + +[IMPORTANT] long_name is a required key + +|=== +| *key* | long_name +| *value type* | String +| *description* | A descriptive name for the CSR +|=== + +Description:: + +[IMPORTANT] description is a required key + +|=== +| *key* | description +| *value type* | String +| *description* | A full Asciidoc description of the CSR, indended to be used as documentation. +|=== + +Defining extension:: + +[IMPORTANT] definedBy is a required key + +|=== +| *key* | definedBy +| *value type* | String +| *description* | The extension that defines this CSR. +|=== + +Privilege Mode:: + +[IMPORTANT] `priv_mode` is a required key + +|=== +| *key* | priv_mode +| *value type* | one of ["M", "S", "U", or "VS"] +| *description* | The least-privilege mode that can access this CSR +|=== + +Length:: + +[IMPORTANT] `length` is a required key + +|=== +| *key* | length +| *value type* | one of [32, 64, "MXLEN", "SXLEN", "VSXLEN"] +| *description* | Length, in bits, of the CSR. Can either be a 32, 64 or MXLEN, SXLEN, VSXLEN to indicate that is is equal to the effective XLEN for a given mode +|=== + +Indirect:: + +|=== +| *key* | indirect +| *value type* | Boolean +| *default* | false +| *description* | Whether or not the CSR is accessible through the indirect CSRs of the `Smcdrind`/`Sscdrind` extensions. +|=== + +Address:: + +[IMPORTANT] `address` is a required key *unless* the CSR is only accessible through the indirect registers of the `Smcsrind`/`Sscrind` extensions, in which case `indirect_address` is required. Both `address` and `indirect_address` may be specified when a CSR is accessible directly and indirectly. + +|=== +| *key* | address +| *value type* | Integer between 0-4095, inclusive +| *description* | Address of the CSR, as given to the CSR access instructions of the `Zicsr` extension +|=== + +|=== +| *key* | indirect_address +| *value type* | Integer +| *description* | Indirect sddress of the CSR, as given to the indirect CSRs of the `Smcsrind`/`Sscdrind` extensions +|=== + +Virtual Address:: + +[IMPORTANT] `virtual_address` is required when the `priv_mode` of the CSR is VS. + +|=== +| *key* | virtual_address +| *value type* | Integer between 0-4095, inclusive +| *description* | Address of the CSR viewed from VS-mode +|=== + +Custom Software Read:: + +|=== +| *key* | sw_read() +| *value type* | String of IDL code that returns a read value +| *description* | Function that returns the value of the CSR when read by software (i.e., a Zicsr instruction). If not specified, the value last written (possibly filtered through field `write(csr_value)` functions) is returned. +|=== + +Fields:: + +[IMPORTANT] `fields` is a required key + +|=== +| *key* | fields +| *value type* | Mapping of field name (String) to field data (Object) +| *description* | Function that returns the value of the CSR when read by software (i.e., a Zicsr instruction). If not specified, the value last written (possibly filtered through field `write(csr_value)` functions) is returned. +|=== + +== Schema for CSR fields + +A CSR field defintion is a mapping (_i.e._, hash, dictionary, ...) containing exactly one key +equal to the CSR field name, in uppercase, and pointing to an object specified below. + +Location:: + +[IMPORTANT] `location` is required *unless* the location is depenent on the XLEN of a certain mode, in which case both `location_rv32` and `location_rv64` are required + +|=== +| *key* | location +| *value type* | Integer (when the field is a single bit) -OR- a String of "MSB-LSB" +| *description* | Location of the field within the CSR. +|=== + +|=== +| *key* | location_rv32 +| *value type* | Integer (when the field is a single bit) -OR- a String of "MSB-LSB" +| *description* | Location of the field within the CSR in RV32. +|=== + +|=== +| *key* | location_rv64 +| *value type* | Integer (when the field is a single bit) -OR- a String of "MSB-LSB" +| *description* | Location of the field within the CSR in RV64. +|=== + +Base:: + +When a CSR field is only present in RV32 or RV64, the `base` field is used. + +|=== +| *key* | base +| *value type* | One of [32, 64] +| *description* | Effective XLEN for this field to exist. +|=== + +Reset Value:: + +[IMPORTANT] `reset_value` is required *unless* the reset value is dependent on a configuration option, in which case `reset_value()` is required. + +|=== +| *key* | reset_value +| *value type* | Integer -OR- "UNDEFINED_LEGAL" +| *description* | Value of the field coming out of reset. When the specific value is not defined, "UNDEFINED_LEGAL" is use to indicate that the value isn't known but is gauranteed to a legal value for the field. +|=== + +|=== +| *key* | reset_value() +| *value type* | String of IDL code that returns a reset value +| *description* | Value of the field coming out of reset. When the specific value is not defined, the special value UNDEFINED_LEGAL can be returned to indicate that the value isn't known but is gauranteed to a legal value for the field. +|=== + +Type:: + +[IMPORTANT] `type` is required, unless the type is configuration-dependent, in which case `type()` is required + +Each field specifies a type as one of: + +[cols="1,4"] +|=== +| Type | Meaning + +| *RO* | Read-only +| *RO-H* | Read-only, and hardware updates the field +| *RW* | Read-write +| *RW-R* | Read-write, but only a restricted set of values are allowed +| *RW-H* | Read-write, and hardware updates the field +| *RW-RH* | Read-write, only a restricted set of values are allowed, and hardware updates the field +|=== + +|=== +| *key* | type +| *value type* | One of ["RO", "RO-H", "RW", "RW-R", "RW-H", "RW-RH"] +| *description* | The type of the field, as described above +|=== + +|=== +| *key* | type() +| *value type* | String of IDL code that returns a CsrFieldType +| *description* | Type of the field, as a CsrFieldType enum value +|=== + +Custom Write Function:: + +[IMPORTANT] `write(csr_value)` is required when the type of the field is restricted ("RW-R" or "RW-RH") + +|=== +| *key* | write(csr_value) +| *value type* | String of IDL code that is run when the software writes the field +| *description* | Function implementing custom write behavior for the CSR. The csr_value parameter is the *entire* attempted CSR write value. Fields within the attempted write value can be accessed with a dot operator (e.g., csr_value.SXL, csr_value.VGEIN, ...) +|=== + +|=== +| *key* | legal?(csr_value) +| *value type* | String of IDL code that returns whether or not an attempted write is legal +| *description* | Function that returns whether or not an attempted value for the field is legal. The csr_value parameter is the *entire* attempted CSR write value. Fields within the attempted write value can be accessed with a dot operator (e.g., csr_value.SXL, csr_value.VGEIN, ...) +|=== + +Alias:: + +Some fields are aliases for another field, often in a different CSR. THe `alias` key is used to indicate that this field just points somewhere else. +