1 /* 2 * s390 PCI instructions 3 * 4 * Copyright 2014 IBM Corp. 5 * Author(s): Frank Blaschka <frank.blaschka@de.ibm.com> 6 * Hong Bo Li <lihbbj@cn.ibm.com> 7 * Yi Min Zhao <zyimin@cn.ibm.com> 8 * 9 * This work is licensed under the terms of the GNU GPL, version 2 or (at 10 * your option) any later version. See the COPYING file in the top-level 11 * directory. 12 */ 13 14 #include "qemu/osdep.h" 15 #include "qemu-common.h" 16 #include "cpu.h" 17 #include "s390-pci-inst.h" 18 #include "s390-pci-bus.h" 19 #include "exec/memory-internal.h" 20 #include "qemu/error-report.h" 21 #include "sysemu/hw_accel.h" 22 23 /* #define DEBUG_S390PCI_INST */ 24 #ifdef DEBUG_S390PCI_INST 25 #define DPRINTF(fmt, ...) \ 26 do { fprintf(stderr, "s390pci-inst: " fmt, ## __VA_ARGS__); } while (0) 27 #else 28 #define DPRINTF(fmt, ...) \ 29 do { } while (0) 30 #endif 31 32 static void s390_set_status_code(CPUS390XState *env, 33 uint8_t r, uint64_t status_code) 34 { 35 env->regs[r] &= ~0xff000000ULL; 36 env->regs[r] |= (status_code & 0xff) << 24; 37 } 38 39 static int list_pci(ClpReqRspListPci *rrb, uint8_t *cc) 40 { 41 S390PCIBusDevice *pbdev = NULL; 42 uint32_t res_code, initial_l2, g_l2; 43 int rc, i; 44 uint64_t resume_token; 45 46 rc = 0; 47 if (lduw_p(&rrb->request.hdr.len) != 32) { 48 res_code = CLP_RC_LEN; 49 rc = -EINVAL; 50 goto out; 51 } 52 53 if ((ldl_p(&rrb->request.fmt) & CLP_MASK_FMT) != 0) { 54 res_code = CLP_RC_FMT; 55 rc = -EINVAL; 56 goto out; 57 } 58 59 if ((ldl_p(&rrb->request.fmt) & ~CLP_MASK_FMT) != 0 || 60 ldq_p(&rrb->request.reserved1) != 0) { 61 res_code = CLP_RC_RESNOT0; 62 rc = -EINVAL; 63 goto out; 64 } 65 66 resume_token = ldq_p(&rrb->request.resume_token); 67 68 if (resume_token) { 69 pbdev = s390_pci_find_dev_by_idx(resume_token); 70 if (!pbdev) { 71 res_code = CLP_RC_LISTPCI_BADRT; 72 rc = -EINVAL; 73 goto out; 74 } 75 } else { 76 pbdev = s390_pci_find_next_avail_dev(NULL); 77 } 78 79 if (lduw_p(&rrb->response.hdr.len) < 48) { 80 res_code = CLP_RC_8K; 81 rc = -EINVAL; 82 goto out; 83 } 84 85 initial_l2 = lduw_p(&rrb->response.hdr.len); 86 if ((initial_l2 - LIST_PCI_HDR_LEN) % sizeof(ClpFhListEntry) 87 != 0) { 88 res_code = CLP_RC_LEN; 89 rc = -EINVAL; 90 *cc = 3; 91 goto out; 92 } 93 94 stl_p(&rrb->response.fmt, 0); 95 stq_p(&rrb->response.reserved1, 0); 96 stl_p(&rrb->response.mdd, FH_MASK_SHM); 97 stw_p(&rrb->response.max_fn, PCI_MAX_FUNCTIONS); 98 rrb->response.flags = UID_CHECKING_ENABLED; 99 rrb->response.entry_size = sizeof(ClpFhListEntry); 100 101 i = 0; 102 g_l2 = LIST_PCI_HDR_LEN; 103 while (g_l2 < initial_l2 && pbdev) { 104 stw_p(&rrb->response.fh_list[i].device_id, 105 pci_get_word(pbdev->pdev->config + PCI_DEVICE_ID)); 106 stw_p(&rrb->response.fh_list[i].vendor_id, 107 pci_get_word(pbdev->pdev->config + PCI_VENDOR_ID)); 108 /* Ignore RESERVED devices. */ 109 stl_p(&rrb->response.fh_list[i].config, 110 pbdev->state == ZPCI_FS_STANDBY ? 0 : 1 << 31); 111 stl_p(&rrb->response.fh_list[i].fid, pbdev->fid); 112 stl_p(&rrb->response.fh_list[i].fh, pbdev->fh); 113 114 g_l2 += sizeof(ClpFhListEntry); 115 /* Add endian check for DPRINTF? */ 116 DPRINTF("g_l2 %d vendor id 0x%x device id 0x%x fid 0x%x fh 0x%x\n", 117 g_l2, 118 lduw_p(&rrb->response.fh_list[i].vendor_id), 119 lduw_p(&rrb->response.fh_list[i].device_id), 120 ldl_p(&rrb->response.fh_list[i].fid), 121 ldl_p(&rrb->response.fh_list[i].fh)); 122 pbdev = s390_pci_find_next_avail_dev(pbdev); 123 i++; 124 } 125 126 if (!pbdev) { 127 resume_token = 0; 128 } else { 129 resume_token = pbdev->fh & FH_MASK_INDEX; 130 } 131 stq_p(&rrb->response.resume_token, resume_token); 132 stw_p(&rrb->response.hdr.len, g_l2); 133 stw_p(&rrb->response.hdr.rsp, CLP_RC_OK); 134 out: 135 if (rc) { 136 DPRINTF("list pci failed rc 0x%x\n", rc); 137 stw_p(&rrb->response.hdr.rsp, res_code); 138 } 139 return rc; 140 } 141 142 int clp_service_call(S390CPU *cpu, uint8_t r2) 143 { 144 ClpReqHdr *reqh; 145 ClpRspHdr *resh; 146 S390PCIBusDevice *pbdev; 147 uint32_t req_len; 148 uint32_t res_len; 149 uint8_t buffer[4096 * 2]; 150 uint8_t cc = 0; 151 CPUS390XState *env = &cpu->env; 152 int i; 153 154 cpu_synchronize_state(CPU(cpu)); 155 156 if (env->psw.mask & PSW_MASK_PSTATE) { 157 program_interrupt(env, PGM_PRIVILEGED, 4); 158 return 0; 159 } 160 161 if (s390_cpu_virt_mem_read(cpu, env->regs[r2], r2, buffer, sizeof(*reqh))) { 162 return 0; 163 } 164 reqh = (ClpReqHdr *)buffer; 165 req_len = lduw_p(&reqh->len); 166 if (req_len < 16 || req_len > 8184 || (req_len % 8 != 0)) { 167 program_interrupt(env, PGM_OPERAND, 4); 168 return 0; 169 } 170 171 if (s390_cpu_virt_mem_read(cpu, env->regs[r2], r2, buffer, 172 req_len + sizeof(*resh))) { 173 return 0; 174 } 175 resh = (ClpRspHdr *)(buffer + req_len); 176 res_len = lduw_p(&resh->len); 177 if (res_len < 8 || res_len > 8176 || (res_len % 8 != 0)) { 178 program_interrupt(env, PGM_OPERAND, 4); 179 return 0; 180 } 181 if ((req_len + res_len) > 8192) { 182 program_interrupt(env, PGM_OPERAND, 4); 183 return 0; 184 } 185 186 if (s390_cpu_virt_mem_read(cpu, env->regs[r2], r2, buffer, 187 req_len + res_len)) { 188 return 0; 189 } 190 191 if (req_len != 32) { 192 stw_p(&resh->rsp, CLP_RC_LEN); 193 goto out; 194 } 195 196 switch (lduw_p(&reqh->cmd)) { 197 case CLP_LIST_PCI: { 198 ClpReqRspListPci *rrb = (ClpReqRspListPci *)buffer; 199 list_pci(rrb, &cc); 200 break; 201 } 202 case CLP_SET_PCI_FN: { 203 ClpReqSetPci *reqsetpci = (ClpReqSetPci *)reqh; 204 ClpRspSetPci *ressetpci = (ClpRspSetPci *)resh; 205 206 pbdev = s390_pci_find_dev_by_fh(ldl_p(&reqsetpci->fh)); 207 if (!pbdev) { 208 stw_p(&ressetpci->hdr.rsp, CLP_RC_SETPCIFN_FH); 209 goto out; 210 } 211 212 switch (reqsetpci->oc) { 213 case CLP_SET_ENABLE_PCI_FN: 214 switch (reqsetpci->ndas) { 215 case 0: 216 stw_p(&ressetpci->hdr.rsp, CLP_RC_SETPCIFN_DMAAS); 217 goto out; 218 case 1: 219 break; 220 default: 221 stw_p(&ressetpci->hdr.rsp, CLP_RC_SETPCIFN_RES); 222 goto out; 223 } 224 225 if (pbdev->fh & FH_MASK_ENABLE) { 226 stw_p(&ressetpci->hdr.rsp, CLP_RC_SETPCIFN_FHOP); 227 goto out; 228 } 229 230 pbdev->fh |= FH_MASK_ENABLE; 231 pbdev->state = ZPCI_FS_ENABLED; 232 stl_p(&ressetpci->fh, pbdev->fh); 233 stw_p(&ressetpci->hdr.rsp, CLP_RC_OK); 234 break; 235 case CLP_SET_DISABLE_PCI_FN: 236 if (!(pbdev->fh & FH_MASK_ENABLE)) { 237 stw_p(&ressetpci->hdr.rsp, CLP_RC_SETPCIFN_FHOP); 238 goto out; 239 } 240 device_reset(DEVICE(pbdev)); 241 pbdev->fh &= ~FH_MASK_ENABLE; 242 pbdev->state = ZPCI_FS_DISABLED; 243 stl_p(&ressetpci->fh, pbdev->fh); 244 stw_p(&ressetpci->hdr.rsp, CLP_RC_OK); 245 break; 246 default: 247 DPRINTF("unknown set pci command\n"); 248 stw_p(&ressetpci->hdr.rsp, CLP_RC_SETPCIFN_FHOP); 249 break; 250 } 251 break; 252 } 253 case CLP_QUERY_PCI_FN: { 254 ClpReqQueryPci *reqquery = (ClpReqQueryPci *)reqh; 255 ClpRspQueryPci *resquery = (ClpRspQueryPci *)resh; 256 257 pbdev = s390_pci_find_dev_by_fh(ldl_p(&reqquery->fh)); 258 if (!pbdev) { 259 DPRINTF("query pci no pci dev\n"); 260 stw_p(&resquery->hdr.rsp, CLP_RC_SETPCIFN_FH); 261 goto out; 262 } 263 264 for (i = 0; i < PCI_BAR_COUNT; i++) { 265 uint32_t data = pci_get_long(pbdev->pdev->config + 266 PCI_BASE_ADDRESS_0 + (i * 4)); 267 268 stl_p(&resquery->bar[i], data); 269 resquery->bar_size[i] = pbdev->pdev->io_regions[i].size ? 270 ctz64(pbdev->pdev->io_regions[i].size) : 0; 271 DPRINTF("bar %d addr 0x%x size 0x%" PRIx64 "barsize 0x%x\n", i, 272 ldl_p(&resquery->bar[i]), 273 pbdev->pdev->io_regions[i].size, 274 resquery->bar_size[i]); 275 } 276 277 stq_p(&resquery->sdma, ZPCI_SDMA_ADDR); 278 stq_p(&resquery->edma, ZPCI_EDMA_ADDR); 279 stl_p(&resquery->fid, pbdev->fid); 280 stw_p(&resquery->pchid, 0); 281 stw_p(&resquery->ug, 1); 282 stl_p(&resquery->uid, pbdev->uid); 283 stw_p(&resquery->hdr.rsp, CLP_RC_OK); 284 break; 285 } 286 case CLP_QUERY_PCI_FNGRP: { 287 ClpRspQueryPciGrp *resgrp = (ClpRspQueryPciGrp *)resh; 288 resgrp->fr = 1; 289 stq_p(&resgrp->dasm, 0); 290 stq_p(&resgrp->msia, ZPCI_MSI_ADDR); 291 stw_p(&resgrp->mui, 0); 292 stw_p(&resgrp->i, 128); 293 resgrp->version = 0; 294 295 stw_p(&resgrp->hdr.rsp, CLP_RC_OK); 296 break; 297 } 298 default: 299 DPRINTF("unknown clp command\n"); 300 stw_p(&resh->rsp, CLP_RC_CMD); 301 break; 302 } 303 304 out: 305 if (s390_cpu_virt_mem_write(cpu, env->regs[r2], r2, buffer, 306 req_len + res_len)) { 307 return 0; 308 } 309 setcc(cpu, cc); 310 return 0; 311 } 312 313 int pcilg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2) 314 { 315 CPUS390XState *env = &cpu->env; 316 S390PCIBusDevice *pbdev; 317 uint64_t offset; 318 uint64_t data; 319 MemoryRegion *mr; 320 MemTxResult result; 321 uint8_t len; 322 uint32_t fh; 323 uint8_t pcias; 324 325 cpu_synchronize_state(CPU(cpu)); 326 327 if (env->psw.mask & PSW_MASK_PSTATE) { 328 program_interrupt(env, PGM_PRIVILEGED, 4); 329 return 0; 330 } 331 332 if (r2 & 0x1) { 333 program_interrupt(env, PGM_SPECIFICATION, 4); 334 return 0; 335 } 336 337 fh = env->regs[r2] >> 32; 338 pcias = (env->regs[r2] >> 16) & 0xf; 339 len = env->regs[r2] & 0xf; 340 offset = env->regs[r2 + 1]; 341 342 pbdev = s390_pci_find_dev_by_fh(fh); 343 if (!pbdev) { 344 DPRINTF("pcilg no pci dev\n"); 345 setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE); 346 return 0; 347 } 348 349 switch (pbdev->state) { 350 case ZPCI_FS_RESERVED: 351 case ZPCI_FS_STANDBY: 352 case ZPCI_FS_DISABLED: 353 case ZPCI_FS_PERMANENT_ERROR: 354 setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE); 355 return 0; 356 case ZPCI_FS_ERROR: 357 setcc(cpu, ZPCI_PCI_LS_ERR); 358 s390_set_status_code(env, r2, ZPCI_PCI_ST_BLOCKED); 359 return 0; 360 default: 361 break; 362 } 363 364 if (pcias < 6) { 365 if ((8 - (offset & 0x7)) < len) { 366 program_interrupt(env, PGM_OPERAND, 4); 367 return 0; 368 } 369 mr = pbdev->pdev->io_regions[pcias].memory; 370 result = memory_region_dispatch_read(mr, offset, &data, len, 371 MEMTXATTRS_UNSPECIFIED); 372 if (result != MEMTX_OK) { 373 program_interrupt(env, PGM_OPERAND, 4); 374 return 0; 375 } 376 } else if (pcias == 15) { 377 if ((4 - (offset & 0x3)) < len) { 378 program_interrupt(env, PGM_OPERAND, 4); 379 return 0; 380 } 381 data = pci_host_config_read_common( 382 pbdev->pdev, offset, pci_config_size(pbdev->pdev), len); 383 384 switch (len) { 385 case 1: 386 break; 387 case 2: 388 data = bswap16(data); 389 break; 390 case 4: 391 data = bswap32(data); 392 break; 393 case 8: 394 data = bswap64(data); 395 break; 396 default: 397 program_interrupt(env, PGM_OPERAND, 4); 398 return 0; 399 } 400 } else { 401 DPRINTF("invalid space\n"); 402 setcc(cpu, ZPCI_PCI_LS_ERR); 403 s390_set_status_code(env, r2, ZPCI_PCI_ST_INVAL_AS); 404 return 0; 405 } 406 407 env->regs[r1] = data; 408 setcc(cpu, ZPCI_PCI_LS_OK); 409 return 0; 410 } 411 412 static void update_msix_table_msg_data(S390PCIBusDevice *pbdev, uint64_t offset, 413 uint64_t *data, uint8_t len) 414 { 415 uint32_t val; 416 uint8_t *msg_data; 417 418 if (offset % PCI_MSIX_ENTRY_SIZE != 8) { 419 return; 420 } 421 422 if (len != 4) { 423 DPRINTF("access msix table msg data but len is %d\n", len); 424 return; 425 } 426 427 msg_data = (uint8_t *)data - offset % PCI_MSIX_ENTRY_SIZE + 428 PCI_MSIX_ENTRY_VECTOR_CTRL; 429 val = pci_get_long(msg_data) | 430 ((pbdev->fh & FH_MASK_INDEX) << ZPCI_MSI_VEC_BITS); 431 pci_set_long(msg_data, val); 432 DPRINTF("update msix msg_data to 0x%" PRIx64 "\n", *data); 433 } 434 435 static int trap_msix(S390PCIBusDevice *pbdev, uint64_t offset, uint8_t pcias) 436 { 437 if (pbdev->msix.available && pbdev->msix.table_bar == pcias && 438 offset >= pbdev->msix.table_offset && 439 offset <= pbdev->msix.table_offset + 440 (pbdev->msix.entries - 1) * PCI_MSIX_ENTRY_SIZE) { 441 return 1; 442 } else { 443 return 0; 444 } 445 } 446 447 int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2) 448 { 449 CPUS390XState *env = &cpu->env; 450 uint64_t offset, data; 451 S390PCIBusDevice *pbdev; 452 MemoryRegion *mr; 453 MemTxResult result; 454 uint8_t len; 455 uint32_t fh; 456 uint8_t pcias; 457 458 cpu_synchronize_state(CPU(cpu)); 459 460 if (env->psw.mask & PSW_MASK_PSTATE) { 461 program_interrupt(env, PGM_PRIVILEGED, 4); 462 return 0; 463 } 464 465 if (r2 & 0x1) { 466 program_interrupt(env, PGM_SPECIFICATION, 4); 467 return 0; 468 } 469 470 fh = env->regs[r2] >> 32; 471 pcias = (env->regs[r2] >> 16) & 0xf; 472 len = env->regs[r2] & 0xf; 473 offset = env->regs[r2 + 1]; 474 475 pbdev = s390_pci_find_dev_by_fh(fh); 476 if (!pbdev) { 477 DPRINTF("pcistg no pci dev\n"); 478 setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE); 479 return 0; 480 } 481 482 switch (pbdev->state) { 483 case ZPCI_FS_RESERVED: 484 case ZPCI_FS_STANDBY: 485 case ZPCI_FS_DISABLED: 486 case ZPCI_FS_PERMANENT_ERROR: 487 setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE); 488 return 0; 489 case ZPCI_FS_ERROR: 490 setcc(cpu, ZPCI_PCI_LS_ERR); 491 s390_set_status_code(env, r2, ZPCI_PCI_ST_BLOCKED); 492 return 0; 493 default: 494 break; 495 } 496 497 data = env->regs[r1]; 498 if (pcias < 6) { 499 if ((8 - (offset & 0x7)) < len) { 500 program_interrupt(env, PGM_OPERAND, 4); 501 return 0; 502 } 503 504 if (trap_msix(pbdev, offset, pcias)) { 505 offset = offset - pbdev->msix.table_offset; 506 mr = &pbdev->pdev->msix_table_mmio; 507 update_msix_table_msg_data(pbdev, offset, &data, len); 508 } else { 509 mr = pbdev->pdev->io_regions[pcias].memory; 510 } 511 512 result = memory_region_dispatch_write(mr, offset, data, len, 513 MEMTXATTRS_UNSPECIFIED); 514 if (result != MEMTX_OK) { 515 program_interrupt(env, PGM_OPERAND, 4); 516 return 0; 517 } 518 } else if (pcias == 15) { 519 if ((4 - (offset & 0x3)) < len) { 520 program_interrupt(env, PGM_OPERAND, 4); 521 return 0; 522 } 523 switch (len) { 524 case 1: 525 break; 526 case 2: 527 data = bswap16(data); 528 break; 529 case 4: 530 data = bswap32(data); 531 break; 532 case 8: 533 data = bswap64(data); 534 break; 535 default: 536 program_interrupt(env, PGM_OPERAND, 4); 537 return 0; 538 } 539 540 pci_host_config_write_common(pbdev->pdev, offset, 541 pci_config_size(pbdev->pdev), 542 data, len); 543 } else { 544 DPRINTF("pcistg invalid space\n"); 545 setcc(cpu, ZPCI_PCI_LS_ERR); 546 s390_set_status_code(env, r2, ZPCI_PCI_ST_INVAL_AS); 547 return 0; 548 } 549 550 setcc(cpu, ZPCI_PCI_LS_OK); 551 return 0; 552 } 553 554 int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2) 555 { 556 CPUS390XState *env = &cpu->env; 557 uint32_t fh; 558 S390PCIBusDevice *pbdev; 559 hwaddr start, end; 560 IOMMUTLBEntry entry; 561 MemoryRegion *mr; 562 563 cpu_synchronize_state(CPU(cpu)); 564 565 if (env->psw.mask & PSW_MASK_PSTATE) { 566 program_interrupt(env, PGM_PRIVILEGED, 4); 567 goto out; 568 } 569 570 if (r2 & 0x1) { 571 program_interrupt(env, PGM_SPECIFICATION, 4); 572 goto out; 573 } 574 575 fh = env->regs[r1] >> 32; 576 start = env->regs[r2]; 577 end = start + env->regs[r2 + 1]; 578 579 pbdev = s390_pci_find_dev_by_fh(fh); 580 if (!pbdev) { 581 DPRINTF("rpcit no pci dev\n"); 582 setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE); 583 goto out; 584 } 585 586 switch (pbdev->state) { 587 case ZPCI_FS_RESERVED: 588 case ZPCI_FS_STANDBY: 589 case ZPCI_FS_DISABLED: 590 case ZPCI_FS_PERMANENT_ERROR: 591 setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE); 592 return 0; 593 case ZPCI_FS_ERROR: 594 setcc(cpu, ZPCI_PCI_LS_ERR); 595 s390_set_status_code(env, r1, ZPCI_MOD_ST_ERROR_RECOVER); 596 return 0; 597 default: 598 break; 599 } 600 601 if (!pbdev->g_iota) { 602 pbdev->state = ZPCI_FS_ERROR; 603 setcc(cpu, ZPCI_PCI_LS_ERR); 604 s390_set_status_code(env, r1, ZPCI_PCI_ST_INSUF_RES); 605 s390_pci_generate_error_event(ERR_EVENT_INVALAS, pbdev->fh, pbdev->fid, 606 start, 0); 607 goto out; 608 } 609 610 if (end < pbdev->pba || start > pbdev->pal) { 611 pbdev->state = ZPCI_FS_ERROR; 612 setcc(cpu, ZPCI_PCI_LS_ERR); 613 s390_set_status_code(env, r1, ZPCI_PCI_ST_INSUF_RES); 614 s390_pci_generate_error_event(ERR_EVENT_OORANGE, pbdev->fh, pbdev->fid, 615 start, 0); 616 goto out; 617 } 618 619 mr = &pbdev->iommu_mr; 620 while (start < end) { 621 entry = mr->iommu_ops->translate(mr, start, 0); 622 623 if (!entry.translated_addr) { 624 pbdev->state = ZPCI_FS_ERROR; 625 setcc(cpu, ZPCI_PCI_LS_ERR); 626 s390_set_status_code(env, r1, ZPCI_PCI_ST_INSUF_RES); 627 s390_pci_generate_error_event(ERR_EVENT_SERR, pbdev->fh, pbdev->fid, 628 start, ERR_EVENT_Q_BIT); 629 goto out; 630 } 631 632 memory_region_notify_iommu(mr, entry); 633 start += entry.addr_mask + 1; 634 } 635 636 setcc(cpu, ZPCI_PCI_LS_OK); 637 out: 638 return 0; 639 } 640 641 int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr, 642 uint8_t ar) 643 { 644 CPUS390XState *env = &cpu->env; 645 S390PCIBusDevice *pbdev; 646 MemoryRegion *mr; 647 MemTxResult result; 648 int i; 649 uint32_t fh; 650 uint8_t pcias; 651 uint8_t len; 652 uint8_t buffer[128]; 653 654 if (env->psw.mask & PSW_MASK_PSTATE) { 655 program_interrupt(env, PGM_PRIVILEGED, 6); 656 return 0; 657 } 658 659 fh = env->regs[r1] >> 32; 660 pcias = (env->regs[r1] >> 16) & 0xf; 661 len = env->regs[r1] & 0xff; 662 663 if (pcias > 5) { 664 DPRINTF("pcistb invalid space\n"); 665 setcc(cpu, ZPCI_PCI_LS_ERR); 666 s390_set_status_code(env, r1, ZPCI_PCI_ST_INVAL_AS); 667 return 0; 668 } 669 670 switch (len) { 671 case 16: 672 case 32: 673 case 64: 674 case 128: 675 break; 676 default: 677 program_interrupt(env, PGM_SPECIFICATION, 6); 678 return 0; 679 } 680 681 pbdev = s390_pci_find_dev_by_fh(fh); 682 if (!pbdev) { 683 DPRINTF("pcistb no pci dev fh 0x%x\n", fh); 684 setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE); 685 return 0; 686 } 687 688 switch (pbdev->state) { 689 case ZPCI_FS_RESERVED: 690 case ZPCI_FS_STANDBY: 691 case ZPCI_FS_DISABLED: 692 case ZPCI_FS_PERMANENT_ERROR: 693 setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE); 694 return 0; 695 case ZPCI_FS_ERROR: 696 setcc(cpu, ZPCI_PCI_LS_ERR); 697 s390_set_status_code(env, r1, ZPCI_PCI_ST_BLOCKED); 698 return 0; 699 default: 700 break; 701 } 702 703 mr = pbdev->pdev->io_regions[pcias].memory; 704 if (!memory_region_access_valid(mr, env->regs[r3], len, true)) { 705 program_interrupt(env, PGM_OPERAND, 6); 706 return 0; 707 } 708 709 if (s390_cpu_virt_mem_read(cpu, gaddr, ar, buffer, len)) { 710 return 0; 711 } 712 713 for (i = 0; i < len / 8; i++) { 714 result = memory_region_dispatch_write(mr, env->regs[r3] + i * 8, 715 ldq_p(buffer + i * 8), 8, 716 MEMTXATTRS_UNSPECIFIED); 717 if (result != MEMTX_OK) { 718 program_interrupt(env, PGM_OPERAND, 6); 719 return 0; 720 } 721 } 722 723 setcc(cpu, ZPCI_PCI_LS_OK); 724 return 0; 725 } 726 727 static int reg_irqs(CPUS390XState *env, S390PCIBusDevice *pbdev, ZpciFib fib) 728 { 729 int ret, len; 730 731 ret = css_register_io_adapter(S390_PCIPT_ADAPTER, 732 FIB_DATA_ISC(ldl_p(&fib.data)), true, false, 733 &pbdev->routes.adapter.adapter_id); 734 assert(ret == 0); 735 736 pbdev->summary_ind = get_indicator(ldq_p(&fib.aisb), sizeof(uint64_t)); 737 len = BITS_TO_LONGS(FIB_DATA_NOI(ldl_p(&fib.data))) * sizeof(unsigned long); 738 pbdev->indicator = get_indicator(ldq_p(&fib.aibv), len); 739 740 ret = map_indicator(&pbdev->routes.adapter, pbdev->summary_ind); 741 if (ret) { 742 goto out; 743 } 744 745 ret = map_indicator(&pbdev->routes.adapter, pbdev->indicator); 746 if (ret) { 747 goto out; 748 } 749 750 pbdev->routes.adapter.summary_addr = ldq_p(&fib.aisb); 751 pbdev->routes.adapter.summary_offset = FIB_DATA_AISBO(ldl_p(&fib.data)); 752 pbdev->routes.adapter.ind_addr = ldq_p(&fib.aibv); 753 pbdev->routes.adapter.ind_offset = FIB_DATA_AIBVO(ldl_p(&fib.data)); 754 pbdev->isc = FIB_DATA_ISC(ldl_p(&fib.data)); 755 pbdev->noi = FIB_DATA_NOI(ldl_p(&fib.data)); 756 pbdev->sum = FIB_DATA_SUM(ldl_p(&fib.data)); 757 758 DPRINTF("reg_irqs adapter id %d\n", pbdev->routes.adapter.adapter_id); 759 return 0; 760 out: 761 release_indicator(&pbdev->routes.adapter, pbdev->summary_ind); 762 release_indicator(&pbdev->routes.adapter, pbdev->indicator); 763 pbdev->summary_ind = NULL; 764 pbdev->indicator = NULL; 765 return ret; 766 } 767 768 int pci_dereg_irqs(S390PCIBusDevice *pbdev) 769 { 770 release_indicator(&pbdev->routes.adapter, pbdev->summary_ind); 771 release_indicator(&pbdev->routes.adapter, pbdev->indicator); 772 773 pbdev->summary_ind = NULL; 774 pbdev->indicator = NULL; 775 pbdev->routes.adapter.summary_addr = 0; 776 pbdev->routes.adapter.summary_offset = 0; 777 pbdev->routes.adapter.ind_addr = 0; 778 pbdev->routes.adapter.ind_offset = 0; 779 pbdev->isc = 0; 780 pbdev->noi = 0; 781 pbdev->sum = 0; 782 783 DPRINTF("dereg_irqs adapter id %d\n", pbdev->routes.adapter.adapter_id); 784 return 0; 785 } 786 787 static int reg_ioat(CPUS390XState *env, S390PCIBusDevice *pbdev, ZpciFib fib) 788 { 789 uint64_t pba = ldq_p(&fib.pba); 790 uint64_t pal = ldq_p(&fib.pal); 791 uint64_t g_iota = ldq_p(&fib.iota); 792 uint8_t dt = (g_iota >> 2) & 0x7; 793 uint8_t t = (g_iota >> 11) & 0x1; 794 795 if (pba > pal || pba < ZPCI_SDMA_ADDR || pal > ZPCI_EDMA_ADDR) { 796 program_interrupt(env, PGM_OPERAND, 6); 797 return -EINVAL; 798 } 799 800 /* currently we only support designation type 1 with translation */ 801 if (!(dt == ZPCI_IOTA_RTTO && t)) { 802 error_report("unsupported ioat dt %d t %d", dt, t); 803 program_interrupt(env, PGM_OPERAND, 6); 804 return -EINVAL; 805 } 806 807 pbdev->pba = pba; 808 pbdev->pal = pal; 809 pbdev->g_iota = g_iota; 810 811 s390_pci_iommu_enable(pbdev); 812 813 return 0; 814 } 815 816 void pci_dereg_ioat(S390PCIBusDevice *pbdev) 817 { 818 s390_pci_iommu_disable(pbdev); 819 pbdev->pba = 0; 820 pbdev->pal = 0; 821 pbdev->g_iota = 0; 822 } 823 824 int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar) 825 { 826 CPUS390XState *env = &cpu->env; 827 uint8_t oc, dmaas; 828 uint32_t fh; 829 ZpciFib fib; 830 S390PCIBusDevice *pbdev; 831 uint64_t cc = ZPCI_PCI_LS_OK; 832 833 if (env->psw.mask & PSW_MASK_PSTATE) { 834 program_interrupt(env, PGM_PRIVILEGED, 6); 835 return 0; 836 } 837 838 oc = env->regs[r1] & 0xff; 839 dmaas = (env->regs[r1] >> 16) & 0xff; 840 fh = env->regs[r1] >> 32; 841 842 if (fiba & 0x7) { 843 program_interrupt(env, PGM_SPECIFICATION, 6); 844 return 0; 845 } 846 847 pbdev = s390_pci_find_dev_by_fh(fh); 848 if (!pbdev) { 849 DPRINTF("mpcifc no pci dev fh 0x%x\n", fh); 850 setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE); 851 return 0; 852 } 853 854 switch (pbdev->state) { 855 case ZPCI_FS_RESERVED: 856 case ZPCI_FS_STANDBY: 857 case ZPCI_FS_DISABLED: 858 case ZPCI_FS_PERMANENT_ERROR: 859 setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE); 860 return 0; 861 default: 862 break; 863 } 864 865 if (s390_cpu_virt_mem_read(cpu, fiba, ar, (uint8_t *)&fib, sizeof(fib))) { 866 return 0; 867 } 868 869 if (fib.fmt != 0) { 870 program_interrupt(env, PGM_OPERAND, 6); 871 return 0; 872 } 873 874 switch (oc) { 875 case ZPCI_MOD_FC_REG_INT: 876 if (pbdev->summary_ind) { 877 cc = ZPCI_PCI_LS_ERR; 878 s390_set_status_code(env, r1, ZPCI_MOD_ST_SEQUENCE); 879 } else if (reg_irqs(env, pbdev, fib)) { 880 cc = ZPCI_PCI_LS_ERR; 881 s390_set_status_code(env, r1, ZPCI_MOD_ST_RES_NOT_AVAIL); 882 } 883 break; 884 case ZPCI_MOD_FC_DEREG_INT: 885 if (!pbdev->summary_ind) { 886 cc = ZPCI_PCI_LS_ERR; 887 s390_set_status_code(env, r1, ZPCI_MOD_ST_SEQUENCE); 888 } else { 889 pci_dereg_irqs(pbdev); 890 } 891 break; 892 case ZPCI_MOD_FC_REG_IOAT: 893 if (dmaas != 0) { 894 cc = ZPCI_PCI_LS_ERR; 895 s390_set_status_code(env, r1, ZPCI_MOD_ST_DMAAS_INVAL); 896 } else if (pbdev->iommu_enabled) { 897 cc = ZPCI_PCI_LS_ERR; 898 s390_set_status_code(env, r1, ZPCI_MOD_ST_SEQUENCE); 899 } else if (reg_ioat(env, pbdev, fib)) { 900 cc = ZPCI_PCI_LS_ERR; 901 s390_set_status_code(env, r1, ZPCI_MOD_ST_INSUF_RES); 902 } 903 break; 904 case ZPCI_MOD_FC_DEREG_IOAT: 905 if (dmaas != 0) { 906 cc = ZPCI_PCI_LS_ERR; 907 s390_set_status_code(env, r1, ZPCI_MOD_ST_DMAAS_INVAL); 908 } else if (!pbdev->iommu_enabled) { 909 cc = ZPCI_PCI_LS_ERR; 910 s390_set_status_code(env, r1, ZPCI_MOD_ST_SEQUENCE); 911 } else { 912 pci_dereg_ioat(pbdev); 913 } 914 break; 915 case ZPCI_MOD_FC_REREG_IOAT: 916 if (dmaas != 0) { 917 cc = ZPCI_PCI_LS_ERR; 918 s390_set_status_code(env, r1, ZPCI_MOD_ST_DMAAS_INVAL); 919 } else if (!pbdev->iommu_enabled) { 920 cc = ZPCI_PCI_LS_ERR; 921 s390_set_status_code(env, r1, ZPCI_MOD_ST_SEQUENCE); 922 } else { 923 pci_dereg_ioat(pbdev); 924 if (reg_ioat(env, pbdev, fib)) { 925 cc = ZPCI_PCI_LS_ERR; 926 s390_set_status_code(env, r1, ZPCI_MOD_ST_INSUF_RES); 927 } 928 } 929 break; 930 case ZPCI_MOD_FC_RESET_ERROR: 931 switch (pbdev->state) { 932 case ZPCI_FS_BLOCKED: 933 case ZPCI_FS_ERROR: 934 pbdev->state = ZPCI_FS_ENABLED; 935 break; 936 default: 937 cc = ZPCI_PCI_LS_ERR; 938 s390_set_status_code(env, r1, ZPCI_MOD_ST_SEQUENCE); 939 } 940 break; 941 case ZPCI_MOD_FC_RESET_BLOCK: 942 switch (pbdev->state) { 943 case ZPCI_FS_ERROR: 944 pbdev->state = ZPCI_FS_BLOCKED; 945 break; 946 default: 947 cc = ZPCI_PCI_LS_ERR; 948 s390_set_status_code(env, r1, ZPCI_MOD_ST_SEQUENCE); 949 } 950 break; 951 case ZPCI_MOD_FC_SET_MEASURE: 952 pbdev->fmb_addr = ldq_p(&fib.fmb_addr); 953 break; 954 default: 955 program_interrupt(&cpu->env, PGM_OPERAND, 6); 956 cc = ZPCI_PCI_LS_ERR; 957 } 958 959 setcc(cpu, cc); 960 return 0; 961 } 962 963 int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar) 964 { 965 CPUS390XState *env = &cpu->env; 966 uint8_t dmaas; 967 uint32_t fh; 968 ZpciFib fib; 969 S390PCIBusDevice *pbdev; 970 uint32_t data; 971 uint64_t cc = ZPCI_PCI_LS_OK; 972 973 if (env->psw.mask & PSW_MASK_PSTATE) { 974 program_interrupt(env, PGM_PRIVILEGED, 6); 975 return 0; 976 } 977 978 fh = env->regs[r1] >> 32; 979 dmaas = (env->regs[r1] >> 16) & 0xff; 980 981 if (dmaas) { 982 setcc(cpu, ZPCI_PCI_LS_ERR); 983 s390_set_status_code(env, r1, ZPCI_STPCIFC_ST_INVAL_DMAAS); 984 return 0; 985 } 986 987 if (fiba & 0x7) { 988 program_interrupt(env, PGM_SPECIFICATION, 6); 989 return 0; 990 } 991 992 pbdev = s390_pci_find_dev_by_idx(fh & FH_MASK_INDEX); 993 if (!pbdev) { 994 setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE); 995 return 0; 996 } 997 998 memset(&fib, 0, sizeof(fib)); 999 1000 switch (pbdev->state) { 1001 case ZPCI_FS_RESERVED: 1002 case ZPCI_FS_STANDBY: 1003 setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE); 1004 return 0; 1005 case ZPCI_FS_DISABLED: 1006 if (fh & FH_MASK_ENABLE) { 1007 setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE); 1008 return 0; 1009 } 1010 goto out; 1011 /* BLOCKED bit is set to one coincident with the setting of ERROR bit. 1012 * FH Enabled bit is set to one in states of ENABLED, BLOCKED or ERROR. */ 1013 case ZPCI_FS_ERROR: 1014 fib.fc |= 0x20; 1015 case ZPCI_FS_BLOCKED: 1016 fib.fc |= 0x40; 1017 case ZPCI_FS_ENABLED: 1018 fib.fc |= 0x80; 1019 if (pbdev->iommu_enabled) { 1020 fib.fc |= 0x10; 1021 } 1022 if (!(fh & FH_MASK_ENABLE)) { 1023 env->regs[r1] |= 1ULL << 63; 1024 } 1025 break; 1026 case ZPCI_FS_PERMANENT_ERROR: 1027 setcc(cpu, ZPCI_PCI_LS_ERR); 1028 s390_set_status_code(env, r1, ZPCI_STPCIFC_ST_PERM_ERROR); 1029 return 0; 1030 } 1031 1032 stq_p(&fib.pba, pbdev->pba); 1033 stq_p(&fib.pal, pbdev->pal); 1034 stq_p(&fib.iota, pbdev->g_iota); 1035 stq_p(&fib.aibv, pbdev->routes.adapter.ind_addr); 1036 stq_p(&fib.aisb, pbdev->routes.adapter.summary_addr); 1037 stq_p(&fib.fmb_addr, pbdev->fmb_addr); 1038 1039 data = ((uint32_t)pbdev->isc << 28) | ((uint32_t)pbdev->noi << 16) | 1040 ((uint32_t)pbdev->routes.adapter.ind_offset << 8) | 1041 ((uint32_t)pbdev->sum << 7) | pbdev->routes.adapter.summary_offset; 1042 stl_p(&fib.data, data); 1043 1044 out: 1045 if (s390_cpu_virt_mem_write(cpu, fiba, ar, (uint8_t *)&fib, sizeof(fib))) { 1046 return 0; 1047 } 1048 1049 setcc(cpu, cc); 1050 return 0; 1051 } 1052