ppc patch queue 2021-07-29
Here's a small batch of bufixes for the ppc target to go into qemu-6.1. -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEdfRlhq5hpmzETofcbDjKyiDZs5IFAmECUiwACgkQbDjKyiDZ s5KcpBAAzDaoqteNlv1pVhsZaEL7vX0IG/zHF79GpsLZVtu/LH6p60O5+jeMcryc hhIpdOB7wPZ6yf/nEGa/slh6DcLQ8Muw606JFD5BmsiF3lZpUHCCkIhq7VlJCeLf HuwLfa4u7SLg03sAnqNdejpj61AQmOGogBN8INT09mRU/cQksu4HAJcIM9yEI7Q4 v3mbseid6+actzbfsVlwhIf8W4tadYjhAGqG4fTB/ayyluThcCHNHXmTpOX83tzN 99C0IV7l0t6LKEGOHBW/JuHecp1vjEXAoMxIKKISTD41Mmr0iQ4W0Oth4TTYghqY a9GJInw9AHxWMOHxoSG1kqEMt4xYeWXowlfDZA7dmIhOJ2hGHIkkAlKbp7ablDcA aLAKDec2f7Y3MtaTUKeu1s6vFSxy3wAkYOzJoUpdzUb1PmGhVVEAdESwXh1AoUKE 2H6z2q5fyiGsesn6HlxxD7Z4pqBgZLHGNr2vZn1tPaLjHccsYiL97DWGBwftades Byhq23qsjLoqUJ2BYt+U1q4vl1ciFeUlk6YBEDjrNnYxVksK/AO2MChottvpALMy 119OyZbPpQNuT5/yst0i1SVQFIcku8Mk2tTTCOG0tgVAl9n5mZoF0i+I8EhStEec zVRkzVtNEKHhGyMQThb8RZuBxp8Hg70TyQfZJHkTrMS5dBzpPP0= =fFyx -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/dg-gitlab/tags/ppc-for-6.1-20210729' into staging ppc patch queue 2021-07-29 Here's a small batch of bufixes for the ppc target to go into qemu-6.1. # gpg: Signature made Thu 29 Jul 2021 08:01:00 BST # gpg: using RSA key 75F46586AE61A66CC44E87DC6C38CACA20D9B392 # gpg: Good signature from "David Gibson <david@gibson.dropbear.id.au>" [full] # gpg: aka "David Gibson (Red Hat) <dgibson@redhat.com>" [full] # gpg: aka "David Gibson (ozlabs.org) <dgibson@ozlabs.org>" [full] # gpg: aka "David Gibson (kernel.org) <dwg@kernel.org>" [unknown] # Primary key fingerprint: 75F4 6586 AE61 A66C C44E 87DC 6C38 CACA 20D9 B392 * remotes/dg-gitlab/tags/ppc-for-6.1-20210729: kvm: ppc: Print meaningful message on KVM_CREATE_VM failure ppc/vof: Fix Coverity issues target/ppc: Ease L=0 requirement on cmp/cmpi/cmpl/cmpli for ppc32 i2c/smbus_eeprom: Add feature bit to SPD data ppc/pegasos2: Fix spurious warning with -bios Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
efba2eebdf
|
@ -2397,6 +2397,12 @@ static int kvm_init(MachineState *ms)
|
||||||
"- for kernels supporting the vm.allocate_pgste sysctl, "
|
"- for kernels supporting the vm.allocate_pgste sysctl, "
|
||||||
"whether it is enabled\n");
|
"whether it is enabled\n");
|
||||||
}
|
}
|
||||||
|
#elif defined(TARGET_PPC)
|
||||||
|
if (ret == -EINVAL) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"PPC KVM module is not loaded. Try modprobe kvm_%s.\n",
|
||||||
|
(type == 2) ? "pr" : "hv");
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -276,7 +276,7 @@ uint8_t *spd_data_generate(enum sdram_type type, ram_addr_t ram_size)
|
||||||
spd[18] = 12; /* ~CAS latencies supported */
|
spd[18] = 12; /* ~CAS latencies supported */
|
||||||
spd[19] = (type == DDR2 ? 0 : 1); /* reserved / ~CS latencies supported */
|
spd[19] = (type == DDR2 ? 0 : 1); /* reserved / ~CS latencies supported */
|
||||||
spd[20] = 2; /* DIMM type / ~WE latencies */
|
spd[20] = 2; /* DIMM type / ~WE latencies */
|
||||||
/* module features */
|
spd[21] = (type < DDR2 ? 0x20 : 0); /* module features */
|
||||||
/* memory chip features */
|
/* memory chip features */
|
||||||
spd[23] = 0x12; /* clock cycle time @ medium CAS latency */
|
spd[23] = 0x12; /* clock cycle time @ medium CAS latency */
|
||||||
/* data access time */
|
/* data access time */
|
||||||
|
|
|
@ -191,7 +191,7 @@ static void pegasos2_init(MachineState *machine)
|
||||||
warn_report("Option -kernel may be ineffective with -bios.");
|
warn_report("Option -kernel may be ineffective with -bios.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (machine->kernel_cmdline && !pm->vof) {
|
if (!pm->vof && machine->kernel_cmdline && machine->kernel_cmdline[0]) {
|
||||||
warn_report("Option -append may be ineffective with -bios.");
|
warn_report("Option -append may be ineffective with -bios.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,8 +88,8 @@ vof_getproplen(uint32_t ph, const char *prop, uint32_t ret) "ph=0x%x \"%s\" => l
|
||||||
vof_setprop(uint32_t ph, const char *prop, const char *val, uint32_t vallen, uint32_t ret) "ph=0x%x \"%s\" [%s] len=%d => ret=%d"
|
vof_setprop(uint32_t ph, const char *prop, const char *val, uint32_t vallen, uint32_t ret) "ph=0x%x \"%s\" [%s] len=%d => ret=%d"
|
||||||
vof_open(const char *path, uint32_t ph, uint32_t ih) "%s ph=0x%x => ih=0x%x"
|
vof_open(const char *path, uint32_t ph, uint32_t ih) "%s ph=0x%x => ih=0x%x"
|
||||||
vof_interpret(const char *cmd, uint32_t param1, uint32_t param2, uint32_t ret, uint32_t ret2) "[%s] 0x%x 0x%x => 0x%x 0x%x"
|
vof_interpret(const char *cmd, uint32_t param1, uint32_t param2, uint32_t ret, uint32_t ret2) "[%s] 0x%x 0x%x => 0x%x 0x%x"
|
||||||
vof_package_to_path(uint32_t ph, const char *tmp, uint32_t ret) "ph=0x%x => %s len=%d"
|
vof_package_to_path(uint32_t ph, const char *tmp, int ret) "ph=0x%x => %s len=%d"
|
||||||
vof_instance_to_path(uint32_t ih, uint32_t ph, const char *tmp, uint32_t ret) "ih=0x%x ph=0x%x => %s len=%d"
|
vof_instance_to_path(uint32_t ih, uint32_t ph, const char *tmp, int ret) "ih=0x%x ph=0x%x => %s len=%d"
|
||||||
vof_instance_to_package(uint32_t ih, uint32_t ph) "ih=0x%x => ph=0x%x"
|
vof_instance_to_package(uint32_t ih, uint32_t ph) "ih=0x%x => ph=0x%x"
|
||||||
vof_write(uint32_t ih, unsigned cb, const char *msg) "ih=0x%x [%u] \"%s\""
|
vof_write(uint32_t ih, unsigned cb, const char *msg) "ih=0x%x [%u] \"%s\""
|
||||||
vof_avail(uint64_t start, uint64_t end, uint64_t size) "0x%"PRIx64"..0x%"PRIx64" size=0x%"PRIx64
|
vof_avail(uint64_t start, uint64_t end, uint64_t size) "0x%"PRIx64"..0x%"PRIx64" size=0x%"PRIx64
|
||||||
|
|
139
hw/ppc/vof.c
139
hw/ppc/vof.c
|
@ -160,7 +160,7 @@ static int path_offset(const void *fdt, const char *path)
|
||||||
static uint32_t vof_finddevice(const void *fdt, uint32_t nodeaddr)
|
static uint32_t vof_finddevice(const void *fdt, uint32_t nodeaddr)
|
||||||
{
|
{
|
||||||
char fullnode[VOF_MAX_PATH];
|
char fullnode[VOF_MAX_PATH];
|
||||||
uint32_t ret = -1;
|
uint32_t ret = PROM_ERROR;
|
||||||
int offset;
|
int offset;
|
||||||
|
|
||||||
if (readstr(nodeaddr, fullnode, sizeof(fullnode))) {
|
if (readstr(nodeaddr, fullnode, sizeof(fullnode))) {
|
||||||
|
@ -172,7 +172,7 @@ static uint32_t vof_finddevice(const void *fdt, uint32_t nodeaddr)
|
||||||
ret = fdt_get_phandle(fdt, offset);
|
ret = fdt_get_phandle(fdt, offset);
|
||||||
}
|
}
|
||||||
trace_vof_finddevice(fullnode, ret);
|
trace_vof_finddevice(fullnode, ret);
|
||||||
return (uint32_t) ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const void *getprop(const void *fdt, int nodeoff, const char *propname,
|
static const void *getprop(const void *fdt, int nodeoff, const char *propname,
|
||||||
|
@ -229,10 +229,10 @@ static uint32_t vof_getprop(const void *fdt, uint32_t nodeph, uint32_t pname,
|
||||||
bool write0;
|
bool write0;
|
||||||
|
|
||||||
if (nodeoff < 0) {
|
if (nodeoff < 0) {
|
||||||
return -1;
|
return PROM_ERROR;
|
||||||
}
|
}
|
||||||
if (readstr(pname, propname, sizeof(propname))) {
|
if (readstr(pname, propname, sizeof(propname))) {
|
||||||
return -1;
|
return PROM_ERROR;
|
||||||
}
|
}
|
||||||
prop = getprop(fdt, nodeoff, propname, &proplen, &write0);
|
prop = getprop(fdt, nodeoff, propname, &proplen, &write0);
|
||||||
if (prop) {
|
if (prop) {
|
||||||
|
@ -244,7 +244,7 @@ static uint32_t vof_getprop(const void *fdt, uint32_t nodeph, uint32_t pname,
|
||||||
(write0 &&
|
(write0 &&
|
||||||
cb == proplen &&
|
cb == proplen &&
|
||||||
VOF_MEM_WRITE(valaddr + cb - 1, &zero, 1) != MEMTX_OK)) {
|
VOF_MEM_WRITE(valaddr + cb - 1, &zero, 1) != MEMTX_OK)) {
|
||||||
ret = -1;
|
ret = PROM_ERROR;
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* OF1275 says:
|
* OF1275 says:
|
||||||
|
@ -259,7 +259,7 @@ static uint32_t vof_getprop(const void *fdt, uint32_t nodeph, uint32_t pname,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ret = -1;
|
ret = PROM_ERROR;
|
||||||
}
|
}
|
||||||
trace_vof_getprop(nodeph, propname, ret, trval);
|
trace_vof_getprop(nodeph, propname, ret, trval);
|
||||||
|
|
||||||
|
@ -275,16 +275,16 @@ static uint32_t vof_getproplen(const void *fdt, uint32_t nodeph, uint32_t pname)
|
||||||
int nodeoff = fdt_node_offset_by_phandle(fdt, nodeph);
|
int nodeoff = fdt_node_offset_by_phandle(fdt, nodeph);
|
||||||
|
|
||||||
if (nodeoff < 0) {
|
if (nodeoff < 0) {
|
||||||
return -1;
|
return PROM_ERROR;
|
||||||
}
|
}
|
||||||
if (readstr(pname, propname, sizeof(propname))) {
|
if (readstr(pname, propname, sizeof(propname))) {
|
||||||
return -1;
|
return PROM_ERROR;
|
||||||
}
|
}
|
||||||
prop = getprop(fdt, nodeoff, propname, &proplen, NULL);
|
prop = getprop(fdt, nodeoff, propname, &proplen, NULL);
|
||||||
if (prop) {
|
if (prop) {
|
||||||
ret = proplen;
|
ret = proplen;
|
||||||
} else {
|
} else {
|
||||||
ret = -1;
|
ret = PROM_ERROR;
|
||||||
}
|
}
|
||||||
trace_vof_getproplen(nodeph, propname, ret);
|
trace_vof_getproplen(nodeph, propname, ret);
|
||||||
|
|
||||||
|
@ -296,8 +296,8 @@ static uint32_t vof_setprop(MachineState *ms, void *fdt, Vof *vof,
|
||||||
uint32_t valaddr, uint32_t vallen)
|
uint32_t valaddr, uint32_t vallen)
|
||||||
{
|
{
|
||||||
char propname[OF_PROPNAME_LEN_MAX + 1];
|
char propname[OF_PROPNAME_LEN_MAX + 1];
|
||||||
uint32_t ret = -1;
|
uint32_t ret = PROM_ERROR;
|
||||||
int offset;
|
int offset, rc;
|
||||||
char trval[64] = "";
|
char trval[64] = "";
|
||||||
char nodepath[VOF_MAX_PATH] = "";
|
char nodepath[VOF_MAX_PATH] = "";
|
||||||
Object *vmo = object_dynamic_cast(OBJECT(ms), TYPE_VOF_MACHINE_IF);
|
Object *vmo = object_dynamic_cast(OBJECT(ms), TYPE_VOF_MACHINE_IF);
|
||||||
|
@ -314,8 +314,8 @@ static uint32_t vof_setprop(MachineState *ms, void *fdt, Vof *vof,
|
||||||
if (offset < 0) {
|
if (offset < 0) {
|
||||||
goto trace_exit;
|
goto trace_exit;
|
||||||
}
|
}
|
||||||
ret = get_path(fdt, offset, nodepath, sizeof(nodepath));
|
rc = get_path(fdt, offset, nodepath, sizeof(nodepath));
|
||||||
if (ret <= 0) {
|
if (rc <= 0) {
|
||||||
goto trace_exit;
|
goto trace_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,8 +333,8 @@ static uint32_t vof_setprop(MachineState *ms, void *fdt, Vof *vof,
|
||||||
goto trace_exit;
|
goto trace_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = fdt_setprop(fdt, offset, propname, val, vallen);
|
rc = fdt_setprop(fdt, offset, propname, val, vallen);
|
||||||
if (ret) {
|
if (rc) {
|
||||||
goto trace_exit;
|
goto trace_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,7 +358,7 @@ static uint32_t vof_nextprop(const void *fdt, uint32_t phandle,
|
||||||
const char *tmp;
|
const char *tmp;
|
||||||
|
|
||||||
if (readstr(prevaddr, prev, sizeof(prev))) {
|
if (readstr(prevaddr, prev, sizeof(prev))) {
|
||||||
return -1;
|
return PROM_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
fdt_for_each_property_offset(offset, fdt, nodeoff) {
|
fdt_for_each_property_offset(offset, fdt, nodeoff) {
|
||||||
|
@ -377,7 +377,7 @@ static uint32_t vof_nextprop(const void *fdt, uint32_t phandle,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (VOF_MEM_WRITE(nameaddr, tmp, strlen(tmp) + 1) != MEMTX_OK) {
|
if (VOF_MEM_WRITE(nameaddr, tmp, strlen(tmp) + 1) != MEMTX_OK) {
|
||||||
return -1;
|
return PROM_ERROR;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -388,18 +388,17 @@ static uint32_t vof_nextprop(const void *fdt, uint32_t phandle,
|
||||||
|
|
||||||
static uint32_t vof_peer(const void *fdt, uint32_t phandle)
|
static uint32_t vof_peer(const void *fdt, uint32_t phandle)
|
||||||
{
|
{
|
||||||
int ret;
|
uint32_t ret = 0;
|
||||||
|
int rc;
|
||||||
|
|
||||||
if (phandle == 0) {
|
if (phandle == 0) {
|
||||||
ret = fdt_path_offset(fdt, "/");
|
rc = fdt_path_offset(fdt, "/");
|
||||||
} else {
|
} else {
|
||||||
ret = fdt_next_subnode(fdt, fdt_node_offset_by_phandle(fdt, phandle));
|
rc = fdt_next_subnode(fdt, fdt_node_offset_by_phandle(fdt, phandle));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret < 0) {
|
if (rc >= 0) {
|
||||||
ret = 0;
|
ret = fdt_get_phandle(fdt, rc);
|
||||||
} else {
|
|
||||||
ret = fdt_get_phandle(fdt, ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -407,12 +406,11 @@ static uint32_t vof_peer(const void *fdt, uint32_t phandle)
|
||||||
|
|
||||||
static uint32_t vof_child(const void *fdt, uint32_t phandle)
|
static uint32_t vof_child(const void *fdt, uint32_t phandle)
|
||||||
{
|
{
|
||||||
int ret = fdt_first_subnode(fdt, fdt_node_offset_by_phandle(fdt, phandle));
|
uint32_t ret = 0;
|
||||||
|
int rc = fdt_first_subnode(fdt, fdt_node_offset_by_phandle(fdt, phandle));
|
||||||
|
|
||||||
if (ret < 0) {
|
if (rc >= 0) {
|
||||||
ret = 0;
|
ret = fdt_get_phandle(fdt, rc);
|
||||||
} else {
|
|
||||||
ret = fdt_get_phandle(fdt, ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -420,12 +418,11 @@ static uint32_t vof_child(const void *fdt, uint32_t phandle)
|
||||||
|
|
||||||
static uint32_t vof_parent(const void *fdt, uint32_t phandle)
|
static uint32_t vof_parent(const void *fdt, uint32_t phandle)
|
||||||
{
|
{
|
||||||
int ret = fdt_parent_offset(fdt, fdt_node_offset_by_phandle(fdt, phandle));
|
uint32_t ret = 0;
|
||||||
|
int rc = fdt_parent_offset(fdt, fdt_node_offset_by_phandle(fdt, phandle));
|
||||||
|
|
||||||
if (ret < 0) {
|
if (rc >= 0) {
|
||||||
ret = 0;
|
ret = fdt_get_phandle(fdt, rc);
|
||||||
} else {
|
|
||||||
ret = fdt_get_phandle(fdt, ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -433,7 +430,7 @@ static uint32_t vof_parent(const void *fdt, uint32_t phandle)
|
||||||
|
|
||||||
static uint32_t vof_do_open(void *fdt, Vof *vof, int offset, const char *path)
|
static uint32_t vof_do_open(void *fdt, Vof *vof, int offset, const char *path)
|
||||||
{
|
{
|
||||||
uint32_t ret = -1;
|
uint32_t ret = PROM_ERROR;
|
||||||
OfInstance *inst = NULL;
|
OfInstance *inst = NULL;
|
||||||
|
|
||||||
if (vof->of_instance_last == 0xFFFFFFFF) {
|
if (vof->of_instance_last == 0xFFFFFFFF) {
|
||||||
|
@ -461,18 +458,18 @@ trace_exit:
|
||||||
uint32_t vof_client_open_store(void *fdt, Vof *vof, const char *nodename,
|
uint32_t vof_client_open_store(void *fdt, Vof *vof, const char *nodename,
|
||||||
const char *prop, const char *path)
|
const char *prop, const char *path)
|
||||||
{
|
{
|
||||||
int node = fdt_path_offset(fdt, nodename);
|
int offset, node = fdt_path_offset(fdt, nodename);
|
||||||
int inst, offset;
|
uint32_t inst;
|
||||||
|
|
||||||
offset = fdt_path_offset(fdt, path);
|
offset = fdt_path_offset(fdt, path);
|
||||||
if (offset < 0) {
|
if (offset < 0) {
|
||||||
trace_vof_error_unknown_path(path);
|
trace_vof_error_unknown_path(path);
|
||||||
return offset;
|
return PROM_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
inst = vof_do_open(fdt, vof, offset, path);
|
inst = vof_do_open(fdt, vof, offset, path);
|
||||||
|
|
||||||
return fdt_setprop_cell(fdt, node, prop, inst);
|
return fdt_setprop_cell(fdt, node, prop, inst) >= 0 ? 0 : PROM_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t vof_open(void *fdt, Vof *vof, uint32_t pathaddr)
|
static uint32_t vof_open(void *fdt, Vof *vof, uint32_t pathaddr)
|
||||||
|
@ -481,13 +478,13 @@ static uint32_t vof_open(void *fdt, Vof *vof, uint32_t pathaddr)
|
||||||
int offset;
|
int offset;
|
||||||
|
|
||||||
if (readstr(pathaddr, path, sizeof(path))) {
|
if (readstr(pathaddr, path, sizeof(path))) {
|
||||||
return -1;
|
return PROM_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
offset = path_offset(fdt, path);
|
offset = path_offset(fdt, path);
|
||||||
if (offset < 0) {
|
if (offset < 0) {
|
||||||
trace_vof_error_unknown_path(path);
|
trace_vof_error_unknown_path(path);
|
||||||
return offset;
|
return PROM_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return vof_do_open(fdt, vof, offset, path);
|
return vof_do_open(fdt, vof, offset, path);
|
||||||
|
@ -504,7 +501,7 @@ static uint32_t vof_instance_to_package(Vof *vof, uint32_t ihandle)
|
||||||
{
|
{
|
||||||
gpointer instp = g_hash_table_lookup(vof->of_instances,
|
gpointer instp = g_hash_table_lookup(vof->of_instances,
|
||||||
GINT_TO_POINTER(ihandle));
|
GINT_TO_POINTER(ihandle));
|
||||||
uint32_t ret = -1;
|
uint32_t ret = PROM_ERROR;
|
||||||
|
|
||||||
if (instp) {
|
if (instp) {
|
||||||
ret = ((OfInstance *)instp)->phandle;
|
ret = ((OfInstance *)instp)->phandle;
|
||||||
|
@ -517,39 +514,39 @@ static uint32_t vof_instance_to_package(Vof *vof, uint32_t ihandle)
|
||||||
static uint32_t vof_package_to_path(const void *fdt, uint32_t phandle,
|
static uint32_t vof_package_to_path(const void *fdt, uint32_t phandle,
|
||||||
uint32_t buf, uint32_t len)
|
uint32_t buf, uint32_t len)
|
||||||
{
|
{
|
||||||
uint32_t ret = -1;
|
int rc;
|
||||||
char tmp[VOF_MAX_PATH] = "";
|
char tmp[VOF_MAX_PATH] = "";
|
||||||
|
|
||||||
ret = phandle_to_path(fdt, phandle, tmp, sizeof(tmp));
|
rc = phandle_to_path(fdt, phandle, tmp, sizeof(tmp));
|
||||||
if (ret > 0) {
|
if (rc > 0) {
|
||||||
if (VOF_MEM_WRITE(buf, tmp, ret) != MEMTX_OK) {
|
if (VOF_MEM_WRITE(buf, tmp, rc) != MEMTX_OK) {
|
||||||
ret = -1;
|
rc = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trace_vof_package_to_path(phandle, tmp, ret);
|
trace_vof_package_to_path(phandle, tmp, rc);
|
||||||
|
|
||||||
return ret;
|
return rc > 0 ? (uint32_t)rc : PROM_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t vof_instance_to_path(void *fdt, Vof *vof, uint32_t ihandle,
|
static uint32_t vof_instance_to_path(void *fdt, Vof *vof, uint32_t ihandle,
|
||||||
uint32_t buf, uint32_t len)
|
uint32_t buf, uint32_t len)
|
||||||
{
|
{
|
||||||
uint32_t ret = -1;
|
int rc = -1;
|
||||||
uint32_t phandle = vof_instance_to_package(vof, ihandle);
|
uint32_t phandle = vof_instance_to_package(vof, ihandle);
|
||||||
char tmp[VOF_MAX_PATH] = "";
|
char tmp[VOF_MAX_PATH] = "";
|
||||||
|
|
||||||
if (phandle != -1) {
|
if (phandle != -1) {
|
||||||
ret = phandle_to_path(fdt, phandle, tmp, sizeof(tmp));
|
rc = phandle_to_path(fdt, phandle, tmp, sizeof(tmp));
|
||||||
if (ret > 0) {
|
if (rc > 0) {
|
||||||
if (VOF_MEM_WRITE(buf, tmp, ret) != MEMTX_OK) {
|
if (VOF_MEM_WRITE(buf, tmp, rc) != MEMTX_OK) {
|
||||||
ret = -1;
|
rc = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
trace_vof_instance_to_path(ihandle, phandle, tmp, ret);
|
trace_vof_instance_to_path(ihandle, phandle, tmp, rc);
|
||||||
|
|
||||||
return ret;
|
return rc > 0 ? (uint32_t)rc : PROM_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t vof_write(Vof *vof, uint32_t ihandle, uint32_t buf,
|
static uint32_t vof_write(Vof *vof, uint32_t ihandle, uint32_t buf,
|
||||||
|
@ -562,13 +559,13 @@ static uint32_t vof_write(Vof *vof, uint32_t ihandle, uint32_t buf,
|
||||||
|
|
||||||
if (!inst) {
|
if (!inst) {
|
||||||
trace_vof_error_write(ihandle);
|
trace_vof_error_write(ihandle);
|
||||||
return -1;
|
return PROM_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( ; len > 0; len -= cb) {
|
for ( ; len > 0; len -= cb) {
|
||||||
cb = MIN(len, sizeof(tmp) - 1);
|
cb = MIN(len, sizeof(tmp) - 1);
|
||||||
if (VOF_MEM_READ(buf, tmp, cb) != MEMTX_OK) {
|
if (VOF_MEM_READ(buf, tmp, cb) != MEMTX_OK) {
|
||||||
return -1;
|
return PROM_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: there is no backend(s) yet so just call a trace */
|
/* FIXME: there is no backend(s) yet so just call a trace */
|
||||||
|
@ -747,7 +744,7 @@ uint64_t vof_claim(Vof *vof, uint64_t virt, uint64_t size,
|
||||||
|
|
||||||
static uint32_t vof_release(Vof *vof, uint64_t virt, uint64_t size)
|
static uint32_t vof_release(Vof *vof, uint64_t virt, uint64_t size)
|
||||||
{
|
{
|
||||||
uint32_t ret = -1;
|
uint32_t ret = PROM_ERROR;
|
||||||
int i;
|
int i;
|
||||||
GArray *claimed = vof->claimed;
|
GArray *claimed = vof->claimed;
|
||||||
OfClaimed c;
|
OfClaimed c;
|
||||||
|
@ -776,7 +773,7 @@ static uint32_t vof_call_method(MachineState *ms, Vof *vof, uint32_t methodaddr,
|
||||||
uint32_t param2, uint32_t param3,
|
uint32_t param2, uint32_t param3,
|
||||||
uint32_t param4, uint32_t *ret2)
|
uint32_t param4, uint32_t *ret2)
|
||||||
{
|
{
|
||||||
uint32_t ret = -1;
|
uint32_t ret = PROM_ERROR;
|
||||||
char method[VOF_MAX_METHODLEN] = "";
|
char method[VOF_MAX_METHODLEN] = "";
|
||||||
OfInstance *inst;
|
OfInstance *inst;
|
||||||
|
|
||||||
|
@ -802,7 +799,8 @@ static uint32_t vof_call_method(MachineState *ms, Vof *vof, uint32_t methodaddr,
|
||||||
VofMachineIfClass *vmc = VOF_MACHINE_GET_CLASS(vmo);
|
VofMachineIfClass *vmc = VOF_MACHINE_GET_CLASS(vmo);
|
||||||
|
|
||||||
g_assert(vmc->client_architecture_support);
|
g_assert(vmc->client_architecture_support);
|
||||||
ret = vmc->client_architecture_support(ms, first_cpu, param1);
|
ret = (uint32_t)vmc->client_architecture_support(ms, first_cpu,
|
||||||
|
param1);
|
||||||
}
|
}
|
||||||
|
|
||||||
*ret2 = 0;
|
*ret2 = 0;
|
||||||
|
@ -826,7 +824,7 @@ trace_exit:
|
||||||
static uint32_t vof_call_interpret(uint32_t cmdaddr, uint32_t param1,
|
static uint32_t vof_call_interpret(uint32_t cmdaddr, uint32_t param1,
|
||||||
uint32_t param2, uint32_t *ret2)
|
uint32_t param2, uint32_t *ret2)
|
||||||
{
|
{
|
||||||
uint32_t ret = -1;
|
uint32_t ret = PROM_ERROR;
|
||||||
char cmd[VOF_MAX_FORTHCODE] = "";
|
char cmd[VOF_MAX_FORTHCODE] = "";
|
||||||
|
|
||||||
/* No interpret implemented so just call a trace */
|
/* No interpret implemented so just call a trace */
|
||||||
|
@ -895,13 +893,20 @@ static uint32_t vof_client_handle(MachineState *ms, void *fdt, Vof *vof,
|
||||||
} else if (cmpserv("write", 3, 1)) {
|
} else if (cmpserv("write", 3, 1)) {
|
||||||
ret = vof_write(vof, args[0], args[1], args[2]);
|
ret = vof_write(vof, args[0], args[1], args[2]);
|
||||||
} else if (cmpserv("claim", 3, 1)) {
|
} else if (cmpserv("claim", 3, 1)) {
|
||||||
ret = vof_claim(vof, args[0], args[1], args[2]);
|
uint64_t ret64 = vof_claim(vof, args[0], args[1], args[2]);
|
||||||
if (ret != -1) {
|
|
||||||
|
if (ret64 < 0x100000000UL) {
|
||||||
vof_dt_memory_available(fdt, vof->claimed, vof->claimed_base);
|
vof_dt_memory_available(fdt, vof->claimed, vof->claimed_base);
|
||||||
|
ret = (uint32_t)ret64;
|
||||||
|
} else {
|
||||||
|
if (ret64 != -1) {
|
||||||
|
vof_release(vof, ret, args[1]);
|
||||||
|
}
|
||||||
|
ret = PROM_ERROR;
|
||||||
}
|
}
|
||||||
} else if (cmpserv("release", 2, 0)) {
|
} else if (cmpserv("release", 2, 0)) {
|
||||||
ret = vof_release(vof, args[0], args[1]);
|
ret = vof_release(vof, args[0], args[1]);
|
||||||
if (ret != -1) {
|
if (ret != PROM_ERROR) {
|
||||||
vof_dt_memory_available(fdt, vof->claimed, vof->claimed_base);
|
vof_dt_memory_available(fdt, vof->claimed, vof->claimed_base);
|
||||||
}
|
}
|
||||||
} else if (cmpserv("call-method", 0, 0)) {
|
} else if (cmpserv("call-method", 0, 0)) {
|
||||||
|
@ -965,11 +970,15 @@ int vof_client_call(MachineState *ms, Vof *vof, void *fdt,
|
||||||
}
|
}
|
||||||
|
|
||||||
nret = be32_to_cpu(args_be.nret);
|
nret = be32_to_cpu(args_be.nret);
|
||||||
|
if (nret > ARRAY_SIZE(args_be.args) - nargs) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
ret = vof_client_handle(ms, fdt, vof, service, args, nargs, rets, nret);
|
ret = vof_client_handle(ms, fdt, vof, service, args, nargs, rets, nret);
|
||||||
if (!nret) {
|
if (!nret) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* @nrets includes the value which this function returns */
|
||||||
args_be.args[nargs] = cpu_to_be32(ret);
|
args_be.args[nargs] = cpu_to_be32(ret);
|
||||||
for (i = 1; i < nret; ++i) {
|
for (i = 1; i < nret; ++i) {
|
||||||
args_be.args[nargs + i] = cpu_to_be32(rets[i - 1]);
|
args_be.args[nargs + i] = cpu_to_be32(rets[i - 1]);
|
||||||
|
|
|
@ -55,4 +55,6 @@ struct VofMachineIfClass {
|
||||||
address_space_write(&address_space_memory, \
|
address_space_write(&address_space_memory, \
|
||||||
(pa), MEMTXATTRS_UNSPECIFIED, (buf), (size))
|
(pa), MEMTXATTRS_UNSPECIFIED, (buf), (size))
|
||||||
|
|
||||||
|
#define PROM_ERROR (~0U)
|
||||||
|
|
||||||
#endif /* HW_VOF_H */
|
#endif /* HW_VOF_H */
|
||||||
|
|
|
@ -171,8 +171,35 @@ TRANS64(PSTD, do_ldst_PLS_D, false, true, MO_Q)
|
||||||
|
|
||||||
static bool do_cmp_X(DisasContext *ctx, arg_X_bfl *a, bool s)
|
static bool do_cmp_X(DisasContext *ctx, arg_X_bfl *a, bool s)
|
||||||
{
|
{
|
||||||
|
if ((ctx->insns_flags & PPC_64B) == 0) {
|
||||||
|
/*
|
||||||
|
* For 32-bit implementations, The Programming Environments Manual says
|
||||||
|
* that "the L field must be cleared, otherwise the instruction form is
|
||||||
|
* invalid." It seems, however, that most 32-bit CPUs ignore invalid
|
||||||
|
* forms (e.g., section "Instruction Formats" of the 405 and 440
|
||||||
|
* manuals, "Integer Compare Instructions" of the 601 manual), with the
|
||||||
|
* notable exception of the e500 and e500mc, where L=1 was reported to
|
||||||
|
* cause an exception.
|
||||||
|
*/
|
||||||
|
if (a->l) {
|
||||||
|
if ((ctx->insns_flags2 & PPC2_BOOKE206)) {
|
||||||
|
/*
|
||||||
|
* For 32-bit Book E v2.06 implementations (i.e. e500/e500mc),
|
||||||
|
* generate an illegal instruction exception.
|
||||||
|
*/
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
qemu_log_mask(LOG_GUEST_ERROR,
|
||||||
|
"Invalid form of CMP%s at 0x" TARGET_FMT_lx ", L = 1\n",
|
||||||
|
s ? "" : "L", ctx->cia);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gen_op_cmp32(cpu_gpr[a->ra], cpu_gpr[a->rb], s, a->bf);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For 64-bit implementations, deal with bit L accordingly. */
|
||||||
if (a->l) {
|
if (a->l) {
|
||||||
REQUIRE_64BIT(ctx);
|
|
||||||
gen_op_cmp(cpu_gpr[a->ra], cpu_gpr[a->rb], s, a->bf);
|
gen_op_cmp(cpu_gpr[a->ra], cpu_gpr[a->rb], s, a->bf);
|
||||||
} else {
|
} else {
|
||||||
gen_op_cmp32(cpu_gpr[a->ra], cpu_gpr[a->rb], s, a->bf);
|
gen_op_cmp32(cpu_gpr[a->ra], cpu_gpr[a->rb], s, a->bf);
|
||||||
|
@ -182,8 +209,35 @@ static bool do_cmp_X(DisasContext *ctx, arg_X_bfl *a, bool s)
|
||||||
|
|
||||||
static bool do_cmp_D(DisasContext *ctx, arg_D_bf *a, bool s)
|
static bool do_cmp_D(DisasContext *ctx, arg_D_bf *a, bool s)
|
||||||
{
|
{
|
||||||
|
if ((ctx->insns_flags & PPC_64B) == 0) {
|
||||||
|
/*
|
||||||
|
* For 32-bit implementations, The Programming Environments Manual says
|
||||||
|
* that "the L field must be cleared, otherwise the instruction form is
|
||||||
|
* invalid." It seems, however, that most 32-bit CPUs ignore invalid
|
||||||
|
* forms (e.g., section "Instruction Formats" of the 405 and 440
|
||||||
|
* manuals, "Integer Compare Instructions" of the 601 manual), with the
|
||||||
|
* notable exception of the e500 and e500mc, where L=1 was reported to
|
||||||
|
* cause an exception.
|
||||||
|
*/
|
||||||
|
if (a->l) {
|
||||||
|
if ((ctx->insns_flags2 & PPC2_BOOKE206)) {
|
||||||
|
/*
|
||||||
|
* For 32-bit Book E v2.06 implementations (i.e. e500/e500mc),
|
||||||
|
* generate an illegal instruction exception.
|
||||||
|
*/
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
qemu_log_mask(LOG_GUEST_ERROR,
|
||||||
|
"Invalid form of CMP%s at 0x" TARGET_FMT_lx ", L = 1\n",
|
||||||
|
s ? "I" : "LI", ctx->cia);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gen_op_cmp32(cpu_gpr[a->ra], tcg_constant_tl(a->imm), s, a->bf);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For 64-bit implementations, deal with bit L accordingly. */
|
||||||
if (a->l) {
|
if (a->l) {
|
||||||
REQUIRE_64BIT(ctx);
|
|
||||||
gen_op_cmp(cpu_gpr[a->ra], tcg_constant_tl(a->imm), s, a->bf);
|
gen_op_cmp(cpu_gpr[a->ra], tcg_constant_tl(a->imm), s, a->bf);
|
||||||
} else {
|
} else {
|
||||||
gen_op_cmp32(cpu_gpr[a->ra], tcg_constant_tl(a->imm), s, a->bf);
|
gen_op_cmp32(cpu_gpr[a->ra], tcg_constant_tl(a->imm), s, a->bf);
|
||||||
|
|
Loading…
Reference in a new issue