Revision 821303f5 hw/spapr_rtas.c

b/hw/spapr_rtas.c
38 38
#define TOKEN_BASE      0x2000
39 39
#define TOKEN_MAX       0x100
40 40

  
41
static void rtas_display_character(sPAPREnvironment *spapr,
42
                                   uint32_t token, uint32_t nargs,
43
                                   target_ulong args,
44
                                   uint32_t nret, target_ulong rets)
45
{
46
    uint8_t c = rtas_ld(args, 0);
47
    VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, 0);
48

  
49
    if (!sdev) {
50
        rtas_st(rets, 0, -1);
51
    } else {
52
        vty_putchars(sdev, &c, sizeof(c));
53
        rtas_st(rets, 0, 0);
54
    }
55
}
56

  
57
static void rtas_get_time_of_day(sPAPREnvironment *spapr,
58
                                 uint32_t token, uint32_t nargs,
59
                                 target_ulong args,
60
                                 uint32_t nret, target_ulong rets)
61
{
62
    struct tm tm;
63

  
64
    if (nret != 8) {
65
        rtas_st(rets, 0, -3);
66
        return;
67
    }
68

  
69
    qemu_get_timedate(&tm, 0);
70

  
71
    rtas_st(rets, 0, 0); /* Success */
72
    rtas_st(rets, 1, tm.tm_year + 1900);
73
    rtas_st(rets, 2, tm.tm_mon + 1);
74
    rtas_st(rets, 3, tm.tm_mday);
75
    rtas_st(rets, 4, tm.tm_hour);
76
    rtas_st(rets, 5, tm.tm_min);
77
    rtas_st(rets, 6, tm.tm_sec);
78
    rtas_st(rets, 7, 0); /* we don't do nanoseconds */
79
}
80

  
81
static void rtas_power_off(sPAPREnvironment *spapr,
82
                           uint32_t token, uint32_t nargs, target_ulong args,
83
                           uint32_t nret, target_ulong rets)
84
{
85
    if (nargs != 2 || nret != 1) {
86
        rtas_st(rets, 0, -3);
87
        return;
88
    }
89
    qemu_system_shutdown_request();
90
    rtas_st(rets, 0, 0);
91
}
92

  
41 93
static struct rtas_call {
42 94
    const char *name;
43 95
    spapr_rtas_fn fn;
......
59 111
        }
60 112
    }
61 113

  
114
    /* HACK: Some Linux early debug code uses RTAS display-character,
115
     * but assumes the token value is 0xa (which it is on some real
116
     * machines) without looking it up in the device tree.  This
117
     * special case makes this work */
118
    if (token == 0xa) {
119
        rtas_display_character(spapr, 0xa, nargs, args, nret, rets);
120
        return H_SUCCESS;
121
    }
122

  
62 123
    hcall_dprintf("Unknown RTAS token 0x%x\n", token);
63 124
    rtas_st(rets, 0, -3);
64 125
    return H_PARAMETER;
......
129 190
    }
130 191
    return 0;
131 192
}
193

  
194
static void register_core_rtas(void)
195
{
196
    spapr_rtas_register("display-character", rtas_display_character);
197
    spapr_rtas_register("get-time-of-day", rtas_get_time_of_day);
198
    spapr_rtas_register("power-off", rtas_power_off);
199
}
200
device_init(register_core_rtas);

Also available in: Unified diff