fix issue with WE+ bit becoming unset, fix pagefault:not-mapped-in logic

Fri, 04 Mar 2011 01:36:30 +0000

author
Philip Pemberton <philpem@philpem.me.uk>
date
Fri, 04 Mar 2011 01:36:30 +0000
changeset 104
b12651d8a0ab
parent 103
b749a3356e8d
child 105
343250338d23

fix issue with WE+ bit becoming unset, fix pagefault:not-mapped-in logic

- The WE+ (page write enable) bit was becoming unset when the Page Status bits were being set.
A stupid mistake in an AND expression was unsetting the write-enable, thus making S4TEST 12,2 and 12,3 fail spectacularly.

- Pagefaults were not being generated correctly for pages which were not mapped in. Even Supervisor code accessing unmapped pages should get a PF.

src/memory.c file | annotate | diff | revisions
     1.1 --- a/src/memory.c	Fri Mar 04 00:44:36 2011 +0000
     1.2 +++ b/src/memory.c	Fri Mar 04 01:36:30 2011 +0000
     1.3 @@ -40,7 +40,7 @@
     1.4  
     1.5  			case 1:
     1.6  				// Page present -- first access
     1.7 -				state.map[page*2] &= 0x1F;	// turn off "present" bit
     1.8 +				state.map[page*2] &= 0x9F;	// turn off "present" bit (but not write enable!)
     1.9  				if (writing)
    1.10  					state.map[page*2] |= 0x60;		// Page written to (dirty)
    1.11  				else
    1.12 @@ -66,6 +66,16 @@
    1.13  
    1.14  MEM_STATUS checkMemoryAccess(uint32_t addr, bool writing)/*{{{*/
    1.15  {
    1.16 +	// Get the page bits for this page.
    1.17 +	uint16_t page = (addr >> 12) & 0x3FF;
    1.18 +	uint8_t pagebits = (MAPRAM(page) >> 13) & 0x07;
    1.19 +
    1.20 +	// Check page is present (but only for RAM zone)
    1.21 +	if ((addr < 0x400000) && ((pagebits & 0x03) == 0)) {
    1.22 +		LOG("Page not mapped in: addr %08X, page %04X, mapbits %04X", addr, page, MAPRAM(page));
    1.23 +		return MEM_PAGEFAULT;
    1.24 +	}
    1.25 +
    1.26  	// Are we in Supervisor mode?
    1.27  	if (m68k_get_reg(NULL, M68K_REG_SR) & 0x2000)
    1.28  		// Yes. We can do anything we like.
    1.29 @@ -76,14 +86,6 @@
    1.30  	if (addr >= 0x400000)
    1.31  		return MEM_UIE;
    1.32  
    1.33 -	// This leaves us with Page Fault checking. Get the page bits for this page.
    1.34 -	uint16_t page = (addr >> 12) & 0x3FF;
    1.35 -	uint8_t pagebits = (MAPRAM(page) >> 13) & 0x07;
    1.36 -
    1.37 -	// Check page is present
    1.38 -	if ((pagebits & 0x03) == 0)
    1.39 -		return MEM_PAGEFAULT;
    1.40 -
    1.41  	// User attempt to access the kernel
    1.42  	// A19, A20, A21, A22 low (kernel access): RAM addr before paging; not in Supervisor mode
    1.43  	if (((addr >> 19) & 0x0F) == 0)