Commit 3f582262e5443ded25ba6c8f016a114279a3b59f
1 parent
209a4e69
Implement the PXA2xx I2C master controller.
Fix PXA270-specific timers and make minor changes in other PXA parts. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2853 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
8 changed files
with
271 additions
and
25 deletions
hw/pxa.h
| @@ -65,10 +65,8 @@ | @@ -65,10 +65,8 @@ | ||
| 65 | qemu_irq *pxa2xx_pic_init(target_phys_addr_t base, CPUState *env); | 65 | qemu_irq *pxa2xx_pic_init(target_phys_addr_t base, CPUState *env); |
| 66 | 66 | ||
| 67 | /* pxa2xx_timer.c */ | 67 | /* pxa2xx_timer.c */ |
| 68 | -void pxa25x_timer_init(target_phys_addr_t base, | ||
| 69 | - qemu_irq *irqs, CPUState *cpustate); | ||
| 70 | -void pxa27x_timer_init(target_phys_addr_t base, | ||
| 71 | - qemu_irq *irqs, qemu_irq irq4, CPUState *cpustate); | 68 | +void pxa25x_timer_init(target_phys_addr_t base, qemu_irq *irqs); |
| 69 | +void pxa27x_timer_init(target_phys_addr_t base, qemu_irq *irqs, qemu_irq irq4); | ||
| 72 | 70 | ||
| 73 | /* pxa2xx_gpio.c */ | 71 | /* pxa2xx_gpio.c */ |
| 74 | struct pxa2xx_gpio_info_s; | 72 | struct pxa2xx_gpio_info_s; |
| @@ -117,6 +115,11 @@ void pxa2xx_ssp_attach(struct pxa2xx_ssp_s *port, | @@ -117,6 +115,11 @@ void pxa2xx_ssp_attach(struct pxa2xx_ssp_s *port, | ||
| 117 | uint32_t (*readfn)(void *opaque), | 115 | uint32_t (*readfn)(void *opaque), |
| 118 | void (*writefn)(void *opaque, uint32_t value), void *opaque); | 116 | void (*writefn)(void *opaque, uint32_t value), void *opaque); |
| 119 | 117 | ||
| 118 | +struct pxa2xx_i2c_s; | ||
| 119 | +struct pxa2xx_i2c_s *pxa2xx_i2c_init(target_phys_addr_t base, | ||
| 120 | + qemu_irq irq, int ioregister); | ||
| 121 | +i2c_bus *pxa2xx_i2c_bus(struct pxa2xx_i2c_s *s); | ||
| 122 | + | ||
| 120 | struct pxa2xx_i2s_s; | 123 | struct pxa2xx_i2s_s; |
| 121 | struct pxa2xx_fir_s; | 124 | struct pxa2xx_fir_s; |
| 122 | 125 | ||
| @@ -127,6 +130,7 @@ struct pxa2xx_state_s { | @@ -127,6 +130,7 @@ struct pxa2xx_state_s { | ||
| 127 | struct pxa2xx_gpio_info_s *gpio; | 130 | struct pxa2xx_gpio_info_s *gpio; |
| 128 | struct pxa2xx_lcdc_s *lcd; | 131 | struct pxa2xx_lcdc_s *lcd; |
| 129 | struct pxa2xx_ssp_s **ssp; | 132 | struct pxa2xx_ssp_s **ssp; |
| 133 | + struct pxa2xx_i2c_s *i2c[2]; | ||
| 130 | struct pxa2xx_mmci_s *mmc; | 134 | struct pxa2xx_mmci_s *mmc; |
| 131 | struct pxa2xx_pcmcia_s *pcmcia[2]; | 135 | struct pxa2xx_pcmcia_s *pcmcia[2]; |
| 132 | struct pxa2xx_i2s_s *i2s; | 136 | struct pxa2xx_i2s_s *i2s; |
hw/pxa2xx.c
| @@ -69,9 +69,16 @@ static struct { | @@ -69,9 +69,16 @@ static struct { | ||
| 69 | #define PCMD0 0x80 /* Power Manager I2C Command register File 0 */ | 69 | #define PCMD0 0x80 /* Power Manager I2C Command register File 0 */ |
| 70 | #define PCMD31 0xfc /* Power Manager I2C Command register File 31 */ | 70 | #define PCMD31 0xfc /* Power Manager I2C Command register File 31 */ |
| 71 | 71 | ||
| 72 | +static uint32_t pxa2xx_i2c_read(void *, target_phys_addr_t); | ||
| 73 | +static void pxa2xx_i2c_write(void *, target_phys_addr_t, uint32_t); | ||
| 74 | + | ||
| 72 | static uint32_t pxa2xx_pm_read(void *opaque, target_phys_addr_t addr) | 75 | static uint32_t pxa2xx_pm_read(void *opaque, target_phys_addr_t addr) |
| 73 | { | 76 | { |
| 74 | struct pxa2xx_state_s *s = (struct pxa2xx_state_s *) opaque; | 77 | struct pxa2xx_state_s *s = (struct pxa2xx_state_s *) opaque; |
| 78 | + if (addr > s->pm_base + PCMD31) { | ||
| 79 | + /* Special case: PWRI2C registers appear in the same range. */ | ||
| 80 | + return pxa2xx_i2c_read(s->i2c[1], addr); | ||
| 81 | + } | ||
| 75 | addr -= s->pm_base; | 82 | addr -= s->pm_base; |
| 76 | 83 | ||
| 77 | switch (addr) { | 84 | switch (addr) { |
| @@ -92,6 +99,11 @@ static void pxa2xx_pm_write(void *opaque, target_phys_addr_t addr, | @@ -92,6 +99,11 @@ static void pxa2xx_pm_write(void *opaque, target_phys_addr_t addr, | ||
| 92 | uint32_t value) | 99 | uint32_t value) |
| 93 | { | 100 | { |
| 94 | struct pxa2xx_state_s *s = (struct pxa2xx_state_s *) opaque; | 101 | struct pxa2xx_state_s *s = (struct pxa2xx_state_s *) opaque; |
| 102 | + if (addr > s->pm_base + PCMD31) { | ||
| 103 | + /* Special case: PWRI2C registers appear in the same range. */ | ||
| 104 | + pxa2xx_i2c_write(s->i2c[1], addr, value); | ||
| 105 | + return; | ||
| 106 | + } | ||
| 95 | addr -= s->pm_base; | 107 | addr -= s->pm_base; |
| 96 | 108 | ||
| 97 | switch (addr) { | 109 | switch (addr) { |
| @@ -1086,6 +1098,225 @@ static CPUWriteMemoryFunc *pxa2xx_rtc_writefn[] = { | @@ -1086,6 +1098,225 @@ static CPUWriteMemoryFunc *pxa2xx_rtc_writefn[] = { | ||
| 1086 | pxa2xx_rtc_write, | 1098 | pxa2xx_rtc_write, |
| 1087 | }; | 1099 | }; |
| 1088 | 1100 | ||
| 1101 | +/* I2C Interface */ | ||
| 1102 | +struct pxa2xx_i2c_s { | ||
| 1103 | + i2c_slave slave; | ||
| 1104 | + i2c_bus *bus; | ||
| 1105 | + target_phys_addr_t base; | ||
| 1106 | + qemu_irq irq; | ||
| 1107 | + | ||
| 1108 | + uint16_t control; | ||
| 1109 | + uint16_t status; | ||
| 1110 | + uint8_t ibmr; | ||
| 1111 | + uint8_t data; | ||
| 1112 | +}; | ||
| 1113 | + | ||
| 1114 | +#define IBMR 0x80 /* I2C Bus Monitor register */ | ||
| 1115 | +#define IDBR 0x88 /* I2C Data Buffer register */ | ||
| 1116 | +#define ICR 0x90 /* I2C Control register */ | ||
| 1117 | +#define ISR 0x98 /* I2C Status register */ | ||
| 1118 | +#define ISAR 0xa0 /* I2C Slave Address register */ | ||
| 1119 | + | ||
| 1120 | +static void pxa2xx_i2c_update(struct pxa2xx_i2c_s *s) | ||
| 1121 | +{ | ||
| 1122 | + uint16_t level = 0; | ||
| 1123 | + level |= s->status & s->control & (1 << 10); /* BED */ | ||
| 1124 | + level |= (s->status & (1 << 7)) && (s->control & (1 << 9)); /* IRF */ | ||
| 1125 | + level |= (s->status & (1 << 6)) && (s->control & (1 << 8)); /* ITE */ | ||
| 1126 | + level |= s->status & (1 << 9); /* SAD */ | ||
| 1127 | + qemu_set_irq(s->irq, !!level); | ||
| 1128 | +} | ||
| 1129 | + | ||
| 1130 | +/* These are only stubs now. */ | ||
| 1131 | +static void pxa2xx_i2c_event(i2c_slave *i2c, enum i2c_event event) | ||
| 1132 | +{ | ||
| 1133 | + struct pxa2xx_i2c_s *s = (struct pxa2xx_i2c_s *) i2c; | ||
| 1134 | + | ||
| 1135 | + switch (event) { | ||
| 1136 | + case I2C_START_SEND: | ||
| 1137 | + s->status |= (1 << 9); /* set SAD */ | ||
| 1138 | + s->status &= ~(1 << 0); /* clear RWM */ | ||
| 1139 | + break; | ||
| 1140 | + case I2C_START_RECV: | ||
| 1141 | + s->status |= (1 << 9); /* set SAD */ | ||
| 1142 | + s->status |= 1 << 0; /* set RWM */ | ||
| 1143 | + break; | ||
| 1144 | + case I2C_FINISH: | ||
| 1145 | + s->status |= (1 << 4); /* set SSD */ | ||
| 1146 | + break; | ||
| 1147 | + case I2C_NACK: | ||
| 1148 | + s->status |= 1 << 1; /* set ACKNAK */ | ||
| 1149 | + break; | ||
| 1150 | + } | ||
| 1151 | + pxa2xx_i2c_update(s); | ||
| 1152 | +} | ||
| 1153 | + | ||
| 1154 | +static int pxa2xx_i2c_rx(i2c_slave *i2c) | ||
| 1155 | +{ | ||
| 1156 | + struct pxa2xx_i2c_s *s = (struct pxa2xx_i2c_s *) i2c; | ||
| 1157 | + if ((s->control & (1 << 14)) || !(s->control & (1 << 6))) | ||
| 1158 | + return 0; | ||
| 1159 | + | ||
| 1160 | + if (s->status & (1 << 0)) { /* RWM */ | ||
| 1161 | + s->status |= 1 << 6; /* set ITE */ | ||
| 1162 | + } | ||
| 1163 | + pxa2xx_i2c_update(s); | ||
| 1164 | + | ||
| 1165 | + return s->data; | ||
| 1166 | +} | ||
| 1167 | + | ||
| 1168 | +static int pxa2xx_i2c_tx(i2c_slave *i2c, uint8_t data) | ||
| 1169 | +{ | ||
| 1170 | + struct pxa2xx_i2c_s *s = (struct pxa2xx_i2c_s *) i2c; | ||
| 1171 | + if ((s->control & (1 << 14)) || !(s->control & (1 << 6))) | ||
| 1172 | + return 1; | ||
| 1173 | + | ||
| 1174 | + if (!(s->status & (1 << 0))) { /* RWM */ | ||
| 1175 | + s->status |= 1 << 7; /* set IRF */ | ||
| 1176 | + s->data = data; | ||
| 1177 | + } | ||
| 1178 | + pxa2xx_i2c_update(s); | ||
| 1179 | + | ||
| 1180 | + return 1; | ||
| 1181 | +} | ||
| 1182 | + | ||
| 1183 | +static uint32_t pxa2xx_i2c_read(void *opaque, target_phys_addr_t addr) | ||
| 1184 | +{ | ||
| 1185 | + struct pxa2xx_i2c_s *s = (struct pxa2xx_i2c_s *) opaque; | ||
| 1186 | + addr -= s->base; | ||
| 1187 | + | ||
| 1188 | + switch (addr) { | ||
| 1189 | + case ICR: | ||
| 1190 | + return s->control; | ||
| 1191 | + case ISR: | ||
| 1192 | + return s->status | (i2c_bus_busy(s->bus) << 2); | ||
| 1193 | + case ISAR: | ||
| 1194 | + return s->slave.address; | ||
| 1195 | + case IDBR: | ||
| 1196 | + return s->data; | ||
| 1197 | + case IBMR: | ||
| 1198 | + if (s->status & (1 << 2)) | ||
| 1199 | + s->ibmr ^= 3; /* Fake SCL and SDA pin changes */ | ||
| 1200 | + else | ||
| 1201 | + s->ibmr = 0; | ||
| 1202 | + return s->ibmr; | ||
| 1203 | + default: | ||
| 1204 | + printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr); | ||
| 1205 | + break; | ||
| 1206 | + } | ||
| 1207 | + return 0; | ||
| 1208 | +} | ||
| 1209 | + | ||
| 1210 | +static void pxa2xx_i2c_write(void *opaque, target_phys_addr_t addr, | ||
| 1211 | + uint32_t value) | ||
| 1212 | +{ | ||
| 1213 | + struct pxa2xx_i2c_s *s = (struct pxa2xx_i2c_s *) opaque; | ||
| 1214 | + int ack; | ||
| 1215 | + addr -= s->base; | ||
| 1216 | + | ||
| 1217 | + switch (addr) { | ||
| 1218 | + case ICR: | ||
| 1219 | + s->control = value & 0xfff7; | ||
| 1220 | + if ((value & (1 << 3)) && (value & (1 << 6))) { /* TB and IUE */ | ||
| 1221 | + /* TODO: slave mode */ | ||
| 1222 | + if (value & (1 << 0)) { /* START condition */ | ||
| 1223 | + if (s->data & 1) | ||
| 1224 | + s->status |= 1 << 0; /* set RWM */ | ||
| 1225 | + else | ||
| 1226 | + s->status &= ~(1 << 0); /* clear RWM */ | ||
| 1227 | + ack = !i2c_start_transfer(s->bus, s->data >> 1, s->data & 1); | ||
| 1228 | + } else { | ||
| 1229 | + if (s->status & (1 << 0)) { /* RWM */ | ||
| 1230 | + s->data = i2c_recv(s->bus); | ||
| 1231 | + if (value & (1 << 2)) /* ACKNAK */ | ||
| 1232 | + i2c_nack(s->bus); | ||
| 1233 | + ack = 1; | ||
| 1234 | + } else | ||
| 1235 | + ack = !i2c_send(s->bus, s->data); | ||
| 1236 | + } | ||
| 1237 | + | ||
| 1238 | + if (value & (1 << 1)) /* STOP condition */ | ||
| 1239 | + i2c_end_transfer(s->bus); | ||
| 1240 | + | ||
| 1241 | + if (ack) { | ||
| 1242 | + if (value & (1 << 0)) /* START condition */ | ||
| 1243 | + s->status |= 1 << 6; /* set ITE */ | ||
| 1244 | + else | ||
| 1245 | + if (s->status & (1 << 0)) /* RWM */ | ||
| 1246 | + s->status |= 1 << 7; /* set IRF */ | ||
| 1247 | + else | ||
| 1248 | + s->status |= 1 << 6; /* set ITE */ | ||
| 1249 | + s->status &= ~(1 << 1); /* clear ACKNAK */ | ||
| 1250 | + } else { | ||
| 1251 | + s->status |= 1 << 6; /* set ITE */ | ||
| 1252 | + s->status |= 1 << 10; /* set BED */ | ||
| 1253 | + s->status |= 1 << 1; /* set ACKNAK */ | ||
| 1254 | + } | ||
| 1255 | + } | ||
| 1256 | + if (!(value & (1 << 3)) && (value & (1 << 6))) /* !TB and IUE */ | ||
| 1257 | + if (value & (1 << 4)) /* MA */ | ||
| 1258 | + i2c_end_transfer(s->bus); | ||
| 1259 | + pxa2xx_i2c_update(s); | ||
| 1260 | + break; | ||
| 1261 | + | ||
| 1262 | + case ISR: | ||
| 1263 | + s->status &= ~(value & 0x07f0); | ||
| 1264 | + pxa2xx_i2c_update(s); | ||
| 1265 | + break; | ||
| 1266 | + | ||
| 1267 | + case ISAR: | ||
| 1268 | + i2c_set_slave_address(&s->slave, value & 0x7f); | ||
| 1269 | + break; | ||
| 1270 | + | ||
| 1271 | + case IDBR: | ||
| 1272 | + s->data = value & 0xff; | ||
| 1273 | + break; | ||
| 1274 | + | ||
| 1275 | + default: | ||
| 1276 | + printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr); | ||
| 1277 | + } | ||
| 1278 | +} | ||
| 1279 | + | ||
| 1280 | +static CPUReadMemoryFunc *pxa2xx_i2c_readfn[] = { | ||
| 1281 | + pxa2xx_i2c_read, | ||
| 1282 | + pxa2xx_i2c_read, | ||
| 1283 | + pxa2xx_i2c_read, | ||
| 1284 | +}; | ||
| 1285 | + | ||
| 1286 | +static CPUWriteMemoryFunc *pxa2xx_i2c_writefn[] = { | ||
| 1287 | + pxa2xx_i2c_write, | ||
| 1288 | + pxa2xx_i2c_write, | ||
| 1289 | + pxa2xx_i2c_write, | ||
| 1290 | +}; | ||
| 1291 | + | ||
| 1292 | +struct pxa2xx_i2c_s *pxa2xx_i2c_init(target_phys_addr_t base, | ||
| 1293 | + qemu_irq irq, int ioregister) | ||
| 1294 | +{ | ||
| 1295 | + int iomemtype; | ||
| 1296 | + struct pxa2xx_i2c_s *s = (struct pxa2xx_i2c_s *) | ||
| 1297 | + qemu_mallocz(sizeof(struct pxa2xx_i2c_s)); | ||
| 1298 | + | ||
| 1299 | + s->base = base; | ||
| 1300 | + s->irq = irq; | ||
| 1301 | + s->slave.event = pxa2xx_i2c_event; | ||
| 1302 | + s->slave.recv = pxa2xx_i2c_rx; | ||
| 1303 | + s->slave.send = pxa2xx_i2c_tx; | ||
| 1304 | + s->bus = i2c_init_bus(); | ||
| 1305 | + | ||
| 1306 | + if (ioregister) { | ||
| 1307 | + iomemtype = cpu_register_io_memory(0, pxa2xx_i2c_readfn, | ||
| 1308 | + pxa2xx_i2c_writefn, s); | ||
| 1309 | + cpu_register_physical_memory(s->base & 0xfffff000, 0xfff, iomemtype); | ||
| 1310 | + } | ||
| 1311 | + | ||
| 1312 | + return s; | ||
| 1313 | +} | ||
| 1314 | + | ||
| 1315 | +i2c_bus *pxa2xx_i2c_bus(struct pxa2xx_i2c_s *s) | ||
| 1316 | +{ | ||
| 1317 | + return s->bus; | ||
| 1318 | +} | ||
| 1319 | + | ||
| 1089 | /* PXA Inter-IC Sound Controller */ | 1320 | /* PXA Inter-IC Sound Controller */ |
| 1090 | static void pxa2xx_i2s_reset(struct pxa2xx_i2s_s *i2s) | 1321 | static void pxa2xx_i2s_reset(struct pxa2xx_i2s_s *i2s) |
| 1091 | { | 1322 | { |
| @@ -1544,7 +1775,7 @@ struct pxa2xx_state_s *pxa270_init(unsigned int sdram_size, | @@ -1544,7 +1775,7 @@ struct pxa2xx_state_s *pxa270_init(unsigned int sdram_size, | ||
| 1544 | s->dma = pxa27x_dma_init(0x40000000, s->pic[PXA2XX_PIC_DMA]); | 1775 | s->dma = pxa27x_dma_init(0x40000000, s->pic[PXA2XX_PIC_DMA]); |
| 1545 | 1776 | ||
| 1546 | pxa27x_timer_init(0x40a00000, &s->pic[PXA2XX_PIC_OST_0], | 1777 | pxa27x_timer_init(0x40a00000, &s->pic[PXA2XX_PIC_OST_0], |
| 1547 | - s->pic[PXA27X_PIC_OST_4_11], s->env); | 1778 | + s->pic[PXA27X_PIC_OST_4_11]); |
| 1548 | 1779 | ||
| 1549 | s->gpio = pxa2xx_gpio_init(0x40e00000, s->env, s->pic, 121); | 1780 | s->gpio = pxa2xx_gpio_init(0x40e00000, s->env, s->pic, 121); |
| 1550 | 1781 | ||
| @@ -1608,6 +1839,12 @@ struct pxa2xx_state_s *pxa270_init(unsigned int sdram_size, | @@ -1608,6 +1839,12 @@ struct pxa2xx_state_s *pxa270_init(unsigned int sdram_size, | ||
| 1608 | cpu_register_physical_memory(s->rtc_base, 0xfff, iomemtype); | 1839 | cpu_register_physical_memory(s->rtc_base, 0xfff, iomemtype); |
| 1609 | pxa2xx_rtc_reset(s); | 1840 | pxa2xx_rtc_reset(s); |
| 1610 | 1841 | ||
| 1842 | + /* Note that PM registers are in the same page with PWRI2C registers. | ||
| 1843 | + * As a workaround we don't map PWRI2C into memory and we expect | ||
| 1844 | + * PM handlers to call PWRI2C handlers when appropriate. */ | ||
| 1845 | + s->i2c[0] = pxa2xx_i2c_init(0x40301600, s->pic[PXA2XX_PIC_I2C], 1); | ||
| 1846 | + s->i2c[1] = pxa2xx_i2c_init(0x40f00100, s->pic[PXA2XX_PIC_PWRI2C], 0); | ||
| 1847 | + | ||
| 1611 | s->pm_base = 0x40f00000; | 1848 | s->pm_base = 0x40f00000; |
| 1612 | iomemtype = cpu_register_io_memory(0, pxa2xx_pm_readfn, | 1849 | iomemtype = cpu_register_io_memory(0, pxa2xx_pm_readfn, |
| 1613 | pxa2xx_pm_writefn, s); | 1850 | pxa2xx_pm_writefn, s); |
| @@ -1643,7 +1880,7 @@ struct pxa2xx_state_s *pxa255_init(unsigned int sdram_size, | @@ -1643,7 +1880,7 @@ struct pxa2xx_state_s *pxa255_init(unsigned int sdram_size, | ||
| 1643 | 1880 | ||
| 1644 | s->dma = pxa255_dma_init(0x40000000, s->pic[PXA2XX_PIC_DMA]); | 1881 | s->dma = pxa255_dma_init(0x40000000, s->pic[PXA2XX_PIC_DMA]); |
| 1645 | 1882 | ||
| 1646 | - pxa25x_timer_init(0x40a00000, &s->pic[PXA2XX_PIC_OST_0], s->env); | 1883 | + pxa25x_timer_init(0x40a00000, &s->pic[PXA2XX_PIC_OST_0]); |
| 1647 | 1884 | ||
| 1648 | s->gpio = pxa2xx_gpio_init(0x40e00000, s->env, s->pic, 85); | 1885 | s->gpio = pxa2xx_gpio_init(0x40e00000, s->env, s->pic, 85); |
| 1649 | 1886 | ||
| @@ -1707,6 +1944,12 @@ struct pxa2xx_state_s *pxa255_init(unsigned int sdram_size, | @@ -1707,6 +1944,12 @@ struct pxa2xx_state_s *pxa255_init(unsigned int sdram_size, | ||
| 1707 | cpu_register_physical_memory(s->rtc_base, 0xfff, iomemtype); | 1944 | cpu_register_physical_memory(s->rtc_base, 0xfff, iomemtype); |
| 1708 | pxa2xx_rtc_reset(s); | 1945 | pxa2xx_rtc_reset(s); |
| 1709 | 1946 | ||
| 1947 | + /* Note that PM registers are in the same page with PWRI2C registers. | ||
| 1948 | + * As a workaround we don't map PWRI2C into memory and we expect | ||
| 1949 | + * PM handlers to call PWRI2C handlers when appropriate. */ | ||
| 1950 | + s->i2c[0] = pxa2xx_i2c_init(0x40301600, s->pic[PXA2XX_PIC_I2C], 1); | ||
| 1951 | + s->i2c[1] = pxa2xx_i2c_init(0x40f00100, s->pic[PXA2XX_PIC_PWRI2C], 0); | ||
| 1952 | + | ||
| 1710 | s->pm_base = 0x40f00000; | 1953 | s->pm_base = 0x40f00000; |
| 1711 | iomemtype = cpu_register_io_memory(0, pxa2xx_pm_readfn, | 1954 | iomemtype = cpu_register_io_memory(0, pxa2xx_pm_readfn, |
| 1712 | pxa2xx_pm_writefn, s); | 1955 | pxa2xx_pm_writefn, s); |
hw/pxa2xx_dma.c
| @@ -443,16 +443,16 @@ static struct pxa2xx_dma_state_s *pxa2xx_dma_init(target_phys_addr_t base, | @@ -443,16 +443,16 @@ static struct pxa2xx_dma_state_s *pxa2xx_dma_init(target_phys_addr_t base, | ||
| 443 | s->base = base; | 443 | s->base = base; |
| 444 | s->irq = irq; | 444 | s->irq = irq; |
| 445 | s->handler = (pxa2xx_dma_handler_t) pxa2xx_dma_request; | 445 | s->handler = (pxa2xx_dma_handler_t) pxa2xx_dma_request; |
| 446 | - s->req = qemu_mallocz(sizeof(int) * PXA2XX_DMA_NUM_REQUESTS); | 446 | + s->req = qemu_mallocz(sizeof(uint8_t) * PXA2XX_DMA_NUM_REQUESTS); |
| 447 | 447 | ||
| 448 | memset(s->chan, 0, sizeof(struct pxa2xx_dma_channel_s) * s->channels); | 448 | memset(s->chan, 0, sizeof(struct pxa2xx_dma_channel_s) * s->channels); |
| 449 | for (i = 0; i < s->channels; i ++) | 449 | for (i = 0; i < s->channels; i ++) |
| 450 | s->chan[i].state = DCSR_STOPINTR; | 450 | s->chan[i].state = DCSR_STOPINTR; |
| 451 | 451 | ||
| 452 | - memset(s->req, 0, sizeof(int) * PXA2XX_DMA_NUM_REQUESTS); | 452 | + memset(s->req, 0, sizeof(uint8_t) * PXA2XX_DMA_NUM_REQUESTS); |
| 453 | 453 | ||
| 454 | iomemtype = cpu_register_io_memory(0, pxa2xx_dma_readfn, | 454 | iomemtype = cpu_register_io_memory(0, pxa2xx_dma_readfn, |
| 455 | - pxa2xx_dma_writefn, s); | 455 | + pxa2xx_dma_writefn, s); |
| 456 | cpu_register_physical_memory(base, 0x0000ffff, iomemtype); | 456 | cpu_register_physical_memory(base, 0x0000ffff, iomemtype); |
| 457 | 457 | ||
| 458 | return s; | 458 | return s; |
hw/pxa2xx_lcd.c
| @@ -793,8 +793,7 @@ static void pxa2xx_lcdc_dma0_redraw_vert(struct pxa2xx_lcdc_s *s, | @@ -793,8 +793,7 @@ static void pxa2xx_lcdc_dma0_redraw_vert(struct pxa2xx_lcdc_s *s, | ||
| 793 | dest, src, s->xres, -dest_width); | 793 | dest, src, s->xres, -dest_width); |
| 794 | if (addr < start) | 794 | if (addr < start) |
| 795 | start = addr; | 795 | start = addr; |
| 796 | - if (new_addr > end) | ||
| 797 | - end = new_addr; | 796 | + end = new_addr; |
| 798 | if (y < *miny) | 797 | if (y < *miny) |
| 799 | *miny = y; | 798 | *miny = y; |
| 800 | if (y >= *maxy) | 799 | if (y >= *maxy) |
hw/pxa2xx_pcmcia.c
| @@ -171,6 +171,7 @@ struct pxa2xx_pcmcia_s *pxa2xx_pcmcia_init(target_phys_addr_t base) | @@ -171,6 +171,7 @@ struct pxa2xx_pcmcia_s *pxa2xx_pcmcia_init(target_phys_addr_t base) | ||
| 171 | s->slot.slot_string = "PXA PC Card Socket 0"; | 171 | s->slot.slot_string = "PXA PC Card Socket 0"; |
| 172 | s->slot.irq = qemu_allocate_irqs(pxa2xx_pcmcia_set_irq, s, 1)[0]; | 172 | s->slot.irq = qemu_allocate_irqs(pxa2xx_pcmcia_set_irq, s, 1)[0]; |
| 173 | pcmcia_socket_register(&s->slot); | 173 | pcmcia_socket_register(&s->slot); |
| 174 | + | ||
| 174 | return s; | 175 | return s; |
| 175 | } | 176 | } |
| 176 | 177 |
hw/pxa2xx_timer.c
| @@ -75,7 +75,7 @@ struct pxa2xx_timer4_s { | @@ -75,7 +75,7 @@ struct pxa2xx_timer4_s { | ||
| 75 | }; | 75 | }; |
| 76 | 76 | ||
| 77 | typedef struct { | 77 | typedef struct { |
| 78 | - uint32_t base; | 78 | + target_phys_addr_t base; |
| 79 | int32_t clock; | 79 | int32_t clock; |
| 80 | int32_t oldclock; | 80 | int32_t oldclock; |
| 81 | uint64_t lastload; | 81 | uint64_t lastload; |
| @@ -85,8 +85,6 @@ typedef struct { | @@ -85,8 +85,6 @@ typedef struct { | ||
| 85 | uint32_t events; | 85 | uint32_t events; |
| 86 | uint32_t irq_enabled; | 86 | uint32_t irq_enabled; |
| 87 | uint32_t reset3; | 87 | uint32_t reset3; |
| 88 | - CPUState *cpustate; | ||
| 89 | - int64_t qemu_ticks; | ||
| 90 | uint32_t snapshot; | 88 | uint32_t snapshot; |
| 91 | } pxa2xx_timer_info; | 89 | } pxa2xx_timer_info; |
| 92 | 90 | ||
| @@ -121,7 +119,7 @@ static void pxa2xx_timer_update4(void *opaque, uint64_t now_qemu, int n) | @@ -121,7 +119,7 @@ static void pxa2xx_timer_update4(void *opaque, uint64_t now_qemu, int n) | ||
| 121 | counter = counters[n]; | 119 | counter = counters[n]; |
| 122 | 120 | ||
| 123 | if (!s->tm4[counter].freq) { | 121 | if (!s->tm4[counter].freq) { |
| 124 | - qemu_del_timer(s->timer[n].qtimer); | 122 | + qemu_del_timer(s->tm4[n].tm.qtimer); |
| 125 | return; | 123 | return; |
| 126 | } | 124 | } |
| 127 | 125 | ||
| @@ -131,7 +129,7 @@ static void pxa2xx_timer_update4(void *opaque, uint64_t now_qemu, int n) | @@ -131,7 +129,7 @@ static void pxa2xx_timer_update4(void *opaque, uint64_t now_qemu, int n) | ||
| 131 | 129 | ||
| 132 | new_qemu = now_qemu + muldiv64((uint32_t) (s->tm4[n].tm.value - now_vm), | 130 | new_qemu = now_qemu + muldiv64((uint32_t) (s->tm4[n].tm.value - now_vm), |
| 133 | ticks_per_sec, s->tm4[counter].freq); | 131 | ticks_per_sec, s->tm4[counter].freq); |
| 134 | - qemu_mod_timer(s->timer[n].qtimer, new_qemu); | 132 | + qemu_mod_timer(s->tm4[n].tm.qtimer, new_qemu); |
| 135 | } | 133 | } |
| 136 | 134 | ||
| 137 | static uint32_t pxa2xx_timer_read(void *opaque, target_phys_addr_t offset) | 135 | static uint32_t pxa2xx_timer_read(void *opaque, target_phys_addr_t offset) |
| @@ -350,7 +348,7 @@ static void pxa2xx_timer_tick(void *opaque) | @@ -350,7 +348,7 @@ static void pxa2xx_timer_tick(void *opaque) | ||
| 350 | if (t->num == 3) | 348 | if (t->num == 3) |
| 351 | if (i->reset3 & 1) { | 349 | if (i->reset3 & 1) { |
| 352 | i->reset3 = 0; | 350 | i->reset3 = 0; |
| 353 | - cpu_reset(i->cpustate); | 351 | + qemu_system_reset_request(); |
| 354 | } | 352 | } |
| 355 | } | 353 | } |
| 356 | 354 | ||
| @@ -367,7 +365,7 @@ static void pxa2xx_timer_tick4(void *opaque) | @@ -367,7 +365,7 @@ static void pxa2xx_timer_tick4(void *opaque) | ||
| 367 | } | 365 | } |
| 368 | 366 | ||
| 369 | static pxa2xx_timer_info *pxa2xx_timer_init(target_phys_addr_t base, | 367 | static pxa2xx_timer_info *pxa2xx_timer_init(target_phys_addr_t base, |
| 370 | - qemu_irq *irqs, CPUState *cpustate) | 368 | + qemu_irq *irqs) |
| 371 | { | 369 | { |
| 372 | int i; | 370 | int i; |
| 373 | int iomemtype; | 371 | int iomemtype; |
| @@ -380,7 +378,6 @@ static pxa2xx_timer_info *pxa2xx_timer_init(target_phys_addr_t base, | @@ -380,7 +378,6 @@ static pxa2xx_timer_info *pxa2xx_timer_init(target_phys_addr_t base, | ||
| 380 | s->clock = 0; | 378 | s->clock = 0; |
| 381 | s->lastload = qemu_get_clock(vm_clock); | 379 | s->lastload = qemu_get_clock(vm_clock); |
| 382 | s->reset3 = 0; | 380 | s->reset3 = 0; |
| 383 | - s->cpustate = cpustate; | ||
| 384 | 381 | ||
| 385 | for (i = 0; i < 4; i ++) { | 382 | for (i = 0; i < 4; i ++) { |
| 386 | s->timer[i].value = 0; | 383 | s->timer[i].value = 0; |
| @@ -398,18 +395,17 @@ static pxa2xx_timer_info *pxa2xx_timer_init(target_phys_addr_t base, | @@ -398,18 +395,17 @@ static pxa2xx_timer_info *pxa2xx_timer_init(target_phys_addr_t base, | ||
| 398 | return s; | 395 | return s; |
| 399 | } | 396 | } |
| 400 | 397 | ||
| 401 | -void pxa25x_timer_init(target_phys_addr_t base, | ||
| 402 | - qemu_irq *irqs, CPUState *cpustate) | 398 | +void pxa25x_timer_init(target_phys_addr_t base, qemu_irq *irqs) |
| 403 | { | 399 | { |
| 404 | - pxa2xx_timer_info *s = pxa2xx_timer_init(base, irqs, cpustate); | 400 | + pxa2xx_timer_info *s = pxa2xx_timer_init(base, irqs); |
| 405 | s->freq = PXA25X_FREQ; | 401 | s->freq = PXA25X_FREQ; |
| 406 | s->tm4 = 0; | 402 | s->tm4 = 0; |
| 407 | } | 403 | } |
| 408 | 404 | ||
| 409 | void pxa27x_timer_init(target_phys_addr_t base, | 405 | void pxa27x_timer_init(target_phys_addr_t base, |
| 410 | - qemu_irq *irqs, qemu_irq irq4, CPUState *cpustate) | 406 | + qemu_irq *irqs, qemu_irq irq4) |
| 411 | { | 407 | { |
| 412 | - pxa2xx_timer_info *s = pxa2xx_timer_init(base, irqs, cpustate); | 408 | + pxa2xx_timer_info *s = pxa2xx_timer_init(base, irqs); |
| 413 | int i; | 409 | int i; |
| 414 | s->freq = PXA27X_FREQ; | 410 | s->freq = PXA27X_FREQ; |
| 415 | s->tm4 = (struct pxa2xx_timer4_s *) qemu_mallocz(8 * | 411 | s->tm4 = (struct pxa2xx_timer4_s *) qemu_mallocz(8 * |
hw/smbus.c
| @@ -193,6 +193,9 @@ SMBusDevice *smbus_device_init(i2c_bus *bus, int address, int size) | @@ -193,6 +193,9 @@ SMBusDevice *smbus_device_init(i2c_bus *bus, int address, int size) | ||
| 193 | { | 193 | { |
| 194 | SMBusDevice *dev; | 194 | SMBusDevice *dev; |
| 195 | 195 | ||
| 196 | + if (size < sizeof(SMBusDevice)) | ||
| 197 | + cpu_abort(cpu_single_env, "SMBus struct too small"); | ||
| 198 | + | ||
| 196 | dev = (SMBusDevice *)i2c_slave_init(bus, address, size); | 199 | dev = (SMBusDevice *)i2c_slave_init(bus, address, size); |
| 197 | dev->i2c.event = smbus_i2c_event; | 200 | dev->i2c.event = smbus_i2c_event; |
| 198 | dev->i2c.recv = smbus_i2c_recv; | 201 | dev->i2c.recv = smbus_i2c_recv; |
hw/smbus.h
| @@ -37,7 +37,7 @@ struct SMBusDevice { | @@ -37,7 +37,7 @@ struct SMBusDevice { | ||
| 37 | (if present). The device is responsible figuring out what type of | 37 | (if present). The device is responsible figuring out what type of |
| 38 | command this is. */ | 38 | command this is. */ |
| 39 | void (*write_data)(SMBusDevice *dev, uint8_t cmd, uint8_t *buf, int len); | 39 | void (*write_data)(SMBusDevice *dev, uint8_t cmd, uint8_t *buf, int len); |
| 40 | - /* Likewise we can't distinguish between defferent reads, or even know | 40 | + /* Likewise we can't distinguish between different reads, or even know |
| 41 | the length of the read until the read is complete, so read data a | 41 | the length of the read until the read is complete, so read data a |
| 42 | byte at a time. The device is responsible for adding the length | 42 | byte at a time. The device is responsible for adding the length |
| 43 | byte on block reads. */ | 43 | byte on block reads. */ |