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 ---