[PATCH] hw/mips/loongson3_virt: Emulate suspend function

Jiaxun Yang posted 1 patch 6 months, 2 weeks ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20240508-loongson3v-suspend-v1-1-186725524a39@flygoat.com
Maintainers: Huacai Chen <chenhuacai@kernel.org>, Jiaxun Yang <jiaxun.yang@flygoat.com>, "Philippe Mathieu-Daudé" <philmd@linaro.org>
hw/mips/loongson3_bootp.c |  1 +
hw/mips/loongson3_virt.c  | 19 +++++++++++++++++++
2 files changed, 20 insertions(+)
[PATCH] hw/mips/loongson3_virt: Emulate suspend function
Posted by Jiaxun Yang 6 months, 2 weeks ago
Suspend function is emulated as what hardware actually do.
Doorbell register fields are updates to include suspend value,
suspend vector is encoded in firmware blob and fw_cfg is updated
to include S3 bits as what x86 did.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
 hw/mips/loongson3_bootp.c |  1 +
 hw/mips/loongson3_virt.c  | 19 +++++++++++++++++++
 2 files changed, 20 insertions(+)

diff --git a/hw/mips/loongson3_bootp.c b/hw/mips/loongson3_bootp.c
index f99af229327a..03a10b63c1b4 100644
--- a/hw/mips/loongson3_bootp.c
+++ b/hw/mips/loongson3_bootp.c
@@ -148,4 +148,5 @@ void init_reset_system(struct efi_reset_system_t *reset)
     reset->Shutdown = cpu_to_le64(0xffffffffbfc000a8);
     reset->ResetCold = cpu_to_le64(0xffffffffbfc00080);
     reset->ResetWarm = cpu_to_le64(0xffffffffbfc00080);
+    reset->DoSuspend = cpu_to_le64(0xffffffffbfc000d0);
 }
diff --git a/hw/mips/loongson3_virt.c b/hw/mips/loongson3_virt.c
index 33eae01eca2b..f06518ad8f54 100644
--- a/hw/mips/loongson3_virt.c
+++ b/hw/mips/loongson3_virt.c
@@ -127,6 +127,9 @@ static void loongson3_pm_write(void *opaque, hwaddr addr,
     case 0x00:
         qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
         return;
+    case 0x01:
+        qemu_system_suspend_request();
+        return;
     case 0xff:
         qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
         return;
@@ -250,6 +253,17 @@ static void init_boot_rom(void)
         0x240D00FF,   /* li      t1, 0xff                                     */
         0xA18D0000,   /* sb      t1, (t0)                                     */
         0x1000FFFF,   /* 1:  b   1b                                           */
+        0x00000000,   /* nop                                                  */
+                      /* Suspend                                              */
+        0x3C0C9000,   /* dli     t0, 0x9000000010080010                       */
+        0x358C0000,
+        0x000C6438,
+        0x358C1008,
+        0x000C6438,
+        0x358C0010,
+        0x240D0001,   /* li      t1, 0x01                                     */
+        0xA18D0000,   /* sb      t1, (t0)                                     */
+        0x03e00008,   /* jr      ra                                           */
         0x00000000    /* nop                                                  */
     };
 
@@ -274,6 +288,10 @@ static void fw_conf_init(unsigned long ram_size)
     fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
     fw_cfg_add_i32(fw_cfg, FW_CFG_MACHINE_VERSION, 1);
     fw_cfg_add_i64(fw_cfg, FW_CFG_CPU_FREQ, get_cpu_freq_hz());
+
+    uint8_t suspend[6] = {128, 0, 0, 129, 128, 128};
+    fw_cfg_add_file(fw_cfg, "etc/system-states", g_memdup(suspend, 6), 6);
+
     qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
 }
 
@@ -551,6 +569,7 @@ static void mips_loongson3_virt_init(MachineState *machine)
                            machine->ram, 0, virt_memmap[VIRT_LOWMEM].size);
     memory_region_init_io(iomem, NULL, &loongson3_pm_ops,
                            NULL, "loongson3_pm", virt_memmap[VIRT_PM].size);
+    qemu_register_wakeup_support();
 
     memory_region_add_subregion(address_space_mem,
                       virt_memmap[VIRT_LOWMEM].base, ram);

---
base-commit: d762bf97931b58839316b68a570eecc6143c9e3e
change-id: 20240508-loongson3v-suspend-cdd33a169eab

Best regards,
-- 
Jiaxun Yang <jiaxun.yang@flygoat.com>
Re: [PATCH] hw/mips/loongson3_virt: Emulate suspend function
Posted by Philippe Mathieu-Daudé 6 months, 2 weeks ago
On 8/5/24 11:31, Jiaxun Yang wrote:
> Suspend function is emulated as what hardware actually do.
> Doorbell register fields are updates to include suspend value,
> suspend vector is encoded in firmware blob and fw_cfg is updated
> to include S3 bits as what x86 did.
> 
> Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> ---
>   hw/mips/loongson3_bootp.c |  1 +
>   hw/mips/loongson3_virt.c  | 19 +++++++++++++++++++
>   2 files changed, 20 insertions(+)

Thanks, patch queued.
Re: [PATCH] hw/mips/loongson3_virt: Emulate suspend function
Posted by Philippe Mathieu-Daudé 6 months, 2 weeks ago
On 8/5/24 17:35, Philippe Mathieu-Daudé wrote:
> On 8/5/24 11:31, Jiaxun Yang wrote:
>> Suspend function is emulated as what hardware actually do.
>> Doorbell register fields are updates to include suspend value,
>> suspend vector is encoded in firmware blob and fw_cfg is updated
>> to include S3 bits as what x86 did.
>>
>> Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
>> ---
>>   hw/mips/loongson3_bootp.c |  1 +
>>   hw/mips/loongson3_virt.c  | 19 +++++++++++++++++++
>>   2 files changed, 20 insertions(+)
> 
> Thanks, patch queued.

Fixed:

ERROR: use g_memdup2() instead of unsafe g_memdup()
#76: FILE: hw/mips/loongson3_virt.c:293:
+    fw_cfg_add_file(fw_cfg, "etc/system-states", g_memdup(suspend, 6), 6);

Re: [PATCH] hw/mips/loongson3_virt: Emulate suspend function
Posted by Jiaxun Yang 6 months, 2 weeks ago

在2024年5月8日五月 下午5:48,Philippe Mathieu-Daudé写道:
> On 8/5/24 17:35, Philippe Mathieu-Daudé wrote:
>> On 8/5/24 11:31, Jiaxun Yang wrote:
>>> Suspend function is emulated as what hardware actually do.
>>> Doorbell register fields are updates to include suspend value,
>>> suspend vector is encoded in firmware blob and fw_cfg is updated
>>> to include S3 bits as what x86 did.
>>>
>>> Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
>>> ---
>>>   hw/mips/loongson3_bootp.c |  1 +
>>>   hw/mips/loongson3_virt.c  | 19 +++++++++++++++++++
>>>   2 files changed, 20 insertions(+)
>> 
>> Thanks, patch queued.
>
> Fixed:
>
> ERROR: use g_memdup2() instead of unsafe g_memdup()
> #76: FILE: hw/mips/loongson3_virt.c:293:
> +    fw_cfg_add_file(fw_cfg, "etc/system-states", g_memdup(suspend, 6), 6);

Thanks, I omitted this one as it is copied from hw/acpi/core.c

Should we fix that one as well?

-- 
- Jiaxun
Re: [PATCH] hw/mips/loongson3_virt: Emulate suspend function
Posted by Philippe Mathieu-Daudé 6 months, 2 weeks ago
On 8/5/24 19:28, Jiaxun Yang wrote:
> 在2024年5月8日五月 下午5:48,Philippe Mathieu-Daudé写道:
>> On 8/5/24 17:35, Philippe Mathieu-Daudé wrote:
>>> On 8/5/24 11:31, Jiaxun Yang wrote:
>>>> Suspend function is emulated as what hardware actually do.
>>>> Doorbell register fields are updates to include suspend value,
>>>> suspend vector is encoded in firmware blob and fw_cfg is updated
>>>> to include S3 bits as what x86 did.
>>>>
>>>> Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
>>>> ---
>>>>    hw/mips/loongson3_bootp.c |  1 +
>>>>    hw/mips/loongson3_virt.c  | 19 +++++++++++++++++++
>>>>    2 files changed, 20 insertions(+)
>>>
>>> Thanks, patch queued.
>>
>> Fixed:
>>
>> ERROR: use g_memdup2() instead of unsafe g_memdup()
>> #76: FILE: hw/mips/loongson3_virt.c:293:
>> +    fw_cfg_add_file(fw_cfg, "etc/system-states", g_memdup(suspend, 6), 6);
> 
> Thanks, I omitted this one as it is copied from hw/acpi/core.c
> 
> Should we fix that one as well?

Sadly for me I did the cleanup 3 years ago:
https://lore.kernel.org/qemu-devel/20210903110702.588291-10-philmd@redhat.com/
but neglected to address the comment from Eric:
https://lore.kernel.org/qemu-devel/20210903211057.kvn6r5pvx7iuwf5a@redhat.com/
so the patch never got merged. I might revisit...

Re: [PATCH] hw/mips/loongson3_virt: Emulate suspend function
Posted by Philippe Mathieu-Daudé 6 months, 2 weeks ago
On 8/5/24 23:54, Philippe Mathieu-Daudé wrote:
> On 8/5/24 19:28, Jiaxun Yang wrote:
>> 在2024年5月8日五月 下午5:48,Philippe Mathieu-Daudé写道:
>>> On 8/5/24 17:35, Philippe Mathieu-Daudé wrote:
>>>> On 8/5/24 11:31, Jiaxun Yang wrote:
>>>>> Suspend function is emulated as what hardware actually do.
>>>>> Doorbell register fields are updates to include suspend value,
>>>>> suspend vector is encoded in firmware blob and fw_cfg is updated
>>>>> to include S3 bits as what x86 did.
>>>>>
>>>>> Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
>>>>> ---
>>>>>    hw/mips/loongson3_bootp.c |  1 +
>>>>>    hw/mips/loongson3_virt.c  | 19 +++++++++++++++++++
>>>>>    2 files changed, 20 insertions(+)
>>>>
>>>> Thanks, patch queued.
>>>
>>> Fixed:
>>>
>>> ERROR: use g_memdup2() instead of unsafe g_memdup()
>>> #76: FILE: hw/mips/loongson3_virt.c:293:
>>> +    fw_cfg_add_file(fw_cfg, "etc/system-states", g_memdup(suspend, 
>>> 6), 6);
>>
>> Thanks, I omitted this one as it is copied from hw/acpi/core.c
>>
>> Should we fix that one as well?
> 
> Sadly for me I did the cleanup 3 years ago:
> https://lore.kernel.org/qemu-devel/20210903110702.588291-10-philmd@redhat.com/
> but neglected to address the comment from Eric:
> https://lore.kernel.org/qemu-devel/20210903211057.kvn6r5pvx7iuwf5a@redhat.com/
> so the patch never got merged. I might revisit...

That said it is recommended to run checkpatch.pl before posting a patch:
https://www.qemu.org/docs/master/devel/submitting-a-patch.html#use-the-qemu-coding-style
This can be automatized, see "Automate a checkpatch run on commit" in
this chapter :)