Am 18.12.2010 um 17:09 schrieb Blue Swirl:
On Sat, Dec 18, 2010 at 1:09 AM, Andreas Färber <andreas.faerber@web.de
wrote: On ppc64 neither long nor pointers can be used for the client interface. Introduce new types prom_[u]arg_t to abstract this and add helpers get_service() and arg2pointer() as well as format strings.
Signed-off-by: Andreas Färber andreas.faerber@web.de
libopenbios/client.c | 302 +++++++++++++++++++++++++++ +---------------------- 1 files changed, 170 insertions(+), 132 deletions(-)
diff --git a/libopenbios/client.c b/libopenbios/client.c index d8a9fdf..d986226 100644 --- a/libopenbios/client.c +++ b/libopenbios/client.c @@ -30,13 +30,47 @@
- (it doesn't) or if the function is unimplemented.
*/
+#ifdef CONFIG_PPC64 +typedef int prom_arg_t; +typedef unsigned int prom_uarg_t; +#define PRIdARG "d" +#define PRIxARG "x" +#define FMT_arg "%" PRIdARG +#define FMT_argx "%08" PRIxARG +#else +typedef long prom_arg_t; +typedef unsigned long prom_uarg_t; +#define PRIdARG "ld" +#define PRIxARG "lx" +#define FMT_arg "%" PRIdARG +#define FMT_argx "%08" PRIxARG
This should be "%016" for Sparc64 since long is 64 bits.
The original code used %08 so I left it that way. We could check #if BITS == 64.
Maybe these should be moved to a common header instead.
In that case we need longer names - e.g., FMT_promarg.
#define PROM_MAX_ARGS 10 typedef struct prom_args {
const char *service;
long nargs;
long nret;
unsigned long args[PROM_MAX_ARGS];
-} prom_args_t; +#ifdef CONFIG_PPC64
- prom_uarg_t service;
+#else
- const char *service;
+#endif
- prom_arg_t nargs;
- prom_arg_t nret;
- prom_uarg_t args[PROM_MAX_ARGS];
+} __attribute__((packed)) prom_args_t;
+static inline void* arg2pointer(prom_uarg_t value) +{
- return (void*)(uintptr_t)value;
+}
Perhaps the the type of the return value should be const char * instead, that may reduce the number of casts.
Will try. I followed the cell2pointer() model.
+static inline const char* get_service(prom_args_t *pb) +{ +#ifdef CONFIG_PPC64
- return arg2pointer(pb->service);
+#else
- return pb->service;
+#endif
I don't think arg2pointer() has any effect for non-PPC64 hosts, so you could also unconditionally use arg2pointer().
OK.
printk("of_client_interface return:"); for (i = 0; i < pb->nret; i++) {
printk(" %lx", pb->args[pb->nargs + i]);
printk(" %" PRIxARG, pb->args[pb->nargs +
i]);
" " FMT_arg?
That would change the output to decimal. Intentional? If I used FMT_argx, we'd introduce zero-padding.
Andreas