mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-03 15:53:54 -06:00
hw/misc/aspeed_scu: Handle AST2600 protection key registers correctly
The AST2600 SCU has two protection key registers (0x00 and 0x10) that both need to be unlocked. (Un-)locking 0x00 modifies both protection key registers, while modifying 0x10 only modifies itself. This commit updates the SCU write logic to reject writes unless both protection key registers are unlocked, matching the behaviour of real hardware. Signed-off-by: Tan Siewert <tan@siewert.io> Reviewed-by: Jamin Lin <jamin_lin@aspeedtech.com> Link: https://lore.kernel.org/qemu-devel/20250619085329.42125-1-tan@siewert.io Signed-off-by: Cédric Le Goater <clg@redhat.com>
This commit is contained in:
parent
8e076a3f1b
commit
10d1b6231b
1 changed files with 14 additions and 2 deletions
|
@ -91,6 +91,7 @@
|
|||
#define BMC_DEV_ID TO_REG(0x1A4)
|
||||
|
||||
#define AST2600_PROT_KEY TO_REG(0x00)
|
||||
#define AST2600_PROT_KEY2 TO_REG(0x10)
|
||||
#define AST2600_SILICON_REV TO_REG(0x04)
|
||||
#define AST2600_SILICON_REV2 TO_REG(0x14)
|
||||
#define AST2600_SYS_RST_CTRL TO_REG(0x40)
|
||||
|
@ -723,6 +724,8 @@ static void aspeed_ast2600_scu_write(void *opaque, hwaddr offset,
|
|||
int reg = TO_REG(offset);
|
||||
/* Truncate here so bitwise operations below behave as expected */
|
||||
uint32_t data = data64;
|
||||
bool prot_data_state = data == ASPEED_SCU_PROT_KEY;
|
||||
bool unlocked = s->regs[AST2600_PROT_KEY] && s->regs[AST2600_PROT_KEY2];
|
||||
|
||||
if (reg >= ASPEED_AST2600_SCU_NR_REGS) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
|
@ -731,15 +734,24 @@ static void aspeed_ast2600_scu_write(void *opaque, hwaddr offset,
|
|||
return;
|
||||
}
|
||||
|
||||
if (reg > PROT_KEY && !s->regs[PROT_KEY]) {
|
||||
if ((reg != AST2600_PROT_KEY && reg != AST2600_PROT_KEY2) && !unlocked) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: SCU is locked!\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
trace_aspeed_scu_write(offset, size, data);
|
||||
|
||||
switch (reg) {
|
||||
case AST2600_PROT_KEY:
|
||||
s->regs[reg] = (data == ASPEED_SCU_PROT_KEY) ? 1 : 0;
|
||||
/*
|
||||
* Writing a value to SCU000 will modify both protection
|
||||
* registers to each protection register individually.
|
||||
*/
|
||||
s->regs[AST2600_PROT_KEY] = prot_data_state;
|
||||
s->regs[AST2600_PROT_KEY2] = prot_data_state;
|
||||
return;
|
||||
case AST2600_PROT_KEY2:
|
||||
s->regs[AST2600_PROT_KEY2] = prot_data_state;
|
||||
return;
|
||||
case AST2600_HW_STRAP1:
|
||||
case AST2600_HW_STRAP2:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue