coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
smi.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <console/console.h>
4 #include <commonlib/region.h>
5 #include <cpu/x86/smm.h>
6 #include <smmstore.h>
7 #include <stddef.h>
8 #include <stdint.h>
9 
10 /*
11  * Check that the given range is legal.
12  *
13  * Legal means:
14  * - not pointing into SMRAM
15  *
16  * returns 0 on success, -1 on failure
17  */
18 static int range_check(void *start, size_t size)
19 {
20  if (smm_points_to_smram(start, size))
21  return -1;
22 
23  return 0;
24 }
25 
26 static uint32_t smmstorev1_exec(uint8_t command, void *param)
27 {
29 
30  switch (command) {
31  case SMMSTORE_CMD_READ: {
32  printk(BIOS_DEBUG, "Reading from SMM store\n");
33  struct smmstore_params_read *params = param;
34 
35  if (range_check(params, sizeof(*params)) != 0)
36  break;
37 
38  if (range_check(params->buf, params->bufsize) != 0)
39  break;
40 
41  if (smmstore_read_region(params->buf, &params->bufsize) == 0)
43  break;
44  }
45 
46  case SMMSTORE_CMD_APPEND: {
47  printk(BIOS_DEBUG, "Appending into SMM store\n");
48  struct smmstore_params_append *params = param;
49 
50  if (range_check(params, sizeof(*params)) != 0)
51  break;
52  if (range_check(params->key, params->keysize) != 0)
53  break;
54  if (range_check(params->val, params->valsize) != 0)
55  break;
56 
57  if (smmstore_append_data(params->key, params->keysize,
58  params->val, params->valsize) == 0)
60  break;
61  }
62 
63  case SMMSTORE_CMD_CLEAR: {
64  if (smmstore_clear_region() == 0)
66  break;
67  }
68  default:
70  "Unknown SMM store v1 command: 0x%02x\n", command);
72  break;
73  }
74 
75  return ret;
76 }
77 
78 static uint32_t smmstorev2_exec(uint8_t command, void *param)
79 {
81 
82  switch (command) {
83  case SMMSTORE_CMD_INIT: {
84  printk(BIOS_DEBUG, "Init SMM store\n");
85  struct smmstore_params_init *params = param;
86 
87  if (range_check(params, sizeof(*params)) != 0)
88  break;
89 
90  void *buf = (void *)(uintptr_t)params->com_buffer;
91 
92  if (range_check(buf, params->com_buffer_size) != 0)
93  break;
94 
95  if (smmstore_init(buf, params->com_buffer_size) == 0)
97  break;
98  }
99  case SMMSTORE_CMD_RAW_READ: {
100  printk(BIOS_DEBUG, "Raw read from SMM store, param = %p\n", param);
101  struct smmstore_params_raw_read *params = param;
102 
103  if (range_check(params, sizeof(*params)) != 0)
104  break;
105 
106  if (smmstore_rawread_region(params->block_id, params->bufoffset,
107  params->bufsize) == 0)
108  ret = SMMSTORE_RET_SUCCESS;
109  break;
110  }
111  case SMMSTORE_CMD_RAW_WRITE: {
112  printk(BIOS_DEBUG, "Raw write to SMM store, param = %p\n", param);
113  struct smmstore_params_raw_write *params = param;
114 
115  if (range_check(params, sizeof(*params)) != 0)
116  break;
117 
118  if (smmstore_rawwrite_region(params->block_id, params->bufoffset,
119  params->bufsize) == 0)
120  ret = SMMSTORE_RET_SUCCESS;
121  break;
122  }
123  case SMMSTORE_CMD_RAW_CLEAR: {
124  printk(BIOS_DEBUG, "Raw clear SMM store, param = %p\n", param);
125  struct smmstore_params_raw_clear *params = param;
126 
127  if (range_check(params, sizeof(*params)) != 0)
128  break;
129 
130  if (smmstore_rawclear_region(params->block_id) == 0)
131  ret = SMMSTORE_RET_SUCCESS;
132  break;
133  }
134  default:
136  "Unknown SMM store v2 command: 0x%02x\n", command);
138  break;
139  }
140 
141  return ret;
142 }
143 
144 uint32_t smmstore_exec(uint8_t command, void *param)
145 {
146  if (command != SMMSTORE_CMD_CLEAR && !param)
147  return SMMSTORE_RET_FAILURE;
148 
149  if (CONFIG(SMMSTORE_V2))
150  return smmstorev2_exec(command, param);
151  else
152  return smmstorev1_exec(command, param);
153 }
static struct sdram_info params
Definition: sdram_configs.c:83
#define printk(level,...)
Definition: stdlib.h:16
static uint32_t smmstorev2_exec(uint8_t command, void *param)
Definition: smi.c:78
uint32_t smmstore_exec(uint8_t command, void *param)
Definition: smi.c:144
static int range_check(void *start, size_t size)
Definition: smi.c:18
static uint32_t smmstorev1_exec(uint8_t command, void *param)
Definition: smi.c:26
@ CONFIG
Definition: dsi_common.h:201
static bool smm_points_to_smram(const void *ptr, const size_t len)
Definition: smm.h:118
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
static uint8_t * buf
Definition: uart.c:7
#define SMMSTORE_CMD_READ
Definition: smmstore.h:15
#define SMMSTORE_CMD_APPEND
Definition: smmstore.h:16
#define SMMSTORE_RET_FAILURE
Definition: smmstore.h:10
#define SMMSTORE_CMD_CLEAR
Definition: smmstore.h:14
#define SMMSTORE_CMD_INIT
Definition: smmstore.h:19
#define SMMSTORE_CMD_RAW_READ
Definition: smmstore.h:20
#define SMMSTORE_CMD_RAW_CLEAR
Definition: smmstore.h:22
#define SMMSTORE_RET_UNSUPPORTED
Definition: smmstore.h:11
#define SMMSTORE_RET_SUCCESS
Definition: smmstore.h:9
#define SMMSTORE_CMD_RAW_WRITE
Definition: smmstore.h:21
unsigned int uint32_t
Definition: stdint.h:14
unsigned long uintptr_t
Definition: stdint.h:21
unsigned char uint8_t
Definition: stdint.h:8
int smmstore_init(void *buf, size_t len)
Call once before using the store.
Definition: store.c:278
int smmstore_append_data(void *key, uint32_t key_sz, void *value, uint32_t value_sz)
Definition: store.c:179
int smmstore_read_region(void *buf, ssize_t *bufsize)
Definition: store.c:97
int smmstore_clear_region(void)
Definition: store.c:242
int smmstore_rawclear_region(uint32_t block_id)
Erases the specified block of the SMMSTORE.
Definition: store.c:441
int smmstore_rawread_region(uint32_t block_id, uint32_t offset, uint32_t bufsize)
Reads the specified block of the SMMSTORE and places it in the communication buffer.
Definition: store.c:372
int smmstore_rawwrite_region(uint32_t block_id, uint32_t offset, uint32_t bufsize)
Writes the specified block of the SMMSTORE by reading it from the communication buffer.
Definition: store.c:406