Files
qemu-ios/contrib/ipod-emu/tests/test-display.c
T

120 lines
4.8 KiB
C

/* Le masque LCD et l'acquittement doivent survivre à plusieurs resprings. */
#include "qemu/osdep.h"
#include "qemu/main-loop.h"
#include "sysemu/cpus.h"
#include "hw/arm/ipod_touch_lcd.c"
#define ipod_touch_machine_types test_mipi_register_types
#include "hw/arm/ipod_touch_mipi_dsi.c"
#undef ipod_touch_machine_types
#include "hw/arm/ipod_touch_tvout.c"
static void irq_changed(void *opaque, int n, int level)
{
*(int *)opaque = level;
}
static void test_interrupt_reenable(void)
{
IPodTouchLCDState *s = IPOD_TOUCH_LCD(object_new(TYPE_IPOD_TOUCH_LCD));
int level = 0;
qemu_irq irq = qemu_allocate_irq(irq_changed, &level, 0);
sysbus_connect_irq(SYS_BUS_DEVICE(s), 0, irq);
s->refresh_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, refresh_timer_tick, s);
for (int cycle = 0; cycle < 3; cycle++) {
/* Vblank masqué : état en attente, aucune interruption CPU. */
ipod_touch_lcd_write(s, 0x8, 0, 4);
refresh_timer_tick(s);
g_assert_cmpint(level, ==, 0);
g_assert_cmpuint(ipod_touch_lcd_read(s, 0xc, 4), ==, 1);
ipod_touch_lcd_write(s, 0xc, 0xff, 4);
g_assert_cmpuint(ipod_touch_lcd_read(s, 0xc, 4), ==, 0);
/* Nouveau client : le masque réactive les vblanks après cet ACK. */
ipod_touch_lcd_write(s, 0x8, 1, 4);
g_assert_cmpint(level, ==, 0);
refresh_timer_tick(s);
g_assert_cmpint(level, ==, 1);
ipod_touch_lcd_write(s, 0xc, 2, 4);
g_assert_cmpint(level, ==, 1);
ipod_touch_lcd_write(s, 0xc, 1, 4);
g_assert_cmpint(level, ==, 0);
g_assert_cmpuint(ipod_touch_lcd_read(s, 0x8, 4), ==, 1);
refresh_timer_tick(s);
g_assert_cmpint(level, ==, 1);
ipod_touch_lcd_write(s, 0x8, 0, 4);
g_assert_cmpint(level, ==, 0);
ipod_touch_lcd_write(s, 0x8, 1, 4);
g_assert_cmpint(level, ==, 1);
}
ipod_touch_lcd_write(s, 0x24, 0x12340000, 4);
device_cold_reset(DEVICE(s));
g_assert_cmpint(level, ==, 0);
g_assert_cmpuint(ipod_touch_lcd_read(s, 0x8, 4), ==, 0);
g_assert_cmpuint(ipod_touch_lcd_read(s, 0xc, 4), ==, 0);
g_assert_cmpuint(ipod_touch_lcd_read(s, 0x24, 4), ==, 0);
timer_del(s->refresh_timer);
timer_free(s->refresh_timer);
object_unref(OBJECT(s));
qemu_free_irq(irq);
}
static void test_tvout_submissions(void)
{
IPodTouchTVOutState *s = IPOD_TOUCH_TVOUT(object_new(TYPE_IPOD_TOUCH_TVOUT));
int level = 0;
qemu_irq irq = qemu_allocate_irq(irq_changed, &level, 0);
sysbus_connect_irq(SYS_BUS_DEVICE(s), 0, irq);
/* L'ancien quota global cessait de répondre dès la troisième soumission. */
for (int cycle = 0; cycle < 20; cycle++) {
ipod_touch_tvout_mixer1_write(s, MXR_STATUS, 0x85, 4);
g_assert_cmpint(level, ==, 1);
ipod_touch_tvout_sdo_write(s, SDO_IRQ, 2, 4);
g_assert_cmpint(level, ==, 1);
ipod_touch_tvout_sdo_write(s, SDO_IRQ, 1, 4);
g_assert_cmpint(level, ==, 0);
}
ipod_touch_tvout_sdo_write(s, SDO_IRQMASK, 1, 4);
ipod_touch_tvout_mixer1_write(s, MXR_STATUS, 0x85, 4);
g_assert_cmpint(level, ==, 0);
g_assert_cmpuint(ipod_touch_tvout_sdo_read(s, SDO_IRQ, 4), ==, 1);
ipod_touch_tvout_sdo_write(s, SDO_IRQMASK, 0, 4);
g_assert_cmpint(level, ==, 1);
device_cold_reset(DEVICE(s));
g_assert_cmpint(level, ==, 0);
g_assert_cmpuint(ipod_touch_tvout_sdo_read(s, SDO_IRQ, 4), ==, 0);
ipod_touch_tvout_mixer1_write(s, MXR_STATUS, 0x85, 4);
g_assert_cmpint(level, ==, 1);
object_unref(OBJECT(s));
qemu_free_irq(irq);
}
static void test_panel_reset(void)
{
IPodTouchMIPIDSIState *s = IPOD_TOUCH_MIPI_DSI(object_new(TYPE_IPOD_TOUCH_MIPI_DSI));
for (int cycle = 0; cycle < 3; cycle++) {
ipod_touch_mipi_dsi_write(s, REG_CLKCTRL, DSIM_CLKCTRL_TX_REQUEST_HSCLK, 4);
g_assert_cmpuint(ipod_touch_mipi_dsi_read(s, 0, 4) & rDSIM_STATUS_TxReadyHsClk, !=, 0);
g_assert_cmpuint(ipod_touch_mipi_dsi_read(s, REG_RXFIFO, 4), ==, 0x31a);
/* Un reset pendant une réponse doit recommencer par son en-tête. */
device_cold_reset(DEVICE(s));
g_assert_cmpuint(ipod_touch_mipi_dsi_read(s, 0, 4) & rDSIM_STATUS_TxReadyHsClk, ==, 0);
g_assert_cmpuint(ipod_touch_mipi_dsi_read(s, REG_RXFIFO, 4), ==, 0x31a);
g_assert_cmpuint(ipod_touch_mipi_dsi_read(s, REG_RXFIFO, 4), ==, 0x00a1d13c);
}
object_unref(OBJECT(s));
}
int main(int argc, char **argv)
{
g_test_init(&argc, &argv, NULL);
module_call_init(MODULE_INIT_QOM);
qemu_init_main_loop(&error_abort);
qemu_init_cpu_loop();
qemu_mutex_lock_iothread();
g_test_add_func("/ipod-lcd/interrupt-reenable", test_interrupt_reenable);
g_test_add_func("/ipod-tvout/repeated-submissions", test_tvout_submissions);
g_test_add_func("/ipod-mipi/panel-reset", test_panel_reset);
return g_test_run();
}