1#include "qemu/osdep.h"
2#include "qemu/cutils.h"
3#include "qapi/error.h"
4#include "sysemu/hw_accel.h"
5#include "sysemu/runstate.h"
6#include "qemu/log.h"
7#include "qemu/main-loop.h"
8#include "qemu/module.h"
9#include "qemu/error-report.h"
10#include "exec/exec-all.h"
11#include "helper_regs.h"
12#include "hw/ppc/spapr.h"
13#include "hw/ppc/spapr_cpu_core.h"
14#include "mmu-hash64.h"
15#include "cpu-models.h"
16#include "trace.h"
17#include "kvm_ppc.h"
18#include "hw/ppc/fdt.h"
19#include "hw/ppc/spapr_ovec.h"
20#include "mmu-book3s-v3.h"
21#include "hw/mem/memory-device.h"
22
23bool is_ram_address(SpaprMachineState *spapr, hwaddr addr)
24{
25 MachineState *machine = MACHINE(spapr);
26 DeviceMemoryState *dms = machine->device_memory;
27
28 if (addr < machine->ram_size) {
29 return true;
30 }
31 if ((addr >= dms->base)
32 && ((addr - dms->base) < memory_region_size(&dms->mr))) {
33 return true;
34 }
35
36 return false;
37}
38
39
40
41static target_ulong resize_hpt_convert_rc(int ret)
42{
43 if (ret >= 100000) {
44 return H_LONG_BUSY_ORDER_100_SEC;
45 } else if (ret >= 10000) {
46 return H_LONG_BUSY_ORDER_10_SEC;
47 } else if (ret >= 1000) {
48 return H_LONG_BUSY_ORDER_1_SEC;
49 } else if (ret >= 100) {
50 return H_LONG_BUSY_ORDER_100_MSEC;
51 } else if (ret >= 10) {
52 return H_LONG_BUSY_ORDER_10_MSEC;
53 } else if (ret > 0) {
54 return H_LONG_BUSY_ORDER_1_MSEC;
55 }
56
57 switch (ret) {
58 case 0:
59 return H_SUCCESS;
60 case -EPERM:
61 return H_AUTHORITY;
62 case -EINVAL:
63 return H_PARAMETER;
64 case -ENXIO:
65 return H_CLOSED;
66 case -ENOSPC:
67 return H_PTEG_FULL;
68 case -EBUSY:
69 return H_BUSY;
70 case -ENOMEM:
71 return H_NO_MEM;
72 default:
73 return H_HARDWARE;
74 }
75}
76
77static target_ulong h_resize_hpt_prepare(PowerPCCPU *cpu,
78 SpaprMachineState *spapr,
79 target_ulong opcode,
80 target_ulong *args)
81{
82 target_ulong flags = args[0];
83 int shift = args[1];
84 uint64_t current_ram_size;
85 int rc;
86
87 if (spapr->resize_hpt == SPAPR_RESIZE_HPT_DISABLED) {
88 return H_AUTHORITY;
89 }
90
91 if (!spapr->htab_shift) {
92
93 return H_NOT_AVAILABLE;
94 }
95
96 trace_spapr_h_resize_hpt_prepare(flags, shift);
97
98 if (flags != 0) {
99 return H_PARAMETER;
100 }
101
102 if (shift && ((shift < 18) || (shift > 46))) {
103 return H_PARAMETER;
104 }
105
106 current_ram_size = MACHINE(spapr)->ram_size + get_plugged_memory_size();
107
108
109
110
111 if (shift > (spapr_hpt_shift_for_ramsize(current_ram_size) + 1)) {
112 return H_RESOURCE;
113 }
114
115 rc = kvmppc_resize_hpt_prepare(cpu, flags, shift);
116 if (rc != -ENOSYS) {
117 return resize_hpt_convert_rc(rc);
118 }
119
120 if (kvm_enabled()) {
121 return H_HARDWARE;
122 }
123
124 return softmmu_resize_hpt_prepare(cpu, spapr, shift);
125}
126
127static void do_push_sregs_to_kvm_pr(CPUState *cs, run_on_cpu_data data)
128{
129 int ret;
130
131 cpu_synchronize_state(cs);
132
133 ret = kvmppc_put_books_sregs(POWERPC_CPU(cs));
134 if (ret < 0) {
135 error_report("failed to push sregs to KVM: %s", strerror(-ret));
136 exit(1);
137 }
138}
139
140void push_sregs_to_kvm_pr(SpaprMachineState *spapr)
141{
142 CPUState *cs;
143
144
145
146
147
148
149 if (!kvm_enabled() || !spapr->htab) {
150 return;
151 }
152
153 CPU_FOREACH(cs) {
154 run_on_cpu(cs, do_push_sregs_to_kvm_pr, RUN_ON_CPU_NULL);
155 }
156}
157
158static target_ulong h_resize_hpt_commit(PowerPCCPU *cpu,
159 SpaprMachineState *spapr,
160 target_ulong opcode,
161 target_ulong *args)
162{
163 target_ulong flags = args[0];
164 target_ulong shift = args[1];
165 int rc;
166
167 if (spapr->resize_hpt == SPAPR_RESIZE_HPT_DISABLED) {
168 return H_AUTHORITY;
169 }
170
171 if (!spapr->htab_shift) {
172
173 return H_NOT_AVAILABLE;
174 }
175
176 trace_spapr_h_resize_hpt_commit(flags, shift);
177
178 rc = kvmppc_resize_hpt_commit(cpu, flags, shift);
179 if (rc != -ENOSYS) {
180 rc = resize_hpt_convert_rc(rc);
181 if (rc == H_SUCCESS) {
182
183 spapr->htab_shift = shift;
184 }
185 return rc;
186 }
187
188 if (kvm_enabled()) {
189 return H_HARDWARE;
190 }
191
192 return softmmu_resize_hpt_commit(cpu, spapr, flags, shift);
193}
194
195
196
197static target_ulong h_set_sprg0(PowerPCCPU *cpu, SpaprMachineState *spapr,
198 target_ulong opcode, target_ulong *args)
199{
200 cpu_synchronize_state(CPU(cpu));
201 cpu->env.spr[SPR_SPRG0] = args[0];
202
203 return H_SUCCESS;
204}
205
206static target_ulong h_set_dabr(PowerPCCPU *cpu, SpaprMachineState *spapr,
207 target_ulong opcode, target_ulong *args)
208{
209 if (!ppc_has_spr(cpu, SPR_DABR)) {
210 return H_HARDWARE;
211 }
212 cpu_synchronize_state(CPU(cpu));
213
214 if (ppc_has_spr(cpu, SPR_DABRX)) {
215 cpu->env.spr[SPR_DABRX] = 0x3;
216 } else if (!(args[0] & 0x4)) {
217 return H_RESERVED_DABR;
218 }
219
220 cpu->env.spr[SPR_DABR] = args[0];
221 return H_SUCCESS;
222}
223
224static target_ulong h_set_xdabr(PowerPCCPU *cpu, SpaprMachineState *spapr,
225 target_ulong opcode, target_ulong *args)
226{
227 target_ulong dabrx = args[1];
228
229 if (!ppc_has_spr(cpu, SPR_DABR) || !ppc_has_spr(cpu, SPR_DABRX)) {
230 return H_HARDWARE;
231 }
232
233 if ((dabrx & ~0xfULL) != 0 || (dabrx & H_DABRX_HYPERVISOR) != 0
234 || (dabrx & (H_DABRX_KERNEL | H_DABRX_USER)) == 0) {
235 return H_PARAMETER;
236 }
237
238 cpu_synchronize_state(CPU(cpu));
239 cpu->env.spr[SPR_DABRX] = dabrx;
240 cpu->env.spr[SPR_DABR] = args[0];
241
242 return H_SUCCESS;
243}
244
245static target_ulong h_page_init(PowerPCCPU *cpu, SpaprMachineState *spapr,
246 target_ulong opcode, target_ulong *args)
247{
248 target_ulong flags = args[0];
249 hwaddr dst = args[1];
250 hwaddr src = args[2];
251 hwaddr len = TARGET_PAGE_SIZE;
252 uint8_t *pdst, *psrc;
253 target_long ret = H_SUCCESS;
254
255 if (flags & ~(H_ICACHE_SYNCHRONIZE | H_ICACHE_INVALIDATE
256 | H_COPY_PAGE | H_ZERO_PAGE)) {
257 qemu_log_mask(LOG_UNIMP, "h_page_init: Bad flags (" TARGET_FMT_lx "\n",
258 flags);
259 return H_PARAMETER;
260 }
261
262
263 if (!is_ram_address(spapr, dst) || (dst & ~TARGET_PAGE_MASK) != 0) {
264 return H_PARAMETER;
265 }
266 pdst = cpu_physical_memory_map(dst, &len, true);
267 if (!pdst || len != TARGET_PAGE_SIZE) {
268 return H_PARAMETER;
269 }
270
271 if (flags & H_COPY_PAGE) {
272
273 if (!is_ram_address(spapr, src) || (src & ~TARGET_PAGE_MASK) != 0) {
274 ret = H_PARAMETER;
275 goto unmap_out;
276 }
277 psrc = cpu_physical_memory_map(src, &len, false);
278 if (!psrc || len != TARGET_PAGE_SIZE) {
279 ret = H_PARAMETER;
280 goto unmap_out;
281 }
282 memcpy(pdst, psrc, len);
283 cpu_physical_memory_unmap(psrc, len, 0, len);
284 } else if (flags & H_ZERO_PAGE) {
285 memset(pdst, 0, len);
286 }
287
288 if (kvm_enabled() && (flags & H_ICACHE_SYNCHRONIZE) != 0) {
289 kvmppc_dcbst_range(cpu, pdst, len);
290 }
291 if (flags & (H_ICACHE_SYNCHRONIZE | H_ICACHE_INVALIDATE)) {
292 if (kvm_enabled()) {
293 kvmppc_icbi_range(cpu, pdst, len);
294 } else {
295 tb_flush(CPU(cpu));
296 }
297 }
298
299unmap_out:
300 cpu_physical_memory_unmap(pdst, TARGET_PAGE_SIZE, 1, len);
301 return ret;
302}
303
304#define FLAGS_REGISTER_VPA 0x0000200000000000ULL
305#define FLAGS_REGISTER_DTL 0x0000400000000000ULL
306#define FLAGS_REGISTER_SLBSHADOW 0x0000600000000000ULL
307#define FLAGS_DEREGISTER_VPA 0x0000a00000000000ULL
308#define FLAGS_DEREGISTER_DTL 0x0000c00000000000ULL
309#define FLAGS_DEREGISTER_SLBSHADOW 0x0000e00000000000ULL
310
311static target_ulong register_vpa(PowerPCCPU *cpu, target_ulong vpa)
312{
313 CPUState *cs = CPU(cpu);
314 CPUPPCState *env = &cpu->env;
315 SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
316 uint16_t size;
317 uint8_t tmp;
318
319 if (vpa == 0) {
320 hcall_dprintf("Can't cope with registering a VPA at logical 0\n");
321 return H_HARDWARE;
322 }
323
324 if (vpa % env->dcache_line_size) {
325 return H_PARAMETER;
326 }
327
328
329 size = lduw_be_phys(cs->as, vpa + 0x4);
330
331 if (size < VPA_MIN_SIZE) {
332 return H_PARAMETER;
333 }
334
335
336 if ((vpa / 4096) != ((vpa + size - 1) / 4096)) {
337 return H_PARAMETER;
338 }
339
340 spapr_cpu->vpa_addr = vpa;
341
342 tmp = ldub_phys(cs->as, spapr_cpu->vpa_addr + VPA_SHARED_PROC_OFFSET);
343 tmp |= VPA_SHARED_PROC_VAL;
344 stb_phys(cs->as, spapr_cpu->vpa_addr + VPA_SHARED_PROC_OFFSET, tmp);
345
346 return H_SUCCESS;
347}
348
349static target_ulong deregister_vpa(PowerPCCPU *cpu, target_ulong vpa)
350{
351 SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
352
353 if (spapr_cpu->slb_shadow_addr) {
354 return H_RESOURCE;
355 }
356
357 if (spapr_cpu->dtl_addr) {
358 return H_RESOURCE;
359 }
360
361 spapr_cpu->vpa_addr = 0;
362 return H_SUCCESS;
363}
364
365static target_ulong register_slb_shadow(PowerPCCPU *cpu, target_ulong addr)
366{
367 SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
368 uint32_t size;
369
370 if (addr == 0) {
371 hcall_dprintf("Can't cope with SLB shadow at logical 0\n");
372 return H_HARDWARE;
373 }
374
375 size = ldl_be_phys(CPU(cpu)->as, addr + 0x4);
376 if (size < 0x8) {
377 return H_PARAMETER;
378 }
379
380 if ((addr / 4096) != ((addr + size - 1) / 4096)) {
381 return H_PARAMETER;
382 }
383
384 if (!spapr_cpu->vpa_addr) {
385 return H_RESOURCE;
386 }
387
388 spapr_cpu->slb_shadow_addr = addr;
389 spapr_cpu->slb_shadow_size = size;
390
391 return H_SUCCESS;
392}
393
394static target_ulong deregister_slb_shadow(PowerPCCPU *cpu, target_ulong addr)
395{
396 SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
397
398 spapr_cpu->slb_shadow_addr = 0;
399 spapr_cpu->slb_shadow_size = 0;
400 return H_SUCCESS;
401}
402
403static target_ulong register_dtl(PowerPCCPU *cpu, target_ulong addr)
404{
405 SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
406 uint32_t size;
407
408 if (addr == 0) {
409 hcall_dprintf("Can't cope with DTL at logical 0\n");
410 return H_HARDWARE;
411 }
412
413 size = ldl_be_phys(CPU(cpu)->as, addr + 0x4);
414
415 if (size < 48) {
416 return H_PARAMETER;
417 }
418
419 if (!spapr_cpu->vpa_addr) {
420 return H_RESOURCE;
421 }
422
423 spapr_cpu->dtl_addr = addr;
424 spapr_cpu->dtl_size = size;
425
426 return H_SUCCESS;
427}
428
429static target_ulong deregister_dtl(PowerPCCPU *cpu, target_ulong addr)
430{
431 SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
432
433 spapr_cpu->dtl_addr = 0;
434 spapr_cpu->dtl_size = 0;
435
436 return H_SUCCESS;
437}
438
439static target_ulong h_register_vpa(PowerPCCPU *cpu, SpaprMachineState *spapr,
440 target_ulong opcode, target_ulong *args)
441{
442 target_ulong flags = args[0];
443 target_ulong procno = args[1];
444 target_ulong vpa = args[2];
445 target_ulong ret = H_PARAMETER;
446 PowerPCCPU *tcpu;
447
448 tcpu = spapr_find_cpu(procno);
449 if (!tcpu) {
450 return H_PARAMETER;
451 }
452
453 switch (flags) {
454 case FLAGS_REGISTER_VPA:
455 ret = register_vpa(tcpu, vpa);
456 break;
457
458 case FLAGS_DEREGISTER_VPA:
459 ret = deregister_vpa(tcpu, vpa);
460 break;
461
462 case FLAGS_REGISTER_SLBSHADOW:
463 ret = register_slb_shadow(tcpu, vpa);
464 break;
465
466 case FLAGS_DEREGISTER_SLBSHADOW:
467 ret = deregister_slb_shadow(tcpu, vpa);
468 break;
469
470 case FLAGS_REGISTER_DTL:
471 ret = register_dtl(tcpu, vpa);
472 break;
473
474 case FLAGS_DEREGISTER_DTL:
475 ret = deregister_dtl(tcpu, vpa);
476 break;
477 }
478
479 return ret;
480}
481
482static target_ulong h_cede(PowerPCCPU *cpu, SpaprMachineState *spapr,
483 target_ulong opcode, target_ulong *args)
484{
485 CPUPPCState *env = &cpu->env;
486 CPUState *cs = CPU(cpu);
487 SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
488
489 env->msr |= (1ULL << MSR_EE);
490 hreg_compute_hflags(env);
491
492 if (spapr_cpu->prod) {
493 spapr_cpu->prod = false;
494 return H_SUCCESS;
495 }
496
497 if (!cpu_has_work(cs)) {
498 cs->halted = 1;
499 cs->exception_index = EXCP_HLT;
500 cs->exit_request = 1;
501 }
502
503 return H_SUCCESS;
504}
505
506
507
508
509
510static target_ulong h_confer_self(PowerPCCPU *cpu)
511{
512 CPUState *cs = CPU(cpu);
513 SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
514
515 if (spapr_cpu->prod) {
516 spapr_cpu->prod = false;
517 return H_SUCCESS;
518 }
519 cs->halted = 1;
520 cs->exception_index = EXCP_HALTED;
521 cs->exit_request = 1;
522
523 return H_SUCCESS;
524}
525
526static target_ulong h_join(PowerPCCPU *cpu, SpaprMachineState *spapr,
527 target_ulong opcode, target_ulong *args)
528{
529 CPUPPCState *env = &cpu->env;
530 CPUState *cs;
531 bool last_unjoined = true;
532
533 if (env->msr & (1ULL << MSR_EE)) {
534 return H_BAD_MODE;
535 }
536
537
538
539
540
541
542 CPU_FOREACH(cs) {
543 PowerPCCPU *c = POWERPC_CPU(cs);
544 CPUPPCState *e = &c->env;
545 if (c == cpu) {
546 continue;
547 }
548
549
550 if (!cs->halted || (e->msr & (1ULL << MSR_EE))) {
551 last_unjoined = false;
552 break;
553 }
554 }
555 if (last_unjoined) {
556 return H_CONTINUE;
557 }
558
559 return h_confer_self(cpu);
560}
561
562static target_ulong h_confer(PowerPCCPU *cpu, SpaprMachineState *spapr,
563 target_ulong opcode, target_ulong *args)
564{
565 target_long target = args[0];
566 uint32_t dispatch = args[1];
567 CPUState *cs = CPU(cpu);
568 SpaprCpuState *spapr_cpu;
569
570
571
572
573
574 if (target != -1) {
575 PowerPCCPU *target_cpu = spapr_find_cpu(target);
576 uint32_t target_dispatch;
577
578 if (!target_cpu) {
579 return H_PARAMETER;
580 }
581
582
583
584
585
586 if (cpu == target_cpu) {
587 return h_confer_self(cpu);
588 }
589
590 spapr_cpu = spapr_cpu_state(target_cpu);
591 if (!spapr_cpu->vpa_addr || ((dispatch & 1) == 0)) {
592 return H_SUCCESS;
593 }
594
595 target_dispatch = ldl_be_phys(cs->as,
596 spapr_cpu->vpa_addr + VPA_DISPATCH_COUNTER);
597 if (target_dispatch != dispatch) {
598 return H_SUCCESS;
599 }
600
601
602
603
604
605
606
607
608 }
609
610 cs->exception_index = EXCP_YIELD;
611 cs->exit_request = 1;
612 cpu_loop_exit(cs);
613
614 return H_SUCCESS;
615}
616
617static target_ulong h_prod(PowerPCCPU *cpu, SpaprMachineState *spapr,
618 target_ulong opcode, target_ulong *args)
619{
620 target_long target = args[0];
621 PowerPCCPU *tcpu;
622 CPUState *cs;
623 SpaprCpuState *spapr_cpu;
624
625 tcpu = spapr_find_cpu(target);
626 cs = CPU(tcpu);
627 if (!cs) {
628 return H_PARAMETER;
629 }
630
631 spapr_cpu = spapr_cpu_state(tcpu);
632 spapr_cpu->prod = true;
633 cs->halted = 0;
634 qemu_cpu_kick(cs);
635
636 return H_SUCCESS;
637}
638
639static target_ulong h_rtas(PowerPCCPU *cpu, SpaprMachineState *spapr,
640 target_ulong opcode, target_ulong *args)
641{
642 target_ulong rtas_r3 = args[0];
643 uint32_t token = rtas_ld(rtas_r3, 0);
644 uint32_t nargs = rtas_ld(rtas_r3, 1);
645 uint32_t nret = rtas_ld(rtas_r3, 2);
646
647 return spapr_rtas_call(cpu, spapr, token, nargs, rtas_r3 + 12,
648 nret, rtas_r3 + 12 + 4*nargs);
649}
650
651static target_ulong h_logical_load(PowerPCCPU *cpu, SpaprMachineState *spapr,
652 target_ulong opcode, target_ulong *args)
653{
654 CPUState *cs = CPU(cpu);
655 target_ulong size = args[0];
656 target_ulong addr = args[1];
657
658 switch (size) {
659 case 1:
660 args[0] = ldub_phys(cs->as, addr);
661 return H_SUCCESS;
662 case 2:
663 args[0] = lduw_phys(cs->as, addr);
664 return H_SUCCESS;
665 case 4:
666 args[0] = ldl_phys(cs->as, addr);
667 return H_SUCCESS;
668 case 8:
669 args[0] = ldq_phys(cs->as, addr);
670 return H_SUCCESS;
671 }
672 return H_PARAMETER;
673}
674
675static target_ulong h_logical_store(PowerPCCPU *cpu, SpaprMachineState *spapr,
676 target_ulong opcode, target_ulong *args)
677{
678 CPUState *cs = CPU(cpu);
679
680 target_ulong size = args[0];
681 target_ulong addr = args[1];
682 target_ulong val = args[2];
683
684 switch (size) {
685 case 1:
686 stb_phys(cs->as, addr, val);
687 return H_SUCCESS;
688 case 2:
689 stw_phys(cs->as, addr, val);
690 return H_SUCCESS;
691 case 4:
692 stl_phys(cs->as, addr, val);
693 return H_SUCCESS;
694 case 8:
695 stq_phys(cs->as, addr, val);
696 return H_SUCCESS;
697 }
698 return H_PARAMETER;
699}
700
701static target_ulong h_logical_memop(PowerPCCPU *cpu, SpaprMachineState *spapr,
702 target_ulong opcode, target_ulong *args)
703{
704 CPUState *cs = CPU(cpu);
705
706 target_ulong dst = args[0];
707 target_ulong src = args[1];
708 target_ulong esize = args[2];
709 target_ulong count = args[3];
710 target_ulong op = args[4];
711 uint64_t tmp;
712 unsigned int mask = (1 << esize) - 1;
713 int step = 1 << esize;
714
715 if (count > 0x80000000) {
716 return H_PARAMETER;
717 }
718
719 if ((dst & mask) || (src & mask) || (op > 1)) {
720 return H_PARAMETER;
721 }
722
723 if (dst >= src && dst < (src + (count << esize))) {
724 dst = dst + ((count - 1) << esize);
725 src = src + ((count - 1) << esize);
726 step = -step;
727 }
728
729 while (count--) {
730 switch (esize) {
731 case 0:
732 tmp = ldub_phys(cs->as, src);
733 break;
734 case 1:
735 tmp = lduw_phys(cs->as, src);
736 break;
737 case 2:
738 tmp = ldl_phys(cs->as, src);
739 break;
740 case 3:
741 tmp = ldq_phys(cs->as, src);
742 break;
743 default:
744 return H_PARAMETER;
745 }
746 if (op == 1) {
747 tmp = ~tmp;
748 }
749 switch (esize) {
750 case 0:
751 stb_phys(cs->as, dst, tmp);
752 break;
753 case 1:
754 stw_phys(cs->as, dst, tmp);
755 break;
756 case 2:
757 stl_phys(cs->as, dst, tmp);
758 break;
759 case 3:
760 stq_phys(cs->as, dst, tmp);
761 break;
762 }
763 dst = dst + step;
764 src = src + step;
765 }
766
767 return H_SUCCESS;
768}
769
770static target_ulong h_logical_icbi(PowerPCCPU *cpu, SpaprMachineState *spapr,
771 target_ulong opcode, target_ulong *args)
772{
773
774 return H_SUCCESS;
775}
776
777static target_ulong h_logical_dcbf(PowerPCCPU *cpu, SpaprMachineState *spapr,
778 target_ulong opcode, target_ulong *args)
779{
780
781 return H_SUCCESS;
782}
783
784static target_ulong h_set_mode_resource_le(PowerPCCPU *cpu,
785 SpaprMachineState *spapr,
786 target_ulong mflags,
787 target_ulong value1,
788 target_ulong value2)
789{
790 if (value1) {
791 return H_P3;
792 }
793 if (value2) {
794 return H_P4;
795 }
796
797 switch (mflags) {
798 case H_SET_MODE_ENDIAN_BIG:
799 spapr_set_all_lpcrs(0, LPCR_ILE);
800 spapr_pci_switch_vga(spapr, true);
801 return H_SUCCESS;
802
803 case H_SET_MODE_ENDIAN_LITTLE:
804 spapr_set_all_lpcrs(LPCR_ILE, LPCR_ILE);
805 spapr_pci_switch_vga(spapr, false);
806 return H_SUCCESS;
807 }
808
809 return H_UNSUPPORTED_FLAG;
810}
811
812static target_ulong h_set_mode_resource_addr_trans_mode(PowerPCCPU *cpu,
813 target_ulong mflags,
814 target_ulong value1,
815 target_ulong value2)
816{
817 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
818
819 if (!(pcc->insns_flags2 & PPC2_ISA207S)) {
820 return H_P2;
821 }
822 if (value1) {
823 return H_P3;
824 }
825 if (value2) {
826 return H_P4;
827 }
828
829 if (mflags == 1) {
830
831 return H_UNSUPPORTED_FLAG;
832 }
833
834 if (mflags == 2 && (pcc->insns_flags2 & PPC2_ISA310)) {
835
836 return H_UNSUPPORTED_FLAG;
837 }
838
839 spapr_set_all_lpcrs(mflags << LPCR_AIL_SHIFT, LPCR_AIL);
840
841 return H_SUCCESS;
842}
843
844static target_ulong h_set_mode(PowerPCCPU *cpu, SpaprMachineState *spapr,
845 target_ulong opcode, target_ulong *args)
846{
847 target_ulong resource = args[1];
848 target_ulong ret = H_P2;
849
850 switch (resource) {
851 case H_SET_MODE_RESOURCE_LE:
852 ret = h_set_mode_resource_le(cpu, spapr, args[0], args[2], args[3]);
853 break;
854 case H_SET_MODE_RESOURCE_ADDR_TRANS_MODE:
855 ret = h_set_mode_resource_addr_trans_mode(cpu, args[0],
856 args[2], args[3]);
857 break;
858 }
859
860 return ret;
861}
862
863static target_ulong h_clean_slb(PowerPCCPU *cpu, SpaprMachineState *spapr,
864 target_ulong opcode, target_ulong *args)
865{
866 qemu_log_mask(LOG_UNIMP, "Unimplemented SPAPR hcall 0x"TARGET_FMT_lx"%s\n",
867 opcode, " (H_CLEAN_SLB)");
868 return H_FUNCTION;
869}
870
871static target_ulong h_invalidate_pid(PowerPCCPU *cpu, SpaprMachineState *spapr,
872 target_ulong opcode, target_ulong *args)
873{
874 qemu_log_mask(LOG_UNIMP, "Unimplemented SPAPR hcall 0x"TARGET_FMT_lx"%s\n",
875 opcode, " (H_INVALIDATE_PID)");
876 return H_FUNCTION;
877}
878
879static void spapr_check_setup_free_hpt(SpaprMachineState *spapr,
880 uint64_t patbe_old, uint64_t patbe_new)
881{
882
883
884
885
886
887
888
889
890
891
892 if ((patbe_old & PATE1_GR) == (patbe_new & PATE1_GR)) {
893
894 } else if (!(patbe_old & PATE1_GR)) {
895
896 spapr_free_hpt(spapr);
897 } else if (!(patbe_new & PATE1_GR)) {
898
899 spapr_setup_hpt(spapr);
900 }
901 return;
902}
903
904#define FLAGS_MASK 0x01FULL
905#define FLAG_MODIFY 0x10
906#define FLAG_REGISTER 0x08
907#define FLAG_RADIX 0x04
908#define FLAG_HASH_PROC_TBL 0x02
909#define FLAG_GTSE 0x01
910
911static target_ulong h_register_process_table(PowerPCCPU *cpu,
912 SpaprMachineState *spapr,
913 target_ulong opcode,
914 target_ulong *args)
915{
916 target_ulong flags = args[0];
917 target_ulong proc_tbl = args[1];
918 target_ulong page_size = args[2];
919 target_ulong table_size = args[3];
920 target_ulong update_lpcr = 0;
921 uint64_t cproc;
922
923 if (flags & ~FLAGS_MASK) {
924 return H_PARAMETER;
925 }
926 if (flags & FLAG_MODIFY) {
927 if (flags & FLAG_REGISTER) {
928 if (flags & FLAG_RADIX) {
929 if (proc_tbl & 0xfff || proc_tbl >> 60) {
930 return H_P2;
931 } else if (page_size) {
932 return H_P3;
933 } else if (table_size > 24) {
934 return H_P4;
935 }
936 cproc = PATE1_GR | proc_tbl | table_size;
937 } else {
938 if (flags & FLAG_HASH_PROC_TBL) {
939
940
941 return H_PARAMETER;
942 } else {
943 if (proc_tbl >> 38) {
944 return H_P2;
945 } else if (page_size & ~0x7) {
946 return H_P3;
947 } else if (table_size > 24) {
948 return H_P4;
949 }
950 }
951 cproc = (proc_tbl << 25) | page_size << 5 | table_size;
952 }
953
954 } else {
955
956
957
958
959
960 cproc = spapr->patb_entry & PATE1_GR;
961 }
962 } else {
963 if (!(flags & FLAG_RADIX) != !(spapr->patb_entry & PATE1_GR)) {
964
965 return H_PARAMETER;
966 }
967 cproc = spapr->patb_entry;
968 }
969
970
971 spapr_check_setup_free_hpt(spapr, spapr->patb_entry, cproc);
972
973 spapr->patb_entry = cproc;
974
975
976 if (flags & FLAG_RADIX)
977 update_lpcr |= (LPCR_UPRT | LPCR_HR);
978 else if (flags & FLAG_HASH_PROC_TBL)
979 update_lpcr |= LPCR_UPRT;
980 if (flags & FLAG_GTSE)
981 update_lpcr |= LPCR_GTSE;
982
983 spapr_set_all_lpcrs(update_lpcr, LPCR_UPRT | LPCR_HR | LPCR_GTSE);
984
985 if (kvm_enabled()) {
986 return kvmppc_configure_v3_mmu(cpu, flags & FLAG_RADIX,
987 flags & FLAG_GTSE, cproc);
988 }
989 return H_SUCCESS;
990}
991
992#define H_SIGNAL_SYS_RESET_ALL -1
993#define H_SIGNAL_SYS_RESET_ALLBUTSELF -2
994
995static target_ulong h_signal_sys_reset(PowerPCCPU *cpu,
996 SpaprMachineState *spapr,
997 target_ulong opcode, target_ulong *args)
998{
999 target_long target = args[0];
1000 CPUState *cs;
1001
1002 if (target < 0) {
1003
1004 if (target < H_SIGNAL_SYS_RESET_ALLBUTSELF) {
1005 return H_PARAMETER;
1006 }
1007
1008 CPU_FOREACH(cs) {
1009 PowerPCCPU *c = POWERPC_CPU(cs);
1010
1011 if (target == H_SIGNAL_SYS_RESET_ALLBUTSELF) {
1012 if (c == cpu) {
1013 continue;
1014 }
1015 }
1016 run_on_cpu(cs, spapr_do_system_reset_on_cpu, RUN_ON_CPU_NULL);
1017 }
1018 return H_SUCCESS;
1019
1020 } else {
1021
1022 cs = CPU(spapr_find_cpu(target));
1023 if (cs) {
1024 run_on_cpu(cs, spapr_do_system_reset_on_cpu, RUN_ON_CPU_NULL);
1025 return H_SUCCESS;
1026 }
1027 return H_PARAMETER;
1028 }
1029}
1030
1031
1032static uint32_t cas_check_pvr(PowerPCCPU *cpu, uint32_t max_compat,
1033 target_ulong *addr, bool *raw_mode_supported)
1034{
1035 bool explicit_match = false;
1036 uint32_t best_compat = 0;
1037 int i;
1038
1039
1040
1041
1042
1043
1044 for (i = 0; i < 512; ++i) {
1045 uint32_t pvr, pvr_mask;
1046
1047 pvr_mask = ldl_be_phys(&address_space_memory, *addr);
1048 pvr = ldl_be_phys(&address_space_memory, *addr + 4);
1049 *addr += 8;
1050
1051 if (~pvr_mask & pvr) {
1052 break;
1053 }
1054
1055 if ((cpu->env.spr[SPR_PVR] & pvr_mask) == (pvr & pvr_mask)) {
1056 explicit_match = true;
1057 } else {
1058 if (ppc_check_compat(cpu, pvr, best_compat, max_compat)) {
1059 best_compat = pvr;
1060 }
1061 }
1062 }
1063
1064 *raw_mode_supported = explicit_match;
1065
1066
1067 trace_spapr_cas_pvr(cpu->compat_pvr, explicit_match, best_compat);
1068
1069 return best_compat;
1070}
1071
1072static
1073target_ulong do_client_architecture_support(PowerPCCPU *cpu,
1074 SpaprMachineState *spapr,
1075 target_ulong vec,
1076 target_ulong fdt_bufsize)
1077{
1078 target_ulong ov_table;
1079 uint32_t cas_pvr;
1080 SpaprOptionVector *ov1_guest, *ov5_guest;
1081 bool guest_radix;
1082 bool raw_mode_supported = false;
1083 bool guest_xive;
1084 CPUState *cs;
1085 void *fdt;
1086 uint32_t max_compat = spapr->max_compat_pvr;
1087
1088
1089 CPU_FOREACH(cs) {
1090 if (cs == CPU(cpu)) {
1091 continue;
1092 }
1093 if (!cs->halted) {
1094 warn_report("guest has multiple active vCPUs at CAS, which is not allowed");
1095 return H_MULTI_THREADS_ACTIVE;
1096 }
1097 }
1098
1099 cas_pvr = cas_check_pvr(cpu, max_compat, &vec, &raw_mode_supported);
1100 if (!cas_pvr && (!raw_mode_supported || max_compat)) {
1101
1102
1103
1104
1105
1106 error_report("Couldn't negotiate a suitable PVR during CAS");
1107 return H_HARDWARE;
1108 }
1109
1110
1111 if (cpu->compat_pvr != cas_pvr) {
1112 Error *local_err = NULL;
1113
1114 if (ppc_set_compat_all(cas_pvr, &local_err) < 0) {
1115
1116
1117
1118 if (!raw_mode_supported) {
1119 error_report_err(local_err);
1120 return H_HARDWARE;
1121 }
1122 error_free(local_err);
1123 }
1124 }
1125
1126
1127 ov_table = vec;
1128
1129 ov1_guest = spapr_ovec_parse_vector(ov_table, 1);
1130 if (!ov1_guest) {
1131 warn_report("guest didn't provide option vector 1");
1132 return H_PARAMETER;
1133 }
1134 ov5_guest = spapr_ovec_parse_vector(ov_table, 5);
1135 if (!ov5_guest) {
1136 spapr_ovec_cleanup(ov1_guest);
1137 warn_report("guest didn't provide option vector 5");
1138 return H_PARAMETER;
1139 }
1140 if (spapr_ovec_test(ov5_guest, OV5_MMU_BOTH)) {
1141 error_report("guest requested hash and radix MMU, which is invalid.");
1142 exit(EXIT_FAILURE);
1143 }
1144 if (spapr_ovec_test(ov5_guest, OV5_XIVE_BOTH)) {
1145 error_report("guest requested an invalid interrupt mode");
1146 exit(EXIT_FAILURE);
1147 }
1148
1149 guest_radix = spapr_ovec_test(ov5_guest, OV5_MMU_RADIX_300);
1150
1151 guest_xive = spapr_ovec_test(ov5_guest, OV5_XIVE_EXPLOIT);
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164 if (!guest_radix && !spapr_ovec_test(ov5_guest, OV5_HPT_RESIZE)) {
1165 int maxshift = spapr_hpt_shift_for_ramsize(MACHINE(spapr)->maxram_size);
1166
1167 if (spapr->resize_hpt == SPAPR_RESIZE_HPT_REQUIRED) {
1168 error_report(
1169 "h_client_architecture_support: Guest doesn't support HPT resizing, but resize-hpt=required");
1170 exit(1);
1171 }
1172
1173 if (spapr->htab_shift < maxshift) {
1174
1175
1176
1177
1178 spapr_reallocate_hpt(spapr, maxshift, &error_fatal);
1179 push_sregs_to_kvm_pr(spapr);
1180 }
1181 }
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192 spapr_ovec_intersect(spapr->ov5_cas, spapr->ov5, ov5_guest);
1193 spapr_ovec_cleanup(ov5_guest);
1194
1195 spapr_check_mmu_mode(guest_radix);
1196
1197 spapr->cas_pre_isa3_guest = !spapr_ovec_test(ov1_guest, OV1_PPC_3_00);
1198 spapr_ovec_cleanup(ov1_guest);
1199
1200
1201
1202
1203
1204 if (guest_xive) {
1205 if (!spapr->irq->xive) {
1206 error_report(
1207"Guest requested unavailable interrupt mode (XIVE), try the ic-mode=xive or ic-mode=dual machine property");
1208 exit(EXIT_FAILURE);
1209 }
1210 } else {
1211 if (!spapr->irq->xics) {
1212 error_report(
1213"Guest requested unavailable interrupt mode (XICS), either don't set the ic-mode machine property or try ic-mode=xics or ic-mode=dual");
1214 exit(EXIT_FAILURE);
1215 }
1216 }
1217
1218 spapr_irq_update_active_intc(spapr);
1219
1220
1221
1222
1223
1224 spapr_drc_reset_all(spapr);
1225 spapr_clear_pending_hotplug_events(spapr);
1226
1227
1228
1229
1230
1231 if ((spapr->patb_entry & PATE1_GR) && !guest_radix) {
1232
1233 spapr_setup_hpt(spapr);
1234 }
1235
1236 fdt = spapr_build_fdt(spapr, spapr->vof != NULL, fdt_bufsize);
1237 g_free(spapr->fdt_blob);
1238 spapr->fdt_size = fdt_totalsize(fdt);
1239 spapr->fdt_initial_size = spapr->fdt_size;
1240 spapr->fdt_blob = fdt;
1241
1242 return H_SUCCESS;
1243}
1244
1245static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
1246 SpaprMachineState *spapr,
1247 target_ulong opcode,
1248 target_ulong *args)
1249{
1250 target_ulong vec = ppc64_phys_to_real(args[0]);
1251 target_ulong fdt_buf = args[1];
1252 target_ulong fdt_bufsize = args[2];
1253 target_ulong ret;
1254 SpaprDeviceTreeUpdateHeader hdr = { .version_id = 1 };
1255
1256 if (fdt_bufsize < sizeof(hdr)) {
1257 error_report("SLOF provided insufficient CAS buffer "
1258 TARGET_FMT_lu " (min: %zu)", fdt_bufsize, sizeof(hdr));
1259 exit(EXIT_FAILURE);
1260 }
1261
1262 fdt_bufsize -= sizeof(hdr);
1263
1264 ret = do_client_architecture_support(cpu, spapr, vec, fdt_bufsize);
1265 if (ret == H_SUCCESS) {
1266 _FDT((fdt_pack(spapr->fdt_blob)));
1267 spapr->fdt_size = fdt_totalsize(spapr->fdt_blob);
1268 spapr->fdt_initial_size = spapr->fdt_size;
1269
1270 cpu_physical_memory_write(fdt_buf, &hdr, sizeof(hdr));
1271 cpu_physical_memory_write(fdt_buf + sizeof(hdr), spapr->fdt_blob,
1272 spapr->fdt_size);
1273 trace_spapr_cas_continue(spapr->fdt_size + sizeof(hdr));
1274 }
1275
1276 return ret;
1277}
1278
1279target_ulong spapr_vof_client_architecture_support(MachineState *ms,
1280 CPUState *cs,
1281 target_ulong ovec_addr)
1282{
1283 SpaprMachineState *spapr = SPAPR_MACHINE(ms);
1284
1285 target_ulong ret = do_client_architecture_support(POWERPC_CPU(cs), spapr,
1286 ovec_addr, FDT_MAX_SIZE);
1287
1288
1289
1290
1291
1292
1293 spapr_vof_client_dt_finalize(spapr, spapr->fdt_blob);
1294
1295 return ret;
1296}
1297
1298static target_ulong h_get_cpu_characteristics(PowerPCCPU *cpu,
1299 SpaprMachineState *spapr,
1300 target_ulong opcode,
1301 target_ulong *args)
1302{
1303 uint64_t characteristics = H_CPU_CHAR_HON_BRANCH_HINTS &
1304 ~H_CPU_CHAR_THR_RECONF_TRIG;
1305 uint64_t behaviour = H_CPU_BEHAV_FAVOUR_SECURITY;
1306 uint8_t safe_cache = spapr_get_cap(spapr, SPAPR_CAP_CFPC);
1307 uint8_t safe_bounds_check = spapr_get_cap(spapr, SPAPR_CAP_SBBC);
1308 uint8_t safe_indirect_branch = spapr_get_cap(spapr, SPAPR_CAP_IBS);
1309 uint8_t count_cache_flush_assist = spapr_get_cap(spapr,
1310 SPAPR_CAP_CCF_ASSIST);
1311
1312 switch (safe_cache) {
1313 case SPAPR_CAP_WORKAROUND:
1314 characteristics |= H_CPU_CHAR_L1D_FLUSH_ORI30;
1315 characteristics |= H_CPU_CHAR_L1D_FLUSH_TRIG2;
1316 characteristics |= H_CPU_CHAR_L1D_THREAD_PRIV;
1317 behaviour |= H_CPU_BEHAV_L1D_FLUSH_PR;
1318 break;
1319 case SPAPR_CAP_FIXED:
1320 behaviour |= H_CPU_BEHAV_NO_L1D_FLUSH_ENTRY;
1321 behaviour |= H_CPU_BEHAV_NO_L1D_FLUSH_UACCESS;
1322 break;
1323 default:
1324 assert(safe_cache == SPAPR_CAP_BROKEN);
1325 behaviour |= H_CPU_BEHAV_L1D_FLUSH_PR;
1326 break;
1327 }
1328
1329 switch (safe_bounds_check) {
1330 case SPAPR_CAP_WORKAROUND:
1331 characteristics |= H_CPU_CHAR_SPEC_BAR_ORI31;
1332 behaviour |= H_CPU_BEHAV_BNDS_CHK_SPEC_BAR;
1333 break;
1334 case SPAPR_CAP_FIXED:
1335 break;
1336 default:
1337 assert(safe_bounds_check == SPAPR_CAP_BROKEN);
1338 behaviour |= H_CPU_BEHAV_BNDS_CHK_SPEC_BAR;
1339 break;
1340 }
1341
1342 switch (safe_indirect_branch) {
1343 case SPAPR_CAP_FIXED_NA:
1344 break;
1345 case SPAPR_CAP_FIXED_CCD:
1346 characteristics |= H_CPU_CHAR_CACHE_COUNT_DIS;
1347 break;
1348 case SPAPR_CAP_FIXED_IBS:
1349 characteristics |= H_CPU_CHAR_BCCTRL_SERIALISED;
1350 break;
1351 case SPAPR_CAP_WORKAROUND:
1352 behaviour |= H_CPU_BEHAV_FLUSH_COUNT_CACHE;
1353 if (count_cache_flush_assist) {
1354 characteristics |= H_CPU_CHAR_BCCTR_FLUSH_ASSIST;
1355 }
1356 break;
1357 default:
1358 assert(safe_indirect_branch == SPAPR_CAP_BROKEN);
1359 break;
1360 }
1361
1362 args[0] = characteristics;
1363 args[1] = behaviour;
1364 return H_SUCCESS;
1365}
1366
1367static target_ulong h_update_dt(PowerPCCPU *cpu, SpaprMachineState *spapr,
1368 target_ulong opcode, target_ulong *args)
1369{
1370 target_ulong dt = ppc64_phys_to_real(args[0]);
1371 struct fdt_header hdr = { 0 };
1372 unsigned cb;
1373 SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
1374 void *fdt;
1375
1376 cpu_physical_memory_read(dt, &hdr, sizeof(hdr));
1377 cb = fdt32_to_cpu(hdr.totalsize);
1378
1379 if (!smc->update_dt_enabled) {
1380 return H_SUCCESS;
1381 }
1382
1383
1384 if (cb > spapr->fdt_initial_size * 2) {
1385 trace_spapr_update_dt_failed_size(spapr->fdt_initial_size, cb,
1386 fdt32_to_cpu(hdr.magic));
1387 return H_PARAMETER;
1388 }
1389
1390 fdt = g_malloc0(cb);
1391 cpu_physical_memory_read(dt, fdt, cb);
1392
1393
1394 if (fdt_check_full(fdt, cb)) {
1395 trace_spapr_update_dt_failed_check(spapr->fdt_initial_size, cb,
1396 fdt32_to_cpu(hdr.magic));
1397 return H_PARAMETER;
1398 }
1399
1400 g_free(spapr->fdt_blob);
1401 spapr->fdt_size = cb;
1402 spapr->fdt_blob = fdt;
1403 trace_spapr_update_dt(cb);
1404
1405 return H_SUCCESS;
1406}
1407
1408static spapr_hcall_fn papr_hypercall_table[(MAX_HCALL_OPCODE / 4) + 1];
1409static spapr_hcall_fn kvmppc_hypercall_table[KVMPPC_HCALL_MAX - KVMPPC_HCALL_BASE + 1];
1410static spapr_hcall_fn svm_hypercall_table[(SVM_HCALL_MAX - SVM_HCALL_BASE) / 4 + 1];
1411
1412void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn)
1413{
1414 spapr_hcall_fn *slot;
1415
1416 if (opcode <= MAX_HCALL_OPCODE) {
1417 assert((opcode & 0x3) == 0);
1418
1419 slot = &papr_hypercall_table[opcode / 4];
1420 } else if (opcode >= SVM_HCALL_BASE && opcode <= SVM_HCALL_MAX) {
1421
1422 assert((opcode & 0x3) == 0);
1423
1424 slot = &svm_hypercall_table[(opcode - SVM_HCALL_BASE) / 4];
1425 } else {
1426 assert((opcode >= KVMPPC_HCALL_BASE) && (opcode <= KVMPPC_HCALL_MAX));
1427
1428 slot = &kvmppc_hypercall_table[opcode - KVMPPC_HCALL_BASE];
1429 }
1430
1431 assert(!(*slot));
1432 *slot = fn;
1433}
1434
1435target_ulong spapr_hypercall(PowerPCCPU *cpu, target_ulong opcode,
1436 target_ulong *args)
1437{
1438 SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
1439
1440 if ((opcode <= MAX_HCALL_OPCODE)
1441 && ((opcode & 0x3) == 0)) {
1442 spapr_hcall_fn fn = papr_hypercall_table[opcode / 4];
1443
1444 if (fn) {
1445 return fn(cpu, spapr, opcode, args);
1446 }
1447 } else if ((opcode >= SVM_HCALL_BASE) &&
1448 (opcode <= SVM_HCALL_MAX)) {
1449 spapr_hcall_fn fn = svm_hypercall_table[(opcode - SVM_HCALL_BASE) / 4];
1450
1451 if (fn) {
1452 return fn(cpu, spapr, opcode, args);
1453 }
1454 } else if ((opcode >= KVMPPC_HCALL_BASE) &&
1455 (opcode <= KVMPPC_HCALL_MAX)) {
1456 spapr_hcall_fn fn = kvmppc_hypercall_table[opcode - KVMPPC_HCALL_BASE];
1457
1458 if (fn) {
1459 return fn(cpu, spapr, opcode, args);
1460 }
1461 }
1462
1463 qemu_log_mask(LOG_UNIMP, "Unimplemented SPAPR hcall 0x" TARGET_FMT_lx "\n",
1464 opcode);
1465 return H_FUNCTION;
1466}
1467
1468#ifndef CONFIG_TCG
1469static target_ulong h_softmmu(PowerPCCPU *cpu, SpaprMachineState *spapr,
1470 target_ulong opcode, target_ulong *args)
1471{
1472 g_assert_not_reached();
1473}
1474
1475static void hypercall_register_softmmu(void)
1476{
1477
1478 spapr_register_hypercall(H_ENTER, h_softmmu);
1479 spapr_register_hypercall(H_REMOVE, h_softmmu);
1480 spapr_register_hypercall(H_PROTECT, h_softmmu);
1481 spapr_register_hypercall(H_READ, h_softmmu);
1482
1483
1484 spapr_register_hypercall(H_BULK_REMOVE, h_softmmu);
1485}
1486#else
1487static void hypercall_register_softmmu(void)
1488{
1489
1490}
1491#endif
1492
1493static void hypercall_register_types(void)
1494{
1495 hypercall_register_softmmu();
1496
1497
1498 spapr_register_hypercall(H_RESIZE_HPT_PREPARE, h_resize_hpt_prepare);
1499 spapr_register_hypercall(H_RESIZE_HPT_COMMIT, h_resize_hpt_commit);
1500
1501
1502 spapr_register_hypercall(H_REGISTER_VPA, h_register_vpa);
1503 spapr_register_hypercall(H_CEDE, h_cede);
1504 spapr_register_hypercall(H_CONFER, h_confer);
1505 spapr_register_hypercall(H_PROD, h_prod);
1506
1507
1508 spapr_register_hypercall(H_JOIN, h_join);
1509
1510 spapr_register_hypercall(H_SIGNAL_SYS_RESET, h_signal_sys_reset);
1511
1512
1513 spapr_register_hypercall(H_SET_SPRG0, h_set_sprg0);
1514 spapr_register_hypercall(H_SET_DABR, h_set_dabr);
1515 spapr_register_hypercall(H_SET_XDABR, h_set_xdabr);
1516 spapr_register_hypercall(H_PAGE_INIT, h_page_init);
1517 spapr_register_hypercall(H_SET_MODE, h_set_mode);
1518
1519
1520 spapr_register_hypercall(H_CLEAN_SLB, h_clean_slb);
1521 spapr_register_hypercall(H_INVALIDATE_PID, h_invalidate_pid);
1522 spapr_register_hypercall(H_REGISTER_PROC_TBL, h_register_process_table);
1523
1524
1525 spapr_register_hypercall(H_GET_CPU_CHARACTERISTICS,
1526 h_get_cpu_characteristics);
1527
1528
1529
1530
1531
1532
1533 spapr_register_hypercall(H_LOGICAL_CI_LOAD, h_logical_load);
1534 spapr_register_hypercall(H_LOGICAL_CI_STORE, h_logical_store);
1535 spapr_register_hypercall(H_LOGICAL_CACHE_LOAD, h_logical_load);
1536 spapr_register_hypercall(H_LOGICAL_CACHE_STORE, h_logical_store);
1537 spapr_register_hypercall(H_LOGICAL_ICBI, h_logical_icbi);
1538 spapr_register_hypercall(H_LOGICAL_DCBF, h_logical_dcbf);
1539 spapr_register_hypercall(KVMPPC_H_LOGICAL_MEMOP, h_logical_memop);
1540
1541
1542 spapr_register_hypercall(KVMPPC_H_RTAS, h_rtas);
1543
1544
1545 spapr_register_hypercall(KVMPPC_H_CAS, h_client_architecture_support);
1546
1547 spapr_register_hypercall(KVMPPC_H_UPDATE_DT, h_update_dt);
1548}
1549
1550type_init(hypercall_register_types)
1551