qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH v2 28/33] mips_malta: Add basic nanoMIPS boot co


From: Aleksandar Markovic
Subject: Re: [Qemu-devel] [PATCH v2 28/33] mips_malta: Add basic nanoMIPS boot code for MIPS' Malta
Date: Tue, 10 Jul 2018 18:30:37 +0000

> Subject: [PATCH v2 28/33] mips_malta: Add basic nanoMIPS boot code for MIPS' 
> Malta
>
> From: Matthew Fortune <address@hidden>
>
> Added very very basic nanoMIPS boot code but this is hacked in
> unconditionally currently.
>
> Signed-off-by: Yongbok Kim <address@hidden>
> Signed-off-by: Aleksandar Markovic <address@hidden>
> Signed-off-by: Stefan Markovic <address@hidden>
> ---
>  hw/mips/mips_malta.c | 75 
> +++++++++++++++++++++++++++++++++++++++++++++++-----
>  include/elf.h        |  1 +
>  2 files changed, 70 insertions(+), 6 deletions(-)
>
> diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
> index 3467451..4bc9036 100644
> --- a/hw/mips/mips_malta.c
> +++ b/hw/mips/mips_malta.c
> @@ -620,6 +620,58 @@ static void network_init(PCIBus *pci_bus)
>       a2 - 32-bit address of the environment variables table
>       a3 - RAM size in bytes
>  */
> +static void write_bootloader_nanomips(uint8_t *base, int64_t run_addr,
> +                                      int64_t kernel_entry)
> +{
> +    uint16_t *p;
> +
> +    /* Small bootloader */
> +    p = (uint16_t *)base;
> +
> +#define NM_HI1(VAL) (((VAL) >> 16) & 0x1f)
> +#define NM_HI2(VAL) \
> +            (((VAL) & 0xf000) | (((VAL) >> 19) & 0xffc) | (((VAL) >> 31) & 
> 0x1))
> +#define NM_LO(VAL)  ((VAL) & 0xfff)
> +
> +    stw_p(p++, 0x2800); stw_p(p++, 0x001c); /* bc to_here */
> +    stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */
> +    stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */
> +    stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */
> +    stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */
> +    stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */
> +    stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */
> +    stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */
> +
> +    /* to_here: */
> +    stw_p(p++, 0x0080); stw_p(p++, 0x0002); /* li a0,2 */
> +    stw_p(p++, 0xe3a0 | NM_HI1(ENVP_ADDR - 64));
> +    stw_p(p++, NM_HI2(ENVP_ADDR - 64));
> +                                /* lui sp,%hi(ENVP_ADDR - 64) */
> +    stw_p(p++, 0x83bd); stw_p(p++, NM_LO(ENVP_ADDR - 64));
> +                                /* ori sp,sp,%lo(ENVP_ADDR - 64) */
> +    stw_p(p++, 0xe0a0 | NM_HI1(ENVP_ADDR));
> +    stw_p(p++, NM_HI2(ENVP_ADDR));
> +                                /* lui a1,%hi(ENVP_ADDR) */
> +    stw_p(p++, 0x80a5); stw_p(p++, NM_LO(ENVP_ADDR));
> +                                /* ori a1,a1,%lo(ENVP_ADDR) */
> +    stw_p(p++, 0xe0c0 | NM_HI1(ENVP_ADDR + 8));
> +    stw_p(p++, NM_HI2(ENVP_ADDR + 8));
> +                                /* lui a2,%hi(ENVP_ADDR + 8) */
> +    stw_p(p++, 0x80c6); stw_p(p++, NM_LO(ENVP_ADDR + 8));
> +                                /* ori a2,a2,%lo(ENVP_ADDR + 8) */
> +    stw_p(p++, 0xe0e0 | NM_HI1(loaderparams.ram_low_size));
> +    stw_p(p++, NM_HI2(loaderparams.ram_low_size));
> +                                /* lui a3,%hi(loaderparams.ram_low_size) */
> +    stw_p(p++, 0x80e7); stw_p(p++, NM_LO(loaderparams.ram_low_size));
> +                                /* ori a3,a3,%lo(loaderparams.ram_low_size) 
> */
> +    stw_p(p++, 0xe320 | NM_HI1(kernel_entry));
> +    stw_p(p++, NM_HI2(kernel_entry));
> +                                /* lui t9,%hi(kernel_entry) */
> +    stw_p(p++, 0x8339); stw_p(p++, NM_LO(kernel_entry));
> +                                /* ori t9,t9,%lo(kernel_entry) */
> +    stw_p(p++, 0x4bf9); stw_p(p++, 0x0000);
> +                                /* jalrc   t8 */
> +}
>
>  static void write_bootloader(uint8_t *base, int64_t run_addr,
>                               int64_t kernel_entry)
> @@ -813,10 +865,16 @@ static int64_t load_kernel (void)
>                             NULL, (uint64_t *)&kernel_entry, NULL,
>                             (uint64_t *)&kernel_high, big_endian, EM_MIPS, 1, 
> 0);
>      if (kernel_size < 0) {
> -        error_report("could not load kernel '%s': %s",
> -                     loaderparams.kernel_filename,
> -                     load_elf_strerror(kernel_size));
> -        exit(1);
> +        kernel_size = load_elf(loaderparams.kernel_filename,
> +                    cpu_mips_kseg0_to_phys, NULL,
> +                    (uint64_t *)&kernel_entry, NULL,
> +                    (uint64_t *)&kernel_high, big_endian, EM_NANOMIPS, 1, 0);
> +        if (kernel_size < 0) {
> +            error_report("could not load kernel '%s': %s",
> +                         loaderparams.kernel_filename,
> +                         load_elf_strerror(kernel_size));
> +            exit(1);
> +        }

Hmmmm... Is there a better way of doing this decision logic?

>      }
>
>      /* Check where the kernel has been linked */
> @@ -1096,8 +1154,13 @@ void mips_malta_init(MachineState *machine)
>          loaderparams.initrd_filename = initrd_filename;
>          kernel_entry = load_kernel();
>
> -        write_bootloader(memory_region_get_ram_ptr(bios),
> -                         bootloader_run_addr, kernel_entry);
> +        if (!cpu_supports_isa(machine->cpu_type, ISA_NANOMIPS32)) {
> +            write_bootloader(memory_region_get_ram_ptr(bios),
> +                             bootloader_run_addr, kernel_entry);
> +        } else {
> +            write_bootloader_nanomips(memory_region_get_ram_ptr(bios),
> +                                      bootloader_run_addr, kernel_entry);
> +        }
>          if (kvm_enabled()) {
>              /* Write the bootloader code @ the end of RAM, 1MB reserved */
>              write_bootloader(memory_region_get_ram_ptr(ram_low_preio) +
> diff --git a/include/elf.h b/include/elf.h
> index b39e303..d322458 100644
> --- a/include/elf.h
> +++ b/include/elf.h
> @@ -144,6 +144,7 @@ typedef int64_t  Elf64_Sxword;
>
>  #define EM_RISCV        243     /* RISC-V */
>
> +#define EM_NANOMIPS     249     /* MIPS Tech nanoMIPS */
>  /*
>   * This is an interim value that we will use until the committee comes
>   * up with a final number.
> --
> 2.7.4
>
>


reply via email to

[Prev in Thread] Current Thread [Next in Thread]