Skip to content

Commit 21bde1e

Browse files
aikdgibson
authored andcommitted
spapr: Fix implementation of Open Firmware client interface
This addresses the comments from v22. The functional changes are (the VOF ones need retesting with Pegasos2): (VOF) setprop will start failing if the machine class callback did not handle it; (VOF) unit addresses are lowered in path_offset(); (SPAPR) /chosen/bootargs is initialized from kernel_cmdline if the client did not change it. Fixes: 5c991e5 ("spapr: Implement Open Firmware client interface") Cc: BALATON Zoltan <[email protected]> Signed-off-by: Alexey Kardashevskiy <[email protected]> Message-Id: <[email protected]> Tested-by: BALATON Zoltan <[email protected]> Signed-off-by: David Gibson <[email protected]>
1 parent 89bb5a4 commit 21bde1e

File tree

11 files changed

+48
-68
lines changed

11 files changed

+48
-68
lines changed

MAINTAINERS

+2-2
Original file line numberDiff line numberDiff line change
@@ -1362,8 +1362,8 @@ F: include/hw/pci-host/mv64361.h
13621362

13631363
Virtual Open Firmware (VOF)
13641364
M: Alexey Kardashevskiy <[email protected]>
1365-
M: David Gibson <[email protected]>
1366-
M: Greg Kurz <[email protected]>
1365+
R: David Gibson <[email protected]>
1366+
R: Greg Kurz <[email protected]>
13671367
13681368
S: Maintained
13691369
F: hw/ppc/spapr_vof*

hw/ppc/spapr.c

+1-9
Original file line numberDiff line numberDiff line change
@@ -1645,15 +1645,7 @@ static void spapr_machine_reset(MachineState *machine)
16451645

16461646
fdt = spapr_build_fdt(spapr, true, FDT_MAX_SIZE);
16471647
if (spapr->vof) {
1648-
target_ulong stack_ptr = 0;
1649-
1650-
spapr_vof_reset(spapr, fdt, &stack_ptr, &error_fatal);
1651-
1652-
spapr_cpu_set_entry_state(first_ppc_cpu, SPAPR_ENTRY_POINT,
1653-
stack_ptr, spapr->initrd_base,
1654-
spapr->initrd_size);
1655-
/* VOF is 32bit BE so enforce MSR here */
1656-
first_ppc_cpu->env.msr &= ~((1ULL << MSR_SF) | (1ULL << MSR_LE));
1648+
spapr_vof_reset(spapr, fdt, &error_fatal);
16571649
/*
16581650
* Do not pack the FDT as the client may change properties.
16591651
* VOF client does not expect the FDT so we do not load it to the VM.

hw/ppc/spapr_hcall.c

+2-3
Original file line numberDiff line numberDiff line change
@@ -1080,7 +1080,7 @@ target_ulong do_client_architecture_support(PowerPCCPU *cpu,
10801080
SpaprOptionVector *ov1_guest, *ov5_guest;
10811081
bool guest_radix;
10821082
bool raw_mode_supported = false;
1083-
bool guest_xive, reset_fdt = false;
1083+
bool guest_xive;
10841084
CPUState *cs;
10851085
void *fdt;
10861086
uint32_t max_compat = spapr->max_compat_pvr;
@@ -1233,8 +1233,7 @@ target_ulong do_client_architecture_support(PowerPCCPU *cpu,
12331233
spapr_setup_hpt(spapr);
12341234
}
12351235

1236-
reset_fdt = spapr->vof != NULL;
1237-
fdt = spapr_build_fdt(spapr, reset_fdt, fdt_bufsize);
1236+
fdt = spapr_build_fdt(spapr, spapr->vof != NULL, fdt_bufsize);
12381237
g_free(spapr->fdt_blob);
12391238
spapr->fdt_size = fdt_totalsize(fdt);
12401239
spapr->fdt_initial_size = spapr->fdt_size;

hw/ppc/spapr_vof.c

+23-9
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "qapi/error.h"
99
#include "hw/ppc/spapr.h"
1010
#include "hw/ppc/spapr_vio.h"
11+
#include "hw/ppc/spapr_cpu_core.h"
1112
#include "hw/ppc/fdt.h"
1213
#include "hw/ppc/vof.h"
1314
#include "sysemu/sysemu.h"
@@ -29,13 +30,19 @@ target_ulong spapr_h_vof_client(PowerPCCPU *cpu, SpaprMachineState *spapr,
2930
void spapr_vof_client_dt_finalize(SpaprMachineState *spapr, void *fdt)
3031
{
3132
char *stdout_path = spapr_vio_stdout_path(spapr->vio_bus);
32-
int chosen;
3333

3434
vof_build_dt(fdt, spapr->vof);
3535

36-
_FDT(chosen = fdt_path_offset(fdt, "/chosen"));
37-
_FDT(fdt_setprop_string(fdt, chosen, "bootargs",
38-
spapr->vof->bootargs ? : ""));
36+
if (spapr->vof->bootargs) {
37+
int chosen;
38+
39+
_FDT(chosen = fdt_path_offset(fdt, "/chosen"));
40+
/*
41+
* If the client did not change "bootargs", spapr_dt_chosen() must have
42+
* stored machine->kernel_cmdline in it before getting here.
43+
*/
44+
_FDT(fdt_setprop_string(fdt, chosen, "bootargs", spapr->vof->bootargs));
45+
}
3946

4047
/*
4148
* SLOF-less setup requires an open instance of stdout for early
@@ -48,20 +55,21 @@ void spapr_vof_client_dt_finalize(SpaprMachineState *spapr, void *fdt)
4855
}
4956
}
5057

51-
void spapr_vof_reset(SpaprMachineState *spapr, void *fdt,
52-
target_ulong *stack_ptr, Error **errp)
58+
void spapr_vof_reset(SpaprMachineState *spapr, void *fdt, Error **errp)
5359
{
60+
target_ulong stack_ptr;
5461
Vof *vof = spapr->vof;
62+
PowerPCCPU *first_ppc_cpu = POWERPC_CPU(first_cpu);
5563

5664
vof_init(vof, spapr->rma_size, errp);
5765

58-
*stack_ptr = vof_claim(vof, 0, VOF_STACK_SIZE, VOF_STACK_SIZE);
59-
if (*stack_ptr == -1) {
66+
stack_ptr = vof_claim(vof, 0, VOF_STACK_SIZE, VOF_STACK_SIZE);
67+
if (stack_ptr == -1) {
6068
error_setg(errp, "Memory allocation for stack failed");
6169
return;
6270
}
6371
/* Stack grows downwards plus reserve space for the minimum stack frame */
64-
*stack_ptr += VOF_STACK_SIZE - 0x20;
72+
stack_ptr += VOF_STACK_SIZE - 0x20;
6573

6674
if (spapr->kernel_size &&
6775
vof_claim(vof, spapr->kernel_addr, spapr->kernel_size, 0) == -1) {
@@ -77,6 +85,12 @@ void spapr_vof_reset(SpaprMachineState *spapr, void *fdt,
7785

7886
spapr_vof_client_dt_finalize(spapr, fdt);
7987

88+
spapr_cpu_set_entry_state(first_ppc_cpu, SPAPR_ENTRY_POINT,
89+
stack_ptr, spapr->initrd_base,
90+
spapr->initrd_size);
91+
/* VOF is 32bit BE so enforce MSR here */
92+
first_ppc_cpu->env.msr &= ~((1ULL << MSR_SF) | (1ULL << MSR_LE));
93+
8094
/*
8195
* At this point the expected allocation map is:
8296
*

hw/ppc/vof.c

+17-13
Original file line numberDiff line numberDiff line change
@@ -144,15 +144,16 @@ static int path_offset(const void *fdt, const char *path)
144144
* the lower case forms of the hexadecimal digits in the range a..f,
145145
* suppressing leading zeros".
146146
*/
147-
at = strchr(path, '@');
148-
if (!at) {
149-
return fdt_path_offset(fdt, path);
150-
}
151-
152147
p = g_strdup(path);
153-
for (at = at - path + p + 1; *at; ++at) {
154-
*at = tolower(*at);
148+
for (at = strchr(p, '@'); at && *at; ) {
149+
if (*at == '/') {
150+
at = strchr(at, '@');
151+
} else {
152+
*at = tolower(*at);
153+
++at;
154+
}
155155
}
156+
156157
return fdt_path_offset(fdt, p);
157158
}
158159

@@ -300,6 +301,7 @@ static uint32_t vof_setprop(MachineState *ms, void *fdt, Vof *vof,
300301
char trval[64] = "";
301302
char nodepath[VOF_MAX_PATH] = "";
302303
Object *vmo = object_dynamic_cast(OBJECT(ms), TYPE_VOF_MACHINE_IF);
304+
VofMachineIfClass *vmc;
303305
g_autofree char *val = NULL;
304306

305307
if (vallen > VOF_MAX_SETPROPLEN) {
@@ -322,13 +324,13 @@ static uint32_t vof_setprop(MachineState *ms, void *fdt, Vof *vof,
322324
goto trace_exit;
323325
}
324326

325-
if (vmo) {
326-
VofMachineIfClass *vmc = VOF_MACHINE_GET_CLASS(vmo);
327+
if (!vmo) {
328+
goto trace_exit;
329+
}
327330

328-
if (vmc->setprop &&
329-
!vmc->setprop(ms, nodepath, propname, val, vallen)) {
330-
goto trace_exit;
331-
}
331+
vmc = VOF_MACHINE_GET_CLASS(vmo);
332+
if (!vmc->setprop || !vmc->setprop(ms, nodepath, propname, val, vallen)) {
333+
goto trace_exit;
332334
}
333335

334336
ret = fdt_setprop(fdt, offset, propname, val, vallen);
@@ -919,6 +921,8 @@ static uint32_t vof_client_handle(MachineState *ms, void *fdt, Vof *vof,
919921
ret = -1;
920922
}
921923

924+
#undef cmpserv
925+
922926
return ret;
923927
}
924928

include/hw/ppc/spapr.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -964,8 +964,7 @@ void spapr_set_all_lpcrs(target_ulong value, target_ulong mask);
964964
hwaddr spapr_get_rtas_addr(void);
965965
bool spapr_memory_hot_unplug_supported(SpaprMachineState *spapr);
966966

967-
void spapr_vof_reset(SpaprMachineState *spapr, void *fdt,
968-
target_ulong *stack_ptr, Error **errp);
967+
void spapr_vof_reset(SpaprMachineState *spapr, void *fdt, Error **errp);
969968
void spapr_vof_quiesce(MachineState *ms);
970969
bool spapr_vof_setprop(MachineState *ms, const char *path, const char *propname,
971970
void *val, int vallen);

pc-bios/vof.bin

-328 Bytes
Binary file not shown.

pc-bios/vof/ci.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ static int call_ci(const char *service, int nargs, int nret, ...)
6969
}
7070

7171
if (ci_entry((uint32_t)(&args)) < 0) {
72-
return PROM_ERROR;
72+
return -1;
7373
}
7474

7575
return (nret > 0) ? args.args[nargs] : 0;

pc-bios/vof/libc.c

-26
Original file line numberDiff line numberDiff line change
@@ -54,32 +54,6 @@ int memcmp(const void *ptr1, const void *ptr2, size_t n)
5454
return 0;
5555
}
5656

57-
void *memmove(void *dest, const void *src, size_t n)
58-
{
59-
char *cdest;
60-
const char *csrc;
61-
int i;
62-
63-
/* Do the buffers overlap in a bad way? */
64-
if (src < dest && src + n >= dest) {
65-
/* Copy from end to start */
66-
cdest = dest + n - 1;
67-
csrc = src + n - 1;
68-
for (i = 0; i < n; i++) {
69-
*cdest-- = *csrc--;
70-
}
71-
} else {
72-
/* Normal copy is possible */
73-
cdest = dest;
74-
csrc = src;
75-
for (i = 0; i < n; i++) {
76-
*cdest++ = *csrc++;
77-
}
78-
}
79-
80-
return dest;
81-
}
82-
8357
void *memset(void *dest, int c, size_t size)
8458
{
8559
unsigned char *d = (unsigned char *)dest;

pc-bios/vof/main.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ void do_boot(unsigned long addr, unsigned long _r3, unsigned long _r4)
66
register unsigned long r4 __asm__("r4") = _r4;
77
register unsigned long r5 __asm__("r5") = (unsigned long) _prom_entry;
88

9-
((client *)(uint32_t)addr)();
9+
((void (*)(void))(uint32_t)addr)();
1010
}
1111

1212
void entry_c(void)

pc-bios/vof/vof.h

-2
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,9 @@ typedef unsigned short uint16_t;
1010
typedef unsigned long uint32_t;
1111
typedef unsigned long long uint64_t;
1212
#define NULL (0)
13-
#define PROM_ERROR (-1u)
1413
typedef unsigned long ihandle;
1514
typedef unsigned long phandle;
1615
typedef int size_t;
17-
typedef void client(void);
1816

1917
/* globals */
2018
extern void _prom_entry(void); /* OF CI entry point (i.e. this firmware) */

0 commit comments

Comments
 (0)