diff --git a/Makefile b/Makefile index a46d659..8c70414 100644 --- a/Makefile +++ b/Makefile @@ -18,8 +18,8 @@ REVMARK ?= Draft DOCKER_RUN := docker run --rm -v ${PWD}:/build -w /build \ riscvintl/riscv-docs-base-container-image:latest -HEADER_SOURCE := header.adoc -PDF_RESULT := spec-sample.pdf +HEADER_SOURCE := riscv-rpmi.adoc +PDF_RESULT := riscv-rpmi.pdf ASCIIDOCTOR_PDF := asciidoctor-pdf OPTIONS := --trace \ @@ -29,7 +29,7 @@ OPTIONS := --trace \ -a revremark=${REVMARK} \ -a revdate=${DATE} \ -a pdf-fontsdir=docs-resources/fonts \ - -a pdf-theme=docs-resources/themes/riscv-pdf.yml \ + -a pdf-theme=riscv-rpmi-pdf.yml \ --failure-level=ERROR REQUIRES := --require=asciidoctor-bibtex \ --require=asciidoctor-diagram \ diff --git a/images/highlevel-arch-queues.png b/images/highlevel-arch-queues.png new file mode 100644 index 0000000..f53eada Binary files /dev/null and b/images/highlevel-arch-queues.png differ diff --git a/images/highlevel-arch.png b/images/highlevel-arch.png new file mode 100644 index 0000000..43b7ac0 Binary files /dev/null and b/images/highlevel-arch.png differ diff --git a/images/highlevel-flow.png b/images/highlevel-flow.png new file mode 100644 index 0000000..2d66c6c Binary files /dev/null and b/images/highlevel-flow.png differ diff --git a/images/message-format.png b/images/message-format.png new file mode 100644 index 0000000..26e8825 Binary files /dev/null and b/images/message-format.png differ diff --git a/images/notification-format.png b/images/notification-format.png new file mode 100644 index 0000000..193150a Binary files /dev/null and b/images/notification-format.png differ diff --git a/images/queue-internals.png b/images/queue-internals.png new file mode 100644 index 0000000..e546181 Binary files /dev/null and b/images/queue-internals.png differ diff --git a/images/queue-operation.png b/images/queue-operation.png new file mode 100644 index 0000000..890c3db Binary files /dev/null and b/images/queue-operation.png differ diff --git a/images/servicegroups-service.png b/images/servicegroups-service.png new file mode 100644 index 0000000..38a008f Binary files /dev/null and b/images/servicegroups-service.png differ diff --git a/images/shmem-layout.png b/images/shmem-layout.png new file mode 100644 index 0000000..c696557 Binary files /dev/null and b/images/shmem-layout.png differ diff --git a/images/transport-bidirectional.png b/images/transport-bidirectional.png new file mode 100644 index 0000000..b236952 Binary files /dev/null and b/images/transport-bidirectional.png differ diff --git a/images/transport-topologies.png b/images/transport-topologies.png new file mode 100644 index 0000000..ce74340 Binary files /dev/null and b/images/transport-topologies.png differ diff --git a/intro.adoc b/intro.adoc deleted file mode 100644 index 0d62327..0000000 --- a/intro.adoc +++ /dev/null @@ -1,15 +0,0 @@ -[[intro]] -== Introduction - -Lorem ipsum indexterm:[Lorem ipsum] dolor sit amet, consectetur adipiscing elit, sed do *eiusmod tempor* incididunt ut labore et dolore magna aliqua. Felis imperdiet proin fermentum leo vel orci porta. Volutpat lacus laoreet non curabitur indexterm:[curabitur] gravida indexterm:[gravida]. Posuere urna nec tincidunt praesent semper feugiat nibh. Elit ``ullamcorper`` dignissim cras tincidunt lobortis. Malesuada fames ac turpis egestas integer eget. Tristique sollicitudin nibh sit amet commodo. Sed felis eget velit aliquet. Sit amet aliquam id diam maecenas ultricies mi. Consectetur purus ut faucibus pulvinar. Lectus urna duis convallis convallis tellus id. Fermentum iaculis eu non diam. Feugiat in fermentum posuere urna nec tincidunt praesent semper feugiat. Urna nec tincidunt praesent semper feugiat nibh. - -Commodo viverra maecenas accumsan lacus. Vulputate odio ut enim blandit indexterm:[blandit] volutpat maecenas volutpat blandit. Urna porttitor rhoncus dolor purus non. Tellus mauris a diam maecenas sed. Vitae auctor eu augue ut lectus. Ridiculus mus mauris vitae ultricies leo integer. Consequat semper viverra nam *libero* justo laoreet sit amet. Pellentesque pulvinar pellentesque habitant morbi tristique senectus et netus et. Ac placerat vestibulum lectus mauris ``ultrices`` eros in cursus turpis. Accumsan in nisl nisi scelerisque eu ultrices vitae. Cras ornare arcu dui vivamus. Vitae congue mauris rhoncus aenean. Consequat mauris nunc congue nisi vitae suscipit tellus. Tempus egestas sed sed risus pretium quam vulputate dignissim. Quis varius quam quisque id diam vel. Mattis nunc sed blandit libero volutpat sed cras ornare arcu. Amet mauris commodo quis imperdiet massa tincidunt nunc. - -[NOTE] -==== -The name RISC-V indexterm:[RISC-V] was chosen to represent the fifth major RISC ISA design from UC Berkeley (RISC-I cite:[riscI-isca1981], RISC-II cite:[Katevenis:1983], SOAR cite:[Ungar:1984], and SPUR cite:[spur-jsscc1989] were the first four). We also pun on the use of the Roman numeral "V" to signify "variations" and "vectors", as support for a range of architecture research, including various data-parallel accelerators, is an explicit goal of the ISA design. -==== - -=== Sub Section of Introduction - -Pellentesque habitant morbi *tristique* senectus et netus et. Aliquam purus sit amet luctus. Odio eu ``feugiat`` pretium nibh ipsum consequat nisl vel. Euismod lacinia at quis risus sed vulputate odio ut. Eu sem integer vitae justo eget. Cursus euismod quis viverra nibh. Tempus egestas sed sed risus. Quis imperdiet massa tincidunt nunc pulvinar. Id venenatis a condimentum vitae sapien pellentesque habitant. diff --git a/riscv-pdf.yml b/riscv-pdf.yml new file mode 100644 index 0000000..2676472 --- /dev/null +++ b/riscv-pdf.yml @@ -0,0 +1,296 @@ +font: + catalog: + merge: false + #Petrona + body: + normal: Petrona-Light.ttf + bold: Petrona-Medium.ttf + italic: Petrona-LightItalic.ttf + bold_italic: Petrona-MediumItalic.ttf + header_thin: Petrona-Thin.ttf + #Montserrat + headings: + normal: Montserrat-Regular.ttf + italic: Montserrat-Italic.ttf + bold: Montserrat-Medium.ttf + light: Montserrat-Light.ttf + code: + normal: cmunbtl.ttf + bold: cmunbtl.ttf + italic: cmunbto.ttf + bold_italic: cmunbto.ttf + # M+ 1mn supports ASCII and the circled numbers used for conums + M+ 1mn: + normal: mplus-1mn-regular.ttf + bold: mplus-1mn-bold.ttf + italic: mplus-1mn-light.ttf + bold_italic: mplus-1mn-medium.ttf + M+ 1p Fallback: + normal: mplus-1p-regular-fallback.ttf + bold: mplus-1p-regular-fallback.ttf + italic: mplus-1p-regular-fallback.ttf + bold_italic: mplus-1p-regular-fallback.ttf + Droid Fallback: + normal: droid-sans-fallback.ttf + # M+ 1p supports Latin, Latin-1 Supplement, Latin Extended, Greek, Cyrillic, Vietnamese, Japanese & an assortment of symbols + # It also provides arrows for ->, <-, => and <= replacements in case these glyphs are missing from font + fallbacks: + - M+ 1p Fallback + - Droid Fallback +page: + background_color: ffffff + layout: portrait + margin: [0.5in, 0.67in, 0.67in, 0.67in] + # margin_inner and margin_outer keys are used for recto/verso print margins when media=prepress + margin_inner: 0.75in + margin_outer: 0.59in + size: A4 +base: + font-family: body + font_size: 11.5 + line_height_length: 12 + font_style: normal + font_size_large: round($base_font_size * 1.25) + font_size_small: round($base_font_size * 0.85) + font_size_min: $base_font_size * 0.75 + border_radius: 3 + border_width: 0.25 +vertical_rhythm: $base_line_height_length +horizontal_rhythm: $base_line_height_length + # QUESTION should vertical_spacing be block_spacing instead? +vertical_spacing: $vertical_rhythm +link: + font_color: 428bca + # literal is currently used for inline monospaced in prose and table cells +literal: + font_color: b12146 + font_family: code +menu_caret_content: " \u203a " +heading: + align: left + font_color: 3e058e + font_family: headings + font_style: light + h1_font_size: floor($base_font_size * 2.8) + # h2 is used for chapter titles (book doctype only) + h2_font_size: floor($base_font_size * 2.15) + h3_font_size: round($base_font_size * 1.7) + h4_font_size: $base_font_size_large + h5_font_size: $base_font_size + h6_font_size: $base_font_size_small +title_page: + align: right + logo: + top: 10% + title: + font_family: headings + font_style: light + font_size: floor($base_font_size * 2.8) + top: 55% + font_color: 3e058e + subtitle: + font_family: headings + font_style: light + font_size: floor($base_font_size * 1.2) + authors: + font_family: headings + font_color: 3e058e + font_style: light + font_size: floor($base_font_size * .8) + revision: + margin_top: $base_font_size * 1.25 +block: + margin_top: 0 + margin_bottom: $vertical_rhythm +caption: + align: left + font_size: $base_font_size * 0.95 + font_style: italic + # FIXME perhaps set line_height instead of / in addition to margins? + margin_inside: $vertical_rhythm / 3 + #margin_inside: $vertical_rhythm / 4 + margin_outside: 0 +lead: + font_size: $base_font_size_large + line_height: 1.4 +abstract: + font_color: 5c6266 + font_size: $lead_font_size + line_height: $lead_line_height + font_style: italic + first_line_font_style: bold + title: + align: left + font_color: $heading_font_color + font_family: $heading_font_family + font_size: $heading_h4_font_size + font_style: $heading_font_style +sidebar: + font-style: italic + background-color: f5f5fc + border-color: 8d81b8 + border-radius: 3 + border-width: 0.2 +sidebar-title: + font_family: $heading_font_family + font-style: light + font-color: $heading-font-color + font-size: 11 + align: left +admonition: + font-style: italic + column_rule_color: $base_border_color + column_rule_width: $base_border_width + padding: [0, $horizontal_rhythm, 0, $horizontal_rhythm] + icon: + note: + name: pencil-square-o + stroke_color: 6489b3 + tip: + name: comments-o + stroke_color: 646b74 + size: 24 + important: + name: info + stroke_color: 5f8c8b + warning: + stroke_color: 9c4d4b + caution: + stroke_color: c99a2c + label: + text_transform: uppercase + font_style: bold +#blockquote: +# font_color: $base_font_color +# font_size: $base_font_size_large +# border_color: $base_border_color +# border_width: 2 + # FIXME disable negative padding bottom once margin collapsing is implemented +# padding: [0, $horizontal_rhythm, $block_margin_bottom * -0.75, $horizontal_rhythm + $blockquote_border_width / 2] +# cite_font_size: $base_font_size_small +# cite_font_color: 51278d +# code is used for source blocks (perhaps change to source or listing?) +code: + font_color: $base_font_color + font_family: $literal_font_family + #font_size: ceil($base_font_size) + font-size: 11 + padding: $code_font_size + line_height: 1.15 + # line_gap is an experimental property to control how a background color is applied to an inline block element + line_gap: 3.8 + background_color: f4f4fb + border_color: cccccc + border_radius: $base_border_radius + border_width: 0.2 +conum: + font_family: M+ 1mn + font_color: $literal_font_color + font_size: $base_font_size + line_height: 4 / 3 +example: + border_color: $base_border_color + border_radius: $base_border_radius + border_width: 0.2 + background_color: ffffff + # FIXME reenable padding bottom once margin collapsing is implemented + padding: [$vertical_rhythm, $horizontal_rhythm, 0, $horizontal_rhythm] +image: + align: left +prose: + margin_top: $block_margin_top + margin_bottom: $block_margin_bottom +thematic_break: + border_color: $base_border_color + border_style: solid + border_width: $base_border_width + margin_top: $vertical_rhythm * 0.5 + margin_bottom: $vertical_rhythm * 1.5 +description_list: + term_font_style: bold + term_spacing: $vertical_rhythm / 4 + description_indent: $horizontal_rhythm * 1.25 +outline_list: + indent: $horizontal_rhythm * 1.5 + #marker_font_color: 404040 + # NOTE outline_list_item_spacing applies to list items that do not have complex content + item_spacing: $vertical_rhythm / 2 +table: + background_color: $page_background_color + #head_background_color: + #head_font_color: $base_font_color + head_font_style: bold + #body_background_color: + body_stripe_background_color: d7d7d7 + foot_background_color: f0f0f0 + border_color: dddddd + border_width: $base_border_width + cell_padding: 3 +toc: + indent: $horizontal_rhythm + line_height: 1.4 + dot_leader: + #content: ". " + font_color: a9a9a9 + #levels: 2 3 +# NOTE in addition to footer, header is also supported +header: + font_size: $base_font_size_small + # NOTE if background_color is set, background and border will span width of page + border_color: dddddd + border_width: 0.35 + height: $base_line_height_length * 2.6 + line_height: 1 + padding: [$base_line_height_length / 1.3, 1, 0, 1] + vertical_align: margin_inside + #image_vertical_align: or + # additional attributes for content: + # * {page-count} + # * {page-number} + # * {document-title} + # * {document-subtitle} + # * {chapter-title} + # * {section-title} + # * {section-or-chapter-title} + recto: + right: + content: '{section-or-chapter-title} | Page {page-number}' + verso: + left: + content: '{section-or-chapter-title} | Page {page-number}' + # left: 'Page {page-number} | {section-or-chapter-title}' +footer: + font_size: $base_font_size_small + # NOTE if background_color is set, background and border will span width of page + border_color: dddddd + border_width: 0.25 + height: $base_line_height_length * 2.5 + line_height: 1 + padding: [$base_line_height_length / 2, 1, 0, 1] + vertical_align: top + #image_vertical_align: or + # additional attributes for content: + # content: '{company}' + # * {page-count} + # * {page-number} + #center: + #content: '{document-title}' + # * {document-subtitle} + # * {chapter-title} + # * {section-title} + # * {section-or-chapter-title} + recto: + #columns: "<50% =0% >50%" + right: + #content: '{page-number}' + content: '{document-title} | © RISC-V' + #content: '{document-title} | © RISC-V' + #center: '{page-number}' + #content: '{revdate}' + verso: + #columns: $footer_recto_columns + left: + content: $footer_recto_right_content + #center: '{page-number}' + #content: '{page-number}' + diff --git a/riscv-rpmi-pdf.yml b/riscv-rpmi-pdf.yml new file mode 100644 index 0000000..50d1369 --- /dev/null +++ b/riscv-rpmi-pdf.yml @@ -0,0 +1,312 @@ +extends: default +font: + catalog: + merge: true +# sans-serif: GEM_FONTS_DIR/mplus1p-regular-fallback.ttf + #Petrona + body: + normal: Petrona-Light.ttf + bold: Petrona-Medium.ttf + italic: Petrona-LightItalic.ttf + bold_italic: Petrona-MediumItalic.ttf + header_thin: Petrona-Thin.ttf + #Montserrat + headings: + normal: Montserrat-Regular.ttf + italic: Montserrat-Italic.ttf + bold: Montserrat-Medium.ttf + light: Montserrat-Light.ttf + code: + normal: cmunbtl.ttf + bold: cmunbtl.ttf + italic: cmunbto.ttf + bold_italic: cmunbto.ttf + # M+ 1mn supports ASCII and the circled numbers used for conums + M+ 1mn: + normal: mplus-1mn-regular.ttf + bold: mplus-1mn-bold.ttf + italic: mplus-1mn-light.ttf + bold_italic: mplus-1mn-medium.ttf + M+ 1p Fallback: + normal: mplus-1p-regular-fallback.ttf + bold: mplus-1p-regular-fallback.ttf + italic: mplus-1p-regular-fallback.ttf + bold_italic: mplus-1p-regular-fallback.ttf + Droid Fallback: + normal: droid-sans-fallback.ttf + italic: droid-sans-fallback.ttf + bold: droid-sans-fallback.ttf + bold_italic: droid-sans-fallback.ttf + # M+ 1p supports Latin, Latin-1 Supplement, Latin Extended, Greek, Cyrillic, Vietnamese, Japanese & an assortment of symbols + # It also provides arrows for ->, <-, => and <= replacements in case these glyphs are missing from font + fallbacks: + - M+ 1p Fallback + - Droid Fallback + svg: + fallback-font-family: M+ 1mn +page: + background_color: ffffff + layout: portrait + margin: [0.5in, 0.67in, 0.67in, 0.67in] + # margin_inner and margin_outer keys are used for recto/verso print margins when media=prepress + margin_inner: 0.75in + margin_outer: 0.59in + size: A4 +base: + font-family: body + font_size: 11.5 + line_height_length: 12 + font_style: normal + font_size_large: round($base_font_size * 1.25) + font_size_small: round($base_font_size * 0.85) + font_size_min: $base_font_size * 0.75 + border_radius: 3 + border_width: 0.25 +vertical_rhythm: $base_line_height_length +horizontal_rhythm: $base_line_height_length + # QUESTION should vertical_spacing be block_spacing instead? +vertical_spacing: $vertical_rhythm +link: + font_color: 428bca + # codespan is currently used for inline monospaced in prose and table cells +codespan: + font-color: 000000 + #font_family: code + #font_family: Droid Fallback + font_family: M+ 1mn + font_style: normal + font-size: 9 +menu_caret_content: " \u203a " +heading: + align: left + font_color: 3e058e + font_family: headings + font_style: light + h1_font_size: floor($base_font_size * 2.8) + # h2 is used for chapter titles (book doctype only) + h2_font_size: floor($base_font_size * 2.15) + h3_font_size: round($base_font_size * 1.7) + h4_font_size: $base_font_size_large + h5_font_size: $base_font_size + h6_font_size: $base_font_size_small +title_page: + align: right + logo: + top: 10% + title: + font_family: headings + font_style: light + font_size: floor($base_font_size * 2.8) + top: 55% + font_color: 3e058e + subtitle: + font_family: headings + font_style: light + font_size: floor($base_font_size * 1.2) + authors: + font_family: headings + font_color: 3e058e + font_style: light + font_size: floor($base_font_size * .8) + revision: + margin_top: $base_font_size * 1.25 +block: + margin_top: 0 + margin_bottom: $vertical_rhythm +caption: + align: left + font_size: $base_font_size * 0.95 + font_style: italic + # FIXME perhaps set line_height instead of / in addition to margins? + margin_inside: $vertical_rhythm / 3 + #margin_inside: $vertical_rhythm / 4 + margin_outside: 0 +lead: + font_size: $base_font_size_large + line_height: 1.4 +abstract: + font_color: 5c6266 + font_size: $lead_font_size + line_height: $lead_line_height + font_style: italic + first_line_font_style: bold + title: + align: left + font_color: $heading_font_color + font_family: $heading_font_family + font_size: $heading_h4_font_size + font_style: $heading_font_style +sidebar: + font-style: italic + background-color: f5f5fc + border-color: 8d81b8 + border-radius: 3 + border-width: 0.2 +sidebar-title: + font_family: $heading_font_family + font-style: light + font-color: $heading-font-color + font-size: 11 + align: left +admonition: + font-style: italic + column_rule_color: $base_border_color + column_rule_width: $base_border_width + padding: [0, $horizontal_rhythm, 0, $horizontal_rhythm] + icon: + note: + name: pencil-square-o + stroke_color: 6489b3 + tip: + name: comments-o + stroke_color: 646b74 + size: 24 + important: + name: info + stroke_color: 5f8c8b + warning: + stroke_color: 9c4d4b + caution: + stroke_color: c99a2c + label: + text_transform: uppercase + font_style: bold +#blockquote: +# font_color: $base_font_color +# font_size: $base_font_size_large +# border_color: $base_border_color +# border_width: 2 +# FIXME disable negative padding bottom once margin collapsing is implemented +# padding: [0, $horizontal_rhythm, $block_margin_bottom * -0.75, $horizontal_rhythm + $blockquote_border_width / 2] +# cite_font_size: $base_font_size_small +# cite_font_color: 51278d +# code is used for source blocks (perhaps change to source or listing?) +code: + font_color: $base_font_color + font_family: $literal_font_family + #font_size: ceil($base_font_size) + font-size: 9 + padding: $code_font_size + line_height: 1.15 + # line_gap is an experimental property to control how a background color is applied to an inline block element + line_gap: 3.8 + background_color: f4f4fb + border_color: cccccc + border_radius: $base_border_radius + border_width: 0.2 +conum: + font_family: M+ 1mn + font_color: $literal_font_color + font_size: $base_font_size + line_height: 4 / 3 +example: + border_color: $base_border_color + border_radius: $base_border_radius + border_width: 0.2 + background_color: ffffff + # FIXME reenable padding bottom once margin collapsing is implemented + padding: [$vertical_rhythm, $horizontal_rhythm, 0, $horizontal_rhythm] +image: + align: left +prose: + margin_top: $block_margin_top + margin_bottom: $block_margin_bottom +thematic_break: + border_color: $base_border_color + border_style: solid + border_width: $base_border_width + margin_top: $vertical_rhythm * 0.5 + margin_bottom: $vertical_rhythm * 1.5 +description_list: + term_font_style: bold + term_spacing: $vertical_rhythm / 4 + description_indent: $horizontal_rhythm * 1.25 +list: + indent: $horizontal_rhythm * 1.5 + #marker_font_color: 404040 + # NOTE outline_list_item_spacing applies to list items that do not have complex content + item_spacing: $vertical_rhythm / 2 +table: + background_color: $page_background_color + #head_background_color: + #head_font_color: $base_font_color + head_font_style: bold + font-size: 9.0 + #body_background_color: + body_stripe_background_color: d7d7d7 + foot_background_color: f0f0f0 + border_color: dddddd + border_width: $base_border_width + cell_padding: 3 + caption: + end: bottom + align: center + text-align: center + max-width: none +toc: + indent: $horizontal_rhythm + line_height: 1.4 + dot_leader: + #content: ". " + font_color: a9a9a9 + #levels: 2 3 +# NOTE in addition to footer, header is also supported +header: + font_size: $base_font_size_small + # NOTE if background_color is set, background and border will span width of page + border_color: dddddd + border_width: 0.35 + height: $base_line_height_length * 2.6 + line_height: 1 + padding: [$base_line_height_length / 1.3, 1, 0, 1] + vertical_align: margin_inside + #image_vertical_align: or + # additional attributes for content: + # * {page-count} + # * {page-number} + # * {document-title} + # * {document-subtitle} + # * {chapter-title} + # * {section-title} + # * {section-or-chapter-title} + recto: + right: + content: "{section-or-chapter-title} | Page {page-number}" + verso: + left: + content: "{section-or-chapter-title} | Page {page-number}" + # left: 'Page {page-number} | {section-or-chapter-title}' +footer: + font_size: $base_font_size_small + # NOTE if background_color is set, background and border will span width of page + border_color: dddddd + border_width: 0.25 + height: $base_line_height_length * 2.5 + line_height: 1 + padding: [$base_line_height_length / 2, 1, 0, 1] + vertical_align: top + #image_vertical_align: or + # additional attributes for content: + # content: '{company}' + # * {page-count} + # * {page-number} + #center: + #content: '{document-title}' + # * {document-subtitle} + # * {chapter-title} + # * {section-title} + # * {section-or-chapter-title} + recto: + #columns: "<50% =0% >50%" + right: + #content: '{page-number}' + content: "{document-title} | © RISC-V" + #content: '{document-title} | © RISC-V' + #center: '{page-number}' + #content: '{revdate}' + verso: + #columns: $footer_recto_columns + left: + content: $footer_recto_right_content + #center: '{page-number}' + #content: '{page-number}' diff --git a/header.adoc b/riscv-rpmi.adoc similarity index 64% rename from header.adoc rename to riscv-rpmi.adoc index 662789d..ca253c4 100644 --- a/header.adoc +++ b/riscv-rpmi.adoc @@ -1,7 +1,6 @@ -= RISC-V Example Specification Document (Zexmpl) -Authors: Author 1, Author 2 -:docgroup: RISC-V Task Group -:description: RISC-V Example Specification Document (Zexmpl) += RISC-V Platform Management Interface Specification (RPMI) +:docgroup: RISC-V RPMI Task Group +:description: RISC-V Platform Management Interface Specification Document (RPMI) :company: RISC-V.org :revdate: 1/2023 :revnumber: 1.0 @@ -12,14 +11,14 @@ Authors: Author 1, Author 2 :preface-title: Preamble :colophon: :appendix-caption: Appendix -:imagesdir: docs-resources/images +:imagesdir: images :title-logo-image: image:risc-v_logo.png[pdfwidth=3.25in,align=center] // Settings: :experimental: :reproducible: //:WaveDromEditorApp: app/wavedrom-editor.app :imagesoutdir: docs-resources/images -:bibtex-file: example.bib +:bibtex-file: src/rpmi.bib :bibtex-order: alphabetical :bibtex-style: apa :icons: font @@ -56,11 +55,22 @@ https://creativecommons.org/licenses/by/4.0/. Copyright 2023 by RISC-V International. [preface] -include::contributors.adoc[] +include::src/contributors.adoc[] -include::intro.adoc[] -include::chapter2.adoc[] +include::src/intro.adoc[] +include::src/transport.adoc[] +include::src/message-protocol.adoc[] +include::src/srvgrp-base.adoc[] +include::src/srvgrp-system-reset.adoc[] +include::src/srvgrp-system-suspend.adoc[] +include::src/srvgrp-hart-state-management.adoc[] +include::src/srvgrp-cppc.adoc[] +include::src/srvgrp-voltage.adoc[] +include::src/srvgrp-clock.adoc[] +include::src/srvgrp-device-power.adoc[] +include::src/srvgrp-performance.adoc[] +include::src/srvgrp-management.adoc[] // The index must precede the bibliography -include::index.adoc[] -include::bibliography.adoc[] +include::src/index.adoc[] +include::src/bibliography.adoc[] diff --git a/bibliography.adoc b/src/bibliography.adoc similarity index 100% rename from bibliography.adoc rename to src/bibliography.adoc diff --git a/chapter2.adoc b/src/chapter2.adoc similarity index 100% rename from chapter2.adoc rename to src/chapter2.adoc diff --git a/contributors.adoc b/src/contributors.adoc similarity index 63% rename from contributors.adoc rename to src/contributors.adoc index 13fd776..cf01386 100644 --- a/contributors.adoc +++ b/src/contributors.adoc @@ -3,5 +3,5 @@ This RISC-V specification has been contributed to directly or indirectly by: [%hardbreaks] -* Author1 -* Author2 +* Rahul Pathak +* diff --git a/index.adoc b/src/index.adoc similarity index 100% rename from index.adoc rename to src/index.adoc diff --git a/src/intro.adoc b/src/intro.adoc new file mode 100644 index 0000000..f0d404b --- /dev/null +++ b/src/intro.adoc @@ -0,0 +1,58 @@ +[[intro]] +== Introduction +This document describes RISC-V Platform Management Interface (RPMI), which is +an extensible interface to manage and control the system using a dedicated microcontroller. Systems today pose challenges in terms of manageability and controllability where the OS may have to support a variety of hardware which +can be different in design and devices connected. The extra complexity and +demand to manage and control the system along with executing compute workloads +is challenging for Application Processors running the OS. To mitigate this, +systems today contain one or more Platform Microcontrollers which abstract +various platform specific system management and control related tasks. +RPMI enables the communication between the application processors and the +Platform micro-controllers. It abstracts the system complexity and provides a message based interface for system management and control. + +RPMI is not limited to a single Application Processor and Platform +Microcontroller. It can support multiple Application Processors and multiple Platform Microcontrollers. + +The Platform Micro-Controller (PuC) serves as an external embedded processor +that abstracts low-level platform control management from the application +processor system. This design allows RPMI to provide an OS-agnostic, generic interface that can support various System-on-Chip (SoC) hardware or platforms. + +Furthermore, RPMI offers a scalable and extensible interface that can support +the addition of new service groups over time, allowing for the implementation +of new features and functions. This feature simplifies the integration of new components and technologies into existing systems, making it easier for system designers to keep up with changing requirements and adapt to evolving industry standards. + + + +=== Abstractions provided by RPMI +*Transport*: Describes the mechanism by which the messages are exchanged +between the Application Processors and Platform Microcontrollers. + +*Messaging Protocol*: Provides Messaging Interface between Application +Processors and Platform Microcontrollers to communicate with each other via +messages to make requests for various services supported by the hardware +platform. This is accomplished by grouping each management interface into +service groups. With each service group implementing several individual +services within. + +RPMI currently provides message interfaces to manage power, voltage, +performance, idle states etc, along with extensibility for vendors to add their +own interfaces. + +Application Processor and A.P are used interchangeably in this document. +Similarly, Platform Microcontroller and PuC are used interchangeably. + +.High Level Architecture +image::highlevel-arch.png[width=800,height=800] + +An RPMI agent is an implementation instance of RPMI Messaging Protocol and Transport. It is necessary to implement the AP side RPMI agent for most RPMI services in M-mode. While it may be possible to implement the AP side RPMI +agent in S-mode for some RPMI services, an M-mode RPMI agent also enhances +security. + +.Transport for M-Mode and S-Mode +image::transport-topologies.png[width=800,height=800] + +RPMI is designed to work with a single or multi-tenant topology as depicted +above. + +NOTE: The discovery of the transport itself is out of scope for this document. Which can either be described in firmware through DT or ACPI. + diff --git a/src/message-protocol.adoc b/src/message-protocol.adoc new file mode 100644 index 0000000..7edfe2e --- /dev/null +++ b/src/message-protocol.adoc @@ -0,0 +1,234 @@ +== Message Protocol +Message Protocol supports a variety of system management and control tasks and +provides a message interface for such tasks. Each message which does a specific +task is called Service. Multiple messages or Services are grouped into Service +Groups like Clock, Voltage, Power management, etc. A service call results in a +message request being sent to the Platform micro-controller for a specific +purpose. Each service may have an associated response message which enables the +Platform micro-controller to provide the status or information for that request. + +.Service Groups and Services +image::servicegroups-service.png[400,400] + +=== Message Types +A message can either be a request or an acknowledgement in response to a request +received by an client. + +==== REQUEST +Messages which convey a command to the other entity/client, usually from the AP +from either S-Mode/M-mode client to Platform Microcontroller (it may also send +REQUESTs to AP, but there are no use cases yet). Each command will have a +certain action that the Platform Microcontroller will take and it may +acknowledge the AP with another message in return which may contain some data or +just the status code. + +Not every request needs to be acknowledged because the action taken by the +Platform Microcontroller may leave the AP in a state where it is not able to +wait for the acknowledgment. For example, in the case when the AP asks the +Platform Microcontroller to perform a Reset, where an acknowledgment would not +be meaningful. + +* *Normal Requests*: Requests with Acknowledgement +* *Posted Requests*: Requests without Acknowledgement + +==== ACKNOWLEDGEMENT +Messages sent from Platform Microcontroller to AP (or vice-versa) in a response +to any previous message request. Acknowledgment is dependent on the service and +each service dictates if acknowledgment is mandatory or not. + +==== NOTIFICATIONS +Notifications are messages which are sent asynchronously from PuC to AP to +notify about the events happening in the system related to various service +groups. Notifications are covered in detail in below section <> + +=== Message Format +On the AP side, each call to a service results in a message request to the PuC. +The type of message depends upon the type of service and to which group that +particular service belongs. Each message, whether its Request or +Acknowledgement, consists of two main parts - Message Header and Data. + +Size of message header is fixed, but size of data is implementation defined, +based on the transport queues layout. All fields in the request and +acknowledgment must follow byte ordering defined by the RPMI transport. + +==== Message Header +Message header has a fixed size of `12-byte` which further contains three +fields each of `4-byte`. Each message gets a unique identity in a RPMI instance +through its header. + +Both REQUEST and ACKNOWLEDGEMENT messages have the same message format. + +image::message-format.png[700,900] + +[#table_message_header] +.Message Header +[cols="1,1,15a", width=100%, align="center", options="header"] +|=== +| Word | Name | Description +| 1 | *TOKEN* | Message identifier. Unique to each +request - acknowledgement transaction for a RPMI implementation instance. +In case of Notifications, `SERVICE_ID` and `MESSAGE_TYPE` for notification +messages are fixed which will contribute to the unique identity of the message +in that RPMI instance implementation. +| 2 | *MESSAGE_ID* | +[cols="1,7a"] +!=== +! *Bits* ! *Description* +! *[31:28]* ! *FLAGS* + + FLAGS[3]: RESERVED. + + FLAGS[2]: DOORBELL + 0: Doorbell interrupt enabled. + 1: Doorbell interrupt disabled. PuC will not ring the doorbell to AP. + This can be used by AP software in case of doorbell interrupts causing spurious interrupts while its also being polled. + + FLAGS[1:0]: MESSAGE_TYPE + 0b00: NORMAL_REQUEST + 0b01: POSTED_REQUEST + 0b10: ACKNOWLEDGEMENT + 0b11: NOTIFICATION +! *[27:8]* ! *SERVICEGROUP_ID* + +Services alike are grouped into Service Groups and each group is identified by `SERVICEGROUP_ID` which is a `20-bit` identifier. +! *[7:0]* ! *SERVICE_ID* + +`8-bit` identifier from LSB in the message identifier word, Services are the +functions which, when called, result in different message requests for different control and management tasks meant for Platform Microcontroller. Each service is identified by a `SERVICE_ID` +!=== +| 3 | *DATALEN* | Encodes the size of the data in the message, data will also be in `32-bit` chunks. +If there is no data, then it must be initialized to zero. +|=== + +Once a message request has been serviced and that service is of type Normal +Request which requires an acknowledgement, PuC must preserve the `TOKEN`, +`SERVICEGROUP_ID`, `SERVICE_ID` from the normal request message header and use +these fields in acknowledgement message header. PuC must mark the message type +in the `FLAGS` and also according to the data expected in the acknowledgement it +may change `DATALEN` in the message header. In case of notifications, PuC will +generate the `TOKEN` and set the `SERVICEGROUP_ID` and fixed `SERVICE_ID=0x00` +assigned for each notification message in every service group and set the +`FLAGS` with notification `MESSAGE_TYPE` marked. Notification messages do not +require any acknowledgement and how data from notification messages is utilized +is dependent on the implementation. + +==== Message Data +Request message data format and acknowledgement data format depends on each +service and details are present with each service section below in their +respective service groups. Size of data each message can accommodate depends on +the transport queues slot size. This specification already defines the data +layout for each size. For few services where the data exceeds the size which a +single message can accommodate, multipart messages are used. + +Message data formats in this specification are tabulated with a list of `32-bit` +wide Word in each of the service groups section as depicted below. + +[#table_message_hdr_data_layout] +.Message Header & Data Layout +[cols="3, 2, 4, 4", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| Word index in message DATA field | Name of field | Type of field, eg: int32 or uint32, etc | Description and interpretation of field +|=== + +The data in acknowledgment at least should contain a `32-bit` `STATUS` code. +Apart from status code, an acknowledgement may encode more data as response to +the request message and details are subsequently present in each service section +below. + + +=== Notifications +Notifications are the messages from Platform Microcontroller to Application +Processor to notify about events taking place in the system. Notifications are +posted messages which do not require acknowledgement from the recipient. Events +can include the system states, power states, errors/faults in the system etc. +Action taken on behalf of any event notification is completely dependent on the +AP and they can be ignored. Platform Microcontroller may combine multiple events +into a single message depending on the available space in the message data. +Individual events may also have additional data associated. _Figure 3.4_ shows +the notification message format. + +Each service group will have a notification service with fixed `SERVICE_ID=0x00` +across every service group. Notifications are sent from PuC to AP with events +and associated data if any. AP has to subscribe to the supported events in each +service group to receive these notification messages. A notification message may +have one or more events with their associated data. +This service with `SERVICE_ID=0x00` is reserved in each service group even if +the service group does not support notifications or need to support any events. +These notifications will only be sent for those events only for which the AP +subscribes. When there are multiple events supported in each service group, AP +has to subscribe to each event and has to make multiple calls to notification +enable service. + +Notifications enable service is also present in each service group even if that +service group does not support notifications or implement any event support. + +Every event will have an Event Header which consists of two fields to identify +an event - `EVENT_ID (12-bit)` and `EVENT_DATALEN (20-bit)`. Events may have +data associated, if present, must be multiple of 4 bytes. + +The number of events which can be accommodated in the message data depends on +the message data field size. The `DATALEN` field in the message header will +encode how much size data is present in the message which is the aggregate of +all events. Then AP must parse each event and its data according to the Event +header. + +Event data and its format depend on the service group and details are present in +respective service group sections. + +image::notification-format.png[500,600] + +[#table_notification_message_format] +.Notification Message Format +[cols="5,2,15a", width=100%, align="center", options="header"] +|=== +| Word | Name | Description +| 1 | *EVENT_HDR* | Event Header is a `32-bit` field which represents a +single event metadata +[cols="1,7a"] +!=== +! *Bits* ! *Description* +! *[31:20]* ! *EVENT_ID* + +Unique identifier for an event in a service group. + +! *[19:0]* ! *EVENT_DATALEN* + +20-bit field to encode the number words(`32-bit`) chunks of event data. +!=== +| 1 : (*EVENT_DATALEN* - 1) | *EVENT_DATA* | Event Data +|=== + +Above table represents the format for one event with its data. Subsequent events +will be packed in the same manner. This spec does not define any ordering of +packing of multiple events and its implementation defined. + +=== Return Status Codes +Below table lists all the error codes which can be returned by any service. Few +probable error codes for each service are also provided in each service response +message format. AP must check for each error code and action based on that is +dependent on the AP. + +[#table_error_codes] +.Return Status Codes +[cols="4, 2, 6", width=100%, align="center", options="header"] +|=== +| Name | Status Code | Description +| RPMI_SUCCESS | 0 | Successful operation +| RPMI_ERROR_FAILED | -1 | Failed due to general error +| RPMI_ERROR_NOT_SUPPORTED | -2 | Service or feature not supported +| RPMI_ERROR_INVALID_PARAMETER | -3 | One or more parameters passed are +invalid +| RPMI_ERROR_DENIED | -4 | Requested operation denied due to insufficient permissions +| RPMI_ERROR_NOT_FOUND | -5 | Requested resource not found +| RPMI_ERROR_OUT_OF_RANGE | -6 | Index out of range +| RPMI_ERROR_OUT_OF_RESOURCE | -7 | Resource limit reached +| RPMI_ERROR_HW_FAULT | -8 | Operation failed due to hardware fault. +| RPMI_ERROR_BUSY | -9 | System is currently busy and cannot +respond to request +| RPMI_ERROR_TIMEOUT | -10 | Operation timed out +| RPMI_ERROR_COMMS | -11 | Error in communication +| RPMI_ERROR_ALREADY | -12 | Operation already in progress or state +changed already for which the operation was carried out. +| RPMI_ERROR_EXTENSION | -13 | Error in extension implementation that +violates the extension specification or the extension version mismatch +| | -14 to -127 | Reserved +| | > -127 | Vendor Specific +|=== + diff --git a/readme.adoc b/src/readme.adoc similarity index 100% rename from readme.adoc rename to src/readme.adoc diff --git a/example.bib b/src/rpmi.bib similarity index 100% rename from example.bib rename to src/rpmi.bib diff --git a/src/srvgrp-base.adoc b/src/srvgrp-base.adoc new file mode 100644 index 0000000..7c1a774 --- /dev/null +++ b/src/srvgrp-base.adoc @@ -0,0 +1,329 @@ + +== Service Groups +A service group is a collection of services which are logically grouped according to the functionality they provide. For example, all voltage related services/messages are collectively referred to as Voltage Service Group. + +This specification defines standard service groups and services with provision to add more service groups as per requirement in the future. + +Following table lists the service group + +[#table_service_groups] +.Service Groups +[cols="2, 4", width=100%, align="center", options="header"] +|=== +| Service Group ID | Service Group Name +| 0x00001 | BASE +| 0x00002 | SYSTEM_RESET +| 0x00003 | SYSTEM_SUSPEND +| 0x00004 | HART_STATE_MANAGEMENT +| 0x00005 | CPPC +| 0x00006 | VOLTAGE +| 0x00007 | CLOCK +| 0x00008 | DEVICE_POWER +| 0x00009 | PERFORMANCE +| 0x0000A | MM_SERVICE +| 0x0000B | RAS_AGENT +| 0x0000B - 0x7FFFF | _Reserved for Future Use_ +| 0x80000 - 0xFFFFF | _Implementation Specific Service Groups_ +|=== +NOTE: The services listed in each service group do not follow any sequence and +are not defined in any specific order. It's possible that any particular service +in any service group inherently requires to be called first before other defined services before that. + +=== Service Group - *BASE* (servicegroup_id: 0x00001) +Base service group is mandatory and provides services for: + +* Initial handshaking between the Application processor and Platform +micro-controller. + +* Querying the message framework implementation version information. + +* Discovering the implementation and version of a specific service group or any specific service in any service group. + +* Gathering allowed system information from the firmware. + +* Status of the transport and if the Platform Microcontroller is ready for +accepting messages. + +Below table lists the services in this group: + +[#table_base_services] +.Base Services +[cols="1, 3, 2", width=100%, align="center", options="header"] +|=== +| Service ID | Service Name | Request Type +| 0x01 | ENABLE_NOTIFICATION | NORMAL_REQUEST +| 0x02 | GET_IMPLEMENTATION_VERSION | NORMAL_REQUEST +| 0x03 | GET_IMPLEMENTATION_ID | NORMAL_REQUEST +| 0x04 | GET_SPEC_VERSION | NORMAL_REQUEST +| 0x05 | GET_HW_INFO | NORMAL_REQUEST +| 0x06 | PROBE_SERVICE_GROUP | NORMAL_REQUEST +| 0x07 | GET_BASE_ATTRIBUTES | NORMAL_REQUEST +| 0x08 | SET_MSI | NORMAL_REQUEST +|=== + +==== Base Notifications +Platform Microcontroller can send asynchronous notifications to AP via this +service. There can be multiple types of events classified in the Base service +group which can be combined into a single message as depicted in _Figure 3.5_. +If Platform Microcontroller has multiple events for the same type, Platform Microcontroller can send the single instance of that event that was received +last. +[#table_base_srvgroup_events] +.Base Service Group Events +[cols="1, 2, 1, 4", width=100%, align="center", options="header"] +|=== +| Event ID | Event Name | Event Data | Description +| 0x001 | REQUEST_HANDLE_ERROR | NA | This event indicates that the Platform Microcontroller is unable to serve the message requests anymore and +this event may send the list of messages which the Platform Microcontroller was processing when the failure took place. No event data is necessary for this +notification +|=== + +=== Service: *ENABLE_NOTIFICATION* +This service allows AP to subscribe to Base service group notifications. + +Platform can optionally support notifications of errors which might occur in the platform. PuC can send these notification messages to AP if they are implemented +and AP has subscribed to these. Events supported are described above in Base Notifications. +[#table_base_ennotification_request_data] +.Request Data +[cols="1, 2, 1, 5", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | EVENT_ID | uint32 | Event to be subscribed for +notification. +|=== + +[#table_base_ennotification_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Notifications are subscribed successfully. +! RPMI_ERROR_NOT_FOUND ! EVENT_ID is not supported or invalid. +! RPMI_ERROR_NOT_SUPPORTED ! Notifications not supported. +!=== +- Other errors <> +|=== + +=== Service: *GET_IMPLEMENTATION_VERSION* +Get the implementation version of the message framework from Platform Microcontroller. Versioning is also done for the spec but it's possible that for a single version of spec there may be multiple implementation versions and based on that any lowest supported implementation version can be mandated to ensure the stability and support. Version returned using this service is a 32-Bit composite number which contains both Major and Minor numbers. + +[#table_base_getimplversion_request_data] +.Request Data +- NA + +[#table_base_getimplversion_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5a"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Implementation version returned successfully. +!=== +- Other errors <> +| 1 | VERSION | uint32 | Implementation Version +[cols="2,5a"] +!=== +! *Bits* ! *Description* +! [31:16] ! Major Number +! [15:0] ! Minor Number +!=== +|=== + +==== Service: *GET_IMPLEMENTATION_ID* +Get the RPMI Implementation ID assigned to the Operating system or Firmware or any other software host which implements the RPMI specification. +[#table_base_getimplid_request_data] +.Request Data +- NA + +[#table_base_getimplid_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5a"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Implementation ID returned successfully. +!=== +- Other errors <> +| 1 | IMPL_ID | uint32 | Implementation ID +|=== + +==== Service: *GET_SPEC_VERSION* +Get version of the implemented RPMI specification +[#table_base_getspecversion_request_data] +.Request Data +- NA + +[#table_base_getspecversion_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5a"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! RPMI specification version returned successfully. +!=== +- Other errors <> +| 1 | VERSION | uint32 | RPMI Specification Version +[cols="2,5a"] +!=== +! *Bits* ! *Description* +! [31:16] ! Major Number +! [15:0] ! Minor Number +!=== +|=== + +==== Service: *GET_HW_INFO* +This service is used to retrieve the Vendor ID and Name of the Vendor having a +RPMI implementation on PuC. Each vendor will be assigned a unique Vendor ID. +[#table_base_gethwinfo_request_data] +.Request Data +- NA + +[#table_base_gethwinfo_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5a"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Vendor info returned successfully. +!=== +- Other errors <> +| 1 | VENDOR_ID | uint32 | Vendor Identifier +[cols="2,9a"] +!=== +! *Bits* ! *Description* +! [31:16] ! *SUB_VENDOR_ID* _(optional)_ + + It is an additional numeric value used to further differentiate + between different sub-vendors or product lines within the same + hardware vendor. + + 0x0: Not Supported + +! [15:0] ! *VENDOR_ID* + + Hardware Vendor ID is a numeric value that uniquely identifies the + manufacturer or vendor of the hardware platform or device. +!=== +| 2 | HW_ID_LEN | uint32 | HW_ID field length in bytes. +| 3 | HW_ID | uint8[HW_ID_LEN] | Hardware Identifier String + + Up to HW_ID_LEN bytes NULL terminated ASCII string. + It can be used to convey details such as the specific product model, revision, or configuration of the + hardware. +|=== + +==== Service: *PROBE_SERVICE_GROUP* +Probe the implementation of any service group by its service group id. Except +BASE, rest of the service groups are optional but if a service group is +implemented then it has to be implemented completely with all services in that group. The notifications in that service group are still optional which will be implemented by the PuC. + +[#table_base_probesrvgrp_request_data] +.Request Data +[cols="1, 2, 1, 5", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | SERVICEGROUP_ID | uint32 | `24 bit` ID assigned to each service + group. +|=== + +[#table_base_probesrvgrp_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5a"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Service completed successfully. Status of Service group + represented by *SERVICEGROUP_ID* is identified by field + *SERVICE_GROUP_STATUS*. +!=== +- Other errors <> +| 1 | SERVICE_GROUP_STATUS | uint32 | Service group implementation + status. + + 0: Service group not implemented by platform. + 1: Service group implemented by platform. +|=== + +==== Service: *GET_BASE_ATTRIBUTES* +This service is used to discover additional features supported by the base service group. +[#table_base_getbaseattrs_request_data] +.Request Data +- NA + +[#table_base_getbaseattrs_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5a"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Attributes returned successfully. +!=== +- Other errors <> +| 1 | FLAGS0 | uint32 | Vendor Identifier +[cols="2,9a"] +!=== +! *Bits* ! *Description* +! [31] ! *EVENT_NOTIFICATION* + + + 0b0: Notifications are not supported + 0b1: Notifications are supported + +! [30] ! *MSI* + + + 0b0: Not Supported + 0b1: Supported +! [29:0] ! _Reserved_ +!=== +| 2 | FLAGS1 | uint32 | _Reserved, initialized to_ `0` +| 3 | FLAGS2 | uint32 | _Reserved, initialized to_ `0` +| 4 | FLAGS3 | uint32 | _Reserved, initialized to_ `0` +|=== + +==== Service: *SET_MSI* +Configure the MSI address and data which the Platform Microcontroller can use as a doorbell to AP. + +The PuC to AP MSI can be used for both sending MSI or injecting wired interrupts. If the MSI target address is IMSIC then AP will take MSI whereas if the MSI target address is "setipnum" of APLIC then AP will take wired interrupt. + +In case of platforms with PLIC, the platform need to provide a MMIO register to inject a edge-triggered interrupt. + +[#table_base_setmsi_request_data] +.Request Data +[cols="1, 2, 1, 5", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | MSI_ADDRESS_LOW | uint32 | Lower `32 bit` of MSI address +| 1 | MSI_ADDRESS_HIGH | uint32 | Higher `32 bit` of MSI address +| 2 | MSI_DATA | uint32 | `32 bit` MSI data +|=== + +[#table_base_setmsi_response_data] +.Response Data +[cols="1, 1, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! MSI address and data are configured successfully. +! RPMI_ERROR_NOT_SUPPORTED ! MSI not supported. Implementation must use base attributes to discover this capability and then use this service.. +!=== +- Other errors <> +|=== \ No newline at end of file diff --git a/src/srvgrp-clock.adoc b/src/srvgrp-clock.adoc new file mode 100644 index 0000000..fec4adb --- /dev/null +++ b/src/srvgrp-clock.adoc @@ -0,0 +1,347 @@ + +=== Service Group - *CLOCK* (servicegroup_id: 0x00007) +This service group is for the management of system clocks. Services defined in +this group are used to enable or disable clocks, and to set/get clock rates. + +Each clock in the system is identified by the clock id which is an integer +identifier assigned to each clock. The mapping of clock_id and clock is known to +both AP and Platform Microcontroller. Clock ID identifiers are sequential and +start from `0`. + +The device or the group of devices which share the same clock source becomes a +single clock domain, which is identified by the clock_id. Any change in the +clock source affects the whole domain which can contain multiple devices. + +This topology of devices and clock source is dependent on how the system is +designed and implementation specific. OS can discover this topology through +firmware tables (DT/ACPI). + + +==== Clock rate format +Each clock rate is a tuple of two `32 bit` values `(uint32, uint32)` represented +as `(clock_rate_low, clock_rate_high)` and packed in the same order where +`clock_rate_low` is at the lower index than the `clock_rate_high`. + +Below table lists the services in this group: +[#table_clock_services] +.Clock Services +[cols="1, 3, 2", width=100%, align="center", options="header"] +|=== +| Service ID | Service Name | Request Type +| 0x01 | ENABLE_NOTIFICATION | NORMAL_REQUEST +| 0x02 | GET_NUM_CLOCKS | NORMAL_REQUEST +| 0x03 | GET_ATTRIBUTES | NORMAL_REQUEST +| 0x04 | GET_SUPPORTED_RATES | NORMAL_REQUEST +| 0x05 | SET_CONFIG | NORMAL_REQUEST +| 0x06 | GET_CONFIG | NORMAL_REQUEST +| 0x07 | SET_RATE | NORMAL_REQUEST +| 0x08 | GET_RATE | NORMAL_REQUEST +|=== + +==== Clock Notifications +This service group does not support any event for notification + +==== Service: *ENABLE_NOTIFICATION* +This service allows AP to subscribe to clock service group notifications. +Platform can optionally support notifications of events which might occur in the platform. PuC can send these notification messages to AP if they are implemented +and AP has subscribed to these. Events supported are described above in Clock Notifications. + +[#table_clock_ennotification_request_data] +.Request Data +[cols="1, 2, 1, 5", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | EVENT_ID | uint32 | Event to be subscribed for +notification. +|=== + +[#table_clock_ennotification_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Notifications are subscribed successfully. +! RPMI_ERROR_NOT_FOUND ! EVENT_ID is not supported or invalid. +! RPMI_ERROR_NOT_SUPPORTED ! Notifications not supported. +!=== +- Other errors <> +|=== + +==== Service: *GET_NUM_CLOCKS* +Request for number of clocks available in the system. All supported clocks in +the system are designated by an integer identifier called clock_id. Clock_id are sequential starting from `0`. + +[#table_clock_getnumclocks_request_data] +.Request Data +- NA + +[#table_clock_getnumclocks_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Service completed successfully. +!=== +- Other errors <> +| 1 | NUM_CLOCKS | uint32 | Number of Clocks +|=== + +==== Service: *GET_ATTRIBUTES* +This service returns the attributes of a clock like name of the clock which is +an array ASCII string of `16 byte`. Transition latency which is the worst case +latency for the clock to return to a stable state once clock configuration is +changed. Number of Clock rates supported by the requested clock. +FLAGS field encode the clock format supported by the clock. + +Current supported clock formats are discrete, which is an array of discrete +values where each value represents a clock rate. Another format is linear range +which is represented by `(min_Hz, max_Hz, step_Hz)`. In future more clock formats +can be supported if required. + +[#table_clock_getattrs_request_data] +.Request Data +[cols="1, 2, 1, 5", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | CLOCK_ID | uint32 | Clock ID +|=== + +[#table_clock_getattrs_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Service completed successfully. +! RPMI_ERROR_NOT_FOUND ! Clock not found +!=== +- Other errors <> +| 1 | FLAGS | uint32 | +[cols="2,5a"] +!=== +! *Bits* ! *Description* +! [31:30] ! CLOCK_FORMAT + + 0b00: Discrete Format + Each element in the CLOCK_RATE array is a supported discrete clock rate + value packed in ascending order. Each rate is in Hertz. + + 0b01: Linear Range + The CLOCK_RATE array contains the triplet (min_Hz, max_Hz, step_Hz). + Each item in the triplet is a clock rate value. + CLOCK_RATE[0] = min_Hz (lowest physical rate that the clock can synthesize) + CLOCK_RATE[1] = max_Hz (highest physical rate that the clock can synthesize) + CLOCK_RATE[2] = step_Hz (Step between two successive rates) +! [29:0] ! _Reserved_ +!=== +| 2 |NUM_RATESS | uint32 | Number of Clock rates of type depending on CLOCK_FORMAT. +| 3 | TRANSITION_LATENCY | uint32 | Transition Latency +| 4:7 | CLOCK_NAME | uint8[16] | Clock name +|=== + +==== Service: *GET_SUPPORTED_RATES* +Each domain may support multiple clock rate values which are allowed by the +domain to operate. Message can also pass the `clock_rate_index` which is the index +to the first rate value to be described in the return rate array. If all +supported rate values are required then this index value can be `0`. + +If the CLOCK_FORMAT is discrete then the clock rate in the received data is an +array of supported discrete rate values packed in ascending order starting from +the lower index in the CLOCK_RATE field. If the CLOCK_FORMAT is a linear range, +then the CLOCK_RATE array contains a triplet of `(min_Hz, max_Hz, step_Hz)` where +each item in the triplet is a clock rate value. + +Total words required for the number of clock rates according to the format in +one message cannot exceed the total words available in one message DATA field. +If they exceed then PuC will return the number of clock rates which can be +accommodated in one message and set the REMAINING field accordingly. AP, when +REMAINING field is not `0` must call this service again with appropriate +CLOCK_RATE_INDEX set to get the remaining clock rates. It's possible that +multiple service calls may be required to get all the clock rates. +In case the CLOCK_FORMAT is a linear range the RETURNED field will be set to `3`. + +[#table_clock_getsupprates_request_data] +.Request Data +[cols="1, 2, 1, 5", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | CLOCK_ID | uint32 | Clock ID +| 1 | CLOCK_RATE_INDEX | uint32 | Clock rate index +|=== + +[#table_clock_getsupprates_response_data] +.Response Data +[cols="1, 2, 2, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Service completed successfully. +! RPMI_ERROR_NOT_FOUND ! CLOCK_ID not found. +! RPMI_ERROR_INVALID_PARAM ! CLOCK_RATE_INDEX is not in valid range. +!=== +- Other errors <> +| 1 | FLAGS | uint32 | _Reserved_ and must be `0`. +| 2 | REMAINING | uint32 | Remaining number of clock rates. +| 3 | RETURNED | uint32 | Number of clock rates returned so far. +| 4 | CLOCK_RATE[0] | (uint32, uint32) | Clock rate value. +| 5 | CLOCK_RATE[1] | (uint32, uint32) | Clock rate value. +| ... | CLOCK_RATE[N-1] | (uint32, uint32) | Clock rate value. +|=== + +==== Service: *SET_CONFIG* +Set clock config, enable or disable the clock. + +[#table_clock_setconfig_request_data] +.Request Data +[cols="1, 2, 1, 5a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | CLOCK_ID | uint32 | Clock ID +| 1 | CONFIG | uint32 | Clock config +[cols="2,5a"] +!=== +! *Bits* ! *Description* +! [31:1] ! _Reserved_ +! [0] ! + + 0b0: Disable clock + + 0b1: Enable clock +!=== +|=== + +[#table_clock_setconfig_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Service completed successfully. +! RPMI_ERROR_NOT_FOUND ! CLOCK_ID not found. +! RPMI_ERROR_INVALID_PARAMETER ! CONFIG is not supported by the clock. +!=== +- Other errors <> +|=== + + +==== Service: *GET_CONFIG* +Get the current status of a clock, if it's enabled or disabled. + +[#table_clock_getconfig_request_data] +.Request Data +[cols="1, 2, 1, 5a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | CLOCK_ID | uint32 | Clock ID +|=== + +[#table_clock_getconfig_response_data] +.Response Data +[cols="1, 2, 1, 5a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Service completed successfully. +! RPMI_ERROR_NOT_FOUND ! CLOCK_ID not found. +!=== +- Other errors <> +| 1 | CONFIG | uint32 | Clock config +[cols="2,5a"] +!=== +! *Value* ! *Description* +! 0x0 ! Disabled +! 0x1 ! Enabled +!=== +|=== + +==== Service: *SET_RATE* +Set clock rate. + +[#table_clock_setrate_request_data] +.Request Data +[cols="1, 2, 1, 5a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | CLOCK_ID | uint32 | Clock ID +| 1 | FLAGS | uint32 | +[cols="2,5a"] +!=== +! *Bits* ! *Description* +! [31:30] ! Clock rate roundup/rounddown + + 0b00: Round down + + 0b01: Round up + + 0b10: Auto. Platform autonomously choose rate closest to the requested + rate. + +! [29:0] ! _Reserved_ +!=== +| 2 | CLOCK_RATE_LOW | uint32 | +| 3 | CLOCK_RATE_HIGH | uint32 +|=== + +[#table_clock_setrate_response_data] +.Response Data +[cols="1, 2, 1, 5a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Service completed successfully. +! RPMI_ERROR_NOT_FOUND ! CLOCK_ID not found. +! RPMI_ERROR_INVALID_PARAMETER ! Clock rate is not supported. +!=== +- Other errors <> +|=== + +==== Service: *GET_RATE* +Get the current clock rate value. + +[#table_clock_getrate_request_data] +.Request Data +[cols="1, 2, 1, 5a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | CLOCK_ID | uint32 | Clock ID +|=== + +[#table_clock_getrate_response_data] +.Request Data +[cols="1, 2, 1, 5a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Service completed successfully. +! RPMI_ERROR_NOT_FOUND ! CLOCK_ID not found. +!=== +- Other errors <> +| 1 | CLOCK_RATE_LOW | uint32 | +| 2 | CLOCK_RATE_HIGH | uint32 | +|=== \ No newline at end of file diff --git a/src/srvgrp-cppc.adoc b/src/srvgrp-cppc.adoc new file mode 100644 index 0000000..0fe7d30 --- /dev/null +++ b/src/srvgrp-cppc.adoc @@ -0,0 +1,285 @@ +=== Service Group - *CPPC* (servicegroup_id: 0x00005) +This service group defines the services to control CPU performance by managing a set of registers and a dedicated physical memory block, which will define fast channel access to each hart in the system. Hart writes a specific 32-Bit desired performance number in fast channel memory. PuC decodes the request and performs the corresponding CPPC operations. + +CPPC physical memory will have enough space to accommodate all available harts. Hart can send an RPMI message GET_CPPC_PERF_CHAN_ADDR to query the physical address of that particular hart. + +Once Hart receives the physical address of the REQ-ACK registers, Hart clears the acknowledgement register and writes a performance counter value in the request register and a sequence number in the sequence number register. On observing this request, PuC changes the performance state and writes the sequence number value of the original request in the Acknowledgement register. That completes the request. + +PROBE_CPPC_REG service can be used to check if a particular CPPC register is implemented. The service READ_CPPC_REG can be used to read all implemented CPPC register values and WRITE_CPPC_REG can be used to write the registers. + +For extra debugging, Hart can send a GET_CPPC_PERF_POKE message to exclusively request PuC to process the pending CPPC requests, if any. + +For more information on CPPC, refer https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/index.html[ACPI] and https://github.com/riscv-non-isa/riscv-sbi-doc/[CPPC]. + +CPPC Fast Channel REQ-ACK Memory Entry per Hart: +[#table_cppc_fastchan_mem] +.CPPC Fast Channel Memory Entry +[cols="1, 3, 2", width=100%, align="center", options="header"] +|=== +| Word | Description | Entity which writes the word +| 0 | Request Sequence Number Register | AP +| 1 | Request Register | AP +| 2 | Acknowledgement Register | PuC +| 3 | Reserved | None +|=== + +Below table lists the services in this group: +[#table_cppc_services] +.CPPC Services +[cols="1, 3, 2", width=100%, align="center", options="header"] +|=== +| Service ID | Service Name | Request Type +| 0x01 | ENABLE_NOTIFICATION | NORMAL_REQUEST +| 0x02 | PROBE_REG | NORMAL_REQUEST +| 0x03 | READ_REG | NORMAL_REQUEST +| 0x04 | WRITE_REG | NORMAL_REQUEST +| 0x05 | GET_FAST_CHANNEL_ADDR | NORMAL_REQUEST +| 0x06 | POKE_FAST_CHANNEL | NORMAL_REQUEST +| 0x07 | GET_HART_LIST | NORMAL_REQUEST +|=== + +==== CPPC Notifications +This service group does not support any event for notification. + + + +==== Service: *ENABLE_NOTIFICATION* +This service allows AP to subscribe to CPPC service group notifications. +Platform can optionally support notifications of events which might occur in the platform. PuC can send these notification messages to AP if they are implemented +and AP has subscribed to these. Events supported are described above in CPPC Notifications. + +[#table_cppc_ennotification_request_data] +.Request Data +[cols="1, 2, 1, 5", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | EVENT_ID | uint32 | Event to be subscribed for +notification. +|=== + +[#table_cppc_ennotification_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Notifications are subscribed successfully. +! RPMI_ERROR_NOT_FOUND ! EVENT_ID is not supported or invalid. +! RPMI_ERROR_NOT_SUPPORTED ! Notifications not supported. +!=== +- Other errors <> +|=== + + + +==== Service: *PROBE_REG* +Probe for CPPC register and get its length in bytes. If the register is not +implemented, REG_LENGTH returned will be zero. + +[#table_cppc_probereg_request_data] +.Request Data +[cols="1, 2, 1, 5", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | HART_ID | uint32 | Hart ID +| 1 | REG_ID | uint32 | Register ID (refer register ids in +https://github.com/riscv-non-isa/riscv-sbi-doc/blob/master/src/ext-cppc.adoc[SBI Spec]) +|=== + +[#table_cppc_probereg_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Service completed successfully and probing details returned. +! RPMI_ERROR_NOT_FOUND ! HART_ID not found +!=== +- Other errors <> +| 1 | REG_LENGTH | uint32 | Register Length +|=== + + + +==== Service: *READ_REG* +Read CPPC register value + +[#table_cppc_readreg_request_data] +.Request Data +[cols="1, 2, 1, 5", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | HART_ID | uint32 | Hart ID +| 1 | REG_ID | uint32 | Register ID (refer register ids in +https://github.com/riscv-non-isa/riscv-sbi-doc/blob/master/src/ext-cppc.adoc[SBI Spec]) +|=== + +[#table_cppc_readreg_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Service completed successfully. +! RPMI_ERROR_NOT_FOUND ! HART_ID not found +! RPMI_ERROR_INVALID_PARAMETER ! REG_ID is invalid or not implemented. AP must +probe the REG_ID before reading. +!=== +- Other errors <> +| 1 | DATA_LOW | uint32 | Low `32 bit` of data +| 2 | DATA_HIGH | uint32 | High `32 bit` of data +|=== + + + +==== Service: *WRITE_REG* +Write a CPPC register + +[#table_cppc_writereg_request_data] +.Request Data +[cols="1, 2, 1, 5", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | HART_ID | uint32 | Hart ID +| 1 | REG_ID | uint32 | Register ID (refer register ids in +https://github.com/riscv-non-isa/riscv-sbi-doc/blob/master/src/ext-cppc.adoc[SBI Spec]) +| 2 | DATA_LOW | uint32 | Low `32 bit` of data +| 3 | DATA_HIGH | uint32 | High `32 bit` of data +|=== + +[#table_cppc_writereg_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Service completed successfully. +! RPMI_ERROR_NOT_FOUND ! HART_ID not found +! RPMI_ERROR_INVALID_PARAMETER ! REG_ID is invalid or not implemented. AP must +probe the REG_ID before reading. +!=== +- Other errors <> +|=== + + + +==== Service: *GET_FAST_CHANNEL_ADDR* +Request for physical address of CPPC fast channel for the hart ID specified, +this physical address shall be used to write the value of https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/08_Processor_Configuration_and_Control/declaring-processors.html?highlight=cppc#desired-performance-register[CPPC Desired +Performance Register]. + +[#table_cppc_getfastchanaddr_request_data] +.Request Data +[cols="1, 2, 1, 5", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | HART_ID | uint32 | Hart ID +|=== + +[#table_cppc_getfastchanaddr_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Service completed successfully. +! RPMI_ERROR_NOT_FOUND ! HART_ID not found +! RPMI_ERROR_NOT_SUPPORTED ! Fast channel not implemented +!=== +- Other errors <> +| 1 | FLAGS | uint32 | +[cols="2,5a"] +!=== +! *Bits* ! *Description* +! [31:3] ! _Reserved_ +! [2:1] ! Doorbell Register Width + + 0b00: 8 bit + 0b01: 16 bit + 0b10: 32 bit + 0b11: 64 bit +! [0] ! + + 0b0: Doorbell not supported + 0b1: Doorbell supported +!=== +| 2 |PHYS_ADDR_LOW | uint32 | Low `32 bit` of physical address +| 3 |PHYS_ADDR_HIGH | uint32 | High `32 bit` of physical address +| 4 |DB_ADDR_LOW | uint32 | Low `32 bit` of doorbell address +| 5 |DB_ADDR_HIGH | uint32 | High `32 bit` of doorbell address +| 6 |DB_ID_LOW | uint32 | Low `32 bit` of doorbell ID +| 7 |DB_ID_HIGH | uint32 | High `32 bit` of doorbell ID +|=== + + + +==== Service: *POKE_FAST_CHANNEL* +Debug request message to poke the PuC FW to process the pending CPPC messages if +any. + +[#table_cppc_pokefastchan_request_data] +.Request Data +[cols="1, 2, 1, 5", width=100%, align="center", options="header"] +- NA + +[#table_cppc_pokefastchan_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Fast channel poked and service completed successfully. +!=== +- Other errors <> +|=== + + + +==== Service: *GET_HART_LIST* +This service gets the list of a hart with a specified hart ID start index. + +[#table_cppc_gethartlist_request_data] +.Request Data +[cols="1, 2, 1, 5", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | START_INDEX | uint32 | Starting index of Hart ID +|=== + +[#table_cppc_gethartlist_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Service completed successfully. +! RPMI_ERROR_INVALID_PARAMETER ! Invalid START_INDEX +!=== +- Other errors <> +| 1 | REMAINING | uint32 | Remaining number of items to be returned +| 2 | RETURNED | uint32 | Total number of items returned so far. +| 3 | HART_ID[0] | uint32 | Hart ID +| 4 | HART_ID[1] | uint32 | Hart ID +| 5 | HART_ID[N-1] | uint32 | Hart ID +|=== \ No newline at end of file diff --git a/src/srvgrp-device-power.adoc b/src/srvgrp-device-power.adoc new file mode 100644 index 0000000..880c746 --- /dev/null +++ b/src/srvgrp-device-power.adoc @@ -0,0 +1,208 @@ + +=== Service Group - *DEVICE_POWER* (servicegroup_id: 0x00008) +This device power service group provides messages to manage the power states of +a device power domain. This service group is only used for device power +management since System and CPU power management is handled by already defined +service groups like SYSTEM_RESET, SYSTEM_SUSPEND and HART_STATE_MANAGEMENT. + +A domain can consist of one device if its power states can be controlled +independently or it may also have multiple devices if they all share the same +power control lines and power state can only be changed collectively. +Each domain must support ON and OFF states along with custom power states which +are discoverable. Domains may also have power states which may preserve the +context. Level of context preserved will depend on the level of power state. + +Power states for domains will be discovered via DT or ACPI where the values for +ON and OFF are already fixed and known. Power state encodes both the power state +value and the context preserved or lost information corresponding to that state. + +[#table_devpower_powerstate_data] +.Power States Encoding +[cols="1, 2, 5a", width=100%, align="center", options="header"] +|=== +| POWER_STATE(uint32) | Field | Description +| POWER_STATE[31] | CONTEXT | + + 0b0: Context is preserved + 0b1: Context is lost +| POWER_STATE[30:16] | RESERVED | _Reserved_ +| POWER_STATE[15:0] | VALUE | +[cols="2,5"] +!=== +! *Value* ! *Description* +! 0x0000 ! ON with POWER_STATE[31] = 1 +! 0x0001 ! _Reserved_ +! 0x0002 ! _Reserved_ +! 0x0003 ! OFF with POWER_STATE[31] = 0 +! 0x0004 - 0x0FFF ! _Reserved_ +! 0x1000 - 0xFFFF ! Vendor specific states +!=== +|=== + +[#table_devpower_services] +.Device Power Services +[cols="1, 3, 2", width=100%, align="center", options="header"] +|=== +| Service ID | Service Name | Request Type +| 0x01 | ENABLE_NOTIFICATION | NORMAL_REQUEST +| 0x02 | GET_DEVICE_POWER_DOMAINS | NORMAL_REQUEST +| 0x03 | GET_DEVICE_POWER_DOMAIN_ATTRIBUTES | NORMAL_REQUEST +| 0x04 | SET_DEVICE_POWER_STATE | NORMAL_REQUEST +| 0x05 | GET_DEVICE_POWER_STATE | NORMAL_REQUEST +|=== + +==== Device Power Notifications +This service group does not support any event for notification. + +==== Service: *ENABLE_NOTIFICATION* +This service allows AP to subscribe to device power service group notifications. +Platform can optionally support notifications of events which might occur in the platform. PuC can send these notification messages to AP if they are implemented +and AP has subscribed to these. Events supported are described above in Device +Power Notifications. + +[#table_devpower_ennotification_request_data] +.Request Data +[cols="1, 2, 1, 5", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | EVENT_ID | uint32 | Event to be subscribed for +notification. +|=== + +[#table_devpower_ennotification_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Notifications are subscribed successfully. +! RPMI_ERROR_NOT_FOUND ! EVENT_ID is not supported or invalid. +! RPMI_ERROR_NOT_SUPPORTED ! Notifications not supported. +!=== +- Other errors <> +|=== + +==== Service: *GET_DEVICE_POWER_DOMAINS* +This service is used to query the number of device power domains available which +can be controlled by the client. The number of domains returned can be less than +the actual number of domains present with the platform. The number of domains +returned are allowed to be managed by the client. + +[#table_devpower_getdomains_request_data] +.Request Data +- NA + +[#table_devpower_getdomains_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Service completed successfully. +!=== +- Other errors <> +| 1 | NUM_DOMAINS | uint32 | Number of domains +|=== + + +==== Service: *GET_DEVICE_POWER_DOMAIN_ATTRIBUTES* +This service is used to query the attributes of a device power domain. + +[#table_devpower_getattrs_request_data] +.Request Data +[cols="1, 2, 1, 5", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | DOMAIN_ID | uint32 | Device power domain ID +|=== + +[#table_devpower_getattrs_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Service completed successfully. +! RPMI_ERROR_NOT_FOUND ! Device power domain not found +!=== +- Other errors <> +| 1 | FLAGS | uint32 | _Reserved_ +| 2 | TRANSITION_LATENCY | uint32 | Worst case transition latency +of domain from one power state to another +| 3:6 | DEVICE_POWER_DOMAIN_NAME | uint8[16] | Device power domain +name +|=== + + +==== Service: *SET_DEVICE_POWER_DOMAIN_STATE* +This service is used to change the power state of a device power domain. + +[#table_devpower_setstate_request_data] +.Request Data +[cols="1, 2, 1, 5", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | DOMAIN_ID | uint32 | Device power domain ID +| 1 | POWER_STATE | uint32 | This field indicates the power state to which the power domain should transition. The specific power states and their +meanings may vary depending on the implementation, but generally, they include +values such as "ON", "OFF" and vendor specific power state. + +See Power States table in the service group description +|=== + +[#table_devpower_setstate_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Service completed successfully. +! RPMI_ERROR_NOT_FOUND ! Device power domain not found. +! RPMI_ERROR_INVALID_PARAMETER ! Invalid or Not supported POWER_STATE value. +! RPMI_ERROR_DENIED ! Client does not have permissions to change the Device power domain power state. +! RPMI_ERROR_HW_FAULT ! Failed due to hardware error. +!=== +- Other errors <> +|=== + +==== Service: *GET_DEVICE_POWER_DOMAIN_STATE* +This service is used to get the current power state of a device power domain. + +[#table_devpower_getstate_request_data] +.Request Data +[cols="1, 2, 1, 5", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | DOMAIN_ID | uint32 | Device power domain ID +|=== + +[#table_devpower_getstate_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Service completed successfully. +! RPMI_ERROR_NOT_FOUND ! Device power domain not found. +! RPMI_ERROR_DENIED ! Client does not have permissions to change the Device power domain power state. +!=== +- Other errors <> +| 1 | POWER_STATE | uint32 | This field indicates the power state to which the power domain should transition. The specific power states and their +meanings may vary depending on the implementation, but generally, they include +values such as "ON", "OFF" and vendor specific power state. + +See Power States table in the service group description +|=== \ No newline at end of file diff --git a/src/srvgrp-hart-state-management.adoc b/src/srvgrp-hart-state-management.adoc new file mode 100644 index 0000000..f2220ce --- /dev/null +++ b/src/srvgrp-hart-state-management.adoc @@ -0,0 +1,298 @@ + +=== Service Group - *HART_STATE_MANAGEMENT* (servicegroup_id: 0x00004) +The Hart State Management (HSM) service group defines a set of Hart states and +functionality equivalent to the RISC-V SBI HSM extension. + +Below table lists the services in this group: +[#table_hsm_services] +.Hart State Management Services +[cols="1, 3, 2", width=100%, align="center", options="header"] +|=== +| Service ID | Service Name | Request Type +| 0x01 | ENABLE_NOTIFICATION | NORMAL_REQUEST +| 0x02 | HART_START | NORMAL_REQUEST +| 0x03 | HART_STOP | NORMAL_REQUEST +| 0x04 | HART_SUSPEND | NORMAL_REQUEST +| 0x05 | GET_HART_STATUS | NORMAL_REQUEST +| 0x06 | GET_HART_LIST | NORMAL_REQUEST +| 0x07 | GET_SUSPEND_TYPES | NORMAL_REQUEST +| 0x08 | GET_SUSPEND_INFO | NORMAL_REQUEST +|=== + +==== Hart State Management Notifications +This service group does not support any event for notification + +==== Service: *ENABLE_NOTIFICATION* +This service allows AP to subscribe to system reset service group notifications. +Platform can optionally support notifications of events which might occur in the +platform. PuC can send these notification messages to AP if they are implemented +and AP has subscribed to these. Events supported are described above in +Hart State Management Notifications. +[#table_hsm_ennotification_request_data] +.Request Data +[cols="1, 2, 1, 5", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | EVENT_ID | uint32 | Event to be subscribed for +notification. +|=== + +[#table_hsm_ennotification_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Notifications are subscribed successfully. +! RPMI_ERROR_NOT_FOUND ! EVENT_ID is not supported or invalid. +! RPMI_ERROR_NOT_SUPPORTED ! Notifications not supported. +!=== +- Other errors <> +|=== + +==== Service: *HART_START* +This service helps start (or power up) a hart with a specified hart-id. +Successful completion of this service means that hart with specified hart-id has +started execution from the provided start address. The previous state of the +hart before this service was called is platform specific. It's possible that +hart was already started or hart with specified hart-id does not exist. +Implementation should return proper error code in the status field accordingly. + +[#table_hsm_hartstart_request_data] +.Request Data +[cols="1, 2, 1, 5", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | HART_ID | uint32 | Hart ID of the hart to be started. +| 1 | START_ADDR_LOW | uint32 | Lower `32 bit` of start address. +| 2 | START_ADDR_HIGH | uint32 | Higher `32 bit` of start address. +|=== + +[#table_hsm_hartstart_response_data] +.Response Data +[cols="1, 2, 1, 9a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Service completed successfully and hart is started. +! RPMI_ERROR_INVALID_PARAMETER ! HART_ID is invalid. +!=== +- Other errors <> +|=== + +==== Service: *HART_STOP* +This service stops the calling hart. Mechanism to stop the hart is platform +specific. Hart can be powered down if supported or it can be put into a deepest +sleep state supported. Platform must acknowledge that hart can be stopped and +return success. Application Processor must execute WFI upon successful +acknowledgement. Platform then proceeds to stop the hart. Detecting the WFI +state from PuC is implementation defined. Once the hart is stopped it can only +be started using an explicit HART_START service call from the application +processor. + +[#table_hsm_hartstop_request_data] +.Request Data +[cols="1, 2, 1, 5", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | HART_ID | uint32 | Hart ID of the calling hart. +|=== + +[#table_hsm_hartstop_response_data] +.Response Data +[cols="1, 2, 1, 9a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Service completed successfully and hart is started. +! RPMI_ERROR_DENIED ! Not allowed due to current hart state which is platform +specific +!=== +- Other errors <> +|=== + +==== Service: *HART_SUSPEND* +This service puts the calling hart in suspended (or low power) state. Upon +success, the calling hart is suspended only after it executes WFI instruction. + +[#table_hsm_hartsuspend_request_data] +.Request Data +[cols="1, 2, 1, 5", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | HART_ID | uint32 | Hart ID of the calling hart. +| 1 | SUSPEND_TYPE | uint32 | Hart suspend type as defined by RISC-V +SBI Extension[[TODO LINK HERE]] +| 2 | RESUME_ADDR_LOW | uint32 | Lower `32 bit` of resume address. + +_Only used for non-retentive suspend types._ +| 3 | RESUME_ADDR_HIGH | uint32 | Higher `32 bit` of resume address. + +_Only used for non-retentive suspend types._ +|=== + +[#table_hsm_hartsuspend_response_data] +.Response Data +[cols="1, 2, 1, 9a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Service completed successfully and hart is started. +! RPMI_ERROR_INVALID_PARAMETER ! Invalid SUSPEND_TYPE. +!=== +- Other errors <> +|=== + +==== Service: *GET_HART_STATUS* +This service gets the running status of a Hart. + +[#table_hsm_gethartstatus_request_data] +.Request Data +[cols="1, 2, 1, 5", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | HART_ID | uint32 | Hart ID. +|=== + +[#table_hsm_gethartstatus_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Notifications are subscribed successfully. +! RPMI_ERROR_INVALID_PARAMETER ! Invalid HART_ID. +!=== +- Other errors <> +| 1 | HART_STATUS | uint32 | Hart status values +[cols="2,5"] +!=== +! *Value* ! *Description* +! 0x0 ! STARTED +! 0x1 ! STOPPED +! 0x2 ! START_PENDING +! 0x3 ! STOP_PENDING +! 0x4 ! SUSPENDED +! 0x5 ! RESUME_PENDING +! 0x6 - 0xFFFFFFFF ! _Reserved_ +!=== +|=== + +==== Service: *GET_HART_LIST* +This service gets the list of harts with a specified Hart ID start index + +[#table_hsm_gethartlist_request_data] +.Request Data +[cols="1, 2, 1, 5", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | START_INDEX | uint32 | Starting index of Hart ID. +|=== + +[#table_hsm_gethartlist_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Notifications are subscribed successfully. +! RPMI_ERROR_INVALID_PARAMETER ! Invalid START_INDEX. +!=== +- Other errors <> +| 1 | REMAINING | uint32 | Number of remaining items in the list pending to be returned. +| 2 | RETURNED | uint32 | Total number of items returned so far. +| 3 | HART_ID[0] | uint32 | HART_ID +| 4 | HART_ID[1] | uint32 | HART_ID +| 5 | HART_ID[N - 1] | uint32 | HART_ID +|=== + +==== Service: *GET_SUSPEND_TYPES* +This service gets a list of all supported suspend types. The system types in the +list must be ordered based on increasing power savings. + +[#table_hsm_getsuspendtypes_request_data] +.Request Data +[cols="1, 2, 1, 5", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | START_INDEX | uint32 | Starting index of Hart ID list. + +`0` for the first call, subsequent calls will use the next index of the remaining +items. +|=== + +[#table_hsm_getsuspendtypes_response_data] +.Response Data +[cols="1, 3, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Notifications are subscribed successfully. +! RPMI_ERROR_INVALID_PARAMETER ! Invalid START_INDEX. +!=== +- Other errors <> +| 1 | REMAINING | uint32 | Number of remaining items in the list pending to be returned. +| 2 | RETURNED | uint32 | Total number of items returned so far. +| 3 | SUSPEND_TYPE[0] | uint32 | Suspend Type +| 4 | SUSPEND_TYPE[1] | uint32 | Suspend Type +| 5 | SUSPEND_TYPE[N - 1] | uint32 | Suspend Type +|=== + +==== Service: *GET_SUSPEND_INFO* +Get attributes of a suspend type. + +[#table_hsm_getsuspendinfo_request_data] +.Request Data +[cols="1, 2, 1, 5", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | SUSPEND_TYPE | uint32 | Suspend type. +|=== + +[#table_hsm_getsuspendinfo_response_data] +.Response Data +[cols="1, 3, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Notifications are subscribed successfully. +! RPMI_ERROR_INVALID_PARAMETER ! Invalid SUSPEND_TYPE. +!=== +- Other errors <> +| 1 | FLAGS | uint32 | +[cols="2,5a"] +!=== +! *Bits* ! *Description* +! [31] ! + + 0b0: Counter does not stop if this bit is cleared. + 0b1: Local timer stops when the hart is suspended if this bit is set. +! [30:0] ! _Reserved, must be initialized to_ `0`. +!=== +| 2 | ENTRY_LATENCY_US | uint32 | Entry latency in microseconds. +| 3 | EXIT_LATENCY_US | uint32 | Exit latency in microseconds. +| 4 | WAKEUP_LATENCY_US | uint32 | Wakeup latency in microseconds. +| 5 | MIN_RESIDENCY_US | uint32 | Minimum residency latency in +microseconds. +|=== \ No newline at end of file diff --git a/src/srvgrp-management.adoc b/src/srvgrp-management.adoc new file mode 100644 index 0000000..aafc62d --- /dev/null +++ b/src/srvgrp-management.adoc @@ -0,0 +1,201 @@ + +=== Service Group - *MANAGEMENT* (servicegroup_id: 0x0000A) +This management service extension is designed to be used for software invocation of Management Mode (MM) in a secure execution environment. For general background +on Management Mode (MM), review the Platform Initialization (PI) specifications, +Volume 4: Management Mode Core Interface. Management Mode (MM) provides an +environment for implementing OS agnostic services (MM services) like secure +variable storage, and firmware updates in system firmware. The services can be +invoked synchronously and asynchronously. This service group describes the +interfaces for invoking MM services synchronously. + +[#table_mm_services] +.Management Services +[cols="1, 3, 2", width=100%, align="center", options="header"] +|=== +| Service ID | Service Name | Request Type +| 0x01 | ENABLE_NOTIFICATION | NORMAL_REQUEST +| 0x02 | MM_VERSION | NORMAL_REQUEST +| 0x03 | MM_COMMUNICATE | NORMAL_REQUEST +| 0x04 | MM_COMPLETE | NORMAL_REQUEST +| 0x05 | MM_INITIALIZE | NORMAL_REQUEST +|=== + +==== Management Notifications +This service group does not support any event for notification. + +==== Service: *ENABLE_NOTIFICATION* +This service allows AP to subscribe to management service group notifications. +Platform can optionally support notifications of events which might occur in +the platform. PuC can send these notification messages to AP if they are +implemented and AP has subscribed to these. Events supported are described above +in Management Notifications. + +[#table_mm_ennotification_request_data] +.Request Data +[cols="1, 2, 1, 5", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | EVENT_ID | uint32 | Event to be subscribed for +notification. +|=== + +[#table_mm_ennotification_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Notifications are subscribed successfully. +! RPMI_ERROR_NOT_FOUND ! EVENT_ID is not supported or invalid. +! RPMI_ERROR_NOT_SUPPORTED ! Notifications not supported. +!=== +- Other errors <> +|=== + + + +==== Service: *MM_VERSION* +This service returns the version of a management mode service. + +[#table_mm_version_request_data] +.Request Data +- NA + +[#table_mm_version_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Service completed successfully. +! RPMI_ERROR_DENIED ! Denied due to no permission. +!=== +- Other errors <> +| 1 | MM_VERSION | uint32 | Management mode service version. +[cols="2,5"] +!=== +! *Bits* ! *Description* +! [31:16] ! Major Version +! [15:0] ! Minor Version +!=== +|=== + + + +==== Service: *MM_COMMUNICATE* +Calling this MM_COMMUNICATE api invokes a MM service that is implemented in the +secure execution environment. The MM_COMM_BUFFER contains data to identify and +invoke the MM service. This synchronous call is returned by using MM_COMPLETE. + +[#table_mm_communicate_request_data] +.Request Data +[cols="1, 2, 1, 5", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | MM_COMM_BUFFER | uint32 | MM data from non-secure to secure +world. +|=== + +[#table_mm_communicate_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Service completed successfully. +! RPMI_ERROR_DENIED ! Denied due to no permission. +!=== +- Other errors <> +|=== + + + +==== Service: *MM_COMPLETE* +Use this MM_COMPLETE as the “world-switch synchronous call” normally at the end +of a synchronous MM_COMMUNICATE call to signal the readiness for handling the +synchronous request. The MM_COMM_BUFFER contains the returned data of the MM +service invoked. + +[#table_mm_complete_request_data] +.Request Data +[cols="1, 2, 1, 5", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | MM_COMM_BUFFER | uint32 | MM data from non-secure to secure +world. +|=== + +[#table_mm_complete_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Service completed successfully. +! RPMI_ERROR_DENIED ! Denied due to no permission. +!=== +- Other errors <> +|=== + + + +==== Service: *MM_INITIALIZE* +This is an optional service. The MM modules may come in the firmware volume or +FD files, loaded by the M-mode firmware like u-boot spl and initialized by the +OpenSBI domain during the M-Mode firmware boot time. If so, this service api is +not needed as default. But there is still case that the MM modules are requested +to be loaded or initialized by the S-Mode firmware components, thus this service +is used to launch the MM related modules as needed. + +[#table_mm_initialize_request_data] +.Request Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | HART_ID | uint8 | Hart ID to launch +| 1 | DOMAIN_ID | uint8 | Secure domain ID to be used to +initialize the mm modules. +| 2:3 | FLAGS | uint16 | +[cols="2,5a"] +!=== +! *Bits* ! *Description* +! [31:1] ! _Reserved_ +! [0] ! + + 0b0: No payload information. + 0b1: With payload information. +!=== +| 4:5 | MM_PAYLOAD_BASE | uint64 | Base address of MM payload +loaded by the S-Mode firmware. +| 6:7 | MM_PAYLOAD_SIZE | uint64 | MM payload size loaded by the +S-Mode firmware. +| 8:263 | MM_PAYLOAD_SIGNATURE | uint8 | MM payload signature loaded by +the S-Mode firmware. +|=== + +[#table_mm_initialize_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Service completed successfully. +! RPMI_ERROR_DENIED ! Denied due to no permission. +!=== +- Other errors <> +|=== \ No newline at end of file diff --git a/src/srvgrp-performance.adoc b/src/srvgrp-performance.adoc new file mode 100644 index 0000000..bc09cb5 --- /dev/null +++ b/src/srvgrp-performance.adoc @@ -0,0 +1,468 @@ + +=== Service Group - *PERFORMANCE* (servicegroup_id: 0x00009) +This performance domain extension is designed for managing the performance of a +group of devices or application processors that operate in the same performance domain. Unlike legacy performance control mechanisms where the OS was +responsible to directly control the voltage and clocks this mechanism instead +operates on an metric less integer performance scale. Each integer value on this +scale represents a performance operating point. What this scale represents and +the metric is completely platform dependent. Values on this scale are discrete +and the platform is given complete control over mapping these performance +operating points to performance states which eventually gets converted into +hardware parameters like voltage and frequency, etc. The mapping between levels +and frequencies can be as simple as using a multiplication factor of 1000. + +CPPC service group is also meant for performance control but it's only for the application processors. This service group is primarily meant for devices like +GPUs, Accelerators, etc but can also be used for application processors. + +It is important to note that performance domains should not be confused with +power domains. A performance domain is defined as a set of devices that must +always run at the same performance level, while a power domain is defined as a +set of devices that can be turned on or off together for power management +purposes. + +The Performance service groups provide a set of services for managing +performance domains. These services include retrieving performance domain +information, setting the performance level, obtaining the current performance +level of a performance domain, and performing other related operations. These operations are described in more detail in the following section. + +[#table_perf_services] +.Performance Services +[cols="1, 3, 2", width=100%, align="center", options="header"] +|=== +| Service ID | Service Name | Request Type +| 0x01 | ENABLE_NOTIFICATION | NORMAL_REQUEST +| 0x02 | GET_PERF_DOMAINS | NORMAL_REQUEST +| 0x03 | GET_PERF_DOMAIN_ATTRIBUTES | NORMAL_REQUEST +| 0x04 | GET_PERF_DOMAIN_LEVELS | NORMAL_REQUEST +| 0x05 | GET_PERF_LEVEL | NORMAL_REQUEST +| 0x06 | SET_PERF_LEVEL | NORMAL_REQUEST +| 0x07 | GET_PERF_LIMIT | NORMAL_REQUEST +| 0x08 | SET_PERF_LIMIT | NORMAL_REQUEST +| 0x09 | GET_PERF_DOMAIN_FAST_CHANNEL_ADDR | NORMAL_REQUEST +|=== + +==== Performance Notifications +When a client registers for performance change notifications, the platform will +send notification to the client whenever there is a change in the performance +level, performance limit or the performance power of a specific performance +domain. This notification is typically sent by the platform control processor to inform clients in the system about changes in the performance domain. + +[#table_perf_notification_events] +.Performance Notification Events +[cols="1, 2, 5a, 2", width=100%, align="center", options="header"] +|=== +| Event ID | Name | Event Data | Description +| 0x001 | PERF_POWER_CHANGE | +[cols="2,2,5"] +!=== +! *Word* ! Type ! *Description* +! 0 ! uint32 ! Performance domain ID whose power changed. +! 1 ! uint32 ! New Power value(uW) +!=== +| Performance power changed notification. + +| 0x002 | PERF_LIMIT_CHANGE | +[cols="2,2,5"] +!=== +! *Word* ! Type ! *Description* +! 0 ! uint32 ! Performance domain ID whose performance limit +changed. +! 1 ! uint32 ! New Max Perf Level. +! 2 ! uint32 ! New Min Perf Level. +!=== +| Performance limit changed notification. + +| 0x003 | PERF_LEVEL_CHANGE | +[cols="2,2,5"] +!=== +! *Word* ! Type ! *Description* +! 0 ! uint32 ! Performance domain ID whose performance level changed. +! 1 ! uint32 ! New Perf Level. +!=== +| Performance level changed notification. +|=== + +==== Service: *ENABLE_NOTIFICATION* +This service is to enable or disable the performance changed notification event. +This notification is sent from the PuC when the performance level, performance +limit or performance power of a performance domain has changed. This allows the +system to adjust its behavior in response to performance changes and ensure that +it is operating within its desired performance level. + +[#table_perf_ennotification_request_data] +.Request Data +[cols="1, 2, 1, 5", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | EVENT_ID | uint32 | Event to be subscribed for +notification. +|=== + +[#table_perf_ennotification_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Notifications are subscribed successfully. +! RPMI_ERROR_NOT_FOUND ! EVENT_ID is not supported or invalid. +! RPMI_ERROR_NOT_SUPPORTED ! Notifications not supported. +!=== +- Other errors <> +|=== + + +==== Service: *GET_PERF_DOMAINS* +Returns the number of performance domains supported by the system. +The number of performance domains can vary depending on the hardware platform +and implementation. In general, performance domains are used to group related +hardware components, such as CPUs, GPUs, memory, and peripherals, into separate +domains that can be independently controlled and managed. This allows for more +fine-grained control over the performance of specific components, which can be +important for optimizing system performance and power consumption. + +[#table_perf_getdomains_request_data] +.Request Data +- NA + +[#table_perf_getdomains_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Service completed successfully. +!=== +- Other errors <> +| 1 | NUM_DOMAINS | uint32 | Number of domains +|=== + + +==== Service: *GET_PERF_DOMAIN_ATTRIBUTES* +This service is used to retrieve the attributes of a specific performance +domain. These attributes provide information about the performance capabilities +and constraints of the domain, such as the performance limit and performance +level. + +[#table_perf_getattrs_request_data] +.Request Data +[cols="1, 2, 1, 5", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | DOMAIN_ID | uint32 | Performance domain ID +|=== + +[#table_perf_getattrs_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Service completed successfully. +! RPMI_ERROR_NOT_FOUND ! Performance domain not found +!=== +- Other errors <> +| 1 | FLAGS | uint32 | +[cols="2,5a"] +!=== +! *Bits* ! *Description* +! [31] ! PERF_LIMIT_SETTING + +This attribute indicates whether the platform allows software to set the +performance limit/range for a specific performance domain. + + 0b0: Performance limit change not allowed. + 0b1: Performance limit change allowed. +! [30] ! PERF_LEVEL_SETTING + +This attribute indicates whether the platform allows software to set the +performance level for a specific performance domain. + + 0b0: Performance level change not allowed. + 0b1: Performance level change allowed. +! [29] ! FAST_CHANNEL_SUPPORT + +This attribute indicates whether the platform supports low latency communication +channels for performance domain management. + + 0b0: Not supported + 0b1: Supported +! [28:21] ! TOTAL_NUM_PERF_LEVELS + +Total number of performance levels supported. +! [20:0] ! _Reserved_ +!=== +| 2 | RATE_LIMIT_US | uint32 | Minimum amount of time that needs to +pass between two consecutive requests, in microsecond(us). +| 3:6 | PERF_DOMAIN_NAME | uint8[16] | A NULL-terminated string for performance domain name. Up to 16-Bytes. +|=== + +==== Service: *GET_PERF_DOMAIN_LEVELS* +This service provides a list of the available Performance levels or also called Operating performance points (OPPs) for a specific performance domain. These +represent different performance levels that can be set for the components in the domain, and are defined by a combination of frequency, power cost and other parameters. By utilizing this information, the OS can choose the optimal +performance level for the system workload and power constraints. + +```c +/* Pseudocode to retrieve the list of the supported OPP */ + +index = 0; +num = 0; +/* Allocate a buffer based on the value returned from the flags[28:21] */ +total_num_levels = perf_domain_attributes.flags[28:21]; + +loop: + list = get_domain_opp_list(index, domain_id); + entry_num = 0; + + for (i = 0; i < list.returned; i++, num++) { + opp[num].level = list.entry[entry_num++]; + opp[num].power = list.entry[entry_num++]; + opp[num].rate_limit = list.entry[entry_num++]; + } + + /* Check if there are remaining OPP to be read */ + if (list.remaining) { + index += list.returned; + goto loop; + } + + +``` +The pseudocode above demonstrates the process for retrieving the level information for a specific performance domain. First, the number of performance levels is determined by checking the FLAGS[28:21] parameter returned by the GET_PERF_DOMAIN_ATTRIBUTES service. + +Total words required for the number of performance levels according to the format in one message cannot exceed the total words available in one message DATA field. If they exceed then PuC will return the number of levels which can be accommodated in one message and set the REMAINING field accordingly. AP, when REMAINING field is not 0 must call this service again with appropriate PERF_LEVEL_INDEX set to get the remaining levels. It's possible that multiple service calls may be required to get all the levels. + +[#table_perf_getdomainlevels_request_data] +.Request Data +[cols="1, 2, 1, 5", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | DOMAIN_ID | uint32 | Performance Domain ID. This field +specifies the identifier of the performance domain whose OPPs are being +described. +| 1 | PERF_LEVEL_INDEX | uint32 | Start array index to read. +First index starts from zero. +|=== + +[#table_perf_getdomainlevels_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Service completed successfully. +! RPMI_ERROR_NOT_FOUND ! Performance domain not found. +! RPMI_ERROR_INVALID_PARAM ! PERF_LEVEL_INDEX is invalid. +!=== +- Other errors <> +| 1 | FLAGS | uint32 | _Reserved_ and must be `0`. +| 2 | REMAINING | uint32 | Remaining number of levels. +| 3 | RETURNED | uint32 | Number of levels returned. Each level +comprimises of three 32 bit words. +| 4 | LEVEL[0] | uint32 | Performance Level +[cols="1,5"] +!=== +! *Word* ! *Description* +! 0 ! OPP-level, a unique ID representing the performance level within the +OPP table. +! 1 ! Power Cost in microwatt (uW). This is an optional parameter. +Set to value of zero to indicate that power cost is not returned by the +platform. +! 2 ! Transition latency in microsecond(us). +!=== +| 5 | LEVEL[1] | uint32 | Performance Level +| ... | LEVEL[N-1] | uint32 | Performance Level +|=== + + +==== Service: *GET_PERF_LEVEL* +This service is used to obtain the current performance level of a specific +performance domain in the system. + +[#table_perf_getlevel_request_data] +.Request Data +[cols="1, 2, 1, 5a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | DOMAIN_ID | uint32 | Performance Domain ID +|=== + +[#table_perf_getlevel_response_data] +.Response Data +[cols="1, 2, 1, 5a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Service completed successfully. +! RPMI_ERROR_NOT_FOUND ! Performance domain not found. +!=== +- Other errors <> +| 1 | LEVEL | uint32 | Current performance level of the domain +|=== + + +==== Service: *SET_PERF_LEVEL* +This service is used to set the current performance level of a specific +performance domain in the system. + +[#table_perf_setlevel_request_data] +.Request Data +[cols="1, 2, 1, 5a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | DOMAIN_ID | uint32 | Performance Domain ID +| 1 | LEVEL | uint32 | Performance level +|=== + +[#table_perf_setlevel_response_data] +.Response Data +[cols="1, 2, 1, 5a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Service completed successfully. +! RPMI_ERROR_NOT_FOUND ! Performance domain not found. +! RPMI_ERROR_INVALID_PARAMETER ! Invalid performance level. +! RPMI_ERROR_NOT_SUPPORTED ! Performance level change not allowed. +! RPMI_ERROR_DENIED ! Client does not have permission to change the +performance level. +! RPMI_ERROR_HW ! Operation failed due to hardware error. +!=== +- Other errors <> +|=== + + +==== Service: *GET_PERF_LIMIT* +This service is used to obtain the current performance limit of a specific +performance domain in the system. + +[#table_perf_getlimit_request_data] +.Request Data +[cols="1, 2, 1, 5a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | DOMAIN_ID | uint32 | Performance Domain ID +|=== + +[#table_perf_getlimit_response_data] +.Response Data +[cols="1, 2, 1, 5a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Service completed successfully. +! RPMI_ERROR_NOT_FOUND ! Performance domain not found. +!=== +- Other errors <> +| 1 | MAX_PERF_LEVEL | uint32 | Max allowed performance level. +| 2 | MIN_PERF_LEVEL | uint32 | Min allowed performance level. +|=== + + +==== Service: *SET_PERF_LIMIT* +This service is used to set the current performance limit of a specific +performance domain in the system. + +[#table_perf_setlimit_request_data] +.Request Data +[cols="1, 2, 1, 5a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | DOMAIN_ID | uint32 | Performance Domain ID +| 1 | MAX_PERF_LEVEL | uint32 | Max allowed performance level +| 1 | MIN_PERF_LEVEL | uint32 | Min allowed performance level +|=== + +[#table_perf_setlimit_response_data] +.Response Data +[cols="1, 2, 1, 5a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Service completed successfully. +! RPMI_ERROR_NOT_FOUND ! Performance domain not found. +! RPMI_ERROR_INVALID_PARAMETER ! Invalid performance level. +! RPMI_ERROR_NOT_SUPPORTED ! Performance limit change not allowed. +! RPMI_ERROR_DENIED ! Client does not have permission to change the +performance level. +! RPMI_ERROR_HW ! Operation failed due to hardware error. +!=== +- Other errors <> +|=== + + +==== Service: *GET_PERF_DOMAIN_FAST_CHANNEL_ADDR* +This service allows clients to query attributes of the fast channel for the specific performance domain and the specific function. + +[#table_perf_getfastchanaddr_request_data] +.Request Data +[cols="1, 2, 1, 5", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | DOMAIN_ID | uint32 | Performance domain ID +|=== + +[#table_perf_getfastchanaddr_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Service completed successfully. +! RPMI_ERROR_NOT_FOUND ! Performance domain not found +! RPMI_ERROR_NOT_SUPPORTED ! Fast channel not implemented +!=== +- Other errors <> +| 1 | FLAGS | uint32 | +[cols="2,5a"] +!=== +! *Bits* ! *Description* +! [31:3] ! _Reserved_ +! [2:1] ! Doorbell Register Width + + 0b00: 8 bit + 0b01: 16 bit + 0b10: 32 bit + 0b11: 64 bit +! [0] ! + + 0b0: Doorbell not supported + 0b1: Doorbell supported +!=== +| 2 |PHYS_ADDR_LOW | uint32 | Low `32 bit` of physical address +| 3 |PHYS_ADDR_HIGH | uint32 | High `32 bit` of physical address +| 4 |DB_ADDR_LOW | uint32 | Low `32 bit` of doorbell address +| 5 |DB_ADDR_HIGH | uint32 | High `32 bit` of doorbell address +| 6 |DB_ID_LOW | uint32 | Low `32 bit` of doorbell ID +| 7 |DB_ID_HIGH | uint32 | High `32 bit` of doorbell ID +| 8 |DB_PRESERVED_LOW | uint32 | A lower `32 bit` doorbell preserved +mask to apply for this service before ring the doorbell. This field is unused +if FLAGS[0] is zero. +| 9 |DB_PRESERVED_HIGH | uint32 | An upper `32 bit` doorbell preserved +mask to apply for this service before ring the doorbell. This field is only +valid if the doorbell register width is 64 bits. This field is unused if +FLAGS[0] is zero. +|=== \ No newline at end of file diff --git a/src/srvgrp-system-reset.adoc b/src/srvgrp-system-reset.adoc new file mode 100644 index 0000000..9592202 --- /dev/null +++ b/src/srvgrp-system-reset.adoc @@ -0,0 +1,139 @@ + +=== Service Group - *SYSTEM_RESET* (servicegroup_id: 0x00002) +This service group provides services to reset or shutdown the system. System +Shutdown or System Cold Reset are Architectural System Reset types. + +System Shutdown causes every component/device in the system to lose power. +Currently, AP is the only entity to request the system shutdown, which means +for Platform Microcontroller it is not important to categorize it as graceful +or forceful shutdown. In case of shutdown request it is implicit for the +Platform micro-controller that AP has prepared itself for the successful +shutdown. + +System Cold Reset also called Power-On-Reset is the power cycling of the +complete system. On the successful system cold reset, all devices will be power +cycled in a implementation defined sequence similar to the first power on of the +system. + +Below table lists the services in this group: +[#table_sysreset_services] +.System Reset Services +[cols="1, 3, 2", width=100%, align="center", options="header"] +|=== +| Service ID | Service Name | Request Type +| 0x01 | ENABLE_NOTIFICATION | NORMAL_REQUEST +| 0x02 | GET_SYSTEM_RESET_ATTRIBUTES | NORMAL_REQUEST +| 0x03 | SYSTEM_RESET | POSTED_REQUEST +|=== + +==== System Reset Notifications +This service group does not support any event for notifications. + +==== Service: *ENABLE_NOTIFICATION* +This service allows AP to subscribe to system reset service group notifications. +Platform can optionally support notifications of events which might occur in the +platform. PuC can send these notification messages to AP if they are +implemented and AP has subscribed to these. Events supported are described above +in System Reset Notifications. +[#table_sysreset_ennotification_request_data] +.Request Data +[cols="1, 2, 1, 5", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | EVENT_ID | uint32 | Event to be subscribed for +notification. +|=== + +[#table_sysreset_ennotification_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Notifications are subscribed successfully. +! RPMI_ERROR_NOT_FOUND ! EVENT_ID is not supported or invalid. +! RPMI_ERROR_NOT_SUPPORTED ! Notifications not supported. +!=== +- Other errors <> +|=== + +==== Service: *GET_SYSTEM_RESET_ATTRIBUTES* +This service is used to discover system reset types supported by the platform. +*System Shutdown* and *System Cold Reset* are mandatory and assumed to be +supported. *System Warm Reset* is a qualified reset type which can be discovered +using this service. Space is reserved for more reset types to be added later as +required. +[#table_sysreset_getsysresetattrs_request_data] +.Request Data +[cols="1, 1, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | RESET_TYPE | uint32 | Reset type value +[cols="2,5"] +!=== +! *Value* ! *Description* +! 0x0 ! System Shutdown +! 0x1 ! System Cold Reset +! 0x2 ! System Warm Reset +! 0x3 - 0xEFFFFFFF ! _Reserved_ +! 0xF0000000 - 0xFFFFFFFF ! _Implementation specific reset types_. +!=== +|=== + +[#table_sysreset_getsysresetattrs_response_data] +.Response Data +[cols="1, 1, 1, 9a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5a"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Attributes returned successfully. +!=== +- Other errors <> +| 1 | FLAGS | uint32 | Attributes of RESET_TYPE +[cols="2,5a"] +!=== +! *Bits* ! *Description* +! [31] ! Reset type support. + + 0b0: RESET_TYPE not supported. + 0b1: RESET_TYPE supported. +! [30:0] ! _Reserved, must be initialized to_ `0`. +!=== +|=== + +==== Service: *SYSTEM_RESET* +This service is used to initiate the system shutdown or reset the system with +the provided type. +*System Shutdown* and *System Cold Reset* are supported implicitly but +*System Warm Reset* and other implementation specific reset types are optional +and discoverable. + +AP must only request for supported reset types which are discovered using the +attributes service. If an unsupported or invalid state is requested the system +might enter into non-functional state +[#table_sysreset_sysreset_request_data] +.Request Data +[cols="1, 1, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | RESET_TYPE | uint32 | +[cols="2,5a"] +!=== +! *Value* ! *Description* +! 0x0 ! System Shutdown +! 0x1 ! System Cold Reset +! 0x2 ! System Warm Reset +! 0x3 - 0xEFFFFFFF ! _Reserved_ +! 0xF0000000 - 0xFFFFFFFF ! _Implementation specific reset types_. +!=== +|=== + +[#table_sysreset_sysreset_response_data] +.Response Data +- NA \ No newline at end of file diff --git a/src/srvgrp-system-suspend.adoc b/src/srvgrp-system-suspend.adoc new file mode 100644 index 0000000..d94468e --- /dev/null +++ b/src/srvgrp-system-suspend.adoc @@ -0,0 +1,136 @@ + +=== Service Group - *SYSTEM_SUSPEND* (servicegroup_id: 0x00003) +This service group provides services to put the entire system in a low power +suspend state. All HARTs except the HART doing system suspend need to be in the +STOPPED state. + +Below if the list of services in this group: +[#table_syssuspend_services] +.System Suspend Services +[cols="1, 3, 2", width=100%, align="center", options="header"] +|=== +| Service ID | Service Name | Request Type +| 0x01 | ENABLE_NOTIFICATION | NORMAL_REQUEST +| 0x02 | GET_SYSTEM_SUSPEND_ATTRIBUTES | NORMAL_REQUEST +| 0x03 | SYSTEM_SUSPEND | NORMAL_REQUEST +|=== + +==== System Suspend Notifications +This service group does not support any event for notification. + +==== Service: *ENABLE_NOTIFICATION* +This service allows AP to subscribe to system reset service group notifications. +Platform can optionally support notifications of events which might occur in the platform. PuC can send these notification messages to AP if they are implemented +and AP has subscribed to these. Events supported are described above in System +Suspend Notifications. +[#table_syssuspend_ennotification_request_data] +.Request Data +[cols="1, 2, 1, 5", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | EVENT_ID | uint32 | Event to be subscribed for +notification. +|=== + +[#table_syssuspend_ennotification_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Notifications are subscribed successfully. +! RPMI_ERROR_NOT_FOUND ! EVENT_ID is not supported or invalid. +! RPMI_ERROR_NOT_SUPPORTED ! Notifications not supported. +!=== +- Other errors <> +|=== + +==== Service: *GET_SYSTEM_SUSPEND_ATTRIBUTES* +This service is used to discover system suspend types supported by the platform. +Each supported system suspend type is identified by SUSPEND_TYPE. + +[#table_syssuspend_getsyssuspendattrs_request_data] +.Request Data +[cols="1, 1, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | SUSPEND_TYPE | uint32 | Suspend type value +[cols="2,5"] +!=== +! *Value* ! *Description* +! 0x0 ! Suspend to Ram +! 0x1 - 0xFFFFFFFF ! _Reserved_ +!=== +|=== + +[#table_syssuspend_getsysuspendattrs_response_data] +.Response Data +[cols="1, 1, 1, 9a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5a"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Attributes returned successfully. +! RPMI_ERROR_NOT_SUPPORTED ! *SUSPEND_TYPE* not supported +!=== +- Other errors <> +| 1 | FLAGS | uint32 | Attributes of SUSPEND_TYPE +[cols="2,5a"] +!=== +! *Bits* ! *Description* +! [31] ! + + 0b0: Custom resume address not supported. + 0b1: Custom resume address supported. +! [30] ! + + 0b0: Suspend not supported + 0b1: Suspend supported +! [29:0] ! _Reserved, must be initialized to_ `0`. +!=== +|=== + +==== Service: *SYSTEM_SUSPEND* +This service puts the system into low power state based on the specified suspend +type. The service requires all harts except the calling hart to be in STOPPED +state as defined by the Hart State Management service group. The system goes +into low power state only after the HART which requested system suspend, +executes WFI instruction. + +[#table_syssuspend_syssuspend_request_data] +.Request Data +[cols="1, 1, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | HART_ID | uint32 | Hart ID of the calling hart. +| 0 | SUSPEND_TYPE | uint32 | +[cols="2,5a"] +!=== +! *Value* ! *Description* +! 0x0 ! Suspend to RAM +! 0x1 - 0xFFFFFFFF ! _Reserved_ +!=== +| RESUME_ADDR_LOW | uint32 | Lower `32 bit` address +| RESUME_ADDR_HIGH | uint32 | High `32 bit` address +|=== + +[#table_syssuspend_syssuspend_response_data] +.Response Data +[cols="1, 2, 1, 9a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_ERROR_NOT_SUPPORTED ! SUSPEND_TYPE not supported. AP must use the +GET_SYSTEM_SUSPEND_ATTRIBUTES service to discover if SUSPEND_TYPE is supported +or not. Only supported SUSPEND_TYPE must be used with this service. +!=== +- Other errors <> +|=== \ No newline at end of file diff --git a/src/srvgrp-voltage.adoc b/src/srvgrp-voltage.adoc new file mode 100644 index 0000000..09ab7e8 --- /dev/null +++ b/src/srvgrp-voltage.adoc @@ -0,0 +1,361 @@ + +=== Service Group - *VOLTAGE* (servicegroup_id: 0x00006) +The complete system can be classified into multiple domains for voltage control. Each domain is the logical group of one or more devices that have a single +voltage source. The action corresponding to the messages in this group controls +the voltage source which affects the device or the group of devices together +since those devices share the same voltage source. Each domain is identified by domain_id which is a `32 bit`` integer starting from `0`. + +Below table lists the services in this group: +[#table_voltage_services] +.Voltage Services +[cols="1, 3, 2", width=100%, align="center", options="header"] +|=== +| Service ID | Service Name | Request Type +| 0x01 | ENABLE_NOTIFICATION | NORMAL_REQUEST +| 0x02 | GET_NUM_DOMAINS | NORMAL_REQUEST +| 0x03 | GET_DOMAIN_ATTRIBUTES | NORMAL_REQUEST +| 0x04 | GET_DOMAIN_LEVELS | NORMAL_REQUEST +| 0x05 | SET_DOMAIN_CONFIG | NORMAL_REQUEST +| 0x06 | GET_DOMAIN_CONFIG | NORMAL_REQUEST +| 0x07 | SET_DOMAIN_LEVEL | NORMAL_REQUEST +| 0x08 | GET_DOMAIN_LEVEL | NORMAL_REQUEST +|=== + +==== Voltage Notifications +This service group does not support any event for notification. + +==== Service: *ENABLE_NOTIFICATION* +This service allows AP to subscribe to voltage service group notifications. +Platform can optionally support notifications of events which might occur in the platform. PuC can send these notification messages to AP if they are implemented +and AP has subscribed to these. Events supported are described above in Voltage Notifications. + + +[#table_voltage_ennotification_request_data] +.Request Data +[cols="1, 2, 1, 5", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | EVENT_ID | uint32 | Event to be subscribed for +notification. +|=== + +[#table_voltage_ennotification_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Notifications are subscribed successfully. +! RPMI_ERROR_NOT_FOUND ! EVENT_ID is not supported or invalid. +! RPMI_ERROR_NOT_SUPPORTED ! Notifications not supported. +!=== +- Other errors <> +|=== + +==== Service: *GET_NUM_DOMAINS* +Request for number of domains available in the system. + +[#table_voltage_getnumdomains_request_data] +.Request Data +- NA + +[#table_voltage_getnumdomains_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Service completed successfully and voltage domains returned +as NUM_DOMAINS. +!=== +- Other errors <> +| 1 | NUM_DOMAINS | uint32 | Number of Domains +|=== + +==== Service: *GET_DOMAIN_ATTRIBUTES* +Each domain may have supported multiple voltage levels which are allowed by the +domain to operate. This message for each domain returns a domain name which is a +null terminated ASCII string of `16 byte`. +Number of levels represents the total number of voltage levels supported by a +voltage domain. Transition latency is the max time taken for voltage to +stabilize when changed on the regulator. Voltage levels depending on the +hardware can be of different formats and this service currently supports Simple +Linear, Multi-Linear and Discrete range. More voltage formats can be supported +in future if required. +[#table_voltage_getdomainattrs_request_data] +.Request Data +[cols="1, 2, 1, 5", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | DOMAIN_ID | uint32 | Voltage Domain ID +|=== + +[#table_voltage_getdomainattrs_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Service completed successfully. +! RPMI_ERROR_NOT_FOUND ! Voltage DOMAIN_ID not found +!=== +- Other errors <> +| 1 | FLAGS | uint32 | +[cols="2,5a"] +!=== +! *Bits* ! *Description* +! [31:30] ! VOLTAGE_FORMAT + + 0b00: Fixed Voltage + + 0b01: Simple Linear Range containing single triplet + (min_uV, max_uV, step_uV). + + 0b10: Multi-Linear range containing multiple linear ranges of type `0x1` + where each range contains (min_uV, min_sel, max_sel, step_uV). + + 0b11: Discrete range. +! [29:1] ! _Reserved_ +! [0] ! ALWAYS_ON + + 0b0: Voltage domain can be enabled/disabled. + + 0b1: Voltage domain is always-on, voltage value can be changed in the + supported voltage range. +!=== +| 2 |NUM_LEVELS | uint32 | Number of voltage levels supported by +domain. Some values are dependent on the VOLTAGE_FORMAT. +[cols="2,5a"] +!=== +! *Value* ! *Description* +! 1 ! VOLTAGE_FORMAT=`0x0` +! 3 ! VOLTAGE_FORMAT=`0x1` +! N ! VOLTAGE_FORMAT=`0x2` or `0x3`. Based on the format here +each item can be a single voltage value or tuple of values. Check VOLTAGE_FORMAT +field in FLAGS. +!=== +| 3 | TRANSITION_LATENCY | uint32 | Transition Latency +| 4:7 | VOLTAGE_DOMAIN_NAME | uint8[16] | Voltage domain name +|=== + +==== Service: *GET_DOMAIN_LEVELS* +Each domain may support multiple voltage levels which are allowed by the domain +to operate. +Depending on the Power supply/Voltage Regulator the domain may support voltage +levels which can be either discrete or stepwise range. Discrete voltage range +will be in sequence starting from lower voltage value at the lowest index to +higher voltage level with increasing index. Number of voltage levels returned +depends on the format of the voltage level. Total words required for the number +levels according to the format in one message cannot exceed the total words +available in one message DATA field. If they exceed then PuC will return the +number of levels which can be accommodated in one message and set the REMAINING +field accordingly. AP, when REMAINING field is not 0 must call this service +again with appropriate VOLTAGE_LEVEL_INDEX set to get the remaining voltage +levels. It's possible that multiple service calls may be required to get all the +voltage levels. + +[#table_voltage_getdomainlevels_request_data] +.Request Data +[cols="1, 2, 1, 5", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | DOMAIN_ID | uint32 | Voltage Domain ID +| 1 | VOLTAGE_LEVEL_INDEX | uint32 | Voltage level index +|=== + +[#table_voltage_getdomainlevels_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Service completed successfully and voltage levels returned. +! RPMI_ERROR_NOT_FOUND ! Voltage DOMAIN_ID not found. +! RPMI_ERROR_INVALID_PARAM ! VOLTAGE_LEVEL_INDEX is not valid +!=== +- Other errors <> +| 1 | FLAGS | uint32 | _Reserved_ and must be `0`. +| 2 | REMAINING | uint32 | Remaining number of levels. +| 3 | RETURNED | uint32 | Number of levels returned so far. +| 4 | VOLTAGE[0] | uint32 | Voltage array where each entry in the +array is a voltage level in microvolts(uV). + +N is specified by the GET_DOMAIN_ATTRIBUTES.NUM_LEVELS. Voltage represented in +microvolt (uV). + +If the bits in GET_DOMAIN_ATTRIBUTES.FLAGS[31:30] are set to `0`, VOLTAGE[0] +contains a fixed voltage level in the array. + +`VOLTAGE[0]: volt_uV` + +If the bits in GET_DOMAIN_ATTRIBUTES.FLAGS[31:30] are set to `1`, it means that +the voltage array contains three entries as below: + +`VOLTAGE[0]: min_uV + +VOLTAGE[1]: max_uV + +VOLTAGE[2]: step_uV` + +If the bits in GET_DOMAIN_ATTRIBUTES.FLAGS[31:30] are set to `2`, it indicates +that the voltage array contains multiple groups of four entries. Each group +represent a linear voltage range and consists of the following entries: + +`VOLTAGE[0] = min_uV + +VOLTAGE[1] = min_sel + +VOLTAGE[2] = max_sel + +VOLTAGE[3] = step_uV` + +If the bits in GET_DOMAIN_ATTRIBUTES.FLAGS[31:30] are set to 3, it means that +the entry array contains discrete voltage levels listed in ascending numeric +order(_Low index represents minimum voltage level, and high index represents +maximum voltage level supported_). + +`VOLTAGE[0]: Voltage0 + +VOLTAGE[1]: Voltage1 + +VOLTAGE[2]: Voltage2 + +VOLTAGE[N - 1]: Voltage(N – 1)` +| 5 | VOLTAGE[1] | int32 | +| ... | VOLTAGE[N-1] | int32 | +|=== + +==== Service: *SET_DOMAIN_CONFIG* +Set voltage config message enable or disable any domain. Enabling the voltage +means applying the domain with the voltage level to operate normally. AP can +enable the voltage to any domain without knowing the actual voltage levels. +Disabling the voltage level means disabling the voltage supply to the domain. + +CONFIG field encodes these discrete settings which do not require AP to know +the voltage level +[#table_voltage_setdomainconfig_request_data] +.Request Data +[cols="1, 2, 1, 5a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | DOMAIN_ID | uint32 | Voltage Domain ID +| 1 | CONFIG | uint32 | Voltage domain config +[cols="2,5a"] +!=== +! *Bits* ! *Description* +! [31:1] ! _Reserved_ +! [0] ! + + 0b0: Disable voltage for domain + + 0b1: Enable voltage for domain +!=== +|=== + +[#table_voltage_setdomainconfig_response_data] +.Response Data +[cols="1, 2, 1, 7a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Service completed successfully. +! RPMI_ERROR_NOT_FOUND ! Voltage DOMAIN_ID not found. +! RPMI_ERROR_INVALID_PARAMETER ! Voltage config is not supported by the +spefified voltage domain. +!=== +- Other errors <> +|=== + +==== Service: *GET_DOMAIN_CONFIG* +Get voltage config message request for the configuration of the voltage domain +currently set. +[#table_voltage_getdomainconfig_request_data] +.Request Data +[cols="1, 2, 1, 5a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | DOMAIN_ID | uint32 | Voltage Domain ID +|=== + +[#table_voltage_getdomainconfig_response_data] +.Response Data +[cols="1, 2, 1, 5a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Service completed successfully. +! RPMI_ERROR_NOT_FOUND ! Voltage DOMAIN_ID not found. +!=== +- Other errors <> +| 1 | CONFIG | uint32 | Voltage domain config +[cols="2,5a"] +!=== +! *Value* ! *Description* +! 0x0 ! Disabled +! 0x1 ! Enabled +!=== +|=== + + +==== Service: *SET_DOMAIN_LEVEL* +Set the voltage level in microvolts(uV) of a voltage domain + +[#table_voltage_setdomainlevel_request_data] +.Request Data +[cols="1, 2, 1, 5a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | DOMAIN_ID | uint32 | Voltage Domain ID +| 1 | VOLTAGE_LEVEL | int32 | Voltage level +|=== + +[#table_voltage_setdomainlevel_response_data] +.Response Data +[cols="1, 2, 1, 5a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Service completed successfully. +! RPMI_ERROR_NOT_FOUND ! Voltage DOMAIN_ID not found. +! RPMI_ERROR_INVALID_PARAMETER ! Voltage level is not supported by specified +voltage domain. +!=== +- Other errors <> +|=== + + +==== Service: *GET_DOMAIN_LEVEL* +Get the current voltage level in microvolts(uV) of a voltage domain. + +[#table_voltage_getdomainlevel_request_data] +.Request Data +[cols="1, 2, 1, 5a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | DOMAIN_ID | uint32 | Voltage Domain ID +|=== + +[#table_voltage_getdomainlevel_response_data] +.Response Data +[cols="1, 2, 1, 5a", width=100%, align="center", options="header"] +|=== +| Word | Name | Type | Description +| 0 | STATUS | int32 | Return Status Code +[cols="2,5"] +!=== +! *Error Code* ! *Description* +! RPMI_SUCCESS ! Service completed successfully. +! RPMI_ERROR_NOT_FOUND ! Voltage DOMAIN_ID not found. +!=== +- Other errors <> +| 1 | VOLTAGE_LEVEL | int32 | Voltage Level +|=== \ No newline at end of file diff --git a/src/transport.adoc b/src/transport.adoc new file mode 100644 index 0000000..4274c2a --- /dev/null +++ b/src/transport.adoc @@ -0,0 +1,154 @@ +:stem: latexmath +== Transport +RPMI Transport is the abstraction over a physical medium used to send and +receive messages between an Application Processor and Platform Microcontroller +enabling bidirectional communication. + +A RPMI transport instance provides a bidirectional communication channel between +a privilege level of a set of APs and one PuC. There can be multiple RPMI +transport instances between a set of APs and one PuC. For example: there can +be a separate transport instance between each privilege level of APs and one +PuC. A platform can also have multiple PuCs with each having its own set of +RPMI transport to communicate with APs. The _Figure 1.2_ above shows different +topologies of RPMI transport. + +The physical medium of a RPMI transport can be shared memory or I2C or SPI or +some other medium. This specification only defines a shared memory based RPMI +transport but a platform can define its own RPMI transport. + +RISC-V S-Mode/M-Mode clients are responsible for the packing of the messages as +per the message binary format requirements described later and sharing the +message via the transport layer. The transport layer abstracts the mechanism of +how the message is physically delivered between Application Processor and +Platform Microcontroller or vice versa. + +.Bidirectional Commmunication +image::transport-bidirectional.png[400,400] + +=== Doorbell Interrupt +A RPMI transport may also provide doorbell interrupts for either Application +Processors or Platform Microcontrollers or both to signal new messages. +The doorbell mechanism is optional for a RPMI transport and implementations can + always use a polling mechanism for checking the arrival of messages. + +The doorbell interrupt from APs to PuC can be a MSI or a wired interrupt with a +RPMI transport specific way to trigger the interrupt. + +The doorbell interrupt from PuC to APs can be either a wired interrupt or +message signaled interrupt (MSI). If the doorbell interrupt from PuC to APs is +a wired interrupt then RPMI transport must define a way to trigger the +interrupt. If the doorbell interrupt from PuC to APs is a MSI then RPMI messages +can be used by APs to configure the MSI. + +=== Shared Memory Transport +The physical memory of the RPMI shared memory transport can be either a device +memory or dedicated SRAM or some portion of DRAM. The RPMI shared memory +transport does not specify where the shared memory resides, but it should be +accessible from both Application Processor and Platform Microcontroller and +all necessary configuration needs to be done to make sure that side effects +related to caching or anything else do not happen. + +NOTE: To avoid the caching side effects, the platform can configure the shared +memory as IO or non-cacheable memory for both APs and PuC. + +All data sent/received through RPMI shared memory MUST follow Little-Endian byte + ordering, unless, optionally, the byte-ordering is discovered during the +transport discovery phase. + +The doorbell interrupt from APs to PuC is optional for RPMI shared memory +transport and if available then it MUST be supported through a read-modify-write +sequence to a memory mapped register. This read-modify-write mechanism can be +discovered by APs via DT or ACPI using properties such as register physical +address, mask, and value. + +The doorbell interrupt from PuC to APs for RPMI shared memory transport is +platform specific. + +The subsequent sections describe the layout and attributes of shared memory +which should be consistent across both Application Processor and Platform +Microcontroller. These attributes can be static for the Platform Microcontroller +and discoverable via DT or ACPI for the Application Processor. + + +==== Attributes of Shared Memory +* `BASE_ADDRESS`: Aligned to `4096 bytes` +* `SIZE`: Aligned to `4096 bytes` +* `SLOT_SIZE`: `>=` 64 bytes + +``` +N bytes : Total Shared Memory Size +M = (N/4) bytes : Single Queue Shared Memory Size +(M-8)/SLOT_SIZE : No. of Slots in Single Queue + +where SLOT_SIZE >= Maximum Message Size +and +8 = No. of Bytes for Head + Tail Slots +``` + +==== Layout of Shared Memory +The shared memory RPMI Transport defines four shared memory based queues for +bidirectional synchronous/asynchronous communication between an AP and PuC. +The detailed layout of shared memory and queues is shown in Figure 2.1. All +queues in shared memory are contiguous and of equal size. Sequence of queues is +arranged such that queues which enable Request-Acknowledgement for a side either +AP to PuC or vice versa are together. + +.Memory Layout of Shared Memory +image::shmem-layout.png[600,600] + +==== Shared Memory Queues +===== AP to PuC Request (*A2P REQ*) +This queue is to transmit REQUEST messages from AP to PuC. + +===== PuC to AP Acknowledgement (*P2A ACK*) +This queue is to transmit the ACKNOWLEDGEMENT messages from PuC to AP for the +request messages received by PuC on A2P REQ Queue. + +===== PuC to AP Request (*P2A REQ*) +This queue is to transmit REQUEST messages from PuC to AP. + +===== AP to PuC Acknowledgement (*A2P ACK*) +This queue is to transmit the ACKNOWLEDGEMENT messages from AP to PuC for the +request messages received by the AP on P2A REQ Queue. + +.Transport Queues +image::highlevel-flow.png[500,500] + +.Transport Architecture +image::highlevel-arch-queues.png[] + +Each queue contains *M* number of slots and each slot stores a single message. +Slot size must be sufficient to store the biggest message in the framework. +Shared memory also contains the head and tail for the enqueuing and dequeuing +of the messages for each queue. The RPMI specification expects a minimum size of +`64 bytes` for each slot but bigger slots may also work depending on the +implementation. + +.Queue Internals +image::queue-internals.png[900,900] + +Slots can be accessed using head and tail which will store the indices. +Head will be used to dequeue the message and Tail will enqueue. + +Head and Tail will be owned and incremented by only a single entity depending on +the role of that entity, whether that entity is enqueuing or dequeuing. +For example, on the A2P channel, Application Processor will enqueue the message +so it will own and increment the Tail, similarly, Platform Microcontroller will +own the head to dequeue the messages and only Platform Microcontroller will +increment the head. + +Once the reader dequeues a message from the slot, it has to mark that slot to be +usable by the writer to enqueue further messages into that slot. Message header +flags are used to mark a message as invalid which makes that slot free to use. + +Like a normal circular queue, it can either be empty, full or have valid +messages. Enqueue operation will check if the queue is not full by checking if +the head is equal to the tail and the slot referenced by the current tail has a +valid message. Similarly, the dequeue operation will check for the empty state +by validating if the slot referenced by the current head has an invalid message. + +Messages which are not consumed yet should not be overwritten and the sender +must block until the slot is available for the sending messages. + +.Queue Slots +image::queue-operation.png[500,500] \ No newline at end of file