src/memory.h

Fri, 12 Apr 2013 16:26:25 +0100

author
Philip Pemberton <philpem@philpem.me.uk>
date
Fri, 12 Apr 2013 16:26:25 +0100
branch
experimental_memory_mapper_v2
changeset 144
609707511166
parent 128
3246b74d96bc
permissions
-rw-r--r--

Don't set PS1 if there is a level-7 interrupt or bus error

PS1 should only be set if the page was originally present (PS1 or PS0 set). If
PS0 and PS1 are clear (page not present) then do NOT set PS1.

Once again the TRM is blatantly and spectacularly wrong...

     1 #ifndef _MEMORY_H
     2 #define _MEMORY_H
     4 /***********************************
     5  * Array read/write utility macros
     6  * "Don't Repeat Yourself" :)
     7  ***********************************/
     9 /// Array read, 32-bit
    10 #define RD32(array, address, andmask)							\
    11 	(((uint32_t)array[(address + 0) & (andmask)] << 24) |		\
    12 	 ((uint32_t)array[(address + 1) & (andmask)] << 16) |		\
    13 	 ((uint32_t)array[(address + 2) & (andmask)] << 8)  |		\
    14 	 ((uint32_t)array[(address + 3) & (andmask)]))
    16 /// Array read, 16-bit
    17 #define RD16(array, address, andmask)							\
    18 	(((uint32_t)array[(address + 0) & (andmask)] << 8)  |		\
    19 	 ((uint32_t)array[(address + 1) & (andmask)]))
    21 /// Array read, 8-bit
    22 #define RD8(array, address, andmask)							\
    23 	((uint32_t)array[(address + 0) & (andmask)])
    25 /// Array write, 32-bit
    26 #define WR32(array, address, andmask, value) do {				\
    27 	array[(address + 0) & (andmask)] = (value >> 24) & 0xff;	\
    28 	array[(address + 1) & (andmask)] = (value >> 16) & 0xff;	\
    29 	array[(address + 2) & (andmask)] = (value >> 8)  & 0xff;	\
    30 	array[(address + 3) & (andmask)] =  value        & 0xff;	\
    31 } while (0)
    33 /// Array write, 16-bit
    34 #define WR16(array, address, andmask, value) do {				\
    35 	array[(address + 0) & (andmask)] = (value >> 8)  & 0xff;	\
    36 	array[(address + 1) & (andmask)] =  value        & 0xff;	\
    37 } while (0)
    39 /// Array write, 8-bit
    40 #define WR8(array, address, andmask, value) do {				\
    41 	array[(address + 0) & (andmask)] =  value        & 0xff;	\
    42 } while (0)
    44 /******************
    45  * Memory mapping
    46  ******************/
    48 /***
    49  * An entry in MAP RAM looks like this:
    50  *
    51  *    15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
    52  *   +-----------------------------------------------+
    53  *   |  |  |  |  |  |  |   MA[21..12] ADDRESS BITS   |
    54  *   +-----------------------------------------------+
    55  *
    56  *   Bits 0 thru 9: High 10 address bits (mapping)
    57  *   Bits 10 thru 15: Page bits
    58  *     B10: PS4
    59  *     B11: PS3
    60  *     B12: PS2
    61  *     B13: PS0
    62  *     B14: PS1
    63  *     B15: WE+
    64  *
    65  * Page bit meanings:
    66  *    PS4, 3 and 2 are unused.
    67  *    PS1:PS0:
    68  *      PS1  PS0   Meaning
    69  *      ---  ---   -------
    70  *       0    0    Page not present
    71  *       0    1    Page present but has not been accessed
    72  *       1    0    Page has been accessed but not written
    73  *       1    1    Page has been accessed and written to (is dirty)
    74  *
    75  *    WE+: Write Enable. Set to 1 if the page is writable.
    76  *
    77  * Each RAM page is 4096 bytes.
    78  */
    80 /// Known page bits and their values
    81 enum {
    82 	PAGE_BIT_PS0 = 0x08,	///< PS0 page status bit
    83 	PAGE_BIT_PS1 = 0x10,	///< PS1 (page accessed) page bit
    84 	PAGE_BIT_WE  = 0x20		///< WE (write enable) page bit
    85 };
    87 /// Get the Map RAM entry for the specified page
    88 #define MAPRAM(page) (((uint16_t)state.map[page*2] << 8) + ((uint16_t)state.map[(page*2)+1]))
    89 /// Get the page number for a given address
    90 #define MAP_ADDR_TO_PAGE(addr) (((addr) >> 12) & 0x3FF)
    91 /// Get the Map RAM entry for the specified virtual address
    92 #define MAPRAM_ADDR(addr) (MAPRAM(MAP_ADDR_TO_PAGE(addr)))
    93 /// Map an address from CPU address space to physical memory
    94 #define MAP_ADDR(addr) (((MAPRAM_ADDR(addr) & 0x3FF) << 12) | (addr & 0xFFF))
    95 /// Get the page bits associated with the mapping for a given physical memory address
    96 #define MAP_PAGEBITS(addr) ((MAPRAM_ADDR(addr) >> 10) & 0x3F)
    98 #if 0
    99 /**
   100  * @brief 	Check memory access permissions for a given address.
   101  * @param	addr		Address.
   102  * @param	writing		true if writing to memory, false if reading.
   103  * @return	One of the MEM_STATUS constants, specifying whether the access is
   104  * 			permitted, or what error occurred.
   105  */
   106 MEM_STATUS checkMemoryAccess(uint32_t addr, bool writing);
   108 /**
   109  * @brief   Check access flags for a DMA transfer and trigger an exception if
   110  *          the access is not permitted
   111  * @param   reading     true if reading from memory, false if writing
   112  */
   113 bool access_check_dma(int reading);
   114 #endif
   117 /**
   118  * Check memory access permissions for a DMA operation.
   119  * @return  true if the access is permitted, false if not
   120  */
   121 bool access_check_dma(void);
   123 #endif