mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-07 01:33:56 -06:00
hw/mips/loongson3_virt: Emulate suspend function
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> Message-ID: <20240508-loongson3v-suspend-v1-1-186725524a39@flygoat.com> [PMD: Use g_memdup2(), constify suspend array] Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
This commit is contained in:
parent
d804ad98f5
commit
5b1a3b9f8c
2 changed files with 21 additions and 0 deletions
|
@ -148,4 +148,5 @@ void init_reset_system(struct efi_reset_system_t *reset)
|
||||||
reset->Shutdown = cpu_to_le64(0xffffffffbfc000a8);
|
reset->Shutdown = cpu_to_le64(0xffffffffbfc000a8);
|
||||||
reset->ResetCold = cpu_to_le64(0xffffffffbfc00080);
|
reset->ResetCold = cpu_to_le64(0xffffffffbfc00080);
|
||||||
reset->ResetWarm = cpu_to_le64(0xffffffffbfc00080);
|
reset->ResetWarm = cpu_to_le64(0xffffffffbfc00080);
|
||||||
|
reset->DoSuspend = cpu_to_le64(0xffffffffbfc000d0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,6 +127,9 @@ static void loongson3_pm_write(void *opaque, hwaddr addr,
|
||||||
case 0x00:
|
case 0x00:
|
||||||
qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
|
qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
|
||||||
return;
|
return;
|
||||||
|
case 0x01:
|
||||||
|
qemu_system_suspend_request();
|
||||||
|
return;
|
||||||
case 0xff:
|
case 0xff:
|
||||||
qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
|
qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
|
||||||
return;
|
return;
|
||||||
|
@ -250,6 +253,17 @@ static void init_boot_rom(void)
|
||||||
0x240D00FF, /* li t1, 0xff */
|
0x240D00FF, /* li t1, 0xff */
|
||||||
0xA18D0000, /* sb t1, (t0) */
|
0xA18D0000, /* sb t1, (t0) */
|
||||||
0x1000FFFF, /* 1: b 1b */
|
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 */
|
0x00000000 /* nop */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -265,6 +279,7 @@ static void fw_cfg_boot_set(void *opaque, const char *boot_device,
|
||||||
|
|
||||||
static void fw_conf_init(unsigned long ram_size)
|
static void fw_conf_init(unsigned long ram_size)
|
||||||
{
|
{
|
||||||
|
static const uint8_t suspend[6] = {128, 0, 0, 129, 128, 128};
|
||||||
FWCfgState *fw_cfg;
|
FWCfgState *fw_cfg;
|
||||||
hwaddr cfg_addr = virt_memmap[VIRT_FW_CFG].base;
|
hwaddr cfg_addr = virt_memmap[VIRT_FW_CFG].base;
|
||||||
|
|
||||||
|
@ -274,6 +289,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_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_i32(fw_cfg, FW_CFG_MACHINE_VERSION, 1);
|
||||||
fw_cfg_add_i64(fw_cfg, FW_CFG_CPU_FREQ, get_cpu_freq_hz());
|
fw_cfg_add_i64(fw_cfg, FW_CFG_CPU_FREQ, get_cpu_freq_hz());
|
||||||
|
|
||||||
|
fw_cfg_add_file(fw_cfg, "etc/system-states",
|
||||||
|
g_memdup2(suspend, sizeof(suspend)), sizeof(suspend));
|
||||||
|
|
||||||
qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
|
qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -553,6 +572,7 @@ static void mips_loongson3_virt_init(MachineState *machine)
|
||||||
machine->ram, 0, virt_memmap[VIRT_LOWMEM].size);
|
machine->ram, 0, virt_memmap[VIRT_LOWMEM].size);
|
||||||
memory_region_init_io(iomem, NULL, &loongson3_pm_ops,
|
memory_region_init_io(iomem, NULL, &loongson3_pm_ops,
|
||||||
NULL, "loongson3_pm", virt_memmap[VIRT_PM].size);
|
NULL, "loongson3_pm", virt_memmap[VIRT_PM].size);
|
||||||
|
qemu_register_wakeup_support();
|
||||||
|
|
||||||
memory_region_add_subregion(address_space_mem,
|
memory_region_add_subregion(address_space_mem,
|
||||||
virt_memmap[VIRT_LOWMEM].base, ram);
|
virt_memmap[VIRT_LOWMEM].base, ram);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue