* with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "qemu/osdep.h"
+#include "qemu/error-report.h"
+#include "qemu/main-loop.h"
+#include "qapi/error.h"
+#include "qemu-common.h"
+#include "cpu.h"
#include "hw/boards.h"
#include "hw/hw.h"
-#include "hw/arm/arm.h"
+#include "hw/irq.h"
+#include "hw/arm/boot.h"
#include "hw/arm/omap.h"
#include "sysemu/sysemu.h"
#include "hw/arm/soc_dma.h"
-#include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
+#include "sysemu/qtest.h"
+#include "sysemu/reset.h"
#include "qemu/range.h"
#include "hw/sysbus.h"
+#include "qemu/cutils.h"
+#include "qemu/bcd.h"
+
+static inline void omap_log_badwidth(const char *funcname, hwaddr addr, int sz)
+{
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: %d-bit register %#08" HWADDR_PRIx "\n",
+ funcname, 8 * sz, addr);
+}
/* Should signal the TCMI/GPMC */
uint32_t omap_badwidth_read8(void *opaque, hwaddr addr)
{
uint8_t ret;
- OMAP_8B_REG(addr);
+ omap_log_badwidth(__func__, addr, 1);
cpu_physical_memory_read(addr, &ret, 1);
return ret;
}
{
uint8_t val8 = value;
- OMAP_8B_REG(addr);
+ omap_log_badwidth(__func__, addr, 1);
cpu_physical_memory_write(addr, &val8, 1);
}
{
uint16_t ret;
- OMAP_16B_REG(addr);
+ omap_log_badwidth(__func__, addr, 2);
cpu_physical_memory_read(addr, &ret, 2);
return ret;
}
{
uint16_t val16 = value;
- OMAP_16B_REG(addr);
+ omap_log_badwidth(__func__, addr, 2);
cpu_physical_memory_write(addr, &val16, 2);
}
{
uint32_t ret;
- OMAP_32B_REG(addr);
+ omap_log_badwidth(__func__, addr, 4);
cpu_physical_memory_read(addr, &ret, 4);
return ret;
}
void omap_badwidth_write32(void *opaque, hwaddr addr,
uint32_t value)
{
- OMAP_32B_REG(addr);
+ omap_log_badwidth(__func__, addr, 4);
cpu_physical_memory_write(addr, &value, 4);
}
if (timer->st && timer->enable && timer->rate)
return timer->val - muldiv64(distance >> (timer->ptv + 1),
- timer->rate, get_ticks_per_sec());
+ timer->rate, NANOSECONDS_PER_SECOND);
else
return timer->val;
}
if (timer->enable && timer->st && timer->rate) {
timer->val = timer->reset_val; /* Should skip this on clk enable */
expires = muldiv64((uint64_t) timer->val << (timer->ptv + 1),
- get_ticks_per_sec(), timer->rate);
+ NANOSECONDS_PER_SECOND, timer->rate);
/* If timer expiry would be sooner than in about 1 ms and
* auto-reload isn't set, then fire immediately. This is a hack
* sets the interval to a very low value and polls the status bit
* in a busy loop when it wants to sleep just a couple of CPU
* ticks. */
- if (expires > (get_ticks_per_sec() >> 10) || timer->ar)
+ if (expires > (NANOSECONDS_PER_SECOND >> 10) || timer->ar) {
timer_mod(timer->timer, timer->time + expires);
- else
+ } else {
qemu_bh_schedule(timer->tick);
+ }
} else
timer_del(timer->timer);
}
/* XXX: on T|E hardware somehow this has no effect,
* on Zire 71 it works as specified. */
s->reset = 1;
- qemu_system_reset_request();
+ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
}
}
s->last_wr = value & 0xff;
now -= s->ulpd_gauge_start;
/* 32-kHz ticks */
- ticks = muldiv64(now, 32768, get_ticks_per_sec());
+ ticks = muldiv64(now, 32768, NANOSECONDS_PER_SECOND);
s->ulpd_pm_regs[0x00 >> 2] = (ticks >> 0) & 0xffff;
s->ulpd_pm_regs[0x04 >> 2] = (ticks >> 16) & 0xffff;
if (ticks >> 32) /* OVERFLOW_32K */
s->ulpd_pm_regs[0x14 >> 2] |= 1 << 2;
/* High frequency ticks */
- ticks = muldiv64(now, 12000000, get_ticks_per_sec());
+ ticks = muldiv64(now, 12000000, NANOSECONDS_PER_SECOND);
s->ulpd_pm_regs[0x08 >> 2] = (ticks >> 0) & 0xffff;
s->ulpd_pm_regs[0x0c >> 2] = (ticks >> 16) & 0xffff;
if (ticks >> 32) /* OVERFLOW_HI_FREQ */
case omap1510:
return 0x03310115;
default:
- hw_error("%s: bad mpu model\n", __FUNCTION__);
+ hw_error("%s: bad mpu model\n", __func__);
}
break;
case omap1510:
return 0xfb47002f;
default:
- hw_error("%s: bad mpu model\n", __FUNCTION__);
+ hw_error("%s: bad mpu model\n", __func__);
}
break;
}
if (value & (1 << 11)) { /* SETARM_IDLE */
cpu_interrupt(CPU(s->cpu), CPU_INTERRUPT_HALT);
}
- if (!(value & (1 << 10))) /* WKUP_MODE */
- qemu_system_shutdown_request(); /* XXX: disable wakeup from IRQ */
+ if (!(value & (1 << 10))) { /* WKUP_MODE */
+ /* XXX: disable wakeup from IRQ */
+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
+ }
#define SET_CANIDLE(clock, bit) \
if (diff & (1 << bit)) { \
diff = s->clkm.arm_rstct1 ^ value;
s->clkm.arm_rstct1 = value & 0x0007;
if (value & 9) {
- qemu_system_reset_request();
+ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
s->clkm.cold_start = 0xa;
}
if (diff & ~value & 4) { /* DSP_RST */
case 0x18: /* ARM_SYSST */
if ((s->clkm.clocking_scheme ^ (value >> 11)) & 7) {
s->clkm.clocking_scheme = (value >> 11) & 7;
- printf("%s: clocking scheme set to %s\n", __FUNCTION__,
- clkschemename[s->clkm.clocking_scheme]);
+ printf("%s: clocking scheme set to %s\n", __func__,
+ clkschemename[s->clkm.clocking_scheme]);
}
s->clkm.cold_start &= value & 0x3f;
return;
void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler)
{
if (line >= 16 || line < 0)
- hw_error("%s: No GPIO line %i\n", __FUNCTION__, line);
+ hw_error("%s: No GPIO line %i\n", __func__, line);
s->handler[line] = handler;
}
void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down)
{
if (row >= 5 || row < 0)
- hw_error("%s: No key %i-%i\n", __FUNCTION__, col, row);
+ hw_error("%s: No key %i-%i\n", __func__, col, row);
if (down)
s->buttons[row] |= 1 << col;
uWireSlave *slave, int chipselect)
{
if (chipselect < 0 || chipselect > 3) {
- fprintf(stderr, "%s: Bad chipselect %i\n", __FUNCTION__, chipselect);
+ error_report("%s: Bad chipselect %i", __func__, chipselect);
exit(-1);
}
if (output != s->output) {
s->output = output;
- printf("%s: Backlight now at %i/256\n", __FUNCTION__, output);
+ printf("%s: Backlight now at %i/256\n", __func__, output);
}
}
case 0x04: /* VRC */
if ((value ^ s->vrc) & 1) {
if (value & 1)
- printf("%s: %iHz buzz on\n", __FUNCTION__, (int)
+ printf("%s: %iHz buzz on\n", __func__, (int)
/* 1.5 MHz from a 12-MHz or 13-MHz PWT_CLK */
((omap_clk_getrate(s->clk) >> 3) /
/* Pre-multiplexer divider */
((value & (1 << 5)) ? 80 : 127) /
(107 * 55 * 63 * 127)));
else
- printf("%s: silence!\n", __FUNCTION__);
+ printf("%s: silence!\n", __func__);
}
s->vrc = value & 0x7f;
break;
{
s->alarm_ti = mktimegm(&s->alarm_tm);
if (s->alarm_ti == -1)
- printf("%s: conversion failed\n", __FUNCTION__);
+ printf("%s: conversion failed\n", __func__);
}
static uint64_t omap_rtc_read(void *opaque, hwaddr addr,
if (!s->rx_rate)
return;
if (s->rx_req)
- printf("%s: Rx FIFO overrun\n", __FUNCTION__);
+ printf("%s: Rx FIFO overrun\n", __func__);
s->rx_req = s->rx_rate << bps[(s->rcr[0] >> 5) & 7];
omap_mcbsp_rx_newdata(s);
timer_mod(s->source_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
- get_ticks_per_sec());
+ NANOSECONDS_PER_SECOND);
}
static void omap_mcbsp_rx_start(struct omap_mcbsp_s *s)
if (!s->tx_rate)
return;
if (s->tx_req)
- printf("%s: Tx FIFO underrun\n", __FUNCTION__);
+ printf("%s: Tx FIFO underrun\n", __func__);
s->tx_req = s->tx_rate << bps[(s->xcr[0] >> 5) & 7];
omap_mcbsp_tx_newdata(s);
timer_mod(s->sink_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
- get_ticks_per_sec());
+ NANOSECONDS_PER_SECOND);
}
static void omap_mcbsp_tx_start(struct omap_mcbsp_s *s)
/* Fall through. */
case 0x02: /* DRR1 */
if (s->rx_req < 2) {
- printf("%s: Rx FIFO underrun\n", __FUNCTION__);
+ printf("%s: Rx FIFO underrun\n", __func__);
omap_mcbsp_rx_done(s);
} else {
s->tx_req -= 2;
if (s->tx_req < 2)
omap_mcbsp_tx_done(s);
} else
- printf("%s: Tx FIFO overrun\n", __FUNCTION__);
+ printf("%s: Tx FIFO overrun\n", __func__);
return;
case 0x08: /* SPCR2 */
s->spcr[0] &= 0x0006;
s->spcr[0] |= 0xf8f9 & value;
if (value & (1 << 15)) /* DLB */
- printf("%s: Digital Loopback mode enable attempt\n", __FUNCTION__);
+ printf("%s: Digital Loopback mode enable attempt\n", __func__);
if (~value & 1) { /* RRST */
s->spcr[0] &= ~6;
s->rx_req = 0;
case 0x18: /* MCR2 */
s->mcr[1] = value & 0x03e3;
if (value & 3) /* XMCM */
- printf("%s: Tx channel selection mode enable attempt\n",
- __FUNCTION__);
+ printf("%s: Tx channel selection mode enable attempt\n", __func__);
return;
case 0x1a: /* MCR1 */
s->mcr[0] = value & 0x03e1;
if (value & 1) /* RMCM */
- printf("%s: Rx channel selection mode enable attempt\n",
- __FUNCTION__);
+ printf("%s: Rx channel selection mode enable attempt\n", __func__);
return;
case 0x1c: /* RCERA */
s->rcer[0] = value & 0xffff;
if (s->tx_req < 4)
omap_mcbsp_tx_done(s);
} else
- printf("%s: Tx FIFO overrun\n", __FUNCTION__);
+ printf("%s: Tx FIFO overrun\n", __func__);
return;
}
timer_mod(s->tm, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + s->on);
s->cycle = !s->cycle;
- printf("%s: LED is %s\n", __FUNCTION__, s->cycle ? "on" : "off");
+ printf("%s: LED is %s\n", __func__, s->cycle ? "on" : "off");
}
static void omap_lpg_update(struct omap_lpg_s *s)
timer_del(s->tm);
if (on == period && s->on < s->period)
- printf("%s: LED is on\n", __FUNCTION__);
+ printf("%s: LED is on\n", __func__);
else if (on == 0 && s->on)
- printf("%s: LED is off\n", __FUNCTION__);
+ printf("%s: LED is off\n", __func__);
else if (on && (on != s->on || period != s->period)) {
s->cycle = 0;
s->on = on;
struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
unsigned long sdram_size,
- const char *core)
+ const char *cpu_type)
{
int i;
struct omap_mpu_state_s *s = g_new0(struct omap_mpu_state_s, 1);
DriveInfo *dinfo;
SysBusDevice *busdev;
- if (!core)
- core = "ti925t";
-
/* Core */
s->mpu_model = omap310;
- s->cpu = cpu_arm_init(core);
- if (s->cpu == NULL) {
- fprintf(stderr, "Unable to find CPU definition\n");
- exit(1);
- }
+ s->cpu = ARM_CPU(cpu_create(cpu_type));
s->sdram_size = sdram_size;
s->sram_size = OMAP15XX_SRAM_SIZE;
s->sdram_size);
memory_region_add_subregion(system_memory, OMAP_EMIFF_BASE, &s->emiff_ram);
memory_region_init_ram(&s->imif_ram, NULL, "omap1.sram", s->sram_size,
- &error_abort);
- vmstate_register_ram_global(&s->imif_ram);
+ &error_fatal);
memory_region_add_subregion(system_memory, OMAP_IMIF_BASE, &s->imif_ram);
omap_clkm_init(system_memory, 0xfffece00, 0xe1008000, s);
omap_findclk(s, "uart1_ck"),
s->drq[OMAP_DMA_UART1_TX], s->drq[OMAP_DMA_UART1_RX],
"uart1",
- serial_hds[0]);
+ serial_hd(0));
s->uart[1] = omap_uart_init(0xfffb0800,
qdev_get_gpio_in(s->ih[1], OMAP_INT_UART2),
omap_findclk(s, "uart2_ck"),
omap_findclk(s, "uart2_ck"),
s->drq[OMAP_DMA_UART2_TX], s->drq[OMAP_DMA_UART2_RX],
"uart2",
- serial_hds[0] ? serial_hds[1] : NULL);
+ serial_hd(0) ? serial_hd(1) : NULL);
s->uart[2] = omap_uart_init(0xfffb9800,
qdev_get_gpio_in(s->ih[0], OMAP_INT_UART3),
omap_findclk(s, "uart3_ck"),
omap_findclk(s, "uart3_ck"),
s->drq[OMAP_DMA_UART3_TX], s->drq[OMAP_DMA_UART3_RX],
"uart3",
- serial_hds[0] && serial_hds[1] ? serial_hds[2] : NULL);
+ serial_hd(0) && serial_hd(1) ? serial_hd(2) : NULL);
s->dpll[0] = omap_dpll_init(system_memory, 0xfffecf00,
omap_findclk(s, "dpll1"));
omap_findclk(s, "dpll3"));
dinfo = drive_get(IF_SD, 0, 0);
- if (!dinfo) {
- fprintf(stderr, "qemu: missing SecureDigital device\n");
- exit(1);
+ if (!dinfo && !qtest_enabled()) {
+ warn_report("missing SecureDigital device");
}
s->mmc = omap_mmc_init(0xfffb7800, system_memory,
- blk_by_legacy_dinfo(dinfo),
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
qdev_get_gpio_in(s->ih[1], OMAP_INT_OQN),
&s->drq[OMAP_DMA_MMC_TX],
omap_findclk(s, "mmc_ck"));