Thu, 02 Dec 2010 02:43:49 +0000
add routines for memory access checking
src/main.c | file | annotate | diff | revisions |
1.1 diff -r d73d07c1d492 -r 3190629004b2 src/main.c 1.2 --- a/src/main.c Thu Dec 02 01:31:05 2010 +0000 1.3 +++ b/src/main.c Thu Dec 02 02:43:49 2010 +0000 1.4 @@ -57,6 +57,83 @@ 1.5 #define WR8(array, address, andmask, value) \ 1.6 array[(address + 0) & (andmask)] = value & 0xff; 1.7 1.8 +/****************** 1.9 + * Memory mapping 1.10 + ******************/ 1.11 + 1.12 +#define MAPRAM(addr) (((uint16_t)state.map[addr*2] << 8) + ((uint16_t)state.map[(addr*2)+1])) 1.13 + 1.14 +uint32_t mapAddr(uint32_t addr, bool writing) 1.15 +{ 1.16 + if (addr < 0x400000) { 1.17 + // RAM access. Check against the Map RAM 1.18 + // Start by getting the original page address 1.19 + uint16_t page = (addr >> 12) & 0x3FF; 1.20 + 1.21 + // Look it up in the map RAM and get the physical page address 1.22 + uint32_t new_page_addr = MAPRAM(page) & 0x3FF; 1.23 + 1.24 + // Update the Page Status bits 1.25 + uint8_t pagebits = (MAPRAM(page) >> 13) & 0x03; 1.26 + if (pagebits != 0) { 1.27 + if (writing) 1.28 + state.map[addr*2] |= 0x60; // Page written to (dirty) 1.29 + else 1.30 + state.map[addr*2] |= 0x40; // Page accessed but not written 1.31 + } 1.32 + 1.33 + // Return the address with the new physical page spliced in 1.34 + return (new_page_addr << 12) + (addr & 0xFFF); 1.35 + } else { 1.36 + // I/O, VRAM or MapRAM space; no mapping is performed or required 1.37 + // TODO: assert here? 1.38 + return addr; 1.39 + } 1.40 +} 1.41 + 1.42 +typedef enum { 1.43 + MEM_ALLOWED = 0, 1.44 + MEM_PAGEFAULT, // Page fault -- page not present 1.45 + MEM_PAGE_NO_WE, // Page not write enabled 1.46 + MEM_KERNEL, // User attempted to access kernel memory 1.47 + MEM_UIE // User Nonmemory Location Access 1.48 +} MEM_STATUS; 1.49 + 1.50 +// check memory access permissions 1.51 +MEM_STATUS checkMemoryAccess(uint32_t addr, bool writing) 1.52 +{ 1.53 + // Are we in Supervisor mode? 1.54 + if (m68k_get_reg(NULL, M68K_REG_SR) & 0x2000) 1.55 + // Yes. We can do anything we like. 1.56 + return MEM_ALLOWED; 1.57 + 1.58 + // If we're here, then we must be in User mode. 1.59 + // Check that the user didn't access memory outside of the RAM area 1.60 + if (addr >= 0x400000) 1.61 + return MEM_UIE; 1.62 + 1.63 + // This leaves us with Page Fault checking. Get the page bits for this page. 1.64 + uint16_t page = (addr >> 12) & 0x3FF; 1.65 + uint8_t pagebits = (MAPRAM(page) >> 13) & 0x07; 1.66 + 1.67 + // Check page is present 1.68 + if ((pagebits & 0x03) == 0) 1.69 + return MEM_PAGEFAULT; 1.70 + 1.71 + // User attempt to access the kernel 1.72 + // A19, A20, A21, A22 low (kernel access): RAM addr before paging; not in Supervisor mode 1.73 + if (((addr >> 19) & 0x0F) == 0) 1.74 + return MEM_KERNEL; 1.75 + 1.76 + // Check page is write enabled 1.77 + if ((pagebits & 0x04) == 0) 1.78 + return MEM_PAGE_NO_WE; 1.79 + 1.80 + // Page access allowed. 1.81 + return MEM_ALLOWED; 1.82 +} 1.83 + 1.84 +#undef MAPRAM 1.85 1.86 /******************************************************** 1.87 * m68k memory read/write support functions for Musashi