* [kvm-unit-tests PATCH] powerpc: Rework the rtas_token() function
@ 2017-05-31 11:15 Thomas Huth
2017-05-31 11:58 ` Andrew Jones
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Thomas Huth @ 2017-05-31 11:15 UTC (permalink / raw)
To: kvm; +Cc: kvm-ppc, Laurent Vivier, Paolo Bonzini,
Radim Krčmář
RTAS tokens can have any value, also 0xffffffff is theoretically
allowed (which is currently used for the RTAS_UNKNOWN_SERVICE error
code). Thus we should not mix error codes and tokens in the return
value here and return the token value via a pointer parameter
instead.
This patch also adds a check to rtas_token() to test whether the device
tree is available at all. This fixes a possible endless loop that
happens without device tree, spamming the console with "rtas_node:
/rtas: FDT_ERR_BADMAGIC" messages: Somewhere the code calls abort()
due to the missing device tree, and abort() calls exit() which in
turn tries to shut down the VM with rtas_power_off(). rtas_power_off()
needs the device tree again to look up the right RTAS token, where we
then end up in the next iteration.
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
lib/powerpc/asm/rtas.h | 2 +-
lib/powerpc/rtas.c | 30 ++++++++++++++++++++++--------
lib/powerpc/smp.c | 11 ++++++-----
powerpc/rtas.c | 24 +++++++++++++-----------
4 files changed, 42 insertions(+), 25 deletions(-)
diff --git a/lib/powerpc/asm/rtas.h b/lib/powerpc/asm/rtas.h
index 9012a1e..6fb407a 100644
--- a/lib/powerpc/asm/rtas.h
+++ b/lib/powerpc/asm/rtas.h
@@ -21,7 +21,7 @@ struct rtas_args {
};
extern void rtas_init(void);
-extern int rtas_token(const char *service);
+extern int rtas_token(const char *service, uint32_t *token);
extern int rtas_call(int token, int nargs, int nret, int *outputs, ...);
extern void rtas_power_off(void);
diff --git a/lib/powerpc/rtas.c b/lib/powerpc/rtas.c
index 3407e25..2e7e0da 100644
--- a/lib/powerpc/rtas.c
+++ b/lib/powerpc/rtas.c
@@ -69,17 +69,22 @@ void rtas_init(void)
}
}
-int rtas_token(const char *service)
+int rtas_token(const char *service, uint32_t *token)
{
const struct fdt_property *prop;
- u32 *token;
+ u32 *data;
+
+ if (!dt_available())
+ return RTAS_UNKNOWN_SERVICE;
prop = fdt_get_property(dt_fdt(), rtas_node(), service, NULL);
- if (prop) {
- token = (u32 *)prop->data;
- return fdt32_to_cpu(*token);
- }
- return RTAS_UNKNOWN_SERVICE;
+ if (!prop)
+ return RTAS_UNKNOWN_SERVICE;
+
+ data = (u32 *)prop->data;
+ *token = fdt32_to_cpu(*data);
+
+ return 0;
}
int rtas_call(int token, int nargs, int nret, int *outputs, ...)
@@ -116,6 +121,15 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...)
void rtas_power_off(void)
{
- int ret = rtas_call(rtas_token("power-off"), 2, 1, NULL, -1, -1);
+ uint32_t token;
+ int ret;
+
+ ret = rtas_token("power-off", &token);
+ if (ret) {
+ puts("RTAS power-off not available\n");
+ return;
+ }
+
+ ret = rtas_call(token, 2, 1, NULL, -1, -1);
printf("RTAS power-off returned %d\n", ret);
}
diff --git a/lib/powerpc/smp.c b/lib/powerpc/smp.c
index e18894b..afe4361 100644
--- a/lib/powerpc/smp.c
+++ b/lib/powerpc/smp.c
@@ -27,12 +27,13 @@ struct secondary_entry_data {
*/
int start_thread(int cpu_id, secondary_entry_fn entry, uint32_t r3)
{
- int query_token, start_token, outputs[1], ret;
+ uint32_t query_token, start_token;
+ int outputs[1], ret;
- query_token = rtas_token("query-cpu-stopped-state");
- start_token = rtas_token("start-cpu");
- assert(query_token != RTAS_UNKNOWN_SERVICE &&
- start_token != RTAS_UNKNOWN_SERVICE);
+ ret = rtas_token("query-cpu-stopped-state", &query_token);
+ assert(ret == 0);
+ ret = rtas_token("start-cpu", &start_token);
+ assert(ret == 0);
ret = rtas_call(query_token, 1, 2, outputs, cpu_id);
if (ret) {
diff --git a/powerpc/rtas.c b/powerpc/rtas.c
index 1b1e9c7..5d43f33 100644
--- a/powerpc/rtas.c
+++ b/powerpc/rtas.c
@@ -39,14 +39,14 @@ static unsigned long mktime(int year, int month, int day,
static void check_get_time_of_day(unsigned long start)
{
- int token;
+ uint32_t token;
int ret;
int now[8];
unsigned long t1, t2, count;
- token = rtas_token("get-time-of-day");
- report("token available", token != RTAS_UNKNOWN_SERVICE);
- if (token == RTAS_UNKNOWN_SERVICE)
+ ret = rtas_token("get-time-of-day", &token);
+ report("token available", ret == 0);
+ if (ret)
return;
ret = rtas_call(token, 0, 8, now);
@@ -74,23 +74,25 @@ static void check_get_time_of_day(unsigned long start)
static void check_set_time_of_day(void)
{
- int token;
+ uint32_t stod_token, gtod_token;
int ret;
int date[8];
unsigned long t1, t2, count;
- token = rtas_token("set-time-of-day");
- report("token available", token != RTAS_UNKNOWN_SERVICE);
- if (token == RTAS_UNKNOWN_SERVICE)
+ ret = rtas_token("set-time-of-day", &stod_token);
+ report("token available", ret == 0);
+ if (ret)
return;
/* 23:59:59 28/2/2000 */
- ret = rtas_call(token, 7, 1, NULL, 2000, 2, 28, 23, 59, 59);
+ ret = rtas_call(stod_token, 7, 1, NULL, 2000, 2, 28, 23, 59, 59);
report("execution", ret == 0);
/* check it has worked */
- ret = rtas_call(rtas_token("get-time-of-day"), 0, 8, date);
+ ret = rtas_token("get-time-of-day", >od_token);
+ assert(ret == 0);
+ ret = rtas_call(gtod_token, 0, 8, date);
report("re-read", ret == 0);
t1 = mktime(2000, 2, 28, 23, 59, 59);
t2 = mktime(date[0], date[1], date[2],
@@ -100,7 +102,7 @@ static void check_set_time_of_day(void)
/* check it is running */
count = 0;
do {
- ret = rtas_call(rtas_token("get-time-of-day"), 0, 8, date);
+ ret = rtas_call(gtod_token, 0, 8, date);
t2 = mktime(date[0], date[1], date[2],
date[3], date[4], date[5]);
count++;
--
1.8.3.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [kvm-unit-tests PATCH] powerpc: Rework the rtas_token() function
2017-05-31 11:15 [kvm-unit-tests PATCH] powerpc: Rework the rtas_token() function Thomas Huth
@ 2017-05-31 11:58 ` Andrew Jones
2017-05-31 12:07 ` Laurent Vivier
2017-05-31 12:31 ` Paolo Bonzini
2 siblings, 0 replies; 4+ messages in thread
From: Andrew Jones @ 2017-05-31 11:58 UTC (permalink / raw)
To: Thomas Huth
Cc: kvm, kvm-ppc, Laurent Vivier, Paolo Bonzini,
Radim Krčmář
On Wed, May 31, 2017 at 01:15:38PM +0200, Thomas Huth wrote:
> RTAS tokens can have any value, also 0xffffffff is theoretically
> allowed (which is currently used for the RTAS_UNKNOWN_SERVICE error
> code). Thus we should not mix error codes and tokens in the return
> value here and return the token value via a pointer parameter
> instead.
>
> This patch also adds a check to rtas_token() to test whether the device
> tree is available at all. This fixes a possible endless loop that
> happens without device tree, spamming the console with "rtas_node:
> /rtas: FDT_ERR_BADMAGIC" messages: Somewhere the code calls abort()
> due to the missing device tree, and abort() calls exit() which in
> turn tries to shut down the VM with rtas_power_off(). rtas_power_off()
> needs the device tree again to look up the right RTAS token, where we
> then end up in the next iteration.
>
> Signed-off-by: Thomas Huth <thuth@redhat.com>
> ---
> lib/powerpc/asm/rtas.h | 2 +-
> lib/powerpc/rtas.c | 30 ++++++++++++++++++++++--------
> lib/powerpc/smp.c | 11 ++++++-----
> powerpc/rtas.c | 24 +++++++++++++-----------
> 4 files changed, 42 insertions(+), 25 deletions(-)
>
> diff --git a/lib/powerpc/asm/rtas.h b/lib/powerpc/asm/rtas.h
> index 9012a1e..6fb407a 100644
> --- a/lib/powerpc/asm/rtas.h
> +++ b/lib/powerpc/asm/rtas.h
> @@ -21,7 +21,7 @@ struct rtas_args {
> };
>
> extern void rtas_init(void);
> -extern int rtas_token(const char *service);
> +extern int rtas_token(const char *service, uint32_t *token);
> extern int rtas_call(int token, int nargs, int nret, int *outputs, ...);
>
> extern void rtas_power_off(void);
> diff --git a/lib/powerpc/rtas.c b/lib/powerpc/rtas.c
> index 3407e25..2e7e0da 100644
> --- a/lib/powerpc/rtas.c
> +++ b/lib/powerpc/rtas.c
> @@ -69,17 +69,22 @@ void rtas_init(void)
> }
> }
>
> -int rtas_token(const char *service)
> +int rtas_token(const char *service, uint32_t *token)
> {
> const struct fdt_property *prop;
> - u32 *token;
> + u32 *data;
> +
> + if (!dt_available())
> + return RTAS_UNKNOWN_SERVICE;
>
> prop = fdt_get_property(dt_fdt(), rtas_node(), service, NULL);
> - if (prop) {
> - token = (u32 *)prop->data;
> - return fdt32_to_cpu(*token);
> - }
> - return RTAS_UNKNOWN_SERVICE;
> + if (!prop)
> + return RTAS_UNKNOWN_SERVICE;
> +
> + data = (u32 *)prop->data;
> + *token = fdt32_to_cpu(*data);
> +
> + return 0;
> }
>
> int rtas_call(int token, int nargs, int nret, int *outputs, ...)
> @@ -116,6 +121,15 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...)
>
> void rtas_power_off(void)
> {
> - int ret = rtas_call(rtas_token("power-off"), 2, 1, NULL, -1, -1);
> + uint32_t token;
> + int ret;
> +
> + ret = rtas_token("power-off", &token);
> + if (ret) {
> + puts("RTAS power-off not available\n");
> + return;
> + }
> +
> + ret = rtas_call(token, 2, 1, NULL, -1, -1);
> printf("RTAS power-off returned %d\n", ret);
> }
> diff --git a/lib/powerpc/smp.c b/lib/powerpc/smp.c
> index e18894b..afe4361 100644
> --- a/lib/powerpc/smp.c
> +++ b/lib/powerpc/smp.c
> @@ -27,12 +27,13 @@ struct secondary_entry_data {
> */
> int start_thread(int cpu_id, secondary_entry_fn entry, uint32_t r3)
> {
> - int query_token, start_token, outputs[1], ret;
> + uint32_t query_token, start_token;
> + int outputs[1], ret;
>
> - query_token = rtas_token("query-cpu-stopped-state");
> - start_token = rtas_token("start-cpu");
> - assert(query_token != RTAS_UNKNOWN_SERVICE &&
> - start_token != RTAS_UNKNOWN_SERVICE);
> + ret = rtas_token("query-cpu-stopped-state", &query_token);
> + assert(ret == 0);
> + ret = rtas_token("start-cpu", &start_token);
> + assert(ret == 0);
>
> ret = rtas_call(query_token, 1, 2, outputs, cpu_id);
> if (ret) {
> diff --git a/powerpc/rtas.c b/powerpc/rtas.c
> index 1b1e9c7..5d43f33 100644
> --- a/powerpc/rtas.c
> +++ b/powerpc/rtas.c
> @@ -39,14 +39,14 @@ static unsigned long mktime(int year, int month, int day,
>
> static void check_get_time_of_day(unsigned long start)
> {
> - int token;
> + uint32_t token;
> int ret;
> int now[8];
> unsigned long t1, t2, count;
>
> - token = rtas_token("get-time-of-day");
> - report("token available", token != RTAS_UNKNOWN_SERVICE);
> - if (token == RTAS_UNKNOWN_SERVICE)
> + ret = rtas_token("get-time-of-day", &token);
> + report("token available", ret == 0);
> + if (ret)
> return;
>
> ret = rtas_call(token, 0, 8, now);
> @@ -74,23 +74,25 @@ static void check_get_time_of_day(unsigned long start)
>
> static void check_set_time_of_day(void)
> {
> - int token;
> + uint32_t stod_token, gtod_token;
> int ret;
> int date[8];
> unsigned long t1, t2, count;
>
> - token = rtas_token("set-time-of-day");
> - report("token available", token != RTAS_UNKNOWN_SERVICE);
> - if (token == RTAS_UNKNOWN_SERVICE)
> + ret = rtas_token("set-time-of-day", &stod_token);
> + report("token available", ret == 0);
> + if (ret)
> return;
>
> /* 23:59:59 28/2/2000 */
>
> - ret = rtas_call(token, 7, 1, NULL, 2000, 2, 28, 23, 59, 59);
> + ret = rtas_call(stod_token, 7, 1, NULL, 2000, 2, 28, 23, 59, 59);
> report("execution", ret == 0);
>
> /* check it has worked */
> - ret = rtas_call(rtas_token("get-time-of-day"), 0, 8, date);
> + ret = rtas_token("get-time-of-day", >od_token);
> + assert(ret == 0);
> + ret = rtas_call(gtod_token, 0, 8, date);
> report("re-read", ret == 0);
> t1 = mktime(2000, 2, 28, 23, 59, 59);
> t2 = mktime(date[0], date[1], date[2],
> @@ -100,7 +102,7 @@ static void check_set_time_of_day(void)
> /* check it is running */
> count = 0;
> do {
> - ret = rtas_call(rtas_token("get-time-of-day"), 0, 8, date);
> + ret = rtas_call(gtod_token, 0, 8, date);
> t2 = mktime(date[0], date[1], date[2],
> date[3], date[4], date[5]);
> count++;
> --
> 1.8.3.1
>
Reviewed-by: Andrew Jones <drjones@redhat.com>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [kvm-unit-tests PATCH] powerpc: Rework the rtas_token() function
2017-05-31 11:15 [kvm-unit-tests PATCH] powerpc: Rework the rtas_token() function Thomas Huth
2017-05-31 11:58 ` Andrew Jones
@ 2017-05-31 12:07 ` Laurent Vivier
2017-05-31 12:31 ` Paolo Bonzini
2 siblings, 0 replies; 4+ messages in thread
From: Laurent Vivier @ 2017-05-31 12:07 UTC (permalink / raw)
To: Thomas Huth, kvm; +Cc: kvm-ppc, Paolo Bonzini, Radim Krčmář
On 31/05/2017 13:15, Thomas Huth wrote:
> RTAS tokens can have any value, also 0xffffffff is theoretically
> allowed (which is currently used for the RTAS_UNKNOWN_SERVICE error
> code). Thus we should not mix error codes and tokens in the return
> value here and return the token value via a pointer parameter
> instead.
>
> This patch also adds a check to rtas_token() to test whether the device
> tree is available at all. This fixes a possible endless loop that
> happens without device tree, spamming the console with "rtas_node:
> /rtas: FDT_ERR_BADMAGIC" messages: Somewhere the code calls abort()
> due to the missing device tree, and abort() calls exit() which in
> turn tries to shut down the VM with rtas_power_off(). rtas_power_off()
> needs the device tree again to look up the right RTAS token, where we
> then end up in the next iteration.
>
> Signed-off-by: Thomas Huth <thuth@redhat.com>
> ---
> lib/powerpc/asm/rtas.h | 2 +-
> lib/powerpc/rtas.c | 30 ++++++++++++++++++++++--------
> lib/powerpc/smp.c | 11 ++++++-----
> powerpc/rtas.c | 24 +++++++++++++-----------
> 4 files changed, 42 insertions(+), 25 deletions(-)
>
> diff --git a/lib/powerpc/asm/rtas.h b/lib/powerpc/asm/rtas.h
> index 9012a1e..6fb407a 100644
> --- a/lib/powerpc/asm/rtas.h
> +++ b/lib/powerpc/asm/rtas.h
> @@ -21,7 +21,7 @@ struct rtas_args {
> };
>
> extern void rtas_init(void);
> -extern int rtas_token(const char *service);
> +extern int rtas_token(const char *service, uint32_t *token);
> extern int rtas_call(int token, int nargs, int nret, int *outputs, ...);
>
> extern void rtas_power_off(void);
> diff --git a/lib/powerpc/rtas.c b/lib/powerpc/rtas.c
> index 3407e25..2e7e0da 100644
> --- a/lib/powerpc/rtas.c
> +++ b/lib/powerpc/rtas.c
> @@ -69,17 +69,22 @@ void rtas_init(void)
> }
> }
>
> -int rtas_token(const char *service)
> +int rtas_token(const char *service, uint32_t *token)
> {
> const struct fdt_property *prop;
> - u32 *token;
> + u32 *data;
> +
> + if (!dt_available())
> + return RTAS_UNKNOWN_SERVICE;
>
> prop = fdt_get_property(dt_fdt(), rtas_node(), service, NULL);
> - if (prop) {
> - token = (u32 *)prop->data;
> - return fdt32_to_cpu(*token);
> - }
> - return RTAS_UNKNOWN_SERVICE;
> + if (!prop)
> + return RTAS_UNKNOWN_SERVICE;
> +
> + data = (u32 *)prop->data;
> + *token = fdt32_to_cpu(*data);
> +
> + return 0;
> }
>
> int rtas_call(int token, int nargs, int nret, int *outputs, ...)
> @@ -116,6 +121,15 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...)
>
> void rtas_power_off(void)
> {
> - int ret = rtas_call(rtas_token("power-off"), 2, 1, NULL, -1, -1);
> + uint32_t token;
> + int ret;
> +
> + ret = rtas_token("power-off", &token);
> + if (ret) {
> + puts("RTAS power-off not available\n");
> + return;
> + }
> +
> + ret = rtas_call(token, 2, 1, NULL, -1, -1);
> printf("RTAS power-off returned %d\n", ret);
> }
> diff --git a/lib/powerpc/smp.c b/lib/powerpc/smp.c
> index e18894b..afe4361 100644
> --- a/lib/powerpc/smp.c
> +++ b/lib/powerpc/smp.c
> @@ -27,12 +27,13 @@ struct secondary_entry_data {
> */
> int start_thread(int cpu_id, secondary_entry_fn entry, uint32_t r3)
> {
> - int query_token, start_token, outputs[1], ret;
> + uint32_t query_token, start_token;
> + int outputs[1], ret;
>
> - query_token = rtas_token("query-cpu-stopped-state");
> - start_token = rtas_token("start-cpu");
> - assert(query_token != RTAS_UNKNOWN_SERVICE &&
> - start_token != RTAS_UNKNOWN_SERVICE);
> + ret = rtas_token("query-cpu-stopped-state", &query_token);
> + assert(ret == 0);
> + ret = rtas_token("start-cpu", &start_token);
> + assert(ret == 0);
>
> ret = rtas_call(query_token, 1, 2, outputs, cpu_id);
> if (ret) {
> diff --git a/powerpc/rtas.c b/powerpc/rtas.c
> index 1b1e9c7..5d43f33 100644
> --- a/powerpc/rtas.c
> +++ b/powerpc/rtas.c
> @@ -39,14 +39,14 @@ static unsigned long mktime(int year, int month, int day,
>
> static void check_get_time_of_day(unsigned long start)
> {
> - int token;
> + uint32_t token;
> int ret;
> int now[8];
> unsigned long t1, t2, count;
>
> - token = rtas_token("get-time-of-day");
> - report("token available", token != RTAS_UNKNOWN_SERVICE);
> - if (token == RTAS_UNKNOWN_SERVICE)
> + ret = rtas_token("get-time-of-day", &token);
> + report("token available", ret == 0);
> + if (ret)
> return;
>
> ret = rtas_call(token, 0, 8, now);
> @@ -74,23 +74,25 @@ static void check_get_time_of_day(unsigned long start)
>
> static void check_set_time_of_day(void)
> {
> - int token;
> + uint32_t stod_token, gtod_token;
> int ret;
> int date[8];
> unsigned long t1, t2, count;
>
> - token = rtas_token("set-time-of-day");
> - report("token available", token != RTAS_UNKNOWN_SERVICE);
> - if (token == RTAS_UNKNOWN_SERVICE)
> + ret = rtas_token("set-time-of-day", &stod_token);
> + report("token available", ret == 0);
> + if (ret)
> return;
>
> /* 23:59:59 28/2/2000 */
>
> - ret = rtas_call(token, 7, 1, NULL, 2000, 2, 28, 23, 59, 59);
> + ret = rtas_call(stod_token, 7, 1, NULL, 2000, 2, 28, 23, 59, 59);
> report("execution", ret == 0);
>
> /* check it has worked */
> - ret = rtas_call(rtas_token("get-time-of-day"), 0, 8, date);
> + ret = rtas_token("get-time-of-day", >od_token);
> + assert(ret == 0);
> + ret = rtas_call(gtod_token, 0, 8, date);
> report("re-read", ret == 0);
> t1 = mktime(2000, 2, 28, 23, 59, 59);
> t2 = mktime(date[0], date[1], date[2],
> @@ -100,7 +102,7 @@ static void check_set_time_of_day(void)
> /* check it is running */
> count = 0;
> do {
> - ret = rtas_call(rtas_token("get-time-of-day"), 0, 8, date);
> + ret = rtas_call(gtod_token, 0, 8, date);
> t2 = mktime(date[0], date[1], date[2],
> date[3], date[4], date[5]);
> count++;
>
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [kvm-unit-tests PATCH] powerpc: Rework the rtas_token() function
2017-05-31 11:15 [kvm-unit-tests PATCH] powerpc: Rework the rtas_token() function Thomas Huth
2017-05-31 11:58 ` Andrew Jones
2017-05-31 12:07 ` Laurent Vivier
@ 2017-05-31 12:31 ` Paolo Bonzini
2 siblings, 0 replies; 4+ messages in thread
From: Paolo Bonzini @ 2017-05-31 12:31 UTC (permalink / raw)
To: Thomas Huth, kvm; +Cc: kvm-ppc, Laurent Vivier, Radim Krčmář
On 31/05/2017 13:15, Thomas Huth wrote:
> RTAS tokens can have any value, also 0xffffffff is theoretically
> allowed (which is currently used for the RTAS_UNKNOWN_SERVICE error
> code). Thus we should not mix error codes and tokens in the return
> value here and return the token value via a pointer parameter
> instead.
>
> This patch also adds a check to rtas_token() to test whether the device
> tree is available at all. This fixes a possible endless loop that
> happens without device tree, spamming the console with "rtas_node:
> /rtas: FDT_ERR_BADMAGIC" messages: Somewhere the code calls abort()
> due to the missing device tree, and abort() calls exit() which in
> turn tries to shut down the VM with rtas_power_off(). rtas_power_off()
> needs the device tree again to look up the right RTAS token, where we
> then end up in the next iteration.
>
> Signed-off-by: Thomas Huth <thuth@redhat.com>
> ---
> lib/powerpc/asm/rtas.h | 2 +-
> lib/powerpc/rtas.c | 30 ++++++++++++++++++++++--------
> lib/powerpc/smp.c | 11 ++++++-----
> powerpc/rtas.c | 24 +++++++++++++-----------
> 4 files changed, 42 insertions(+), 25 deletions(-)
>
> diff --git a/lib/powerpc/asm/rtas.h b/lib/powerpc/asm/rtas.h
> index 9012a1e..6fb407a 100644
> --- a/lib/powerpc/asm/rtas.h
> +++ b/lib/powerpc/asm/rtas.h
> @@ -21,7 +21,7 @@ struct rtas_args {
> };
>
> extern void rtas_init(void);
> -extern int rtas_token(const char *service);
> +extern int rtas_token(const char *service, uint32_t *token);
> extern int rtas_call(int token, int nargs, int nret, int *outputs, ...);
>
> extern void rtas_power_off(void);
> diff --git a/lib/powerpc/rtas.c b/lib/powerpc/rtas.c
> index 3407e25..2e7e0da 100644
> --- a/lib/powerpc/rtas.c
> +++ b/lib/powerpc/rtas.c
> @@ -69,17 +69,22 @@ void rtas_init(void)
> }
> }
>
> -int rtas_token(const char *service)
> +int rtas_token(const char *service, uint32_t *token)
> {
> const struct fdt_property *prop;
> - u32 *token;
> + u32 *data;
> +
> + if (!dt_available())
> + return RTAS_UNKNOWN_SERVICE;
>
> prop = fdt_get_property(dt_fdt(), rtas_node(), service, NULL);
> - if (prop) {
> - token = (u32 *)prop->data;
> - return fdt32_to_cpu(*token);
> - }
> - return RTAS_UNKNOWN_SERVICE;
> + if (!prop)
> + return RTAS_UNKNOWN_SERVICE;
> +
> + data = (u32 *)prop->data;
> + *token = fdt32_to_cpu(*data);
> +
> + return 0;
> }
>
> int rtas_call(int token, int nargs, int nret, int *outputs, ...)
> @@ -116,6 +121,15 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...)
>
> void rtas_power_off(void)
> {
> - int ret = rtas_call(rtas_token("power-off"), 2, 1, NULL, -1, -1);
> + uint32_t token;
> + int ret;
> +
> + ret = rtas_token("power-off", &token);
> + if (ret) {
> + puts("RTAS power-off not available\n");
> + return;
> + }
> +
> + ret = rtas_call(token, 2, 1, NULL, -1, -1);
> printf("RTAS power-off returned %d\n", ret);
> }
> diff --git a/lib/powerpc/smp.c b/lib/powerpc/smp.c
> index e18894b..afe4361 100644
> --- a/lib/powerpc/smp.c
> +++ b/lib/powerpc/smp.c
> @@ -27,12 +27,13 @@ struct secondary_entry_data {
> */
> int start_thread(int cpu_id, secondary_entry_fn entry, uint32_t r3)
> {
> - int query_token, start_token, outputs[1], ret;
> + uint32_t query_token, start_token;
> + int outputs[1], ret;
>
> - query_token = rtas_token("query-cpu-stopped-state");
> - start_token = rtas_token("start-cpu");
> - assert(query_token != RTAS_UNKNOWN_SERVICE &&
> - start_token != RTAS_UNKNOWN_SERVICE);
> + ret = rtas_token("query-cpu-stopped-state", &query_token);
> + assert(ret == 0);
> + ret = rtas_token("start-cpu", &start_token);
> + assert(ret == 0);
>
> ret = rtas_call(query_token, 1, 2, outputs, cpu_id);
> if (ret) {
> diff --git a/powerpc/rtas.c b/powerpc/rtas.c
> index 1b1e9c7..5d43f33 100644
> --- a/powerpc/rtas.c
> +++ b/powerpc/rtas.c
> @@ -39,14 +39,14 @@ static unsigned long mktime(int year, int month, int day,
>
> static void check_get_time_of_day(unsigned long start)
> {
> - int token;
> + uint32_t token;
> int ret;
> int now[8];
> unsigned long t1, t2, count;
>
> - token = rtas_token("get-time-of-day");
> - report("token available", token != RTAS_UNKNOWN_SERVICE);
> - if (token == RTAS_UNKNOWN_SERVICE)
> + ret = rtas_token("get-time-of-day", &token);
> + report("token available", ret == 0);
> + if (ret)
> return;
>
> ret = rtas_call(token, 0, 8, now);
> @@ -74,23 +74,25 @@ static void check_get_time_of_day(unsigned long start)
>
> static void check_set_time_of_day(void)
> {
> - int token;
> + uint32_t stod_token, gtod_token;
> int ret;
> int date[8];
> unsigned long t1, t2, count;
>
> - token = rtas_token("set-time-of-day");
> - report("token available", token != RTAS_UNKNOWN_SERVICE);
> - if (token == RTAS_UNKNOWN_SERVICE)
> + ret = rtas_token("set-time-of-day", &stod_token);
> + report("token available", ret == 0);
> + if (ret)
> return;
>
> /* 23:59:59 28/2/2000 */
>
> - ret = rtas_call(token, 7, 1, NULL, 2000, 2, 28, 23, 59, 59);
> + ret = rtas_call(stod_token, 7, 1, NULL, 2000, 2, 28, 23, 59, 59);
> report("execution", ret == 0);
>
> /* check it has worked */
> - ret = rtas_call(rtas_token("get-time-of-day"), 0, 8, date);
> + ret = rtas_token("get-time-of-day", >od_token);
> + assert(ret == 0);
> + ret = rtas_call(gtod_token, 0, 8, date);
> report("re-read", ret == 0);
> t1 = mktime(2000, 2, 28, 23, 59, 59);
> t2 = mktime(date[0], date[1], date[2],
> @@ -100,7 +102,7 @@ static void check_set_time_of_day(void)
> /* check it is running */
> count = 0;
> do {
> - ret = rtas_call(rtas_token("get-time-of-day"), 0, 8, date);
> + ret = rtas_call(gtod_token, 0, 8, date);
> t2 = mktime(date[0], date[1], date[2],
> date[3], date[4], date[5]);
> count++;
>
Dropped "powerpc: Fix endless loop that occurs without a device tree",
and queued.
Paolo
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2017-05-31 12:31 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-05-31 11:15 [kvm-unit-tests PATCH] powerpc: Rework the rtas_token() function Thomas Huth
2017-05-31 11:58 ` Andrew Jones
2017-05-31 12:07 ` Laurent Vivier
2017-05-31 12:31 ` Paolo Bonzini
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).