76,8 → 76,6 |
* Handler of the Fast Data Access MMU Miss trap. If the trap occurred in the kernel |
* (context 0), an identity mapping (with displacement) is installed. Otherwise |
* a higher level service routine is called. |
* |
* TODO implement calling the higher level service routine |
*/ |
.macro FAST_DATA_ACCESS_MMU_MISS_HANDLER tl |
|
84,11 → 82,9 |
mov SCRATCHPAD_MMU_FSA, %g1 |
ldxa [%g1] ASI_SCRATCHPAD, %g1 ! g1 <= RA of MMU fault status area |
|
/* service by higher-level routine when context != 0 */ |
/* read faulting context */ |
add %g1, FSA_DFC_OFFSET, %g2 ! g2 <= RA of data fault context |
ldxa [%g2] ASI_REAL, %g3 ! read the fault context |
brnz %g3, 0f |
nop |
|
/* read the faulting address */ |
add %g1, FSA_DFA_OFFSET, %g2 ! g2 <= RA of data fault address |
96,19 → 92,80 |
srlx %g1, TTE_DATA_TADDR_OFFSET, %g1 ! truncate it to page boundary |
sllx %g1, TTE_DATA_TADDR_OFFSET, %g1 |
|
/* service by higher-level routine when context != 0 */ |
brnz %g3, 0f |
nop |
|
/* exclude page number 0 from installing the identity mapping */ |
brz %g1, 0f |
nop |
|
/* installing the identity does not fit into 32 instructions, call a separate routine */ |
/* |
* Installing the identity does not fit into 32 instructions, call |
* a separate routine. The routine performs RETRY, hence the call never |
* returns. |
*/ |
ba install_identity_mapping |
nop |
|
0: ! TODO - call higher level service routine |
0: |
|
/* |
* One of the scenarios in which this trap can occur is when the |
* register window spill/fill handler accesses a memory which is not |
* mapped. In such a case, this handler will be called from TL = 1. |
* We handle the situation by pretending that the MMU miss occurred |
* on TL = 0. Once the MMU miss trap is services, the instruction which |
* caused the spill/fill trap is restarted, the spill/fill trap occurs, |
* but this time its handler accesse memory which IS mapped. |
*/ |
.if (\tl > 0) |
wrpr %g0, 1, %tl |
.endif |
|
/* |
* Save the faulting virtual page and faulting context to the %g2 |
* register. The most significant 51 bits of the %g2 register will |
* contain the virtual address which caused the fault truncated to the |
* page boundary. The least significant 13 bits of the %g2 register |
* will contain the number of the context in which the fault occurred. |
* The value of the %g2 register will be passed as a parameter to the |
* higher level service routine. |
*/ |
or %g1, %g3, %g2 |
|
PREEMPTIBLE_HANDLER fast_data_access_mmu_miss |
.endm |
|
/* |
* Handler of the Fast Data MMU Protection trap. Finds the trapping address |
* and context and calls higher level service routine. |
*/ |
.macro FAST_DATA_ACCESS_PROTECTION_HANDLER tl |
/* |
* The same special case as in FAST_DATA_ACCESS_MMU_MISS_HANDLER. |
*/ |
.if (\tl > 0) |
wrpr %g0, 1, %tl |
.endif |
|
mov SCRATCHPAD_MMU_FSA, %g1 |
ldxa [%g1] ASI_SCRATCHPAD, %g1 ! g1 <= RA of MMU fault status area |
|
/* read faulting context */ |
add %g1, FSA_DFC_OFFSET, %g2 ! g2 <= RA of data fault context |
ldxa [%g2] ASI_REAL, %g3 ! read the fault context |
|
/* read the faulting address */ |
add %g1, FSA_DFA_OFFSET, %g2 ! g2 <= RA of data fault address |
ldxa [%g2] ASI_REAL, %g1 ! read the fault address |
srlx %g1, TTE_DATA_TADDR_OFFSET, %g1 ! truncate it to page boundary |
sllx %g1, TTE_DATA_TADDR_OFFSET, %g1 |
|
/* the same as for FAST_DATA_ACCESS_MMU_MISS_HANDLER */ |
or %g1, %g3, %g2 |
|
PREEMPTIBLE_HANDLER fast_data_access_protection |
.endm |
|
#endif /* __ASM__ */ |