Commit b854bc196f5c4b4e3299c0b0ee63cf828ece9e77
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
Showing
3 changed files
with
59 additions
and
20 deletions
hw/omap.c
... | ... | @@ -27,38 +27,51 @@ uint32_t omap_badwidth_read8(void *opaque, target_phys_addr_t addr) |
27 | 27 | uint8_t ret; |
28 | 28 | |
29 | 29 | OMAP_8B_REG(addr); |
30 | - cpu_physical_memory_read(addr, &ret, 1); | |
30 | + cpu_physical_memory_read(addr, (void *) &ret, 1); | |
31 | 31 | return ret; |
32 | 32 | } |
33 | 33 | |
34 | 34 | void omap_badwidth_write8(void *opaque, target_phys_addr_t addr, |
35 | 35 | uint32_t value) |
36 | 36 | { |
37 | + uint8_t val8 = value; | |
38 | + | |
37 | 39 | OMAP_8B_REG(addr); |
40 | + cpu_physical_memory_write(addr, (void *) &val8, 1); | |
38 | 41 | } |
39 | 42 | |
40 | 43 | uint32_t omap_badwidth_read16(void *opaque, target_phys_addr_t addr) |
41 | 44 | { |
45 | + uint16_t ret; | |
46 | + | |
42 | 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 | 52 | void omap_badwidth_write16(void *opaque, target_phys_addr_t addr, |
47 | 53 | uint32_t value) |
48 | 54 | { |
55 | + uint16_t val16 = value; | |
56 | + | |
49 | 57 | OMAP_16B_REG(addr); |
58 | + cpu_physical_memory_write(addr, (void *) &val16, 2); | |
50 | 59 | } |
51 | 60 | |
52 | 61 | uint32_t omap_badwidth_read32(void *opaque, target_phys_addr_t addr) |
53 | 62 | { |
63 | + uint32_t ret; | |
64 | + | |
54 | 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 | 70 | void omap_badwidth_write32(void *opaque, target_phys_addr_t addr, |
59 | 71 | uint32_t value) |
60 | 72 | { |
61 | 73 | OMAP_32B_REG(addr); |
74 | + cpu_physical_memory_write(addr, (void *) &value, 4); | |
62 | 75 | } |
63 | 76 | |
64 | 77 | /* Interrupt Handlers */ |
... | ... | @@ -787,7 +800,7 @@ static int omap_dma_ch_reg_write(struct omap_dma_s *s, |
787 | 800 | |
788 | 801 | case 0x0a: /* SYS_DMA_CSSA_U_CH0 */ |
789 | 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 | 804 | break; |
792 | 805 | |
793 | 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 | 810 | |
798 | 811 | case 0x0e: /* SYS_DMA_CDSA_U_CH0 */ |
799 | 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 | 814 | break; |
802 | 815 | |
803 | 816 | case 0x10: /* SYS_DMA_CEN_CH0 */ |
... | ... | @@ -1033,37 +1046,37 @@ struct omap_dma_s *omap_dma_init(target_phys_addr_t base, |
1033 | 1046 | } |
1034 | 1047 | |
1035 | 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 | 1050 | target_phys_addr_t addr) |
1038 | 1051 | { |
1039 | 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 | 1056 | target_phys_addr_t addr) |
1044 | 1057 | { |
1045 | 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 | 1062 | target_phys_addr_t addr) |
1050 | 1063 | { |
1051 | 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 | 1068 | target_phys_addr_t addr) |
1056 | 1069 | { |
1057 | 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 | 1074 | target_phys_addr_t addr) |
1062 | 1075 | { |
1063 | 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 | 1080 | target_phys_addr_t addr) |
1068 | 1081 | { |
1069 | 1082 | return addr >= 0xe1010000 && addr < 0xe1020004; |
... | ... | @@ -1110,9 +1123,23 @@ static inline void omap_timer_update(struct omap_mpu_timer_s *timer) |
1110 | 1123 | |
1111 | 1124 | if (timer->enable && timer->st && timer->rate) { |
1112 | 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 | 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 | 1143 | } else |
1117 | 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 | 3529 | { |
3503 | 3530 | int iomemtype; |
3504 | 3531 | |
3505 | - s->pwl.base = base; | |
3506 | 3532 | omap_pwl_reset(s); |
3507 | 3533 | |
3508 | 3534 | iomemtype = cpu_register_io_memory(0, omap_pwl_readfn, |
3509 | 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 | 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 | 3623 | { |
3598 | 3624 | int iomemtype; |
3599 | 3625 | |
3600 | - s->pwt.base = base; | |
3601 | 3626 | s->pwt.clk = clk; |
3602 | 3627 | omap_pwt_reset(s); |
3603 | 3628 | |
3604 | 3629 | iomemtype = cpu_register_io_memory(0, omap_pwt_readfn, |
3605 | 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 | 3634 | /* Real-time Clock module */ |
... | ... | @@ -4207,6 +4232,7 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size, |
4207 | 4232 | * USB Host fffba000 - fffba7ff |
4208 | 4233 | * FAC fffba800 - fffbafff |
4209 | 4234 | * HDQ/1-Wire fffbc000 - fffbc7ff |
4235 | + * TIPB switches fffbc800 - fffbcfff | |
4210 | 4236 | * LED1 fffbd000 - fffbd7ff |
4211 | 4237 | * LED2 fffbd800 - fffbdfff |
4212 | 4238 | * Mailbox fffcf000 - fffcf7ff | ... | ... |
hw/omap.h
... | ... | @@ -646,14 +646,23 @@ void omap_badwidth_write32(void *opaque, target_phys_addr_t addr, |
646 | 646 | # define OMAP_RO_REG(paddr) \ |
647 | 647 | printf("%s: Read-only register " OMAP_FMT_plx "\n", \ |
648 | 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 | 654 | printf("%s: 8-bit register " OMAP_FMT_plx "\n", \ |
651 | 655 | __FUNCTION__, paddr) |
652 | -# define OMAP_16B_REG(paddr) \ | |
656 | +# define OMAP_16B_REG(paddr) \ | |
653 | 657 | printf("%s: 16-bit register " OMAP_FMT_plx "\n", \ |
654 | 658 | __FUNCTION__, paddr) |
655 | -# define OMAP_32B_REG(paddr) \ | |
659 | +# define OMAP_32B_REG(paddr) \ | |
656 | 660 | printf("%s: 32-bit register " OMAP_FMT_plx "\n", \ |
657 | 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 | 668 | #endif /* hw_omap_h */ | ... | ... |
hw/omap1_clk.c