Signed-off-by: Song Gao <gaosong@loongson.cn>
Message-Id: <20240301093839.663947-4-gaosong@loongson.cn>
---
hw/loongarch/boot.c | 70 ++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 69 insertions(+), 1 deletion(-)
diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
index 149deb2e01..e560ac178a 100644
--- a/hw/loongarch/boot.c
+++ b/hw/loongarch/boot.c
@@ -15,6 +15,54 @@
#include "sysemu/reset.h"
#include "sysemu/qtest.h"
+static const unsigned int slave_boot_code[] = {
+ /* Configure reset ebase. */
+ 0x0400302c, /* csrwr $r12,0xc */
+
+ /* Disable interrupt. */
+ 0x0380100c, /* ori $r12,$r0,0x4 */
+ 0x04000180, /* csrxchg $r0,$r12,0x0 */
+
+ /* Clear mailbox. */
+ 0x1400002d, /* lu12i.w $r13,1(0x1) */
+ 0x038081ad, /* ori $r13,$r13,0x20 */
+ 0x06481da0, /* iocsrwr.d $r0,$r13 */
+
+ /* Enable IPI interrupt. */
+ 0x1400002c, /* lu12i.w $r12,1(0x1) */
+ 0x0400118c, /* csrxchg $r12,$r12,0x4 */
+ 0x02fffc0c, /* addi.d $r12,$r0,-1(0xfff) */
+ 0x1400002d, /* lu12i.w $r13,1(0x1) */
+ 0x038011ad, /* ori $r13,$r13,0x4 */
+ 0x064819ac, /* iocsrwr.w $r12,$r13 */
+ 0x1400002d, /* lu12i.w $r13,1(0x1) */
+ 0x038081ad, /* ori $r13,$r13,0x20 */
+
+ /* Wait for wakeup <.L11>: */
+ 0x06488000, /* idle 0x0 */
+ 0x03400000, /* andi $r0,$r0,0x0 */
+ 0x064809ac, /* iocsrrd.w $r12,$r13 */
+ 0x43fff59f, /* beqz $r12,-12(0x7ffff4) # 48 <.L11> */
+
+ /* Read and clear IPI interrupt. */
+ 0x1400002d, /* lu12i.w $r13,1(0x1) */
+ 0x064809ac, /* iocsrrd.w $r12,$r13 */
+ 0x1400002d, /* lu12i.w $r13,1(0x1) */
+ 0x038031ad, /* ori $r13,$r13,0xc */
+ 0x064819ac, /* iocsrwr.w $r12,$r13 */
+
+ /* Disable IPI interrupt. */
+ 0x1400002c, /* lu12i.w $r12,1(0x1) */
+ 0x04001180, /* csrxchg $r0,$r12,0x4 */
+
+ /* Read mail buf and jump to specified entry */
+ 0x1400002d, /* lu12i.w $r13,1(0x1) */
+ 0x038081ad, /* ori $r13,$r13,0x20 */
+ 0x06480dac, /* iocsrrd.d $r12,$r13 */
+ 0x00150181, /* move $r1,$r12 */
+ 0x4c000020, /* jirl $r0,$r1,0 */
+};
+
static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr)
{
return addr & MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS);
@@ -111,8 +159,15 @@ static void loongarch_firmware_boot(LoongArchMachineState *lams,
fw_cfg_add_kernel_info(info, lams->fw_cfg);
}
+static void init_boot_rom(struct loongarch_boot_info *info, void *p)
+{
+ memcpy(p, &slave_boot_code, sizeof(slave_boot_code));
+ p += sizeof(slave_boot_code);
+}
+
static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info)
{
+ void *p, *bp;
int64_t kernel_addr = 0;
LoongArchCPU *lacpu;
CPUState *cs;
@@ -126,11 +181,24 @@ static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info)
}
}
+ /* Load 'boot_rom' at [0 - 1MiB] */
+ p = g_malloc0(1 * MiB);
+ bp = p;
+ init_boot_rom(info, p);
+ rom_add_blob_fixed("boot_rom", bp, 1 * MiB, 0);
+
CPU_FOREACH(cs) {
lacpu = LOONGARCH_CPU(cs);
lacpu->env.load_elf = true;
- lacpu->env.elf_address = kernel_addr;
+ if (cs == first_cpu) {
+ lacpu->env.elf_address = kernel_addr;
+ } else {
+ lacpu->env.elf_address = 0;
+ }
+ lacpu->env.boot_info = info;
}
+
+ g_free(bp);
}
void loongarch_load_kernel(MachineState *ms, struct loongarch_boot_info *info)
--
2.34.1
Song,
On Fri, Mar 8, 2024 at 12:51 AM Song Gao <gaosong@loongson.cn> wrote:
>
> Signed-off-by: Song Gao <gaosong@loongson.cn>
> Message-Id: <20240301093839.663947-4-gaosong@loongson.cn>
> ---
> hw/loongarch/boot.c | 70 ++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 69 insertions(+), 1 deletion(-)
>
> diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
> index 149deb2e01..e560ac178a 100644
> --- a/hw/loongarch/boot.c
> +++ b/hw/loongarch/boot.c
> @@ -15,6 +15,54 @@
> #include "sysemu/reset.h"
> #include "sysemu/qtest.h"
>
> +static const unsigned int slave_boot_code[] = {
> + /* Configure reset ebase. */
> + 0x0400302c, /* csrwr $r12,0xc */
Use reg-names may be a little better than reg-nums.
Huacai
> +
> + /* Disable interrupt. */
> + 0x0380100c, /* ori $r12,$r0,0x4 */
> + 0x04000180, /* csrxchg $r0,$r12,0x0 */
> +
> + /* Clear mailbox. */
> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
> + 0x038081ad, /* ori $r13,$r13,0x20 */
> + 0x06481da0, /* iocsrwr.d $r0,$r13 */
> +
> + /* Enable IPI interrupt. */
> + 0x1400002c, /* lu12i.w $r12,1(0x1) */
> + 0x0400118c, /* csrxchg $r12,$r12,0x4 */
> + 0x02fffc0c, /* addi.d $r12,$r0,-1(0xfff) */
> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
> + 0x038011ad, /* ori $r13,$r13,0x4 */
> + 0x064819ac, /* iocsrwr.w $r12,$r13 */
> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
> + 0x038081ad, /* ori $r13,$r13,0x20 */
> +
> + /* Wait for wakeup <.L11>: */
> + 0x06488000, /* idle 0x0 */
> + 0x03400000, /* andi $r0,$r0,0x0 */
> + 0x064809ac, /* iocsrrd.w $r12,$r13 */
> + 0x43fff59f, /* beqz $r12,-12(0x7ffff4) # 48 <.L11> */
> +
> + /* Read and clear IPI interrupt. */
> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
> + 0x064809ac, /* iocsrrd.w $r12,$r13 */
> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
> + 0x038031ad, /* ori $r13,$r13,0xc */
> + 0x064819ac, /* iocsrwr.w $r12,$r13 */
> +
> + /* Disable IPI interrupt. */
> + 0x1400002c, /* lu12i.w $r12,1(0x1) */
> + 0x04001180, /* csrxchg $r0,$r12,0x4 */
> +
> + /* Read mail buf and jump to specified entry */
> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
> + 0x038081ad, /* ori $r13,$r13,0x20 */
> + 0x06480dac, /* iocsrrd.d $r12,$r13 */
> + 0x00150181, /* move $r1,$r12 */
> + 0x4c000020, /* jirl $r0,$r1,0 */
> +};
> +
> static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr)
> {
> return addr & MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS);
> @@ -111,8 +159,15 @@ static void loongarch_firmware_boot(LoongArchMachineState *lams,
> fw_cfg_add_kernel_info(info, lams->fw_cfg);
> }
>
> +static void init_boot_rom(struct loongarch_boot_info *info, void *p)
> +{
> + memcpy(p, &slave_boot_code, sizeof(slave_boot_code));
> + p += sizeof(slave_boot_code);
> +}
> +
> static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info)
> {
> + void *p, *bp;
> int64_t kernel_addr = 0;
> LoongArchCPU *lacpu;
> CPUState *cs;
> @@ -126,11 +181,24 @@ static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info)
> }
> }
>
> + /* Load 'boot_rom' at [0 - 1MiB] */
> + p = g_malloc0(1 * MiB);
> + bp = p;
> + init_boot_rom(info, p);
> + rom_add_blob_fixed("boot_rom", bp, 1 * MiB, 0);
> +
> CPU_FOREACH(cs) {
> lacpu = LOONGARCH_CPU(cs);
> lacpu->env.load_elf = true;
> - lacpu->env.elf_address = kernel_addr;
> + if (cs == first_cpu) {
> + lacpu->env.elf_address = kernel_addr;
> + } else {
> + lacpu->env.elf_address = 0;
> + }
> + lacpu->env.boot_info = info;
> }
> +
> + g_free(bp);
> }
>
> void loongarch_load_kernel(MachineState *ms, struct loongarch_boot_info *info)
> --
> 2.34.1
>
>
--
Huacai Chen
在 2024/3/14 10:28, chen huacai 写道:
> Song,
>
> On Fri, Mar 8, 2024 at 12:51 AM Song Gao <gaosong@loongson.cn> wrote:
>>
>> Signed-off-by: Song Gao <gaosong@loongson.cn>
>> Message-Id: <20240301093839.663947-4-gaosong@loongson.cn>
>> ---
>> hw/loongarch/boot.c | 70 ++++++++++++++++++++++++++++++++++++++++++++-
>> 1 file changed, 69 insertions(+), 1 deletion(-)
>>
>> diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
>> index 149deb2e01..e560ac178a 100644
>> --- a/hw/loongarch/boot.c
>> +++ b/hw/loongarch/boot.c
>> @@ -15,6 +15,54 @@
>> #include "sysemu/reset.h"
>> #include "sysemu/qtest.h"
>>
>> +static const unsigned int slave_boot_code[] = {
>> + /* Configure reset ebase. */
>> + 0x0400302c, /* csrwr $r12,0xc */
> Use reg-names may be a little better than reg-nums.
>
Got it.
Thanks.
Song Gao
> Huacai
>
>> +
>> + /* Disable interrupt. */
>> + 0x0380100c, /* ori $r12,$r0,0x4 */
>> + 0x04000180, /* csrxchg $r0,$r12,0x0 */
>> +
>> + /* Clear mailbox. */
>> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
>> + 0x038081ad, /* ori $r13,$r13,0x20 */
>> + 0x06481da0, /* iocsrwr.d $r0,$r13 */
>> +
>> + /* Enable IPI interrupt. */
>> + 0x1400002c, /* lu12i.w $r12,1(0x1) */
>> + 0x0400118c, /* csrxchg $r12,$r12,0x4 */
>> + 0x02fffc0c, /* addi.d $r12,$r0,-1(0xfff) */
>> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
>> + 0x038011ad, /* ori $r13,$r13,0x4 */
>> + 0x064819ac, /* iocsrwr.w $r12,$r13 */
>> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
>> + 0x038081ad, /* ori $r13,$r13,0x20 */
>> +
>> + /* Wait for wakeup <.L11>: */
>> + 0x06488000, /* idle 0x0 */
>> + 0x03400000, /* andi $r0,$r0,0x0 */
>> + 0x064809ac, /* iocsrrd.w $r12,$r13 */
>> + 0x43fff59f, /* beqz $r12,-12(0x7ffff4) # 48 <.L11> */
>> +
>> + /* Read and clear IPI interrupt. */
>> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
>> + 0x064809ac, /* iocsrrd.w $r12,$r13 */
>> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
>> + 0x038031ad, /* ori $r13,$r13,0xc */
>> + 0x064819ac, /* iocsrwr.w $r12,$r13 */
>> +
>> + /* Disable IPI interrupt. */
>> + 0x1400002c, /* lu12i.w $r12,1(0x1) */
>> + 0x04001180, /* csrxchg $r0,$r12,0x4 */
>> +
>> + /* Read mail buf and jump to specified entry */
>> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
>> + 0x038081ad, /* ori $r13,$r13,0x20 */
>> + 0x06480dac, /* iocsrrd.d $r12,$r13 */
>> + 0x00150181, /* move $r1,$r12 */
>> + 0x4c000020, /* jirl $r0,$r1,0 */
>> +};
>> +
>> static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr)
>> {
>> return addr & MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS);
>> @@ -111,8 +159,15 @@ static void loongarch_firmware_boot(LoongArchMachineState *lams,
>> fw_cfg_add_kernel_info(info, lams->fw_cfg);
>> }
>>
>> +static void init_boot_rom(struct loongarch_boot_info *info, void *p)
>> +{
>> + memcpy(p, &slave_boot_code, sizeof(slave_boot_code));
>> + p += sizeof(slave_boot_code);
>> +}
>> +
>> static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info)
>> {
>> + void *p, *bp;
>> int64_t kernel_addr = 0;
>> LoongArchCPU *lacpu;
>> CPUState *cs;
>> @@ -126,11 +181,24 @@ static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info)
>> }
>> }
>>
>> + /* Load 'boot_rom' at [0 - 1MiB] */
>> + p = g_malloc0(1 * MiB);
>> + bp = p;
>> + init_boot_rom(info, p);
>> + rom_add_blob_fixed("boot_rom", bp, 1 * MiB, 0);
>> +
>> CPU_FOREACH(cs) {
>> lacpu = LOONGARCH_CPU(cs);
>> lacpu->env.load_elf = true;
>> - lacpu->env.elf_address = kernel_addr;
>> + if (cs == first_cpu) {
>> + lacpu->env.elf_address = kernel_addr;
>> + } else {
>> + lacpu->env.elf_address = 0;
>> + }
>> + lacpu->env.boot_info = info;
>> }
>> +
>> + g_free(bp);
>> }
>>
>> void loongarch_load_kernel(MachineState *ms, struct loongarch_boot_info *info)
>> --
>> 2.34.1
>>
>>
>
>
On 2024/3/8 上午12:48, Song Gao wrote:
> Signed-off-by: Song Gao <gaosong@loongson.cn>
> Message-Id: <20240301093839.663947-4-gaosong@loongson.cn>
> ---
> hw/loongarch/boot.c | 70 ++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 69 insertions(+), 1 deletion(-)
>
> diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
> index 149deb2e01..e560ac178a 100644
> --- a/hw/loongarch/boot.c
> +++ b/hw/loongarch/boot.c
> @@ -15,6 +15,54 @@
> #include "sysemu/reset.h"
> #include "sysemu/qtest.h"
>
> +static const unsigned int slave_boot_code[] = {
> + /* Configure reset ebase. */
> + 0x0400302c, /* csrwr $r12,0xc */
> +
> + /* Disable interrupt. */
> + 0x0380100c, /* ori $r12,$r0,0x4 */
> + 0x04000180, /* csrxchg $r0,$r12,0x0 */
> +
> + /* Clear mailbox. */
> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
> + 0x038081ad, /* ori $r13,$r13,0x20 */
> + 0x06481da0, /* iocsrwr.d $r0,$r13 */
> +
> + /* Enable IPI interrupt. */
> + 0x1400002c, /* lu12i.w $r12,1(0x1) */
> + 0x0400118c, /* csrxchg $r12,$r12,0x4 */
> + 0x02fffc0c, /* addi.d $r12,$r0,-1(0xfff) */
> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
> + 0x038011ad, /* ori $r13,$r13,0x4 */
> + 0x064819ac, /* iocsrwr.w $r12,$r13 */
> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
> + 0x038081ad, /* ori $r13,$r13,0x20 */
> +
> + /* Wait for wakeup <.L11>: */
> + 0x06488000, /* idle 0x0 */
> + 0x03400000, /* andi $r0,$r0,0x0 */
> + 0x064809ac, /* iocsrrd.w $r12,$r13 */
> + 0x43fff59f, /* beqz $r12,-12(0x7ffff4) # 48 <.L11> */
> +
> + /* Read and clear IPI interrupt. */
> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
> + 0x064809ac, /* iocsrrd.w $r12,$r13 */
> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
> + 0x038031ad, /* ori $r13,$r13,0xc */
> + 0x064819ac, /* iocsrwr.w $r12,$r13 */
> +
> + /* Disable IPI interrupt. */
> + 0x1400002c, /* lu12i.w $r12,1(0x1) */
> + 0x04001180, /* csrxchg $r0,$r12,0x4 */
> +
> + /* Read mail buf and jump to specified entry */
> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
> + 0x038081ad, /* ori $r13,$r13,0x20 */
> + 0x06480dac, /* iocsrrd.d $r12,$r13 */
> + 0x00150181, /* move $r1,$r12 */
> + 0x4c000020, /* jirl $r0,$r1,0 */
> +};
> +
> static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr)
> {
> return addr & MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS);
> @@ -111,8 +159,15 @@ static void loongarch_firmware_boot(LoongArchMachineState *lams,
> fw_cfg_add_kernel_info(info, lams->fw_cfg);
> }
>
> +static void init_boot_rom(struct loongarch_boot_info *info, void *p)
> +{
> + memcpy(p, &slave_boot_code, sizeof(slave_boot_code));
> + p += sizeof(slave_boot_code);
> +}
> +
> static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info)
> {
> + void *p, *bp;
> int64_t kernel_addr = 0;
> LoongArchCPU *lacpu;
> CPUState *cs;
> @@ -126,11 +181,24 @@ static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info)
> }
> }
>
> + /* Load 'boot_rom' at [0 - 1MiB] */
> + p = g_malloc0(1 * MiB);
> + bp = p;
> + init_boot_rom(info, p);
> + rom_add_blob_fixed("boot_rom", bp, 1 * MiB, 0);
> +
The secondary cpu waiting on the bootrom located memory address
0x0-0x100000.
Is it possible that primary cpu clears the memory located at bootrom
and then wakeup the secondary cpu?
Regards
Bibo Mao
> CPU_FOREACH(cs) {
> lacpu = LOONGARCH_CPU(cs);
> lacpu->env.load_elf = true;
> - lacpu->env.elf_address = kernel_addr;
> + if (cs == first_cpu) {
> + lacpu->env.elf_address = kernel_addr;
> + } else {
> + lacpu->env.elf_address = 0;
> + }
> + lacpu->env.boot_info = info;
> }
> +
> + g_free(bp);
> }
>
> void loongarch_load_kernel(MachineState *ms, struct loongarch_boot_info *info)
>
在 2024/3/8 16:27, maobibo 写道:
>
>
> On 2024/3/8 上午12:48, Song Gao wrote:
>> Signed-off-by: Song Gao <gaosong@loongson.cn>
>> Message-Id: <20240301093839.663947-4-gaosong@loongson.cn>
>> ---
>> hw/loongarch/boot.c | 70 ++++++++++++++++++++++++++++++++++++++++++++-
>> 1 file changed, 69 insertions(+), 1 deletion(-)
>>
>> diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
>> index 149deb2e01..e560ac178a 100644
>> --- a/hw/loongarch/boot.c
>> +++ b/hw/loongarch/boot.c
>> @@ -15,6 +15,54 @@
>> #include "sysemu/reset.h"
>> #include "sysemu/qtest.h"
>> +static const unsigned int slave_boot_code[] = {
>> + /* Configure reset ebase. */
>> + 0x0400302c, /* csrwr $r12,0xc */
>> +
>> + /* Disable interrupt. */
>> + 0x0380100c, /* ori $r12,$r0,0x4 */
>> + 0x04000180, /* csrxchg $r0,$r12,0x0 */
>> +
>> + /* Clear mailbox. */
>> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
>> + 0x038081ad, /* ori $r13,$r13,0x20 */
>> + 0x06481da0, /* iocsrwr.d $r0,$r13 */
>> +
>> + /* Enable IPI interrupt. */
>> + 0x1400002c, /* lu12i.w $r12,1(0x1) */
>> + 0x0400118c, /* csrxchg $r12,$r12,0x4 */
>> + 0x02fffc0c, /* addi.d $r12,$r0,-1(0xfff) */
>> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
>> + 0x038011ad, /* ori $r13,$r13,0x4 */
>> + 0x064819ac, /* iocsrwr.w $r12,$r13 */
>> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
>> + 0x038081ad, /* ori $r13,$r13,0x20 */
>> +
>> + /* Wait for wakeup <.L11>: */
>> + 0x06488000, /* idle 0x0 */
>> + 0x03400000, /* andi $r0,$r0,0x0 */
>> + 0x064809ac, /* iocsrrd.w $r12,$r13 */
>> + 0x43fff59f, /* beqz $r12,-12(0x7ffff4) # 48 <.L11> */
>> +
>> + /* Read and clear IPI interrupt. */
>> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
>> + 0x064809ac, /* iocsrrd.w $r12,$r13 */
>> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
>> + 0x038031ad, /* ori $r13,$r13,0xc */
>> + 0x064819ac, /* iocsrwr.w $r12,$r13 */
>> +
>> + /* Disable IPI interrupt. */
>> + 0x1400002c, /* lu12i.w $r12,1(0x1) */
>> + 0x04001180, /* csrxchg $r0,$r12,0x4 */
>> +
>> + /* Read mail buf and jump to specified entry */
>> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
>> + 0x038081ad, /* ori $r13,$r13,0x20 */
>> + 0x06480dac, /* iocsrrd.d $r12,$r13 */
>> + 0x00150181, /* move $r1,$r12 */
>> + 0x4c000020, /* jirl $r0,$r1,0 */
>> +};
>> +
>> static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr)
>> {
>> return addr & MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS);
>> @@ -111,8 +159,15 @@ static void
>> loongarch_firmware_boot(LoongArchMachineState *lams,
>> fw_cfg_add_kernel_info(info, lams->fw_cfg);
>> }
>> +static void init_boot_rom(struct loongarch_boot_info *info, void *p)
>> +{
>> + memcpy(p, &slave_boot_code, sizeof(slave_boot_code));
>> + p += sizeof(slave_boot_code);
>> +}
>> +
>> static void loongarch_direct_kernel_boot(struct loongarch_boot_info
>> *info)
>> {
>> + void *p, *bp;
>> int64_t kernel_addr = 0;
>> LoongArchCPU *lacpu;
>> CPUState *cs;
>> @@ -126,11 +181,24 @@ static void loongarch_direct_kernel_boot(struct
>> loongarch_boot_info *info)
>> }
>> }
>> + /* Load 'boot_rom' at [0 - 1MiB] */
>> + p = g_malloc0(1 * MiB);
>> + bp = p;
>> + init_boot_rom(info, p);
>> + rom_add_blob_fixed("boot_rom", bp, 1 * MiB, 0);
>> +
> The secondary cpu waiting on the bootrom located memory address
> 0x0-0x100000.
>
> Is it possible that primary cpu clears the memory located at bootrom
> and then wakeup the secondary cpu?
>
I think it impossible,0-1M is ROM。
Thanks.
Song Gao
> Regards
> Bibo Mao
>
>> CPU_FOREACH(cs) {
>> lacpu = LOONGARCH_CPU(cs);
>> lacpu->env.load_elf = true;
>> - lacpu->env.elf_address = kernel_addr;
>> + if (cs == first_cpu) {
>> + lacpu->env.elf_address = kernel_addr;
>> + } else {
>> + lacpu->env.elf_address = 0;
>> + }
>> + lacpu->env.boot_info = info;
>> }
>> +
>> + g_free(bp);
>> }
>> void loongarch_load_kernel(MachineState *ms, struct
>> loongarch_boot_info *info)
>>
On 2024/3/8 下午5:36, gaosong wrote:
>
>
> 在 2024/3/8 16:27, maobibo 写道:
>>
>>
>> On 2024/3/8 上午12:48, Song Gao wrote:
>>> Signed-off-by: Song Gao <gaosong@loongson.cn>
>>> Message-Id: <20240301093839.663947-4-gaosong@loongson.cn>
>>> ---
>>> hw/loongarch/boot.c | 70 ++++++++++++++++++++++++++++++++++++++++++++-
>>> 1 file changed, 69 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
>>> index 149deb2e01..e560ac178a 100644
>>> --- a/hw/loongarch/boot.c
>>> +++ b/hw/loongarch/boot.c
>>> @@ -15,6 +15,54 @@
>>> #include "sysemu/reset.h"
>>> #include "sysemu/qtest.h"
>>> +static const unsigned int slave_boot_code[] = {
>>> + /* Configure reset ebase. */
>>> + 0x0400302c, /* csrwr $r12,0xc */
>>> +
>>> + /* Disable interrupt. */
>>> + 0x0380100c, /* ori $r12,$r0,0x4 */
>>> + 0x04000180, /* csrxchg $r0,$r12,0x0 */
>>> +
>>> + /* Clear mailbox. */
>>> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
>>> + 0x038081ad, /* ori $r13,$r13,0x20 */
>>> + 0x06481da0, /* iocsrwr.d $r0,$r13 */
>>> +
>>> + /* Enable IPI interrupt. */
>>> + 0x1400002c, /* lu12i.w $r12,1(0x1) */
>>> + 0x0400118c, /* csrxchg $r12,$r12,0x4 */
>>> + 0x02fffc0c, /* addi.d $r12,$r0,-1(0xfff) */
>>> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
>>> + 0x038011ad, /* ori $r13,$r13,0x4 */
>>> + 0x064819ac, /* iocsrwr.w $r12,$r13 */
>>> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
>>> + 0x038081ad, /* ori $r13,$r13,0x20 */
>>> +
>>> + /* Wait for wakeup <.L11>: */
>>> + 0x06488000, /* idle 0x0 */
>>> + 0x03400000, /* andi $r0,$r0,0x0 */
>>> + 0x064809ac, /* iocsrrd.w $r12,$r13 */
>>> + 0x43fff59f, /* beqz $r12,-12(0x7ffff4) # 48 <.L11> */
>>> +
>>> + /* Read and clear IPI interrupt. */
>>> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
>>> + 0x064809ac, /* iocsrrd.w $r12,$r13 */
>>> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
>>> + 0x038031ad, /* ori $r13,$r13,0xc */
>>> + 0x064819ac, /* iocsrwr.w $r12,$r13 */
>>> +
>>> + /* Disable IPI interrupt. */
>>> + 0x1400002c, /* lu12i.w $r12,1(0x1) */
>>> + 0x04001180, /* csrxchg $r0,$r12,0x4 */
>>> +
>>> + /* Read mail buf and jump to specified entry */
>>> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
>>> + 0x038081ad, /* ori $r13,$r13,0x20 */
>>> + 0x06480dac, /* iocsrrd.d $r12,$r13 */
>>> + 0x00150181, /* move $r1,$r12 */
>>> + 0x4c000020, /* jirl $r0,$r1,0 */
>>> +};
>>> +
>>> static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t
>>> addr)
>>> {
>>> return addr & MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS);
>>> @@ -111,8 +159,15 @@ static void
>>> loongarch_firmware_boot(LoongArchMachineState *lams,
>>> fw_cfg_add_kernel_info(info, lams->fw_cfg);
>>> }
>>> +static void init_boot_rom(struct loongarch_boot_info *info, void *p)
>>> +{
>>> + memcpy(p, &slave_boot_code, sizeof(slave_boot_code));
>>> + p += sizeof(slave_boot_code);
>>> +}
>>> +
>>> static void loongarch_direct_kernel_boot(struct loongarch_boot_info
>>> *info)
>>> {
>>> + void *p, *bp;
>>> int64_t kernel_addr = 0;
>>> LoongArchCPU *lacpu;
>>> CPUState *cs;
>>> @@ -126,11 +181,24 @@ static void loongarch_direct_kernel_boot(struct
>>> loongarch_boot_info *info)
>>> }
>>> }
>>> + /* Load 'boot_rom' at [0 - 1MiB] */
>>> + p = g_malloc0(1 * MiB);
>>> + bp = p;
>>> + init_boot_rom(info, p);
>>> + rom_add_blob_fixed("boot_rom", bp, 1 * MiB, 0);
>>> +
>> The secondary cpu waiting on the bootrom located memory address
>> 0x0-0x100000.
>>
>> Is it possible that primary cpu clears the memory located at bootrom
>> and then wakeup the secondary cpu?
>>
> I think it impossible,0-1M is ROM。
I am not sure whether it is ok if area between 0-1M is ROM.
For the memory map table, low memory area (0 - 256M) is still ddr ram.
And it is passed to kernel with fdt system table, rather than
area(1-256M). Is that right?
There are some lines like this:
/* Node0 memory */
memmap_add_entry(VIRT_LOWMEM_BASE, VIRT_LOWMEM_SIZE, 1);
Regards
Bibo Mao
>
> Thanks.
> Song Gao
>> Regards
>> Bibo Mao
>>
>>> CPU_FOREACH(cs) {
>>> lacpu = LOONGARCH_CPU(cs);
>>> lacpu->env.load_elf = true;
>>> - lacpu->env.elf_address = kernel_addr;
>>> + if (cs == first_cpu) {
>>> + lacpu->env.elf_address = kernel_addr;
>>> + } else {
>>> + lacpu->env.elf_address = 0;
>>> + }
>>> + lacpu->env.boot_info = info;
>>> }
>>> +
>>> + g_free(bp);
>>> }
>>> void loongarch_load_kernel(MachineState *ms, struct
>>> loongarch_boot_info *info)
>>>
On 2024/3/11 下午2:50, maobibo wrote:
>
>
> On 2024/3/8 下午5:36, gaosong wrote:
>>
>>
>> 在 2024/3/8 16:27, maobibo 写道:
>>>
>>>
>>> On 2024/3/8 上午12:48, Song Gao wrote:
>>>> Signed-off-by: Song Gao <gaosong@loongson.cn>
>>>> Message-Id: <20240301093839.663947-4-gaosong@loongson.cn>
>>>> ---
>>>> hw/loongarch/boot.c | 70
>>>> ++++++++++++++++++++++++++++++++++++++++++++-
>>>> 1 file changed, 69 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
>>>> index 149deb2e01..e560ac178a 100644
>>>> --- a/hw/loongarch/boot.c
>>>> +++ b/hw/loongarch/boot.c
>>>> @@ -15,6 +15,54 @@
>>>> #include "sysemu/reset.h"
>>>> #include "sysemu/qtest.h"
>>>> +static const unsigned int slave_boot_code[] = {
>>>> + /* Configure reset ebase. */
>>>> + 0x0400302c, /* csrwr $r12,0xc */
>>>> +
>>>> + /* Disable interrupt. */
>>>> + 0x0380100c, /* ori $r12,$r0,0x4 */
>>>> + 0x04000180, /* csrxchg $r0,$r12,0x0 */
>>>> +
>>>> + /* Clear mailbox. */
>>>> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
>>>> + 0x038081ad, /* ori $r13,$r13,0x20 */
>>>> + 0x06481da0, /* iocsrwr.d $r0,$r13 */
>>>> +
>>>> + /* Enable IPI interrupt. */
>>>> + 0x1400002c, /* lu12i.w $r12,1(0x1) */
>>>> + 0x0400118c, /* csrxchg $r12,$r12,0x4 */
>>>> + 0x02fffc0c, /* addi.d $r12,$r0,-1(0xfff) */
>>>> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
>>>> + 0x038011ad, /* ori $r13,$r13,0x4 */
>>>> + 0x064819ac, /* iocsrwr.w $r12,$r13 */
>>>> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
>>>> + 0x038081ad, /* ori $r13,$r13,0x20 */
>>>> +
>>>> + /* Wait for wakeup <.L11>: */
>>>> + 0x06488000, /* idle 0x0 */
>>>> + 0x03400000, /* andi $r0,$r0,0x0 */
>>>> + 0x064809ac, /* iocsrrd.w $r12,$r13 */
>>>> + 0x43fff59f, /* beqz $r12,-12(0x7ffff4) # 48 <.L11> */
>>>> +
>>>> + /* Read and clear IPI interrupt. */
>>>> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
>>>> + 0x064809ac, /* iocsrrd.w $r12,$r13 */
>>>> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
>>>> + 0x038031ad, /* ori $r13,$r13,0xc */
>>>> + 0x064819ac, /* iocsrwr.w $r12,$r13 */
>>>> +
>>>> + /* Disable IPI interrupt. */
>>>> + 0x1400002c, /* lu12i.w $r12,1(0x1) */
>>>> + 0x04001180, /* csrxchg $r0,$r12,0x4 */
>>>> +
>>>> + /* Read mail buf and jump to specified entry */
>>>> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
>>>> + 0x038081ad, /* ori $r13,$r13,0x20 */
>>>> + 0x06480dac, /* iocsrrd.d $r12,$r13 */
>>>> + 0x00150181, /* move $r1,$r12 */
>>>> + 0x4c000020, /* jirl $r0,$r1,0 */
>>>> +};
>>>> +
>>>> static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t
>>>> addr)
>>>> {
>>>> return addr & MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS);
>>>> @@ -111,8 +159,15 @@ static void
>>>> loongarch_firmware_boot(LoongArchMachineState *lams,
>>>> fw_cfg_add_kernel_info(info, lams->fw_cfg);
>>>> }
>>>> +static void init_boot_rom(struct loongarch_boot_info *info, void *p)
>>>> +{
>>>> + memcpy(p, &slave_boot_code, sizeof(slave_boot_code));
>>>> + p += sizeof(slave_boot_code);
>>>> +}
>>>> +
>>>> static void loongarch_direct_kernel_boot(struct
>>>> loongarch_boot_info *info)
>>>> {
>>>> + void *p, *bp;
>>>> int64_t kernel_addr = 0;
>>>> LoongArchCPU *lacpu;
>>>> CPUState *cs;
>>>> @@ -126,11 +181,24 @@ static void
>>>> loongarch_direct_kernel_boot(struct loongarch_boot_info *info)
>>>> }
>>>> }
>>>> + /* Load 'boot_rom' at [0 - 1MiB] */
>>>> + p = g_malloc0(1 * MiB);
>>>> + bp = p;
>>>> + init_boot_rom(info, p);
>>>> + rom_add_blob_fixed("boot_rom", bp, 1 * MiB, 0);
>>>> +
>>> The secondary cpu waiting on the bootrom located memory address
>>> 0x0-0x100000.
>>>
>>> Is it possible that primary cpu clears the memory located at bootrom
>>> and then wakeup the secondary cpu?
>>>
>> I think it impossible,0-1M is ROM。
> I am not sure whether it is ok if area between 0-1M is ROM.
>
> For the memory map table, low memory area (0 - 256M) is still ddr ram.
> And it is passed to kernel with fdt system table, rather than
> area(1-256M). Is that right?
>
> There are some lines like this:
> /* Node0 memory */
> memmap_add_entry(VIRT_LOWMEM_BASE, VIRT_LOWMEM_SIZE, 1);
Song,
Can the base memory address of bootrom for secondary cpus be set as base
address of flash like bios, such as VIRT_FLASH0_BASE/VIRT_FLASH1_BASE?
And ddr memory map area is kept unchanged.
Regards
Bibo Mao
>
> Regards
> Bibo Mao
>
>>
>> Thanks.
>> Song Gao
>>> Regards
>>> Bibo Mao
>>>
>>>> CPU_FOREACH(cs) {
>>>> lacpu = LOONGARCH_CPU(cs);
>>>> lacpu->env.load_elf = true;
>>>> - lacpu->env.elf_address = kernel_addr;
>>>> + if (cs == first_cpu) {
>>>> + lacpu->env.elf_address = kernel_addr;
>>>> + } else {
>>>> + lacpu->env.elf_address = 0;
>>>> + }
>>>> + lacpu->env.boot_info = info;
>>>> }
>>>> +
>>>> + g_free(bp);
>>>> }
>>>> void loongarch_load_kernel(MachineState *ms, struct
>>>> loongarch_boot_info *info)
>>>>
>
在 2024/3/14 9:31, maobibo 写道:
>
>
> On 2024/3/11 下午2:50, maobibo wrote:
>>
>>
>> On 2024/3/8 下午5:36, gaosong wrote:
>>>
>>>
>>> 在 2024/3/8 16:27, maobibo 写道:
>>>>
>>>>
>>>> On 2024/3/8 上午12:48, Song Gao wrote:
>>>>> Signed-off-by: Song Gao <gaosong@loongson.cn>
>>>>> Message-Id: <20240301093839.663947-4-gaosong@loongson.cn>
>>>>> ---
>>>>> hw/loongarch/boot.c | 70
>>>>> ++++++++++++++++++++++++++++++++++++++++++++-
>>>>> 1 file changed, 69 insertions(+), 1 deletion(-)
>>>>>
>>>>> diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
>>>>> index 149deb2e01..e560ac178a 100644
>>>>> --- a/hw/loongarch/boot.c
>>>>> +++ b/hw/loongarch/boot.c
>>>>> @@ -15,6 +15,54 @@
>>>>> #include "sysemu/reset.h"
>>>>> #include "sysemu/qtest.h"
>>>>> +static const unsigned int slave_boot_code[] = {
>>>>> + /* Configure reset ebase. */
>>>>> + 0x0400302c, /* csrwr $r12,0xc */
>>>>> +
>>>>> + /* Disable interrupt. */
>>>>> + 0x0380100c, /* ori $r12,$r0,0x4 */
>>>>> + 0x04000180, /* csrxchg $r0,$r12,0x0 */
>>>>> +
>>>>> + /* Clear mailbox. */
>>>>> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
>>>>> + 0x038081ad, /* ori $r13,$r13,0x20 */
>>>>> + 0x06481da0, /* iocsrwr.d $r0,$r13 */
>>>>> +
>>>>> + /* Enable IPI interrupt. */
>>>>> + 0x1400002c, /* lu12i.w $r12,1(0x1) */
>>>>> + 0x0400118c, /* csrxchg $r12,$r12,0x4 */
>>>>> + 0x02fffc0c, /* addi.d $r12,$r0,-1(0xfff) */
>>>>> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
>>>>> + 0x038011ad, /* ori $r13,$r13,0x4 */
>>>>> + 0x064819ac, /* iocsrwr.w $r12,$r13 */
>>>>> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
>>>>> + 0x038081ad, /* ori $r13,$r13,0x20 */
>>>>> +
>>>>> + /* Wait for wakeup <.L11>: */
>>>>> + 0x06488000, /* idle 0x0 */
>>>>> + 0x03400000, /* andi $r0,$r0,0x0 */
>>>>> + 0x064809ac, /* iocsrrd.w $r12,$r13 */
>>>>> + 0x43fff59f, /* beqz $r12,-12(0x7ffff4) # 48 <.L11> */
>>>>> +
>>>>> + /* Read and clear IPI interrupt. */
>>>>> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
>>>>> + 0x064809ac, /* iocsrrd.w $r12,$r13 */
>>>>> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
>>>>> + 0x038031ad, /* ori $r13,$r13,0xc */
>>>>> + 0x064819ac, /* iocsrwr.w $r12,$r13 */
>>>>> +
>>>>> + /* Disable IPI interrupt. */
>>>>> + 0x1400002c, /* lu12i.w $r12,1(0x1) */
>>>>> + 0x04001180, /* csrxchg $r0,$r12,0x4 */
>>>>> +
>>>>> + /* Read mail buf and jump to specified entry */
>>>>> + 0x1400002d, /* lu12i.w $r13,1(0x1) */
>>>>> + 0x038081ad, /* ori $r13,$r13,0x20 */
>>>>> + 0x06480dac, /* iocsrrd.d $r12,$r13 */
>>>>> + 0x00150181, /* move $r1,$r12 */
>>>>> + 0x4c000020, /* jirl $r0,$r1,0 */
>>>>> +};
>>>>> +
>>>>> static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t
>>>>> addr)
>>>>> {
>>>>> return addr & MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS);
>>>>> @@ -111,8 +159,15 @@ static void
>>>>> loongarch_firmware_boot(LoongArchMachineState *lams,
>>>>> fw_cfg_add_kernel_info(info, lams->fw_cfg);
>>>>> }
>>>>> +static void init_boot_rom(struct loongarch_boot_info *info, void *p)
>>>>> +{
>>>>> + memcpy(p, &slave_boot_code, sizeof(slave_boot_code));
>>>>> + p += sizeof(slave_boot_code);
>>>>> +}
>>>>> +
>>>>> static void loongarch_direct_kernel_boot(struct
>>>>> loongarch_boot_info *info)
>>>>> {
>>>>> + void *p, *bp;
>>>>> int64_t kernel_addr = 0;
>>>>> LoongArchCPU *lacpu;
>>>>> CPUState *cs;
>>>>> @@ -126,11 +181,24 @@ static void
>>>>> loongarch_direct_kernel_boot(struct loongarch_boot_info *info)
>>>>> }
>>>>> }
>>>>> + /* Load 'boot_rom' at [0 - 1MiB] */
>>>>> + p = g_malloc0(1 * MiB);
>>>>> + bp = p;
>>>>> + init_boot_rom(info, p);
>>>>> + rom_add_blob_fixed("boot_rom", bp, 1 * MiB, 0);
>>>>> +
>>>> The secondary cpu waiting on the bootrom located memory address
>>>> 0x0-0x100000.
>>>>
>>>> Is it possible that primary cpu clears the memory located at bootrom
>>>> and then wakeup the secondary cpu?
>>>>
>>> I think it impossible,0-1M is ROM。
>> I am not sure whether it is ok if area between 0-1M is ROM.
>>
>> For the memory map table, low memory area (0 - 256M) is still ddr ram.
>> And it is passed to kernel with fdt system table, rather than
>> area(1-256M). Is that right?
>>
>> There are some lines like this:
>> /* Node0 memory */
>> memmap_add_entry(VIRT_LOWMEM_BASE, VIRT_LOWMEM_SIZE, 1);
> Song,
>
> Can the base memory address of bootrom for secondary cpus be set as base
> address of flash like bios, such as VIRT_FLASH0_BASE/VIRT_FLASH1_BASE?
> > And ddr memory map area is kept unchanged.
>
Good suggestions, I wil do this on v7.
Thanks.
Song Gao
> Regards
> Bibo Mao
>
>>
>> Regards
>> Bibo Mao
>>
>>>
>>> Thanks.
>>> Song Gao
>>>> Regards
>>>> Bibo Mao
>>>>
>>>>> CPU_FOREACH(cs) {
>>>>> lacpu = LOONGARCH_CPU(cs);
>>>>> lacpu->env.load_elf = true;
>>>>> - lacpu->env.elf_address = kernel_addr;
>>>>> + if (cs == first_cpu) {
>>>>> + lacpu->env.elf_address = kernel_addr;
>>>>> + } else {
>>>>> + lacpu->env.elf_address = 0;
>>>>> + }
>>>>> + lacpu->env.boot_info = info;
>>>>> }
>>>>> +
>>>>> + g_free(bp);
>>>>> }
>>>>> void loongarch_load_kernel(MachineState *ms, struct
>>>>> loongarch_boot_info *info)
>>>>>
>>
© 2016 - 2026 Red Hat, Inc.