Commit b854bc196f5c4b4e3299c0b0ee63cf828ece9e77

Authored by balrog
1 parent e616a7e8

Make accesses with wrong width also work as apparently real hardware allows them…

… when the fault is disabled.
Fix DMA register writes if target_phys_addr_t is 64-bit.
Make more functions static.
A timer hack to make PalmOS run in finite time (uses very short timer periods, much shorter than clocksource tick).
Re-calculate internal clock rates on start-up.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3527 c046a42c-6fe2-441c-8c8c-71466251a162
hw/omap.c
@@ -27,38 +27,51 @@ uint32_t omap_badwidth_read8(void *opaque, target_phys_addr_t addr) @@ -27,38 +27,51 @@ uint32_t omap_badwidth_read8(void *opaque, target_phys_addr_t addr)
27 uint8_t ret; 27 uint8_t ret;
28 28
29 OMAP_8B_REG(addr); 29 OMAP_8B_REG(addr);
30 - cpu_physical_memory_read(addr, &ret, 1); 30 + cpu_physical_memory_read(addr, (void *) &ret, 1);
31 return ret; 31 return ret;
32 } 32 }
33 33
34 void omap_badwidth_write8(void *opaque, target_phys_addr_t addr, 34 void omap_badwidth_write8(void *opaque, target_phys_addr_t addr,
35 uint32_t value) 35 uint32_t value)
36 { 36 {
  37 + uint8_t val8 = value;
  38 +
37 OMAP_8B_REG(addr); 39 OMAP_8B_REG(addr);
  40 + cpu_physical_memory_write(addr, (void *) &val8, 1);
38 } 41 }
39 42
40 uint32_t omap_badwidth_read16(void *opaque, target_phys_addr_t addr) 43 uint32_t omap_badwidth_read16(void *opaque, target_phys_addr_t addr)
41 { 44 {
  45 + uint16_t ret;
  46 +
42 OMAP_16B_REG(addr); 47 OMAP_16B_REG(addr);
43 - return 0; 48 + cpu_physical_memory_read(addr, (void *) &ret, 2);
  49 + return ret;
44 } 50 }
45 51
46 void omap_badwidth_write16(void *opaque, target_phys_addr_t addr, 52 void omap_badwidth_write16(void *opaque, target_phys_addr_t addr,
47 uint32_t value) 53 uint32_t value)
48 { 54 {
  55 + uint16_t val16 = value;
  56 +
49 OMAP_16B_REG(addr); 57 OMAP_16B_REG(addr);
  58 + cpu_physical_memory_write(addr, (void *) &val16, 2);
50 } 59 }
51 60
52 uint32_t omap_badwidth_read32(void *opaque, target_phys_addr_t addr) 61 uint32_t omap_badwidth_read32(void *opaque, target_phys_addr_t addr)
53 { 62 {
  63 + uint32_t ret;
  64 +
54 OMAP_32B_REG(addr); 65 OMAP_32B_REG(addr);
55 - return 0; 66 + cpu_physical_memory_read(addr, (void *) &ret, 4);
  67 + return ret;
56 } 68 }
57 69
58 void omap_badwidth_write32(void *opaque, target_phys_addr_t addr, 70 void omap_badwidth_write32(void *opaque, target_phys_addr_t addr,
59 uint32_t value) 71 uint32_t value)
60 { 72 {
61 OMAP_32B_REG(addr); 73 OMAP_32B_REG(addr);
  74 + cpu_physical_memory_write(addr, (void *) &value, 4);
62 } 75 }
63 76
64 /* Interrupt Handlers */ 77 /* Interrupt Handlers */
@@ -787,7 +800,7 @@ static int omap_dma_ch_reg_write(struct omap_dma_s *s, @@ -787,7 +800,7 @@ static int omap_dma_ch_reg_write(struct omap_dma_s *s,
787 800
788 case 0x0a: /* SYS_DMA_CSSA_U_CH0 */ 801 case 0x0a: /* SYS_DMA_CSSA_U_CH0 */
789 s->ch[ch].addr[0] &= 0x0000ffff; 802 s->ch[ch].addr[0] &= 0x0000ffff;
790 - s->ch[ch].addr[0] |= value << 16; 803 + s->ch[ch].addr[0] |= (uint32_t) value << 16;
791 break; 804 break;
792 805
793 case 0x0c: /* SYS_DMA_CDSA_L_CH0 */ 806 case 0x0c: /* SYS_DMA_CDSA_L_CH0 */
@@ -797,7 +810,7 @@ static int omap_dma_ch_reg_write(struct omap_dma_s *s, @@ -797,7 +810,7 @@ static int omap_dma_ch_reg_write(struct omap_dma_s *s,
797 810
798 case 0x0e: /* SYS_DMA_CDSA_U_CH0 */ 811 case 0x0e: /* SYS_DMA_CDSA_U_CH0 */
799 s->ch[ch].addr[1] &= 0x0000ffff; 812 s->ch[ch].addr[1] &= 0x0000ffff;
800 - s->ch[ch].addr[1] |= value << 16; 813 + s->ch[ch].addr[1] |= (uint32_t) value << 16;
801 break; 814 break;
802 815
803 case 0x10: /* SYS_DMA_CEN_CH0 */ 816 case 0x10: /* SYS_DMA_CEN_CH0 */
@@ -1033,37 +1046,37 @@ struct omap_dma_s *omap_dma_init(target_phys_addr_t base, @@ -1033,37 +1046,37 @@ struct omap_dma_s *omap_dma_init(target_phys_addr_t base,
1033 } 1046 }
1034 1047
1035 /* DMA ports */ 1048 /* DMA ports */
1036 -int omap_validate_emiff_addr(struct omap_mpu_state_s *s, 1049 +static int omap_validate_emiff_addr(struct omap_mpu_state_s *s,
1037 target_phys_addr_t addr) 1050 target_phys_addr_t addr)
1038 { 1051 {
1039 return addr >= OMAP_EMIFF_BASE && addr < OMAP_EMIFF_BASE + s->sdram_size; 1052 return addr >= OMAP_EMIFF_BASE && addr < OMAP_EMIFF_BASE + s->sdram_size;
1040 } 1053 }
1041 1054
1042 -int omap_validate_emifs_addr(struct omap_mpu_state_s *s, 1055 +static int omap_validate_emifs_addr(struct omap_mpu_state_s *s,
1043 target_phys_addr_t addr) 1056 target_phys_addr_t addr)
1044 { 1057 {
1045 return addr >= OMAP_EMIFS_BASE && addr < OMAP_EMIFF_BASE; 1058 return addr >= OMAP_EMIFS_BASE && addr < OMAP_EMIFF_BASE;
1046 } 1059 }
1047 1060
1048 -int omap_validate_imif_addr(struct omap_mpu_state_s *s, 1061 +static int omap_validate_imif_addr(struct omap_mpu_state_s *s,
1049 target_phys_addr_t addr) 1062 target_phys_addr_t addr)
1050 { 1063 {
1051 return addr >= OMAP_IMIF_BASE && addr < OMAP_IMIF_BASE + s->sram_size; 1064 return addr >= OMAP_IMIF_BASE && addr < OMAP_IMIF_BASE + s->sram_size;
1052 } 1065 }
1053 1066
1054 -int omap_validate_tipb_addr(struct omap_mpu_state_s *s, 1067 +static int omap_validate_tipb_addr(struct omap_mpu_state_s *s,
1055 target_phys_addr_t addr) 1068 target_phys_addr_t addr)
1056 { 1069 {
1057 return addr >= 0xfffb0000 && addr < 0xffff0000; 1070 return addr >= 0xfffb0000 && addr < 0xffff0000;
1058 } 1071 }
1059 1072
1060 -int omap_validate_local_addr(struct omap_mpu_state_s *s, 1073 +static int omap_validate_local_addr(struct omap_mpu_state_s *s,
1061 target_phys_addr_t addr) 1074 target_phys_addr_t addr)
1062 { 1075 {
1063 return addr >= OMAP_LOCALBUS_BASE && addr < OMAP_LOCALBUS_BASE + 0x1000000; 1076 return addr >= OMAP_LOCALBUS_BASE && addr < OMAP_LOCALBUS_BASE + 0x1000000;
1064 } 1077 }
1065 1078
1066 -int omap_validate_tipb_mpui_addr(struct omap_mpu_state_s *s, 1079 +static int omap_validate_tipb_mpui_addr(struct omap_mpu_state_s *s,
1067 target_phys_addr_t addr) 1080 target_phys_addr_t addr)
1068 { 1081 {
1069 return addr >= 0xe1010000 && addr < 0xe1020004; 1082 return addr >= 0xe1010000 && addr < 0xe1020004;
@@ -1110,9 +1123,23 @@ static inline void omap_timer_update(struct omap_mpu_timer_s *timer) @@ -1110,9 +1123,23 @@ static inline void omap_timer_update(struct omap_mpu_timer_s *timer)
1110 1123
1111 if (timer->enable && timer->st && timer->rate) { 1124 if (timer->enable && timer->st && timer->rate) {
1112 timer->val = timer->reset_val; /* Should skip this on clk enable */ 1125 timer->val = timer->reset_val; /* Should skip this on clk enable */
1113 - expires = timer->time + muldiv64(timer->val << (timer->ptv + 1), 1126 + expires = muldiv64(timer->val << (timer->ptv + 1),
1114 ticks_per_sec, timer->rate); 1127 ticks_per_sec, timer->rate);
1115 - qemu_mod_timer(timer->timer, expires); 1128 +
  1129 + /* If timer expiry would be sooner than in about 1 ms and
  1130 + * auto-reload isn't set, then fire immediately. This is a hack
  1131 + * to make systems like PalmOS run in acceptable time. PalmOS
  1132 + * sets the interval to a very low value and polls the status bit
  1133 + * in a busy loop when it wants to sleep just a couple of CPU
  1134 + * ticks. */
  1135 + if (expires > (ticks_per_sec >> 10) || timer->ar)
  1136 + qemu_mod_timer(timer->timer, timer->time + expires);
  1137 + else {
  1138 + timer->val = 0;
  1139 + timer->st = 0;
  1140 + if (timer->it_ena)
  1141 + qemu_irq_raise(timer->irq);
  1142 + }
1116 } else 1143 } else
1117 qemu_del_timer(timer->timer); 1144 qemu_del_timer(timer->timer);
1118 } 1145 }
@@ -3502,12 +3529,11 @@ static void omap_pwl_init(target_phys_addr_t base, struct omap_mpu_state_s *s, @@ -3502,12 +3529,11 @@ static void omap_pwl_init(target_phys_addr_t base, struct omap_mpu_state_s *s,
3502 { 3529 {
3503 int iomemtype; 3530 int iomemtype;
3504 3531
3505 - s->pwl.base = base;  
3506 omap_pwl_reset(s); 3532 omap_pwl_reset(s);
3507 3533
3508 iomemtype = cpu_register_io_memory(0, omap_pwl_readfn, 3534 iomemtype = cpu_register_io_memory(0, omap_pwl_readfn,
3509 omap_pwl_writefn, s); 3535 omap_pwl_writefn, s);
3510 - cpu_register_physical_memory(s->pwl.base, 0x800, iomemtype); 3536 + cpu_register_physical_memory(base, 0x800, iomemtype);
3511 3537
3512 omap_clk_adduser(clk, qemu_allocate_irqs(omap_pwl_clk_update, s, 1)[0]); 3538 omap_clk_adduser(clk, qemu_allocate_irqs(omap_pwl_clk_update, s, 1)[0]);
3513 } 3539 }
@@ -3597,13 +3623,12 @@ static void omap_pwt_init(target_phys_addr_t base, struct omap_mpu_state_s *s, @@ -3597,13 +3623,12 @@ static void omap_pwt_init(target_phys_addr_t base, struct omap_mpu_state_s *s,
3597 { 3623 {
3598 int iomemtype; 3624 int iomemtype;
3599 3625
3600 - s->pwt.base = base;  
3601 s->pwt.clk = clk; 3626 s->pwt.clk = clk;
3602 omap_pwt_reset(s); 3627 omap_pwt_reset(s);
3603 3628
3604 iomemtype = cpu_register_io_memory(0, omap_pwt_readfn, 3629 iomemtype = cpu_register_io_memory(0, omap_pwt_readfn,
3605 omap_pwt_writefn, s); 3630 omap_pwt_writefn, s);
3606 - cpu_register_physical_memory(s->pwt.base, 0x800, iomemtype); 3631 + cpu_register_physical_memory(base, 0x800, iomemtype);
3607 } 3632 }
3608 3633
3609 /* Real-time Clock module */ 3634 /* Real-time Clock module */
@@ -4207,6 +4232,7 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size, @@ -4207,6 +4232,7 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
4207 * USB Host fffba000 - fffba7ff 4232 * USB Host fffba000 - fffba7ff
4208 * FAC fffba800 - fffbafff 4233 * FAC fffba800 - fffbafff
4209 * HDQ/1-Wire fffbc000 - fffbc7ff 4234 * HDQ/1-Wire fffbc000 - fffbc7ff
  4235 + * TIPB switches fffbc800 - fffbcfff
4210 * LED1 fffbd000 - fffbd7ff 4236 * LED1 fffbd000 - fffbd7ff
4211 * LED2 fffbd800 - fffbdfff 4237 * LED2 fffbd800 - fffbdfff
4212 * Mailbox fffcf000 - fffcf7ff 4238 * Mailbox fffcf000 - fffcf7ff
hw/omap.h
@@ -646,14 +646,23 @@ void omap_badwidth_write32(void *opaque, target_phys_addr_t addr, @@ -646,14 +646,23 @@ void omap_badwidth_write32(void *opaque, target_phys_addr_t addr,
646 # define OMAP_RO_REG(paddr) \ 646 # define OMAP_RO_REG(paddr) \
647 printf("%s: Read-only register " OMAP_FMT_plx "\n", \ 647 printf("%s: Read-only register " OMAP_FMT_plx "\n", \
648 __FUNCTION__, paddr) 648 __FUNCTION__, paddr)
649 -# define OMAP_8B_REG(paddr) \ 649 +
  650 +# define TCMI_VERBOSE 1
  651 +
  652 +# ifdef TCMI_VERBOSE
  653 +# define OMAP_8B_REG(paddr) \
650 printf("%s: 8-bit register " OMAP_FMT_plx "\n", \ 654 printf("%s: 8-bit register " OMAP_FMT_plx "\n", \
651 __FUNCTION__, paddr) 655 __FUNCTION__, paddr)
652 -# define OMAP_16B_REG(paddr) \ 656 +# define OMAP_16B_REG(paddr) \
653 printf("%s: 16-bit register " OMAP_FMT_plx "\n", \ 657 printf("%s: 16-bit register " OMAP_FMT_plx "\n", \
654 __FUNCTION__, paddr) 658 __FUNCTION__, paddr)
655 -# define OMAP_32B_REG(paddr) \ 659 +# define OMAP_32B_REG(paddr) \
656 printf("%s: 32-bit register " OMAP_FMT_plx "\n", \ 660 printf("%s: 32-bit register " OMAP_FMT_plx "\n", \
657 __FUNCTION__, paddr) 661 __FUNCTION__, paddr)
  662 +# else
  663 +# define OMAP_8B_REG(paddr)
  664 +# define OMAP_16B_REG(paddr)
  665 +# define OMAP_32B_REG(paddr)
  666 +# endif
658 667
659 #endif /* hw_omap_h */ 668 #endif /* hw_omap_h */
hw/omap1_clk.c
@@ -742,4 +742,8 @@ void omap_clk_init(struct omap_mpu_state_s *mpu) @@ -742,4 +742,8 @@ void omap_clk_init(struct omap_mpu_state_s *mpu)
742 j->multiplier = j->multiplier ?: 1; 742 j->multiplier = j->multiplier ?: 1;
743 j ++; 743 j ++;
744 } 744 }
  745 + for (j = mpu->clks; count --; j ++) {
  746 + omap_clk_update(j);
  747 + omap_clk_rate_update(j);
  748 + }
745 } 749 }