Message ID | 20240307164835.300412-4-gaosong@loongson.cn (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Add boot LoongArch elf kernel with FDT | expand |
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) >>>> >
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 > >
在 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) >>>>> >>
在 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 >> >> > >
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)
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(-)