Skip to content

Commit

Permalink
Always use supervisor mode when MMU accesses descriptors.
Browse files Browse the repository at this point in the history
  • Loading branch information
tonioni committed Dec 1, 2018
1 parent 4885c33 commit 6a8393c
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 45 deletions.
14 changes: 11 additions & 3 deletions cpummu.cpp
Expand Up @@ -630,9 +630,14 @@ static void desc_put_long(uaecptr addr, uae_u32 v)
static uae_u32 mmu_fill_atc(uaecptr addr, bool super, uae_u32 tag, bool write, struct mmu_atc_line *l, uae_u32 *status060)
{
uae_u32 desc, desc_addr, wp;
uae_u32 status = 0;
uae_u32 status = 0;
int i;
int old_s;

// Always use supervisor mode to access descriptors
old_s = regs.s;
regs.s = 1;

wp = 0;
desc = super ? regs.srp : regs.urp;

Expand Down Expand Up @@ -758,8 +763,11 @@ static uae_u32 mmu_fill_atc(uaecptr addr, bool super, uae_u32 tag, bool write, s
#if MMUDEBUG > 0
write_log(_T("MMU: bus error during table search.\n"));
#endif
} ENDTRY

} ENDTRY;

// Restore original supervisor state
regs.s = old_s;

#if MMUDEBUG > 2
write_log(_T("translate: %x,%u,%u -> %x\n"), addr, super, write, desc);
#endif
Expand Down
102 changes: 60 additions & 42 deletions cpummu30.cpp
Expand Up @@ -1028,6 +1028,20 @@ static void mmu030_atc_handle_history_bit(int entry_num) {
}
}

static void desc_put_long(uaecptr addr, uae_u32 v)
{
x_phys_put_long(addr, v);
}
static uae_u32 desc_get_long(uaecptr addr)
{
return x_phys_get_long(addr);
}
static void desc_get_quad(uaecptr addr, uae_u32 *descr)
{
descr[0] = x_phys_get_long(addr);
descr[1] = x_phys_get_long(addr + 4);
}

/* Descriptors */

#define DESCR_TYPE_MASK 0x00000003
Expand Down Expand Up @@ -1188,38 +1202,42 @@ static void mmu030_atc_handle_history_bit(int entry_num) {
* for PTEST (levels 1 to 7). Using level 0 creates an ATC entry. */

static uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int level) {
/* During table walk up to 7 different descriptors are used:
* root pointer, descriptors fetched from function code lookup table,
* tables A, B, C and D and one indirect descriptor */
uae_u32 descr[2];
uae_u32 descr_type;
uaecptr descr_addr[7];
uaecptr table_addr = 0;
uaecptr page_addr = 0;
uaecptr indirect_addr = 0;
uae_u32 table_index = 0;
uae_u32 limit = 0;
uae_u32 unused_fields_mask = 0;
bool super = (fc&4) ? true : false;
bool super_violation = false;
bool write_protected = false;
uae_u8 cache_inhibit = CACHE_ENABLE_ALL;
bool descr_modified = false;
/* During table walk up to 7 different descriptors are used:
* root pointer, descriptors fetched from function code lookup table,
* tables A, B, C and D and one indirect descriptor */
uae_u32 descr[2];
uae_u32 descr_type;
uaecptr descr_addr[7];
uaecptr table_addr = 0;
uaecptr page_addr = 0;
uaecptr indirect_addr = 0;
uae_u32 table_index = 0;
uae_u32 limit = 0;
uae_u32 unused_fields_mask = 0;
bool super = (fc&4) ? true : false;
bool super_violation = false;
bool write_protected = false;
uae_u8 cache_inhibit = CACHE_ENABLE_ALL;
bool descr_modified = false;

mmu030.status = 0; /* Reset status */
mmu030.status = 0; /* Reset status */

/* Initial values for condition variables.
* Note: Root pointer is long descriptor. */
int t = 0;
int addr_position = 1;
int next_size = 0;
int descr_size = 8;
int descr_num = 0;
bool early_termination = false;
int i;
/* Initial values for condition variables.
* Note: Root pointer is long descriptor. */
int t = 0;
int addr_position = 1;
int next_size = 0;
int descr_size = 8;
int descr_num = 0;
bool early_termination = false;
int old_s;
int i;

TRY(prb) {
// Always use supervisor mode to access descriptors
old_s = regs.s;
regs.s = 1;

TRY(prb) {
/* Use super user root pointer if enabled in TC register and access is in
* super user mode, else use cpu root pointer. */
if ((tc_030&TC_ENABLE_SUPERVISOR) && super) {
Expand Down Expand Up @@ -1278,13 +1296,12 @@ static uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int lev
descr_addr[descr_num] = table_addr+(table_index*next_size);

if (next_size==4) {
descr[0] = phys_get_long(descr_addr[descr_num]);
descr[0] = desc_get_long(descr_addr[descr_num]);
#if MMU030_REG_DBG_MSG
write_log(_T("Next descriptor: %08X\n"),descr[0]);
#endif
} else {
descr[0] = phys_get_long(descr_addr[descr_num]);
descr[1] = phys_get_long(descr_addr[descr_num]+4);
desc_get_quad(descr_addr[descr_num], descr);
#if MMU030_REG_DBG_MSG
write_log(_T("Next descriptor: %08X%08X\n"),descr[0],descr[1]);
#endif
Expand Down Expand Up @@ -1330,7 +1347,7 @@ static uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int lev
/* Set the updated bit */
if (!level && !(descr[0]&DESCR_U) && !super_violation) {
descr[0] |= DESCR_U;
phys_put_long(descr_addr[descr_num], descr[0]);
desc_put_long(descr_addr[descr_num], descr[0]);
}

/* Update status bits */
Expand Down Expand Up @@ -1375,13 +1392,12 @@ static uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int lev
descr_addr[descr_num] = table_addr+(table_index*next_size);

if (next_size==4) {
descr[0] = phys_get_long(descr_addr[descr_num]);
descr[0] = desc_get_long(descr_addr[descr_num]);
#if MMU030_REG_DBG_MSG
write_log(_T("Next descriptor: %08X\n"),descr[0]);
#endif
} else {
descr[0] = phys_get_long(descr_addr[descr_num]);
descr[1] = phys_get_long(descr_addr[descr_num]+4);
desc_get_quad(descr_addr[descr_num], descr);
#if MMU030_REG_DBG_MSG
write_log(_T("Next descriptor: %08X%08X\n"),descr[0],descr[1]);
#endif
Expand Down Expand Up @@ -1436,13 +1452,12 @@ static uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int lev
descr_addr[descr_num] = indirect_addr;

if (next_size==4) {
descr[0] = phys_get_long(descr_addr[descr_num]);
descr[0] = desc_get_long(descr_addr[descr_num]);
#if MMU030_REG_DBG_MSG
write_log(_T("descr = %08X\n"),descr[0]);
#endif
} else {
descr[0] = phys_get_long(descr_addr[descr_num]);
descr[1] = phys_get_long(descr_addr[descr_num]+4);
desc_get_quad(descr_addr[descr_num], descr);
#if MMU030_REG_DBG_MSG
write_log(_T("descr = %08X%08X"),descr[0],descr[1]);
#endif
Expand Down Expand Up @@ -1481,7 +1496,7 @@ static uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int lev
}
/* write modified descriptor if necessary */
if (descr_modified) {
phys_put_long(descr_addr[descr_num], descr[0]);
desc_put_long(descr_addr[descr_num], descr[0]);
}
}

Expand Down Expand Up @@ -1553,8 +1568,11 @@ static uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int lev
mmu030.status |= (MMUSR_BUS_ERROR|MMUSR_INVALID);
write_log(_T("MMU: Bus error while %s descriptor!\n"),
bBusErrorReadWrite?_T("reading"):_T("writing"));
} ENDTRY

} ENDTRY;

// Restore original supervisor state
regs.s = old_s;

/* check if we have to handle ptest */
if (level) {
/* Note: wp, m and sv bits are undefined if the invalid bit is set */
Expand Down

0 comments on commit 6a8393c

Please sign in to comment.