diff options
Diffstat (limited to 'arch/powerpc/kernel/iommu.c')
-rw-r--r-- | arch/powerpc/kernel/iommu.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index 7cb77c20fc5d..3d677ac99659 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <asm/iommu.h> | 38 | #include <asm/iommu.h> |
39 | #include <asm/pci-bridge.h> | 39 | #include <asm/pci-bridge.h> |
40 | #include <asm/machdep.h> | 40 | #include <asm/machdep.h> |
41 | #include <asm/kdump.h> | ||
41 | 42 | ||
42 | #define DBG(...) | 43 | #define DBG(...) |
43 | 44 | ||
@@ -440,8 +441,37 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid) | |||
440 | tbl->it_largehint = tbl->it_halfpoint; | 441 | tbl->it_largehint = tbl->it_halfpoint; |
441 | spin_lock_init(&tbl->it_lock); | 442 | spin_lock_init(&tbl->it_lock); |
442 | 443 | ||
444 | #ifdef CONFIG_CRASH_DUMP | ||
445 | if (ppc_md.tce_get) { | ||
446 | unsigned long index, tceval; | ||
447 | unsigned long tcecount = 0; | ||
448 | |||
449 | /* | ||
450 | * Reserve the existing mappings left by the first kernel. | ||
451 | */ | ||
452 | for (index = 0; index < tbl->it_size; index++) { | ||
453 | tceval = ppc_md.tce_get(tbl, index + tbl->it_offset); | ||
454 | /* | ||
455 | * Freed TCE entry contains 0x7fffffffffffffff on JS20 | ||
456 | */ | ||
457 | if (tceval && (tceval != 0x7fffffffffffffffUL)) { | ||
458 | __set_bit(index, tbl->it_map); | ||
459 | tcecount++; | ||
460 | } | ||
461 | } | ||
462 | if ((tbl->it_size - tcecount) < KDUMP_MIN_TCE_ENTRIES) { | ||
463 | printk(KERN_WARNING "TCE table is full; "); | ||
464 | printk(KERN_WARNING "freeing %d entries for the kdump boot\n", | ||
465 | KDUMP_MIN_TCE_ENTRIES); | ||
466 | for (index = tbl->it_size - KDUMP_MIN_TCE_ENTRIES; | ||
467 | index < tbl->it_size; index++) | ||
468 | __clear_bit(index, tbl->it_map); | ||
469 | } | ||
470 | } | ||
471 | #else | ||
443 | /* Clear the hardware table in case firmware left allocations in it */ | 472 | /* Clear the hardware table in case firmware left allocations in it */ |
444 | ppc_md.tce_free(tbl, tbl->it_offset, tbl->it_size); | 473 | ppc_md.tce_free(tbl, tbl->it_offset, tbl->it_size); |
474 | #endif | ||
445 | 475 | ||
446 | if (!welcomed) { | 476 | if (!welcomed) { |
447 | printk(KERN_INFO "IOMMU table initialized, virtual merging %s\n", | 477 | printk(KERN_INFO "IOMMU table initialized, virtual merging %s\n", |