1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Intel On Demand (Software Defined Silicon) driver 4 * 5 * Copyright (c) 2022, Intel Corporation. 6 * All Rights Reserved. 7 * 8 * Author: "David E. Box" <david.e.box@linux.intel.com> 9 */ 10 11 #include <linux/auxiliary_bus.h> 12 #include <linux/bits.h> 13 #include <linux/bitfield.h> 14 #include <linux/device.h> 15 #include <linux/iopoll.h> 16 #include <linux/kernel.h> 17 #include <linux/module.h> 18 #include <linux/pci.h> 19 #include <linux/slab.h> 20 #include <linux/sysfs.h> 21 #include <linux/types.h> 22 #include <linux/uaccess.h> 23 24 #include "vsec.h" 25 26 #define ACCESS_TYPE_BARID 2 27 #define ACCESS_TYPE_LOCAL 3 28 29 #define SDSI_MIN_SIZE_DWORDS 276 30 #define SDSI_SIZE_MAILBOX 1024 31 #define SDSI_SIZE_REGS 80 32 #define SDSI_SIZE_CMD sizeof(u64) 33 34 /* 35 * Write messages are currently up to the size of the mailbox 36 * while read messages are up to 4 times the size of the 37 * mailbox, sent in packets 38 */ 39 #define SDSI_SIZE_WRITE_MSG SDSI_SIZE_MAILBOX 40 #define SDSI_SIZE_READ_MSG (SDSI_SIZE_MAILBOX * 4) 41 42 #define SDSI_ENABLED_FEATURES_OFFSET 16 43 #define SDSI_FEATURE_SDSI BIT(3) 44 #define SDSI_FEATURE_METERING BIT(26) 45 46 #define SDSI_SOCKET_ID_OFFSET 64 47 #define SDSI_SOCKET_ID GENMASK(3, 0) 48 49 #define SDSI_MBOX_CMD_SUCCESS 0x40 50 #define SDSI_MBOX_CMD_TIMEOUT 0x80 51 52 #define MBOX_TIMEOUT_US 500000 53 #define MBOX_TIMEOUT_ACQUIRE_US 1000 54 #define MBOX_POLLING_PERIOD_US 100 55 #define MBOX_ACQUIRE_NUM_RETRIES 5 56 #define MBOX_ACQUIRE_RETRY_DELAY_MS 500 57 #define MBOX_MAX_PACKETS 4 58 59 #define MBOX_OWNER_NONE 0x00 60 #define MBOX_OWNER_INBAND 0x01 61 62 #define CTRL_RUN_BUSY BIT(0) 63 #define CTRL_READ_WRITE BIT(1) 64 #define CTRL_SOM BIT(2) 65 #define CTRL_EOM BIT(3) 66 #define CTRL_OWNER GENMASK(5, 4) 67 #define CTRL_COMPLETE BIT(6) 68 #define CTRL_READY BIT(7) 69 #define CTRL_STATUS GENMASK(15, 8) 70 #define CTRL_PACKET_SIZE GENMASK(31, 16) 71 #define CTRL_MSG_SIZE GENMASK(63, 48) 72 73 #define DISC_TABLE_SIZE 12 74 #define DT_ACCESS_TYPE GENMASK(3, 0) 75 #define DT_SIZE GENMASK(27, 12) 76 #define DT_TBIR GENMASK(2, 0) 77 #define DT_OFFSET(v) ((v) & GENMASK(31, 3)) 78 79 #define SDSI_GUID_V1 0x006DD191 80 #define GUID_V1_CNTRL_SIZE 8 81 #define GUID_V1_REGS_SIZE 72 82 #define SDSI_GUID_V2 0xF210D9EF 83 #define GUID_V2_CNTRL_SIZE 16 84 #define GUID_V2_REGS_SIZE 80 85 86 enum sdsi_command { 87 SDSI_CMD_PROVISION_AKC = 0x0004, 88 SDSI_CMD_PROVISION_CAP = 0x0008, 89 SDSI_CMD_READ_STATE = 0x0010, 90 SDSI_CMD_READ_METER = 0x0014, 91 }; 92 93 struct sdsi_mbox_info { 94 u64 *payload; 95 void *buffer; 96 int size; 97 }; 98 99 struct disc_table { 100 u32 access_info; 101 u32 guid; 102 u32 offset; 103 }; 104 105 struct sdsi_priv { 106 struct mutex mb_lock; /* Mailbox access lock */ 107 struct device *dev; 108 void __iomem *control_addr; 109 void __iomem *mbox_addr; 110 void __iomem *regs_addr; 111 int control_size; 112 int maibox_size; 113 int registers_size; 114 u32 guid; 115 u32 features; 116 }; 117 118 /* SDSi mailbox operations must be performed using 64bit mov instructions */ 119 static __always_inline void 120 sdsi_memcpy64_toio(u64 __iomem *to, const u64 *from, size_t count_bytes) 121 { 122 size_t count = count_bytes / sizeof(*to); 123 int i; 124 125 for (i = 0; i < count; i++) 126 writeq(from[i], &to[i]); 127 } 128 129 static __always_inline void 130 sdsi_memcpy64_fromio(u64 *to, const u64 __iomem *from, size_t count_bytes) 131 { 132 size_t count = count_bytes / sizeof(*to); 133 int i; 134 135 for (i = 0; i < count; i++) 136 to[i] = readq(&from[i]); 137 } 138 139 static inline void sdsi_complete_transaction(struct sdsi_priv *priv) 140 { 141 u64 control = FIELD_PREP(CTRL_COMPLETE, 1); 142 143 lockdep_assert_held(&priv->mb_lock); 144 writeq(control, priv->control_addr); 145 } 146 147 static int sdsi_status_to_errno(u32 status) 148 { 149 switch (status) { 150 case SDSI_MBOX_CMD_SUCCESS: 151 return 0; 152 case SDSI_MBOX_CMD_TIMEOUT: 153 return -ETIMEDOUT; 154 default: 155 return -EIO; 156 } 157 } 158 159 static int sdsi_mbox_cmd_read(struct sdsi_priv *priv, struct sdsi_mbox_info *info, 160 size_t *data_size) 161 { 162 struct device *dev = priv->dev; 163 u32 total, loop, eom, status, message_size; 164 u64 control; 165 int ret; 166 167 lockdep_assert_held(&priv->mb_lock); 168 169 /* Format and send the read command */ 170 control = FIELD_PREP(CTRL_EOM, 1) | 171 FIELD_PREP(CTRL_SOM, 1) | 172 FIELD_PREP(CTRL_RUN_BUSY, 1) | 173 FIELD_PREP(CTRL_PACKET_SIZE, info->size); 174 writeq(control, priv->control_addr); 175 176 /* For reads, data sizes that are larger than the mailbox size are read in packets. */ 177 total = 0; 178 loop = 0; 179 do { 180 void *buf = info->buffer + (SDSI_SIZE_MAILBOX * loop); 181 u32 packet_size; 182 183 /* Poll on ready bit */ 184 ret = readq_poll_timeout(priv->control_addr, control, control & CTRL_READY, 185 MBOX_POLLING_PERIOD_US, MBOX_TIMEOUT_US); 186 if (ret) 187 break; 188 189 eom = FIELD_GET(CTRL_EOM, control); 190 status = FIELD_GET(CTRL_STATUS, control); 191 packet_size = FIELD_GET(CTRL_PACKET_SIZE, control); 192 message_size = FIELD_GET(CTRL_MSG_SIZE, control); 193 194 ret = sdsi_status_to_errno(status); 195 if (ret) 196 break; 197 198 /* Only the last packet can be less than the mailbox size. */ 199 if (!eom && packet_size != SDSI_SIZE_MAILBOX) { 200 dev_err(dev, "Invalid packet size\n"); 201 ret = -EPROTO; 202 break; 203 } 204 205 if (packet_size > SDSI_SIZE_MAILBOX) { 206 dev_err(dev, "Packet size too large\n"); 207 ret = -EPROTO; 208 break; 209 } 210 211 sdsi_memcpy64_fromio(buf, priv->mbox_addr, round_up(packet_size, SDSI_SIZE_CMD)); 212 213 total += packet_size; 214 215 sdsi_complete_transaction(priv); 216 } while (!eom && ++loop < MBOX_MAX_PACKETS); 217 218 if (ret) { 219 sdsi_complete_transaction(priv); 220 return ret; 221 } 222 223 if (!eom) { 224 dev_err(dev, "Exceeded read attempts\n"); 225 return -EPROTO; 226 } 227 228 /* Message size check is only valid for multi-packet transfers */ 229 if (loop && total != message_size) 230 dev_warn(dev, "Read count %u differs from expected count %u\n", 231 total, message_size); 232 233 *data_size = total; 234 235 return 0; 236 } 237 238 static int sdsi_mbox_cmd_write(struct sdsi_priv *priv, struct sdsi_mbox_info *info) 239 { 240 u64 control; 241 u32 status; 242 int ret; 243 244 lockdep_assert_held(&priv->mb_lock); 245 246 /* Write rest of the payload */ 247 sdsi_memcpy64_toio(priv->mbox_addr + SDSI_SIZE_CMD, info->payload + 1, 248 info->size - SDSI_SIZE_CMD); 249 250 /* Format and send the write command */ 251 control = FIELD_PREP(CTRL_EOM, 1) | 252 FIELD_PREP(CTRL_SOM, 1) | 253 FIELD_PREP(CTRL_RUN_BUSY, 1) | 254 FIELD_PREP(CTRL_READ_WRITE, 1) | 255 FIELD_PREP(CTRL_PACKET_SIZE, info->size); 256 writeq(control, priv->control_addr); 257 258 /* Poll on ready bit */ 259 ret = readq_poll_timeout(priv->control_addr, control, control & CTRL_READY, 260 MBOX_POLLING_PERIOD_US, MBOX_TIMEOUT_US); 261 262 if (ret) 263 goto release_mbox; 264 265 status = FIELD_GET(CTRL_STATUS, control); 266 ret = sdsi_status_to_errno(status); 267 268 release_mbox: 269 sdsi_complete_transaction(priv); 270 271 return ret; 272 } 273 274 static int sdsi_mbox_acquire(struct sdsi_priv *priv, struct sdsi_mbox_info *info) 275 { 276 u64 control; 277 u32 owner; 278 int ret, retries = 0; 279 280 lockdep_assert_held(&priv->mb_lock); 281 282 /* Check mailbox is available */ 283 control = readq(priv->control_addr); 284 owner = FIELD_GET(CTRL_OWNER, control); 285 if (owner != MBOX_OWNER_NONE) 286 return -EBUSY; 287 288 /* 289 * If there has been no recent transaction and no one owns the mailbox, 290 * we should acquire it in under 1ms. However, if we've accessed it 291 * recently it may take up to 2.1 seconds to acquire it again. 292 */ 293 do { 294 /* Write first qword of payload */ 295 writeq(info->payload[0], priv->mbox_addr); 296 297 /* Check for ownership */ 298 ret = readq_poll_timeout(priv->control_addr, control, 299 FIELD_GET(CTRL_OWNER, control) == MBOX_OWNER_INBAND, 300 MBOX_POLLING_PERIOD_US, MBOX_TIMEOUT_ACQUIRE_US); 301 302 if (FIELD_GET(CTRL_OWNER, control) == MBOX_OWNER_NONE && 303 retries++ < MBOX_ACQUIRE_NUM_RETRIES) { 304 msleep(MBOX_ACQUIRE_RETRY_DELAY_MS); 305 continue; 306 } 307 308 /* Either we got it or someone else did. */ 309 break; 310 } while (true); 311 312 return ret; 313 } 314 315 static int sdsi_mbox_write(struct sdsi_priv *priv, struct sdsi_mbox_info *info) 316 { 317 int ret; 318 319 lockdep_assert_held(&priv->mb_lock); 320 321 ret = sdsi_mbox_acquire(priv, info); 322 if (ret) 323 return ret; 324 325 return sdsi_mbox_cmd_write(priv, info); 326 } 327 328 static int sdsi_mbox_read(struct sdsi_priv *priv, struct sdsi_mbox_info *info, size_t *data_size) 329 { 330 int ret; 331 332 lockdep_assert_held(&priv->mb_lock); 333 334 ret = sdsi_mbox_acquire(priv, info); 335 if (ret) 336 return ret; 337 338 return sdsi_mbox_cmd_read(priv, info, data_size); 339 } 340 341 static ssize_t sdsi_provision(struct sdsi_priv *priv, char *buf, size_t count, 342 enum sdsi_command command) 343 { 344 struct sdsi_mbox_info info; 345 int ret; 346 347 if (count > (SDSI_SIZE_WRITE_MSG - SDSI_SIZE_CMD)) 348 return -EOVERFLOW; 349 350 /* Qword aligned message + command qword */ 351 info.size = round_up(count, SDSI_SIZE_CMD) + SDSI_SIZE_CMD; 352 353 info.payload = kzalloc(info.size, GFP_KERNEL); 354 if (!info.payload) 355 return -ENOMEM; 356 357 /* Copy message to payload buffer */ 358 memcpy(info.payload, buf, count); 359 360 /* Command is last qword of payload buffer */ 361 info.payload[(info.size - SDSI_SIZE_CMD) / SDSI_SIZE_CMD] = command; 362 363 ret = mutex_lock_interruptible(&priv->mb_lock); 364 if (ret) 365 goto free_payload; 366 ret = sdsi_mbox_write(priv, &info); 367 mutex_unlock(&priv->mb_lock); 368 369 free_payload: 370 kfree(info.payload); 371 372 if (ret) 373 return ret; 374 375 return count; 376 } 377 378 static ssize_t provision_akc_write(struct file *filp, struct kobject *kobj, 379 struct bin_attribute *attr, char *buf, loff_t off, 380 size_t count) 381 { 382 struct device *dev = kobj_to_dev(kobj); 383 struct sdsi_priv *priv = dev_get_drvdata(dev); 384 385 if (off) 386 return -ESPIPE; 387 388 return sdsi_provision(priv, buf, count, SDSI_CMD_PROVISION_AKC); 389 } 390 static BIN_ATTR_WO(provision_akc, SDSI_SIZE_WRITE_MSG); 391 392 static ssize_t provision_cap_write(struct file *filp, struct kobject *kobj, 393 struct bin_attribute *attr, char *buf, loff_t off, 394 size_t count) 395 { 396 struct device *dev = kobj_to_dev(kobj); 397 struct sdsi_priv *priv = dev_get_drvdata(dev); 398 399 if (off) 400 return -ESPIPE; 401 402 return sdsi_provision(priv, buf, count, SDSI_CMD_PROVISION_CAP); 403 } 404 static BIN_ATTR_WO(provision_cap, SDSI_SIZE_WRITE_MSG); 405 406 static ssize_t 407 certificate_read(u64 command, struct sdsi_priv *priv, char *buf, loff_t off, 408 size_t count) 409 { 410 struct sdsi_mbox_info info; 411 size_t size; 412 int ret; 413 414 if (off) 415 return 0; 416 417 /* Buffer for return data */ 418 info.buffer = kmalloc(SDSI_SIZE_READ_MSG, GFP_KERNEL); 419 if (!info.buffer) 420 return -ENOMEM; 421 422 info.payload = &command; 423 info.size = sizeof(command); 424 425 ret = mutex_lock_interruptible(&priv->mb_lock); 426 if (ret) 427 goto free_buffer; 428 ret = sdsi_mbox_read(priv, &info, &size); 429 mutex_unlock(&priv->mb_lock); 430 if (ret < 0) 431 goto free_buffer; 432 433 if (size > count) 434 size = count; 435 436 memcpy(buf, info.buffer, size); 437 438 free_buffer: 439 kfree(info.buffer); 440 441 if (ret) 442 return ret; 443 444 return size; 445 } 446 447 static ssize_t 448 state_certificate_read(struct file *filp, struct kobject *kobj, 449 struct bin_attribute *attr, char *buf, loff_t off, 450 size_t count) 451 { 452 struct device *dev = kobj_to_dev(kobj); 453 struct sdsi_priv *priv = dev_get_drvdata(dev); 454 455 return certificate_read(SDSI_CMD_READ_STATE, priv, buf, off, count); 456 } 457 static BIN_ATTR_ADMIN_RO(state_certificate, SDSI_SIZE_READ_MSG); 458 459 static ssize_t 460 meter_certificate_read(struct file *filp, struct kobject *kobj, 461 struct bin_attribute *attr, char *buf, loff_t off, 462 size_t count) 463 { 464 struct device *dev = kobj_to_dev(kobj); 465 struct sdsi_priv *priv = dev_get_drvdata(dev); 466 467 return certificate_read(SDSI_CMD_READ_METER, priv, buf, off, count); 468 } 469 static BIN_ATTR_ADMIN_RO(meter_certificate, SDSI_SIZE_READ_MSG); 470 471 static ssize_t registers_read(struct file *filp, struct kobject *kobj, 472 struct bin_attribute *attr, char *buf, loff_t off, 473 size_t count) 474 { 475 struct device *dev = kobj_to_dev(kobj); 476 struct sdsi_priv *priv = dev_get_drvdata(dev); 477 void __iomem *addr = priv->regs_addr; 478 int size = priv->registers_size; 479 480 /* 481 * The check below is performed by the sysfs caller based on the static 482 * file size. But this may be greater than the actual size which is based 483 * on the GUID. So check here again based on actual size before reading. 484 */ 485 if (off >= size) 486 return 0; 487 488 if (off + count > size) 489 count = size - off; 490 491 memcpy_fromio(buf, addr + off, count); 492 493 return count; 494 } 495 static BIN_ATTR_ADMIN_RO(registers, SDSI_SIZE_REGS); 496 497 static struct bin_attribute *sdsi_bin_attrs[] = { 498 &bin_attr_registers, 499 &bin_attr_state_certificate, 500 &bin_attr_meter_certificate, 501 &bin_attr_provision_akc, 502 &bin_attr_provision_cap, 503 NULL 504 }; 505 506 static umode_t 507 sdsi_battr_is_visible(struct kobject *kobj, struct bin_attribute *attr, int n) 508 { 509 struct device *dev = kobj_to_dev(kobj); 510 struct sdsi_priv *priv = dev_get_drvdata(dev); 511 512 /* Registers file is always readable if the device is present */ 513 if (attr == &bin_attr_registers) 514 return attr->attr.mode; 515 516 /* All other attributes not visible if BIOS has not enabled On Demand */ 517 if (!(priv->features & SDSI_FEATURE_SDSI)) 518 return 0; 519 520 if (attr == &bin_attr_meter_certificate) 521 return (priv->features & SDSI_FEATURE_METERING) ? 522 attr->attr.mode : 0; 523 524 return attr->attr.mode; 525 } 526 527 static ssize_t guid_show(struct device *dev, struct device_attribute *attr, char *buf) 528 { 529 struct sdsi_priv *priv = dev_get_drvdata(dev); 530 531 return sysfs_emit(buf, "0x%x\n", priv->guid); 532 } 533 static DEVICE_ATTR_RO(guid); 534 535 static struct attribute *sdsi_attrs[] = { 536 &dev_attr_guid.attr, 537 NULL 538 }; 539 540 static const struct attribute_group sdsi_group = { 541 .attrs = sdsi_attrs, 542 .bin_attrs = sdsi_bin_attrs, 543 .is_bin_visible = sdsi_battr_is_visible, 544 }; 545 __ATTRIBUTE_GROUPS(sdsi); 546 547 static int sdsi_get_layout(struct sdsi_priv *priv, struct disc_table *table) 548 { 549 switch (table->guid) { 550 case SDSI_GUID_V1: 551 priv->control_size = GUID_V1_CNTRL_SIZE; 552 priv->registers_size = GUID_V1_REGS_SIZE; 553 break; 554 case SDSI_GUID_V2: 555 priv->control_size = GUID_V2_CNTRL_SIZE; 556 priv->registers_size = GUID_V2_REGS_SIZE; 557 break; 558 default: 559 dev_err(priv->dev, "Unrecognized GUID 0x%x\n", table->guid); 560 return -EINVAL; 561 } 562 return 0; 563 } 564 565 static int sdsi_map_mbox_registers(struct sdsi_priv *priv, struct pci_dev *parent, 566 struct disc_table *disc_table, struct resource *disc_res) 567 { 568 u32 access_type = FIELD_GET(DT_ACCESS_TYPE, disc_table->access_info); 569 u32 size = FIELD_GET(DT_SIZE, disc_table->access_info); 570 u32 tbir = FIELD_GET(DT_TBIR, disc_table->offset); 571 u32 offset = DT_OFFSET(disc_table->offset); 572 struct resource res = {}; 573 574 /* Starting location of SDSi MMIO region based on access type */ 575 switch (access_type) { 576 case ACCESS_TYPE_LOCAL: 577 if (tbir) { 578 dev_err(priv->dev, "Unsupported BAR index %u for access type %u\n", 579 tbir, access_type); 580 return -EINVAL; 581 } 582 583 /* 584 * For access_type LOCAL, the base address is as follows: 585 * base address = end of discovery region + base offset + 1 586 */ 587 res.start = disc_res->end + offset + 1; 588 break; 589 590 case ACCESS_TYPE_BARID: 591 res.start = pci_resource_start(parent, tbir) + offset; 592 break; 593 594 default: 595 dev_err(priv->dev, "Unrecognized access_type %u\n", access_type); 596 return -EINVAL; 597 } 598 599 res.end = res.start + size * sizeof(u32) - 1; 600 res.flags = IORESOURCE_MEM; 601 602 priv->control_addr = devm_ioremap_resource(priv->dev, &res); 603 if (IS_ERR(priv->control_addr)) 604 return PTR_ERR(priv->control_addr); 605 606 priv->mbox_addr = priv->control_addr + priv->control_size; 607 priv->regs_addr = priv->mbox_addr + SDSI_SIZE_MAILBOX; 608 609 priv->features = readq(priv->regs_addr + SDSI_ENABLED_FEATURES_OFFSET); 610 611 return 0; 612 } 613 614 static int sdsi_probe(struct auxiliary_device *auxdev, const struct auxiliary_device_id *id) 615 { 616 struct intel_vsec_device *intel_cap_dev = auxdev_to_ivdev(auxdev); 617 struct disc_table disc_table; 618 struct resource *disc_res; 619 void __iomem *disc_addr; 620 struct sdsi_priv *priv; 621 int ret; 622 623 priv = devm_kzalloc(&auxdev->dev, sizeof(*priv), GFP_KERNEL); 624 if (!priv) 625 return -ENOMEM; 626 627 priv->dev = &auxdev->dev; 628 mutex_init(&priv->mb_lock); 629 auxiliary_set_drvdata(auxdev, priv); 630 631 /* Get the SDSi discovery table */ 632 disc_res = &intel_cap_dev->resource[0]; 633 disc_addr = devm_ioremap_resource(&auxdev->dev, disc_res); 634 if (IS_ERR(disc_addr)) 635 return PTR_ERR(disc_addr); 636 637 memcpy_fromio(&disc_table, disc_addr, DISC_TABLE_SIZE); 638 639 priv->guid = disc_table.guid; 640 641 /* Get guid based layout info */ 642 ret = sdsi_get_layout(priv, &disc_table); 643 if (ret) 644 return ret; 645 646 /* Map the SDSi mailbox registers */ 647 ret = sdsi_map_mbox_registers(priv, intel_cap_dev->pcidev, &disc_table, disc_res); 648 if (ret) 649 return ret; 650 651 return 0; 652 } 653 654 static const struct auxiliary_device_id sdsi_aux_id_table[] = { 655 { .name = "intel_vsec.sdsi" }, 656 {} 657 }; 658 MODULE_DEVICE_TABLE(auxiliary, sdsi_aux_id_table); 659 660 static struct auxiliary_driver sdsi_aux_driver = { 661 .driver = { 662 .dev_groups = sdsi_groups, 663 }, 664 .id_table = sdsi_aux_id_table, 665 .probe = sdsi_probe, 666 /* No remove. All resources are handled under devm */ 667 }; 668 module_auxiliary_driver(sdsi_aux_driver); 669 670 MODULE_AUTHOR("David E. Box <david.e.box@linux.intel.com>"); 671 MODULE_DESCRIPTION("Intel On Demand (SDSi) driver"); 672 MODULE_LICENSE("GPL"); 673