map unassigned p4 regions to the external address space

This commit is contained in:
Anthony Pesch 2017-11-21 08:25:14 -05:00
parent 225592a955
commit 4380719481
3 changed files with 42 additions and 24 deletions

View File

@ -329,14 +329,17 @@ static void as_map(struct memory *mem, struct address_space *space,
#ifdef HAVE_FASTMEM #ifdef HAVE_FASTMEM
uint8_t *target = space->base + begin; uint8_t *target = space->base + begin;
void *res = NULL;
if (offset >= 0) { if (offset >= 0) {
/* map physical memory into the address space */ /* map physical memory into the address space */
map_shared_memory(mem->shmem, offset, target, size, ACC_READWRITE); res = map_shared_memory(mem->shmem, offset, target, size, ACC_READWRITE);
} else { } else {
/* disable access to mmio areas */ /* disable access to mmio areas */
map_shared_memory(mem->shmem, 0x0, target, size, ACC_NONE); res = map_shared_memory(mem->shmem, 0x0, target, size, ACC_NONE);
} }
CHECK_NE(res, SHMEM_MAP_FAILED);
#else #else
(void)(offset); (void)(offset);
#endif #endif
@ -443,15 +446,23 @@ int sh4_init(struct memory *mem) {
return 0; return 0;
} }
/* note, p0-p3 map to the entire external address space, while p4 only maps to
the external regions in between the gaps in its own internal regions. these
gaps map to areas 1-3 (0xe4000000-0xefffffff) and 6-7 (0xf8000000-
0xffffffff) */
/* area 0 */ /* area 0 */
sh4_map(mem, SH4_AREA0_BEGIN, SH4_AREA0_END, P0 | P1 | P2 | P3, MAP_MMIO, sh4_map(mem, SH4_AREA0_BEGIN, SH4_AICA_MEM_BEGIN - 1, P0 | P1 | P2 | P3,
(mmio_read_cb)&sh4_area0_read, (mmio_write_cb)&sh4_area0_write, NULL, MAP_MMIO, (mmio_read_cb)&sh4_area0_read,
NULL); (mmio_write_cb)&sh4_area0_write, NULL, NULL);
sh4_map(mem, SH4_AICA_MEM_BEGIN, SH4_AICA_MEM_END, P0 | P1 | P2 | P3, sh4_map(mem, SH4_AICA_MEM_BEGIN, SH4_AICA_MEM_END, P0 | P1 | P2 | P3,
MAP_ARAM, NULL, NULL, NULL, NULL); MAP_ARAM, NULL, NULL, NULL, NULL);
sh4_map(mem, SH4_AICA_MEM_END + 1, SH4_AREA0_END, P0 | P1 | P2 | P3, MAP_MMIO,
(mmio_read_cb)&sh4_area0_read, (mmio_write_cb)&sh4_area0_write, NULL,
NULL);
/* area 1 */ /* area 1 */
sh4_map(mem, SH4_AREA1_BEGIN, SH4_AREA1_END, P0 | P1 | P2 | P3, MAP_MMIO, sh4_map(mem, SH4_AREA1_BEGIN, SH4_AREA1_END, P0 | P1 | P2 | P3 | P4, MAP_MMIO,
(mmio_read_cb)&sh4_area1_read, (mmio_write_cb)&sh4_area1_write, NULL, (mmio_read_cb)&sh4_area1_read, (mmio_write_cb)&sh4_area1_write, NULL,
NULL); NULL);
#if 0 #if 0
@ -466,17 +477,16 @@ int sh4_init(struct memory *mem) {
/* area 2 */ /* area 2 */
/* area 3 */ /* area 3 */
sh4_map(mem, SH4_AREA3_RAM0_BEGIN, SH4_AREA3_RAM0_END, P0 | P1 | P2 | P3, sh4_map(mem, SH4_AREA3_RAM0_BEGIN, SH4_AREA3_RAM0_END, P0 | P1 | P2 | P3 | P4,
MAP_RAM, NULL, NULL, NULL, NULL); MAP_RAM, NULL, NULL, NULL, NULL);
sh4_map(mem, SH4_AREA3_RAM1_BEGIN, SH4_AREA3_RAM1_END, P0 | P1 | P2 | P3, sh4_map(mem, SH4_AREA3_RAM1_BEGIN, SH4_AREA3_RAM1_END, P0 | P1 | P2 | P3 | P4,
MAP_RAM, NULL, NULL, NULL, NULL); MAP_RAM, NULL, NULL, NULL, NULL);
sh4_map(mem, SH4_AREA3_RAM2_BEGIN, SH4_AREA3_RAM2_END, P0 | P1 | P2 | P3, sh4_map(mem, SH4_AREA3_RAM2_BEGIN, SH4_AREA3_RAM2_END, P0 | P1 | P2 | P3 | P4,
MAP_RAM, NULL, NULL, NULL, NULL); MAP_RAM, NULL, NULL, NULL, NULL);
sh4_map(mem, SH4_AREA3_RAM3_BEGIN, SH4_AREA3_RAM3_END, P0 | P1 | P2 | P3, sh4_map(mem, SH4_AREA3_RAM3_BEGIN, SH4_AREA3_RAM3_END, P0 | P1 | P2 | P3 | P4,
MAP_RAM, NULL, NULL, NULL, NULL); MAP_RAM, NULL, NULL, NULL, NULL);
/* area 4 */ /* area 4. this region is only written through sq / dma transfers, so only a
/* note, this region is only accessed through sq / dma transfers, so only a
write_string handler is added */ write_string handler is added */
sh4_map(mem, SH4_AREA4_BEGIN, SH4_AREA4_END, P0 | P1 | P2 | P3, MAP_MMIO, sh4_map(mem, SH4_AREA4_BEGIN, SH4_AREA4_END, P0 | P1 | P2 | P3, MAP_MMIO,
(mmio_read_cb)&mem_unhandled_read, NULL, NULL, (mmio_read_cb)&mem_unhandled_read, NULL, NULL,
@ -487,12 +497,22 @@ int sh4_init(struct memory *mem) {
/* area 6 */ /* area 6 */
/* area 7 */ /* area 7 */
sh4_map(mem, SH4_AREA7_BEGIN, SH4_AREA7_END, P0 | P1 | P2 | P3, MAP_MMIO, sh4_map(mem, SH4_AREA7_BEGIN, SH4_AREA7_END, P0 | P1 | P2 | P3 | P4, MAP_MMIO,
(mmio_read_cb)&sh4_area7_read, (mmio_write_cb)&sh4_area7_write, NULL, (mmio_read_cb)&sh4_area7_read, (mmio_write_cb)&sh4_area7_write, NULL,
NULL); NULL);
/* p4 */ /* p4. the unassigned regions have already been mapped to the external address
sh4_map(mem, SH4_P4_BEGIN, SH4_P4_END, P4, MAP_MMIO, space. instead of mapping the entire p4 area, selectively map each internal
region to avoid overwriting the existing mappings */
sh4_map(mem, SH4_SQ_BEGIN, SH4_SQ_END, P4, MAP_MMIO,
(mmio_read_cb)&sh4_p4_read, (mmio_write_cb)&sh4_p4_write, NULL, NULL);
sh4_map(mem, SH4_ICACHE_BEGIN, SH4_ICACHE_END, P4, MAP_MMIO,
(mmio_read_cb)&sh4_p4_read, (mmio_write_cb)&sh4_p4_write, NULL, NULL);
sh4_map(mem, SH4_ITLB_BEGIN, SH4_ITLB_END, P4, MAP_MMIO,
(mmio_read_cb)&sh4_p4_read, (mmio_write_cb)&sh4_p4_write, NULL, NULL);
sh4_map(mem, SH4_OCACHE_BEGIN, SH4_OCACHE_END, P4, MAP_MMIO,
(mmio_read_cb)&sh4_p4_read, (mmio_write_cb)&sh4_p4_write, NULL, NULL);
sh4_map(mem, SH4_UTLB_BEGIN, SH4_UTLB_END, P4, MAP_MMIO,
(mmio_read_cb)&sh4_p4_read, (mmio_write_cb)&sh4_p4_write, NULL, NULL); (mmio_read_cb)&sh4_p4_read, (mmio_write_cb)&sh4_p4_write, NULL, NULL);
return 1; return 1;
@ -512,8 +532,11 @@ uint8_t *mem_ram(struct memory *mem, uint32_t offset) {
int mem_init(struct memory *mem) { int mem_init(struct memory *mem) {
#ifdef HAVE_FASTMEM #ifdef HAVE_FASTMEM
/* create the shared memory object to back the physical memory */ /* create the shared memory object to back the physical memory. note, because
mem->shmem = create_shared_memory("/redream", PHYSICAL_SIZE, ACC_READWRITE); mmio regions also map this shared memory object when disabling permissions,
the object has to at least be the size of an entire mmio region */
size_t shmem_size = MAX(PHYSICAL_SIZE, SH4_AREA_SIZE);
mem->shmem = create_shared_memory("/redream", shmem_size, ACC_READWRITE);
if (mem->shmem == SHMEM_INVALID) { if (mem->shmem == SHMEM_INVALID) {
LOG_WARNING("mem_init failed to create shared memory object"); LOG_WARNING("mem_init failed to create shared memory object");

View File

@ -53,8 +53,6 @@ void sh4_p4_write(struct sh4 *sh4, uint32_t addr, uint32_t data,
sh4_ccn_ocache_write(sh4, addr - SH4_OCACHE_BEGIN, data, mask); sh4_ccn_ocache_write(sh4, addr - SH4_OCACHE_BEGIN, data, mask);
} else if (addr >= SH4_UTLB_BEGIN && addr <= SH4_UTLB_END) { } else if (addr >= SH4_UTLB_BEGIN && addr <= SH4_UTLB_END) {
sh4_mmu_utlb_write(sh4, addr - SH4_UTLB_BEGIN, data, mask); sh4_mmu_utlb_write(sh4, addr - SH4_UTLB_BEGIN, data, mask);
} else if (addr >= SH4_REG2_BEGIN && addr <= SH4_REG2_END) {
sh4_reg_write(sh4, addr - SH4_REG2_BEGIN, data, mask);
} else { } else {
LOG_FATAL("sh4_p4_write unexpected addr 0x%08x", addr); LOG_FATAL("sh4_p4_write unexpected addr 0x%08x", addr);
} }
@ -70,8 +68,6 @@ uint32_t sh4_p4_read(struct sh4 *sh4, uint32_t addr, uint32_t mask) {
return sh4_ccn_ocache_read(sh4, addr - SH4_OCACHE_BEGIN, mask); return sh4_ccn_ocache_read(sh4, addr - SH4_OCACHE_BEGIN, mask);
} else if (addr >= SH4_UTLB_BEGIN && addr <= SH4_UTLB_END) { } else if (addr >= SH4_UTLB_BEGIN && addr <= SH4_UTLB_END) {
return sh4_mmu_utlb_read(sh4, addr - SH4_UTLB_BEGIN, mask); return sh4_mmu_utlb_read(sh4, addr - SH4_UTLB_BEGIN, mask);
} else if (addr >= SH4_REG2_BEGIN && addr <= SH4_REG2_END) {
return sh4_reg_read(sh4, addr - SH4_REG2_BEGIN, mask);
} else { } else {
LOG_FATAL("sh4_p4_read unexpected addr 0x%08x", addr); LOG_FATAL("sh4_p4_read unexpected addr 0x%08x", addr);
} }

View File

@ -2,7 +2,8 @@
#define SH4_MEM_H #define SH4_MEM_H
/* clang-format off */ /* clang-format off */
#define SH4_ADDR_MASK 0x1fffffff #define SH4_AREA_SIZE 0x20000000
#define SH4_ADDR_MASK (SH4_AREA_SIZE-1)
/* area 0 */ /* area 0 */
#define SH4_AREA0_BEGIN 0x00000000 #define SH4_AREA0_BEGIN 0x00000000
@ -116,8 +117,6 @@
#define SH4_OCACHE_END 0xf5ffffff #define SH4_OCACHE_END 0xf5ffffff
#define SH4_UTLB_BEGIN 0xf6000000 #define SH4_UTLB_BEGIN 0xf6000000
#define SH4_UTLB_END 0xf7ffffff #define SH4_UTLB_END 0xf7ffffff
#define SH4_REG2_BEGIN 0xfc000000
#define SH4_REG2_END 0xffffffff
/* clang-format on */ /* clang-format on */
uint32_t sh4_area0_read(struct sh4 *sh4, uint32_t addr, uint32_t mask); uint32_t sh4_area0_read(struct sh4 *sh4, uint32_t addr, uint32_t mask);