xref: /openbmc/qemu/hw/misc/aspeed_sbc.c (revision 867f7d4087ec3693ae7632b4c71d9241521b6e8a)
1 /*
2  * ASPEED Secure Boot Controller
3  *
4  * Copyright (C) 2021-2022 IBM Corp.
5  *
6  * Joel Stanley <joel@jms.id.au>
7  *
8  * SPDX-License-Identifier: GPL-2.0-or-later
9  */
10 
11 #include "qemu/osdep.h"
12 #include "qemu/log.h"
13 #include "qemu/error-report.h"
14 #include "hw/qdev-properties.h"
15 #include "hw/misc/aspeed_sbc.h"
16 #include "qapi/error.h"
17 #include "migration/vmstate.h"
18 #include "trace.h"
19 
20 #define R_PROT          (0x000 / 4)
21 #define R_CMD           (0x004 / 4)
22 #define R_ADDR          (0x010 / 4)
23 #define R_STATUS        (0x014 / 4)
24 #define R_CAMP1         (0x020 / 4)
25 #define R_QSR           (0x040 / 4)
26 
27 /* R_STATUS */
28 #define ABR_EN                  BIT(14) /* Mirrors SCU510[11] */
29 #define ABR_IMAGE_SOURCE        BIT(13)
30 #define SPI_ABR_IMAGE_SOURCE    BIT(12)
31 #define SB_CRYPTO_KEY_EXP_DONE  BIT(11)
32 #define SB_CRYPTO_BUSY          BIT(10)
33 #define OTP_WP_EN               BIT(9)
34 #define OTP_ADDR_WP_EN          BIT(8)
35 #define LOW_SEC_KEY_EN          BIT(7)
36 #define SECURE_BOOT_EN          BIT(6)
37 #define UART_BOOT_EN            BIT(5)
38 /* bit 4 reserved*/
39 #define OTP_CHARGE_PUMP_READY   BIT(3)
40 #define OTP_IDLE                BIT(2)
41 #define OTP_MEM_IDLE            BIT(1)
42 #define OTP_COMPARE_STATUS      BIT(0)
43 
44 /* QSR */
45 #define QSR_RSA_MASK           (0x3 << 12)
46 #define QSR_HASH_MASK          (0x3 << 10)
47 
48 #define OTP_MEMORY_SIZE 0x4000
49 /* OTP command */
50 #define SBC_OTP_CMD_READ 0x23b1e361
51 #define SBC_OTP_CMD_PROG 0x23b1e364
52 
53 static uint64_t aspeed_sbc_read(void *opaque, hwaddr addr, unsigned int size)
54 {
55     AspeedSBCState *s = ASPEED_SBC(opaque);
56 
57     addr >>= 2;
58 
59     if (addr >= ASPEED_SBC_NR_REGS) {
60         qemu_log_mask(LOG_GUEST_ERROR,
61                       "%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n",
62                       __func__, addr << 2);
63         return 0;
64     }
65 
66     return s->regs[addr];
67 }
68 
69 static bool aspeed_sbc_otp_read(AspeedSBCState *s,
70                                    uint32_t otp_addr)
71 {
72     MemTxResult ret;
73     AspeedOTPState *otp = &s->otp;
74     uint32_t value, otp_offset;
75 
76     otp_offset = otp_addr << 2;
77     ret = address_space_read(&otp->as, otp_offset, MEMTXATTRS_UNSPECIFIED,
78                              &value, sizeof(value));
79     if (ret != MEMTX_OK) {
80         qemu_log_mask(LOG_GUEST_ERROR,
81                       "Failed to read OTP memory, addr = %x\n",
82                       otp_addr);
83         return false;
84     }
85     s->regs[R_CAMP1] = value;
86     trace_aspeed_sbc_otp_read(otp_addr, value);
87 
88     return true;
89 }
90 
91 static bool aspeed_sbc_otp_prog(AspeedSBCState *s,
92                                    uint32_t otp_addr)
93 {
94     MemTxResult ret;
95     AspeedOTPState *otp = &s->otp;
96     uint32_t value = s->regs[R_CAMP1];
97 
98     ret = address_space_write(&otp->as, otp_addr, MEMTXATTRS_UNSPECIFIED,
99                         &value, sizeof(value));
100     if (ret != MEMTX_OK) {
101         qemu_log_mask(LOG_GUEST_ERROR,
102                       "Failed to write OTP memory, addr = %x\n",
103                       otp_addr);
104         return false;
105     }
106 
107     trace_aspeed_sbc_otp_prog(otp_addr, value);
108 
109     return true;
110 }
111 
112 static void aspeed_sbc_handle_command(void *opaque, uint32_t cmd)
113 {
114     AspeedSBCState *s = ASPEED_SBC(opaque);
115     AspeedSBCClass *sc = ASPEED_SBC_GET_CLASS(opaque);
116     bool ret = false;
117     uint32_t otp_addr;
118 
119     if (!sc->has_otp) {
120         qemu_log_mask(LOG_GUEST_ERROR,
121                       "%s: OTP memory is not supported\n",
122                       __func__);
123         return;
124     }
125 
126     s->regs[R_STATUS] &= ~(OTP_MEM_IDLE | OTP_IDLE);
127     otp_addr = s->regs[R_ADDR];
128 
129     switch (cmd) {
130     case SBC_OTP_CMD_READ:
131         ret = aspeed_sbc_otp_read(s, otp_addr);
132         break;
133     case SBC_OTP_CMD_PROG:
134         ret = aspeed_sbc_otp_prog(s, otp_addr);
135         break;
136     default:
137         qemu_log_mask(LOG_GUEST_ERROR,
138                       "%s: Unknown command 0x%x\n",
139                       __func__, cmd);
140         break;
141     }
142 
143     trace_aspeed_sbc_handle_cmd(cmd, otp_addr, ret);
144     s->regs[R_STATUS] |= (OTP_MEM_IDLE | OTP_IDLE);
145 }
146 
147 static void aspeed_sbc_write(void *opaque, hwaddr addr, uint64_t data,
148                               unsigned int size)
149 {
150     AspeedSBCState *s = ASPEED_SBC(opaque);
151 
152     addr >>= 2;
153 
154     if (addr >= ASPEED_SBC_NR_REGS) {
155         qemu_log_mask(LOG_GUEST_ERROR,
156                       "%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n",
157                       __func__, addr << 2);
158         return;
159     }
160 
161     switch (addr) {
162     case R_STATUS:
163     case R_QSR:
164         qemu_log_mask(LOG_GUEST_ERROR,
165                       "%s: write to read only register 0x%" HWADDR_PRIx "\n",
166                       __func__, addr << 2);
167         return;
168     case R_CMD:
169         aspeed_sbc_handle_command(opaque, data);
170         return;
171     default:
172         break;
173     }
174 
175     s->regs[addr] = data;
176 }
177 
178 static const MemoryRegionOps aspeed_sbc_ops = {
179     .read = aspeed_sbc_read,
180     .write = aspeed_sbc_write,
181     .endianness = DEVICE_LITTLE_ENDIAN,
182     .valid = {
183         .min_access_size = 1,
184         .max_access_size = 4,
185     },
186 };
187 
188 static void aspeed_sbc_reset(DeviceState *dev)
189 {
190     struct AspeedSBCState *s = ASPEED_SBC(dev);
191 
192     memset(s->regs, 0, sizeof(s->regs));
193 
194     /* Set secure boot enabled with RSA4096_SHA256 and enable eMMC ABR */
195     s->regs[R_STATUS] = OTP_IDLE | OTP_MEM_IDLE;
196 
197     if (s->emmc_abr) {
198         s->regs[R_STATUS] &= ABR_EN;
199     }
200 
201     if (s->signing_settings) {
202         s->regs[R_STATUS] &= SECURE_BOOT_EN;
203     }
204 
205     s->regs[R_QSR] = s->signing_settings;
206 }
207 
208 static void aspeed_sbc_instance_init(Object *obj)
209 {
210     AspeedSBCClass *sc = ASPEED_SBC_GET_CLASS(obj);
211     AspeedSBCState *s = ASPEED_SBC(obj);
212 
213     if (sc->has_otp) {
214         object_initialize_child(OBJECT(s), "otp", &s->otp,
215                                 TYPE_ASPEED_OTP);
216     }
217 }
218 
219 static void aspeed_sbc_realize(DeviceState *dev, Error **errp)
220 {
221     AspeedSBCState *s = ASPEED_SBC(dev);
222     SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
223     AspeedSBCClass *sc = ASPEED_SBC_GET_CLASS(dev);
224 
225     if (sc->has_otp) {
226         object_property_set_int(OBJECT(&s->otp), "size",
227                                 OTP_MEMORY_SIZE, &error_abort);
228         if (!qdev_realize(DEVICE(&s->otp), NULL, errp)) {
229             return;
230         }
231     }
232 
233     memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_sbc_ops, s,
234             TYPE_ASPEED_SBC, 0x1000);
235 
236     sysbus_init_mmio(sbd, &s->iomem);
237 }
238 
239 static const VMStateDescription vmstate_aspeed_sbc = {
240     .name = TYPE_ASPEED_SBC,
241     .version_id = 1,
242     .minimum_version_id = 1,
243     .fields = (const VMStateField[]) {
244         VMSTATE_UINT32_ARRAY(regs, AspeedSBCState, ASPEED_SBC_NR_REGS),
245         VMSTATE_END_OF_LIST(),
246     }
247 };
248 
249 static const Property aspeed_sbc_properties[] = {
250     DEFINE_PROP_BOOL("emmc-abr", AspeedSBCState, emmc_abr, 0),
251     DEFINE_PROP_UINT32("signing-settings", AspeedSBCState, signing_settings, 0),
252 };
253 
254 static void aspeed_sbc_class_init(ObjectClass *klass, const void *data)
255 {
256     DeviceClass *dc = DEVICE_CLASS(klass);
257 
258     dc->realize = aspeed_sbc_realize;
259     device_class_set_legacy_reset(dc, aspeed_sbc_reset);
260     dc->vmsd = &vmstate_aspeed_sbc;
261     device_class_set_props(dc, aspeed_sbc_properties);
262 }
263 
264 static const TypeInfo aspeed_sbc_info = {
265     .name = TYPE_ASPEED_SBC,
266     .parent = TYPE_SYS_BUS_DEVICE,
267     .instance_size = sizeof(AspeedSBCState),
268     .instance_init = aspeed_sbc_instance_init,
269     .class_init = aspeed_sbc_class_init,
270     .class_size = sizeof(AspeedSBCClass)
271 };
272 
273 static void aspeed_ast2600_sbc_class_init(ObjectClass *klass, const void *data)
274 {
275     DeviceClass *dc = DEVICE_CLASS(klass);
276 
277     dc->desc = "AST2600 Secure Boot Controller";
278 }
279 
280 static const TypeInfo aspeed_ast2600_sbc_info = {
281     .name = TYPE_ASPEED_AST2600_SBC,
282     .parent = TYPE_ASPEED_SBC,
283     .class_init = aspeed_ast2600_sbc_class_init,
284 };
285 
286 static void aspeed_sbc_register_types(void)
287 {
288     type_register_static(&aspeed_ast2600_sbc_info);
289     type_register_static(&aspeed_sbc_info);
290 }
291 
292 type_init(aspeed_sbc_register_types);
293