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 821 the physical address */
822 822 #define IO_MEM_ROMD (1)
823 823 #define IO_MEM_SUBPAGE (2)
  824 +#define IO_MEM_SUBWIDTH (4)
824 825  
825 826 typedef void CPUWriteMemoryFunc(void *opaque, target_phys_addr_t addr, uint32_t value);
826 827 typedef uint32_t CPUReadMemoryFunc(void *opaque, target_phys_addr_t addr);
... ...
... ... @@ -163,8 +163,8 @@ static int tb_phys_invalidate_count;
163 163 #define SUBPAGE_IDX(addr) ((addr) & ~TARGET_PAGE_MASK)
164 164 typedef struct subpage_t {
165 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 168 void *opaque[TARGET_PAGE_SIZE];
169 169 } subpage_t;
170 170  
... ... @@ -2025,7 +2025,7 @@ void cpu_register_physical_memory(target_phys_addr_t start_addr,
2025 2025  
2026 2026 CHECK_SUBPAGE(addr, start_addr, start_addr2, end_addr, end_addr2,
2027 2027 need_subpage);
2028   - if (need_subpage) {
  2028 + if (need_subpage || phys_offset & IO_MEM_SUBWIDTH) {
2029 2029 if (!(orig_memory & IO_MEM_SUBPAGE)) {
2030 2030 subpage = subpage_init((addr & TARGET_PAGE_MASK),
2031 2031 &p->phys_offset, orig_memory);
... ... @@ -2053,7 +2053,7 @@ void cpu_register_physical_memory(target_phys_addr_t start_addr,
2053 2053 CHECK_SUBPAGE(addr, start_addr, start_addr2, end_addr,
2054 2054 end_addr2, need_subpage);
2055 2055  
2056   - if (need_subpage) {
  2056 + if (need_subpage || phys_offset & IO_MEM_SUBWIDTH) {
2057 2057 subpage = subpage_init((addr & TARGET_PAGE_MASK),
2058 2058 &p->phys_offset, IO_MEM_UNASSIGNED);
2059 2059 subpage_register(subpage, start_addr2, end_addr2,
... ... @@ -2308,7 +2308,6 @@ static CPUWriteMemoryFunc *watch_mem_write[3] = {
2308 2308 static inline uint32_t subpage_readlen (subpage_t *mmio, target_phys_addr_t addr,
2309 2309 unsigned int len)
2310 2310 {
2311   - CPUReadMemoryFunc **mem_read;
2312 2311 uint32_t ret;
2313 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 2316 printf("%s: subpage %p len %d addr " TARGET_FMT_plx " idx %d\n", __func__,
2318 2317 mmio, len, addr, idx);
2319 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 2321 return ret;
2324 2322 }
... ... @@ -2326,7 +2324,6 @@ static inline uint32_t subpage_readlen (subpage_t *mmio, target_phys_addr_t addr
2326 2324 static inline void subpage_writelen (subpage_t *mmio, target_phys_addr_t addr,
2327 2325 uint32_t value, unsigned int len)
2328 2326 {
2329   - CPUWriteMemoryFunc **mem_write;
2330 2327 unsigned int idx;
2331 2328  
2332 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 2331 printf("%s: subpage %p len %d addr " TARGET_FMT_plx " idx %d value %08x\n", __func__,
2335 2332 mmio, len, addr, idx, value);
2336 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 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 2404 int memory)
2409 2405 {
2410 2406 int idx, eidx;
  2407 + unsigned int i;
2411 2408  
2412 2409 if (start >= TARGET_PAGE_SIZE || end >= TARGET_PAGE_SIZE)
2413 2410 return -1;
... ... @@ -2419,8 +2416,12 @@ static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end,
2419 2416 #endif
2420 2417 memory >>= IO_MEM_SHIFT;
2421 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 2425 mmio->opaque[idx] = io_mem_opaque[memory];
2425 2426 }
2426 2427  
... ... @@ -2466,16 +2467,16 @@ static void io_mem_init(void)
2466 2467  
2467 2468 /* mem_read and mem_write are arrays of functions containing the
2468 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 2474 int cpu_register_io_memory(int io_index,
2474 2475 CPUReadMemoryFunc **mem_read,
2475 2476 CPUWriteMemoryFunc **mem_write,
2476 2477 void *opaque)
2477 2478 {
2478   - int i;
  2479 + int i, subwidth = 0;
2479 2480  
2480 2481 if (io_index <= 0) {
2481 2482 if (io_mem_nb >= IO_MEM_NB_ENTRIES)
... ... @@ -2487,11 +2488,13 @@ int cpu_register_io_memory(int io_index,
2487 2488 }
2488 2489  
2489 2490 for(i = 0;i < 3; i++) {
  2491 + if (!mem_read[i] || !mem_write[i])
  2492 + subwidth = IO_MEM_SUBWIDTH;
2490 2493 io_mem_read[io_index][i] = mem_read[i];
2491 2494 io_mem_write[io_index][i] = mem_write[i];
2492 2495 }
2493 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 2500 CPUWriteMemoryFunc **cpu_get_io_memory_write(int io_index)
... ...