1 /*
2  * Arm SCP/MCP Software
3  * Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include "config_clock.h"
9 #include "scp_sgi575_mmap.h"
10 #include "scp_sgi575_pik.h"
11 #include "scp_software_mmap.h"
12 #include "sgi575_pik_scp.h"
13 #include "sgi575_sds.h"
14 #include "sgi575_ssc.h"
15 
16 #include <mod_sds.h>
17 
18 #include <fwk_assert.h>
19 #include <fwk_element.h>
20 #include <fwk_id.h>
21 #include <fwk_macros.h>
22 #include <fwk_module.h>
23 #include <fwk_module_idx.h>
24 
25 #include <stdbool.h>
26 #include <stdint.h>
27 
28 static const uint32_t version_packed = FWK_BUILD_VERSION;
29 static const uint32_t feature_flags = 0x00000000;
30 
31 static const struct mod_sds_region_desc sds_module_regions[] = {
32     [SGI575_SDS_REGION_SECURE] = {
33         .base = (void*)SCP_SDS_SECURE_BASE,
34         .size = SCP_SDS_SECURE_SIZE,
35     },
36 #ifdef BUILD_MODE_DEBUG
37     [SGI575_SDS_REGION_NONSECURE] = {
38         .base = (void *)SCP_SDS_NONSECURE_BASE,
39         .size = SCP_SDS_NONSECURE_SIZE,
40     },
41 #endif
42 };
43 
44 static_assert(FWK_ARRAY_SIZE(sds_module_regions) == SGI575_SDS_REGION_COUNT,
45               "Mismatch between number of SDS regions and number of regions "
46               "provided by the SDS configuration.");
47 
48 static const struct mod_sds_config sds_module_config = {
49     .regions = sds_module_regions,
50     .region_count = SGI575_SDS_REGION_COUNT,
51     .clock_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK,
52                                     CLOCK_IDX_INTERCONNECT)
53 };
54 
55 static struct sgi575_sds_platid platid;
56 
57 static struct fwk_element sds_element_table[] = {
58     {
59         .name = "CPU Info",
60         .data = &((struct mod_sds_structure_desc) {
61             .id = SGI575_SDS_CPU_INFO,
62             .size = SGI575_SDS_CPU_INFO_SIZE,
63             .region_id = SGI575_SDS_REGION_SECURE,
64             .finalize = true,
65         }),
66     },
67     {
68         .name = "Firmware version",
69         .data = &((struct mod_sds_structure_desc) {
70             .id = SGI575_SDS_FIRMWARE_VERSION,
71             .size = SGI575_SDS_FIRMWARE_VERSION_SIZE,
72             .region_id = SGI575_SDS_REGION_SECURE,
73             .payload = &version_packed,
74             .finalize = true,
75         }),
76     },
77     {
78         .name = "Platform ID",
79         .data = &((struct mod_sds_structure_desc) {
80             .id = SGI575_SDS_PLATFORM_ID,
81             .size = SGI575_SDS_PLATFORM_ID_SIZE,
82             .region_id = SGI575_SDS_REGION_SECURE,
83             .payload = &platid,
84             .finalize = true,
85         }),
86     },
87     {
88         .name = "Reset Syndrome",
89         .data = &((struct mod_sds_structure_desc) {
90             .id = SGI575_SDS_RESET_SYNDROME,
91             .size = SGI575_SDS_RESET_SYNDROME_SIZE,
92             .region_id = SGI575_SDS_REGION_SECURE,
93             .payload = (void *)(&PIK_SCP->RESET_SYNDROME),
94             .finalize = true,
95         }),
96     },
97     {
98         .name = "Feature Availability",
99         .data = &((struct mod_sds_structure_desc) {
100             .id = SGI575_SDS_FEATURE_AVAILABILITY,
101             .size = SGI575_SDS_FEATURE_AVAILABILITY_SIZE,
102             .region_id = SGI575_SDS_REGION_SECURE,
103             .payload = &feature_flags,
104             .finalize = true,
105         }),
106     },
107 #ifdef BUILD_MODE_DEBUG
108     {
109         .name = "Boot Counters",
110         .data = &((struct mod_sds_structure_desc) {
111             .id = SGI575_SDS_CPU_BOOTCTR,
112             .size = SGI575_SDS_CPU_BOOTCTR_SIZE,
113             .region_id = SGI575_SDS_REGION_NONSECURE,
114             .finalize = true,
115         }),
116     },
117     {
118         .name = "CPU Flags",
119         .data = &((struct mod_sds_structure_desc) {
120             .id = SGI575_SDS_CPU_FLAGS,
121             .size = SGI575_SDS_CPU_FLAGS_SIZE,
122             .region_id = SGI575_SDS_REGION_NONSECURE,
123             .finalize = true,
124         }),
125     },
126 #endif
127     { 0 }, /* Termination description. */
128 };
129 
130 static_assert(SCP_SDS_SECURE_SIZE >
131                     SGI575_SDS_CPU_INFO_SIZE +
132                     SGI575_SDS_FIRMWARE_VERSION_SIZE +
133                     SGI575_SDS_PLATFORM_ID_SIZE +
134                     SGI575_SDS_RESET_SYNDROME_SIZE +
135                     SGI575_SDS_FEATURE_AVAILABILITY_SIZE,
136             "SDS structures too large for SDS S-RAM.\n");
137 
138 #ifdef BUILD_MODE_DEBUG
139     static_assert(SCP_SDS_NONSECURE_SIZE >
140                         SGI575_SDS_CPU_BOOTCTR_SIZE +
141                         SGI575_SDS_CPU_FLAGS_SIZE,
142                 "SDS structures too large for SDS NS-RAM.\n");
143 #endif
144 
sds_get_element_table(fwk_id_t module_id)145 static const struct fwk_element *sds_get_element_table(fwk_id_t module_id)
146 {
147     struct ssc_reg *ssc_regs = ((struct ssc_reg *)(SSC_BASE));
148 
149     static_assert(BUILD_VERSION_MAJOR < UINT8_MAX, "Invalid version size");
150     static_assert(BUILD_VERSION_MINOR < UINT8_MAX, "Invalid version size");
151     static_assert(BUILD_VERSION_PATCH < UINT16_MAX, "Invalid version size");
152 
153     platid.platform_identifier = ssc_regs->SSC_VERSION;
154     platid.platform_type_identifier = platid.platform_identifier &
155                                       SGI575_SDS_PLATID_PARTNO_MASK;
156 
157     return sds_element_table;
158 }
159 
160 struct fwk_module_config config_sds = {
161     .data = &sds_module_config,
162     .elements = FWK_MODULE_DYNAMIC_ELEMENTS(sds_get_element_table),
163 };
164