diff options
author | Joerg Roedel <joerg.roedel@amd.com> | 2008-06-26 15:27:50 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-06-27 04:12:13 -0400 |
commit | fe74c9cf3985e307e9734296d08a270d510e3fb7 (patch) | |
tree | 1df43923863cc542ff6770bd8769e76cb011fa68 /arch/x86/kernel/amd_iommu_init.c | |
parent | be2a022c0dd0f630b06f83de284df53cb60a308f (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.c | 126 |
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 555fcc9830c8..c792ddc4fec6 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 | ||
646 | int __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 | |||
742 | out: | ||
743 | return ret; | ||
744 | |||
745 | free: | ||
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 | |||