boot.c (02307a678c3cb366d089ef8d90f6acb9663b98ce) | boot.c (7e0510d7600cd0c1c4742751b415f4f7df84328e) |
---|---|
1/* SPDX-License-Identifier: GPL-2.0-or-later */ 2/* 3 * LoongArch boot helper functions. 4 * 5 * Copyright (c) 2023 Loongson Technology Corporation Limited 6 */ 7 8#include "qemu/osdep.h" 9#include "qemu/units.h" 10#include "target/loongarch/cpu.h" 11#include "hw/loongarch/virt.h" 12#include "hw/loader.h" 13#include "elf.h" 14#include "qemu/error-report.h" 15#include "sysemu/reset.h" 16#include "sysemu/qtest.h" 17 | 1/* SPDX-License-Identifier: GPL-2.0-or-later */ 2/* 3 * LoongArch boot helper functions. 4 * 5 * Copyright (c) 2023 Loongson Technology Corporation Limited 6 */ 7 8#include "qemu/osdep.h" 9#include "qemu/units.h" 10#include "target/loongarch/cpu.h" 11#include "hw/loongarch/virt.h" 12#include "hw/loader.h" 13#include "elf.h" 14#include "qemu/error-report.h" 15#include "sysemu/reset.h" 16#include "sysemu/qtest.h" 17 |
18static const unsigned int slave_boot_code[] = { 19 /* Configure reset ebase. */ 20 0x0400302c, /* csrwr $t0, LOONGARCH_CSR_EENTRY */ 21 22 /* Disable interrupt. */ 23 0x0380100c, /* ori $t0, $zero,0x4 */ 24 0x04000180, /* csrxchg $zero, $t0, LOONGARCH_CSR_CRMD */ 25 26 /* Clear mailbox. */ 27 0x1400002d, /* lu12i.w $t1, 1(0x1) */ 28 0x038081ad, /* ori $t1, $t1, CORE_BUF_20 */ 29 0x06481da0, /* iocsrwr.d $zero, $t1 */ 30 31 /* Enable IPI interrupt. */ 32 0x1400002c, /* lu12i.w $t0, 1(0x1) */ 33 0x0400118c, /* csrxchg $t0, $t0, LOONGARCH_CSR_ECFG */ 34 0x02fffc0c, /* addi.d $t0, $r0,-1(0xfff) */ 35 0x1400002d, /* lu12i.w $t1, 1(0x1) */ 36 0x038011ad, /* ori $t1, $t1, CORE_EN_OFF */ 37 0x064819ac, /* iocsrwr.w $t0, $t1 */ 38 0x1400002d, /* lu12i.w $t1, 1(0x1) */ 39 0x038081ad, /* ori $t1, $t1, CORE_BUF_20 */ 40 41 /* Wait for wakeup <.L11>: */ 42 0x06488000, /* idle 0x0 */ 43 0x03400000, /* andi $zero, $zero, 0x0 */ 44 0x064809ac, /* iocsrrd.w $t0, $t1 */ 45 0x43fff59f, /* beqz $t0, -12(0x7ffff4) # 48 <.L11> */ 46 47 /* Read and clear IPI interrupt. */ 48 0x1400002d, /* lu12i.w $t1, 1(0x1) */ 49 0x064809ac, /* iocsrrd.w $t0, $t1 */ 50 0x1400002d, /* lu12i.w $t1, 1(0x1) */ 51 0x038031ad, /* ori $t1, $t1, CORE_CLEAR_OFF */ 52 0x064819ac, /* iocsrwr.w $t0, $t1 */ 53 54 /* Disable IPI interrupt. */ 55 0x1400002c, /* lu12i.w $t0, 1(0x1) */ 56 0x04001180, /* csrxchg $zero, $t0, LOONGARCH_CSR_ECFG */ 57 58 /* Read mail buf and jump to specified entry */ 59 0x1400002d, /* lu12i.w $t1, 1(0x1) */ 60 0x038081ad, /* ori $t1, $t1, CORE_BUF_20 */ 61 0x06480dac, /* iocsrrd.d $t0, $t1 */ 62 0x00150181, /* move $ra, $t0 */ 63 0x4c000020, /* jirl $zero, $ra,0 */ 64}; 65 |
|
18static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr) 19{ 20 return addr & MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS); 21} 22 23static int64_t load_kernel_info(struct loongarch_boot_info *info) 24{ 25 uint64_t kernel_entry, kernel_low, kernel_high, initrd_size; --- 94 unchanged lines hidden (view full) --- 120 kernel_addr = load_kernel_info(info); 121 } else { 122 if(!qtest_enabled()) { 123 error_report("Need kernel filename\n"); 124 exit(1); 125 } 126 } 127 | 66static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr) 67{ 68 return addr & MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS); 69} 70 71static int64_t load_kernel_info(struct loongarch_boot_info *info) 72{ 73 uint64_t kernel_entry, kernel_low, kernel_high, initrd_size; --- 94 unchanged lines hidden (view full) --- 168 kernel_addr = load_kernel_info(info); 169 } else { 170 if(!qtest_enabled()) { 171 error_report("Need kernel filename\n"); 172 exit(1); 173 } 174 } 175 |
176 /* Load slave boot code at pflash0 . */ 177 void *boot_code = g_malloc0(VIRT_FLASH0_SIZE); 178 memcpy(boot_code, &slave_boot_code, sizeof(slave_boot_code)); 179 rom_add_blob_fixed("boot_code", boot_code, VIRT_FLASH0_SIZE, VIRT_FLASH0_BASE); 180 |
|
128 CPU_FOREACH(cs) { 129 lacpu = LOONGARCH_CPU(cs); 130 lacpu->env.load_elf = true; | 181 CPU_FOREACH(cs) { 182 lacpu = LOONGARCH_CPU(cs); 183 lacpu->env.load_elf = true; |
131 lacpu->env.elf_address = kernel_addr; | 184 if (cs == first_cpu) { 185 lacpu->env.elf_address = kernel_addr; 186 } else { 187 lacpu->env.elf_address = VIRT_FLASH0_BASE; 188 } 189 lacpu->env.boot_info = info; |
132 } | 190 } |
191 192 g_free(boot_code); |
|
133} 134 135void loongarch_load_kernel(MachineState *ms, struct loongarch_boot_info *info) 136{ 137 LoongArchMachineState *lams = LOONGARCH_MACHINE(ms); 138 int i; 139 140 /* register reset function */ --- 14 unchanged lines hidden --- | 193} 194 195void loongarch_load_kernel(MachineState *ms, struct loongarch_boot_info *info) 196{ 197 LoongArchMachineState *lams = LOONGARCH_MACHINE(ms); 198 int i; 199 200 /* register reset function */ --- 14 unchanged lines hidden --- |