xref: /qemu/hw/ppc/spapr_rtas.c (revision 028ec3cee3872fca661a5339b5b75b965f593597)
1 /*
2  * QEMU PowerPC pSeries Logical Partition (aka sPAPR) hardware System Emulator
3  *
4  * Hypercall based emulated RTAS
5  *
6  * Copyright (c) 2010-2011 David Gibson, IBM Corporation.
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a copy
9  * of this software and associated documentation files (the "Software"), to deal
10  * in the Software without restriction, including without limitation the rights
11  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12  * copies of the Software, and to permit persons to whom the Software is
13  * furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24  * THE SOFTWARE.
25  *
26  */
27 #include "qemu/osdep.h"
28 #include "cpu.h"
29 #include "qemu/log.h"
30 #include "qemu/error-report.h"
31 #include "sysemu/sysemu.h"
32 #include "sysemu/char.h"
33 #include "hw/qdev.h"
34 #include "sysemu/device_tree.h"
35 #include "sysemu/cpus.h"
36 #include "sysemu/kvm.h"
37 
38 #include "hw/ppc/spapr.h"
39 #include "hw/ppc/spapr_vio.h"
40 #include "hw/ppc/spapr_rtas.h"
41 #include "hw/ppc/ppc.h"
42 #include "qapi-event.h"
43 #include "hw/boards.h"
44 
45 #include <libfdt.h>
46 #include "hw/ppc/spapr_drc.h"
47 #include "qemu/cutils.h"
48 #include "trace.h"
49 
50 static sPAPRConfigureConnectorState *spapr_ccs_find(sPAPRMachineState *spapr,
51                                                     uint32_t drc_index)
52 {
53     sPAPRConfigureConnectorState *ccs = NULL;
54 
55     QTAILQ_FOREACH(ccs, &spapr->ccs_list, next) {
56         if (ccs->drc_index == drc_index) {
57             break;
58         }
59     }
60 
61     return ccs;
62 }
63 
64 static void spapr_ccs_add(sPAPRMachineState *spapr,
65                           sPAPRConfigureConnectorState *ccs)
66 {
67     g_assert(!spapr_ccs_find(spapr, ccs->drc_index));
68     QTAILQ_INSERT_HEAD(&spapr->ccs_list, ccs, next);
69 }
70 
71 static void spapr_ccs_remove(sPAPRMachineState *spapr,
72                              sPAPRConfigureConnectorState *ccs)
73 {
74     QTAILQ_REMOVE(&spapr->ccs_list, ccs, next);
75     g_free(ccs);
76 }
77 
78 void spapr_ccs_reset_hook(void *opaque)
79 {
80     sPAPRMachineState *spapr = opaque;
81     sPAPRConfigureConnectorState *ccs, *ccs_tmp;
82 
83     QTAILQ_FOREACH_SAFE(ccs, &spapr->ccs_list, next, ccs_tmp) {
84         spapr_ccs_remove(spapr, ccs);
85     }
86 }
87 
88 static void rtas_display_character(PowerPCCPU *cpu, sPAPRMachineState *spapr,
89                                    uint32_t token, uint32_t nargs,
90                                    target_ulong args,
91                                    uint32_t nret, target_ulong rets)
92 {
93     uint8_t c = rtas_ld(args, 0);
94     VIOsPAPRDevice *sdev = vty_lookup(spapr, 0);
95 
96     if (!sdev) {
97         rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
98     } else {
99         vty_putchars(sdev, &c, sizeof(c));
100         rtas_st(rets, 0, RTAS_OUT_SUCCESS);
101     }
102 }
103 
104 static void rtas_power_off(PowerPCCPU *cpu, sPAPRMachineState *spapr,
105                            uint32_t token, uint32_t nargs, target_ulong args,
106                            uint32_t nret, target_ulong rets)
107 {
108     if (nargs != 2 || nret != 1) {
109         rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
110         return;
111     }
112     qemu_system_shutdown_request();
113     cpu_stop_current();
114     rtas_st(rets, 0, RTAS_OUT_SUCCESS);
115 }
116 
117 static void rtas_system_reboot(PowerPCCPU *cpu, sPAPRMachineState *spapr,
118                                uint32_t token, uint32_t nargs,
119                                target_ulong args,
120                                uint32_t nret, target_ulong rets)
121 {
122     if (nargs != 0 || nret != 1) {
123         rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
124         return;
125     }
126     qemu_system_reset_request();
127     rtas_st(rets, 0, RTAS_OUT_SUCCESS);
128 }
129 
130 static void rtas_query_cpu_stopped_state(PowerPCCPU *cpu_,
131                                          sPAPRMachineState *spapr,
132                                          uint32_t token, uint32_t nargs,
133                                          target_ulong args,
134                                          uint32_t nret, target_ulong rets)
135 {
136     target_ulong id;
137     PowerPCCPU *cpu;
138 
139     if (nargs != 1 || nret != 2) {
140         rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
141         return;
142     }
143 
144     id = rtas_ld(args, 0);
145     cpu = ppc_get_vcpu_by_dt_id(id);
146     if (cpu != NULL) {
147         if (CPU(cpu)->halted) {
148             rtas_st(rets, 1, 0);
149         } else {
150             rtas_st(rets, 1, 2);
151         }
152 
153         rtas_st(rets, 0, RTAS_OUT_SUCCESS);
154         return;
155     }
156 
157     /* Didn't find a matching cpu */
158     rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
159 }
160 
161 /*
162  * Set the timebase offset of the CPU to that of first CPU.
163  * This helps hotplugged CPU to have the correct timebase offset.
164  */
165 static void spapr_cpu_update_tb_offset(PowerPCCPU *cpu)
166 {
167     PowerPCCPU *fcpu = POWERPC_CPU(first_cpu);
168 
169     cpu->env.tb_env->tb_offset = fcpu->env.tb_env->tb_offset;
170 }
171 
172 static void spapr_cpu_set_endianness(PowerPCCPU *cpu)
173 {
174     PowerPCCPU *fcpu = POWERPC_CPU(first_cpu);
175     PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(fcpu);
176 
177     if (!pcc->interrupts_big_endian(fcpu)) {
178         cpu->env.spr[SPR_LPCR] |= LPCR_ILE;
179     }
180 }
181 
182 static void rtas_start_cpu(PowerPCCPU *cpu_, sPAPRMachineState *spapr,
183                            uint32_t token, uint32_t nargs,
184                            target_ulong args,
185                            uint32_t nret, target_ulong rets)
186 {
187     target_ulong id, start, r3;
188     PowerPCCPU *cpu;
189 
190     if (nargs != 3 || nret != 1) {
191         rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
192         return;
193     }
194 
195     id = rtas_ld(args, 0);
196     start = rtas_ld(args, 1);
197     r3 = rtas_ld(args, 2);
198 
199     cpu = ppc_get_vcpu_by_dt_id(id);
200     if (cpu != NULL) {
201         CPUState *cs = CPU(cpu);
202         CPUPPCState *env = &cpu->env;
203 
204         if (!cs->halted) {
205             rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
206             return;
207         }
208 
209         /* This will make sure qemu state is up to date with kvm, and
210          * mark it dirty so our changes get flushed back before the
211          * new cpu enters */
212         kvm_cpu_synchronize_state(cs);
213 
214         env->msr = (1ULL << MSR_SF) | (1ULL << MSR_ME);
215         env->nip = start;
216         env->gpr[3] = r3;
217         cs->halted = 0;
218         spapr_cpu_set_endianness(cpu);
219         spapr_cpu_update_tb_offset(cpu);
220 
221         qemu_cpu_kick(cs);
222 
223         rtas_st(rets, 0, RTAS_OUT_SUCCESS);
224         return;
225     }
226 
227     /* Didn't find a matching cpu */
228     rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
229 }
230 
231 static void rtas_stop_self(PowerPCCPU *cpu, sPAPRMachineState *spapr,
232                            uint32_t token, uint32_t nargs,
233                            target_ulong args,
234                            uint32_t nret, target_ulong rets)
235 {
236     CPUState *cs = CPU(cpu);
237     CPUPPCState *env = &cpu->env;
238 
239     cs->halted = 1;
240     qemu_cpu_kick(cs);
241     /*
242      * While stopping a CPU, the guest calls H_CPPR which
243      * effectively disables interrupts on XICS level.
244      * However decrementer interrupts in TCG can still
245      * wake the CPU up so here we disable interrupts in MSR
246      * as well.
247      * As rtas_start_cpu() resets the whole MSR anyway, there is
248      * no need to bother with specific bits, we just clear it.
249      */
250     env->msr = 0;
251 }
252 
253 static inline int sysparm_st(target_ulong addr, target_ulong len,
254                              const void *val, uint16_t vallen)
255 {
256     hwaddr phys = ppc64_phys_to_real(addr);
257 
258     if (len < 2) {
259         return RTAS_OUT_SYSPARM_PARAM_ERROR;
260     }
261     stw_be_phys(&address_space_memory, phys, vallen);
262     cpu_physical_memory_write(phys + 2, val, MIN(len - 2, vallen));
263     return RTAS_OUT_SUCCESS;
264 }
265 
266 static void rtas_ibm_get_system_parameter(PowerPCCPU *cpu,
267                                           sPAPRMachineState *spapr,
268                                           uint32_t token, uint32_t nargs,
269                                           target_ulong args,
270                                           uint32_t nret, target_ulong rets)
271 {
272     target_ulong parameter = rtas_ld(args, 0);
273     target_ulong buffer = rtas_ld(args, 1);
274     target_ulong length = rtas_ld(args, 2);
275     target_ulong ret;
276 
277     switch (parameter) {
278     case RTAS_SYSPARM_SPLPAR_CHARACTERISTICS: {
279         char *param_val = g_strdup_printf("MaxEntCap=%d,"
280                                           "DesMem=%llu,"
281                                           "DesProcs=%d,"
282                                           "MaxPlatProcs=%d",
283                                           max_cpus,
284                                           current_machine->ram_size / M_BYTE,
285                                           smp_cpus,
286                                           max_cpus);
287         ret = sysparm_st(buffer, length, param_val, strlen(param_val) + 1);
288         g_free(param_val);
289         break;
290     }
291     case RTAS_SYSPARM_DIAGNOSTICS_RUN_MODE: {
292         uint8_t param_val = DIAGNOSTICS_RUN_MODE_DISABLED;
293 
294         ret = sysparm_st(buffer, length, &param_val, sizeof(param_val));
295         break;
296     }
297     case RTAS_SYSPARM_UUID:
298         ret = sysparm_st(buffer, length, qemu_uuid, (qemu_uuid_set ? 16 : 0));
299         break;
300     default:
301         ret = RTAS_OUT_NOT_SUPPORTED;
302     }
303 
304     rtas_st(rets, 0, ret);
305 }
306 
307 static void rtas_ibm_set_system_parameter(PowerPCCPU *cpu,
308                                           sPAPRMachineState *spapr,
309                                           uint32_t token, uint32_t nargs,
310                                           target_ulong args,
311                                           uint32_t nret, target_ulong rets)
312 {
313     target_ulong parameter = rtas_ld(args, 0);
314     target_ulong ret = RTAS_OUT_NOT_SUPPORTED;
315 
316     switch (parameter) {
317     case RTAS_SYSPARM_SPLPAR_CHARACTERISTICS:
318     case RTAS_SYSPARM_DIAGNOSTICS_RUN_MODE:
319     case RTAS_SYSPARM_UUID:
320         ret = RTAS_OUT_NOT_AUTHORIZED;
321         break;
322     }
323 
324     rtas_st(rets, 0, ret);
325 }
326 
327 static void rtas_ibm_os_term(PowerPCCPU *cpu,
328                             sPAPRMachineState *spapr,
329                             uint32_t token, uint32_t nargs,
330                             target_ulong args,
331                             uint32_t nret, target_ulong rets)
332 {
333     target_ulong ret = 0;
334 
335     qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_PAUSE, &error_abort);
336 
337     rtas_st(rets, 0, ret);
338 }
339 
340 static void rtas_set_power_level(PowerPCCPU *cpu, sPAPRMachineState *spapr,
341                                  uint32_t token, uint32_t nargs,
342                                  target_ulong args, uint32_t nret,
343                                  target_ulong rets)
344 {
345     int32_t power_domain;
346 
347     if (nargs != 2 || nret != 2) {
348         rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
349         return;
350     }
351 
352     /* we currently only use a single, "live insert" powerdomain for
353      * hotplugged/dlpar'd resources, so the power is always live/full (100)
354      */
355     power_domain = rtas_ld(args, 0);
356     if (power_domain != -1) {
357         rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED);
358         return;
359     }
360 
361     rtas_st(rets, 0, RTAS_OUT_SUCCESS);
362     rtas_st(rets, 1, 100);
363 }
364 
365 static void rtas_get_power_level(PowerPCCPU *cpu, sPAPRMachineState *spapr,
366                                   uint32_t token, uint32_t nargs,
367                                   target_ulong args, uint32_t nret,
368                                   target_ulong rets)
369 {
370     int32_t power_domain;
371 
372     if (nargs != 1 || nret != 2) {
373         rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
374         return;
375     }
376 
377     /* we currently only use a single, "live insert" powerdomain for
378      * hotplugged/dlpar'd resources, so the power is always live/full (100)
379      */
380     power_domain = rtas_ld(args, 0);
381     if (power_domain != -1) {
382         rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED);
383         return;
384     }
385 
386     rtas_st(rets, 0, RTAS_OUT_SUCCESS);
387     rtas_st(rets, 1, 100);
388 }
389 
390 static bool sensor_type_is_dr(uint32_t sensor_type)
391 {
392     switch (sensor_type) {
393     case RTAS_SENSOR_TYPE_ISOLATION_STATE:
394     case RTAS_SENSOR_TYPE_DR:
395     case RTAS_SENSOR_TYPE_ALLOCATION_STATE:
396         return true;
397     }
398 
399     return false;
400 }
401 
402 static void rtas_set_indicator(PowerPCCPU *cpu, sPAPRMachineState *spapr,
403                                uint32_t token, uint32_t nargs,
404                                target_ulong args, uint32_t nret,
405                                target_ulong rets)
406 {
407     uint32_t sensor_type;
408     uint32_t sensor_index;
409     uint32_t sensor_state;
410     uint32_t ret = RTAS_OUT_SUCCESS;
411     sPAPRDRConnector *drc;
412     sPAPRDRConnectorClass *drck;
413 
414     if (nargs != 3 || nret != 1) {
415         ret = RTAS_OUT_PARAM_ERROR;
416         goto out;
417     }
418 
419     sensor_type = rtas_ld(args, 0);
420     sensor_index = rtas_ld(args, 1);
421     sensor_state = rtas_ld(args, 2);
422 
423     if (!sensor_type_is_dr(sensor_type)) {
424         goto out_unimplemented;
425     }
426 
427     /* if this is a DR sensor we can assume sensor_index == drc_index */
428     drc = spapr_dr_connector_by_index(sensor_index);
429     if (!drc) {
430         trace_spapr_rtas_set_indicator_invalid(sensor_index);
431         ret = RTAS_OUT_PARAM_ERROR;
432         goto out;
433     }
434     drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
435 
436     switch (sensor_type) {
437     case RTAS_SENSOR_TYPE_ISOLATION_STATE:
438         /* if the guest is configuring a device attached to this
439          * DRC, we should reset the configuration state at this
440          * point since it may no longer be reliable (guest released
441          * device and needs to start over, or unplug occurred so
442          * the FDT is no longer valid)
443          */
444         if (sensor_state == SPAPR_DR_ISOLATION_STATE_ISOLATED) {
445             sPAPRConfigureConnectorState *ccs = spapr_ccs_find(spapr,
446                                                                sensor_index);
447             if (ccs) {
448                 spapr_ccs_remove(spapr, ccs);
449             }
450         }
451         ret = drck->set_isolation_state(drc, sensor_state);
452         break;
453     case RTAS_SENSOR_TYPE_DR:
454         ret = drck->set_indicator_state(drc, sensor_state);
455         break;
456     case RTAS_SENSOR_TYPE_ALLOCATION_STATE:
457         ret = drck->set_allocation_state(drc, sensor_state);
458         break;
459     default:
460         goto out_unimplemented;
461     }
462 
463 out:
464     rtas_st(rets, 0, ret);
465     return;
466 
467 out_unimplemented:
468     /* currently only DR-related sensors are implemented */
469     trace_spapr_rtas_set_indicator_not_supported(sensor_index, sensor_type);
470     rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED);
471 }
472 
473 static void rtas_get_sensor_state(PowerPCCPU *cpu, sPAPRMachineState *spapr,
474                                   uint32_t token, uint32_t nargs,
475                                   target_ulong args, uint32_t nret,
476                                   target_ulong rets)
477 {
478     uint32_t sensor_type;
479     uint32_t sensor_index;
480     uint32_t sensor_state = 0;
481     sPAPRDRConnector *drc;
482     sPAPRDRConnectorClass *drck;
483     uint32_t ret = RTAS_OUT_SUCCESS;
484 
485     if (nargs != 2 || nret != 2) {
486         ret = RTAS_OUT_PARAM_ERROR;
487         goto out;
488     }
489 
490     sensor_type = rtas_ld(args, 0);
491     sensor_index = rtas_ld(args, 1);
492 
493     if (sensor_type != RTAS_SENSOR_TYPE_ENTITY_SENSE) {
494         /* currently only DR-related sensors are implemented */
495         trace_spapr_rtas_get_sensor_state_not_supported(sensor_index,
496                                                         sensor_type);
497         ret = RTAS_OUT_NOT_SUPPORTED;
498         goto out;
499     }
500 
501     drc = spapr_dr_connector_by_index(sensor_index);
502     if (!drc) {
503         trace_spapr_rtas_get_sensor_state_invalid(sensor_index);
504         ret = RTAS_OUT_PARAM_ERROR;
505         goto out;
506     }
507     drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
508     ret = drck->entity_sense(drc, &sensor_state);
509 
510 out:
511     rtas_st(rets, 0, ret);
512     rtas_st(rets, 1, sensor_state);
513 }
514 
515 /* configure-connector work area offsets, int32_t units for field
516  * indexes, bytes for field offset/len values.
517  *
518  * as documented by PAPR+ v2.7, 13.5.3.5
519  */
520 #define CC_IDX_NODE_NAME_OFFSET 2
521 #define CC_IDX_PROP_NAME_OFFSET 2
522 #define CC_IDX_PROP_LEN 3
523 #define CC_IDX_PROP_DATA_OFFSET 4
524 #define CC_VAL_DATA_OFFSET ((CC_IDX_PROP_DATA_OFFSET + 1) * 4)
525 #define CC_WA_LEN 4096
526 
527 static void configure_connector_st(target_ulong addr, target_ulong offset,
528                                    const void *buf, size_t len)
529 {
530     cpu_physical_memory_write(ppc64_phys_to_real(addr + offset),
531                               buf, MIN(len, CC_WA_LEN - offset));
532 }
533 
534 static void rtas_ibm_configure_connector(PowerPCCPU *cpu,
535                                          sPAPRMachineState *spapr,
536                                          uint32_t token, uint32_t nargs,
537                                          target_ulong args, uint32_t nret,
538                                          target_ulong rets)
539 {
540     uint64_t wa_addr;
541     uint64_t wa_offset;
542     uint32_t drc_index;
543     sPAPRDRConnector *drc;
544     sPAPRDRConnectorClass *drck;
545     sPAPRConfigureConnectorState *ccs;
546     sPAPRDRCCResponse resp = SPAPR_DR_CC_RESPONSE_CONTINUE;
547     int rc;
548     const void *fdt;
549 
550     if (nargs != 2 || nret != 1) {
551         rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
552         return;
553     }
554 
555     wa_addr = ((uint64_t)rtas_ld(args, 1) << 32) | rtas_ld(args, 0);
556 
557     drc_index = rtas_ld(wa_addr, 0);
558     drc = spapr_dr_connector_by_index(drc_index);
559     if (!drc) {
560         trace_spapr_rtas_ibm_configure_connector_invalid(drc_index);
561         rc = RTAS_OUT_PARAM_ERROR;
562         goto out;
563     }
564 
565     drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
566     fdt = drck->get_fdt(drc, NULL);
567     if (!fdt) {
568         trace_spapr_rtas_ibm_configure_connector_missing_fdt(drc_index);
569         rc = SPAPR_DR_CC_RESPONSE_NOT_CONFIGURABLE;
570         goto out;
571     }
572 
573     ccs = spapr_ccs_find(spapr, drc_index);
574     if (!ccs) {
575         ccs = g_new0(sPAPRConfigureConnectorState, 1);
576         (void)drck->get_fdt(drc, &ccs->fdt_offset);
577         ccs->drc_index = drc_index;
578         spapr_ccs_add(spapr, ccs);
579     }
580 
581     do {
582         uint32_t tag;
583         const char *name;
584         const struct fdt_property *prop;
585         int fdt_offset_next, prop_len;
586 
587         tag = fdt_next_tag(fdt, ccs->fdt_offset, &fdt_offset_next);
588 
589         switch (tag) {
590         case FDT_BEGIN_NODE:
591             ccs->fdt_depth++;
592             name = fdt_get_name(fdt, ccs->fdt_offset, NULL);
593 
594             /* provide the name of the next OF node */
595             wa_offset = CC_VAL_DATA_OFFSET;
596             rtas_st(wa_addr, CC_IDX_NODE_NAME_OFFSET, wa_offset);
597             configure_connector_st(wa_addr, wa_offset, name, strlen(name) + 1);
598             resp = SPAPR_DR_CC_RESPONSE_NEXT_CHILD;
599             break;
600         case FDT_END_NODE:
601             ccs->fdt_depth--;
602             if (ccs->fdt_depth == 0) {
603                 /* done sending the device tree, don't need to track
604                  * the state anymore
605                  */
606                 drck->set_configured(drc);
607                 spapr_ccs_remove(spapr, ccs);
608                 ccs = NULL;
609                 resp = SPAPR_DR_CC_RESPONSE_SUCCESS;
610             } else {
611                 resp = SPAPR_DR_CC_RESPONSE_PREV_PARENT;
612             }
613             break;
614         case FDT_PROP:
615             prop = fdt_get_property_by_offset(fdt, ccs->fdt_offset,
616                                               &prop_len);
617             name = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
618 
619             /* provide the name of the next OF property */
620             wa_offset = CC_VAL_DATA_OFFSET;
621             rtas_st(wa_addr, CC_IDX_PROP_NAME_OFFSET, wa_offset);
622             configure_connector_st(wa_addr, wa_offset, name, strlen(name) + 1);
623 
624             /* provide the length and value of the OF property. data gets
625              * placed immediately after NULL terminator of the OF property's
626              * name string
627              */
628             wa_offset += strlen(name) + 1,
629             rtas_st(wa_addr, CC_IDX_PROP_LEN, prop_len);
630             rtas_st(wa_addr, CC_IDX_PROP_DATA_OFFSET, wa_offset);
631             configure_connector_st(wa_addr, wa_offset, prop->data, prop_len);
632             resp = SPAPR_DR_CC_RESPONSE_NEXT_PROPERTY;
633             break;
634         case FDT_END:
635             resp = SPAPR_DR_CC_RESPONSE_ERROR;
636         default:
637             /* keep seeking for an actionable tag */
638             break;
639         }
640         if (ccs) {
641             ccs->fdt_offset = fdt_offset_next;
642         }
643     } while (resp == SPAPR_DR_CC_RESPONSE_CONTINUE);
644 
645     rc = resp;
646 out:
647     rtas_st(rets, 0, rc);
648 }
649 
650 static struct rtas_call {
651     const char *name;
652     spapr_rtas_fn fn;
653 } rtas_table[RTAS_TOKEN_MAX - RTAS_TOKEN_BASE];
654 
655 target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPRMachineState *spapr,
656                              uint32_t token, uint32_t nargs, target_ulong args,
657                              uint32_t nret, target_ulong rets)
658 {
659     if ((token >= RTAS_TOKEN_BASE) && (token < RTAS_TOKEN_MAX)) {
660         struct rtas_call *call = rtas_table + (token - RTAS_TOKEN_BASE);
661 
662         if (call->fn) {
663             call->fn(cpu, spapr, token, nargs, args, nret, rets);
664             return H_SUCCESS;
665         }
666     }
667 
668     /* HACK: Some Linux early debug code uses RTAS display-character,
669      * but assumes the token value is 0xa (which it is on some real
670      * machines) without looking it up in the device tree.  This
671      * special case makes this work */
672     if (token == 0xa) {
673         rtas_display_character(cpu, spapr, 0xa, nargs, args, nret, rets);
674         return H_SUCCESS;
675     }
676 
677     hcall_dprintf("Unknown RTAS token 0x%x\n", token);
678     rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
679     return H_PARAMETER;
680 }
681 
682 uint64_t qtest_rtas_call(char *cmd, uint32_t nargs, uint64_t args,
683                          uint32_t nret, uint64_t rets)
684 {
685     int token;
686 
687     for (token = 0; token < RTAS_TOKEN_MAX - RTAS_TOKEN_BASE; token++) {
688         if (strcmp(cmd, rtas_table[token].name) == 0) {
689             sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
690             PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
691 
692             rtas_table[token].fn(cpu, spapr, token + RTAS_TOKEN_BASE,
693                                  nargs, args, nret, rets);
694             return H_SUCCESS;
695         }
696     }
697     return H_PARAMETER;
698 }
699 
700 void spapr_rtas_register(int token, const char *name, spapr_rtas_fn fn)
701 {
702     assert((token >= RTAS_TOKEN_BASE) && (token < RTAS_TOKEN_MAX));
703 
704     token -= RTAS_TOKEN_BASE;
705 
706     assert(!rtas_table[token].name);
707 
708     rtas_table[token].name = name;
709     rtas_table[token].fn = fn;
710 }
711 
712 int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
713                                  hwaddr rtas_size)
714 {
715     int ret;
716     int i;
717     uint32_t lrdr_capacity[5];
718     MachineState *machine = MACHINE(qdev_get_machine());
719     sPAPRMachineState *spapr = SPAPR_MACHINE(machine);
720     uint64_t max_hotplug_addr = spapr->hotplug_memory.base +
721                                 memory_region_size(&spapr->hotplug_memory.mr);
722 
723     ret = fdt_add_mem_rsv(fdt, rtas_addr, rtas_size);
724     if (ret < 0) {
725         error_report("Couldn't add RTAS reserve entry: %s",
726                 fdt_strerror(ret));
727         return ret;
728     }
729 
730     ret = qemu_fdt_setprop_cell(fdt, "/rtas", "linux,rtas-base",
731                                 rtas_addr);
732     if (ret < 0) {
733         error_report("Couldn't add linux,rtas-base property: %s",
734                 fdt_strerror(ret));
735         return ret;
736     }
737 
738     ret = qemu_fdt_setprop_cell(fdt, "/rtas", "linux,rtas-entry",
739                                 rtas_addr);
740     if (ret < 0) {
741         error_report("Couldn't add linux,rtas-entry property: %s",
742                 fdt_strerror(ret));
743         return ret;
744     }
745 
746     ret = qemu_fdt_setprop_cell(fdt, "/rtas", "rtas-size",
747                                 rtas_size);
748     if (ret < 0) {
749         error_report("Couldn't add rtas-size property: %s",
750                 fdt_strerror(ret));
751         return ret;
752     }
753 
754     for (i = 0; i < RTAS_TOKEN_MAX - RTAS_TOKEN_BASE; i++) {
755         struct rtas_call *call = &rtas_table[i];
756 
757         if (!call->name) {
758             continue;
759         }
760 
761         ret = qemu_fdt_setprop_cell(fdt, "/rtas", call->name,
762                                     i + RTAS_TOKEN_BASE);
763         if (ret < 0) {
764             error_report("Couldn't add rtas token for %s: %s",
765                     call->name, fdt_strerror(ret));
766             return ret;
767         }
768 
769     }
770 
771     lrdr_capacity[0] = cpu_to_be32(max_hotplug_addr >> 32);
772     lrdr_capacity[1] = cpu_to_be32(max_hotplug_addr & 0xffffffff);
773     lrdr_capacity[2] = 0;
774     lrdr_capacity[3] = cpu_to_be32(SPAPR_MEMORY_BLOCK_SIZE);
775     lrdr_capacity[4] = cpu_to_be32(max_cpus/smp_threads);
776     ret = qemu_fdt_setprop(fdt, "/rtas", "ibm,lrdr-capacity", lrdr_capacity,
777                      sizeof(lrdr_capacity));
778     if (ret < 0) {
779         error_report("Couldn't add ibm,lrdr-capacity rtas property");
780         return ret;
781     }
782 
783     return 0;
784 }
785 
786 static void core_rtas_register_types(void)
787 {
788     spapr_rtas_register(RTAS_DISPLAY_CHARACTER, "display-character",
789                         rtas_display_character);
790     spapr_rtas_register(RTAS_POWER_OFF, "power-off", rtas_power_off);
791     spapr_rtas_register(RTAS_SYSTEM_REBOOT, "system-reboot",
792                         rtas_system_reboot);
793     spapr_rtas_register(RTAS_QUERY_CPU_STOPPED_STATE, "query-cpu-stopped-state",
794                         rtas_query_cpu_stopped_state);
795     spapr_rtas_register(RTAS_START_CPU, "start-cpu", rtas_start_cpu);
796     spapr_rtas_register(RTAS_STOP_SELF, "stop-self", rtas_stop_self);
797     spapr_rtas_register(RTAS_IBM_GET_SYSTEM_PARAMETER,
798                         "ibm,get-system-parameter",
799                         rtas_ibm_get_system_parameter);
800     spapr_rtas_register(RTAS_IBM_SET_SYSTEM_PARAMETER,
801                         "ibm,set-system-parameter",
802                         rtas_ibm_set_system_parameter);
803     spapr_rtas_register(RTAS_IBM_OS_TERM, "ibm,os-term",
804                         rtas_ibm_os_term);
805     spapr_rtas_register(RTAS_SET_POWER_LEVEL, "set-power-level",
806                         rtas_set_power_level);
807     spapr_rtas_register(RTAS_GET_POWER_LEVEL, "get-power-level",
808                         rtas_get_power_level);
809     spapr_rtas_register(RTAS_SET_INDICATOR, "set-indicator",
810                         rtas_set_indicator);
811     spapr_rtas_register(RTAS_GET_SENSOR_STATE, "get-sensor-state",
812                         rtas_get_sensor_state);
813     spapr_rtas_register(RTAS_IBM_CONFIGURE_CONNECTOR, "ibm,configure-connector",
814                         rtas_ibm_configure_connector);
815 }
816 
817 type_init(core_rtas_register_types)
818