Commit 5c16736a371525e1bafd1941b0d9a83c84cb0702

Authored by balrog
1 parent 486579de

SH4: Eliminate P4 to A7 mangling (Takashi YOSHII).

Main purpose of this is to delete
       *physical = address & 0x1fffffff;
at target-sh4/helper.c:449, using new mmio rule introduced by #5849
This masking is a nice trick to realize P4/A7 duality of SH registers.
But, IMHO, it is logically wrong.

Most of SH4 cpu control registers in P4 area(0xfc000000...0xffffffff) have
one more address called A7 which is usually P4 address with upper 3bits masked.
This is an address only appears in TLB's physical address part.

Current code use trick writing drivers as if they are really in A7
(that's why you see many *_A7 in hw/sh*.c), and using translation P4 to A7.

Signed-off-by: Takashi YOSHII <takasi-y@ops.dti.ne.jp>
Signed-off-by: Andrzej Zaborowski <andrew.zaborowski@intel.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5935 c046a42c-6fe2-441c-8c8c-71466251a162
@@ -4,6 +4,9 @@ @@ -4,6 +4,9 @@
4 4
5 #include "sh_intc.h" 5 #include "sh_intc.h"
6 6
  7 +#define A7ADDR(x) ((x) & 0x1fffffff)
  8 +#define P4ADDR(x) ((x) | 0xe0000000)
  9 +
7 /* sh7750.c */ 10 /* sh7750.c */
8 struct SH7750State; 11 struct SH7750State;
9 12
hw/sh7750.c
@@ -683,10 +683,16 @@ SH7750State *sh7750_init(CPUSH4State * cpu) @@ -683,10 +683,16 @@ SH7750State *sh7750_init(CPUSH4State * cpu)
683 sh7750_mem_write, s); 683 sh7750_mem_write, s);
684 cpu_register_physical_memory_offset(0x1f000000, 0x1000, 684 cpu_register_physical_memory_offset(0x1f000000, 0x1000,
685 sh7750_io_memory, 0x1f000000); 685 sh7750_io_memory, 0x1f000000);
  686 + cpu_register_physical_memory_offset(0xff000000, 0x1000,
  687 + sh7750_io_memory, 0x1f000000);
686 cpu_register_physical_memory_offset(0x1f800000, 0x1000, 688 cpu_register_physical_memory_offset(0x1f800000, 0x1000,
687 sh7750_io_memory, 0x1f800000); 689 sh7750_io_memory, 0x1f800000);
  690 + cpu_register_physical_memory_offset(0xff800000, 0x1000,
  691 + sh7750_io_memory, 0x1f800000);
688 cpu_register_physical_memory_offset(0x1fc00000, 0x1000, 692 cpu_register_physical_memory_offset(0x1fc00000, 0x1000,
689 sh7750_io_memory, 0x1fc00000); 693 sh7750_io_memory, 0x1fc00000);
  694 + cpu_register_physical_memory_offset(0xffc00000, 0x1000,
  695 + sh7750_io_memory, 0x1fc00000);
690 696
691 sh7750_mm_cache_and_tlb = cpu_register_io_memory(0, 697 sh7750_mm_cache_and_tlb = cpu_register_io_memory(0,
692 sh7750_mmct_read, 698 sh7750_mmct_read,
hw/sh_intc.c
@@ -307,9 +307,12 @@ struct intc_source *sh_intc_source(struct intc_desc *desc, intc_enum id) @@ -307,9 +307,12 @@ struct intc_source *sh_intc_source(struct intc_desc *desc, intc_enum id)
307 static void sh_intc_register(struct intc_desc *desc, 307 static void sh_intc_register(struct intc_desc *desc,
308 unsigned long address) 308 unsigned long address)
309 { 309 {
310 - if (address)  
311 - cpu_register_physical_memory_offset(INTC_A7(address), 4, 310 + if (address) {
  311 + cpu_register_physical_memory_offset(P4ADDR(address), 4,
312 desc->iomemtype, INTC_A7(address)); 312 desc->iomemtype, INTC_A7(address));
  313 + cpu_register_physical_memory_offset(A7ADDR(address), 4,
  314 + desc->iomemtype, INTC_A7(address));
  315 + }
313 } 316 }
314 317
315 static void sh_intc_register_source(struct intc_desc *desc, 318 static void sh_intc_register_source(struct intc_desc *desc,
hw/sh_serial.c
@@ -399,7 +399,8 @@ void sh_serial_init (target_phys_addr_t base, int feat, @@ -399,7 +399,8 @@ void sh_serial_init (target_phys_addr_t base, int feat,
399 399
400 s_io_memory = cpu_register_io_memory(0, sh_serial_readfn, 400 s_io_memory = cpu_register_io_memory(0, sh_serial_readfn,
401 sh_serial_writefn, s); 401 sh_serial_writefn, s);
402 - cpu_register_physical_memory(base, 0x28, s_io_memory); 402 + cpu_register_physical_memory(P4ADDR(base), 0x28, s_io_memory);
  403 + cpu_register_physical_memory(A7ADDR(base), 0x28, s_io_memory);
403 404
404 s->chr = chr; 405 s->chr = chr;
405 406
hw/sh_timer.c
@@ -320,6 +320,7 @@ void tmu012_init(target_phys_addr_t base, int feat, uint32_t freq, @@ -320,6 +320,7 @@ void tmu012_init(target_phys_addr_t base, int feat, uint32_t freq,
320 ch2_irq0); /* ch2_irq1 not supported */ 320 ch2_irq0); /* ch2_irq1 not supported */
321 iomemtype = cpu_register_io_memory(0, tmu012_readfn, 321 iomemtype = cpu_register_io_memory(0, tmu012_readfn,
322 tmu012_writefn, s); 322 tmu012_writefn, s);
323 - cpu_register_physical_memory(base, 0x00001000, iomemtype); 323 + cpu_register_physical_memory(P4ADDR(base), 0x00001000, iomemtype);
  324 + cpu_register_physical_memory(A7ADDR(base), 0x00001000, iomemtype);
324 /* ??? Save/restore. */ 325 /* ??? Save/restore. */
325 } 326 }
target-sh4/helper.c
@@ -439,19 +439,7 @@ int get_physical_address(CPUState * env, target_ulong * physical, @@ -439,19 +439,7 @@ int get_physical_address(CPUState * env, target_ulong * physical,
439 if (address >= 0x80000000 && address < 0xc0000000) { 439 if (address >= 0x80000000 && address < 0xc0000000) {
440 /* Mask upper 3 bits for P1 and P2 areas */ 440 /* Mask upper 3 bits for P1 and P2 areas */
441 *physical = address & 0x1fffffff; 441 *physical = address & 0x1fffffff;
442 - } else if (address >= 0xfd000000 && address < 0xfe000000) {  
443 - /* PCI memory space */  
444 - *physical = address;  
445 - } else if (address >= 0xfc000000) {  
446 - /*  
447 - * Mask upper 3 bits for control registers in P4 area,  
448 - * to unify access to control registers via P0-P3 area.  
449 - * The addresses for cache store queue, TLB address array  
450 - * are not masked.  
451 - */  
452 - *physical = address & 0x1fffffff;  
453 } else { 442 } else {
454 - /* access to cache store queue, or TLB address array. */  
455 *physical = address; 443 *physical = address;
456 } 444 }
457 *prot = PAGE_READ | PAGE_WRITE; 445 *prot = PAGE_READ | PAGE_WRITE;