mirror of
https://github.com/dingusdev/dingusppc.git
synced 2025-01-11 20:29:46 +00:00
ppcmmu: fix TLB flushing.
This commit is contained in:
parent
d5960ca70b
commit
bb0ca2ac40
@ -704,6 +704,9 @@ static uint32_t read_unaligned(uint32_t guest_va, uint8_t *host_va, uint32_t siz
|
|||||||
static void write_unaligned(uint32_t guest_va, uint8_t *host_va, uint32_t value,
|
static void write_unaligned(uint32_t guest_va, uint8_t *host_va, uint32_t value,
|
||||||
uint32_t size);
|
uint32_t size);
|
||||||
|
|
||||||
|
template <const TLBType tlb_type>
|
||||||
|
void tlb_flush_bat_entries();
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
inline T mmu_read_vmem(uint32_t guest_va)
|
inline T mmu_read_vmem(uint32_t guest_va)
|
||||||
{
|
{
|
||||||
@ -1018,23 +1021,53 @@ void tlb_flush_entry(uint32_t ea)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <const TLBType tlb_type>
|
||||||
void tlb_flush_entries(TLBFlags type)
|
void tlb_flush_entries(TLBFlags type)
|
||||||
{
|
{
|
||||||
|
TLBEntry *m1_tlb, *m2_tlb, *m3_tlb;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
// Flush BAT entries from the primary TLBs
|
if (tlb_type == TLBType::ITLB) {
|
||||||
|
m1_tlb = &itlb1_mode1[0];
|
||||||
|
m2_tlb = &itlb1_mode2[0];
|
||||||
|
m3_tlb = &itlb1_mode3[0];
|
||||||
|
} else {
|
||||||
|
m1_tlb = &dtlb1_mode1[0];
|
||||||
|
m2_tlb = &dtlb1_mode2[0];
|
||||||
|
m3_tlb = &dtlb1_mode3[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flush entries from the primary TLBs
|
||||||
for (i = 0; i < TLB_SIZE; i++) {
|
for (i = 0; i < TLB_SIZE; i++) {
|
||||||
if (dtlb1_mode2[i].flags & type) {
|
if (m1_tlb[i].flags & type) {
|
||||||
dtlb1_mode2[i].tag = TLB_INVALID_TAG;
|
m1_tlb[i].tag = TLB_INVALID_TAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dtlb1_mode3[i].flags & type) {
|
if (m2_tlb[i].flags & type) {
|
||||||
dtlb1_mode3[i].tag = TLB_INVALID_TAG;
|
m2_tlb[i].tag = TLB_INVALID_TAG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m3_tlb[i].flags & type) {
|
||||||
|
m3_tlb[i].tag = TLB_INVALID_TAG;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flush BAT entries from the secondary TLBs
|
if (tlb_type == TLBType::ITLB) {
|
||||||
|
m1_tlb = &itlb2_mode1[0];
|
||||||
|
m2_tlb = &itlb2_mode2[0];
|
||||||
|
m3_tlb = &itlb2_mode3[0];
|
||||||
|
} else {
|
||||||
|
m1_tlb = &dtlb2_mode1[0];
|
||||||
|
m2_tlb = &dtlb2_mode2[0];
|
||||||
|
m3_tlb = &dtlb2_mode3[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flush entries from the secondary TLBs
|
||||||
for (i = 0; i < TLB_SIZE * TLB2_WAYS; i++) {
|
for (i = 0; i < TLB_SIZE * TLB2_WAYS; i++) {
|
||||||
|
if (dtlb2_mode1[i].flags & type) {
|
||||||
|
dtlb2_mode1[i].tag = TLB_INVALID_TAG;
|
||||||
|
}
|
||||||
|
|
||||||
if (dtlb2_mode2[i].flags & type) {
|
if (dtlb2_mode2[i].flags & type) {
|
||||||
dtlb2_mode2[i].tag = TLB_INVALID_TAG;
|
dtlb2_mode2[i].tag = TLB_INVALID_TAG;
|
||||||
}
|
}
|
||||||
@ -1048,22 +1081,24 @@ void tlb_flush_entries(TLBFlags type)
|
|||||||
bool gTLBFlushBatEntries = false;
|
bool gTLBFlushBatEntries = false;
|
||||||
bool gTLBFlushPatEntries = false;
|
bool gTLBFlushPatEntries = false;
|
||||||
|
|
||||||
|
template <const TLBType tlb_type>
|
||||||
void tlb_flush_bat_entries()
|
void tlb_flush_bat_entries()
|
||||||
{
|
{
|
||||||
if (!gTLBFlushBatEntries)
|
if (!gTLBFlushBatEntries)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
tlb_flush_entries(TLBE_FROM_BAT);
|
tlb_flush_entries<tlb_type>(TLBE_FROM_BAT);
|
||||||
|
|
||||||
gTLBFlushBatEntries = false;
|
gTLBFlushBatEntries = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <const TLBType tlb_type>
|
||||||
void tlb_flush_pat_entries()
|
void tlb_flush_pat_entries()
|
||||||
{
|
{
|
||||||
if (!gTLBFlushPatEntries)
|
if (!gTLBFlushPatEntries)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
tlb_flush_entries(TLBE_FROM_PAT);
|
tlb_flush_entries<tlb_type>(TLBE_FROM_PAT);
|
||||||
|
|
||||||
gTLBFlushPatEntries = false;
|
gTLBFlushPatEntries = false;
|
||||||
}
|
}
|
||||||
@ -1099,9 +1134,11 @@ static void mpc601_bat_update(uint32_t bat_reg)
|
|||||||
dbat_entry->valid = false;
|
dbat_entry->valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MPC601 has unified BATs so we're going to fush both ITLB and DTLB
|
||||||
if (!gTLBFlushBatEntries) {
|
if (!gTLBFlushBatEntries) {
|
||||||
gTLBFlushBatEntries = true;
|
gTLBFlushBatEntries = true;
|
||||||
add_ctx_sync_action(&tlb_flush_bat_entries);
|
add_ctx_sync_action(&tlb_flush_bat_entries<TLBType::ITLB>);
|
||||||
|
add_ctx_sync_action(&tlb_flush_bat_entries<TLBType::DTLB>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1126,7 +1163,7 @@ static void ppc_ibat_update(uint32_t bat_reg)
|
|||||||
|
|
||||||
if (!gTLBFlushBatEntries) {
|
if (!gTLBFlushBatEntries) {
|
||||||
gTLBFlushBatEntries = true;
|
gTLBFlushBatEntries = true;
|
||||||
add_ctx_sync_action(&tlb_flush_bat_entries);
|
add_ctx_sync_action(&tlb_flush_bat_entries<TLBType::ITLB>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1152,16 +1189,19 @@ static void ppc_dbat_update(uint32_t bat_reg)
|
|||||||
|
|
||||||
if (!gTLBFlushBatEntries) {
|
if (!gTLBFlushBatEntries) {
|
||||||
gTLBFlushBatEntries = true;
|
gTLBFlushBatEntries = true;
|
||||||
add_ctx_sync_action(&tlb_flush_bat_entries);
|
add_ctx_sync_action(&tlb_flush_bat_entries<TLBType::DTLB>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void mmu_pat_ctx_changed()
|
void mmu_pat_ctx_changed()
|
||||||
{
|
{
|
||||||
|
// Page address translation context changed so we need to flush
|
||||||
|
// all PAT entries from both ITLB and DTLB
|
||||||
if (!gTLBFlushPatEntries) {
|
if (!gTLBFlushPatEntries) {
|
||||||
gTLBFlushPatEntries = true;
|
gTLBFlushPatEntries = true;
|
||||||
add_ctx_sync_action(&tlb_flush_pat_entries);
|
add_ctx_sync_action(&tlb_flush_pat_entries<TLBType::ITLB>);
|
||||||
|
add_ctx_sync_action(&tlb_flush_pat_entries<TLBType::DTLB>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user