aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/amd_iommu_init.c
diff options
context:
space:
mode:
authorJoerg Roedel <joerg.roedel@amd.com>2008-06-26 15:27:50 -0400
committerIngo Molnar <mingo@elte.hu>2008-06-27 04:12:13 -0400
commitfe74c9cf3985e307e9734296d08a270d510e3fb7 (patch)
tree1df43923863cc542ff6770bd8769e76cb011fa68 /arch/x86/kernel/amd_iommu_init.c
parentbe2a022c0dd0f630b06f83de284df53cb60a308f (diff)
x86, AMD IOMMU: clue initialization code together
This patch puts the AMD IOMMU ACPI table parsing and hardware initialization functions together to the main intialization routine. Signed-off-by: Joerg Roedel <joerg.roedel@amd.com> Cc: iommu@lists.linux-foundation.org Cc: bhavna.sarathy@amd.com Cc: Sebastian.Biemueller@amd.com Cc: robert.richter@amd.com Cc: joro@8bytes.org Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/amd_iommu_init.c')
-rw-r--r--arch/x86/kernel/amd_iommu_init.c126
1 files changed, 126 insertions, 0 deletions
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c
index 555fcc9830c..c792ddc4fec 100644
--- a/arch/x86/kernel/amd_iommu_init.c
+++ b/arch/x86/kernel/amd_iommu_init.c
@@ -643,3 +643,129 @@ static int __init init_memory_definitions(struct acpi_table_header *table)
643 return 0; 643 return 0;
644} 644}
645 645
646int __init amd_iommu_init(void)
647{
648 int i, ret = 0;
649
650
651 if (amd_iommu_disable) {
652 printk(KERN_INFO "AMD IOMMU disabled by kernel command line\n");
653 return 0;
654 }
655
656 /*
657 * First parse ACPI tables to find the largest Bus/Dev/Func
658 * we need to handle. Upon this information the shared data
659 * structures for the IOMMUs in the system will be allocated
660 */
661 if (acpi_table_parse("IVRS", find_last_devid_acpi) != 0)
662 return -ENODEV;
663
664 dev_table_size = TBL_SIZE(DEV_TABLE_ENTRY_SIZE);
665 alias_table_size = TBL_SIZE(ALIAS_TABLE_ENTRY_SIZE);
666 rlookup_table_size = TBL_SIZE(RLOOKUP_TABLE_ENTRY_SIZE);
667
668 ret = -ENOMEM;
669
670 /* Device table - directly used by all IOMMUs */
671 amd_iommu_dev_table = (void *)__get_free_pages(GFP_KERNEL,
672 get_order(dev_table_size));
673 if (amd_iommu_dev_table == NULL)
674 goto out;
675
676 /*
677 * Alias table - map PCI Bus/Dev/Func to Bus/Dev/Func the
678 * IOMMU see for that device
679 */
680 amd_iommu_alias_table = (void *)__get_free_pages(GFP_KERNEL,
681 get_order(alias_table_size));
682 if (amd_iommu_alias_table == NULL)
683 goto free;
684
685 /* IOMMU rlookup table - find the IOMMU for a specific device */
686 amd_iommu_rlookup_table = (void *)__get_free_pages(GFP_KERNEL,
687 get_order(rlookup_table_size));
688 if (amd_iommu_rlookup_table == NULL)
689 goto free;
690
691 /*
692 * Protection Domain table - maps devices to protection domains
693 * This table has the same size as the rlookup_table
694 */
695 amd_iommu_pd_table = (void *)__get_free_pages(GFP_KERNEL,
696 get_order(rlookup_table_size));
697 if (amd_iommu_pd_table == NULL)
698 goto free;
699
700 amd_iommu_pd_alloc_bitmap = (void *)__get_free_pages(GFP_KERNEL,
701 get_order(MAX_DOMAIN_ID/8));
702 if (amd_iommu_pd_alloc_bitmap == NULL)
703 goto free;
704
705 /*
706 * memory is allocated now; initialize the device table with all zeroes
707 * and let all alias entries point to itself
708 */
709 memset(amd_iommu_dev_table, 0, dev_table_size);
710 for (i = 0; i < amd_iommu_last_bdf; ++i)
711 amd_iommu_alias_table[i] = i;
712
713 memset(amd_iommu_pd_table, 0, rlookup_table_size);
714 memset(amd_iommu_pd_alloc_bitmap, 0, MAX_DOMAIN_ID / 8);
715
716 /*
717 * never allocate domain 0 because its used as the non-allocated and
718 * error value placeholder
719 */
720 amd_iommu_pd_alloc_bitmap[0] = 1;
721
722 /*
723 * now the data structures are allocated and basically initialized
724 * start the real acpi table scan
725 */
726 ret = -ENODEV;
727 if (acpi_table_parse("IVRS", init_iommu_all) != 0)
728 goto free;
729
730 if (acpi_table_parse("IVRS", init_memory_definitions) != 0)
731 goto free;
732
733 printk(KERN_INFO "AMD IOMMU: aperture size is %d MB\n",
734 (1 << (amd_iommu_aperture_order-20)));
735
736 printk(KERN_INFO "AMD IOMMU: device isolation ");
737 if (amd_iommu_isolate)
738 printk("enabled\n");
739 else
740 printk("disabled\n");
741
742out:
743 return ret;
744
745free:
746 if (amd_iommu_pd_alloc_bitmap)
747 free_pages((unsigned long)amd_iommu_pd_alloc_bitmap, 1);
748
749 if (amd_iommu_pd_table)
750 free_pages((unsigned long)amd_iommu_pd_table,
751 get_order(rlookup_table_size));
752
753 if (amd_iommu_rlookup_table)
754 free_pages((unsigned long)amd_iommu_rlookup_table,
755 get_order(rlookup_table_size));
756
757 if (amd_iommu_alias_table)
758 free_pages((unsigned long)amd_iommu_alias_table,
759 get_order(alias_table_size));
760
761 if (amd_iommu_dev_table)
762 free_pages((unsigned long)amd_iommu_dev_table,
763 get_order(dev_table_size));
764
765 free_iommu_all();
766
767 free_unity_maps();
768
769 goto out;
770}
771