diff options
author | Steven J. Hill <Steven.Hill@imgtec.com> | 2013-03-25 12:58:57 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2013-05-08 06:30:10 -0400 |
commit | d532f3d26716a39dfd4b88d687bd344fbe77e390 (patch) | |
tree | 64bb16ffd8176e0c9e692817b1d17df717c127ed /arch/mips/kernel | |
parent | 49bffbdc88fdd8f5eac40306a617252625a0fa35 (diff) |
MIPS: Allow ASID size to be determined at boot time.
Original patch by Ralf Baechle and removed by Harold Koerfgen
with commit f67e4ffc79905482c3b9b8c8dd65197bac7eb508. This
allows for more generic kernels since the size of the ASID
and corresponding masks can be determined at run-time. This
patch is also required for the new Aptiv cores and has been
tested on Malta and Malta Aptiv platforms.
[ralf@linux-mips.org: Added relevant part of fix
https://patchwork.linux-mips.org/patch/5213/]
Signed-off-by: Steven J. Hill <Steven.Hill@imgtec.com>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/kernel')
-rw-r--r-- | arch/mips/kernel/genex.S | 2 | ||||
-rw-r--r-- | arch/mips/kernel/smtc.c | 10 | ||||
-rw-r--r-- | arch/mips/kernel/traps.c | 6 |
3 files changed, 10 insertions, 8 deletions
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S index ecb347ce1b3d..5360b1db337d 100644 --- a/arch/mips/kernel/genex.S +++ b/arch/mips/kernel/genex.S | |||
@@ -480,7 +480,7 @@ NESTED(nmi_handler, PT_SIZE, sp) | |||
480 | .set noreorder | 480 | .set noreorder |
481 | /* check if TLB contains a entry for EPC */ | 481 | /* check if TLB contains a entry for EPC */ |
482 | MFC0 k1, CP0_ENTRYHI | 482 | MFC0 k1, CP0_ENTRYHI |
483 | andi k1, 0xff /* ASID_MASK */ | 483 | andi k1, 0xff /* ASID_MASK patched at run-time!! */ |
484 | MFC0 k0, CP0_EPC | 484 | MFC0 k0, CP0_EPC |
485 | PTR_SRL k0, _PAGE_SHIFT + 1 | 485 | PTR_SRL k0, _PAGE_SHIFT + 1 |
486 | PTR_SLL k0, _PAGE_SHIFT + 1 | 486 | PTR_SLL k0, _PAGE_SHIFT + 1 |
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index 7186222dc5bb..31d22f3121c9 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c | |||
@@ -111,7 +111,7 @@ static int vpe0limit; | |||
111 | static int ipibuffers; | 111 | static int ipibuffers; |
112 | static int nostlb; | 112 | static int nostlb; |
113 | static int asidmask; | 113 | static int asidmask; |
114 | unsigned long smtc_asid_mask = 0xff; | 114 | unsigned int smtc_asid_mask = 0xff; |
115 | 115 | ||
116 | static int __init vpe0tcs(char *str) | 116 | static int __init vpe0tcs(char *str) |
117 | { | 117 | { |
@@ -1395,7 +1395,7 @@ void smtc_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu) | |||
1395 | asid = asid_cache(cpu); | 1395 | asid = asid_cache(cpu); |
1396 | 1396 | ||
1397 | do { | 1397 | do { |
1398 | if (!((asid += ASID_INC) & ASID_MASK) ) { | 1398 | if (!ASID_MASK(ASID_INC(asid))) { |
1399 | if (cpu_has_vtag_icache) | 1399 | if (cpu_has_vtag_icache) |
1400 | flush_icache_all(); | 1400 | flush_icache_all(); |
1401 | /* Traverse all online CPUs (hack requires contiguous range) */ | 1401 | /* Traverse all online CPUs (hack requires contiguous range) */ |
@@ -1414,7 +1414,7 @@ void smtc_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu) | |||
1414 | mips_ihb(); | 1414 | mips_ihb(); |
1415 | } | 1415 | } |
1416 | tcstat = read_tc_c0_tcstatus(); | 1416 | tcstat = read_tc_c0_tcstatus(); |
1417 | smtc_live_asid[tlb][(tcstat & ASID_MASK)] |= (asiduse)(0x1 << i); | 1417 | smtc_live_asid[tlb][ASID_MASK(tcstat)] |= (asiduse)(0x1 << i); |
1418 | if (!prevhalt) | 1418 | if (!prevhalt) |
1419 | write_tc_c0_tchalt(0); | 1419 | write_tc_c0_tchalt(0); |
1420 | } | 1420 | } |
@@ -1423,7 +1423,7 @@ void smtc_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu) | |||
1423 | asid = ASID_FIRST_VERSION; | 1423 | asid = ASID_FIRST_VERSION; |
1424 | local_flush_tlb_all(); /* start new asid cycle */ | 1424 | local_flush_tlb_all(); /* start new asid cycle */ |
1425 | } | 1425 | } |
1426 | } while (smtc_live_asid[tlb][(asid & ASID_MASK)]); | 1426 | } while (smtc_live_asid[tlb][ASID_MASK(asid)]); |
1427 | 1427 | ||
1428 | /* | 1428 | /* |
1429 | * SMTC shares the TLB within VPEs and possibly across all VPEs. | 1429 | * SMTC shares the TLB within VPEs and possibly across all VPEs. |
@@ -1461,7 +1461,7 @@ void smtc_flush_tlb_asid(unsigned long asid) | |||
1461 | tlb_read(); | 1461 | tlb_read(); |
1462 | ehb(); | 1462 | ehb(); |
1463 | ehi = read_c0_entryhi(); | 1463 | ehi = read_c0_entryhi(); |
1464 | if ((ehi & ASID_MASK) == asid) { | 1464 | if (ASID_MASK(ehi) == asid) { |
1465 | /* | 1465 | /* |
1466 | * Invalidate only entries with specified ASID, | 1466 | * Invalidate only entries with specified ASID, |
1467 | * makiing sure all entries differ. | 1467 | * makiing sure all entries differ. |
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index c3abb88170fc..4b6b607b0179 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
@@ -1547,6 +1547,7 @@ void __cpuinit per_cpu_trap_init(bool is_boot_cpu) | |||
1547 | unsigned int cpu = smp_processor_id(); | 1547 | unsigned int cpu = smp_processor_id(); |
1548 | unsigned int status_set = ST0_CU0; | 1548 | unsigned int status_set = ST0_CU0; |
1549 | unsigned int hwrena = cpu_hwrena_impl_bits; | 1549 | unsigned int hwrena = cpu_hwrena_impl_bits; |
1550 | unsigned long asid = 0; | ||
1550 | #ifdef CONFIG_MIPS_MT_SMTC | 1551 | #ifdef CONFIG_MIPS_MT_SMTC |
1551 | int secondaryTC = 0; | 1552 | int secondaryTC = 0; |
1552 | int bootTC = (cpu == 0); | 1553 | int bootTC = (cpu == 0); |
@@ -1630,8 +1631,9 @@ void __cpuinit per_cpu_trap_init(bool is_boot_cpu) | |||
1630 | } | 1631 | } |
1631 | #endif /* CONFIG_MIPS_MT_SMTC */ | 1632 | #endif /* CONFIG_MIPS_MT_SMTC */ |
1632 | 1633 | ||
1633 | if (!cpu_data[cpu].asid_cache) | 1634 | asid = ASID_FIRST_VERSION; |
1634 | cpu_data[cpu].asid_cache = ASID_FIRST_VERSION; | 1635 | cpu_data[cpu].asid_cache = asid; |
1636 | TLBMISS_HANDLER_SETUP(); | ||
1635 | 1637 | ||
1636 | atomic_inc(&init_mm.mm_count); | 1638 | atomic_inc(&init_mm.mm_count); |
1637 | current->active_mm = &init_mm; | 1639 | current->active_mm = &init_mm; |