blob: 6501f1147fcf5d3e941e0a68776b2736d23dbb0a [file] [log] [blame]
Angel Pons0612b272020-04-05 15:46:56 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Pratik Prajapatib90b94d2015-09-11 13:51:38 -07002
Pratik Prajapatib90b94d2015-09-11 13:51:38 -07003#include <bootstate.h>
4#include <cbfs.h>
5#include <cbmem.h>
6#include <console/console.h>
Pratik Prajapatiffc934d2016-11-18 14:36:34 -08007#include <soc/intel/common/mma.h>
Elyes HAOUASa1e22b82019-03-18 22:49:36 +01008#include <string.h>
Pratik Prajapatib90b94d2015-09-11 13:51:38 -07009
Pratik Prajapatiffc934d2016-11-18 14:36:34 -080010#define MMA_TEST_METADATA_FILENAME "mma_test_metadata.bin"
11#define MMA_TEST_NAME_TAG "MMA_TEST_NAME"
12#define MMA_TEST_PARAM_TAG "MMA_TEST_PARAM"
13#define TEST_NAME_MAX_SIZE 30
14#define TEST_PARAM_MAX_SIZE 100
15#define MMA_DATA_SIGNATURE (('M' << 0) | ('M' << 8) | \
16 ('A' << 16) | ('D' << 24))
Pratik Prajapatib90b94d2015-09-11 13:51:38 -070017
18struct mma_data_container {
Pratik Prajapatiffc934d2016-11-18 14:36:34 -080019 uint32_t mma_signature; /* "MMAD" */
Elyes Haouas5ebf1072023-07-30 13:07:18 +020020 uint8_t mma_data[]; /* Variable size, platform/run time dependent. */
Stefan Reinauer6a001132017-07-13 02:20:27 +020021} __packed;
Pratik Prajapatib90b94d2015-09-11 13:51:38 -070022
23/*
Pratik Prajapatiffc934d2016-11-18 14:36:34 -080024 * Format of the MMA test metadata file, stored under CBFS
25 * MMA_TEST_NAME=xxxxxx.efi;MMA_TEST_PARAM=xxxxxx.bin;
26 */
Pratik Prajapatib90b94d2015-09-11 13:51:38 -070027
Pratik Prajapatiffc934d2016-11-18 14:36:34 -080028/* Returns index in haystack after 'LABEL='
29 * string is found, < 0 on error.
30 */
Pratik Prajapatib90b94d2015-09-11 13:51:38 -070031static int find_label(const char *haystack, size_t haystack_sz,
32 const char *label)
33{
34 size_t label_sz;
35 size_t i;
36 size_t search_sz;
37
38 label_sz = strlen(label);
39
40 if (label_sz + 1 >= haystack_sz)
41 return -1;
42
43 /* Handle '=' follow label. i.e. LABEL= */
44 search_sz = haystack_sz - label_sz - 1;
45 for (i = 0; i < search_sz; i++) {
46 if (!strncmp(&haystack[i], label, label_sz))
47 break;
48 }
49
50 if (i == search_sz)
51 return -1;
52
53 if (haystack[i + label_sz] != '=')
54 return -1;
55
56 return i + label_sz + 1;
57}
Pratik Prajapatiffc934d2016-11-18 14:36:34 -080058
Pratik Prajapatib90b94d2015-09-11 13:51:38 -070059/*
60 * Fill in value in dest field located by LABEL=.
Pratik Prajapatiffc934d2016-11-18 14:36:34 -080061 * Returns 0 on success, < 0 on error.
Pratik Prajapatib90b94d2015-09-11 13:51:38 -070062 */
63static int label_value(const char *haystack, size_t haystack_sz,
Pratik Prajapatiffc934d2016-11-18 14:36:34 -080064 const char *label, char *dest, size_t dest_sz)
Pratik Prajapatib90b94d2015-09-11 13:51:38 -070065{
66 size_t val_begin;
67 size_t val_end;
68 size_t val_sz;
69 int val_index;
70
71 memset(dest, 0, dest_sz);
72
73 /* Allow for NULL termination. */
74 dest_sz--;
75 val_index = find_label(haystack, haystack_sz, label);
76 if (val_index < 0)
77 return -1;
78
79 val_begin = val_index;
80 val_end = val_begin;
81 val_sz = 0;
82
83 for (val_end = val_begin; val_end < haystack_sz; val_end++) {
84 if (haystack[val_end] == ';') {
85 val_sz = val_end - val_begin;
86 break;
87 }
88 }
89
90 if (val_end == haystack_sz)
91 return -1;
92
93 if (dest_sz < val_sz)
94 return -1;
95
96 memcpy(dest, &haystack[val_begin], val_sz);
97
98 return 0;
99}
100
Julius Werner62fa9f32021-04-12 17:23:55 -0700101int mma_map_param(struct mma_config_param *mma_cfg)
Pratik Prajapatide62e0f2016-02-22 16:50:31 -0800102{
Pratik Prajapatiffc934d2016-11-18 14:36:34 -0800103 void *mma_test_metadata;
104 size_t mma_test_metadata_file_len;
Pratik Prajapatib90b94d2015-09-11 13:51:38 -0700105 char test_filename[TEST_NAME_MAX_SIZE],
Pratik Prajapatiffc934d2016-11-18 14:36:34 -0800106 test_param_filename[TEST_PARAM_MAX_SIZE];
Pratik Prajapatiffc934d2016-11-18 14:36:34 -0800107 bool metadata_parse_flag = true;
Pratik Prajapatib90b94d2015-09-11 13:51:38 -0700108
Pratik Prajapatiffc934d2016-11-18 14:36:34 -0800109 printk(BIOS_DEBUG, "MMA: Entry %s\n", __func__);
Pratik Prajapatib90b94d2015-09-11 13:51:38 -0700110
Julius Werner62fa9f32021-04-12 17:23:55 -0700111 mma_test_metadata = cbfs_ro_map(MMA_TEST_METADATA_FILENAME,
112 &mma_test_metadata_file_len);
113 if (!mma_test_metadata) {
114 printk(BIOS_DEBUG, "MMA: Failed to map %s\n",
Pratik Prajapatiffc934d2016-11-18 14:36:34 -0800115 MMA_TEST_METADATA_FILENAME);
116 return -1;
Pratik Prajapatib90b94d2015-09-11 13:51:38 -0700117 }
118
119 if (label_value(mma_test_metadata, mma_test_metadata_file_len,
Pratik Prajapatiffc934d2016-11-18 14:36:34 -0800120 MMA_TEST_NAME_TAG, test_filename,
121 TEST_NAME_MAX_SIZE)) {
122 printk(BIOS_DEBUG, "MMA: Failed to get %s\n",
123 MMA_TEST_NAME_TAG);
124 metadata_parse_flag = false;
Pratik Prajapatib90b94d2015-09-11 13:51:38 -0700125 }
126
Pratik Prajapatiffc934d2016-11-18 14:36:34 -0800127 if (metadata_parse_flag &&
128 label_value(mma_test_metadata, mma_test_metadata_file_len,
Pratik Prajapatib90b94d2015-09-11 13:51:38 -0700129 MMA_TEST_PARAM_TAG, test_param_filename,
Pratik Prajapatiffc934d2016-11-18 14:36:34 -0800130 TEST_PARAM_MAX_SIZE)) {
131 printk(BIOS_DEBUG, "MMA: Failed to get %s\n",
Pratik Prajapatib90b94d2015-09-11 13:51:38 -0700132 MMA_TEST_PARAM_TAG);
Pratik Prajapatiffc934d2016-11-18 14:36:34 -0800133 metadata_parse_flag = false;
Pratik Prajapatib90b94d2015-09-11 13:51:38 -0700134 }
135
Julius Werner62fa9f32021-04-12 17:23:55 -0700136 cbfs_unmap(mma_test_metadata);
Pratik Prajapatiffc934d2016-11-18 14:36:34 -0800137
138 if (!metadata_parse_flag)
139 return -1;
140
141 printk(BIOS_DEBUG, "MMA: Got MMA_TEST_NAME=%s MMA_TEST_PARAM=%s\n",
Pratik Prajapatib90b94d2015-09-11 13:51:38 -0700142 test_filename, test_param_filename);
143
Julius Werner62fa9f32021-04-12 17:23:55 -0700144 mma_cfg->test_content = cbfs_ro_map(test_filename, &mma_cfg->test_content_size);
145 if (!mma_cfg->test_content) {
146 printk(BIOS_DEBUG, "MMA: Failed to map %s\n", test_filename);
Pratik Prajapatiffc934d2016-11-18 14:36:34 -0800147 return -1;
Pratik Prajapatib90b94d2015-09-11 13:51:38 -0700148 }
149
Julius Werner62fa9f32021-04-12 17:23:55 -0700150 mma_cfg->test_param = cbfs_ro_map(test_param_filename, &mma_cfg->test_param_size);
151 if (!mma_cfg->test_param) {
152 printk(BIOS_DEBUG, "MMA: Failed to map %s\n", test_param);
Pratik Prajapatiffc934d2016-11-18 14:36:34 -0800153 return -1;
Pratik Prajapatib90b94d2015-09-11 13:51:38 -0700154 }
155
Pratik Prajapatiffc934d2016-11-18 14:36:34 -0800156 printk(BIOS_DEBUG, "MMA: %s exit success\n", __func__);
Pratik Prajapatiad8c35c2016-04-11 16:44:15 -0700157
Pratik Prajapatiffc934d2016-11-18 14:36:34 -0800158 return 0;
Pratik Prajapatib90b94d2015-09-11 13:51:38 -0700159}
160
161static void save_mma_results_data(void *unused)
162{
Pratik Prajapatiffc934d2016-11-18 14:36:34 -0800163 const void *mma_hob;
164 size_t mma_hob_size;
Pratik Prajapatib90b94d2015-09-11 13:51:38 -0700165 struct mma_data_container *mma_data;
Pratik Prajapatiffc934d2016-11-18 14:36:34 -0800166 size_t mma_data_size;
Pratik Prajapatib90b94d2015-09-11 13:51:38 -0700167
Pratik Prajapatiffc934d2016-11-18 14:36:34 -0800168 printk(BIOS_DEBUG, "MMA: Entry %s\n", __func__);
Pratik Prajapatib90b94d2015-09-11 13:51:38 -0700169
Pratik Prajapatiffc934d2016-11-18 14:36:34 -0800170 if (fsp_locate_mma_results(&mma_hob, &mma_hob_size)) {
Pratik Prajapatib90b94d2015-09-11 13:51:38 -0700171 printk(BIOS_DEBUG,
Pratik Prajapatiffc934d2016-11-18 14:36:34 -0800172 "MMA: results data Hob not present\n");
Pratik Prajapatib90b94d2015-09-11 13:51:38 -0700173 return;
174 }
175
Elyes Haouasd6b6b222022-10-10 12:34:21 +0200176 mma_data_size = ALIGN_UP(mma_hob_size, 16) +
Pratik Prajapatib90b94d2015-09-11 13:51:38 -0700177 sizeof(struct mma_data_container);
Pratik Prajapatiffc934d2016-11-18 14:36:34 -0800178
179 mma_data = cbmem_add(CBMEM_ID_MMA_DATA, mma_data_size);
Pratik Prajapatib90b94d2015-09-11 13:51:38 -0700180
181 if (mma_data == NULL) {
182 printk(BIOS_DEBUG,
Pratik Prajapatiffc934d2016-11-18 14:36:34 -0800183 "MMA: CBMEM was not available to save the MMA data.\n");
Pratik Prajapatib90b94d2015-09-11 13:51:38 -0700184 return;
185 }
186
187 /*clear the mma_data before coping the actual data */
Pratik Prajapatiffc934d2016-11-18 14:36:34 -0800188 memset(mma_data, 0, mma_data_size);
Pratik Prajapatib90b94d2015-09-11 13:51:38 -0700189
190 printk(BIOS_DEBUG,
Julius Werner540a9802019-12-09 13:03:29 -0800191 "MMA: copy MMA data to CBMEM(src %p, dest %p, %u bytes)\n",
Pratik Prajapatiffc934d2016-11-18 14:36:34 -0800192 mma_hob, mma_data, mma_hob_size);
Pratik Prajapatib90b94d2015-09-11 13:51:38 -0700193
194 mma_data->mma_signature = MMA_DATA_SIGNATURE;
Pratik Prajapatiffc934d2016-11-18 14:36:34 -0800195 memcpy(mma_data->mma_data, mma_hob, mma_hob_size);
Pratik Prajapatib90b94d2015-09-11 13:51:38 -0700196
Pratik Prajapatiffc934d2016-11-18 14:36:34 -0800197 printk(BIOS_DEBUG, "MMA: %s exit successfully\n", __func__);
Pratik Prajapatib90b94d2015-09-11 13:51:38 -0700198}
199
200BOOT_STATE_INIT_ENTRY(BS_WRITE_TABLES, BS_ON_ENTRY,
201 save_mma_results_data, NULL);