github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/cpvmm/vmm/include/hw/vtd_hw_layer.h (about) 1 /* 2 * Copyright (c) 2013 Intel Corporation 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * Unless required by applicable law or agreed to in writing, software 9 * distributed under the License is distributed on an "AS IS" BASIS, 10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 * See the License for the specific language governing permissions and 12 * limitations under the License. 13 */ 14 15 #ifndef _VTD_HW_LAYER 16 #define _VTD_HW_LAYER 17 18 #include "vtd.h" 19 #include "hw_utils.h" 20 21 #pragma warning(push) 22 #pragma warning(disable:4214) 23 24 typedef union _DMA_REMAPPING_ROOT_ENTRY_LOW 25 { 26 struct 27 { 28 UINT32 29 present:1, 30 reserved:11, 31 context_entry_table_ptr_low:20; 32 UINT32 context_entry_table_ptr_high; 33 } bits; 34 UINT64 uint64; 35 } DMA_REMAPPING_ROOT_ENTRY_LOW; 36 37 typedef union _DMA_REMAPPING_ROOT_ENTRY_HIGH 38 { 39 struct 40 { 41 UINT64 reserved; 42 } bits; 43 UINT64 uint64; 44 } DMA_REMAPPING_ROOT_ENTRY_HIGH; 45 46 typedef struct _DMA_REMAPPING_ROOT_ENTRY 47 { 48 DMA_REMAPPING_ROOT_ENTRY_LOW low; 49 DMA_REMAPPING_ROOT_ENTRY_HIGH high; 50 } DMA_REMAPPING_ROOT_ENTRY; 51 52 typedef enum 53 { 54 TRANSLATION_TYPE_UNTRANSLATED_ADDRESS_ONLY = 0, 55 TRANSLATION_TYPE_ALL, 56 TRANSLATION_TYPE_PASSTHROUGH_UNTRANSLATED_ADDRESS 57 } DMA_REMAPPING_TRANSLATION_TYPE; 58 59 typedef enum 60 { 61 DMA_REMAPPING_GAW_30 = 0, 62 DMA_REMAPPING_GAW_39, 63 DMA_REMAPPING_GAW_48, 64 DMA_REMAPPING_GAW_57, 65 DMA_REMAPPING_GAW_64 66 } DMA_REMAPPING_GUEST_ADDRESS_WIDTH; 67 68 typedef union _DMA_REMAPPING_CONTEXT_ENTRY_LOW 69 { 70 struct 71 { 72 UINT32 73 present:1, 74 fault_processing_disable:1, 75 translation_type:2, 76 eviction_hint:1, // 0 = default, 1 = eager eviction 77 adress_locality_hint:1, // 0 = default, 1 = requests have spatial locality 78 reserved:6, 79 address_space_root_low:20; 80 UINT32 address_space_root_high; 81 } bits; 82 UINT64 uint64; 83 } DMA_REMAPPING_CONTEXT_ENTRY_LOW; 84 85 typedef union _DMA_REMAPPING_CONTEXT_ENTRY_HIGH 86 { 87 struct 88 { 89 UINT32 90 address_width:3, 91 available:4, 92 reserved0:1, 93 domain_id:16, 94 reserved1:8; 95 UINT32 reserved; 96 } bits; 97 UINT64 uint64; 98 } DMA_REMAPPING_CONTEXT_ENTRY_HIGH; 99 100 typedef struct _DMA_REMAPPING_CONTEXT_ENTRY 101 { 102 DMA_REMAPPING_CONTEXT_ENTRY_LOW low; 103 DMA_REMAPPING_CONTEXT_ENTRY_HIGH high; 104 } DMA_REMAPPING_CONTEXT_ENTRY; 105 106 typedef union _DMA_REMAPPING_PAGE_TABLE_ENTRY 107 { 108 struct 109 { 110 UINT32 111 read:1, 112 write:1, 113 available0:5, 114 super_page:1, 115 available:3, 116 snoop_behavior:1, // 0 = default, 1 = treat as snooped 117 address_low:20; 118 UINT32 119 address_high:30, 120 transient_mapping:1, 121 available1:1; 122 } bits; 123 UINT64 uint64; 124 } DMA_REMAPPING_PAGE_TABLE_ENTRY; 125 126 typedef union _DMA_REMAPPING_FAULT_RECORD_LOW 127 { 128 struct 129 { 130 UINT32 131 reserved:12, 132 fault_information_low:20; 133 UINT32 fault_information_high; 134 } bits; 135 UINT64 uint64; 136 } DMA_REMAPPING_FAULT_RECORD_LOW; 137 138 typedef union _DMA_REMAPPING_FAULT_RECORD_HIGH 139 { 140 struct 141 { 142 UINT32 143 source_id:16, 144 reserved0:16; 145 UINT32 146 fault_reason:8, 147 reserved1:20, 148 address_type:2, 149 access_type:1, // 0 = write, 1 = read 150 reserved2:1; 151 } bits; 152 UINT64 uint64; 153 } DMA_REMAPPING_FAULT_RECORD_HIGH; 154 155 typedef struct _DMA_REMAPPING_FAULT_RECORD 156 { 157 DMA_REMAPPING_FAULT_RECORD_LOW low; 158 DMA_REMAPPING_FAULT_RECORD_HIGH high; 159 } DMA_REMAPPING_FAULT_RECORD; 160 161 typedef enum 162 { 163 SOURCE_ID_QUALIFIER_ALL = 0, 164 SOURCE_ID_QUALIFIER_IGNORE_FUNCTION_MSB, 165 SOURCE_ID_QUALIFIER_IGNORE_2_FUNCTION_MSB, 166 SOURCE_ID_QUALIFIER_IGNORE_FUNCTION 167 } INTERRUPT_REMAPPING_SOURCE_ID_QUALIFIER; 168 169 typedef enum 170 { 171 SOURCE_ID_VALIDATION_NONE, 172 SOURCE_ID_VALIDATION_AS_BDF, 173 SOURCE_ID_VALIDATION_BUS_IN_RANGE 174 } INTERRUPT_REMAPPING_SOURCE_ID_VALIDATION_TYPE; 175 176 typedef union _INTERRUPT_REMAPPING_TABLE_ENTRY_LOW 177 { 178 struct 179 { 180 UINT32 181 present:1, 182 fault_processing_disable:1, 183 destination_mode:1, // 0 = physical APIC ID, 1 = logical APIC ID 184 redirection_hint:1, // 0 = direct to CPU in destination id field, 1 = direct to one CPU from the group 185 trigger_mode:1, // 0 = edge, 1 = level 186 delivery_mode:1, 187 available:4, 188 reserved:4; 189 UINT32 destination_id; 190 } bits; 191 UINT64 uint64; 192 } INTERRUPT_REMAPPING_TABLE_ENTRY_LOW; 193 194 typedef union _INTERRUPT_REMAPPING_TABLE_ENTRY_HIGH 195 { 196 struct 197 { 198 UINT32 199 source_id:16, 200 source_id_qualifier:2, 201 source_validation_type:2, 202 reserved0:12; 203 UINT32 reserved1; 204 } bits; 205 UINT64 uint64; 206 } INTERRUPT_REMAPPING_TABLE_ENTRY_HIGH; 207 208 typedef struct _INTERRUPT_REMAPPING_TABLE_ENTRY 209 { 210 INTERRUPT_REMAPPING_TABLE_ENTRY_LOW low; 211 INTERRUPT_REMAPPING_TABLE_ENTRY_HIGH high; 212 } INTERRUPT_REMAPPING_TABLE_ENTRY; 213 214 // vtd registers 215 #define VTD_VERSION_REGISTER_OFFSET 0x0000 216 #define VTD_CAPABILITY_REGISTER_OFFSET 0x0008 217 #define VTD_EXTENDED_CAPABILITY_REGISTER_OFFSET 0x0010 218 #define VTD_GLOBAL_COMMAND_REGISTER_OFFSET 0x0018 219 #define VTD_GLOBAL_STATUS_REGISTER_OFFSET 0x001C 220 #define VTD_ROOT_ENTRY_TABLE_ADDRESS_REGISTER_OFFSET 0x0020 221 #define VTD_CONTEXT_COMMAND_REGISTER_OFFSET 0x0028 222 #define VTD_FAULT_STATUS_REGISTER_OFFSET 0x0034 223 #define VTD_FAULT_EVENT_CONTROL_REGISTER_OFFSET 0x0038 224 #define VTD_FAULT_EVENT_DATA_REGISTER_OFFSET 0x003C 225 #define VTD_FAULT_EVENT_ADDRESS_REGISTER_OFFSET 0x0040 226 #define VTD_FAULT_EVENT_ADDRESS_HIGH_REGISTER_OFFSET 0x0044 227 #define VTD_ADVANCED_FAULT_LOG_REGISTER_OFFSET 0x0058 228 #define VTD_PROTECTED_MEMORY_ENABLE_REGISTER_OFFSET 0x0064 229 #define VTD_PROTECTED_LOW_MEMORY_BASE_REGISTER_OFFSET 0x0068 230 #define VTD_PROTECTED_LOW_MEMORY_LIMIT_REGISTER_OFFSET 0x006C 231 #define VTD_PROTECTED_HIGH_MEMORY_BASE_REGISTER_OFFSET 0x0070 232 #define VTD_PROTECTED_HIGH_MEMORY_LIMIT_REGISTER_OFFSET 0x0078 233 #define VTD_INVALIDATION_QUEUE_HEAD_REGISTER_OFFSET 0x0080 234 #define VTD_INVALIDATION_QUEUE_TAIL_REGISTER_OFFSET 0x0088 235 #define VTD_INVALIDATION_QUEUE_ADDRESS_REGISTER_OFFSET 0x0090 236 #define VTD_INVALIDATION_COMPLETION_STATUS_REGISTER_OFFSET 0x009C 237 #define VTD_INVALIDATION_COMPLETION_EVENT_CONTROL_REGISTER_OFFSET 0x00A0 238 #define VTD_INVALIDATION_COMPLETION_EVENT_DATA_REGISTER_OFFSET 0x00A4 239 #define VTD_INVALIDATION_COMPLETION_EVENT_ADDRESS_REGISTER_OFFSET 0x00A8 240 #define VTD_INVALIDATION_COMPLETION_EVENT_ADDRESS_HIGH_REGISTER_OFFSET 0x00AC 241 #define VTD_INTERRUPT_REMAPPING_TABLE_ADDRESS_REGISTER_OFFSET 0x00A0 242 243 // definition for "Snoop Behavior" and "Transient Mapping" filds in VT-d page tables 244 #define VTD_SNPB_SNOOPED 1 245 #define VTD_NON_SNPB_SNOOPED 0 246 #define VTD_TRANSIENT_MAPPING 1 247 #define VTD_NON_TRANSIENT_MAPPING 0 248 249 typedef union 250 { 251 struct 252 { 253 UINT32 minor:4; 254 UINT32 major:4; 255 UINT32 reserved:24; 256 } bits; 257 UINT32 uint32; 258 } VTD_VERSION_REGISTER; 259 260 typedef enum 261 { 262 VTD_NUMBER_OF_SUPPORTED_DOMAINS_16 = 0, 263 VTD_NUMBER_OF_SUPPORTED_DOMAINS_64, 264 VTD_NUMBER_OF_SUPPORTED_DOMAINS_256, 265 VTD_NUMBER_OF_SUPPORTED_DOMAINS_1024, 266 VTD_NUMBER_OF_SUPPORTED_DOMAINS_4K, 267 VTD_NUMBER_OF_SUPPORTED_DOMAINS_16K, 268 VTD_NUMBER_OF_SUPPORTED_DOMAINS_64K 269 } VTD_NUMBER_OF_SUPPORTED_DOMAINS; 270 271 #define VTD_SUPER_PAGE_SUPPORT_21(sp_support) ((sp_support) & 0x0001) 272 #define VTD_SUPER_PAGE_SUPPORT_30(sp_support) ((sp_support) & 0x0010) 273 #define VTD_SUPER_PAGE_SUPPORT_39(sp_support) ((sp_support) & 0x0100) 274 #define VTD_SUPER_PAGE_SUPPORT_48(sp_support) ((sp_support) & 0x1000) 275 276 typedef union 277 { 278 struct 279 { 280 UINT32 281 number_of_domains:3, 282 advanced_fault_log:1, 283 required_write_buffer_flush:1, 284 protected_low_memory_region:1, // 0 = not supported, 1 = supported 285 protected_high_memory_region:1, // 0 = not supported, 1 = supported 286 caching_mode:1, 287 adjusted_guest_address_width:5, 288 reserved0:3, 289 max_guest_address_width:6, 290 zero_length_read:1, 291 isochrony:1, 292 fault_recording_register_offset_low:8; 293 UINT32 294 fault_recording_register_offset_high:2, 295 super_page_support:4, 296 reserved1:1, 297 page_selective_invalidation:1, // 0 = not supported (only global and domain), 1 = supported 298 number_of_fault_recording_registers:8, 299 max_address_mask_value:6, 300 dma_write_draining:1, // 0 = not supported, 1 = supported 301 dma_read_draining:1, // 0 = not supported, 1 = supported 302 reserved2:8; 303 } bits; 304 UINT64 uint64; 305 } VTD_CAPABILITY_REGISTER; 306 307 typedef union 308 { 309 struct 310 { 311 UINT32 312 coherency:1, // 0 = not-snooped, 1 = snooped 313 queued_invalidation:1, // 0 = not-supported, 1 = supported 314 device_iotlb:1, 315 interrupt_remapping:1, 316 extended_interrupt_mode:1, // 0 = 8-bit APIC id, 1 = 16-bit (x2APIC) 317 caching_hints:1, 318 pass_through:1, 319 snoop_control:1, 320 iotlb_register_offset:10, 321 reserved0:2, 322 max_handle_mask_value:4, 323 reserved1:8; 324 UINT32 reserved2; 325 } bits; 326 UINT64 uint64; 327 } VTD_EXTENDED_CAPABILITY_REGISTER; 328 329 typedef union 330 { 331 struct 332 { 333 UINT32 reserved0:23; 334 UINT32 compatibility_format_interrupt:1; // 0 = block; 1 = pass-through 335 UINT32 set_interrupt_remap_table_ptr:1; 336 UINT32 interrupt_remap_enable:1; 337 UINT32 queued_invalidation_enable:1; 338 UINT32 write_buffer_flush:1; 339 UINT32 advanced_fault_log_enable:1; 340 UINT32 set_advanced_fault_log_ptr:1; 341 UINT32 set_root_table_ptr:1; 342 UINT32 translation_enable:1; 343 } bits; 344 UINT32 uint32; 345 } VTD_GLOBAL_COMMAND_REGISTER; 346 347 typedef union 348 { 349 struct 350 { 351 UINT32 reserved0:23; 352 UINT32 compatibility_format_interrupt_status:1; 353 UINT32 interrupt_remap_table_ptr_status:1; 354 UINT32 interrupt_remap_enable_status:1; 355 UINT32 queued_invalidation_enable_status:1; 356 UINT32 write_buffer_flush_status:1; 357 UINT32 advanced_fault_log_enable_status:1; 358 UINT32 advanced_fault_log_ptr_status:1; 359 UINT32 root_table_ptr_status:1; 360 UINT32 translation_enable_status:1; 361 } bits; 362 UINT32 uint32; 363 } VTD_GLOBAL_STATUS_REGISTER; 364 365 typedef union 366 { 367 struct 368 { 369 UINT32 370 reserved:12, 371 address_low:20; 372 UINT32 address_high; 373 } bits; 374 UINT64 uint64; 375 } VTD_ROOT_ENTRY_TABLE_ADDRESS_REGISTER; 376 377 typedef enum 378 { 379 VTD_CONTEXT_INV_GRANULARITY_GLOBAL = 0x1, 380 VTD_CONTEXT_INV_GRANULARITY_DOMAIN = 0x2, 381 VTD_CONTEXT_INV_GRANULARITY_DEVICE = 0x3 382 } VTD_CONTEXT_INV_GRANULARITY; 383 384 typedef union 385 { 386 struct 387 { 388 UINT32 389 domain_id:16, 390 source_id:16; 391 UINT32 392 function_mask:2, 393 reserved:25, 394 context_actual_invld_granularity:2, 395 context_invld_request_granularity:2, 396 invalidate_context_cache:1; 397 } bits; 398 UINT64 uint64; 399 } VTD_CONTEXT_COMMAND_REGISTER; 400 401 typedef enum 402 { 403 VTD_IOTLB_INV_GRANULARITY_GLOBAL = 0x1, 404 VTD_IOTLB_INV_GRANULARITY_DOMAIN = 0x2, 405 VTD_IOTLB_INV_GRANULARITY_PAGE = 0x3 406 } VTD_IOTLB_INV_GRANULARITY; 407 408 typedef union 409 { 410 struct 411 { 412 UINT32 reserved0; 413 UINT32 domain_id:16, 414 drain_writes:1, 415 drain_reads:1, 416 reserved1:7, 417 iotlb_actual_invld_granularity:3, 418 iotlb_invld_request_granularity:3, 419 invalidate_iotlb:1; 420 } bits; 421 UINT64 uint64; 422 } VTD_IOTLB_INVALIDATE_REGISTER; 423 424 typedef union 425 { 426 struct 427 { 428 UINT32 429 address_mask:6, 430 invalidation_hint:1, 431 reserved:5, 432 address_low:20; 433 UINT32 address_high; 434 } bits; 435 UINT64 uint64; 436 } VTD_INVALIDATE_ADDRESS_REGISTER; 437 438 typedef union 439 { 440 struct 441 { 442 UINT32 fault_overflow:1; 443 UINT32 primary_pending_fault:1; 444 UINT32 advanced_fault_overflow:1; 445 UINT32 advanced_pending_fault:1; 446 UINT32 invalidation_queue_error:1; 447 UINT32 invalidation_completion_error:1; 448 UINT32 invalidation_timeout_error:1; 449 UINT32 reserved0:1; 450 UINT32 fault_record_index:8; 451 UINT32 reserved1:16; 452 } bits; 453 UINT32 uint32; 454 } VTD_FAULT_STATUS_REGISTER; 455 456 typedef union 457 { 458 struct 459 { 460 UINT32 reserved:30; 461 UINT32 interrupt_pending:1; 462 UINT32 interrupt_mask:1; 463 } bits; 464 UINT32 uint32; 465 } VTD_FAULT_EVENT_CONTROL_REGISTER; 466 467 typedef union 468 { 469 struct 470 { 471 UINT32 vector:8; 472 UINT32 delivery_mode:3; // 0 = fixed; 1=lowest priority 473 UINT32 reserved:3; 474 UINT32 trigger_mode_level:1; 475 UINT32 trigger_mode:1; 476 UINT32 reserved1:18; 477 } bits; 478 UINT32 uint32; 479 } VTD_FAULT_EVENT_DATA_REGISTER; 480 481 typedef union 482 { 483 struct 484 { 485 UINT32 reserved0:2; 486 UINT32 destination_mode:1; 487 UINT32 redirection_hint:1; 488 UINT32 reserved1:8; 489 UINT32 destination_id:8; 490 UINT32 reserved2:12; // reserved to 0xfee 491 } bits; 492 UINT32 uint32; 493 } VTD_FAULT_EVENT_ADDRESS_REGISTER; 494 495 typedef struct 496 { 497 UINT32 reserved; 498 } VTD_FAULT_EVENT_UPPER_ADDRESS_REGISTER; 499 500 typedef union 501 { 502 struct 503 { 504 UINT32 505 reserved:12, 506 fault_info_low:20; 507 UINT32 fault_info_high; 508 } bits; 509 UINT64 uint64; 510 } VTD_FAULT_RECORDING_REGISTER_LOW; 511 512 typedef union 513 { 514 struct 515 { 516 UINT32 517 source_id:16, 518 reserved0:16; 519 UINT32 520 fault_reason:8, 521 reserved1:20, 522 address_type:2, 523 request_type:1, // 0 = write; 1 = read 524 fault:1; 525 } bits; 526 UINT64 uint64; 527 } VTD_FAULT_RECORDING_REGISTER_HIGH; 528 529 typedef struct 530 { 531 VTD_FAULT_RECORDING_REGISTER_LOW low; 532 VTD_FAULT_RECORDING_REGISTER_HIGH high; 533 } VTD_FAULT_RECORDING_REGISTER; 534 535 typedef union 536 { 537 struct 538 { 539 UINT32 540 reserved:9, 541 fault_log_size:3, 542 fault_log_address_low:20; 543 UINT32 fault_log_address_high; 544 } bits; 545 UINT64 uint64; 546 } VTD_ADVANCED_FAULT_LOG_REGISTER; 547 548 typedef union 549 { 550 struct 551 { 552 UINT32 protected_region_status:1; 553 UINT32 reserved_p:30; 554 UINT32 enable_protected_memory:1; 555 } bits; 556 UINT32 uint32; 557 } VTD_PROTECTED_MEMORY_ENABLE_REGISTER; 558 559 typedef union 560 { 561 struct 562 { 563 UINT32 564 reserved0:4, 565 queue_head:15, // 128-bit aligned 566 reserved1:13; 567 UINT32 reserved2; 568 } bits; 569 UINT64 uint64; 570 } VTD_INVALIDATION_QUEUE_HEAD_REGISTER; 571 572 typedef union 573 { 574 struct 575 { 576 UINT32 577 reserved0:4, 578 queue_tail:15, // 128-bit aligned 579 reserved1:13; 580 UINT32 reserved2; 581 } bits; 582 UINT64 uint64; 583 } VTD_INVALIDATION_QUEUE_TAIL_REGISTER; 584 585 typedef union 586 { 587 struct 588 { 589 UINT32 590 queue_size:3, 591 reserved:9, 592 queue_base_low:20; 593 UINT32 queue_base_high; 594 } bits; 595 UINT64 uint64; 596 } VTD_INVALIDATION_QUEUE_ADDRESS_REGISTER; 597 598 typedef union 599 { 600 struct 601 { 602 UINT32 wait_descriptor_complete:1; 603 UINT32 reserved:31; 604 } bits; 605 UINT32 uint32; 606 } VTD_INVALIDATION_COMPLETION_STATUS_REGISTER; 607 608 typedef union 609 { 610 struct 611 { 612 UINT32 reserved:30; 613 UINT32 interrupt_pending:1; 614 UINT32 interrupt_mask:1; 615 } bits; 616 UINT32 uint32; 617 } VTD_INVALIDATION_EVENT_CONTROL_REGISTER; 618 619 typedef union 620 { 621 struct 622 { 623 UINT32 interrupt_message_data:16; 624 UINT32 extended_interrupt_message_data:16; 625 } bits; 626 UINT32 uint32; 627 } VTD_INVALIDATION_EVENT_DATA_REGISTER; 628 629 typedef union 630 { 631 struct 632 { 633 UINT32 reserved:2; 634 UINT32 message_address:30; 635 } bits; 636 UINT32 uint32; 637 } VTD_INVALIDATION_EVENT_ADDRESS_REGISTER; 638 639 typedef struct 640 { 641 UINT32 message_upper_address; 642 } VTD_INVALIDATION_EVENT_UPPER_ADDRESS_REGISTER; 643 644 typedef union 645 { 646 struct 647 { 648 UINT32 649 size:4, 650 reserved:7, 651 extended_interrupt_mode_enable:1, 652 address_low:20; 653 UINT32 address_high; 654 } bits; 655 UINT64 uint64; 656 } VTD_INTERRUPT_REMAPPING_TABLE_ADDRESS_REGISTER; 657 658 #pragma warning(pop) 659 660 typedef enum 661 { 662 VTD_POWER_ACTIVE, 663 VTD_POWER_SUSPEND, 664 VTD_POWER_RESUME 665 } VTD_POWER_STATE; 666 667 typedef struct _VTD_DMA_REMAPPING_HW_UNIT 668 { 669 UINT32 id; 670 VTD_DOMAIN_ID avail_domain_id; 671 LIST_ELEMENT domain_list; 672 UINT64 register_base; 673 UINT32 num_devices; 674 VMM_LOCK hw_lock; 675 VTD_POWER_STATE power_state; 676 VTD_CAPABILITY_REGISTER capability; 677 VTD_EXTENDED_CAPABILITY_REGISTER extended_capability; 678 DMAR_DEVICE *devices; 679 DMA_REMAPPING_ROOT_ENTRY *root_entry_table; 680 } VTD_DMA_REMAPPING_HW_UNIT; 681 682 BOOLEAN vtd_hw_set_root_entry_table(VTD_DMA_REMAPPING_HW_UNIT *dmar, DMA_REMAPPING_ROOT_ENTRY *root_entry_table); 683 684 BOOLEAN vtd_hw_enable_translation(VTD_DMA_REMAPPING_HW_UNIT *dmar); 685 void vtd_hw_disable_translation(VTD_DMA_REMAPPING_HW_UNIT *dmar); 686 687 BOOLEAN vtd_hw_enable_interrupt_remapping(VTD_DMA_REMAPPING_HW_UNIT *dmar); 688 void vtd_hw_disable_interrupt_remapping(VTD_DMA_REMAPPING_HW_UNIT *dmar); 689 690 void vtd_hw_inv_context_cache_global(VTD_DMA_REMAPPING_HW_UNIT *dmar); 691 void vtd_hw_flush_write_buffers(VTD_DMA_REMAPPING_HW_UNIT *dmar); 692 void vtd_hw_inv_iotlb_global(VTD_DMA_REMAPPING_HW_UNIT *dmar); 693 void vtd_hw_inv_iotlb_page(VTD_DMA_REMAPPING_HW_UNIT *dmar, 694 ADDRESS addr, 695 size_t size, 696 VTD_DOMAIN_ID domain_id); 697 698 UINT32 vtd_hw_get_protected_low_memory_base_alignment(VTD_DMA_REMAPPING_HW_UNIT *dmar); 699 UINT32 vtd_hw_get_protected_low_memory_limit_alignment(VTD_DMA_REMAPPING_HW_UNIT *dmar); 700 UINT64 vtd_hw_get_protected_high_memory_base_alignment(VTD_DMA_REMAPPING_HW_UNIT *dmar); 701 UINT64 vtd_hw_get_protected_high_memory_limit_alignment(VTD_DMA_REMAPPING_HW_UNIT *dmar); 702 BOOLEAN vtd_hw_setup_protected_low_memory(VTD_DMA_REMAPPING_HW_UNIT *dmar, UINT32 base, UINT32 limit); 703 BOOLEAN vtd_hw_setup_protected_high_memory(VTD_DMA_REMAPPING_HW_UNIT *dmar, UINT64 base, UINT64 limit); 704 BOOLEAN vtd_hw_enable_protected_memory(VTD_DMA_REMAPPING_HW_UNIT *dmar); 705 void vtd_hw_disable_protected_memory(VTD_DMA_REMAPPING_HW_UNIT *dmar); 706 BOOLEAN vtd_hw_is_protected_memory_enabled(VTD_DMA_REMAPPING_HW_UNIT *dmar); 707 708 // hw read/write 709 UINT32 vtd_hw_read_reg32(VTD_DMA_REMAPPING_HW_UNIT *dmar, UINT64 reg); 710 void vtd_hw_write_reg32(VTD_DMA_REMAPPING_HW_UNIT *dmar, UINT64 reg, UINT32 value); 711 712 UINT64 vtd_hw_read_reg64(VTD_DMA_REMAPPING_HW_UNIT *dmar, UINT64 reg); 713 void vtd_hw_write_reg64(VTD_DMA_REMAPPING_HW_UNIT *dmar, UINT64 reg, UINT64 value); 714 715 // capabilities 716 INLINE 717 UINT32 vtd_hw_get_super_page_support(VTD_DMA_REMAPPING_HW_UNIT *dmar) 718 { 719 return (UINT32) dmar->capability.bits.super_page_support; 720 } 721 722 INLINE 723 UINT32 vtd_hw_get_supported_ajusted_guest_address_width(VTD_DMA_REMAPPING_HW_UNIT *dmar) 724 { 725 return (UINT32) dmar->capability.bits.adjusted_guest_address_width; 726 } 727 728 INLINE 729 UINT32 vtd_hw_get_max_guest_address_width(VTD_DMA_REMAPPING_HW_UNIT *dmar) 730 { 731 return (UINT32) dmar->capability.bits.max_guest_address_width; 732 } 733 734 INLINE 735 UINT32 vtd_hw_get_number_of_domains(VTD_DMA_REMAPPING_HW_UNIT *dmar) 736 { 737 return (UINT32) dmar->capability.bits.number_of_domains; 738 } 739 740 INLINE 741 UINT32 vtd_hw_get_caching_mode(VTD_DMA_REMAPPING_HW_UNIT *dmar) 742 { 743 return (UINT32) dmar->capability.bits.caching_mode; 744 } 745 746 INLINE 747 UINT32 vtd_hw_get_required_write_buffer_flush(VTD_DMA_REMAPPING_HW_UNIT *dmar) 748 { 749 return (UINT32) dmar->capability.bits.required_write_buffer_flush; 750 } 751 752 INLINE 753 UINT32 vtd_hw_get_coherency(VTD_DMA_REMAPPING_HW_UNIT *dmar) 754 { 755 return (UINT32) dmar->extended_capability.bits.coherency; 756 } 757 758 INLINE 759 UINT32 vtd_hw_get_protected_low_memory_support(VTD_DMA_REMAPPING_HW_UNIT *dmar) 760 { 761 return (UINT32) dmar->capability.bits.protected_low_memory_region; 762 } 763 764 INLINE 765 UINT32 vtd_hw_get_protected_high_memory_support(VTD_DMA_REMAPPING_HW_UNIT *dmar) 766 { 767 return (UINT32) dmar->capability.bits.protected_high_memory_region; 768 } 769 770 // fault handling 771 INLINE 772 UINT32 vtd_hw_get_number_of_fault_recording_regs(VTD_DMA_REMAPPING_HW_UNIT *dmar) 773 { 774 return (UINT32) dmar->capability.bits.number_of_fault_recording_registers; 775 } 776 777 INLINE 778 UINT64 vtd_hw_get_fault_recording_reg_offset(VTD_DMA_REMAPPING_HW_UNIT *dmar, UINT32 fault_record_index) 779 { 780 UINT32 fault_recording_register_offset = 781 dmar->capability.bits.fault_recording_register_offset_high << 8 | 782 dmar->capability.bits.fault_recording_register_offset_low; 783 return (16 * fault_recording_register_offset) 784 + (sizeof(VTD_FAULT_RECORDING_REGISTER) * fault_record_index); 785 } 786 787 void vtd_hw_mask_fault_interrupt(VTD_DMA_REMAPPING_HW_UNIT *dmar); 788 void vtd_hw_unmask_fault_interrupt(VTD_DMA_REMAPPING_HW_UNIT *dmar); 789 790 UINT32 vtd_hw_get_fault_overflow(VTD_DMA_REMAPPING_HW_UNIT *dmar); 791 UINT32 vtd_hw_get_primary_fault_pending(VTD_DMA_REMAPPING_HW_UNIT *dmar); 792 UINT32 vtd_hw_get_fault_record_index(VTD_DMA_REMAPPING_HW_UNIT *dmar); 793 794 void vtd_hw_set_fault_event_data(VTD_DMA_REMAPPING_HW_UNIT *dmar, 795 UINT8 vector, 796 UINT8 delivery_mode, 797 UINT32 trigger_mode_level, 798 UINT32 trigger_mode); 799 800 void vtd_hw_set_fault_event_addr(VTD_DMA_REMAPPING_HW_UNIT *dmar, UINT8 dest_mode, UINT8 dest_id); 801 void vtd_hw_clear_fault_overflow(VTD_DMA_REMAPPING_HW_UNIT *dmar); 802 UINT64 vtd_hw_read_fault_register(VTD_DMA_REMAPPING_HW_UNIT *dmar, UINT32 fault_record_index); 803 UINT64 vtd_hw_read_fault_register_high(VTD_DMA_REMAPPING_HW_UNIT *dmar, UINT32 fault_record_index); 804 void vtd_hw_clear_fault_register(VTD_DMA_REMAPPING_HW_UNIT *dmar, UINT32 fault_record_index); 805 806 void vtd_hw_print_capabilities(VTD_DMA_REMAPPING_HW_UNIT *dmar); 807 void vtd_print_hw_status(VTD_DMA_REMAPPING_HW_UNIT *dmar); 808 809 #endif