qemu/pc-bios/vof/ci.c
<<
>>
Prefs
   1#include "vof.h"
   2
   3struct prom_args {
   4    uint32_t service;
   5    uint32_t nargs;
   6    uint32_t nret;
   7    uint32_t args[10];
   8};
   9
  10typedef unsigned long prom_arg_t;
  11
  12#define ADDR(x) (uint32_t)(x)
  13
  14static int prom_handle(struct prom_args *pargs)
  15{
  16    void *rtasbase;
  17    uint32_t rtassize = 0;
  18    phandle rtas;
  19
  20    if (strcmp("call-method", (void *)(unsigned long)pargs->service)) {
  21        return -1;
  22    }
  23
  24    if (strcmp("instantiate-rtas", (void *)(unsigned long)pargs->args[0])) {
  25        return -1;
  26    }
  27
  28    rtas = ci_finddevice("/rtas");
  29    /* rtas-size is set by QEMU depending of FWNMI support */
  30    ci_getprop(rtas, "rtas-size", &rtassize, sizeof(rtassize));
  31    if (rtassize < hv_rtas_size) {
  32        return -1;
  33    }
  34
  35    rtasbase = (void *)(unsigned long) pargs->args[2];
  36
  37    memcpy(rtasbase, hv_rtas, hv_rtas_size);
  38    pargs->args[pargs->nargs] = 0;
  39    pargs->args[pargs->nargs + 1] = pargs->args[2];
  40
  41    return 0;
  42}
  43
  44void prom_entry(uint32_t args)
  45{
  46    if (prom_handle((void *)(unsigned long) args)) {
  47        ci_entry(args);
  48    }
  49}
  50
  51static int call_ci(const char *service, int nargs, int nret, ...)
  52{
  53    int i;
  54    struct prom_args args;
  55    va_list list;
  56
  57    args.service = ADDR(service);
  58    args.nargs = nargs;
  59    args.nret = nret;
  60
  61    va_start(list, nret);
  62    for (i = 0; i < nargs; i++) {
  63        args.args[i] = va_arg(list, prom_arg_t);
  64    }
  65    va_end(list);
  66
  67    for (i = 0; i < nret; i++) {
  68        args.args[nargs + i] = 0;
  69    }
  70
  71    if (ci_entry((uint32_t)(&args)) < 0) {
  72        return -1;
  73    }
  74
  75    return (nret > 0) ? args.args[nargs] : 0;
  76}
  77
  78void ci_panic(const char *str)
  79{
  80    call_ci("exit", 0, 0);
  81}
  82
  83phandle ci_finddevice(const char *path)
  84{
  85    return call_ci("finddevice", 1, 1, path);
  86}
  87
  88uint32_t ci_getprop(phandle ph, const char *propname, void *prop, int len)
  89{
  90    return call_ci("getprop", 4, 1, ph, propname, prop, len);
  91}
  92