Commit 4254fab8f96ecffebf204ff34c8e7eac7a3e0aed

Authored by blueswir1
1 parent 0b09be2b

Support for registering address space only for some access widths


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3879 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 2 changed files with 22 additions and 18 deletions
cpu-all.h
@@ -821,6 +821,7 @@ extern uint8_t *phys_ram_dirty; @@ -821,6 +821,7 @@ extern uint8_t *phys_ram_dirty;
821 the physical address */ 821 the physical address */
822 #define IO_MEM_ROMD (1) 822 #define IO_MEM_ROMD (1)
823 #define IO_MEM_SUBPAGE (2) 823 #define IO_MEM_SUBPAGE (2)
  824 +#define IO_MEM_SUBWIDTH (4)
824 825
825 typedef void CPUWriteMemoryFunc(void *opaque, target_phys_addr_t addr, uint32_t value); 826 typedef void CPUWriteMemoryFunc(void *opaque, target_phys_addr_t addr, uint32_t value);
826 typedef uint32_t CPUReadMemoryFunc(void *opaque, target_phys_addr_t addr); 827 typedef uint32_t CPUReadMemoryFunc(void *opaque, target_phys_addr_t addr);
@@ -163,8 +163,8 @@ static int tb_phys_invalidate_count; @@ -163,8 +163,8 @@ static int tb_phys_invalidate_count;
163 #define SUBPAGE_IDX(addr) ((addr) & ~TARGET_PAGE_MASK) 163 #define SUBPAGE_IDX(addr) ((addr) & ~TARGET_PAGE_MASK)
164 typedef struct subpage_t { 164 typedef struct subpage_t {
165 target_phys_addr_t base; 165 target_phys_addr_t base;
166 - CPUReadMemoryFunc **mem_read[TARGET_PAGE_SIZE];  
167 - CPUWriteMemoryFunc **mem_write[TARGET_PAGE_SIZE]; 166 + CPUReadMemoryFunc *mem_read[TARGET_PAGE_SIZE][4];
  167 + CPUWriteMemoryFunc *mem_write[TARGET_PAGE_SIZE][4];
168 void *opaque[TARGET_PAGE_SIZE]; 168 void *opaque[TARGET_PAGE_SIZE];
169 } subpage_t; 169 } subpage_t;
170 170
@@ -2025,7 +2025,7 @@ void cpu_register_physical_memory(target_phys_addr_t start_addr, @@ -2025,7 +2025,7 @@ void cpu_register_physical_memory(target_phys_addr_t start_addr,
2025 2025
2026 CHECK_SUBPAGE(addr, start_addr, start_addr2, end_addr, end_addr2, 2026 CHECK_SUBPAGE(addr, start_addr, start_addr2, end_addr, end_addr2,
2027 need_subpage); 2027 need_subpage);
2028 - if (need_subpage) { 2028 + if (need_subpage || phys_offset & IO_MEM_SUBWIDTH) {
2029 if (!(orig_memory & IO_MEM_SUBPAGE)) { 2029 if (!(orig_memory & IO_MEM_SUBPAGE)) {
2030 subpage = subpage_init((addr & TARGET_PAGE_MASK), 2030 subpage = subpage_init((addr & TARGET_PAGE_MASK),
2031 &p->phys_offset, orig_memory); 2031 &p->phys_offset, orig_memory);
@@ -2053,7 +2053,7 @@ void cpu_register_physical_memory(target_phys_addr_t start_addr, @@ -2053,7 +2053,7 @@ void cpu_register_physical_memory(target_phys_addr_t start_addr,
2053 CHECK_SUBPAGE(addr, start_addr, start_addr2, end_addr, 2053 CHECK_SUBPAGE(addr, start_addr, start_addr2, end_addr,
2054 end_addr2, need_subpage); 2054 end_addr2, need_subpage);
2055 2055
2056 - if (need_subpage) { 2056 + if (need_subpage || phys_offset & IO_MEM_SUBWIDTH) {
2057 subpage = subpage_init((addr & TARGET_PAGE_MASK), 2057 subpage = subpage_init((addr & TARGET_PAGE_MASK),
2058 &p->phys_offset, IO_MEM_UNASSIGNED); 2058 &p->phys_offset, IO_MEM_UNASSIGNED);
2059 subpage_register(subpage, start_addr2, end_addr2, 2059 subpage_register(subpage, start_addr2, end_addr2,
@@ -2308,7 +2308,6 @@ static CPUWriteMemoryFunc *watch_mem_write[3] = { @@ -2308,7 +2308,6 @@ static CPUWriteMemoryFunc *watch_mem_write[3] = {
2308 static inline uint32_t subpage_readlen (subpage_t *mmio, target_phys_addr_t addr, 2308 static inline uint32_t subpage_readlen (subpage_t *mmio, target_phys_addr_t addr,
2309 unsigned int len) 2309 unsigned int len)
2310 { 2310 {
2311 - CPUReadMemoryFunc **mem_read;  
2312 uint32_t ret; 2311 uint32_t ret;
2313 unsigned int idx; 2312 unsigned int idx;
2314 2313
@@ -2317,8 +2316,7 @@ static inline uint32_t subpage_readlen (subpage_t *mmio, target_phys_addr_t addr @@ -2317,8 +2316,7 @@ static inline uint32_t subpage_readlen (subpage_t *mmio, target_phys_addr_t addr
2317 printf("%s: subpage %p len %d addr " TARGET_FMT_plx " idx %d\n", __func__, 2316 printf("%s: subpage %p len %d addr " TARGET_FMT_plx " idx %d\n", __func__,
2318 mmio, len, addr, idx); 2317 mmio, len, addr, idx);
2319 #endif 2318 #endif
2320 - mem_read = mmio->mem_read[idx];  
2321 - ret = (*mem_read[len])(mmio->opaque[idx], addr); 2319 + ret = (*mmio->mem_read[idx][len])(mmio->opaque[idx], addr);
2322 2320
2323 return ret; 2321 return ret;
2324 } 2322 }
@@ -2326,7 +2324,6 @@ static inline uint32_t subpage_readlen (subpage_t *mmio, target_phys_addr_t addr @@ -2326,7 +2324,6 @@ static inline uint32_t subpage_readlen (subpage_t *mmio, target_phys_addr_t addr
2326 static inline void subpage_writelen (subpage_t *mmio, target_phys_addr_t addr, 2324 static inline void subpage_writelen (subpage_t *mmio, target_phys_addr_t addr,
2327 uint32_t value, unsigned int len) 2325 uint32_t value, unsigned int len)
2328 { 2326 {
2329 - CPUWriteMemoryFunc **mem_write;  
2330 unsigned int idx; 2327 unsigned int idx;
2331 2328
2332 idx = SUBPAGE_IDX(addr - mmio->base); 2329 idx = SUBPAGE_IDX(addr - mmio->base);
@@ -2334,8 +2331,7 @@ static inline void subpage_writelen (subpage_t *mmio, target_phys_addr_t addr, @@ -2334,8 +2331,7 @@ static inline void subpage_writelen (subpage_t *mmio, target_phys_addr_t addr,
2334 printf("%s: subpage %p len %d addr " TARGET_FMT_plx " idx %d value %08x\n", __func__, 2331 printf("%s: subpage %p len %d addr " TARGET_FMT_plx " idx %d value %08x\n", __func__,
2335 mmio, len, addr, idx, value); 2332 mmio, len, addr, idx, value);
2336 #endif 2333 #endif
2337 - mem_write = mmio->mem_write[idx];  
2338 - (*mem_write[len])(mmio->opaque[idx], addr, value); 2334 + (*mmio->mem_write[idx][len])(mmio->opaque[idx], addr, value);
2339 } 2335 }
2340 2336
2341 static uint32_t subpage_readb (void *opaque, target_phys_addr_t addr) 2337 static uint32_t subpage_readb (void *opaque, target_phys_addr_t addr)
@@ -2408,6 +2404,7 @@ static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end, @@ -2408,6 +2404,7 @@ static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end,
2408 int memory) 2404 int memory)
2409 { 2405 {
2410 int idx, eidx; 2406 int idx, eidx;
  2407 + unsigned int i;
2411 2408
2412 if (start >= TARGET_PAGE_SIZE || end >= TARGET_PAGE_SIZE) 2409 if (start >= TARGET_PAGE_SIZE || end >= TARGET_PAGE_SIZE)
2413 return -1; 2410 return -1;
@@ -2419,8 +2416,12 @@ static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end, @@ -2419,8 +2416,12 @@ static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end,
2419 #endif 2416 #endif
2420 memory >>= IO_MEM_SHIFT; 2417 memory >>= IO_MEM_SHIFT;
2421 for (; idx <= eidx; idx++) { 2418 for (; idx <= eidx; idx++) {
2422 - mmio->mem_read[idx] = io_mem_read[memory];  
2423 - mmio->mem_write[idx] = io_mem_write[memory]; 2419 + for (i = 0; i < 4; i++) {
  2420 + if (io_mem_read[memory][i])
  2421 + mmio->mem_read[idx][i] = io_mem_read[memory][i];
  2422 + if (io_mem_write[memory][i])
  2423 + mmio->mem_write[idx][i] = io_mem_write[memory][i];
  2424 + }
2424 mmio->opaque[idx] = io_mem_opaque[memory]; 2425 mmio->opaque[idx] = io_mem_opaque[memory];
2425 } 2426 }
2426 2427
@@ -2466,16 +2467,16 @@ static void io_mem_init(void) @@ -2466,16 +2467,16 @@ static void io_mem_init(void)
2466 2467
2467 /* mem_read and mem_write are arrays of functions containing the 2468 /* mem_read and mem_write are arrays of functions containing the
2468 function to access byte (index 0), word (index 1) and dword (index 2469 function to access byte (index 0), word (index 1) and dword (index
2469 - 2). All functions must be supplied. If io_index is non zero, the  
2470 - corresponding io zone is modified. If it is zero, a new io zone is  
2471 - allocated. The return value can be used with  
2472 - cpu_register_physical_memory(). (-1) is returned if error. */ 2470 + 2). If io_index is non zero, the corresponding io zone is
  2471 + modified. If it is zero, a new io zone is allocated. The return
  2472 + value can be used with cpu_register_physical_memory(). (-1) is
  2473 + returned if error. */
2473 int cpu_register_io_memory(int io_index, 2474 int cpu_register_io_memory(int io_index,
2474 CPUReadMemoryFunc **mem_read, 2475 CPUReadMemoryFunc **mem_read,
2475 CPUWriteMemoryFunc **mem_write, 2476 CPUWriteMemoryFunc **mem_write,
2476 void *opaque) 2477 void *opaque)
2477 { 2478 {
2478 - int i; 2479 + int i, subwidth = 0;
2479 2480
2480 if (io_index <= 0) { 2481 if (io_index <= 0) {
2481 if (io_mem_nb >= IO_MEM_NB_ENTRIES) 2482 if (io_mem_nb >= IO_MEM_NB_ENTRIES)
@@ -2487,11 +2488,13 @@ int cpu_register_io_memory(int io_index, @@ -2487,11 +2488,13 @@ int cpu_register_io_memory(int io_index,
2487 } 2488 }
2488 2489
2489 for(i = 0;i < 3; i++) { 2490 for(i = 0;i < 3; i++) {
  2491 + if (!mem_read[i] || !mem_write[i])
  2492 + subwidth = IO_MEM_SUBWIDTH;
2490 io_mem_read[io_index][i] = mem_read[i]; 2493 io_mem_read[io_index][i] = mem_read[i];
2491 io_mem_write[io_index][i] = mem_write[i]; 2494 io_mem_write[io_index][i] = mem_write[i];
2492 } 2495 }
2493 io_mem_opaque[io_index] = opaque; 2496 io_mem_opaque[io_index] = opaque;
2494 - return io_index << IO_MEM_SHIFT; 2497 + return (io_index << IO_MEM_SHIFT) | subwidth;
2495 } 2498 }
2496 2499
2497 CPUWriteMemoryFunc **cpu_get_io_memory_write(int io_index) 2500 CPUWriteMemoryFunc **cpu_get_io_memory_write(int io_index)