1 #include "sysemu/sysemu.h" 2 #include "cpu.h" 3 #include "helper_regs.h" 4 #include "hw/ppc/spapr.h" 5 #include "mmu-hash64.h" 6 7 static target_ulong compute_tlbie_rb(target_ulong v, target_ulong r, 8 target_ulong pte_index) 9 { 10 target_ulong rb, va_low; 11 12 rb = (v & ~0x7fULL) << 16; /* AVA field */ 13 va_low = pte_index >> 3; 14 if (v & HPTE64_V_SECONDARY) { 15 va_low = ~va_low; 16 } 17 /* xor vsid from AVA */ 18 if (!(v & HPTE64_V_1TB_SEG)) { 19 va_low ^= v >> 12; 20 } else { 21 va_low ^= v >> 24; 22 } 23 va_low &= 0x7ff; 24 if (v & HPTE64_V_LARGE) { 25 rb |= 1; /* L field */ 26 #if 0 /* Disable that P7 specific bit for now */ 27 if (r & 0xff000) { 28 /* non-16MB large page, must be 64k */ 29 /* (masks depend on page size) */ 30 rb |= 0x1000; /* page encoding in LP field */ 31 rb |= (va_low & 0x7f) << 16; /* 7b of VA in AVA/LP field */ 32 rb |= (va_low & 0xfe); /* AVAL field */ 33 } 34 #endif 35 } else { 36 /* 4kB page */ 37 rb |= (va_low & 0x7ff) << 12; /* remaining 11b of AVA */ 38 } 39 rb |= (v >> 54) & 0x300; /* B field */ 40 return rb; 41 } 42 43 static target_ulong h_enter(PowerPCCPU *cpu, sPAPREnvironment *spapr, 44 target_ulong opcode, target_ulong *args) 45 { 46 CPUPPCState *env = &cpu->env; 47 target_ulong flags = args[0]; 48 target_ulong pte_index = args[1]; 49 target_ulong pteh = args[2]; 50 target_ulong ptel = args[3]; 51 target_ulong page_shift = 12; 52 target_ulong raddr; 53 target_ulong i; 54 hwaddr hpte; 55 56 /* only handle 4k and 16M pages for now */ 57 if (pteh & HPTE64_V_LARGE) { 58 #if 0 /* We don't support 64k pages yet */ 59 if ((ptel & 0xf000) == 0x1000) { 60 /* 64k page */ 61 } else 62 #endif 63 if ((ptel & 0xff000) == 0) { 64 /* 16M page */ 65 page_shift = 24; 66 /* lowest AVA bit must be 0 for 16M pages */ 67 if (pteh & 0x80) { 68 return H_PARAMETER; 69 } 70 } else { 71 return H_PARAMETER; 72 } 73 } 74 75 raddr = (ptel & HPTE64_R_RPN) & ~((1ULL << page_shift) - 1); 76 77 if (raddr < spapr->ram_limit) { 78 /* Regular RAM - should have WIMG=0010 */ 79 if ((ptel & HPTE64_R_WIMG) != HPTE64_R_M) { 80 return H_PARAMETER; 81 } 82 } else { 83 /* Looks like an IO address */ 84 /* FIXME: What WIMG combinations could be sensible for IO? 85 * For now we allow WIMG=010x, but are there others? */ 86 /* FIXME: Should we check against registered IO addresses? */ 87 if ((ptel & (HPTE64_R_W | HPTE64_R_I | HPTE64_R_M)) != HPTE64_R_I) { 88 return H_PARAMETER; 89 } 90 } 91 92 pteh &= ~0x60ULL; 93 94 if ((pte_index * HASH_PTE_SIZE_64) & ~env->htab_mask) { 95 return H_PARAMETER; 96 } 97 if (likely((flags & H_EXACT) == 0)) { 98 pte_index &= ~7ULL; 99 hpte = pte_index * HASH_PTE_SIZE_64; 100 for (i = 0; ; ++i) { 101 if (i == 8) { 102 return H_PTEG_FULL; 103 } 104 if ((ppc_hash64_load_hpte0(env, hpte) & HPTE64_V_VALID) == 0) { 105 break; 106 } 107 hpte += HASH_PTE_SIZE_64; 108 } 109 } else { 110 i = 0; 111 hpte = pte_index * HASH_PTE_SIZE_64; 112 if (ppc_hash64_load_hpte0(env, hpte) & HPTE64_V_VALID) { 113 return H_PTEG_FULL; 114 } 115 } 116 ppc_hash64_store_hpte1(env, hpte, ptel); 117 /* eieio(); FIXME: need some sort of barrier for smp? */ 118 ppc_hash64_store_hpte0(env, hpte, pteh | HPTE64_V_HPTE_DIRTY); 119 120 args[0] = pte_index + i; 121 return H_SUCCESS; 122 } 123 124 typedef enum { 125 REMOVE_SUCCESS = 0, 126 REMOVE_NOT_FOUND = 1, 127 REMOVE_PARM = 2, 128 REMOVE_HW = 3, 129 } RemoveResult; 130 131 static RemoveResult remove_hpte(CPUPPCState *env, target_ulong ptex, 132 target_ulong avpn, 133 target_ulong flags, 134 target_ulong *vp, target_ulong *rp) 135 { 136 hwaddr hpte; 137 target_ulong v, r, rb; 138 139 if ((ptex * HASH_PTE_SIZE_64) & ~env->htab_mask) { 140 return REMOVE_PARM; 141 } 142 143 hpte = ptex * HASH_PTE_SIZE_64; 144 145 v = ppc_hash64_load_hpte0(env, hpte); 146 r = ppc_hash64_load_hpte1(env, hpte); 147 148 if ((v & HPTE64_V_VALID) == 0 || 149 ((flags & H_AVPN) && (v & ~0x7fULL) != avpn) || 150 ((flags & H_ANDCOND) && (v & avpn) != 0)) { 151 return REMOVE_NOT_FOUND; 152 } 153 *vp = v; 154 *rp = r; 155 ppc_hash64_store_hpte0(env, hpte, HPTE64_V_HPTE_DIRTY); 156 rb = compute_tlbie_rb(v, r, ptex); 157 ppc_tlb_invalidate_one(env, rb); 158 return REMOVE_SUCCESS; 159 } 160 161 static target_ulong h_remove(PowerPCCPU *cpu, sPAPREnvironment *spapr, 162 target_ulong opcode, target_ulong *args) 163 { 164 CPUPPCState *env = &cpu->env; 165 target_ulong flags = args[0]; 166 target_ulong pte_index = args[1]; 167 target_ulong avpn = args[2]; 168 RemoveResult ret; 169 170 ret = remove_hpte(env, pte_index, avpn, flags, 171 &args[0], &args[1]); 172 173 switch (ret) { 174 case REMOVE_SUCCESS: 175 return H_SUCCESS; 176 177 case REMOVE_NOT_FOUND: 178 return H_NOT_FOUND; 179 180 case REMOVE_PARM: 181 return H_PARAMETER; 182 183 case REMOVE_HW: 184 return H_HARDWARE; 185 } 186 187 g_assert_not_reached(); 188 } 189 190 #define H_BULK_REMOVE_TYPE 0xc000000000000000ULL 191 #define H_BULK_REMOVE_REQUEST 0x4000000000000000ULL 192 #define H_BULK_REMOVE_RESPONSE 0x8000000000000000ULL 193 #define H_BULK_REMOVE_END 0xc000000000000000ULL 194 #define H_BULK_REMOVE_CODE 0x3000000000000000ULL 195 #define H_BULK_REMOVE_SUCCESS 0x0000000000000000ULL 196 #define H_BULK_REMOVE_NOT_FOUND 0x1000000000000000ULL 197 #define H_BULK_REMOVE_PARM 0x2000000000000000ULL 198 #define H_BULK_REMOVE_HW 0x3000000000000000ULL 199 #define H_BULK_REMOVE_RC 0x0c00000000000000ULL 200 #define H_BULK_REMOVE_FLAGS 0x0300000000000000ULL 201 #define H_BULK_REMOVE_ABSOLUTE 0x0000000000000000ULL 202 #define H_BULK_REMOVE_ANDCOND 0x0100000000000000ULL 203 #define H_BULK_REMOVE_AVPN 0x0200000000000000ULL 204 #define H_BULK_REMOVE_PTEX 0x00ffffffffffffffULL 205 206 #define H_BULK_REMOVE_MAX_BATCH 4 207 208 static target_ulong h_bulk_remove(PowerPCCPU *cpu, sPAPREnvironment *spapr, 209 target_ulong opcode, target_ulong *args) 210 { 211 CPUPPCState *env = &cpu->env; 212 int i; 213 214 for (i = 0; i < H_BULK_REMOVE_MAX_BATCH; i++) { 215 target_ulong *tsh = &args[i*2]; 216 target_ulong tsl = args[i*2 + 1]; 217 target_ulong v, r, ret; 218 219 if ((*tsh & H_BULK_REMOVE_TYPE) == H_BULK_REMOVE_END) { 220 break; 221 } else if ((*tsh & H_BULK_REMOVE_TYPE) != H_BULK_REMOVE_REQUEST) { 222 return H_PARAMETER; 223 } 224 225 *tsh &= H_BULK_REMOVE_PTEX | H_BULK_REMOVE_FLAGS; 226 *tsh |= H_BULK_REMOVE_RESPONSE; 227 228 if ((*tsh & H_BULK_REMOVE_ANDCOND) && (*tsh & H_BULK_REMOVE_AVPN)) { 229 *tsh |= H_BULK_REMOVE_PARM; 230 return H_PARAMETER; 231 } 232 233 ret = remove_hpte(env, *tsh & H_BULK_REMOVE_PTEX, tsl, 234 (*tsh & H_BULK_REMOVE_FLAGS) >> 26, 235 &v, &r); 236 237 *tsh |= ret << 60; 238 239 switch (ret) { 240 case REMOVE_SUCCESS: 241 *tsh |= (r & (HPTE64_R_C | HPTE64_R_R)) << 43; 242 break; 243 244 case REMOVE_PARM: 245 return H_PARAMETER; 246 247 case REMOVE_HW: 248 return H_HARDWARE; 249 } 250 } 251 252 return H_SUCCESS; 253 } 254 255 static target_ulong h_protect(PowerPCCPU *cpu, sPAPREnvironment *spapr, 256 target_ulong opcode, target_ulong *args) 257 { 258 CPUPPCState *env = &cpu->env; 259 target_ulong flags = args[0]; 260 target_ulong pte_index = args[1]; 261 target_ulong avpn = args[2]; 262 hwaddr hpte; 263 target_ulong v, r, rb; 264 265 if ((pte_index * HASH_PTE_SIZE_64) & ~env->htab_mask) { 266 return H_PARAMETER; 267 } 268 269 hpte = pte_index * HASH_PTE_SIZE_64; 270 271 v = ppc_hash64_load_hpte0(env, hpte); 272 r = ppc_hash64_load_hpte1(env, hpte); 273 274 if ((v & HPTE64_V_VALID) == 0 || 275 ((flags & H_AVPN) && (v & ~0x7fULL) != avpn)) { 276 return H_NOT_FOUND; 277 } 278 279 r &= ~(HPTE64_R_PP0 | HPTE64_R_PP | HPTE64_R_N | 280 HPTE64_R_KEY_HI | HPTE64_R_KEY_LO); 281 r |= (flags << 55) & HPTE64_R_PP0; 282 r |= (flags << 48) & HPTE64_R_KEY_HI; 283 r |= flags & (HPTE64_R_PP | HPTE64_R_N | HPTE64_R_KEY_LO); 284 rb = compute_tlbie_rb(v, r, pte_index); 285 ppc_hash64_store_hpte0(env, hpte, (v & ~HPTE64_V_VALID) | HPTE64_V_HPTE_DIRTY); 286 ppc_tlb_invalidate_one(env, rb); 287 ppc_hash64_store_hpte1(env, hpte, r); 288 /* Don't need a memory barrier, due to qemu's global lock */ 289 ppc_hash64_store_hpte0(env, hpte, v | HPTE64_V_HPTE_DIRTY); 290 return H_SUCCESS; 291 } 292 293 static target_ulong h_read(PowerPCCPU *cpu, sPAPREnvironment *spapr, 294 target_ulong opcode, target_ulong *args) 295 { 296 CPUPPCState *env = &cpu->env; 297 target_ulong flags = args[0]; 298 target_ulong pte_index = args[1]; 299 uint8_t *hpte; 300 int i, ridx, n_entries = 1; 301 302 if ((pte_index * HASH_PTE_SIZE_64) & ~env->htab_mask) { 303 return H_PARAMETER; 304 } 305 306 if (flags & H_READ_4) { 307 /* Clear the two low order bits */ 308 pte_index &= ~(3ULL); 309 n_entries = 4; 310 } 311 312 hpte = env->external_htab + (pte_index * HASH_PTE_SIZE_64); 313 314 for (i = 0, ridx = 0; i < n_entries; i++) { 315 args[ridx++] = ldq_p(hpte); 316 args[ridx++] = ldq_p(hpte + (HASH_PTE_SIZE_64/2)); 317 hpte += HASH_PTE_SIZE_64; 318 } 319 320 return H_SUCCESS; 321 } 322 323 static target_ulong h_set_dabr(PowerPCCPU *cpu, sPAPREnvironment *spapr, 324 target_ulong opcode, target_ulong *args) 325 { 326 /* FIXME: actually implement this */ 327 return H_HARDWARE; 328 } 329 330 #define FLAGS_REGISTER_VPA 0x0000200000000000ULL 331 #define FLAGS_REGISTER_DTL 0x0000400000000000ULL 332 #define FLAGS_REGISTER_SLBSHADOW 0x0000600000000000ULL 333 #define FLAGS_DEREGISTER_VPA 0x0000a00000000000ULL 334 #define FLAGS_DEREGISTER_DTL 0x0000c00000000000ULL 335 #define FLAGS_DEREGISTER_SLBSHADOW 0x0000e00000000000ULL 336 337 #define VPA_MIN_SIZE 640 338 #define VPA_SIZE_OFFSET 0x4 339 #define VPA_SHARED_PROC_OFFSET 0x9 340 #define VPA_SHARED_PROC_VAL 0x2 341 342 static target_ulong register_vpa(CPUPPCState *env, target_ulong vpa) 343 { 344 uint16_t size; 345 uint8_t tmp; 346 347 if (vpa == 0) { 348 hcall_dprintf("Can't cope with registering a VPA at logical 0\n"); 349 return H_HARDWARE; 350 } 351 352 if (vpa % env->dcache_line_size) { 353 return H_PARAMETER; 354 } 355 /* FIXME: bounds check the address */ 356 357 size = lduw_be_phys(vpa + 0x4); 358 359 if (size < VPA_MIN_SIZE) { 360 return H_PARAMETER; 361 } 362 363 /* VPA is not allowed to cross a page boundary */ 364 if ((vpa / 4096) != ((vpa + size - 1) / 4096)) { 365 return H_PARAMETER; 366 } 367 368 env->vpa_addr = vpa; 369 370 tmp = ldub_phys(env->vpa_addr + VPA_SHARED_PROC_OFFSET); 371 tmp |= VPA_SHARED_PROC_VAL; 372 stb_phys(env->vpa_addr + VPA_SHARED_PROC_OFFSET, tmp); 373 374 return H_SUCCESS; 375 } 376 377 static target_ulong deregister_vpa(CPUPPCState *env, target_ulong vpa) 378 { 379 if (env->slb_shadow_addr) { 380 return H_RESOURCE; 381 } 382 383 if (env->dtl_addr) { 384 return H_RESOURCE; 385 } 386 387 env->vpa_addr = 0; 388 return H_SUCCESS; 389 } 390 391 static target_ulong register_slb_shadow(CPUPPCState *env, target_ulong addr) 392 { 393 uint32_t size; 394 395 if (addr == 0) { 396 hcall_dprintf("Can't cope with SLB shadow at logical 0\n"); 397 return H_HARDWARE; 398 } 399 400 size = ldl_be_phys(addr + 0x4); 401 if (size < 0x8) { 402 return H_PARAMETER; 403 } 404 405 if ((addr / 4096) != ((addr + size - 1) / 4096)) { 406 return H_PARAMETER; 407 } 408 409 if (!env->vpa_addr) { 410 return H_RESOURCE; 411 } 412 413 env->slb_shadow_addr = addr; 414 env->slb_shadow_size = size; 415 416 return H_SUCCESS; 417 } 418 419 static target_ulong deregister_slb_shadow(CPUPPCState *env, target_ulong addr) 420 { 421 env->slb_shadow_addr = 0; 422 env->slb_shadow_size = 0; 423 return H_SUCCESS; 424 } 425 426 static target_ulong register_dtl(CPUPPCState *env, target_ulong addr) 427 { 428 uint32_t size; 429 430 if (addr == 0) { 431 hcall_dprintf("Can't cope with DTL at logical 0\n"); 432 return H_HARDWARE; 433 } 434 435 size = ldl_be_phys(addr + 0x4); 436 437 if (size < 48) { 438 return H_PARAMETER; 439 } 440 441 if (!env->vpa_addr) { 442 return H_RESOURCE; 443 } 444 445 env->dtl_addr = addr; 446 env->dtl_size = size; 447 448 return H_SUCCESS; 449 } 450 451 static target_ulong deregister_dtl(CPUPPCState *env, target_ulong addr) 452 { 453 env->dtl_addr = 0; 454 env->dtl_size = 0; 455 456 return H_SUCCESS; 457 } 458 459 static target_ulong h_register_vpa(PowerPCCPU *cpu, sPAPREnvironment *spapr, 460 target_ulong opcode, target_ulong *args) 461 { 462 target_ulong flags = args[0]; 463 target_ulong procno = args[1]; 464 target_ulong vpa = args[2]; 465 target_ulong ret = H_PARAMETER; 466 CPUPPCState *tenv; 467 CPUState *tcpu; 468 469 tcpu = qemu_get_cpu(procno); 470 if (!tcpu) { 471 return H_PARAMETER; 472 } 473 tenv = tcpu->env_ptr; 474 475 switch (flags) { 476 case FLAGS_REGISTER_VPA: 477 ret = register_vpa(tenv, vpa); 478 break; 479 480 case FLAGS_DEREGISTER_VPA: 481 ret = deregister_vpa(tenv, vpa); 482 break; 483 484 case FLAGS_REGISTER_SLBSHADOW: 485 ret = register_slb_shadow(tenv, vpa); 486 break; 487 488 case FLAGS_DEREGISTER_SLBSHADOW: 489 ret = deregister_slb_shadow(tenv, vpa); 490 break; 491 492 case FLAGS_REGISTER_DTL: 493 ret = register_dtl(tenv, vpa); 494 break; 495 496 case FLAGS_DEREGISTER_DTL: 497 ret = deregister_dtl(tenv, vpa); 498 break; 499 } 500 501 return ret; 502 } 503 504 static target_ulong h_cede(PowerPCCPU *cpu, sPAPREnvironment *spapr, 505 target_ulong opcode, target_ulong *args) 506 { 507 CPUPPCState *env = &cpu->env; 508 CPUState *cs = CPU(cpu); 509 510 env->msr |= (1ULL << MSR_EE); 511 hreg_compute_hflags(env); 512 if (!cpu_has_work(cs)) { 513 cs->halted = 1; 514 env->exception_index = EXCP_HLT; 515 cs->exit_request = 1; 516 } 517 return H_SUCCESS; 518 } 519 520 static target_ulong h_rtas(PowerPCCPU *cpu, sPAPREnvironment *spapr, 521 target_ulong opcode, target_ulong *args) 522 { 523 target_ulong rtas_r3 = args[0]; 524 uint32_t token = ldl_be_phys(rtas_r3); 525 uint32_t nargs = ldl_be_phys(rtas_r3 + 4); 526 uint32_t nret = ldl_be_phys(rtas_r3 + 8); 527 528 return spapr_rtas_call(cpu, spapr, token, nargs, rtas_r3 + 12, 529 nret, rtas_r3 + 12 + 4*nargs); 530 } 531 532 static target_ulong h_logical_load(PowerPCCPU *cpu, sPAPREnvironment *spapr, 533 target_ulong opcode, target_ulong *args) 534 { 535 target_ulong size = args[0]; 536 target_ulong addr = args[1]; 537 538 switch (size) { 539 case 1: 540 args[0] = ldub_phys(addr); 541 return H_SUCCESS; 542 case 2: 543 args[0] = lduw_phys(addr); 544 return H_SUCCESS; 545 case 4: 546 args[0] = ldl_phys(addr); 547 return H_SUCCESS; 548 case 8: 549 args[0] = ldq_phys(addr); 550 return H_SUCCESS; 551 } 552 return H_PARAMETER; 553 } 554 555 static target_ulong h_logical_store(PowerPCCPU *cpu, sPAPREnvironment *spapr, 556 target_ulong opcode, target_ulong *args) 557 { 558 target_ulong size = args[0]; 559 target_ulong addr = args[1]; 560 target_ulong val = args[2]; 561 562 switch (size) { 563 case 1: 564 stb_phys(addr, val); 565 return H_SUCCESS; 566 case 2: 567 stw_phys(addr, val); 568 return H_SUCCESS; 569 case 4: 570 stl_phys(addr, val); 571 return H_SUCCESS; 572 case 8: 573 stq_phys(addr, val); 574 return H_SUCCESS; 575 } 576 return H_PARAMETER; 577 } 578 579 static target_ulong h_logical_memop(PowerPCCPU *cpu, sPAPREnvironment *spapr, 580 target_ulong opcode, target_ulong *args) 581 { 582 target_ulong dst = args[0]; /* Destination address */ 583 target_ulong src = args[1]; /* Source address */ 584 target_ulong esize = args[2]; /* Element size (0=1,1=2,2=4,3=8) */ 585 target_ulong count = args[3]; /* Element count */ 586 target_ulong op = args[4]; /* 0 = copy, 1 = invert */ 587 uint64_t tmp; 588 unsigned int mask = (1 << esize) - 1; 589 int step = 1 << esize; 590 591 if (count > 0x80000000) { 592 return H_PARAMETER; 593 } 594 595 if ((dst & mask) || (src & mask) || (op > 1)) { 596 return H_PARAMETER; 597 } 598 599 if (dst >= src && dst < (src + (count << esize))) { 600 dst = dst + ((count - 1) << esize); 601 src = src + ((count - 1) << esize); 602 step = -step; 603 } 604 605 while (count--) { 606 switch (esize) { 607 case 0: 608 tmp = ldub_phys(src); 609 break; 610 case 1: 611 tmp = lduw_phys(src); 612 break; 613 case 2: 614 tmp = ldl_phys(src); 615 break; 616 case 3: 617 tmp = ldq_phys(src); 618 break; 619 default: 620 return H_PARAMETER; 621 } 622 if (op == 1) { 623 tmp = ~tmp; 624 } 625 switch (esize) { 626 case 0: 627 stb_phys(dst, tmp); 628 break; 629 case 1: 630 stw_phys(dst, tmp); 631 break; 632 case 2: 633 stl_phys(dst, tmp); 634 break; 635 case 3: 636 stq_phys(dst, tmp); 637 break; 638 } 639 dst = dst + step; 640 src = src + step; 641 } 642 643 return H_SUCCESS; 644 } 645 646 static target_ulong h_logical_icbi(PowerPCCPU *cpu, sPAPREnvironment *spapr, 647 target_ulong opcode, target_ulong *args) 648 { 649 /* Nothing to do on emulation, KVM will trap this in the kernel */ 650 return H_SUCCESS; 651 } 652 653 static target_ulong h_logical_dcbf(PowerPCCPU *cpu, sPAPREnvironment *spapr, 654 target_ulong opcode, target_ulong *args) 655 { 656 /* Nothing to do on emulation, KVM will trap this in the kernel */ 657 return H_SUCCESS; 658 } 659 660 static spapr_hcall_fn papr_hypercall_table[(MAX_HCALL_OPCODE / 4) + 1]; 661 static spapr_hcall_fn kvmppc_hypercall_table[KVMPPC_HCALL_MAX - KVMPPC_HCALL_BASE + 1]; 662 663 void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn) 664 { 665 spapr_hcall_fn *slot; 666 667 if (opcode <= MAX_HCALL_OPCODE) { 668 assert((opcode & 0x3) == 0); 669 670 slot = &papr_hypercall_table[opcode / 4]; 671 } else { 672 assert((opcode >= KVMPPC_HCALL_BASE) && (opcode <= KVMPPC_HCALL_MAX)); 673 674 slot = &kvmppc_hypercall_table[opcode - KVMPPC_HCALL_BASE]; 675 } 676 677 assert(!(*slot)); 678 *slot = fn; 679 } 680 681 target_ulong spapr_hypercall(PowerPCCPU *cpu, target_ulong opcode, 682 target_ulong *args) 683 { 684 if ((opcode <= MAX_HCALL_OPCODE) 685 && ((opcode & 0x3) == 0)) { 686 spapr_hcall_fn fn = papr_hypercall_table[opcode / 4]; 687 688 if (fn) { 689 return fn(cpu, spapr, opcode, args); 690 } 691 } else if ((opcode >= KVMPPC_HCALL_BASE) && 692 (opcode <= KVMPPC_HCALL_MAX)) { 693 spapr_hcall_fn fn = kvmppc_hypercall_table[opcode - KVMPPC_HCALL_BASE]; 694 695 if (fn) { 696 return fn(cpu, spapr, opcode, args); 697 } 698 } 699 700 hcall_dprintf("Unimplemented hcall 0x" TARGET_FMT_lx "\n", opcode); 701 return H_FUNCTION; 702 } 703 704 static void hypercall_register_types(void) 705 { 706 /* hcall-pft */ 707 spapr_register_hypercall(H_ENTER, h_enter); 708 spapr_register_hypercall(H_REMOVE, h_remove); 709 spapr_register_hypercall(H_PROTECT, h_protect); 710 spapr_register_hypercall(H_READ, h_read); 711 712 /* hcall-bulk */ 713 spapr_register_hypercall(H_BULK_REMOVE, h_bulk_remove); 714 715 /* hcall-dabr */ 716 spapr_register_hypercall(H_SET_DABR, h_set_dabr); 717 718 /* hcall-splpar */ 719 spapr_register_hypercall(H_REGISTER_VPA, h_register_vpa); 720 spapr_register_hypercall(H_CEDE, h_cede); 721 722 /* "debugger" hcalls (also used by SLOF). Note: We do -not- differenciate 723 * here between the "CI" and the "CACHE" variants, they will use whatever 724 * mapping attributes qemu is using. When using KVM, the kernel will 725 * enforce the attributes more strongly 726 */ 727 spapr_register_hypercall(H_LOGICAL_CI_LOAD, h_logical_load); 728 spapr_register_hypercall(H_LOGICAL_CI_STORE, h_logical_store); 729 spapr_register_hypercall(H_LOGICAL_CACHE_LOAD, h_logical_load); 730 spapr_register_hypercall(H_LOGICAL_CACHE_STORE, h_logical_store); 731 spapr_register_hypercall(H_LOGICAL_ICBI, h_logical_icbi); 732 spapr_register_hypercall(H_LOGICAL_DCBF, h_logical_dcbf); 733 spapr_register_hypercall(KVMPPC_H_LOGICAL_MEMOP, h_logical_memop); 734 735 /* qemu/KVM-PPC specific hcalls */ 736 spapr_register_hypercall(KVMPPC_H_RTAS, h_rtas); 737 } 738 739 type_init(hypercall_register_types) 740