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