Message ID | 20240927083508.59483-1-yanmingzhu@iscas.ac.cn (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | hw/char/riscv_htif: Fix htif_mm_write that causes infinite loop in ACT. | expand |
On Fri, Sep 27, 2024 at 11:26 PM MingZhu Yan <trdthg47@gmail.com> wrote: > > Applications sometimes only write the lower 32-bit payload bytes, this is used > in ACT tests. As a workaround, this refers to the solution of sail-riscv. I'm not sure what ACT is, but this feels like a guest bug, not a QEMU issue. Alistair > if the payload is written a few times with the same value, we process the whole > htif command anyway. > > Signed-off-by: MingZhu Yan <yanmingzhu@iscas.ac.cn> > --- > hw/char/riscv_htif.c | 35 +++++++++++++++++++---------------- > 1 file changed, 19 insertions(+), 16 deletions(-) > > diff --git a/hw/char/riscv_htif.c b/hw/char/riscv_htif.c > index 9bef60def1..d74cce3bef 100644 > --- a/hw/char/riscv_htif.c > +++ b/hw/char/riscv_htif.c > @@ -65,16 +65,8 @@ void htif_symbol_callback(const char *st_name, int st_info, uint64_t st_value, > { > if (strcmp("fromhost", st_name) == 0) { > fromhost_addr = st_value; > - if (st_size != 8) { > - error_report("HTIF fromhost must be 8 bytes"); > - exit(1); > - } > } else if (strcmp("tohost", st_name) == 0) { > tohost_addr = st_value; > - if (st_size != 8) { > - error_report("HTIF tohost must be 8 bytes"); > - exit(1); > - } > } else if (strcmp("begin_signature", st_name) == 0) { > begin_sig_addr = st_value; > } else if (strcmp("end_signature", st_name) == 0) { > @@ -290,18 +282,26 @@ static void htif_mm_write(void *opaque, hwaddr addr, > uint64_t value, unsigned size) > { > HTIFState *s = opaque; > - if (addr == TOHOST_OFFSET1) { > - if (s->tohost == 0x0) { > - s->allow_tohost = 1; > - s->tohost = value & 0xFFFFFFFF; > + int htif_cmd_write = 0; > + if (size == 8 && addr == TOHOST_OFFSET1) { > + htif_cmd_write = 1; > + s->tohost = value; > + htif_handle_tohost_write(s, s->tohost); > + } else if (size == 4 && addr == TOHOST_OFFSET1) { > + if ((value) == (s->tohost & 0xFFFF)) { > + s->allow_tohost = s->allow_tohost + 1; > } else { > s->allow_tohost = 0; > } > - } else if (addr == TOHOST_OFFSET2) { > - if (s->allow_tohost) { > - s->tohost |= value << 32; > - htif_handle_tohost_write(s, s->tohost); > + s->tohost = deposit64(s->tohost, 0, 32, value); > + } else if (size == 4 && addr == TOHOST_OFFSET2) { > + if ((value & 0xFF) == (s->tohost & 0xFF00)) { > + s->allow_tohost = s->allow_tohost + 1; > + } else { > + s->allow_tohost = 1; > } > + htif_cmd_write = 1; > + s->tohost = deposit64(s->tohost, 32, 32, value); > } else if (addr == FROMHOST_OFFSET1) { > s->fromhost_inprogress = 1; > s->fromhost = value & 0xFFFFFFFF; > @@ -312,6 +312,9 @@ static void htif_mm_write(void *opaque, hwaddr addr, > qemu_log("Invalid htif write: address %016" PRIx64 "\n", > (uint64_t)addr); > } > + if ((s->tohost == 1 && htif_cmd_write) || s->allow_tohost > 2) { > + htif_handle_tohost_write(s, s->tohost); > + } > } > > static const MemoryRegionOps htif_mm_ops = { > -- > 2.34.1 > >
Thank you for your reply and I'm sorry that I didn't explain it clearly. - ACT is an official riscv test suite to check the riscv support of the DUT(device under test). - Currently ACT support using [sail-riscv](https://github.com/riscv/sail-riscv)(default) or [spike](https://github.com/riscv-software-src/riscv-isa-sim) - QEMU is not supported yet,but someone made a commit: [commit](https://github.com/qemu/qemu/commit/66247edc8b6fb36d6b905babcd795068ea989ad5) But there are still problems, so I'm trying to fix it. After debugging, I found that it's a htif problem, and the idea of fixing it is referenced from the sail-riscv implementation "Alistair Francis" <alistair23@gmail.com>写道: > On Fri, Sep 27, 2024 at 11:26 PM MingZhu Yan <trdthg47@gmail.com> wrote: > > > > Applications sometimes only write the lower 32-bit payload bytes, this is used > > in ACT tests. As a workaround, this refers to the solution of sail-riscv. > > I'm not sure what ACT is, but this feels like a guest bug, not a QEMU issue. > > Alistair > > > if the payload is written a few times with the same value, we process the whole > > htif command anyway. > > > > Signed-off-by: MingZhu Yan <yanmingzhu@iscas.ac.cn> > > --- > > hw/char/riscv_htif.c | 35 +++++++++++++++++++---------------- > > 1 file changed, 19 insertions(+), 16 deletions(-) > > > > diff --git a/hw/char/riscv_htif.c b/hw/char/riscv_htif.c > > index 9bef60def1..d74cce3bef 100644 > > --- a/hw/char/riscv_htif.c > > +++ b/hw/char/riscv_htif.c > > @@ -65,16 +65,8 @@ void htif_symbol_callback(const char *st_name, int st_info, uint64_t st_value, > > { > > if (strcmp("fromhost", st_name) == 0) { > > fromhost_addr = st_value; > > - if (st_size != 8) { > > - error_report("HTIF fromhost must be 8 bytes"); > > - exit(1); > > - } > > } else if (strcmp("tohost", st_name) == 0) { > > tohost_addr = st_value; > > - if (st_size != 8) { > > - error_report("HTIF tohost must be 8 bytes"); > > - exit(1); > > - } > > } else if (strcmp("begin_signature", st_name) == 0) { > > begin_sig_addr = st_value; > > } else if (strcmp("end_signature", st_name) == 0) { > > @@ -290,18 +282,26 @@ static void htif_mm_write(void *opaque, hwaddr addr, > > uint64_t value, unsigned size) > > { > > HTIFState *s = opaque; > > - if (addr == TOHOST_OFFSET1) { > > - if (s->tohost == 0x0) { > > - s->allow_tohost = 1; > > - s->tohost = value & 0xFFFFFFFF; > > + int htif_cmd_write = 0; > > + if (size == 8 && addr == TOHOST_OFFSET1) { > > + htif_cmd_write = 1; > > + s->tohost = value; > > + htif_handle_tohost_write(s, s->tohost); > > + } else if (size == 4 && addr == TOHOST_OFFSET1) { > > + if ((value) == (s->tohost & 0xFFFF)) { > > + s->allow_tohost = s->allow_tohost + 1; > > } else { > > s->allow_tohost = 0; > > } > > - } else if (addr == TOHOST_OFFSET2) { > > - if (s->allow_tohost) { > > - s->tohost |= value << 32; > > - htif_handle_tohost_write(s, s->tohost); > > + s->tohost = deposit64(s->tohost, 0, 32, value); > > + } else if (size == 4 && addr == TOHOST_OFFSET2) { > > + if ((value & 0xFF) == (s->tohost & 0xFF00)) { > > + s->allow_tohost = s->allow_tohost + 1; > > + } else { > > + s->allow_tohost = 1; > > } > > + htif_cmd_write = 1; > > + s->tohost = deposit64(s->tohost, 32, 32, value); > > } else if (addr == FROMHOST_OFFSET1) { > > s->fromhost_inprogress = 1; > > s->fromhost = value & 0xFFFFFFFF; > > @@ -312,6 +312,9 @@ static void htif_mm_write(void *opaque, hwaddr addr, > > qemu_log("Invalid htif write: address %016" PRIx64 "\n", > > (uint64_t)addr); > > } > > + if ((s->tohost == 1 && htif_cmd_write) || s->allow_tohost > 2) { > > + htif_handle_tohost_write(s, s->tohost); > > + } > > } > > > > static const MemoryRegionOps htif_mm_ops = { > > -- > > 2.34.1 > > > > </yanmingzhu@iscas.ac.cn></trdthg47@gmail.com>
On Mon, Oct 14, 2024 at 8:08 PM 阎明铸 <yanmingzhu@iscas.ac.cn> wrote: > > Thank you for your reply and I'm sorry that I didn't explain it clearly. > > - ACT is an official riscv test suite to check the riscv support of the DUT(device under test). It's probably worth including this in the commit message. > - Currently ACT support using [sail-riscv](https://github.com/riscv/sail-riscv)(default) or [spike](https://github.com/riscv-software-src/riscv-isa-sim) > - QEMU is not supported yet,but someone made a commit: [commit](https://github.com/qemu/qemu/commit/66247edc8b6fb36d6b905babcd795068ea989ad5) > > But there are still problems, so I'm trying to fix it. After debugging, I found that it's a htif problem, and the idea of fixing it is referenced from the sail-riscv implementation It would be good to reference the sail implementation and the justification for the change there Alistair > > "Alistair Francis" <alistair23@gmail.com>写道: > > On Fri, Sep 27, 2024 at 11:26 PM MingZhu Yan <trdthg47@gmail.com> wrote: > > > > > > Applications sometimes only write the lower 32-bit payload bytes, this is used > > > in ACT tests. As a workaround, this refers to the solution of sail-riscv. > > > > I'm not sure what ACT is, but this feels like a guest bug, not a QEMU issue. > > > > Alistair > > > > > if the payload is written a few times with the same value, we process the whole > > > htif command anyway. > > > > > > Signed-off-by: MingZhu Yan <yanmingzhu@iscas.ac.cn> > > > --- > > > hw/char/riscv_htif.c | 35 +++++++++++++++++++---------------- > > > 1 file changed, 19 insertions(+), 16 deletions(-) > > > > > > diff --git a/hw/char/riscv_htif.c b/hw/char/riscv_htif.c > > > index 9bef60def1..d74cce3bef 100644 > > > --- a/hw/char/riscv_htif.c > > > +++ b/hw/char/riscv_htif.c > > > @@ -65,16 +65,8 @@ void htif_symbol_callback(const char *st_name, int st_info, uint64_t st_value, > > > { > > > if (strcmp("fromhost", st_name) == 0) { > > > fromhost_addr = st_value; > > > - if (st_size != 8) { > > > - error_report("HTIF fromhost must be 8 bytes"); > > > - exit(1); > > > - } > > > } else if (strcmp("tohost", st_name) == 0) { > > > tohost_addr = st_value; > > > - if (st_size != 8) { > > > - error_report("HTIF tohost must be 8 bytes"); > > > - exit(1); > > > - } > > > } else if (strcmp("begin_signature", st_name) == 0) { > > > begin_sig_addr = st_value; > > > } else if (strcmp("end_signature", st_name) == 0) { > > > @@ -290,18 +282,26 @@ static void htif_mm_write(void *opaque, hwaddr addr, > > > uint64_t value, unsigned size) > > > { > > > HTIFState *s = opaque; > > > - if (addr == TOHOST_OFFSET1) { > > > - if (s->tohost == 0x0) { > > > - s->allow_tohost = 1; > > > - s->tohost = value & 0xFFFFFFFF; > > > + int htif_cmd_write = 0; > > > + if (size == 8 && addr == TOHOST_OFFSET1) { > > > + htif_cmd_write = 1; > > > + s->tohost = value; > > > + htif_handle_tohost_write(s, s->tohost); > > > + } else if (size == 4 && addr == TOHOST_OFFSET1) { > > > + if ((value) == (s->tohost & 0xFFFF)) { > > > + s->allow_tohost = s->allow_tohost + 1; > > > } else { > > > s->allow_tohost = 0; > > > } > > > - } else if (addr == TOHOST_OFFSET2) { > > > - if (s->allow_tohost) { > > > - s->tohost |= value << 32; > > > - htif_handle_tohost_write(s, s->tohost); > > > + s->tohost = deposit64(s->tohost, 0, 32, value); > > > + } else if (size == 4 && addr == TOHOST_OFFSET2) { > > > + if ((value & 0xFF) == (s->tohost & 0xFF00)) { > > > + s->allow_tohost = s->allow_tohost + 1; > > > + } else { > > > + s->allow_tohost = 1; > > > } > > > + htif_cmd_write = 1; > > > + s->tohost = deposit64(s->tohost, 32, 32, value); > > > } else if (addr == FROMHOST_OFFSET1) { > > > s->fromhost_inprogress = 1; > > > s->fromhost = value & 0xFFFFFFFF; > > > @@ -312,6 +312,9 @@ static void htif_mm_write(void *opaque, hwaddr addr, > > > qemu_log("Invalid htif write: address %016" PRIx64 "\n", > > > (uint64_t)addr); > > > } > > > + if ((s->tohost == 1 && htif_cmd_write) || s->allow_tohost > 2) { > > > + htif_handle_tohost_write(s, s->tohost); > > > + } > > > } > > > > > > static const MemoryRegionOps htif_mm_ops = { > > > -- > > > 2.34.1 > > > > > > > </yanmingzhu@iscas.ac.cn></trdthg47@gmail.com>
Sorry about the email style, I'm not familiar with it yet > It's probably worth including this in the commit message. Agree, I'll do it. > It would be good to reference the sail implementation and the justification for the change there Sail implementation is probably here: https://github.com/riscv/sail-riscv/blob/master/model/riscv_platform.sail#L340 - related commit: https://github.com/riscv/sail-riscv/commit/848312ce7c59fa08c304cab4b4e8060c67d5dfc9 The following is the "infinite loop" part is exported by objdump from the test ELF of the add instruction generated from ACT ```txt 00000000800082a0 <write_tohost>: 800082a0: 00001f17 auipc t5,0x1 800082a4: d61f2023 sw ra,-672(t5) # 80009000 <tohost> 800082a8: ff9ff06f j 800082a0 <write_tohost> ``` QEMU cannot respond to the above `sw` behavior, It makes no distinction regarding the size written, I guess that currently qemu will only respond to the writing to the high 32 bits and low 32 bits of tohost twice in succession. I think the behavior here is very strange, and you can find aswaterman's description of HTIF(include RV32) at: https://github.com/riscv-software-src/riscv-isa-sim/issues/364#issuecomment-607657754 So this patch try to distinguish these cases based on size and addr. About the sail impl, there are some related discussions at: https://github.com/riscv/sail-riscv/issues/218 I made some summaries: - The implementation of sail as a workaround is not very ideal; we should follow the experience of spike I checked the impl of spike. Although spike handles tohost in a syscall manner, I don't think this means that spike is better. Compared to sail, it does not distinguish whether the write to tohost is 4 bytes or 8 bytes, but at least in act, it always works properly. - spike code: https://github.com/riscv-software-src/riscv-isa-sim/blob/master/fesvr/htif.cc#L265 - HTIF has been deprecated I don't know if this is true or not, because I haven't found any official comment. However, since ACT is still using htif and is not expected to change for quite a long time, and no new solutions have emerged, we should go ahead and implement it - What are the advantages of QEMU supporting ACT - do cross validation with sail/spike, and contributors can use ACT to verify the correctness when adding new instructions to QEMU. (we do have this need.) > If you think that the benefits of supporting ACT are not obvious, then I think we can remove all the code related to supporting ACT (should be the commit mentioned above) What do you think about this? Thank you! Alistair Francis <alistair23@gmail.com> 于2024年10月16日周三 13:27写道: > > On Mon, Oct 14, 2024 at 8:08 PM 阎明铸 <yanmingzhu@iscas.ac.cn> wrote: > > > > Thank you for your reply and I'm sorry that I didn't explain it clearly. > > > > - ACT is an official riscv test suite to check the riscv support of the DUT(device under test). > > It's probably worth including this in the commit message. > > > - Currently ACT support using [sail-riscv](https://github.com/riscv/sail-riscv)(default) or [spike](https://github.com/riscv-software-src/riscv-isa-sim) > > - QEMU is not supported yet,but someone made a commit: [commit](https://github.com/qemu/qemu/commit/66247edc8b6fb36d6b905babcd795068ea989ad5) > > > > But there are still problems, so I'm trying to fix it. After debugging, I found that it's a htif problem, and the idea of fixing it is referenced from the sail-riscv implementation > > It would be good to reference the sail implementation and the > justification for the change there > > Alistair > > > > > "Alistair Francis" <alistair23@gmail.com>写道: > > > On Fri, Sep 27, 2024 at 11:26 PM MingZhu Yan <trdthg47@gmail.com> wrote: > > > > > > > > Applications sometimes only write the lower 32-bit payload bytes, this is used > > > > in ACT tests. As a workaround, this refers to the solution of sail-riscv. > > > > > > I'm not sure what ACT is, but this feels like a guest bug, not a QEMU issue. > > > > > > Alistair > > > > > > > if the payload is written a few times with the same value, we process the whole > > > > htif command anyway. > > > > > > > > Signed-off-by: MingZhu Yan <yanmingzhu@iscas.ac.cn> > > > > --- > > > > hw/char/riscv_htif.c | 35 +++++++++++++++++++---------------- > > > > 1 file changed, 19 insertions(+), 16 deletions(-) > > > > > > > > diff --git a/hw/char/riscv_htif.c b/hw/char/riscv_htif.c > > > > index 9bef60def1..d74cce3bef 100644 > > > > --- a/hw/char/riscv_htif.c > > > > +++ b/hw/char/riscv_htif.c > > > > @@ -65,16 +65,8 @@ void htif_symbol_callback(const char *st_name, int st_info, uint64_t st_value, > > > > { > > > > if (strcmp("fromhost", st_name) == 0) { > > > > fromhost_addr = st_value; > > > > - if (st_size != 8) { > > > > - error_report("HTIF fromhost must be 8 bytes"); > > > > - exit(1); > > > > - } > > > > } else if (strcmp("tohost", st_name) == 0) { > > > > tohost_addr = st_value; > > > > - if (st_size != 8) { > > > > - error_report("HTIF tohost must be 8 bytes"); > > > > - exit(1); > > > > - } > > > > } else if (strcmp("begin_signature", st_name) == 0) { > > > > begin_sig_addr = st_value; > > > > } else if (strcmp("end_signature", st_name) == 0) { > > > > @@ -290,18 +282,26 @@ static void htif_mm_write(void *opaque, hwaddr addr, > > > > uint64_t value, unsigned size) > > > > { > > > > HTIFState *s = opaque; > > > > - if (addr == TOHOST_OFFSET1) { > > > > - if (s->tohost == 0x0) { > > > > - s->allow_tohost = 1; > > > > - s->tohost = value & 0xFFFFFFFF; > > > > + int htif_cmd_write = 0; > > > > + if (size == 8 && addr == TOHOST_OFFSET1) { > > > > + htif_cmd_write = 1; > > > > + s->tohost = value; > > > > + htif_handle_tohost_write(s, s->tohost); > > > > + } else if (size == 4 && addr == TOHOST_OFFSET1) { > > > > + if ((value) == (s->tohost & 0xFFFF)) { > > > > + s->allow_tohost = s->allow_tohost + 1; > > > > } else { > > > > s->allow_tohost = 0; > > > > } > > > > - } else if (addr == TOHOST_OFFSET2) { > > > > - if (s->allow_tohost) { > > > > - s->tohost |= value << 32; > > > > - htif_handle_tohost_write(s, s->tohost); > > > > + s->tohost = deposit64(s->tohost, 0, 32, value); > > > > + } else if (size == 4 && addr == TOHOST_OFFSET2) { > > > > + if ((value & 0xFF) == (s->tohost & 0xFF00)) { > > > > + s->allow_tohost = s->allow_tohost + 1; > > > > + } else { > > > > + s->allow_tohost = 1; > > > > } > > > > + htif_cmd_write = 1; > > > > + s->tohost = deposit64(s->tohost, 32, 32, value); > > > > } else if (addr == FROMHOST_OFFSET1) { > > > > s->fromhost_inprogress = 1; > > > > s->fromhost = value & 0xFFFFFFFF; > > > > @@ -312,6 +312,9 @@ static void htif_mm_write(void *opaque, hwaddr addr, > > > > qemu_log("Invalid htif write: address %016" PRIx64 "\n", > > > > (uint64_t)addr); > > > > } > > > > + if ((s->tohost == 1 && htif_cmd_write) || s->allow_tohost > 2) { > > > > + htif_handle_tohost_write(s, s->tohost); > > > > + } > > > > } > > > > > > > > static const MemoryRegionOps htif_mm_ops = { > > > > -- > > > > 2.34.1 > > > > > > > > > > </yanmingzhu@iscas.ac.cn></trdthg47@gmail.com>
On Wed, Oct 16, 2024 at 8:32 PM Trd thg <trdthg47@gmail.com> wrote: > > Sorry about the email style, I'm not familiar with it yet No worries! It takes some getting used to. Mostly just plain text emails and reply inline :) Alistair > > > It's probably worth including this in the commit message. > Agree, I'll do it. > > > It would be good to reference the sail implementation and the > justification for the change there > > Sail implementation is probably here: > https://github.com/riscv/sail-riscv/blob/master/model/riscv_platform.sail#L340 > - related commit: > https://github.com/riscv/sail-riscv/commit/848312ce7c59fa08c304cab4b4e8060c67d5dfc9 > > The following is the "infinite loop" part is exported by objdump from > the test ELF of the add instruction generated from ACT > ```txt > 00000000800082a0 <write_tohost>: > 800082a0: 00001f17 auipc t5,0x1 > 800082a4: d61f2023 sw ra,-672(t5) # 80009000 <tohost> > 800082a8: ff9ff06f j 800082a0 <write_tohost> > ``` > QEMU cannot respond to the above `sw` behavior, It makes no > distinction regarding the size written, > I guess that currently qemu will only respond to the writing to the > high 32 bits and low 32 bits of tohost twice in succession. > I think the behavior here is very strange, and you can find > aswaterman's description of HTIF(include RV32) at: > https://github.com/riscv-software-src/riscv-isa-sim/issues/364#issuecomment-607657754 > So this patch try to distinguish these cases based on size and addr. > > About the sail impl, there are some related discussions at: > https://github.com/riscv/sail-riscv/issues/218 > I made some summaries: > - The implementation of sail as a workaround is not very ideal; we > should follow the experience of spike > I checked the impl of spike. Although spike handles tohost in a > syscall manner, I don't think this means that spike is better. > Compared to sail, it does not distinguish whether the write to > tohost is 4 bytes or 8 bytes, but at least in act, it always works > properly. > - spike code: > https://github.com/riscv-software-src/riscv-isa-sim/blob/master/fesvr/htif.cc#L265 > - HTIF has been deprecated > I don't know if this is true or not, because I haven't found any > official comment. > However, since ACT is still using htif and is not expected to change > for quite a long time, and no new solutions have emerged, we should go > ahead and implement it > - What are the advantages of QEMU supporting ACT > - do cross validation with sail/spike, and contributors can use ACT > to verify the correctness when adding new instructions to QEMU. (we do > have this need.) > > If you think that the benefits of supporting ACT are not obvious, > then I think we can remove all the code related to supporting ACT > (should be the commit mentioned above) > > What do you think about this? Thank you! > > Alistair Francis <alistair23@gmail.com> 于2024年10月16日周三 13:27写道: > > > > On Mon, Oct 14, 2024 at 8:08 PM 阎明铸 <yanmingzhu@iscas.ac.cn> wrote: > > > > > > Thank you for your reply and I'm sorry that I didn't explain it clearly. > > > > > > - ACT is an official riscv test suite to check the riscv support of the DUT(device under test). > > > > It's probably worth including this in the commit message. > > > > > - Currently ACT support using [sail-riscv](https://github.com/riscv/sail-riscv)(default) or [spike](https://github.com/riscv-software-src/riscv-isa-sim) > > > - QEMU is not supported yet,but someone made a commit: [commit](https://github.com/qemu/qemu/commit/66247edc8b6fb36d6b905babcd795068ea989ad5) > > > > > > But there are still problems, so I'm trying to fix it. After debugging, I found that it's a htif problem, and the idea of fixing it is referenced from the sail-riscv implementation > > > > It would be good to reference the sail implementation and the > > justification for the change there > > > > Alistair > > > > > > > > "Alistair Francis" <alistair23@gmail.com>写道: > > > > On Fri, Sep 27, 2024 at 11:26 PM MingZhu Yan <trdthg47@gmail.com> wrote: > > > > > > > > > > Applications sometimes only write the lower 32-bit payload bytes, this is used > > > > > in ACT tests. As a workaround, this refers to the solution of sail-riscv. > > > > > > > > I'm not sure what ACT is, but this feels like a guest bug, not a QEMU issue. > > > > > > > > Alistair > > > > > > > > > if the payload is written a few times with the same value, we process the whole > > > > > htif command anyway. > > > > > > > > > > Signed-off-by: MingZhu Yan <yanmingzhu@iscas.ac.cn> > > > > > --- > > > > > hw/char/riscv_htif.c | 35 +++++++++++++++++++---------------- > > > > > 1 file changed, 19 insertions(+), 16 deletions(-) > > > > > > > > > > diff --git a/hw/char/riscv_htif.c b/hw/char/riscv_htif.c > > > > > index 9bef60def1..d74cce3bef 100644 > > > > > --- a/hw/char/riscv_htif.c > > > > > +++ b/hw/char/riscv_htif.c > > > > > @@ -65,16 +65,8 @@ void htif_symbol_callback(const char *st_name, int st_info, uint64_t st_value, > > > > > { > > > > > if (strcmp("fromhost", st_name) == 0) { > > > > > fromhost_addr = st_value; > > > > > - if (st_size != 8) { > > > > > - error_report("HTIF fromhost must be 8 bytes"); > > > > > - exit(1); > > > > > - } > > > > > } else if (strcmp("tohost", st_name) == 0) { > > > > > tohost_addr = st_value; > > > > > - if (st_size != 8) { > > > > > - error_report("HTIF tohost must be 8 bytes"); > > > > > - exit(1); > > > > > - } > > > > > } else if (strcmp("begin_signature", st_name) == 0) { > > > > > begin_sig_addr = st_value; > > > > > } else if (strcmp("end_signature", st_name) == 0) { > > > > > @@ -290,18 +282,26 @@ static void htif_mm_write(void *opaque, hwaddr addr, > > > > > uint64_t value, unsigned size) > > > > > { > > > > > HTIFState *s = opaque; > > > > > - if (addr == TOHOST_OFFSET1) { > > > > > - if (s->tohost == 0x0) { > > > > > - s->allow_tohost = 1; > > > > > - s->tohost = value & 0xFFFFFFFF; > > > > > + int htif_cmd_write = 0; > > > > > + if (size == 8 && addr == TOHOST_OFFSET1) { > > > > > + htif_cmd_write = 1; > > > > > + s->tohost = value; > > > > > + htif_handle_tohost_write(s, s->tohost); > > > > > + } else if (size == 4 && addr == TOHOST_OFFSET1) { > > > > > + if ((value) == (s->tohost & 0xFFFF)) { > > > > > + s->allow_tohost = s->allow_tohost + 1; > > > > > } else { > > > > > s->allow_tohost = 0; > > > > > } > > > > > - } else if (addr == TOHOST_OFFSET2) { > > > > > - if (s->allow_tohost) { > > > > > - s->tohost |= value << 32; > > > > > - htif_handle_tohost_write(s, s->tohost); > > > > > + s->tohost = deposit64(s->tohost, 0, 32, value); > > > > > + } else if (size == 4 && addr == TOHOST_OFFSET2) { > > > > > + if ((value & 0xFF) == (s->tohost & 0xFF00)) { > > > > > + s->allow_tohost = s->allow_tohost + 1; > > > > > + } else { > > > > > + s->allow_tohost = 1; > > > > > } > > > > > + htif_cmd_write = 1; > > > > > + s->tohost = deposit64(s->tohost, 32, 32, value); > > > > > } else if (addr == FROMHOST_OFFSET1) { > > > > > s->fromhost_inprogress = 1; > > > > > s->fromhost = value & 0xFFFFFFFF; > > > > > @@ -312,6 +312,9 @@ static void htif_mm_write(void *opaque, hwaddr addr, > > > > > qemu_log("Invalid htif write: address %016" PRIx64 "\n", > > > > > (uint64_t)addr); > > > > > } > > > > > + if ((s->tohost == 1 && htif_cmd_write) || s->allow_tohost > 2) { > > > > > + htif_handle_tohost_write(s, s->tohost); > > > > > + } > > > > > } > > > > > > > > > > static const MemoryRegionOps htif_mm_ops = { > > > > > -- > > > > > 2.34.1 > > > > > > > > > > > > > </yanmingzhu@iscas.ac.cn></trdthg47@gmail.com>
diff --git a/hw/char/riscv_htif.c b/hw/char/riscv_htif.c index 9bef60def1..d74cce3bef 100644 --- a/hw/char/riscv_htif.c +++ b/hw/char/riscv_htif.c @@ -65,16 +65,8 @@ void htif_symbol_callback(const char *st_name, int st_info, uint64_t st_value, { if (strcmp("fromhost", st_name) == 0) { fromhost_addr = st_value; - if (st_size != 8) { - error_report("HTIF fromhost must be 8 bytes"); - exit(1); - } } else if (strcmp("tohost", st_name) == 0) { tohost_addr = st_value; - if (st_size != 8) { - error_report("HTIF tohost must be 8 bytes"); - exit(1); - } } else if (strcmp("begin_signature", st_name) == 0) { begin_sig_addr = st_value; } else if (strcmp("end_signature", st_name) == 0) { @@ -290,18 +282,26 @@ static void htif_mm_write(void *opaque, hwaddr addr, uint64_t value, unsigned size) { HTIFState *s = opaque; - if (addr == TOHOST_OFFSET1) { - if (s->tohost == 0x0) { - s->allow_tohost = 1; - s->tohost = value & 0xFFFFFFFF; + int htif_cmd_write = 0; + if (size == 8 && addr == TOHOST_OFFSET1) { + htif_cmd_write = 1; + s->tohost = value; + htif_handle_tohost_write(s, s->tohost); + } else if (size == 4 && addr == TOHOST_OFFSET1) { + if ((value) == (s->tohost & 0xFFFF)) { + s->allow_tohost = s->allow_tohost + 1; } else { s->allow_tohost = 0; } - } else if (addr == TOHOST_OFFSET2) { - if (s->allow_tohost) { - s->tohost |= value << 32; - htif_handle_tohost_write(s, s->tohost); + s->tohost = deposit64(s->tohost, 0, 32, value); + } else if (size == 4 && addr == TOHOST_OFFSET2) { + if ((value & 0xFF) == (s->tohost & 0xFF00)) { + s->allow_tohost = s->allow_tohost + 1; + } else { + s->allow_tohost = 1; } + htif_cmd_write = 1; + s->tohost = deposit64(s->tohost, 32, 32, value); } else if (addr == FROMHOST_OFFSET1) { s->fromhost_inprogress = 1; s->fromhost = value & 0xFFFFFFFF; @@ -312,6 +312,9 @@ static void htif_mm_write(void *opaque, hwaddr addr, qemu_log("Invalid htif write: address %016" PRIx64 "\n", (uint64_t)addr); } + if ((s->tohost == 1 && htif_cmd_write) || s->allow_tohost > 2) { + htif_handle_tohost_write(s, s->tohost); + } } static const MemoryRegionOps htif_mm_ops = {
Applications sometimes only write the lower 32-bit payload bytes, this is used in ACT tests. As a workaround, this refers to the solution of sail-riscv. if the payload is written a few times with the same value, we process the whole htif command anyway. Signed-off-by: MingZhu Yan <yanmingzhu@iscas.ac.cn> --- hw/char/riscv_htif.c | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-)