* [PATCH V1 0/2] Fix the rtc issue on loongarch @ 2025-06-13 1:31 Xianglai Li 2025-06-13 1:31 ` [PATCH V1 1/2] hw/rtc: Fixed loongson rtc emulation errors Xianglai Li 2025-06-13 1:31 ` [PATCH V1 2/2] hw/loongarch: add rtc acpi table Xianglai Li 0 siblings, 2 replies; 9+ messages in thread From: Xianglai Li @ 2025-06-13 1:31 UTC (permalink / raw) To: qemu-devel; +Cc: Bibo Mao, Song Gao, Jiaxun Yang The first patch fixed the issue with rtc hardware emulation on the loongarch platform. The second patch adds an acpi table to the rtc hardware simulation of the loongarch platform, enabling the virtual machine kernel to use the loongson rtc driver through the acpi table. Cc: Bibo Mao <maobibo@loongson.cn> Cc: Song Gao <gaosong@loongson.cn> Cc: Jiaxun Yang <jiaxun.yang@flygoat.com> Cc: Xianglai Li <lixianglai@loongson.cn> Xianglai Li (2): hw/rtc: Fixed loongson rtc emulation errors hw/loongarch: add rtc acpi table hw/loongarch/virt-acpi-build.c | 24 ++++++++++++++++++++++++ hw/loongarch/virt-fdt-build.c | 11 +++++++++-- hw/rtc/ls7a_rtc.c | 26 +++++++++++++++++--------- 3 files changed, 50 insertions(+), 11 deletions(-) -- 2.39.1 ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH V1 1/2] hw/rtc: Fixed loongson rtc emulation errors 2025-06-13 1:31 [PATCH V1 0/2] Fix the rtc issue on loongarch Xianglai Li @ 2025-06-13 1:31 ` Xianglai Li 2025-06-13 2:54 ` Bibo Mao 2025-06-13 4:43 ` Bibo Mao 2025-06-13 1:31 ` [PATCH V1 2/2] hw/loongarch: add rtc acpi table Xianglai Li 1 sibling, 2 replies; 9+ messages in thread From: Xianglai Li @ 2025-06-13 1:31 UTC (permalink / raw) To: qemu-devel; +Cc: Bibo Mao, Song Gao, Jiaxun Yang The expire time is sent to the timer only when the expire Time is greater than 0 or greater than now. Otherwise, the timer will trigger interruption continuously. Timer interrupts are sent using pulse functions. Signed-off-by: Xianglai Li <lixianglai@loongson.cn> --- Cc: Bibo Mao <maobibo@loongson.cn> Cc: Song Gao <gaosong@loongson.cn> Cc: Jiaxun Yang <jiaxun.yang@flygoat.com> Cc: Xianglai Li <lixianglai@loongson.cn> hw/loongarch/virt-fdt-build.c | 11 +++++++++-- hw/rtc/ls7a_rtc.c | 26 +++++++++++++++++--------- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/hw/loongarch/virt-fdt-build.c b/hw/loongarch/virt-fdt-build.c index 728ce46699..c613131a07 100644 --- a/hw/loongarch/virt-fdt-build.c +++ b/hw/loongarch/virt-fdt-build.c @@ -17,6 +17,11 @@ #include "system/reset.h" #include "target/loongarch/cpu.h" +#define FDT_IRQ_FLAGS_EDGE_LO_HI 1 +#define FDT_IRQ_FLAGS_EDGE_HI_LO 2 +#define FDT_IRQ_FLAGS_LEVEL_HI 4 +#define FDT_IRQ_FLAGS_LEVEL_LO 8 + static void create_fdt(LoongArchVirtMachineState *lvms) { MachineState *ms = MACHINE(lvms); @@ -416,7 +421,8 @@ static void fdt_add_uart_node(LoongArchVirtMachineState *lvms, if (chosen) { qemu_fdt_setprop_string(ms->fdt, "/chosen", "stdout-path", nodename); } - qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts", irq, 0x4); + qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts", irq, + FDT_IRQ_FLAGS_LEVEL_HI); qemu_fdt_setprop_cell(ms->fdt, nodename, "interrupt-parent", *pch_pic_phandle); g_free(nodename); @@ -436,7 +442,8 @@ static void fdt_add_rtc_node(LoongArchVirtMachineState *lvms, "loongson,ls7a-rtc"); qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", 2, base, 2, size); qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts", - VIRT_RTC_IRQ - VIRT_GSI_BASE , 0x4); + VIRT_RTC_IRQ - VIRT_GSI_BASE , + FDT_IRQ_FLAGS_EDGE_LO_HI); qemu_fdt_setprop_cell(ms->fdt, nodename, "interrupt-parent", *pch_pic_phandle); g_free(nodename); diff --git a/hw/rtc/ls7a_rtc.c b/hw/rtc/ls7a_rtc.c index 10097b2db7..7eca75a42a 100644 --- a/hw/rtc/ls7a_rtc.c +++ b/hw/rtc/ls7a_rtc.c @@ -145,20 +145,24 @@ static void toymatch_write(LS7ARtcState *s, uint64_t val, int num) now = qemu_clock_get_ms(rtc_clock); toymatch_val_to_time(s, val, &tm); expire_time = now + (qemu_timedate_diff(&tm) - s->offset_toy) * 1000; - timer_mod(s->toy_timer[num], expire_time); + if (expire_time > now) { + timer_mod(s->toy_timer[num], expire_time); + } } } static void rtcmatch_write(LS7ARtcState *s, uint64_t val, int num) { - uint64_t expire_ns; + int64_t expire_ns; /* it do not support write when toy disabled */ if (rtc_enabled(s)) { s->rtcmatch[num] = val; /* calculate expire time */ expire_ns = ticks_to_ns(val) - ticks_to_ns(s->offset_rtc); - timer_mod_ns(s->rtc_timer[num], expire_ns); + if (expire_ns > 0) { + timer_mod_ns(s->rtc_timer[num], expire_ns); + } } } @@ -185,7 +189,7 @@ static void ls7a_rtc_stop(LS7ARtcState *s) static void ls7a_toy_start(LS7ARtcState *s) { int i; - uint64_t expire_time, now; + int64_t expire_time, now; struct tm tm = {}; now = qemu_clock_get_ms(rtc_clock); @@ -194,19 +198,23 @@ static void ls7a_toy_start(LS7ARtcState *s) for (i = 0; i < TIMER_NUMS; i++) { toymatch_val_to_time(s, s->toymatch[i], &tm); expire_time = now + (qemu_timedate_diff(&tm) - s->offset_toy) * 1000; - timer_mod(s->toy_timer[i], expire_time); + if (expire_time > now) { + timer_mod(s->toy_timer[i], expire_time); + } } } static void ls7a_rtc_start(LS7ARtcState *s) { int i; - uint64_t expire_time; + int64_t expire_time; /* recalculate expire time and enable timer */ for (i = 0; i < TIMER_NUMS; i++) { expire_time = ticks_to_ns(s->rtcmatch[i]) - ticks_to_ns(s->offset_rtc); - timer_mod_ns(s->rtc_timer[i], expire_time); + if (expire_time > 0) { + timer_mod_ns(s->rtc_timer[i], expire_time); + } } } @@ -370,7 +378,7 @@ static void toy_timer_cb(void *opaque) LS7ARtcState *s = opaque; if (toy_enabled(s)) { - qemu_irq_raise(s->irq); + qemu_irq_pulse(s->irq); } } @@ -379,7 +387,7 @@ static void rtc_timer_cb(void *opaque) LS7ARtcState *s = opaque; if (rtc_enabled(s)) { - qemu_irq_raise(s->irq); + qemu_irq_pulse(s->irq); } } -- 2.39.1 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH V1 1/2] hw/rtc: Fixed loongson rtc emulation errors 2025-06-13 1:31 ` [PATCH V1 1/2] hw/rtc: Fixed loongson rtc emulation errors Xianglai Li @ 2025-06-13 2:54 ` Bibo Mao 2025-06-13 4:43 ` Bibo Mao 1 sibling, 0 replies; 9+ messages in thread From: Bibo Mao @ 2025-06-13 2:54 UTC (permalink / raw) To: Xianglai Li, qemu-devel; +Cc: Song Gao, Jiaxun Yang On 2025/6/13 上午9:31, Xianglai Li wrote: > The expire time is sent to the timer only > when the expire Time is greater than 0 or > greater than now. Otherwise, the timer > will trigger interruption continuously. Again, one line of the comments should no more than 75 bytes :) I think it should be split into two patches, one is fixup with irq pulse type setting, the other is fixup with expired time out calculation in rtc emulation driver. Regards Bibo Mao > > Timer interrupts are sent using pulse functions. > > Signed-off-by: Xianglai Li <lixianglai@loongson.cn> > --- > Cc: Bibo Mao <maobibo@loongson.cn> > Cc: Song Gao <gaosong@loongson.cn> > Cc: Jiaxun Yang <jiaxun.yang@flygoat.com> > Cc: Xianglai Li <lixianglai@loongson.cn> > > hw/loongarch/virt-fdt-build.c | 11 +++++++++-- > hw/rtc/ls7a_rtc.c | 26 +++++++++++++++++--------- > 2 files changed, 26 insertions(+), 11 deletions(-) > > diff --git a/hw/loongarch/virt-fdt-build.c b/hw/loongarch/virt-fdt-build.c > index 728ce46699..c613131a07 100644 > --- a/hw/loongarch/virt-fdt-build.c > +++ b/hw/loongarch/virt-fdt-build.c > @@ -17,6 +17,11 @@ > #include "system/reset.h" > #include "target/loongarch/cpu.h" > > +#define FDT_IRQ_FLAGS_EDGE_LO_HI 1 > +#define FDT_IRQ_FLAGS_EDGE_HI_LO 2 > +#define FDT_IRQ_FLAGS_LEVEL_HI 4 > +#define FDT_IRQ_FLAGS_LEVEL_LO 8 > + > static void create_fdt(LoongArchVirtMachineState *lvms) > { > MachineState *ms = MACHINE(lvms); > @@ -416,7 +421,8 @@ static void fdt_add_uart_node(LoongArchVirtMachineState *lvms, > if (chosen) { > qemu_fdt_setprop_string(ms->fdt, "/chosen", "stdout-path", nodename); > } > - qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts", irq, 0x4); > + qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts", irq, > + FDT_IRQ_FLAGS_LEVEL_HI); > qemu_fdt_setprop_cell(ms->fdt, nodename, "interrupt-parent", > *pch_pic_phandle); > g_free(nodename); > @@ -436,7 +442,8 @@ static void fdt_add_rtc_node(LoongArchVirtMachineState *lvms, > "loongson,ls7a-rtc"); > qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", 2, base, 2, size); > qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts", > - VIRT_RTC_IRQ - VIRT_GSI_BASE , 0x4); > + VIRT_RTC_IRQ - VIRT_GSI_BASE , > + FDT_IRQ_FLAGS_EDGE_LO_HI); > qemu_fdt_setprop_cell(ms->fdt, nodename, "interrupt-parent", > *pch_pic_phandle); > g_free(nodename); > diff --git a/hw/rtc/ls7a_rtc.c b/hw/rtc/ls7a_rtc.c > index 10097b2db7..7eca75a42a 100644 > --- a/hw/rtc/ls7a_rtc.c > +++ b/hw/rtc/ls7a_rtc.c > @@ -145,20 +145,24 @@ static void toymatch_write(LS7ARtcState *s, uint64_t val, int num) > now = qemu_clock_get_ms(rtc_clock); > toymatch_val_to_time(s, val, &tm); > expire_time = now + (qemu_timedate_diff(&tm) - s->offset_toy) * 1000; > - timer_mod(s->toy_timer[num], expire_time); > + if (expire_time > now) { > + timer_mod(s->toy_timer[num], expire_time); > + } > } > } > > static void rtcmatch_write(LS7ARtcState *s, uint64_t val, int num) > { > - uint64_t expire_ns; > + int64_t expire_ns; > > /* it do not support write when toy disabled */ > if (rtc_enabled(s)) { > s->rtcmatch[num] = val; > /* calculate expire time */ > expire_ns = ticks_to_ns(val) - ticks_to_ns(s->offset_rtc); > - timer_mod_ns(s->rtc_timer[num], expire_ns); > + if (expire_ns > 0) { > + timer_mod_ns(s->rtc_timer[num], expire_ns); > + } > } > } > > @@ -185,7 +189,7 @@ static void ls7a_rtc_stop(LS7ARtcState *s) > static void ls7a_toy_start(LS7ARtcState *s) > { > int i; > - uint64_t expire_time, now; > + int64_t expire_time, now; > struct tm tm = {}; > > now = qemu_clock_get_ms(rtc_clock); > @@ -194,19 +198,23 @@ static void ls7a_toy_start(LS7ARtcState *s) > for (i = 0; i < TIMER_NUMS; i++) { > toymatch_val_to_time(s, s->toymatch[i], &tm); > expire_time = now + (qemu_timedate_diff(&tm) - s->offset_toy) * 1000; > - timer_mod(s->toy_timer[i], expire_time); > + if (expire_time > now) { > + timer_mod(s->toy_timer[i], expire_time); > + } > } > } > > static void ls7a_rtc_start(LS7ARtcState *s) > { > int i; > - uint64_t expire_time; > + int64_t expire_time; > > /* recalculate expire time and enable timer */ > for (i = 0; i < TIMER_NUMS; i++) { > expire_time = ticks_to_ns(s->rtcmatch[i]) - ticks_to_ns(s->offset_rtc); > - timer_mod_ns(s->rtc_timer[i], expire_time); > + if (expire_time > 0) { > + timer_mod_ns(s->rtc_timer[i], expire_time); > + } > } > } > > @@ -370,7 +378,7 @@ static void toy_timer_cb(void *opaque) > LS7ARtcState *s = opaque; > > if (toy_enabled(s)) { > - qemu_irq_raise(s->irq); > + qemu_irq_pulse(s->irq); > } > } > > @@ -379,7 +387,7 @@ static void rtc_timer_cb(void *opaque) > LS7ARtcState *s = opaque; > > if (rtc_enabled(s)) { > - qemu_irq_raise(s->irq); > + qemu_irq_pulse(s->irq); > } > } > > ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH V1 1/2] hw/rtc: Fixed loongson rtc emulation errors 2025-06-13 1:31 ` [PATCH V1 1/2] hw/rtc: Fixed loongson rtc emulation errors Xianglai Li 2025-06-13 2:54 ` Bibo Mao @ 2025-06-13 4:43 ` Bibo Mao 2025-07-07 6:36 ` lixianglai 1 sibling, 1 reply; 9+ messages in thread From: Bibo Mao @ 2025-06-13 4:43 UTC (permalink / raw) To: Xianglai Li, qemu-devel; +Cc: Song Gao, Jiaxun Yang On 2025/6/13 上午9:31, Xianglai Li wrote: > The expire time is sent to the timer only > when the expire Time is greater than 0 or > greater than now. Otherwise, the timer > will trigger interruption continuously. > > Timer interrupts are sent using pulse functions. > > Signed-off-by: Xianglai Li <lixianglai@loongson.cn> > --- > Cc: Bibo Mao <maobibo@loongson.cn> > Cc: Song Gao <gaosong@loongson.cn> > Cc: Jiaxun Yang <jiaxun.yang@flygoat.com> > Cc: Xianglai Li <lixianglai@loongson.cn> > > hw/loongarch/virt-fdt-build.c | 11 +++++++++-- > hw/rtc/ls7a_rtc.c | 26 +++++++++++++++++--------- > 2 files changed, 26 insertions(+), 11 deletions(-) > > diff --git a/hw/loongarch/virt-fdt-build.c b/hw/loongarch/virt-fdt-build.c > index 728ce46699..c613131a07 100644 > --- a/hw/loongarch/virt-fdt-build.c > +++ b/hw/loongarch/virt-fdt-build.c > @@ -17,6 +17,11 @@ > #include "system/reset.h" > #include "target/loongarch/cpu.h" > > +#define FDT_IRQ_FLAGS_EDGE_LO_HI 1 > +#define FDT_IRQ_FLAGS_EDGE_HI_LO 2 > +#define FDT_IRQ_FLAGS_LEVEL_HI 4 > +#define FDT_IRQ_FLAGS_LEVEL_LO 8 > + > static void create_fdt(LoongArchVirtMachineState *lvms) > { > MachineState *ms = MACHINE(lvms); > @@ -416,7 +421,8 @@ static void fdt_add_uart_node(LoongArchVirtMachineState *lvms, > if (chosen) { > qemu_fdt_setprop_string(ms->fdt, "/chosen", "stdout-path", nodename); > } > - qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts", irq, 0x4); > + qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts", irq, > + FDT_IRQ_FLAGS_LEVEL_HI); > qemu_fdt_setprop_cell(ms->fdt, nodename, "interrupt-parent", > *pch_pic_phandle); > g_free(nodename); > @@ -436,7 +442,8 @@ static void fdt_add_rtc_node(LoongArchVirtMachineState *lvms, > "loongson,ls7a-rtc"); > qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", 2, base, 2, size); > qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts", > - VIRT_RTC_IRQ - VIRT_GSI_BASE , 0x4); > + VIRT_RTC_IRQ - VIRT_GSI_BASE , > + FDT_IRQ_FLAGS_EDGE_LO_HI); > qemu_fdt_setprop_cell(ms->fdt, nodename, "interrupt-parent", > *pch_pic_phandle); > g_free(nodename); > diff --git a/hw/rtc/ls7a_rtc.c b/hw/rtc/ls7a_rtc.c > index 10097b2db7..7eca75a42a 100644 > --- a/hw/rtc/ls7a_rtc.c > +++ b/hw/rtc/ls7a_rtc.c > @@ -145,20 +145,24 @@ static void toymatch_write(LS7ARtcState *s, uint64_t val, int num) > now = qemu_clock_get_ms(rtc_clock); > toymatch_val_to_time(s, val, &tm); > expire_time = now + (qemu_timedate_diff(&tm) - s->offset_toy) * 1000; > - timer_mod(s->toy_timer[num], expire_time); > + if (expire_time > now) { > + timer_mod(s->toy_timer[num], expire_time); > + } Should rtc alarm interrupt be injected directly if (expire_time <= now)? Regards Bibo Mao > } > } > > static void rtcmatch_write(LS7ARtcState *s, uint64_t val, int num) > { > - uint64_t expire_ns; > + int64_t expire_ns; > > /* it do not support write when toy disabled */ > if (rtc_enabled(s)) { > s->rtcmatch[num] = val; > /* calculate expire time */ > expire_ns = ticks_to_ns(val) - ticks_to_ns(s->offset_rtc); > - timer_mod_ns(s->rtc_timer[num], expire_ns); > + if (expire_ns > 0) { > + timer_mod_ns(s->rtc_timer[num], expire_ns); > + } > } > } > > @@ -185,7 +189,7 @@ static void ls7a_rtc_stop(LS7ARtcState *s) > static void ls7a_toy_start(LS7ARtcState *s) > { > int i; > - uint64_t expire_time, now; > + int64_t expire_time, now; > struct tm tm = {}; > > now = qemu_clock_get_ms(rtc_clock); > @@ -194,19 +198,23 @@ static void ls7a_toy_start(LS7ARtcState *s) > for (i = 0; i < TIMER_NUMS; i++) { > toymatch_val_to_time(s, s->toymatch[i], &tm); > expire_time = now + (qemu_timedate_diff(&tm) - s->offset_toy) * 1000; > - timer_mod(s->toy_timer[i], expire_time); > + if (expire_time > now) { > + timer_mod(s->toy_timer[i], expire_time); > + } > } > } > > static void ls7a_rtc_start(LS7ARtcState *s) > { > int i; > - uint64_t expire_time; > + int64_t expire_time; > > /* recalculate expire time and enable timer */ > for (i = 0; i < TIMER_NUMS; i++) { > expire_time = ticks_to_ns(s->rtcmatch[i]) - ticks_to_ns(s->offset_rtc); > - timer_mod_ns(s->rtc_timer[i], expire_time); > + if (expire_time > 0) { > + timer_mod_ns(s->rtc_timer[i], expire_time); > + } > } > } > > @@ -370,7 +378,7 @@ static void toy_timer_cb(void *opaque) > LS7ARtcState *s = opaque; > > if (toy_enabled(s)) { > - qemu_irq_raise(s->irq); > + qemu_irq_pulse(s->irq); > } > } > > @@ -379,7 +387,7 @@ static void rtc_timer_cb(void *opaque) > LS7ARtcState *s = opaque; > > if (rtc_enabled(s)) { > - qemu_irq_raise(s->irq); > + qemu_irq_pulse(s->irq); > } > } > > ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH V1 1/2] hw/rtc: Fixed loongson rtc emulation errors 2025-06-13 4:43 ` Bibo Mao @ 2025-07-07 6:36 ` lixianglai 2025-07-07 7:17 ` Bibo Mao 0 siblings, 1 reply; 9+ messages in thread From: lixianglai @ 2025-07-07 6:36 UTC (permalink / raw) To: Bibo Mao, qemu-devel; +Cc: Song Gao, Jiaxun Yang Hi Bibo Mao: > > > On 2025/6/13 上午9:31, Xianglai Li wrote: >> The expire time is sent to the timer only >> when the expire Time is greater than 0 or >> greater than now. Otherwise, the timer >> will trigger interruption continuously. >> >> Timer interrupts are sent using pulse functions. >> >> Signed-off-by: Xianglai Li <lixianglai@loongson.cn> >> --- >> Cc: Bibo Mao <maobibo@loongson.cn> >> Cc: Song Gao <gaosong@loongson.cn> >> Cc: Jiaxun Yang <jiaxun.yang@flygoat.com> >> Cc: Xianglai Li <lixianglai@loongson.cn> >> >> hw/loongarch/virt-fdt-build.c | 11 +++++++++-- >> hw/rtc/ls7a_rtc.c | 26 +++++++++++++++++--------- >> 2 files changed, 26 insertions(+), 11 deletions(-) >> >> diff --git a/hw/loongarch/virt-fdt-build.c >> b/hw/loongarch/virt-fdt-build.c >> index 728ce46699..c613131a07 100644 >> --- a/hw/loongarch/virt-fdt-build.c >> +++ b/hw/loongarch/virt-fdt-build.c >> @@ -17,6 +17,11 @@ >> #include "system/reset.h" >> #include "target/loongarch/cpu.h" >> +#define FDT_IRQ_FLAGS_EDGE_LO_HI 1 >> +#define FDT_IRQ_FLAGS_EDGE_HI_LO 2 >> +#define FDT_IRQ_FLAGS_LEVEL_HI 4 >> +#define FDT_IRQ_FLAGS_LEVEL_LO 8 >> + >> static void create_fdt(LoongArchVirtMachineState *lvms) >> { >> MachineState *ms = MACHINE(lvms); >> @@ -416,7 +421,8 @@ static void >> fdt_add_uart_node(LoongArchVirtMachineState *lvms, >> if (chosen) { >> qemu_fdt_setprop_string(ms->fdt, "/chosen", "stdout-path", >> nodename); >> } >> - qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts", irq, 0x4); >> + qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts", irq, >> + FDT_IRQ_FLAGS_LEVEL_HI); >> qemu_fdt_setprop_cell(ms->fdt, nodename, "interrupt-parent", >> *pch_pic_phandle); >> g_free(nodename); >> @@ -436,7 +442,8 @@ static void >> fdt_add_rtc_node(LoongArchVirtMachineState *lvms, >> "loongson,ls7a-rtc"); >> qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", 2, base, >> 2, size); >> qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts", >> - VIRT_RTC_IRQ - VIRT_GSI_BASE , 0x4); >> + VIRT_RTC_IRQ - VIRT_GSI_BASE , >> + FDT_IRQ_FLAGS_EDGE_LO_HI); >> qemu_fdt_setprop_cell(ms->fdt, nodename, "interrupt-parent", >> *pch_pic_phandle); >> g_free(nodename); >> diff --git a/hw/rtc/ls7a_rtc.c b/hw/rtc/ls7a_rtc.c >> index 10097b2db7..7eca75a42a 100644 >> --- a/hw/rtc/ls7a_rtc.c >> +++ b/hw/rtc/ls7a_rtc.c >> @@ -145,20 +145,24 @@ static void toymatch_write(LS7ARtcState *s, >> uint64_t val, int num) >> now = qemu_clock_get_ms(rtc_clock); >> toymatch_val_to_time(s, val, &tm); >> expire_time = now + (qemu_timedate_diff(&tm) - >> s->offset_toy) * 1000; >> - timer_mod(s->toy_timer[num], expire_time); >> + if (expire_time > now) { >> + timer_mod(s->toy_timer[num], expire_time); >> + } > Should rtc alarm interrupt be injected directly if (expire_time <= now)? > Through experiments on the hardware platform, sending an alarm less than the current time to loongson rtc alarm does not trigger an interrupt. According to the behavior of the hardware, we do not need to trigger an interrupt immediately when expire_time <= now Thanks, Xianglai Li. > Regards > Bibo Mao >> } >> } >> static void rtcmatch_write(LS7ARtcState *s, uint64_t val, int num) >> { >> - uint64_t expire_ns; >> + int64_t expire_ns; >> /* it do not support write when toy disabled */ >> if (rtc_enabled(s)) { >> s->rtcmatch[num] = val; >> /* calculate expire time */ >> expire_ns = ticks_to_ns(val) - ticks_to_ns(s->offset_rtc); >> - timer_mod_ns(s->rtc_timer[num], expire_ns); >> + if (expire_ns > 0) { >> + timer_mod_ns(s->rtc_timer[num], expire_ns); >> + } >> } >> } >> @@ -185,7 +189,7 @@ static void ls7a_rtc_stop(LS7ARtcState *s) >> static void ls7a_toy_start(LS7ARtcState *s) >> { >> int i; >> - uint64_t expire_time, now; >> + int64_t expire_time, now; >> struct tm tm = {}; >> now = qemu_clock_get_ms(rtc_clock); >> @@ -194,19 +198,23 @@ static void ls7a_toy_start(LS7ARtcState *s) >> for (i = 0; i < TIMER_NUMS; i++) { >> toymatch_val_to_time(s, s->toymatch[i], &tm); >> expire_time = now + (qemu_timedate_diff(&tm) - >> s->offset_toy) * 1000; >> - timer_mod(s->toy_timer[i], expire_time); >> + if (expire_time > now) { >> + timer_mod(s->toy_timer[i], expire_time); >> + } >> } >> } >> static void ls7a_rtc_start(LS7ARtcState *s) >> { >> int i; >> - uint64_t expire_time; >> + int64_t expire_time; >> /* recalculate expire time and enable timer */ >> for (i = 0; i < TIMER_NUMS; i++) { >> expire_time = ticks_to_ns(s->rtcmatch[i]) - >> ticks_to_ns(s->offset_rtc); >> - timer_mod_ns(s->rtc_timer[i], expire_time); >> + if (expire_time > 0) { >> + timer_mod_ns(s->rtc_timer[i], expire_time); >> + } >> } >> } >> @@ -370,7 +378,7 @@ static void toy_timer_cb(void *opaque) >> LS7ARtcState *s = opaque; >> if (toy_enabled(s)) { >> - qemu_irq_raise(s->irq); >> + qemu_irq_pulse(s->irq); >> } >> } >> @@ -379,7 +387,7 @@ static void rtc_timer_cb(void *opaque) >> LS7ARtcState *s = opaque; >> if (rtc_enabled(s)) { >> - qemu_irq_raise(s->irq); >> + qemu_irq_pulse(s->irq); >> } >> } >> ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH V1 1/2] hw/rtc: Fixed loongson rtc emulation errors 2025-07-07 6:36 ` lixianglai @ 2025-07-07 7:17 ` Bibo Mao 0 siblings, 0 replies; 9+ messages in thread From: Bibo Mao @ 2025-07-07 7:17 UTC (permalink / raw) To: lixianglai, qemu-devel; +Cc: Song Gao, Jiaxun Yang On 2025/7/7 下午2:36, lixianglai wrote: > Hi Bibo Mao: >> >> >> On 2025/6/13 上午9:31, Xianglai Li wrote: >>> The expire time is sent to the timer only >>> when the expire Time is greater than 0 or >>> greater than now. Otherwise, the timer >>> will trigger interruption continuously. >>> >>> Timer interrupts are sent using pulse functions. >>> >>> Signed-off-by: Xianglai Li <lixianglai@loongson.cn> >>> --- >>> Cc: Bibo Mao <maobibo@loongson.cn> >>> Cc: Song Gao <gaosong@loongson.cn> >>> Cc: Jiaxun Yang <jiaxun.yang@flygoat.com> >>> Cc: Xianglai Li <lixianglai@loongson.cn> >>> >>> hw/loongarch/virt-fdt-build.c | 11 +++++++++-- >>> hw/rtc/ls7a_rtc.c | 26 +++++++++++++++++--------- >>> 2 files changed, 26 insertions(+), 11 deletions(-) >>> >>> diff --git a/hw/loongarch/virt-fdt-build.c >>> b/hw/loongarch/virt-fdt-build.c >>> index 728ce46699..c613131a07 100644 >>> --- a/hw/loongarch/virt-fdt-build.c >>> +++ b/hw/loongarch/virt-fdt-build.c >>> @@ -17,6 +17,11 @@ >>> #include "system/reset.h" >>> #include "target/loongarch/cpu.h" >>> +#define FDT_IRQ_FLAGS_EDGE_LO_HI 1 >>> +#define FDT_IRQ_FLAGS_EDGE_HI_LO 2 >>> +#define FDT_IRQ_FLAGS_LEVEL_HI 4 >>> +#define FDT_IRQ_FLAGS_LEVEL_LO 8 >>> + >>> static void create_fdt(LoongArchVirtMachineState *lvms) >>> { >>> MachineState *ms = MACHINE(lvms); >>> @@ -416,7 +421,8 @@ static void >>> fdt_add_uart_node(LoongArchVirtMachineState *lvms, >>> if (chosen) { >>> qemu_fdt_setprop_string(ms->fdt, "/chosen", "stdout-path", >>> nodename); >>> } >>> - qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts", irq, 0x4); >>> + qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts", irq, >>> + FDT_IRQ_FLAGS_LEVEL_HI); >>> qemu_fdt_setprop_cell(ms->fdt, nodename, "interrupt-parent", >>> *pch_pic_phandle); >>> g_free(nodename); >>> @@ -436,7 +442,8 @@ static void >>> fdt_add_rtc_node(LoongArchVirtMachineState *lvms, >>> "loongson,ls7a-rtc"); >>> qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", 2, base, >>> 2, size); >>> qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts", >>> - VIRT_RTC_IRQ - VIRT_GSI_BASE , 0x4); >>> + VIRT_RTC_IRQ - VIRT_GSI_BASE , >>> + FDT_IRQ_FLAGS_EDGE_LO_HI); >>> qemu_fdt_setprop_cell(ms->fdt, nodename, "interrupt-parent", >>> *pch_pic_phandle); >>> g_free(nodename); >>> diff --git a/hw/rtc/ls7a_rtc.c b/hw/rtc/ls7a_rtc.c >>> index 10097b2db7..7eca75a42a 100644 >>> --- a/hw/rtc/ls7a_rtc.c >>> +++ b/hw/rtc/ls7a_rtc.c >>> @@ -145,20 +145,24 @@ static void toymatch_write(LS7ARtcState *s, >>> uint64_t val, int num) >>> now = qemu_clock_get_ms(rtc_clock); >>> toymatch_val_to_time(s, val, &tm); >>> expire_time = now + (qemu_timedate_diff(&tm) - >>> s->offset_toy) * 1000; >>> - timer_mod(s->toy_timer[num], expire_time); >>> + if (expire_time > now) { >>> + timer_mod(s->toy_timer[num], expire_time); >>> + } >> Should rtc alarm interrupt be injected directly if (expire_time <= now)? >> > Through experiments on the hardware platform, sending an alarm less than > the current time to loongson rtc alarm does not trigger an interrupt. > > According to the behavior of the hardware, we do not need to trigger an > interrupt immediately when expire_time <= now Sounds good. yes, the behavior of qemu emulation should be the same with real HW. Regards Bibo Mao > > Thanks, > Xianglai Li. > >> Regards >> Bibo Mao >>> } >>> } >>> static void rtcmatch_write(LS7ARtcState *s, uint64_t val, int num) >>> { >>> - uint64_t expire_ns; >>> + int64_t expire_ns; >>> /* it do not support write when toy disabled */ >>> if (rtc_enabled(s)) { >>> s->rtcmatch[num] = val; >>> /* calculate expire time */ >>> expire_ns = ticks_to_ns(val) - ticks_to_ns(s->offset_rtc); >>> - timer_mod_ns(s->rtc_timer[num], expire_ns); >>> + if (expire_ns > 0) { >>> + timer_mod_ns(s->rtc_timer[num], expire_ns); >>> + } >>> } >>> } >>> @@ -185,7 +189,7 @@ static void ls7a_rtc_stop(LS7ARtcState *s) >>> static void ls7a_toy_start(LS7ARtcState *s) >>> { >>> int i; >>> - uint64_t expire_time, now; >>> + int64_t expire_time, now; >>> struct tm tm = {}; >>> now = qemu_clock_get_ms(rtc_clock); >>> @@ -194,19 +198,23 @@ static void ls7a_toy_start(LS7ARtcState *s) >>> for (i = 0; i < TIMER_NUMS; i++) { >>> toymatch_val_to_time(s, s->toymatch[i], &tm); >>> expire_time = now + (qemu_timedate_diff(&tm) - >>> s->offset_toy) * 1000; >>> - timer_mod(s->toy_timer[i], expire_time); >>> + if (expire_time > now) { >>> + timer_mod(s->toy_timer[i], expire_time); >>> + } >>> } >>> } >>> static void ls7a_rtc_start(LS7ARtcState *s) >>> { >>> int i; >>> - uint64_t expire_time; >>> + int64_t expire_time; >>> /* recalculate expire time and enable timer */ >>> for (i = 0; i < TIMER_NUMS; i++) { >>> expire_time = ticks_to_ns(s->rtcmatch[i]) - >>> ticks_to_ns(s->offset_rtc); >>> - timer_mod_ns(s->rtc_timer[i], expire_time); >>> + if (expire_time > 0) { >>> + timer_mod_ns(s->rtc_timer[i], expire_time); >>> + } >>> } >>> } >>> @@ -370,7 +378,7 @@ static void toy_timer_cb(void *opaque) >>> LS7ARtcState *s = opaque; >>> if (toy_enabled(s)) { >>> - qemu_irq_raise(s->irq); >>> + qemu_irq_pulse(s->irq); >>> } >>> } >>> @@ -379,7 +387,7 @@ static void rtc_timer_cb(void *opaque) >>> LS7ARtcState *s = opaque; >>> if (rtc_enabled(s)) { >>> - qemu_irq_raise(s->irq); >>> + qemu_irq_pulse(s->irq); >>> } >>> } >>> ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH V1 2/2] hw/loongarch: add rtc acpi table 2025-06-13 1:31 [PATCH V1 0/2] Fix the rtc issue on loongarch Xianglai Li 2025-06-13 1:31 ` [PATCH V1 1/2] hw/rtc: Fixed loongson rtc emulation errors Xianglai Li @ 2025-06-13 1:31 ` Xianglai Li 2025-06-13 2:48 ` Bibo Mao 2025-06-13 4:47 ` Bibo Mao 1 sibling, 2 replies; 9+ messages in thread From: Xianglai Li @ 2025-06-13 1:31 UTC (permalink / raw) To: qemu-devel; +Cc: Bibo Mao, Song Gao, Jiaxun Yang Add the acpi table to the loongson rtc hardware so that the virtual machine kernel can use the loongson RTC-related drivers. Signed-off-by: Xianglai Li <lixianglai@loongson.cn> --- Cc: Bibo Mao <maobibo@loongson.cn> Cc: Song Gao <gaosong@loongson.cn> Cc: Jiaxun Yang <jiaxun.yang@flygoat.com> Cc: Xianglai Li <lixianglai@loongson.cn> hw/loongarch/virt-acpi-build.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/hw/loongarch/virt-acpi-build.c b/hw/loongarch/virt-acpi-build.c index 2cd2d9d842..2cfc5421c5 100644 --- a/hw/loongarch/virt-acpi-build.c +++ b/hw/loongarch/virt-acpi-build.c @@ -473,6 +473,29 @@ static void acpi_dsdt_add_tpm(Aml *scope, LoongArchVirtMachineState *vms) } #endif +static void acpi_dsdt_add_rtc(Aml *scope) +{ + uint32_t rtc_irq = VIRT_RTC_IRQ; + Aml *dev = aml_device("RTC"); + + aml_append(dev, aml_name_decl("_HID", aml_string("LOON0001"))); + aml_append(dev, aml_name_decl("_UID", aml_int(0))); + + Aml *crs = aml_resource_template(); + aml_append(crs, + aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED, + AML_NON_CACHEABLE, AML_READ_WRITE, + 0, VIRT_RTC_REG_BASE, + VIRT_RTC_REG_BASE + VIRT_RTC_LEN - 1, + 0, VIRT_RTC_LEN)); + aml_append(crs, + aml_interrupt(AML_CONSUMER, AML_EDGE, AML_ACTIVE_HIGH, + AML_EXCLUSIVE, &rtc_irq, 1)); + + aml_append(dev, aml_name_decl("_CRS", crs)); + aml_append(scope, dev); +} + /* build DSDT */ static void build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine) @@ -488,6 +511,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine) for (i = 0; i < VIRT_UART_COUNT; i++) { build_uart_device_aml(dsdt, i); } + acpi_dsdt_add_rtc(dsdt); build_pci_device_aml(dsdt, lvms); build_la_ged_aml(dsdt, machine); build_flash_aml(dsdt, lvms); -- 2.39.1 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH V1 2/2] hw/loongarch: add rtc acpi table 2025-06-13 1:31 ` [PATCH V1 2/2] hw/loongarch: add rtc acpi table Xianglai Li @ 2025-06-13 2:48 ` Bibo Mao 2025-06-13 4:47 ` Bibo Mao 1 sibling, 0 replies; 9+ messages in thread From: Bibo Mao @ 2025-06-13 2:48 UTC (permalink / raw) To: Xianglai Li, qemu-devel; +Cc: Song Gao, Jiaxun Yang Xianglai, On 2025/6/13 上午9:31, Xianglai Li wrote: > Add the acpi table to the loongson rtc hardware > so that the virtual machine kernel can use the > loongson RTC-related drivers. One line of the comments is no more than 75 bytes, it seems that it is far less than 75 bytes. > > Signed-off-by: Xianglai Li <lixianglai@loongson.cn> > --- > Cc: Bibo Mao <maobibo@loongson.cn> > Cc: Song Gao <gaosong@loongson.cn> > Cc: Jiaxun Yang <jiaxun.yang@flygoat.com> > Cc: Xianglai Li <lixianglai@loongson.cn> > > hw/loongarch/virt-acpi-build.c | 24 ++++++++++++++++++++++++ > 1 file changed, 24 insertions(+) > > diff --git a/hw/loongarch/virt-acpi-build.c b/hw/loongarch/virt-acpi-build.c > index 2cd2d9d842..2cfc5421c5 100644 > --- a/hw/loongarch/virt-acpi-build.c > +++ b/hw/loongarch/virt-acpi-build.c > @@ -473,6 +473,29 @@ static void acpi_dsdt_add_tpm(Aml *scope, LoongArchVirtMachineState *vms) > } > #endif > > +static void acpi_dsdt_add_rtc(Aml *scope) > +{ > + uint32_t rtc_irq = VIRT_RTC_IRQ; > + Aml *dev = aml_device("RTC"); > + > + aml_append(dev, aml_name_decl("_HID", aml_string("LOON0001"))); > + aml_append(dev, aml_name_decl("_UID", aml_int(0))); > + > + Aml *crs = aml_resource_template(); > + aml_append(crs, > + aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED, > + AML_NON_CACHEABLE, AML_READ_WRITE, > + 0, VIRT_RTC_REG_BASE, > + VIRT_RTC_REG_BASE + VIRT_RTC_LEN - 1, > + 0, VIRT_RTC_LEN)); > + aml_append(crs, > + aml_interrupt(AML_CONSUMER, AML_EDGE, AML_ACTIVE_HIGH, > + AML_EXCLUSIVE, &rtc_irq, 1)); > + > + aml_append(dev, aml_name_decl("_CRS", crs)); > + aml_append(scope, dev); > +} > + > /* build DSDT */ > static void > build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine) > @@ -488,6 +511,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine) > for (i = 0; i < VIRT_UART_COUNT; i++) { > build_uart_device_aml(dsdt, i); > } > + acpi_dsdt_add_rtc(dsdt); > build_pci_device_aml(dsdt, lvms); > build_la_ged_aml(dsdt, machine); > build_flash_aml(dsdt, lvms); > Otherwise looks good to me except comments alignment. Reviewed-by: Bibo Mao <maobibo@loongson.cn> ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH V1 2/2] hw/loongarch: add rtc acpi table 2025-06-13 1:31 ` [PATCH V1 2/2] hw/loongarch: add rtc acpi table Xianglai Li 2025-06-13 2:48 ` Bibo Mao @ 2025-06-13 4:47 ` Bibo Mao 1 sibling, 0 replies; 9+ messages in thread From: Bibo Mao @ 2025-06-13 4:47 UTC (permalink / raw) To: Xianglai Li, qemu-devel; +Cc: Song Gao, Jiaxun Yang On 2025/6/13 上午9:31, Xianglai Li wrote: > Add the acpi table to the loongson rtc hardware > so that the virtual machine kernel can use the > loongson RTC-related drivers. > > Signed-off-by: Xianglai Li <lixianglai@loongson.cn> > --- > Cc: Bibo Mao <maobibo@loongson.cn> > Cc: Song Gao <gaosong@loongson.cn> > Cc: Jiaxun Yang <jiaxun.yang@flygoat.com> > Cc: Xianglai Li <lixianglai@loongson.cn> > > hw/loongarch/virt-acpi-build.c | 24 ++++++++++++++++++++++++ > 1 file changed, 24 insertions(+) > > diff --git a/hw/loongarch/virt-acpi-build.c b/hw/loongarch/virt-acpi-build.c > index 2cd2d9d842..2cfc5421c5 100644 > --- a/hw/loongarch/virt-acpi-build.c > +++ b/hw/loongarch/virt-acpi-build.c > @@ -473,6 +473,29 @@ static void acpi_dsdt_add_tpm(Aml *scope, LoongArchVirtMachineState *vms) > } > #endif > > +static void acpi_dsdt_add_rtc(Aml *scope) > +{ > + uint32_t rtc_irq = VIRT_RTC_IRQ; > + Aml *dev = aml_device("RTC"); > + > + aml_append(dev, aml_name_decl("_HID", aml_string("LOON0001"))); > + aml_append(dev, aml_name_decl("_UID", aml_int(0))); > + > + Aml *crs = aml_resource_template(); > + aml_append(crs, > + aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED, > + AML_NON_CACHEABLE, AML_READ_WRITE, > + 0, VIRT_RTC_REG_BASE, > + VIRT_RTC_REG_BASE + VIRT_RTC_LEN - 1, > + 0, VIRT_RTC_LEN)); > + aml_append(crs, > + aml_interrupt(AML_CONSUMER, AML_EDGE, AML_ACTIVE_HIGH, > + AML_EXCLUSIVE, &rtc_irq, 1)); > + > + aml_append(dev, aml_name_decl("_CRS", crs)); > + aml_append(scope, dev); > +} > + The rtc loongson driver drivers/rtc/rtc-loongson.c is bond with acpi pm1 device since rtc device is wake-up source on physical machine, however acpi ged device rather than pm1 device is used on virt machine. I think firstly we should submit patch to rtc loongson driver drivers/rtc/rtc-loongson.c so that it supports non acpi pm1 device, then submit rtc acpi dsdt table. Regards Bibo Mao > /* build DSDT */ > static void > build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine) > @@ -488,6 +511,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine) > for (i = 0; i < VIRT_UART_COUNT; i++) { > build_uart_device_aml(dsdt, i); > } > + acpi_dsdt_add_rtc(dsdt); > build_pci_device_aml(dsdt, lvms); > build_la_ged_aml(dsdt, machine); > build_flash_aml(dsdt, lvms); > ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2025-07-07 7:20 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-06-13 1:31 [PATCH V1 0/2] Fix the rtc issue on loongarch Xianglai Li 2025-06-13 1:31 ` [PATCH V1 1/2] hw/rtc: Fixed loongson rtc emulation errors Xianglai Li 2025-06-13 2:54 ` Bibo Mao 2025-06-13 4:43 ` Bibo Mao 2025-07-07 6:36 ` lixianglai 2025-07-07 7:17 ` Bibo Mao 2025-06-13 1:31 ` [PATCH V1 2/2] hw/loongarch: add rtc acpi table Xianglai Li 2025-06-13 2:48 ` Bibo Mao 2025-06-13 4:47 ` Bibo Mao
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).