2005-09-22 05:50:51 +04:00
|
|
|
/* arch/sparc64/kernel/ktlb.S: Kernel mapping TLB miss handling.
|
|
|
|
*
|
2008-01-11 08:10:54 +03:00
|
|
|
* Copyright (C) 1995, 1997, 2005, 2008 David S. Miller <davem@davemloft.net>
|
2005-09-22 05:50:51 +04:00
|
|
|
* Copyright (C) 1996 Eddie C. Dost (ecd@brainaid.de)
|
|
|
|
* Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
|
|
|
|
* Copyright (C) 1996,98,99 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
|
2006-02-01 05:29:18 +03:00
|
|
|
*/
|
2005-09-22 05:50:51 +04:00
|
|
|
|
|
|
|
#include <asm/head.h>
|
|
|
|
#include <asm/asi.h>
|
|
|
|
#include <asm/page.h>
|
|
|
|
#include <asm/pgtable.h>
|
2006-02-01 05:29:18 +03:00
|
|
|
#include <asm/tsb.h>
|
2005-09-22 05:50:51 +04:00
|
|
|
|
|
|
|
.text
|
|
|
|
.align 32
|
|
|
|
|
2006-02-01 05:29:18 +03:00
|
|
|
kvmap_itlb:
|
|
|
|
/* g6: TAG TARGET */
|
|
|
|
mov TLB_TAG_ACCESS, %g4
|
|
|
|
ldxa [%g4] ASI_IMMU, %g4
|
|
|
|
|
2006-02-07 10:44:37 +03:00
|
|
|
/* sun4v_itlb_miss branches here with the missing virtual
|
|
|
|
* address already loaded into %g4
|
|
|
|
*/
|
|
|
|
kvmap_itlb_4v:
|
|
|
|
|
2006-02-01 05:29:18 +03:00
|
|
|
kvmap_itlb_nonlinear:
|
|
|
|
/* Catch kernel NULL pointer calls. */
|
|
|
|
sethi %hi(PAGE_SIZE), %g5
|
|
|
|
cmp %g4, %g5
|
|
|
|
bleu,pn %xcc, kvmap_dtlb_longpath
|
|
|
|
nop
|
|
|
|
|
|
|
|
KERN_TSB_LOOKUP_TL1(%g4, %g6, %g5, %g1, %g2, %g3, kvmap_itlb_load)
|
|
|
|
|
|
|
|
kvmap_itlb_tsb_miss:
|
2005-09-22 05:50:51 +04:00
|
|
|
sethi %hi(LOW_OBP_ADDRESS), %g5
|
|
|
|
cmp %g4, %g5
|
2006-02-01 05:29:18 +03:00
|
|
|
blu,pn %xcc, kvmap_itlb_vmalloc_addr
|
2005-09-22 05:50:51 +04:00
|
|
|
mov 0x1, %g5
|
|
|
|
sllx %g5, 32, %g5
|
|
|
|
cmp %g4, %g5
|
2006-02-01 05:29:18 +03:00
|
|
|
blu,pn %xcc, kvmap_itlb_obp
|
2005-09-22 05:50:51 +04:00
|
|
|
nop
|
|
|
|
|
2006-02-01 05:29:18 +03:00
|
|
|
kvmap_itlb_vmalloc_addr:
|
|
|
|
KERN_PGTABLE_WALK(%g4, %g5, %g2, kvmap_itlb_longpath)
|
|
|
|
|
2011-08-05 11:53:57 +04:00
|
|
|
TSB_LOCK_TAG(%g1, %g2, %g7)
|
2006-02-01 05:29:18 +03:00
|
|
|
|
|
|
|
/* Load and check PTE. */
|
|
|
|
ldxa [%g5] ASI_PHYS_USE_EC, %g5
|
2006-02-18 05:01:02 +03:00
|
|
|
mov 1, %g7
|
|
|
|
sllx %g7, TSB_TAG_INVALID_BIT, %g7
|
2006-02-01 05:29:18 +03:00
|
|
|
brgez,a,pn %g5, kvmap_itlb_longpath
|
2011-08-05 11:53:57 +04:00
|
|
|
TSB_STORE(%g1, %g7)
|
2005-09-22 05:50:51 +04:00
|
|
|
|
2011-08-05 11:53:57 +04:00
|
|
|
TSB_WRITE(%g1, %g5, %g6)
|
2006-02-01 05:29:18 +03:00
|
|
|
|
|
|
|
/* fallthrough to TLB load */
|
|
|
|
|
|
|
|
kvmap_itlb_load:
|
2006-02-11 23:21:20 +03:00
|
|
|
|
|
|
|
661: stxa %g5, [%g0] ASI_ITLB_DATA_IN
|
2005-09-22 05:50:51 +04:00
|
|
|
retry
|
2006-02-11 23:21:20 +03:00
|
|
|
.section .sun4v_2insn_patch, "ax"
|
|
|
|
.word 661b
|
|
|
|
nop
|
|
|
|
nop
|
|
|
|
.previous
|
|
|
|
|
|
|
|
/* For sun4v the ASI_ITLB_DATA_IN store and the retry
|
|
|
|
* instruction get nop'd out and we get here to branch
|
|
|
|
* to the sun4v tlb load code. The registers are setup
|
|
|
|
* as follows:
|
|
|
|
*
|
|
|
|
* %g4: vaddr
|
|
|
|
* %g5: PTE
|
|
|
|
* %g6: TAG
|
|
|
|
*
|
|
|
|
* The sun4v TLB load wants the PTE in %g3 so we fix that
|
|
|
|
* up here.
|
|
|
|
*/
|
|
|
|
ba,pt %xcc, sun4v_itlb_load
|
|
|
|
mov %g5, %g3
|
2005-09-22 05:50:51 +04:00
|
|
|
|
2006-02-01 05:29:18 +03:00
|
|
|
kvmap_itlb_longpath:
|
2006-02-06 09:27:28 +03:00
|
|
|
|
|
|
|
661: rdpr %pstate, %g5
|
2006-02-01 05:29:18 +03:00
|
|
|
wrpr %g5, PSTATE_AG | PSTATE_MG, %pstate
|
2006-02-07 11:00:16 +03:00
|
|
|
.section .sun4v_2insn_patch, "ax"
|
2006-02-06 09:27:28 +03:00
|
|
|
.word 661b
|
2006-02-19 03:36:39 +03:00
|
|
|
SET_GL(1)
|
2006-02-06 09:27:28 +03:00
|
|
|
nop
|
|
|
|
.previous
|
|
|
|
|
2006-02-01 05:29:18 +03:00
|
|
|
rdpr %tpc, %g5
|
|
|
|
ba,pt %xcc, sparc64_realfault_common
|
|
|
|
mov FAULT_CODE_ITLB, %g4
|
|
|
|
|
|
|
|
kvmap_itlb_obp:
|
|
|
|
OBP_TRANS_LOOKUP(%g4, %g5, %g2, %g3, kvmap_itlb_longpath)
|
|
|
|
|
2011-08-05 11:53:57 +04:00
|
|
|
TSB_LOCK_TAG(%g1, %g2, %g7)
|
2006-02-01 05:29:18 +03:00
|
|
|
|
2011-08-05 11:53:57 +04:00
|
|
|
TSB_WRITE(%g1, %g5, %g6)
|
2006-02-01 05:29:18 +03:00
|
|
|
|
|
|
|
ba,pt %xcc, kvmap_itlb_load
|
|
|
|
nop
|
|
|
|
|
|
|
|
kvmap_dtlb_obp:
|
|
|
|
OBP_TRANS_LOOKUP(%g4, %g5, %g2, %g3, kvmap_dtlb_longpath)
|
|
|
|
|
2011-08-05 11:53:57 +04:00
|
|
|
TSB_LOCK_TAG(%g1, %g2, %g7)
|
2006-02-01 05:29:18 +03:00
|
|
|
|
2011-08-05 11:53:57 +04:00
|
|
|
TSB_WRITE(%g1, %g5, %g6)
|
2006-02-01 05:29:18 +03:00
|
|
|
|
|
|
|
ba,pt %xcc, kvmap_dtlb_load
|
|
|
|
nop
|
2005-10-12 23:22:46 +04:00
|
|
|
|
2005-09-22 05:50:51 +04:00
|
|
|
.align 32
|
2006-02-22 09:31:11 +03:00
|
|
|
kvmap_dtlb_tsb4m_load:
|
2011-08-05 11:53:57 +04:00
|
|
|
TSB_LOCK_TAG(%g1, %g2, %g7)
|
|
|
|
TSB_WRITE(%g1, %g5, %g6)
|
2006-02-22 09:31:11 +03:00
|
|
|
ba,pt %xcc, kvmap_dtlb_load
|
|
|
|
nop
|
|
|
|
|
2006-02-01 05:29:18 +03:00
|
|
|
kvmap_dtlb:
|
|
|
|
/* %g6: TAG TARGET */
|
|
|
|
mov TLB_TAG_ACCESS, %g4
|
|
|
|
ldxa [%g4] ASI_DMMU, %g4
|
2006-02-07 10:44:37 +03:00
|
|
|
|
|
|
|
/* sun4v_dtlb_miss branches here with the missing virtual
|
|
|
|
* address already loaded into %g4
|
|
|
|
*/
|
|
|
|
kvmap_dtlb_4v:
|
2006-02-01 05:29:18 +03:00
|
|
|
brgez,pn %g4, kvmap_dtlb_nonlinear
|
2005-09-26 03:46:57 +04:00
|
|
|
nop
|
|
|
|
|
2007-03-17 03:20:28 +03:00
|
|
|
#ifdef CONFIG_DEBUG_PAGEALLOC
|
|
|
|
/* Index through the base page size TSB even for linear
|
|
|
|
* mappings when using page allocation debugging.
|
|
|
|
*/
|
|
|
|
KERN_TSB_LOOKUP_TL1(%g4, %g6, %g5, %g1, %g2, %g3, kvmap_dtlb_load)
|
|
|
|
#else
|
2006-02-22 09:31:11 +03:00
|
|
|
/* Correct TAG_TARGET is already in %g6, check 4mb TSB. */
|
|
|
|
KERN_TSB4M_LOOKUP_TL1(%g6, %g5, %g1, %g2, %g3, kvmap_dtlb_load)
|
2007-03-17 03:20:28 +03:00
|
|
|
#endif
|
2006-02-22 09:31:11 +03:00
|
|
|
/* TSB entry address left in %g1, lookup linear PTE.
|
|
|
|
* Must preserve %g1 and %g6 (TAG).
|
|
|
|
*/
|
|
|
|
kvmap_dtlb_tsb4m_miss:
|
sparc64: Validate linear D-TLB misses.
When page alloc debugging is not enabled, we essentially accept any
virtual address for linear kernel TLB misses. But with kgdb, kernel
address probing, and other facilities we can try to access arbitrary
crap.
So, make sure the address we miss on will translate to physical memory
that actually exists.
In order to make this work we have to embed the valid address bitmap
into the kernel image. And in order to make that less expensive we
make an adjustment, in that the max physical memory address is
decreased to "1 << 41", even on the chips that support a 42-bit
physical address space. We can do this because bit 41 indicates
"I/O space" and thus covers non-memory ranges.
The result of this is that:
1) kpte_linear_bitmap shrinks from 2K to 1K in size
2) we need 64K more for the valid address bitmap
We can't let the valid address bitmap be dynamically allocated
once we start using it to validate TLB misses, otherwise we have
crazy issues to deal with wrt. recursive TLB misses and such.
If we're in a TLB miss it could be the deepest trap level that's legal
inside of the cpu. So if we TLB miss referencing the bitmap, the cpu
will be out of trap levels and enter RED state.
To guard against out-of-range accesses to the bitmap, we have to check
to make sure no bits in the physical address above bit 40 are set. We
could export and use last_valid_pfn for this check, but that's just an
unnecessary extra memory reference.
On the plus side of all this, since we load all of these translations
into the special 4MB mapping TSB, and we check the TSB first for TLB
misses, there should be absolutely no real cost for these new checks
in the TLB miss path.
Reported-by: heyongli@gmail.com
Signed-off-by: David S. Miller <davem@davemloft.net>
2009-08-26 03:47:46 +04:00
|
|
|
/* Clear the PAGE_OFFSET top virtual bits, shift
|
|
|
|
* down to get PFN, and make sure PFN is in range.
|
|
|
|
*/
|
|
|
|
sllx %g4, 21, %g5
|
2006-02-22 07:51:13 +03:00
|
|
|
|
sparc64: Validate linear D-TLB misses.
When page alloc debugging is not enabled, we essentially accept any
virtual address for linear kernel TLB misses. But with kgdb, kernel
address probing, and other facilities we can try to access arbitrary
crap.
So, make sure the address we miss on will translate to physical memory
that actually exists.
In order to make this work we have to embed the valid address bitmap
into the kernel image. And in order to make that less expensive we
make an adjustment, in that the max physical memory address is
decreased to "1 << 41", even on the chips that support a 42-bit
physical address space. We can do this because bit 41 indicates
"I/O space" and thus covers non-memory ranges.
The result of this is that:
1) kpte_linear_bitmap shrinks from 2K to 1K in size
2) we need 64K more for the valid address bitmap
We can't let the valid address bitmap be dynamically allocated
once we start using it to validate TLB misses, otherwise we have
crazy issues to deal with wrt. recursive TLB misses and such.
If we're in a TLB miss it could be the deepest trap level that's legal
inside of the cpu. So if we TLB miss referencing the bitmap, the cpu
will be out of trap levels and enter RED state.
To guard against out-of-range accesses to the bitmap, we have to check
to make sure no bits in the physical address above bit 40 are set. We
could export and use last_valid_pfn for this check, but that's just an
unnecessary extra memory reference.
On the plus side of all this, since we load all of these translations
into the special 4MB mapping TSB, and we check the TSB first for TLB
misses, there should be absolutely no real cost for these new checks
in the TLB miss path.
Reported-by: heyongli@gmail.com
Signed-off-by: David S. Miller <davem@davemloft.net>
2009-08-26 03:47:46 +04:00
|
|
|
/* Check to see if we know about valid memory at the 4MB
|
|
|
|
* chunk this physical address will reside within.
|
2006-02-22 07:51:13 +03:00
|
|
|
*/
|
sparc64: Validate linear D-TLB misses.
When page alloc debugging is not enabled, we essentially accept any
virtual address for linear kernel TLB misses. But with kgdb, kernel
address probing, and other facilities we can try to access arbitrary
crap.
So, make sure the address we miss on will translate to physical memory
that actually exists.
In order to make this work we have to embed the valid address bitmap
into the kernel image. And in order to make that less expensive we
make an adjustment, in that the max physical memory address is
decreased to "1 << 41", even on the chips that support a 42-bit
physical address space. We can do this because bit 41 indicates
"I/O space" and thus covers non-memory ranges.
The result of this is that:
1) kpte_linear_bitmap shrinks from 2K to 1K in size
2) we need 64K more for the valid address bitmap
We can't let the valid address bitmap be dynamically allocated
once we start using it to validate TLB misses, otherwise we have
crazy issues to deal with wrt. recursive TLB misses and such.
If we're in a TLB miss it could be the deepest trap level that's legal
inside of the cpu. So if we TLB miss referencing the bitmap, the cpu
will be out of trap levels and enter RED state.
To guard against out-of-range accesses to the bitmap, we have to check
to make sure no bits in the physical address above bit 40 are set. We
could export and use last_valid_pfn for this check, but that's just an
unnecessary extra memory reference.
On the plus side of all this, since we load all of these translations
into the special 4MB mapping TSB, and we check the TSB first for TLB
misses, there should be absolutely no real cost for these new checks
in the TLB miss path.
Reported-by: heyongli@gmail.com
Signed-off-by: David S. Miller <davem@davemloft.net>
2009-08-26 03:47:46 +04:00
|
|
|
srlx %g5, 21 + 41, %g2
|
|
|
|
brnz,pn %g2, kvmap_dtlb_longpath
|
|
|
|
nop
|
|
|
|
|
|
|
|
/* This unconditional branch and delay-slot nop gets patched
|
|
|
|
* by the sethi sequence once the bitmap is properly setup.
|
|
|
|
*/
|
|
|
|
.globl valid_addr_bitmap_insn
|
|
|
|
valid_addr_bitmap_insn:
|
|
|
|
ba,pt %xcc, 2f
|
|
|
|
nop
|
|
|
|
.subsection 2
|
|
|
|
.globl valid_addr_bitmap_patch
|
|
|
|
valid_addr_bitmap_patch:
|
|
|
|
sethi %hi(sparc64_valid_addr_bitmap), %g7
|
|
|
|
or %g7, %lo(sparc64_valid_addr_bitmap), %g7
|
|
|
|
.previous
|
|
|
|
|
|
|
|
srlx %g5, 21 + 22, %g2
|
|
|
|
srlx %g2, 6, %g5
|
|
|
|
and %g2, 63, %g2
|
|
|
|
sllx %g5, 3, %g5
|
|
|
|
ldx [%g7 + %g5], %g5
|
|
|
|
mov 1, %g7
|
|
|
|
sllx %g7, %g2, %g7
|
|
|
|
andcc %g5, %g7, %g0
|
|
|
|
be,pn %xcc, kvmap_dtlb_longpath
|
|
|
|
|
|
|
|
2: sethi %hi(kpte_linear_bitmap), %g2
|
|
|
|
|
|
|
|
/* Get the 256MB physical address index. */
|
2006-02-22 07:51:13 +03:00
|
|
|
sllx %g4, 21, %g5
|
2012-09-07 05:13:58 +04:00
|
|
|
or %g2, %lo(kpte_linear_bitmap), %g2
|
2006-02-22 07:51:13 +03:00
|
|
|
srlx %g5, 21 + 28, %g5
|
2012-09-07 05:13:58 +04:00
|
|
|
and %g5, (32 - 1), %g7
|
2006-02-22 07:51:13 +03:00
|
|
|
|
2012-09-07 05:13:58 +04:00
|
|
|
/* Divide by 32 to get the offset into the bitmask. */
|
|
|
|
srlx %g5, 5, %g5
|
|
|
|
add %g7, %g7, %g7
|
2006-02-27 10:09:37 +03:00
|
|
|
sllx %g5, 3, %g5
|
2006-02-22 07:51:13 +03:00
|
|
|
|
2012-09-07 05:13:58 +04:00
|
|
|
/* kern_linear_pte_xor[(mask >> shift) & 3)] */
|
2006-02-22 07:51:13 +03:00
|
|
|
ldx [%g2 + %g5], %g2
|
2012-09-07 05:13:58 +04:00
|
|
|
srlx %g2, %g7, %g7
|
2006-02-22 07:51:13 +03:00
|
|
|
sethi %hi(kern_linear_pte_xor), %g5
|
2012-09-07 05:13:58 +04:00
|
|
|
and %g7, 3, %g7
|
2006-02-22 07:51:13 +03:00
|
|
|
or %g5, %lo(kern_linear_pte_xor), %g5
|
2012-09-07 05:13:58 +04:00
|
|
|
sllx %g7, 3, %g7
|
|
|
|
ldx [%g5 + %g7], %g2
|
2006-02-01 05:29:18 +03:00
|
|
|
|
2005-09-26 03:46:57 +04:00
|
|
|
.globl kvmap_linear_patch
|
|
|
|
kvmap_linear_patch:
|
2006-02-22 09:31:11 +03:00
|
|
|
ba,pt %xcc, kvmap_dtlb_tsb4m_load
|
2005-09-22 05:50:51 +04:00
|
|
|
xor %g2, %g4, %g5
|
|
|
|
|
2006-02-01 05:29:18 +03:00
|
|
|
kvmap_dtlb_vmalloc_addr:
|
|
|
|
KERN_PGTABLE_WALK(%g4, %g5, %g2, kvmap_dtlb_longpath)
|
|
|
|
|
2011-08-05 11:53:57 +04:00
|
|
|
TSB_LOCK_TAG(%g1, %g2, %g7)
|
2006-02-01 05:29:18 +03:00
|
|
|
|
|
|
|
/* Load and check PTE. */
|
|
|
|
ldxa [%g5] ASI_PHYS_USE_EC, %g5
|
2006-02-18 05:01:02 +03:00
|
|
|
mov 1, %g7
|
|
|
|
sllx %g7, TSB_TAG_INVALID_BIT, %g7
|
2006-02-01 05:29:18 +03:00
|
|
|
brgez,a,pn %g5, kvmap_dtlb_longpath
|
2011-08-05 11:53:57 +04:00
|
|
|
TSB_STORE(%g1, %g7)
|
2006-02-01 05:29:18 +03:00
|
|
|
|
2011-08-05 11:53:57 +04:00
|
|
|
TSB_WRITE(%g1, %g5, %g6)
|
2006-02-01 05:29:18 +03:00
|
|
|
|
|
|
|
/* fallthrough to TLB load */
|
|
|
|
|
|
|
|
kvmap_dtlb_load:
|
2006-02-11 23:21:20 +03:00
|
|
|
|
|
|
|
661: stxa %g5, [%g0] ASI_DTLB_DATA_IN ! Reload TLB
|
2006-02-01 05:29:18 +03:00
|
|
|
retry
|
2006-02-11 23:21:20 +03:00
|
|
|
.section .sun4v_2insn_patch, "ax"
|
|
|
|
.word 661b
|
|
|
|
nop
|
|
|
|
nop
|
|
|
|
.previous
|
|
|
|
|
|
|
|
/* For sun4v the ASI_DTLB_DATA_IN store and the retry
|
|
|
|
* instruction get nop'd out and we get here to branch
|
|
|
|
* to the sun4v tlb load code. The registers are setup
|
|
|
|
* as follows:
|
|
|
|
*
|
|
|
|
* %g4: vaddr
|
|
|
|
* %g5: PTE
|
|
|
|
* %g6: TAG
|
|
|
|
*
|
|
|
|
* The sun4v TLB load wants the PTE in %g3 so we fix that
|
|
|
|
* up here.
|
|
|
|
*/
|
|
|
|
ba,pt %xcc, sun4v_dtlb_load
|
|
|
|
mov %g5, %g3
|
2006-02-01 05:29:18 +03:00
|
|
|
|
2008-01-11 08:10:54 +03:00
|
|
|
#ifdef CONFIG_SPARSEMEM_VMEMMAP
|
2007-10-16 12:24:16 +04:00
|
|
|
kvmap_vmemmap:
|
|
|
|
sub %g4, %g5, %g5
|
|
|
|
srlx %g5, 22, %g5
|
|
|
|
sethi %hi(vmemmap_table), %g1
|
|
|
|
sllx %g5, 3, %g5
|
|
|
|
or %g1, %lo(vmemmap_table), %g1
|
|
|
|
ba,pt %xcc, kvmap_dtlb_load
|
|
|
|
ldx [%g1 + %g5], %g5
|
2008-01-11 08:10:54 +03:00
|
|
|
#endif
|
2007-10-16 12:24:16 +04:00
|
|
|
|
2006-02-01 05:29:18 +03:00
|
|
|
kvmap_dtlb_nonlinear:
|
|
|
|
/* Catch kernel NULL pointer derefs. */
|
|
|
|
sethi %hi(PAGE_SIZE), %g5
|
|
|
|
cmp %g4, %g5
|
|
|
|
bleu,pn %xcc, kvmap_dtlb_longpath
|
2005-09-26 03:46:57 +04:00
|
|
|
nop
|
|
|
|
|
2008-01-11 08:10:54 +03:00
|
|
|
#ifdef CONFIG_SPARSEMEM_VMEMMAP
|
2007-10-16 12:24:16 +04:00
|
|
|
/* Do not use the TSB for vmemmap. */
|
2009-09-29 01:39:58 +04:00
|
|
|
mov (VMEMMAP_BASE >> 40), %g5
|
|
|
|
sllx %g5, 40, %g5
|
2007-10-16 12:24:16 +04:00
|
|
|
cmp %g4,%g5
|
|
|
|
bgeu,pn %xcc, kvmap_vmemmap
|
|
|
|
nop
|
2008-01-11 08:10:54 +03:00
|
|
|
#endif
|
2007-10-16 12:24:16 +04:00
|
|
|
|
2006-02-01 05:29:18 +03:00
|
|
|
KERN_TSB_LOOKUP_TL1(%g4, %g6, %g5, %g1, %g2, %g3, kvmap_dtlb_load)
|
|
|
|
|
|
|
|
kvmap_dtlb_tsbmiss:
|
2005-09-22 05:50:51 +04:00
|
|
|
sethi %hi(MODULES_VADDR), %g5
|
|
|
|
cmp %g4, %g5
|
2006-02-01 05:29:18 +03:00
|
|
|
blu,pn %xcc, kvmap_dtlb_longpath
|
2009-09-29 01:39:58 +04:00
|
|
|
mov (VMALLOC_END >> 40), %g5
|
|
|
|
sllx %g5, 40, %g5
|
2005-09-22 05:50:51 +04:00
|
|
|
cmp %g4, %g5
|
2006-02-01 05:29:18 +03:00
|
|
|
bgeu,pn %xcc, kvmap_dtlb_longpath
|
2005-09-22 05:50:51 +04:00
|
|
|
nop
|
|
|
|
|
|
|
|
kvmap_check_obp:
|
|
|
|
sethi %hi(LOW_OBP_ADDRESS), %g5
|
|
|
|
cmp %g4, %g5
|
2006-02-01 05:29:18 +03:00
|
|
|
blu,pn %xcc, kvmap_dtlb_vmalloc_addr
|
2005-09-22 05:50:51 +04:00
|
|
|
mov 0x1, %g5
|
|
|
|
sllx %g5, 32, %g5
|
|
|
|
cmp %g4, %g5
|
2006-02-01 05:29:18 +03:00
|
|
|
blu,pn %xcc, kvmap_dtlb_obp
|
2005-09-22 05:50:51 +04:00
|
|
|
nop
|
2006-02-01 05:29:18 +03:00
|
|
|
ba,pt %xcc, kvmap_dtlb_vmalloc_addr
|
2005-09-22 05:50:51 +04:00
|
|
|
nop
|
|
|
|
|
2006-02-01 05:29:18 +03:00
|
|
|
kvmap_dtlb_longpath:
|
2006-02-06 09:27:28 +03:00
|
|
|
|
|
|
|
661: rdpr %pstate, %g5
|
2006-02-01 05:29:18 +03:00
|
|
|
wrpr %g5, PSTATE_AG | PSTATE_MG, %pstate
|
2006-02-07 11:00:16 +03:00
|
|
|
.section .sun4v_2insn_patch, "ax"
|
2006-02-06 09:27:28 +03:00
|
|
|
.word 661b
|
2006-02-18 05:01:02 +03:00
|
|
|
SET_GL(1)
|
|
|
|
ldxa [%g0] ASI_SCRATCHPAD, %g5
|
2006-02-06 09:27:28 +03:00
|
|
|
.previous
|
|
|
|
|
2006-02-11 23:21:20 +03:00
|
|
|
rdpr %tl, %g3
|
|
|
|
cmp %g3, 1
|
|
|
|
|
|
|
|
661: mov TLB_TAG_ACCESS, %g4
|
2006-02-01 05:29:18 +03:00
|
|
|
ldxa [%g4] ASI_DMMU, %g5
|
2006-02-11 23:21:20 +03:00
|
|
|
.section .sun4v_2insn_patch, "ax"
|
|
|
|
.word 661b
|
2006-02-18 05:01:02 +03:00
|
|
|
ldx [%g5 + HV_FAULT_D_ADDR_OFFSET], %g5
|
2006-02-11 23:21:20 +03:00
|
|
|
nop
|
|
|
|
.previous
|
|
|
|
|
2006-02-01 05:29:18 +03:00
|
|
|
be,pt %xcc, sparc64_realfault_common
|
|
|
|
mov FAULT_CODE_DTLB, %g4
|
|
|
|
ba,pt %xcc, winfix_trampoline
|
|
|
|
nop
|