mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-11-05 20:35:44 +00:00
aspeed/scu: Create separate write callbacks
This splits the common write callback into separate ast2400 and ast2500 implementations. This makes it clearer when implementing differing behaviour. Signed-off-by: Joel Stanley <joel@jms.id.au> Reviewed-by: Andrew Jeffery <andrew@aj.id.au> Reviewed-by: Cédric Le Goater <clg@kaod.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> Message-id: 20200121013302.43839-2-joel@jms.id.au Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
a8c6af67e1
commit
c7e1f57291
1 changed files with 57 additions and 23 deletions
|
@ -232,8 +232,47 @@ static uint64_t aspeed_scu_read(void *opaque, hwaddr offset, unsigned size)
|
|||
return s->regs[reg];
|
||||
}
|
||||
|
||||
static void aspeed_scu_write(void *opaque, hwaddr offset, uint64_t data,
|
||||
unsigned size)
|
||||
static void aspeed_ast2400_scu_write(void *opaque, hwaddr offset,
|
||||
uint64_t data, unsigned size)
|
||||
{
|
||||
AspeedSCUState *s = ASPEED_SCU(opaque);
|
||||
int reg = TO_REG(offset);
|
||||
|
||||
if (reg >= ASPEED_SCU_NR_REGS) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n",
|
||||
__func__, offset);
|
||||
return;
|
||||
}
|
||||
|
||||
if (reg > PROT_KEY && reg < CPU2_BASE_SEG1 &&
|
||||
!s->regs[PROT_KEY]) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: SCU is locked!\n", __func__);
|
||||
}
|
||||
|
||||
trace_aspeed_scu_write(offset, size, data);
|
||||
|
||||
switch (reg) {
|
||||
case PROT_KEY:
|
||||
s->regs[reg] = (data == ASPEED_SCU_PROT_KEY) ? 1 : 0;
|
||||
return;
|
||||
case SILICON_REV:
|
||||
case FREQ_CNTR_EVAL:
|
||||
case VGA_SCRATCH1 ... VGA_SCRATCH8:
|
||||
case RNG_DATA:
|
||||
case FREE_CNTR4:
|
||||
case FREE_CNTR4_EXT:
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: Write to read-only offset 0x%" HWADDR_PRIx "\n",
|
||||
__func__, offset);
|
||||
return;
|
||||
}
|
||||
|
||||
s->regs[reg] = data;
|
||||
}
|
||||
|
||||
static void aspeed_ast2500_scu_write(void *opaque, hwaddr offset,
|
||||
uint64_t data, unsigned size)
|
||||
{
|
||||
AspeedSCUState *s = ASPEED_SCU(opaque);
|
||||
int reg = TO_REG(offset);
|
||||
|
@ -257,25 +296,11 @@ static void aspeed_scu_write(void *opaque, hwaddr offset, uint64_t data,
|
|||
case PROT_KEY:
|
||||
s->regs[reg] = (data == ASPEED_SCU_PROT_KEY) ? 1 : 0;
|
||||
return;
|
||||
case CLK_SEL:
|
||||
s->regs[reg] = data;
|
||||
break;
|
||||
case HW_STRAP1:
|
||||
if (ASPEED_IS_AST2500(s->regs[SILICON_REV])) {
|
||||
s->regs[HW_STRAP1] |= data;
|
||||
return;
|
||||
}
|
||||
/* Jump to assignment below */
|
||||
break;
|
||||
s->regs[HW_STRAP1] |= data;
|
||||
return;
|
||||
case SILICON_REV:
|
||||
if (ASPEED_IS_AST2500(s->regs[SILICON_REV])) {
|
||||
s->regs[HW_STRAP1] &= ~data;
|
||||
} else {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: Write to read-only offset 0x%" HWADDR_PRIx "\n",
|
||||
__func__, offset);
|
||||
}
|
||||
/* Avoid assignment below, we've handled everything */
|
||||
s->regs[HW_STRAP1] &= ~data;
|
||||
return;
|
||||
case FREQ_CNTR_EVAL:
|
||||
case VGA_SCRATCH1 ... VGA_SCRATCH8:
|
||||
|
@ -291,9 +316,18 @@ static void aspeed_scu_write(void *opaque, hwaddr offset, uint64_t data,
|
|||
s->regs[reg] = data;
|
||||
}
|
||||
|
||||
static const MemoryRegionOps aspeed_scu_ops = {
|
||||
static const MemoryRegionOps aspeed_ast2400_scu_ops = {
|
||||
.read = aspeed_scu_read,
|
||||
.write = aspeed_scu_write,
|
||||
.write = aspeed_ast2400_scu_write,
|
||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
.valid.min_access_size = 4,
|
||||
.valid.max_access_size = 4,
|
||||
.valid.unaligned = false,
|
||||
};
|
||||
|
||||
static const MemoryRegionOps aspeed_ast2500_scu_ops = {
|
||||
.read = aspeed_scu_read,
|
||||
.write = aspeed_ast2500_scu_write,
|
||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
.valid.min_access_size = 4,
|
||||
.valid.max_access_size = 4,
|
||||
|
@ -469,7 +503,7 @@ static void aspeed_2400_scu_class_init(ObjectClass *klass, void *data)
|
|||
asc->calc_hpll = aspeed_2400_scu_calc_hpll;
|
||||
asc->apb_divider = 2;
|
||||
asc->nr_regs = ASPEED_SCU_NR_REGS;
|
||||
asc->ops = &aspeed_scu_ops;
|
||||
asc->ops = &aspeed_ast2400_scu_ops;
|
||||
}
|
||||
|
||||
static const TypeInfo aspeed_2400_scu_info = {
|
||||
|
@ -489,7 +523,7 @@ static void aspeed_2500_scu_class_init(ObjectClass *klass, void *data)
|
|||
asc->calc_hpll = aspeed_2500_scu_calc_hpll;
|
||||
asc->apb_divider = 4;
|
||||
asc->nr_regs = ASPEED_SCU_NR_REGS;
|
||||
asc->ops = &aspeed_scu_ops;
|
||||
asc->ops = &aspeed_ast2500_scu_ops;
|
||||
}
|
||||
|
||||
static const TypeInfo aspeed_2500_scu_info = {
|
||||
|
|
Loading…
Reference in a new issue