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