1
Fix a bug introduced with dynamic TLB sizing -- we forgot to account
1
Hi,
2
for possible TLB resizes during tlb_fill().
3
2
4
Max reported the bug and provided a reproducer here:
3
This new version removed the translate_fn() from patch 1 because it
5
https://lists.gnu.org/archive/html/qemu-devel/2019-02/msg02283.html
4
wasn't removing the sign-extension for pentry as we thought it would.
5
A more detailed explanation is given in the commit msg of patch 1.
6
6
7
Thanks,
7
We're now retrieving the 'lowaddr' value from load_elf_ram_sym() and
8
using it when we're running a 32-bit CPU. This worked with 32 bit
9
'virt' machine booting with the -kernel option.
8
10
9
        Emilio
11
If this approach doesn't work for the Xvisor use case, IMO we should
12
just filter kernel_load_addr bits directly as we were doing a handful of
13
versions ago.
10
14
15
Patches are based on current riscv-to-apply.next.
11
16
17
Changes from v9:
18
- patch 1:
19
- removed the translate_fn() callback
20
- return 'kernel_low' when running a 32-bit CPU
21
- v9 link: https://lists.gnu.org/archive/html/qemu-devel/2023-01/msg04509.html
12
22
23
Daniel Henrique Barboza (3):
24
hw/riscv: handle 32 bit CPUs kernel_addr in riscv_load_kernel()
25
hw/riscv/boot.c: consolidate all kernel init in riscv_load_kernel()
26
hw/riscv/boot.c: make riscv_load_initrd() static
27
28
hw/riscv/boot.c | 96 +++++++++++++++++++++++---------------
29
hw/riscv/microchip_pfsoc.c | 12 +----
30
hw/riscv/opentitan.c | 4 +-
31
hw/riscv/sifive_e.c | 4 +-
32
hw/riscv/sifive_u.c | 12 +----
33
hw/riscv/spike.c | 14 ++----
34
hw/riscv/virt.c | 12 +----
35
include/hw/riscv/boot.h | 3 +-
36
8 files changed, 76 insertions(+), 81 deletions(-)
37
38
--
39
2.39.1
diff view generated by jsdifflib
1
We are failing to take into account that tlb_fill() can cause a
1
load_elf_ram_sym() will sign-extend 32 bit addresses. If a 32 bit QEMU
2
TLB resize, which renders prior TLB entry pointers/indices stale.
2
guest happens to be running in a hypervisor that are using 64 bits to
3
Fix it by re-doing the TLB entry lookups immediately after tlb_fill.
3
encode its address, kernel_entry can be padded with '1's and create
4
problems [1].
4
5
5
Fixes: 86e1eff8bc ("tcg: introduce dynamic TLB sizing", 2019-01-28)
6
Using a translate_fn() callback in load_elf_ram_sym() to filter the
6
Reported-by: Max Filippov <jcmvbkbc@gmail.com>
7
padding from the address doesn't work. A more detailed explanation can
7
Tested-by: Max Filippov <jcmvbkbc@gmail.com>
8
be found in [2]. The short version is that glue(load_elf, SZ), from
8
Signed-off-by: Emilio G. Cota <cota@braap.org>
9
include/hw/elf_ops.h, will calculate 'pentry' (mapped into the
10
'kernel_load_base' var in riscv_load_Kernel()) before using
11
translate_fn(), and will not recalculate it after executing it. This
12
means that the callback does not prevent the padding from
13
kernel_load_base to appear.
14
15
Let's instead use a kernel_low var to capture the 'lowaddr' value from
16
load_elf_ram_sim(), and return it when we're dealing with 32 bit CPUs.
17
18
[1] https://lists.gnu.org/archive/html/qemu-devel/2023-01/msg02281.html
19
[2] https://lists.gnu.org/archive/html/qemu-devel/2023-02/msg00099.html
20
21
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
---
22
---
10
accel/tcg/softmmu_template.h | 8 ++++++++
23
hw/riscv/boot.c | 15 +++++++++++----
11
accel/tcg/cputlb.c | 4 ++++
24
hw/riscv/microchip_pfsoc.c | 3 ++-
12
2 files changed, 12 insertions(+)
25
hw/riscv/opentitan.c | 3 ++-
26
hw/riscv/sifive_e.c | 3 ++-
27
hw/riscv/sifive_u.c | 3 ++-
28
hw/riscv/spike.c | 3 ++-
29
hw/riscv/virt.c | 3 ++-
30
include/hw/riscv/boot.h | 1 +
31
8 files changed, 24 insertions(+), 10 deletions(-)
13
32
14
diff --git a/accel/tcg/softmmu_template.h b/accel/tcg/softmmu_template.h
33
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
15
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
16
--- a/accel/tcg/softmmu_template.h
35
--- a/hw/riscv/boot.c
17
+++ b/accel/tcg/softmmu_template.h
36
+++ b/hw/riscv/boot.c
18
@@ -XXX,XX +XXX,XX @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr,
37
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_load_firmware(const char *firmware_filename,
19
if (!VICTIM_TLB_HIT(ADDR_READ, addr)) {
38
}
20
tlb_fill(ENV_GET_CPU(env), addr, DATA_SIZE, READ_ACCESS_TYPE,
39
21
mmu_idx, retaddr);
40
target_ulong riscv_load_kernel(MachineState *machine,
22
+ index = tlb_index(env, mmu_idx, addr);
41
+ RISCVHartArrayState *harts,
23
+ entry = tlb_entry(env, mmu_idx, addr);
42
target_ulong kernel_start_addr,
24
}
43
symbol_fn_t sym_cb)
25
tlb_addr = entry->ADDR_READ;
44
{
45
const char *kernel_filename = machine->kernel_filename;
46
- uint64_t kernel_load_base, kernel_entry;
47
+ uint64_t kernel_load_base, kernel_entry, kernel_low;
48
49
g_assert(kernel_filename != NULL);
50
51
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_load_kernel(MachineState *machine,
52
* the (expected) load address load address. This allows kernels to have
53
* separate SBI and ELF entry points (used by FreeBSD, for example).
54
*/
55
- if (load_elf_ram_sym(kernel_filename, NULL, NULL, NULL,
56
- NULL, &kernel_load_base, NULL, NULL, 0,
57
+ if (load_elf_ram_sym(kernel_filename, NULL, NULL, NULL, NULL,
58
+ &kernel_load_base, &kernel_low, NULL, 0,
59
EM_RISCV, 1, 0, NULL, true, sym_cb) > 0) {
60
- return kernel_load_base;
61
+ kernel_entry = kernel_load_base;
62
+
63
+ if (riscv_is_32bit(harts)) {
64
+ kernel_entry = kernel_low;
65
+ }
66
+
67
+ return kernel_entry;
26
}
68
}
27
@@ -XXX,XX +XXX,XX @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr,
69
28
if (!VICTIM_TLB_HIT(ADDR_READ, addr)) {
70
if (load_uimage_as(kernel_filename, &kernel_entry, NULL, NULL,
29
tlb_fill(ENV_GET_CPU(env), addr, DATA_SIZE, READ_ACCESS_TYPE,
71
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
30
mmu_idx, retaddr);
72
index XXXXXXX..XXXXXXX 100644
31
+ index = tlb_index(env, mmu_idx, addr);
73
--- a/hw/riscv/microchip_pfsoc.c
32
+ entry = tlb_entry(env, mmu_idx, addr);
74
+++ b/hw/riscv/microchip_pfsoc.c
33
}
75
@@ -XXX,XX +XXX,XX @@ static void microchip_icicle_kit_machine_init(MachineState *machine)
34
tlb_addr = entry->ADDR_READ;
76
kernel_start_addr = riscv_calc_kernel_start_addr(&s->soc.u_cpus,
77
firmware_end_addr);
78
79
- kernel_entry = riscv_load_kernel(machine, kernel_start_addr, NULL);
80
+ kernel_entry = riscv_load_kernel(machine, &s->soc.u_cpus,
81
+ kernel_start_addr, NULL);
82
83
if (machine->initrd_filename) {
84
riscv_load_initrd(machine, kernel_entry);
85
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
86
index XXXXXXX..XXXXXXX 100644
87
--- a/hw/riscv/opentitan.c
88
+++ b/hw/riscv/opentitan.c
89
@@ -XXX,XX +XXX,XX @@ static void opentitan_board_init(MachineState *machine)
35
}
90
}
36
@@ -XXX,XX +XXX,XX @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
91
37
if (!VICTIM_TLB_HIT(addr_write, addr)) {
92
if (machine->kernel_filename) {
38
tlb_fill(ENV_GET_CPU(env), addr, DATA_SIZE, MMU_DATA_STORE,
93
- riscv_load_kernel(machine, memmap[IBEX_DEV_RAM].base, NULL);
39
mmu_idx, retaddr);
94
+ riscv_load_kernel(machine, &s->soc.cpus,
40
+ index = tlb_index(env, mmu_idx, addr);
95
+ memmap[IBEX_DEV_RAM].base, NULL);
41
+ entry = tlb_entry(env, mmu_idx, addr);
42
}
43
tlb_addr = tlb_addr_write(entry) & ~TLB_INVALID_MASK;
44
}
96
}
45
@@ -XXX,XX +XXX,XX @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
97
}
46
if (!VICTIM_TLB_HIT(addr_write, addr)) {
98
47
tlb_fill(ENV_GET_CPU(env), addr, DATA_SIZE, MMU_DATA_STORE,
99
diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
48
mmu_idx, retaddr);
100
index XXXXXXX..XXXXXXX 100644
49
+ index = tlb_index(env, mmu_idx, addr);
101
--- a/hw/riscv/sifive_e.c
50
+ entry = tlb_entry(env, mmu_idx, addr);
102
+++ b/hw/riscv/sifive_e.c
51
}
103
@@ -XXX,XX +XXX,XX @@ static void sifive_e_machine_init(MachineState *machine)
52
tlb_addr = tlb_addr_write(entry) & ~TLB_INVALID_MASK;
104
memmap[SIFIVE_E_DEV_MROM].base, &address_space_memory);
105
106
if (machine->kernel_filename) {
107
- riscv_load_kernel(machine, memmap[SIFIVE_E_DEV_DTIM].base, NULL);
108
+ riscv_load_kernel(machine, &s->soc.cpus,
109
+ memmap[SIFIVE_E_DEV_DTIM].base, NULL);
53
}
110
}
54
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
111
}
112
113
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
55
index XXXXXXX..XXXXXXX 100644
114
index XXXXXXX..XXXXXXX 100644
56
--- a/accel/tcg/cputlb.c
115
--- a/hw/riscv/sifive_u.c
57
+++ b/accel/tcg/cputlb.c
116
+++ b/hw/riscv/sifive_u.c
58
@@ -XXX,XX +XXX,XX @@ tb_page_addr_t get_page_addr_code(CPUArchState *env, target_ulong addr)
117
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
59
if (unlikely(!tlb_hit(entry->addr_code, addr))) {
118
kernel_start_addr = riscv_calc_kernel_start_addr(&s->soc.u_cpus,
60
if (!VICTIM_TLB_HIT(addr_code, addr)) {
119
firmware_end_addr);
61
tlb_fill(ENV_GET_CPU(env), addr, 0, MMU_INST_FETCH, mmu_idx, 0);
120
62
+ index = tlb_index(env, mmu_idx, addr);
121
- kernel_entry = riscv_load_kernel(machine, kernel_start_addr, NULL);
63
+ entry = tlb_entry(env, mmu_idx, addr);
122
+ kernel_entry = riscv_load_kernel(machine, &s->soc.u_cpus,
64
}
123
+ kernel_start_addr, NULL);
65
assert(tlb_hit(entry->addr_code, addr));
124
66
}
125
if (machine->initrd_filename) {
67
@@ -XXX,XX +XXX,XX @@ static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
126
riscv_load_initrd(machine, kernel_entry);
68
if (!VICTIM_TLB_HIT(addr_write, addr)) {
127
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
69
tlb_fill(ENV_GET_CPU(env), addr, 1 << s_bits, MMU_DATA_STORE,
128
index XXXXXXX..XXXXXXX 100644
70
mmu_idx, retaddr);
129
--- a/hw/riscv/spike.c
71
+ index = tlb_index(env, mmu_idx, addr);
130
+++ b/hw/riscv/spike.c
72
+ tlbe = tlb_entry(env, mmu_idx, addr);
131
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
73
}
132
kernel_start_addr = riscv_calc_kernel_start_addr(&s->soc[0],
74
tlb_addr = tlb_addr_write(tlbe) & ~TLB_INVALID_MASK;
133
firmware_end_addr);
75
}
134
135
- kernel_entry = riscv_load_kernel(machine, kernel_start_addr,
136
+ kernel_entry = riscv_load_kernel(machine, &s->soc[0],
137
+ kernel_start_addr,
138
htif_symbol_callback);
139
140
if (machine->initrd_filename) {
141
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
142
index XXXXXXX..XXXXXXX 100644
143
--- a/hw/riscv/virt.c
144
+++ b/hw/riscv/virt.c
145
@@ -XXX,XX +XXX,XX @@ static void virt_machine_done(Notifier *notifier, void *data)
146
kernel_start_addr = riscv_calc_kernel_start_addr(&s->soc[0],
147
firmware_end_addr);
148
149
- kernel_entry = riscv_load_kernel(machine, kernel_start_addr, NULL);
150
+ kernel_entry = riscv_load_kernel(machine, &s->soc[0],
151
+ kernel_start_addr, NULL);
152
153
if (machine->initrd_filename) {
154
riscv_load_initrd(machine, kernel_entry);
155
diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
156
index XXXXXXX..XXXXXXX 100644
157
--- a/include/hw/riscv/boot.h
158
+++ b/include/hw/riscv/boot.h
159
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_load_firmware(const char *firmware_filename,
160
hwaddr firmware_load_addr,
161
symbol_fn_t sym_cb);
162
target_ulong riscv_load_kernel(MachineState *machine,
163
+ RISCVHartArrayState *harts,
164
target_ulong firmware_end_addr,
165
symbol_fn_t sym_cb);
166
void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry);
76
--
167
--
77
2.17.1
168
2.39.1
78
79
diff view generated by jsdifflib
New patch
1
1
The microchip_icicle_kit, sifive_u, spike and virt boards are now doing
2
the same steps when '-kernel' is used:
3
4
- execute load_kernel()
5
- load init_rd()
6
- write kernel_cmdline
7
8
Let's fold everything inside riscv_load_kernel() to avoid code
9
repetition. To not change the behavior of boards that aren't calling
10
riscv_load_init(), add an 'load_initrd' flag to riscv_load_kernel() and
11
allow these boards to opt out from initrd loading.
12
13
Cc: Palmer Dabbelt <palmer@dabbelt.com>
14
Reviewed-by: Bin Meng <bmeng@tinylab.org>
15
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
16
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
17
---
18
hw/riscv/boot.c | 21 ++++++++++++++++++---
19
hw/riscv/microchip_pfsoc.c | 11 +----------
20
hw/riscv/opentitan.c | 3 ++-
21
hw/riscv/sifive_e.c | 3 ++-
22
hw/riscv/sifive_u.c | 11 +----------
23
hw/riscv/spike.c | 11 +----------
24
hw/riscv/virt.c | 11 +----------
25
include/hw/riscv/boot.h | 1 +
26
8 files changed, 27 insertions(+), 45 deletions(-)
27
28
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/riscv/boot.c
31
+++ b/hw/riscv/boot.c
32
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_load_firmware(const char *firmware_filename,
33
target_ulong riscv_load_kernel(MachineState *machine,
34
RISCVHartArrayState *harts,
35
target_ulong kernel_start_addr,
36
+ bool load_initrd,
37
symbol_fn_t sym_cb)
38
{
39
const char *kernel_filename = machine->kernel_filename;
40
uint64_t kernel_load_base, kernel_entry, kernel_low;
41
+ void *fdt = machine->fdt;
42
43
g_assert(kernel_filename != NULL);
44
45
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_load_kernel(MachineState *machine,
46
kernel_entry = kernel_low;
47
}
48
49
- return kernel_entry;
50
+ goto out;
51
}
52
53
if (load_uimage_as(kernel_filename, &kernel_entry, NULL, NULL,
54
NULL, NULL, NULL) > 0) {
55
- return kernel_entry;
56
+ goto out;
57
}
58
59
if (load_image_targphys_as(kernel_filename, kernel_start_addr,
60
current_machine->ram_size, NULL) > 0) {
61
- return kernel_start_addr;
62
+ kernel_entry = kernel_start_addr;
63
+ goto out;
64
}
65
66
error_report("could not load kernel '%s'", kernel_filename);
67
exit(1);
68
+
69
+out:
70
+ if (load_initrd && machine->initrd_filename) {
71
+ riscv_load_initrd(machine, kernel_entry);
72
+ }
73
+
74
+ if (fdt && machine->kernel_cmdline && *machine->kernel_cmdline) {
75
+ qemu_fdt_setprop_string(fdt, "/chosen", "bootargs",
76
+ machine->kernel_cmdline);
77
+ }
78
+
79
+ return kernel_entry;
80
}
81
82
void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry)
83
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
84
index XXXXXXX..XXXXXXX 100644
85
--- a/hw/riscv/microchip_pfsoc.c
86
+++ b/hw/riscv/microchip_pfsoc.c
87
@@ -XXX,XX +XXX,XX @@ static void microchip_icicle_kit_machine_init(MachineState *machine)
88
firmware_end_addr);
89
90
kernel_entry = riscv_load_kernel(machine, &s->soc.u_cpus,
91
- kernel_start_addr, NULL);
92
-
93
- if (machine->initrd_filename) {
94
- riscv_load_initrd(machine, kernel_entry);
95
- }
96
-
97
- if (machine->kernel_cmdline && *machine->kernel_cmdline) {
98
- qemu_fdt_setprop_string(machine->fdt, "/chosen",
99
- "bootargs", machine->kernel_cmdline);
100
- }
101
+ kernel_start_addr, true, NULL);
102
103
/* Compute the fdt load address in dram */
104
fdt_load_addr = riscv_compute_fdt_addr(memmap[MICROCHIP_PFSOC_DRAM_LO].base,
105
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
106
index XXXXXXX..XXXXXXX 100644
107
--- a/hw/riscv/opentitan.c
108
+++ b/hw/riscv/opentitan.c
109
@@ -XXX,XX +XXX,XX @@ static void opentitan_board_init(MachineState *machine)
110
111
if (machine->kernel_filename) {
112
riscv_load_kernel(machine, &s->soc.cpus,
113
- memmap[IBEX_DEV_RAM].base, NULL);
114
+ memmap[IBEX_DEV_RAM].base,
115
+ false, NULL);
116
}
117
}
118
119
diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
120
index XXXXXXX..XXXXXXX 100644
121
--- a/hw/riscv/sifive_e.c
122
+++ b/hw/riscv/sifive_e.c
123
@@ -XXX,XX +XXX,XX @@ static void sifive_e_machine_init(MachineState *machine)
124
125
if (machine->kernel_filename) {
126
riscv_load_kernel(machine, &s->soc.cpus,
127
- memmap[SIFIVE_E_DEV_DTIM].base, NULL);
128
+ memmap[SIFIVE_E_DEV_DTIM].base,
129
+ false, NULL);
130
}
131
}
132
133
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
134
index XXXXXXX..XXXXXXX 100644
135
--- a/hw/riscv/sifive_u.c
136
+++ b/hw/riscv/sifive_u.c
137
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
138
firmware_end_addr);
139
140
kernel_entry = riscv_load_kernel(machine, &s->soc.u_cpus,
141
- kernel_start_addr, NULL);
142
-
143
- if (machine->initrd_filename) {
144
- riscv_load_initrd(machine, kernel_entry);
145
- }
146
-
147
- if (machine->kernel_cmdline && *machine->kernel_cmdline) {
148
- qemu_fdt_setprop_string(machine->fdt, "/chosen", "bootargs",
149
- machine->kernel_cmdline);
150
- }
151
+ kernel_start_addr, true, NULL);
152
} else {
153
/*
154
* If dynamic firmware is used, it doesn't know where is the next mode
155
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
156
index XXXXXXX..XXXXXXX 100644
157
--- a/hw/riscv/spike.c
158
+++ b/hw/riscv/spike.c
159
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
160
161
kernel_entry = riscv_load_kernel(machine, &s->soc[0],
162
kernel_start_addr,
163
- htif_symbol_callback);
164
-
165
- if (machine->initrd_filename) {
166
- riscv_load_initrd(machine, kernel_entry);
167
- }
168
-
169
- if (machine->kernel_cmdline && *machine->kernel_cmdline) {
170
- qemu_fdt_setprop_string(machine->fdt, "/chosen", "bootargs",
171
- machine->kernel_cmdline);
172
- }
173
+ true, htif_symbol_callback);
174
} else {
175
/*
176
* If dynamic firmware is used, it doesn't know where is the next mode
177
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
178
index XXXXXXX..XXXXXXX 100644
179
--- a/hw/riscv/virt.c
180
+++ b/hw/riscv/virt.c
181
@@ -XXX,XX +XXX,XX @@ static void virt_machine_done(Notifier *notifier, void *data)
182
firmware_end_addr);
183
184
kernel_entry = riscv_load_kernel(machine, &s->soc[0],
185
- kernel_start_addr, NULL);
186
-
187
- if (machine->initrd_filename) {
188
- riscv_load_initrd(machine, kernel_entry);
189
- }
190
-
191
- if (machine->kernel_cmdline && *machine->kernel_cmdline) {
192
- qemu_fdt_setprop_string(machine->fdt, "/chosen", "bootargs",
193
- machine->kernel_cmdline);
194
- }
195
+ kernel_start_addr, true, NULL);
196
} else {
197
/*
198
* If dynamic firmware is used, it doesn't know where is the next mode
199
diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
200
index XXXXXXX..XXXXXXX 100644
201
--- a/include/hw/riscv/boot.h
202
+++ b/include/hw/riscv/boot.h
203
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_load_firmware(const char *firmware_filename,
204
target_ulong riscv_load_kernel(MachineState *machine,
205
RISCVHartArrayState *harts,
206
target_ulong firmware_end_addr,
207
+ bool load_initrd,
208
symbol_fn_t sym_cb);
209
void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry);
210
uint64_t riscv_compute_fdt_addr(hwaddr dram_start, uint64_t dram_size,
211
--
212
2.39.1
diff view generated by jsdifflib
1
Signed-off-by: Emilio G. Cota <cota@braap.org>
1
The only remaining caller is riscv_load_kernel_and_initrd() which
2
belongs to the same file.
3
4
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Bin Meng <bmeng@tinylab.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
2
---
8
---
3
include/exec/exec-all.h | 5 +++++
9
hw/riscv/boot.c | 80 ++++++++++++++++++++---------------------
4
1 file changed, 5 insertions(+)
10
include/hw/riscv/boot.h | 1 -
11
2 files changed, 40 insertions(+), 41 deletions(-)
5
12
6
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
13
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
7
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
8
--- a/include/exec/exec-all.h
15
--- a/hw/riscv/boot.c
9
+++ b/include/exec/exec-all.h
16
+++ b/hw/riscv/boot.c
10
@@ -XXX,XX +XXX,XX @@ static inline void assert_no_pages_locked(void)
17
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_load_firmware(const char *firmware_filename,
11
struct MemoryRegionSection *iotlb_to_section(CPUState *cpu,
18
exit(1);
12
hwaddr index, MemTxAttrs attrs);
19
}
13
20
14
+/*
21
+static void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry)
15
+ * Note: tlb_fill() can trigger a resize of the TLB. This means that all of the
22
+{
16
+ * caller's prior references to the TLB table (e.g. CPUTLBEntry pointers) must
23
+ const char *filename = machine->initrd_filename;
17
+ * be discarded and looked up again (e.g. via tlb_entry()).
24
+ uint64_t mem_size = machine->ram_size;
18
+ */
25
+ void *fdt = machine->fdt;
19
void tlb_fill(CPUState *cpu, target_ulong addr, int size,
26
+ hwaddr start, end;
20
MMUAccessType access_type, int mmu_idx, uintptr_t retaddr);
27
+ ssize_t size;
21
28
+
29
+ g_assert(filename != NULL);
30
+
31
+ /*
32
+ * We want to put the initrd far enough into RAM that when the
33
+ * kernel is uncompressed it will not clobber the initrd. However
34
+ * on boards without much RAM we must ensure that we still leave
35
+ * enough room for a decent sized initrd, and on boards with large
36
+ * amounts of RAM we must avoid the initrd being so far up in RAM
37
+ * that it is outside lowmem and inaccessible to the kernel.
38
+ * So for boards with less than 256MB of RAM we put the initrd
39
+ * halfway into RAM, and for boards with 256MB of RAM or more we put
40
+ * the initrd at 128MB.
41
+ */
42
+ start = kernel_entry + MIN(mem_size / 2, 128 * MiB);
43
+
44
+ size = load_ramdisk(filename, start, mem_size - start);
45
+ if (size == -1) {
46
+ size = load_image_targphys(filename, start, mem_size - start);
47
+ if (size == -1) {
48
+ error_report("could not load ramdisk '%s'", filename);
49
+ exit(1);
50
+ }
51
+ }
52
+
53
+ /* Some RISC-V machines (e.g. opentitan) don't have a fdt. */
54
+ if (fdt) {
55
+ end = start + size;
56
+ qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-start", start);
57
+ qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end", end);
58
+ }
59
+}
60
+
61
target_ulong riscv_load_kernel(MachineState *machine,
62
RISCVHartArrayState *harts,
63
target_ulong kernel_start_addr,
64
@@ -XXX,XX +XXX,XX @@ out:
65
return kernel_entry;
66
}
67
68
-void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry)
69
-{
70
- const char *filename = machine->initrd_filename;
71
- uint64_t mem_size = machine->ram_size;
72
- void *fdt = machine->fdt;
73
- hwaddr start, end;
74
- ssize_t size;
75
-
76
- g_assert(filename != NULL);
77
-
78
- /*
79
- * We want to put the initrd far enough into RAM that when the
80
- * kernel is uncompressed it will not clobber the initrd. However
81
- * on boards without much RAM we must ensure that we still leave
82
- * enough room for a decent sized initrd, and on boards with large
83
- * amounts of RAM we must avoid the initrd being so far up in RAM
84
- * that it is outside lowmem and inaccessible to the kernel.
85
- * So for boards with less than 256MB of RAM we put the initrd
86
- * halfway into RAM, and for boards with 256MB of RAM or more we put
87
- * the initrd at 128MB.
88
- */
89
- start = kernel_entry + MIN(mem_size / 2, 128 * MiB);
90
-
91
- size = load_ramdisk(filename, start, mem_size - start);
92
- if (size == -1) {
93
- size = load_image_targphys(filename, start, mem_size - start);
94
- if (size == -1) {
95
- error_report("could not load ramdisk '%s'", filename);
96
- exit(1);
97
- }
98
- }
99
-
100
- /* Some RISC-V machines (e.g. opentitan) don't have a fdt. */
101
- if (fdt) {
102
- end = start + size;
103
- qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-start", start);
104
- qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end", end);
105
- }
106
-}
107
-
108
/*
109
* This function makes an assumption that the DRAM interval
110
* 'dram_base' + 'dram_size' is contiguous.
111
diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
112
index XXXXXXX..XXXXXXX 100644
113
--- a/include/hw/riscv/boot.h
114
+++ b/include/hw/riscv/boot.h
115
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_load_kernel(MachineState *machine,
116
target_ulong firmware_end_addr,
117
bool load_initrd,
118
symbol_fn_t sym_cb);
119
-void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry);
120
uint64_t riscv_compute_fdt_addr(hwaddr dram_start, uint64_t dram_size,
121
MachineState *ms);
122
void riscv_load_fdt(hwaddr fdt_addr, void *fdt);
22
--
123
--
23
2.17.1
124
2.39.1
24
125
25
126
diff view generated by jsdifflib