2 * ASPEED Secure Boot Controller
4 * Copyright (C) 2021-2022 IBM Corp.
6 * Joel Stanley <joel@jms.id.au>
8 * SPDX-License-Identifier: GPL-2.0-or-later
11 #include "qemu/osdep.h"
13 #include "qemu/error-report.h"
14 #include "hw/misc/aspeed_sbc.h"
15 #include "qapi/error.h"
16 #include "migration/vmstate.h"
18 #define R_PROT (0x000 / 4)
19 #define R_STATUS (0x014 / 4)
20 #define R_QSR (0x040 / 4)
22 static uint64_t aspeed_sbc_read(void *opaque
, hwaddr addr
, unsigned int size
)
24 AspeedSBCState
*s
= ASPEED_SBC(opaque
);
28 if (addr
>= ASPEED_SBC_NR_REGS
) {
29 qemu_log_mask(LOG_GUEST_ERROR
,
30 "%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx
"\n",
38 static void aspeed_sbc_write(void *opaque
, hwaddr addr
, uint64_t data
,
41 AspeedSBCState
*s
= ASPEED_SBC(opaque
);
45 if (addr
>= ASPEED_SBC_NR_REGS
) {
46 qemu_log_mask(LOG_GUEST_ERROR
,
47 "%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx
"\n",
55 qemu_log_mask(LOG_GUEST_ERROR
,
56 "%s: write to read only register 0x%" HWADDR_PRIx
"\n",
66 static const MemoryRegionOps aspeed_sbc_ops
= {
67 .read
= aspeed_sbc_read
,
68 .write
= aspeed_sbc_write
,
69 .endianness
= DEVICE_LITTLE_ENDIAN
,
76 static void aspeed_sbc_reset(DeviceState
*dev
)
78 struct AspeedSBCState
*s
= ASPEED_SBC(dev
);
80 memset(s
->regs
, 0, sizeof(s
->regs
));
82 /* Set secure boot enabled with RSA4096_SHA256 and enable eMMC ABR */
83 s
->regs
[R_STATUS
] = 0x000044C6;
84 s
->regs
[R_QSR
] = 0x07C07C89;
87 static void aspeed_sbc_realize(DeviceState
*dev
, Error
**errp
)
89 AspeedSBCState
*s
= ASPEED_SBC(dev
);
90 SysBusDevice
*sbd
= SYS_BUS_DEVICE(dev
);
92 memory_region_init_io(&s
->iomem
, OBJECT(s
), &aspeed_sbc_ops
, s
,
93 TYPE_ASPEED_SBC
, 0x1000);
95 sysbus_init_mmio(sbd
, &s
->iomem
);
98 static const VMStateDescription vmstate_aspeed_sbc
= {
99 .name
= TYPE_ASPEED_SBC
,
101 .minimum_version_id
= 1,
102 .fields
= (VMStateField
[]) {
103 VMSTATE_UINT32_ARRAY(regs
, AspeedSBCState
, ASPEED_SBC_NR_REGS
),
104 VMSTATE_END_OF_LIST(),
108 static void aspeed_sbc_class_init(ObjectClass
*klass
, void *data
)
110 DeviceClass
*dc
= DEVICE_CLASS(klass
);
112 dc
->realize
= aspeed_sbc_realize
;
113 dc
->reset
= aspeed_sbc_reset
;
114 dc
->vmsd
= &vmstate_aspeed_sbc
;
117 static const TypeInfo aspeed_sbc_info
= {
118 .name
= TYPE_ASPEED_SBC
,
119 .parent
= TYPE_SYS_BUS_DEVICE
,
120 .instance_size
= sizeof(AspeedSBCState
),
121 .class_init
= aspeed_sbc_class_init
,
122 .class_size
= sizeof(AspeedSBCClass
)
125 static void aspeed_ast2600_sbc_class_init(ObjectClass
*klass
, void *data
)
127 DeviceClass
*dc
= DEVICE_CLASS(klass
);
129 dc
->desc
= "AST2600 Secure Boot Controller";
132 static const TypeInfo aspeed_ast2600_sbc_info
= {
133 .name
= TYPE_ASPEED_AST2600_SBC
,
134 .parent
= TYPE_ASPEED_SBC
,
135 .class_init
= aspeed_ast2600_sbc_class_init
,
138 static void aspeed_sbc_register_types(void)
140 type_register_static(&aspeed_ast2600_sbc_info
);
141 type_register_static(&aspeed_sbc_info
);
144 type_init(aspeed_sbc_register_types
);