mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-31 05:51:53 -06:00
hw/misc: Support 8-bytes memop in NPCM GCR module
The NPCM8xx GCR device can be accessed with 64-bit memory operations. This patch supports that. Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Hao Wu <wuhaotsh@google.com> Reviewed-by: Philippe Mathieu-Daude <philmd@linaro.org> Message-id: 20250219184609.1839281-10-wuhaotsh@google.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
0ad46bbb56
commit
ca2fd966ea
2 changed files with 73 additions and 23 deletions
|
@ -200,6 +200,7 @@ static uint64_t npcm_gcr_read(void *opaque, hwaddr offset, unsigned size)
|
||||||
uint32_t reg = offset / sizeof(uint32_t);
|
uint32_t reg = offset / sizeof(uint32_t);
|
||||||
NPCMGCRState *s = opaque;
|
NPCMGCRState *s = opaque;
|
||||||
NPCMGCRClass *c = NPCM_GCR_GET_CLASS(s);
|
NPCMGCRClass *c = NPCM_GCR_GET_CLASS(s);
|
||||||
|
uint64_t value;
|
||||||
|
|
||||||
if (reg >= c->nr_regs) {
|
if (reg >= c->nr_regs) {
|
||||||
qemu_log_mask(LOG_GUEST_ERROR,
|
qemu_log_mask(LOG_GUEST_ERROR,
|
||||||
|
@ -208,9 +209,21 @@ static uint64_t npcm_gcr_read(void *opaque, hwaddr offset, unsigned size)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
trace_npcm_gcr_read(offset, s->regs[reg]);
|
switch (size) {
|
||||||
|
case 4:
|
||||||
|
value = s->regs[reg];
|
||||||
|
break;
|
||||||
|
|
||||||
return s->regs[reg];
|
case 8:
|
||||||
|
value = deposit64(s->regs[reg], 32, 32, s->regs[reg + 1]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_assert_not_reached();
|
||||||
|
}
|
||||||
|
|
||||||
|
trace_npcm_gcr_read(offset, value);
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void npcm_gcr_write(void *opaque, hwaddr offset,
|
static void npcm_gcr_write(void *opaque, hwaddr offset,
|
||||||
|
@ -230,29 +243,65 @@ static void npcm_gcr_write(void *opaque, hwaddr offset,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (reg) {
|
switch (size) {
|
||||||
case NPCM7XX_GCR_PDID:
|
case 4:
|
||||||
case NPCM7XX_GCR_PWRON:
|
switch (reg) {
|
||||||
case NPCM7XX_GCR_INTSR:
|
case NPCM7XX_GCR_PDID:
|
||||||
qemu_log_mask(LOG_GUEST_ERROR,
|
case NPCM7XX_GCR_PWRON:
|
||||||
"%s: register @ 0x%04" HWADDR_PRIx " is read-only\n",
|
case NPCM7XX_GCR_INTSR:
|
||||||
__func__, offset);
|
qemu_log_mask(LOG_GUEST_ERROR,
|
||||||
return;
|
"%s: register @ 0x%04" HWADDR_PRIx " is read-only\n",
|
||||||
|
__func__, offset);
|
||||||
|
return;
|
||||||
|
|
||||||
case NPCM7XX_GCR_RESSR:
|
case NPCM7XX_GCR_RESSR:
|
||||||
case NPCM7XX_GCR_CP2BST:
|
case NPCM7XX_GCR_CP2BST:
|
||||||
/* Write 1 to clear */
|
/* Write 1 to clear */
|
||||||
value = s->regs[reg] & ~value;
|
value = s->regs[reg] & ~value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NPCM7XX_GCR_RLOCKR1:
|
||||||
|
case NPCM7XX_GCR_MDLR:
|
||||||
|
/* Write 1 to set */
|
||||||
|
value |= s->regs[reg];
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
s->regs[reg] = value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NPCM7XX_GCR_RLOCKR1:
|
case 8:
|
||||||
case NPCM7XX_GCR_MDLR:
|
s->regs[reg] = value;
|
||||||
/* Write 1 to set */
|
s->regs[reg + 1] = extract64(v, 32, 32);
|
||||||
value |= s->regs[reg];
|
|
||||||
break;
|
break;
|
||||||
};
|
|
||||||
|
|
||||||
s->regs[reg] = value;
|
default:
|
||||||
|
g_assert_not_reached();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool npcm_gcr_check_mem_op(void *opaque, hwaddr offset,
|
||||||
|
unsigned size, bool is_write,
|
||||||
|
MemTxAttrs attrs)
|
||||||
|
{
|
||||||
|
NPCMGCRClass *c = NPCM_GCR_GET_CLASS(opaque);
|
||||||
|
|
||||||
|
if (offset >= c->nr_regs * sizeof(uint32_t)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (size) {
|
||||||
|
case 4:
|
||||||
|
return true;
|
||||||
|
case 8:
|
||||||
|
if (offset >= NPCM8XX_GCR_SCRPAD_00 * sizeof(uint32_t) &&
|
||||||
|
offset < (NPCM8XX_GCR_NR_REGS - 1) * sizeof(uint32_t)) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct MemoryRegionOps npcm_gcr_ops = {
|
static const struct MemoryRegionOps npcm_gcr_ops = {
|
||||||
|
@ -261,7 +310,8 @@ static const struct MemoryRegionOps npcm_gcr_ops = {
|
||||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||||
.valid = {
|
.valid = {
|
||||||
.min_access_size = 4,
|
.min_access_size = 4,
|
||||||
.max_access_size = 4,
|
.max_access_size = 8,
|
||||||
|
.accepts = npcm_gcr_check_mem_op,
|
||||||
.unaligned = false,
|
.unaligned = false,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -135,8 +135,8 @@ npcm7xx_clk_read(uint64_t offset, uint32_t value) " offset: 0x%04" PRIx64 " valu
|
||||||
npcm7xx_clk_write(uint64_t offset, uint32_t value) "offset: 0x%04" PRIx64 " value: 0x%08" PRIx32
|
npcm7xx_clk_write(uint64_t offset, uint32_t value) "offset: 0x%04" PRIx64 " value: 0x%08" PRIx32
|
||||||
|
|
||||||
# npcm_gcr.c
|
# npcm_gcr.c
|
||||||
npcm_gcr_read(uint64_t offset, uint32_t value) " offset: 0x%04" PRIx64 " value: 0x%08" PRIx32
|
npcm_gcr_read(uint64_t offset, uint64_t value) " offset: 0x%04" PRIx64 " value: 0x%08" PRIx64
|
||||||
npcm_gcr_write(uint64_t offset, uint32_t value) "offset: 0x%04" PRIx64 " value: 0x%08" PRIx32
|
npcm_gcr_write(uint64_t offset, uint64_t value) "offset: 0x%04" PRIx64 " value: 0x%08" PRIx64
|
||||||
|
|
||||||
# npcm7xx_mft.c
|
# npcm7xx_mft.c
|
||||||
npcm7xx_mft_read(const char *name, uint64_t offset, uint16_t value) "%s: offset: 0x%04" PRIx64 " value: 0x%04" PRIx16
|
npcm7xx_mft_read(const char *name, uint64_t offset, uint16_t value) "%s: offset: 0x%04" PRIx64 " value: 0x%04" PRIx16
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue