Cleanup "invalidate_pte" function:

All I did was replace some hard coded constants with #define constants instead and tweak some comments to try and make the function easier to follow/understand.

There *should* be NO CHANGE in actual functionality.

[skip travis] (more commits coming)
This commit is contained in:
Fish (David B. Trout)
2021-09-14 13:27:53 -07:00
parent c16013ca86
commit 8e91bafa2c
+127 -82
View File
@@ -1888,134 +1888,179 @@ void ARCH_DEP( invalidate_tlbe )( REGS* regs, BYTE* main )
/*-------------------------------------------------------------------*/
/* Invalidate page table entry */
/* Invalidate Page Table Entry */
/*-------------------------------------------------------------------*/
/* */
/* Input: */
/* ibyte 0x21=IPTE instruction, 0x59=IESBE instruction */
/* r1 First operand register number */
/* r2 Second operand register number */
/* This function is called by the IPTE and IESBE instructions. It */
/* either sets the PAGETAB_INVALID bit (for IPTE instruction) or */
/* resets the PAGETAB_ESVALID bit (for IESBE instruction) for the */
/* Page Table Entry addressed by the passed Page Table Origin value */
/* plus the Virtual Address's page index value, and clears the TLB */
/* of all entries with a Page Frame Real Address matching the one */
/* from the invalidated Page Table Entry. */
/* */
/* Input: */
/* */
/* ibyte 0x21 = IPTE instruction, 0x59 = IESBE instruction */
/* pto Real address of Page Table Origin identifying the */
/* Page Table containing the Entry to be invalidated */
/* vaddr Virtual Address of page within specified Page Table */
/* whose entry is to be invalidated */
/* regs CPU register context */
/* */
/* This function is called by the IPTE and IESBE instructions. */
/* It sets the PAGETAB_INVALID bit (for IPTE) or resets the */
/* PAGETAB_ESVALID bit (for IESBE) in the page table entry */
/* addressed by the page table origin in the R1 register and */
/* the page index in the R2 register. It clears the TLB of */
/* all entries whose PFRA matches the page table entry. */
/* *** IMPORTANT! *** */
/* */
/* invalidate_pte should be called with the intlock held and */
/* SYNCHRONIZE_CPUS issued while intlock is held. */
/* This function expects INTLOCK to be held */
/* and SYNCHRONIZE_CPUS to be called beforehand! */
/* */
/*-------------------------------------------------------------------*/
void ARCH_DEP(invalidate_pte) (BYTE ibyte, RADR op1,
U32 op2, REGS *regs)
void ARCH_DEP( invalidate_pte )( BYTE ibyte, RADR pto, VADR vaddr, REGS* regs )
{
RADR raddr; /* Addr of page table entry */
RADR pte;
RADR pfra;
RADR raddr; /* Addr of Page Table Entry */
RADR pte; /* Page Table Entry itself */
RADR pfra; /* Page Frame Real Address */
UNREFERENCED_370( ibyte );
#if !defined( FEATURE_S390_DAT ) && !defined( FEATURE_001_ZARCH_INSTALLED_FACILITY )
{
// SYSTEM/370...
/* Program check if translation format is invalid */
if ((((regs->CR(0) & CR0_PAGE_SIZE) != CR0_PAGE_SZ_2K) &&
((regs->CR(0) & CR0_PAGE_SIZE) != CR0_PAGE_SZ_4K)) ||
(((regs->CR(0) & CR0_SEG_SIZE) != CR0_SEG_SZ_64K) &&
((regs->CR(0) & CR0_SEG_SIZE) != CR0_SEG_SZ_1M)))
regs->program_interrupt (regs,
PGM_TRANSLATION_SPECIFICATION_EXCEPTION);
if (0
|| (((regs->CR(0) & CR0_PAGE_SIZE) != CR0_PAGE_SZ_2K) && ((regs->CR(0) & CR0_PAGE_SIZE) != CR0_PAGE_SZ_4K))
|| (((regs->CR(0) & CR0_SEG_SIZE) != CR0_SEG_SZ_64K) && ((regs->CR(0) & CR0_SEG_SIZE) != CR0_SEG_SZ_1M))
)
regs->program_interrupt( regs, PGM_TRANSLATION_SPECIFICATION_EXCEPTION );
/* Combine the page table origin in the R1 register with
the page index in the R2 register, ignoring carry, to
form the 31-bit real address of the page table entry */
raddr = (op1 & SEGTAB_370_PTO)
+ (((regs->CR(0) & CR0_SEG_SIZE) == CR0_SEG_SZ_1M) ?
(((regs->CR(0) & CR0_PAGE_SIZE) == CR0_PAGE_SZ_4K) ?
((op2 & 0x000FF000) >> 11) :
((op2 & 0x000FF800) >> 10)) :
(((regs->CR(0) & CR0_PAGE_SIZE) == CR0_PAGE_SZ_4K) ?
((op2 & 0x0000F000) >> 11) :
((op2 & 0x0000F800) >> 10)));
raddr &= 0x00FFFFFF;
/* Add the vaddr's page table entry index to the Page Table
Origin, ignoring any carry, to form the 24-bit real address
of the Page Table Entry to be invalidated, taking into account
that each Page Table Entry is 2 bytes wide (shift 1 less bit)
*/
raddr = (pto & SEGTAB_370_PTO) +
(
((regs->CR(0) & CR0_SEG_SIZE) == CR0_SEG_SZ_1M)
?
(((regs->CR(0) & CR0_PAGE_SIZE) == CR0_PAGE_SZ_4K) ?
((vaddr & 0x000FF000) >> (SHIFT_4K-1)) : ((vaddr & 0x000FF800) >> (SHIFT_2K-1)))
:
(((regs->CR(0) & CR0_PAGE_SIZE) == CR0_PAGE_SZ_4K) ?
((vaddr & 0x0000F000) >> (SHIFT_4K-1)) : ((vaddr & 0x0000F800) >> (SHIFT_2K-1)))
);
raddr &= MAXADDRESS;
/* Fetch the page table entry from real storage, subject
to normal storage protection mechanisms */
pte = ARCH_DEP(vfetch2) ( raddr, USE_REAL_ADDR, regs );
/* Fetch the Page Table Entry from real storage,
subject to normal storage protection mechanisms
*/
pte = ARCH_DEP( vfetch2 )( raddr, USE_REAL_ADDR, regs );
/* Set the page invalid bit in the page table entry,
again subject to storage protection mechansims */
// /*debug*/ LOGMSG("dat.c: IPTE issued for entry %4.4X at %8.8X...\n"
// " page table %8.8X, page index %8.8X, cr0 %8.8X\n",
// pte, raddr, regs->GR_L(r1), regs->GR_L(r2), regs->CR(0));
if ((regs->CR(0) & CR0_PAGE_SIZE) == CR0_PAGE_SZ_2K)
pte |= PAGETAB_INV_2K;
else
pte |= PAGETAB_INV_4K;
ARCH_DEP(vstore2) ( pte, raddr, USE_REAL_ADDR, regs );
pfra = ((regs->CR(0) & CR0_PAGE_SIZE) == CR0_PAGE_SZ_4K) ?
#if 0 // debug 370 IPTE
LOGMSG
(
"dat.c: IPTE issued for entry %4.4X at %8.8X...\n"
" pto %8.8X, vaddr %8.8X, cr0 %8.8X\n"
, pte, raddr
, pto, vaddr, regs->CR(0)
);
#endif
/* Set the invalid bit in the Page Table Entry just fetched */
pte |= ((regs->CR(0) & CR0_PAGE_SIZE) == CR0_PAGE_SZ_2K)
? PAGETAB_INV_2K : PAGETAB_INV_4K;
/* Store the now invalidated Page Table Entry back into
real storage where we originally got it from, subject
to the same storage protection mechanisms
*/
ARCH_DEP( vstore2 )( pte, raddr, USE_REAL_ADDR, regs );
/* Extract the Page Frame Address from the Page Table Entry */
pfra = ((regs->CR(0) & CR0_PAGE_SIZE) == CR0_PAGE_SZ_4K)
?
#if defined( FEATURE_S370E_EXTENDED_ADDRESSING )
(((U32)pte & PAGETAB_EA_4K) << 23) |
#endif
(((U32)pte & PAGETAB_PFRA_4K) << 8) :
(((U32)pte & PAGETAB_PFRA_4K) << 8)
:
(((U32)pte & PAGETAB_PFRA_2K) << 8);
}
#elif defined( FEATURE_S390_DAT )
{
// SYSTEM/390...
/* Program check if translation format is invalid */
if ((regs->CR(0) & CR0_TRAN_FMT) != CR0_TRAN_ESA390)
regs->program_interrupt (regs,
PGM_TRANSLATION_SPECIFICATION_EXCEPTION);
regs->program_interrupt( regs, PGM_TRANSLATION_SPECIFICATION_EXCEPTION );
/* Combine the page table origin in the R1 register with
the page index in the R2 register, ignoring carry, to
form the 31-bit real address of the page table entry */
raddr = (op1 & SEGTAB_PTO)
+ ((op2 & 0x000FF000) >> 10);
raddr &= 0x7FFFFFFF;
/* Add the vaddr's page table entry index to the Page Table
Origin, ignoring any carry, to form the 31-bit real address
of the Page Table Entry to be invalidated, taking into account
that each Page Table Entry is 4 bytes wide (shift 2 fewer bits)
*/
raddr = (pto & SEGTAB_PTO) + ((vaddr & 0x000FF000) >> (PAGEFRAME_PAGESHIFT-2));
raddr &= MAXADDRESS;
/* Fetch the page table entry from real storage, subject
to normal storage protection mechanisms */
pte = ARCH_DEP(vfetch4) ( raddr, USE_REAL_ADDR, regs );
/* Fetch the Page Table Entry from real storage,
subject to normal storage protection mechanisms */
pte = ARCH_DEP( vfetch4 )( raddr, USE_REAL_ADDR, regs );
/* Set the page invalid bit in the page table entry,
again subject to storage protection mechansims */
/* Set the invalid bit in the Page Table Entry just fetched */
#if defined( FEATURE_MOVE_PAGE_FACILITY_2 ) && defined( FEATURE_EXPANDED_STORAGE )
if(ibyte == 0x59)
if (ibyte == 0x59) // (IESBE instruction?)
pte &= ~PAGETAB_ESVALID;
else
#endif
pte |= PAGETAB_INVALID;
ARCH_DEP(vstore4) ( pte, raddr, USE_REAL_ADDR, regs );
pte |= PAGETAB_INVALID; // (no, IPTE instruction)
/* Store the now invalidated Page Table Entry back into
real storage where we originally got it from, subject
to the same storage protection mechanisms
*/
ARCH_DEP( vstore4 )( pte, raddr, USE_REAL_ADDR, regs );
/* Extract the Page Frame Address from the Page Table Entry */
pfra = pte & PAGETAB_PFRA;
}
#else /* defined( FEATURE_001_ZARCH_INSTALLED_FACILITY ) */
{
/* Combine the page table origin in the R1 register with
the page index in the R2 register, ignoring carry, to
form the 64-bit real address of the page table entry */
raddr = (op1 & ZSEGTAB_PTO)
+ ((op2 & 0x000FF000) >> 9);
// ESAME = z/Architecture...
/* Fetch the page table entry from real storage, subject
to normal storage protection mechanisms */
pte = ARCH_DEP(vfetch8) ( raddr, USE_REAL_ADDR, regs );
/* Add the vaddr's page table entry index to the Page Table
Origin, ignoring any carry, to form the 64-bit real address
of the Page Table Entry to be invalidated, taking into account
that each Page Table Entry is 8 bytes wide (shift 3 fewer bits)
*/
raddr = (pto & ZSEGTAB_PTO) + ((vaddr & 0x000FF000) >> (PAGEFRAME_PAGESHIFT-3));
raddr &= MAXADDRESS;
/* Set the page invalid bit in the page table entry,
again subject to storage protection mechansims */
/* Fetch the Page Table Entry from real storage,
subject to normal storage protection mechanisms
*/
pte = ARCH_DEP( vfetch8 )( raddr, USE_REAL_ADDR, regs );
/* Set the invalid bit in the Page Table Entry just fetched */
#if defined( FEATURE_MOVE_PAGE_FACILITY_2 ) && defined( FEATURE_EXPANDED_STORAGE )
if(ibyte == 0x59)
if (ibyte == 0x59) // (IESBE instruction?)
pte &= ~ZPGETAB_ESVALID;
else
#endif
pte |= ZPGETAB_I;
ARCH_DEP(vstore8) ( pte, raddr, USE_REAL_ADDR, regs );
pte |= ZPGETAB_I; // (no, IPTE instruction)
/* Store the now invalidated Page Table Entry back into
real storage where we originally got it from, subject
to the same storage protection mechanisms
*/
ARCH_DEP( vstore8 )( pte, raddr, USE_REAL_ADDR, regs );
/* Extract the Page Frame Address from the Page Table Entry */
pfra = pte & ZPGETAB_PFRA;
}
#endif /* defined( FEATURE_001_ZARCH_INSTALLED_FACILITY ) */
/* Invalidate TLB entries */
ARCH_DEP(purge_tlbe_all) (pfra);
/* Invalidate all TLB entries for this Page Frame Real Address */
ARCH_DEP( purge_tlbe_all )( pfra );
} /* end function invalidate_pte */