mirror of https://github.com/xemu-project/xemu.git
hw/intc/arm_gicv3_its: Reduce code duplication in extract_table_params()
The extract_table_params() decodes the fields in the GITS_BASER<n> registers into TableDesc structs. Since the fields are the same for all the GITS_BASER<n> registers, there is currently a lot of code duplication within the switch (type) statement. Refactor so that the cases include only what is genuinely different for each type: the calculation of the number of bits in the ID value that indexes into the table. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
This commit is contained in:
parent
62df780e3d
commit
e5487a4139
|
@ -758,6 +758,9 @@ static void extract_table_params(GICv3ITSState *s)
|
||||||
uint64_t value;
|
uint64_t value;
|
||||||
|
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
|
TableDesc *td;
|
||||||
|
int idbits;
|
||||||
|
|
||||||
value = s->baser[i];
|
value = s->baser[i];
|
||||||
|
|
||||||
if (!value) {
|
if (!value) {
|
||||||
|
@ -789,73 +792,53 @@ static void extract_table_params(GICv3ITSState *s)
|
||||||
type = FIELD_EX64(value, GITS_BASER, TYPE);
|
type = FIELD_EX64(value, GITS_BASER, TYPE);
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
|
||||||
case GITS_BASER_TYPE_DEVICE:
|
case GITS_BASER_TYPE_DEVICE:
|
||||||
memset(&s->dt, 0 , sizeof(s->dt));
|
td = &s->dt;
|
||||||
s->dt.valid = FIELD_EX64(value, GITS_BASER, VALID);
|
idbits = FIELD_EX64(s->typer, GITS_TYPER, DEVBITS) + 1;
|
||||||
|
|
||||||
if (!s->dt.valid) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
s->dt.page_sz = page_sz;
|
|
||||||
s->dt.indirect = FIELD_EX64(value, GITS_BASER, INDIRECT);
|
|
||||||
s->dt.entry_sz = FIELD_EX64(value, GITS_BASER, ENTRYSIZE);
|
|
||||||
|
|
||||||
if (!s->dt.indirect) {
|
|
||||||
s->dt.max_entries = (num_pages * page_sz) / s->dt.entry_sz;
|
|
||||||
} else {
|
|
||||||
s->dt.max_entries = (((num_pages * page_sz) /
|
|
||||||
L1TABLE_ENTRY_SIZE) *
|
|
||||||
(page_sz / s->dt.entry_sz));
|
|
||||||
}
|
|
||||||
|
|
||||||
s->dt.max_ids = (1UL << (FIELD_EX64(s->typer, GITS_TYPER,
|
|
||||||
DEVBITS) + 1));
|
|
||||||
|
|
||||||
s->dt.base_addr = baser_base_addr(value, page_sz);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GITS_BASER_TYPE_COLLECTION:
|
case GITS_BASER_TYPE_COLLECTION:
|
||||||
memset(&s->ct, 0 , sizeof(s->ct));
|
td = &s->ct;
|
||||||
s->ct.valid = FIELD_EX64(value, GITS_BASER, VALID);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* GITS_TYPER.HCC is 0 for this implementation
|
|
||||||
* hence writes are discarded if ct.valid is 0
|
|
||||||
*/
|
|
||||||
if (!s->ct.valid) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
s->ct.page_sz = page_sz;
|
|
||||||
s->ct.indirect = FIELD_EX64(value, GITS_BASER, INDIRECT);
|
|
||||||
s->ct.entry_sz = FIELD_EX64(value, GITS_BASER, ENTRYSIZE);
|
|
||||||
|
|
||||||
if (!s->ct.indirect) {
|
|
||||||
s->ct.max_entries = (num_pages * page_sz) / s->ct.entry_sz;
|
|
||||||
} else {
|
|
||||||
s->ct.max_entries = (((num_pages * page_sz) /
|
|
||||||
L1TABLE_ENTRY_SIZE) *
|
|
||||||
(page_sz / s->ct.entry_sz));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FIELD_EX64(s->typer, GITS_TYPER, CIL)) {
|
if (FIELD_EX64(s->typer, GITS_TYPER, CIL)) {
|
||||||
s->ct.max_ids = (1UL << (FIELD_EX64(s->typer,
|
idbits = FIELD_EX64(s->typer, GITS_TYPER, CIDBITS) + 1;
|
||||||
GITS_TYPER, CIDBITS) + 1));
|
|
||||||
} else {
|
} else {
|
||||||
/* 16-bit CollectionId supported when CIL == 0 */
|
/* 16-bit CollectionId supported when CIL == 0 */
|
||||||
s->ct.max_ids = (1UL << 16);
|
idbits = 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
s->ct.base_addr = baser_base_addr(value, page_sz);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
/*
|
||||||
|
* GITS_BASER<n>.TYPE is read-only, so GITS_BASER_RO_MASK
|
||||||
|
* ensures we will only see type values corresponding to
|
||||||
|
* the values set up in gicv3_its_reset().
|
||||||
|
*/
|
||||||
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memset(td, 0, sizeof(*td));
|
||||||
|
td->valid = FIELD_EX64(value, GITS_BASER, VALID);
|
||||||
|
/*
|
||||||
|
* If GITS_BASER<n>.Valid is 0 for any <n> then we will not process
|
||||||
|
* interrupts. (GITS_TYPER.HCC is 0 for this implementation, so we
|
||||||
|
* do not have a special case where the GITS_BASER<n>.Valid bit is 0
|
||||||
|
* for the register corresponding to the Collection table but we
|
||||||
|
* still have to process interrupts using non-memory-backed
|
||||||
|
* Collection table entries.)
|
||||||
|
*/
|
||||||
|
if (!td->valid) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
td->page_sz = page_sz;
|
||||||
|
td->indirect = FIELD_EX64(value, GITS_BASER, INDIRECT);
|
||||||
|
td->entry_sz = FIELD_EX64(value, GITS_BASER, ENTRYSIZE);
|
||||||
|
td->base_addr = baser_base_addr(value, page_sz);
|
||||||
|
if (!td->indirect) {
|
||||||
|
td->max_entries = (num_pages * page_sz) / td->entry_sz;
|
||||||
|
} else {
|
||||||
|
td->max_entries = (((num_pages * page_sz) /
|
||||||
|
L1TABLE_ENTRY_SIZE) *
|
||||||
|
(page_sz / td->entry_sz));
|
||||||
|
}
|
||||||
|
td->max_ids = 1ULL << idbits;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue