diff options
author | Bin Meng <bmeng@tinylab.org> | 2022-12-11 11:08:20 +0800 |
---|---|---|
committer | Alistair Francis <alistair.francis@wdc.com> | 2023-01-06 10:42:55 +1000 |
commit | 7b0f26e420f7988ae8c257c1f4369ba92c9b1594 (patch) | |
tree | caf5b25ff100238d450d906123cfad26bbb9eca4 /hw/intc | |
parent | 2904dc1c1e7895a65a2ac18ea4bb1042d6dced50 (diff) | |
download | qemu-7b0f26e420f7988ae8c257c1f4369ba92c9b1594.zip qemu-7b0f26e420f7988ae8c257c1f4369ba92c9b1594.tar.gz qemu-7b0f26e420f7988ae8c257c1f4369ba92c9b1594.tar.bz2 |
hw/intc: sifive_plic: Improve robustness of the PLIC config parser
At present the PLIC config parser can only handle legal config string
like "MS,MS". However if a config string like ",MS,MS,,MS,MS,," is
given the parser won't get the correct configuration.
This commit improves the config parser to make it more robust.
Signed-off-by: Bin Meng <bmeng@tinylab.org>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Message-Id: <20221211030829.802437-7-bmeng@tinylab.org>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Diffstat (limited to 'hw/intc')
-rw-r--r-- | hw/intc/sifive_plic.c | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c index 936dcf7..c9af94a 100644 --- a/hw/intc/sifive_plic.c +++ b/hw/intc/sifive_plic.c @@ -290,7 +290,7 @@ static void sifive_plic_reset(DeviceState *dev) */ static void parse_hart_config(SiFivePLICState *plic) { - int addrid, hartid, modes; + int addrid, hartid, modes, m; const char *p; char c; @@ -299,11 +299,13 @@ static void parse_hart_config(SiFivePLICState *plic) p = plic->hart_config; while ((c = *p++)) { if (c == ',') { - addrid += ctpop8(modes); - modes = 0; - hartid++; + if (modes) { + addrid += ctpop8(modes); + hartid++; + modes = 0; + } } else { - int m = 1 << char_to_mode(c); + m = 1 << char_to_mode(c); if (modes == (modes | m)) { error_report("plic: duplicate mode '%c' in config: %s", c, plic->hart_config); @@ -314,8 +316,9 @@ static void parse_hart_config(SiFivePLICState *plic) } if (modes) { addrid += ctpop8(modes); + hartid++; + modes = 0; } - hartid++; plic->num_addrs = addrid; plic->num_harts = hartid; @@ -326,11 +329,16 @@ static void parse_hart_config(SiFivePLICState *plic) p = plic->hart_config; while ((c = *p++)) { if (c == ',') { - hartid++; + if (modes) { + hartid++; + modes = 0; + } } else { + m = char_to_mode(c); plic->addr_config[addrid].addrid = addrid; plic->addr_config[addrid].hartid = hartid; - plic->addr_config[addrid].mode = char_to_mode(c); + plic->addr_config[addrid].mode = m; + modes |= (1 << m); addrid++; } } |