Fri, 12 Apr 2013 16:26:25 +0100
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