]> git.proxmox.com Git - mirror_qemu.git/blobdiff - hw/omap2.c
hpet: Save/restore cached RTC IRQ level
[mirror_qemu.git] / hw / omap2.c
index 6a681d60f38beaaf9ca922dca190ec7e613b2386..a6851b0fb08b234e80a950a5376adfb8013386cf 100644 (file)
  * You should have received a copy of the GNU General Public License along
  * with this program; if not, see <http://www.gnu.org/licenses/>.
  */
-#include "hw.h"
-#include "arm-misc.h"
-#include "omap.h"
-#include "sysemu.h"
-#include "qemu-timer.h"
-#include "qemu-char.h"
-#include "flash.h"
-#include "soc_dma.h"
-#include "audio/audio.h"
-
-/* GP timers */
-struct omap_gp_timer_s {
-    qemu_irq irq;
-    qemu_irq wkup;
-    qemu_irq in;
-    qemu_irq out;
-    omap_clk clk;
-    QEMUTimer *timer;
-    QEMUTimer *match;
-    struct omap_target_agent_s *ta;
-
-    int in_val;
-    int out_val;
-    int64_t time;
-    int64_t rate;
-    int64_t ticks_per_sec;
-
-    int16_t config;
-    int status;
-    int it_ena;
-    int wu_ena;
-    int enable;
-    int inout;
-    int capt2;
-    int pt;
-    enum {
-        gpt_trigger_none, gpt_trigger_overflow, gpt_trigger_both
-    } trigger;
-    enum {
-        gpt_capture_none, gpt_capture_rising,
-        gpt_capture_falling, gpt_capture_both
-    } capture;
-    int scpwm;
-    int ce;
-    int pre;
-    int ptv;
-    int ar;
-    int st;
-    int posted;
-    uint32_t val;
-    uint32_t load_val;
-    uint32_t capture_val[2];
-    uint32_t match_val;
-    int capt_num;
-
-    uint16_t writeh;   /* LSB */
-    uint16_t readh;    /* MSB */
-};
-
-#define GPT_TCAR_IT    (1 << 2)
-#define GPT_OVF_IT     (1 << 1)
-#define GPT_MAT_IT     (1 << 0)
-
-static inline void omap_gp_timer_intr(struct omap_gp_timer_s *timer, int it)
-{
-    if (timer->it_ena & it) {
-        if (!timer->status)
-            qemu_irq_raise(timer->irq);
-
-        timer->status |= it;
-        /* Or are the status bits set even when masked?
-         * i.e. is masking applied before or after the status register?  */
-    }
-
-    if (timer->wu_ena & it)
-        qemu_irq_pulse(timer->wkup);
-}
-
-static inline void omap_gp_timer_out(struct omap_gp_timer_s *timer, int level)
-{
-    if (!timer->inout && timer->out_val != level) {
-        timer->out_val = level;
-        qemu_set_irq(timer->out, level);
-    }
-}
-
-static inline uint32_t omap_gp_timer_read(struct omap_gp_timer_s *timer)
-{
-    uint64_t distance;
-
-    if (timer->st && timer->rate) {
-        distance = qemu_get_clock(vm_clock) - timer->time;
-        distance = muldiv64(distance, timer->rate, timer->ticks_per_sec);
-
-        if (distance >= 0xffffffff - timer->val)
-            return 0xffffffff;
-        else
-            return timer->val + distance;
-    } else
-        return timer->val;
-}
-
-static inline void omap_gp_timer_sync(struct omap_gp_timer_s *timer)
-{
-    if (timer->st) {
-        timer->val = omap_gp_timer_read(timer);
-        timer->time = qemu_get_clock(vm_clock);
-    }
-}
-
-static inline void omap_gp_timer_update(struct omap_gp_timer_s *timer)
-{
-    int64_t expires, matches;
-
-    if (timer->st && timer->rate) {
-        expires = muldiv64(0x100000000ll - timer->val,
-                        timer->ticks_per_sec, timer->rate);
-        qemu_mod_timer(timer->timer, timer->time + expires);
-
-        if (timer->ce && timer->match_val >= timer->val) {
-            matches = muldiv64(timer->match_val - timer->val,
-                            timer->ticks_per_sec, timer->rate);
-            qemu_mod_timer(timer->match, timer->time + matches);
-        } else
-            qemu_del_timer(timer->match);
-    } else {
-        qemu_del_timer(timer->timer);
-        qemu_del_timer(timer->match);
-        omap_gp_timer_out(timer, timer->scpwm);
-    }
-}
-
-static inline void omap_gp_timer_trigger(struct omap_gp_timer_s *timer)
-{
-    if (timer->pt)
-        /* TODO in overflow-and-match mode if the first event to
-         * occur is the match, don't toggle.  */
-        omap_gp_timer_out(timer, !timer->out_val);
-    else
-        /* TODO inverted pulse on timer->out_val == 1?  */
-        qemu_irq_pulse(timer->out);
-}
-
-static void omap_gp_timer_tick(void *opaque)
-{
-    struct omap_gp_timer_s *timer = (struct omap_gp_timer_s *) opaque;
-
-    if (!timer->ar) {
-        timer->st = 0;
-        timer->val = 0;
-    } else {
-        timer->val = timer->load_val;
-        timer->time = qemu_get_clock(vm_clock);
-    }
-
-    if (timer->trigger == gpt_trigger_overflow ||
-                    timer->trigger == gpt_trigger_both)
-        omap_gp_timer_trigger(timer);
-
-    omap_gp_timer_intr(timer, GPT_OVF_IT);
-    omap_gp_timer_update(timer);
-}
-
-static void omap_gp_timer_match(void *opaque)
-{
-    struct omap_gp_timer_s *timer = (struct omap_gp_timer_s *) opaque;
-
-    if (timer->trigger == gpt_trigger_both)
-        omap_gp_timer_trigger(timer);
-
-    omap_gp_timer_intr(timer, GPT_MAT_IT);
-}
-
-static void omap_gp_timer_input(void *opaque, int line, int on)
-{
-    struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque;
-    int trigger;
-
-    switch (s->capture) {
-    default:
-    case gpt_capture_none:
-        trigger = 0;
-        break;
-    case gpt_capture_rising:
-        trigger = !s->in_val && on;
-        break;
-    case gpt_capture_falling:
-        trigger = s->in_val && !on;
-        break;
-    case gpt_capture_both:
-        trigger = (s->in_val == !on);
-        break;
-    }
-    s->in_val = on;
-
-    if (s->inout && trigger && s->capt_num < 2) {
-        s->capture_val[s->capt_num] = omap_gp_timer_read(s);
-
-        if (s->capt2 == s->capt_num ++)
-            omap_gp_timer_intr(s, GPT_TCAR_IT);
-    }
-}
-
-static void omap_gp_timer_clk_update(void *opaque, int line, int on)
-{
-    struct omap_gp_timer_s *timer = (struct omap_gp_timer_s *) opaque;
-
-    omap_gp_timer_sync(timer);
-    timer->rate = on ? omap_clk_getrate(timer->clk) : 0;
-    omap_gp_timer_update(timer);
-}
-
-static void omap_gp_timer_clk_setup(struct omap_gp_timer_s *timer)
-{
-    omap_clk_adduser(timer->clk,
-                    qemu_allocate_irqs(omap_gp_timer_clk_update, timer, 1)[0]);
-    timer->rate = omap_clk_getrate(timer->clk);
-}
-
-static void omap_gp_timer_reset(struct omap_gp_timer_s *s)
-{
-    s->config = 0x000;
-    s->status = 0;
-    s->it_ena = 0;
-    s->wu_ena = 0;
-    s->inout = 0;
-    s->capt2 = 0;
-    s->capt_num = 0;
-    s->pt = 0;
-    s->trigger = gpt_trigger_none;
-    s->capture = gpt_capture_none;
-    s->scpwm = 0;
-    s->ce = 0;
-    s->pre = 0;
-    s->ptv = 0;
-    s->ar = 0;
-    s->st = 0;
-    s->posted = 1;
-    s->val = 0x00000000;
-    s->load_val = 0x00000000;
-    s->capture_val[0] = 0x00000000;
-    s->capture_val[1] = 0x00000000;
-    s->match_val = 0x00000000;
-    omap_gp_timer_update(s);
-}
-
-static uint32_t omap_gp_timer_readw(void *opaque, target_phys_addr_t addr)
-{
-    struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque;
-
-    switch (addr) {
-    case 0x00: /* TIDR */
-        return 0x21;
-
-    case 0x10: /* TIOCP_CFG */
-        return s->config;
-
-    case 0x14: /* TISTAT */
-        /* ??? When's this bit reset? */
-        return 1;                                              /* RESETDONE */
-
-    case 0x18: /* TISR */
-        return s->status;
-
-    case 0x1c: /* TIER */
-        return s->it_ena;
-
-    case 0x20: /* TWER */
-        return s->wu_ena;
-
-    case 0x24: /* TCLR */
-        return (s->inout << 14) |
-                (s->capt2 << 13) |
-                (s->pt << 12) |
-                (s->trigger << 10) |
-                (s->capture << 8) |
-                (s->scpwm << 7) |
-                (s->ce << 6) |
-                (s->pre << 5) |
-                (s->ptv << 2) |
-                (s->ar << 1) |
-                (s->st << 0);
-
-    case 0x28: /* TCRR */
-        return omap_gp_timer_read(s);
-
-    case 0x2c: /* TLDR */
-        return s->load_val;
-
-    case 0x30: /* TTGR */
-        return 0xffffffff;
-
-    case 0x34: /* TWPS */
-        return 0x00000000;     /* No posted writes pending.  */
-
-    case 0x38: /* TMAR */
-        return s->match_val;
-
-    case 0x3c: /* TCAR1 */
-        return s->capture_val[0];
-
-    case 0x40: /* TSICR */
-        return s->posted << 2;
-
-    case 0x44: /* TCAR2 */
-        return s->capture_val[1];
-    }
-
-    OMAP_BAD_REG(addr);
-    return 0;
-}
-
-static uint32_t omap_gp_timer_readh(void *opaque, target_phys_addr_t addr)
-{
-    struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque;
-    uint32_t ret;
-
-    if (addr & 2)
-        return s->readh;
-    else {
-        ret = omap_gp_timer_readw(opaque, addr);
-        s->readh = ret >> 16;
-        return ret & 0xffff;
-    }
-}
-
-static CPUReadMemoryFunc * const omap_gp_timer_readfn[] = {
-    omap_badwidth_read32,
-    omap_gp_timer_readh,
-    omap_gp_timer_readw,
-};
-
-static void omap_gp_timer_write(void *opaque, target_phys_addr_t addr,
-                uint32_t value)
-{
-    struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque;
-
-    switch (addr) {
-    case 0x00: /* TIDR */
-    case 0x14: /* TISTAT */
-    case 0x34: /* TWPS */
-    case 0x3c: /* TCAR1 */
-    case 0x44: /* TCAR2 */
-        OMAP_RO_REG(addr);
-        break;
-
-    case 0x10: /* TIOCP_CFG */
-        s->config = value & 0x33d;
-        if (((value >> 3) & 3) == 3)                           /* IDLEMODE */
-            fprintf(stderr, "%s: illegal IDLEMODE value in TIOCP_CFG\n",
-                            __FUNCTION__);
-        if (value & 2)                                         /* SOFTRESET */
-            omap_gp_timer_reset(s);
-        break;
-
-    case 0x18: /* TISR */
-        if (value & GPT_TCAR_IT)
-            s->capt_num = 0;
-        if (s->status && !(s->status &= ~value))
-            qemu_irq_lower(s->irq);
-        break;
-
-    case 0x1c: /* TIER */
-        s->it_ena = value & 7;
-        break;
-
-    case 0x20: /* TWER */
-        s->wu_ena = value & 7;
-        break;
-
-    case 0x24: /* TCLR */
-        omap_gp_timer_sync(s);
-        s->inout = (value >> 14) & 1;
-        s->capt2 = (value >> 13) & 1;
-        s->pt = (value >> 12) & 1;
-        s->trigger = (value >> 10) & 3;
-        if (s->capture == gpt_capture_none &&
-                        ((value >> 8) & 3) != gpt_capture_none)
-            s->capt_num = 0;
-        s->capture = (value >> 8) & 3;
-        s->scpwm = (value >> 7) & 1;
-        s->ce = (value >> 6) & 1;
-        s->pre = (value >> 5) & 1;
-        s->ptv = (value >> 2) & 7;
-        s->ar = (value >> 1) & 1;
-        s->st = (value >> 0) & 1;
-        if (s->inout && s->trigger != gpt_trigger_none)
-            fprintf(stderr, "%s: GP timer pin must be an output "
-                            "for this trigger mode\n", __FUNCTION__);
-        if (!s->inout && s->capture != gpt_capture_none)
-            fprintf(stderr, "%s: GP timer pin must be an input "
-                            "for this capture mode\n", __FUNCTION__);
-        if (s->trigger == gpt_trigger_none)
-            omap_gp_timer_out(s, s->scpwm);
-        /* TODO: make sure this doesn't overflow 32-bits */
-        s->ticks_per_sec = ticks_per_sec << (s->pre ? s->ptv + 1 : 0);
-        omap_gp_timer_update(s);
-        break;
-
-    case 0x28: /* TCRR */
-        s->time = qemu_get_clock(vm_clock);
-        s->val = value;
-        omap_gp_timer_update(s);
-        break;
-
-    case 0x2c: /* TLDR */
-        s->load_val = value;
-        break;
-
-    case 0x30: /* TTGR */
-        s->time = qemu_get_clock(vm_clock);
-        s->val = s->load_val;
-        omap_gp_timer_update(s);
-        break;
-
-    case 0x38: /* TMAR */
-        omap_gp_timer_sync(s);
-        s->match_val = value;
-        omap_gp_timer_update(s);
-        break;
-
-    case 0x40: /* TSICR */
-        s->posted = (value >> 2) & 1;
-        if (value & 2) /* How much exactly are we supposed to reset? */
-            omap_gp_timer_reset(s);
-        break;
-
-    default:
-        OMAP_BAD_REG(addr);
-    }
-}
-
-static void omap_gp_timer_writeh(void *opaque, target_phys_addr_t addr,
-                uint32_t value)
-{
-    struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque;
-
-    if (addr & 2)
-        return omap_gp_timer_write(opaque, addr, (value << 16) | s->writeh);
-    else
-        s->writeh = (uint16_t) value;
-}
-
-static CPUWriteMemoryFunc * const omap_gp_timer_writefn[] = {
-    omap_badwidth_write32,
-    omap_gp_timer_writeh,
-    omap_gp_timer_write,
-};
-
-struct omap_gp_timer_s *omap_gp_timer_init(struct omap_target_agent_s *ta,
-                qemu_irq irq, omap_clk fclk, omap_clk iclk)
-{
-    int iomemtype;
-    struct omap_gp_timer_s *s = (struct omap_gp_timer_s *)
-            qemu_mallocz(sizeof(struct omap_gp_timer_s));
-
-    s->ta = ta;
-    s->irq = irq;
-    s->clk = fclk;
-    s->timer = qemu_new_timer(vm_clock, omap_gp_timer_tick, s);
-    s->match = qemu_new_timer(vm_clock, omap_gp_timer_match, s);
-    s->in = qemu_allocate_irqs(omap_gp_timer_input, s, 1)[0];
-    omap_gp_timer_reset(s);
-    omap_gp_timer_clk_setup(s);
-
-    iomemtype = l4_register_io_memory(omap_gp_timer_readfn,
-                    omap_gp_timer_writefn, s);
-    omap_l4_attach(ta, 0, iomemtype);
-
-    return s;
-}
-
-/* 32-kHz Sync Timer of the OMAP2 */
-static uint32_t omap_synctimer_read(struct omap_synctimer_s *s) {
-    return muldiv64(qemu_get_clock(vm_clock), 0x8000, ticks_per_sec);
-}
-
-static void omap_synctimer_reset(struct omap_synctimer_s *s)
-{
-    s->val = omap_synctimer_read(s);
-}
-
-static uint32_t omap_synctimer_readw(void *opaque, target_phys_addr_t addr)
-{
-    struct omap_synctimer_s *s = (struct omap_synctimer_s *) opaque;
-
-    switch (addr) {
-    case 0x00: /* 32KSYNCNT_REV */
-        return 0x21;
-
-    case 0x10: /* CR */
-        return omap_synctimer_read(s) - s->val;
-    }
-
-    OMAP_BAD_REG(addr);
-    return 0;
-}
-
-static uint32_t omap_synctimer_readh(void *opaque, target_phys_addr_t addr)
-{
-    struct omap_synctimer_s *s = (struct omap_synctimer_s *) opaque;
-    uint32_t ret;
-
-    if (addr & 2)
-        return s->readh;
-    else {
-        ret = omap_synctimer_readw(opaque, addr);
-        s->readh = ret >> 16;
-        return ret & 0xffff;
-    }
-}
-
-static CPUReadMemoryFunc * const omap_synctimer_readfn[] = {
-    omap_badwidth_read32,
-    omap_synctimer_readh,
-    omap_synctimer_readw,
-};
-
-static void omap_synctimer_write(void *opaque, target_phys_addr_t addr,
-                uint32_t value)
-{
-    OMAP_BAD_REG(addr);
-}
-
-static CPUWriteMemoryFunc * const omap_synctimer_writefn[] = {
-    omap_badwidth_write32,
-    omap_synctimer_write,
-    omap_synctimer_write,
-};
-
-void omap_synctimer_init(struct omap_target_agent_s *ta,
-                struct omap_mpu_state_s *mpu, omap_clk fclk, omap_clk iclk)
-{
-    struct omap_synctimer_s *s = &mpu->synctimer;
-
-    omap_synctimer_reset(s);
-    omap_l4_attach(ta, 0, l4_register_io_memory(
-                      omap_synctimer_readfn, omap_synctimer_writefn, s));
-}
-
-/* General-Purpose Interface of OMAP2 */
-struct omap2_gpio_s {
-    qemu_irq irq[2];
-    qemu_irq wkup;
-    qemu_irq *in;
-    qemu_irq handler[32];
-
-    uint8_t config[2];
-    uint32_t inputs;
-    uint32_t outputs;
-    uint32_t dir;
-    uint32_t level[2];
-    uint32_t edge[2];
-    uint32_t mask[2];
-    uint32_t wumask;
-    uint32_t ints[2];
-    uint32_t debounce;
-    uint8_t delay;
-};
-
-static inline void omap_gpio_module_int_update(struct omap2_gpio_s *s,
-                int line)
-{
-    qemu_set_irq(s->irq[line], s->ints[line] & s->mask[line]);
-}
-
-static void omap_gpio_module_wake(struct omap2_gpio_s *s, int line)
-{
-    if (!(s->config[0] & (1 << 2)))                    /* ENAWAKEUP */
-        return;
-    if (!(s->config[0] & (3 << 3)))                    /* Force Idle */
-        return;
-    if (!(s->wumask & (1 << line)))
-        return;
-
-    qemu_irq_raise(s->wkup);
-}
-
-static inline void omap_gpio_module_out_update(struct omap2_gpio_s *s,
-                uint32_t diff)
-{
-    int ln;
-
-    s->outputs ^= diff;
-    diff &= ~s->dir;
-    while ((ln = ffs(diff))) {
-        ln --;
-        qemu_set_irq(s->handler[ln], (s->outputs >> ln) & 1);
-        diff &= ~(1 << ln);
-    }
-}
-
-static void omap_gpio_module_level_update(struct omap2_gpio_s *s, int line)
-{
-    s->ints[line] |= s->dir &
-            ((s->inputs & s->level[1]) | (~s->inputs & s->level[0]));
-    omap_gpio_module_int_update(s, line);
-}
-
-static inline void omap_gpio_module_int(struct omap2_gpio_s *s, int line)
-{
-    s->ints[0] |= 1 << line;
-    omap_gpio_module_int_update(s, 0);
-    s->ints[1] |= 1 << line;
-    omap_gpio_module_int_update(s, 1);
-    omap_gpio_module_wake(s, line);
-}
-
-static void omap_gpio_module_set(void *opaque, int line, int level)
-{
-    struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;
-
-    if (level) {
-        if (s->dir & (1 << line) & ((~s->inputs & s->edge[0]) | s->level[1]))
-            omap_gpio_module_int(s, line);
-        s->inputs |= 1 << line;
-    } else {
-        if (s->dir & (1 << line) & ((s->inputs & s->edge[1]) | s->level[0]))
-            omap_gpio_module_int(s, line);
-        s->inputs &= ~(1 << line);
-    }
-}
-
-static void omap_gpio_module_reset(struct omap2_gpio_s *s)
-{
-    s->config[0] = 0;
-    s->config[1] = 2;
-    s->ints[0] = 0;
-    s->ints[1] = 0;
-    s->mask[0] = 0;
-    s->mask[1] = 0;
-    s->wumask = 0;
-    s->dir = ~0;
-    s->level[0] = 0;
-    s->level[1] = 0;
-    s->edge[0] = 0;
-    s->edge[1] = 0;
-    s->debounce = 0;
-    s->delay = 0;
-}
-
-static uint32_t omap_gpio_module_read(void *opaque, target_phys_addr_t addr)
-{
-    struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;
-
-    switch (addr) {
-    case 0x00: /* GPIO_REVISION */
-        return 0x18;
-
-    case 0x10: /* GPIO_SYSCONFIG */
-        return s->config[0];
-
-    case 0x14: /* GPIO_SYSSTATUS */
-        return 0x01;
-
-    case 0x18: /* GPIO_IRQSTATUS1 */
-        return s->ints[0];
-
-    case 0x1c: /* GPIO_IRQENABLE1 */
-    case 0x60: /* GPIO_CLEARIRQENABLE1 */
-    case 0x64: /* GPIO_SETIRQENABLE1 */
-        return s->mask[0];
-
-    case 0x20: /* GPIO_WAKEUPENABLE */
-    case 0x80: /* GPIO_CLEARWKUENA */
-    case 0x84: /* GPIO_SETWKUENA */
-        return s->wumask;
-
-    case 0x28: /* GPIO_IRQSTATUS2 */
-        return s->ints[1];
-
-    case 0x2c: /* GPIO_IRQENABLE2 */
-    case 0x70: /* GPIO_CLEARIRQENABLE2 */
-    case 0x74: /* GPIO_SETIREQNEABLE2 */
-        return s->mask[1];
-
-    case 0x30: /* GPIO_CTRL */
-        return s->config[1];
-
-    case 0x34: /* GPIO_OE */
-        return s->dir;
-
-    case 0x38: /* GPIO_DATAIN */
-        return s->inputs;
-
-    case 0x3c: /* GPIO_DATAOUT */
-    case 0x90: /* GPIO_CLEARDATAOUT */
-    case 0x94: /* GPIO_SETDATAOUT */
-        return s->outputs;
-
-    case 0x40: /* GPIO_LEVELDETECT0 */
-        return s->level[0];
-
-    case 0x44: /* GPIO_LEVELDETECT1 */
-        return s->level[1];
-
-    case 0x48: /* GPIO_RISINGDETECT */
-        return s->edge[0];
-
-    case 0x4c: /* GPIO_FALLINGDETECT */
-        return s->edge[1];
-
-    case 0x50: /* GPIO_DEBOUNCENABLE */
-        return s->debounce;
-
-    case 0x54: /* GPIO_DEBOUNCINGTIME */
-        return s->delay;
-    }
-
-    OMAP_BAD_REG(addr);
-    return 0;
-}
-
-static void omap_gpio_module_write(void *opaque, target_phys_addr_t addr,
-                uint32_t value)
-{
-    struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;
-    uint32_t diff;
-    int ln;
-
-    switch (addr) {
-    case 0x00: /* GPIO_REVISION */
-    case 0x14: /* GPIO_SYSSTATUS */
-    case 0x38: /* GPIO_DATAIN */
-        OMAP_RO_REG(addr);
-        break;
-
-    case 0x10: /* GPIO_SYSCONFIG */
-        if (((value >> 3) & 3) == 3)
-            fprintf(stderr, "%s: bad IDLEMODE value\n", __FUNCTION__);
-        if (value & 2)
-            omap_gpio_module_reset(s);
-        s->config[0] = value & 0x1d;
-        break;
-
-    case 0x18: /* GPIO_IRQSTATUS1 */
-        if (s->ints[0] & value) {
-            s->ints[0] &= ~value;
-            omap_gpio_module_level_update(s, 0);
-        }
-        break;
-
-    case 0x1c: /* GPIO_IRQENABLE1 */
-        s->mask[0] = value;
-        omap_gpio_module_int_update(s, 0);
-        break;
-
-    case 0x20: /* GPIO_WAKEUPENABLE */
-        s->wumask = value;
-        break;
-
-    case 0x28: /* GPIO_IRQSTATUS2 */
-        if (s->ints[1] & value) {
-            s->ints[1] &= ~value;
-            omap_gpio_module_level_update(s, 1);
-        }
-        break;
-
-    case 0x2c: /* GPIO_IRQENABLE2 */
-        s->mask[1] = value;
-        omap_gpio_module_int_update(s, 1);
-        break;
-
-    case 0x30: /* GPIO_CTRL */
-        s->config[1] = value & 7;
-        break;
-
-    case 0x34: /* GPIO_OE */
-        diff = s->outputs & (s->dir ^ value);
-        s->dir = value;
-
-        value = s->outputs & ~s->dir;
-        while ((ln = ffs(diff))) {
-            diff &= ~(1 <<-- ln);
-            qemu_set_irq(s->handler[ln], (value >> ln) & 1);
-        }
-
-        omap_gpio_module_level_update(s, 0);
-        omap_gpio_module_level_update(s, 1);
-        break;
-
-    case 0x3c: /* GPIO_DATAOUT */
-        omap_gpio_module_out_update(s, s->outputs ^ value);
-        break;
-
-    case 0x40: /* GPIO_LEVELDETECT0 */
-        s->level[0] = value;
-        omap_gpio_module_level_update(s, 0);
-        omap_gpio_module_level_update(s, 1);
-        break;
-
-    case 0x44: /* GPIO_LEVELDETECT1 */
-        s->level[1] = value;
-        omap_gpio_module_level_update(s, 0);
-        omap_gpio_module_level_update(s, 1);
-        break;
-
-    case 0x48: /* GPIO_RISINGDETECT */
-        s->edge[0] = value;
-        break;
-
-    case 0x4c: /* GPIO_FALLINGDETECT */
-        s->edge[1] = value;
-        break;
-
-    case 0x50: /* GPIO_DEBOUNCENABLE */
-        s->debounce = value;
-        break;
-
-    case 0x54: /* GPIO_DEBOUNCINGTIME */
-        s->delay = value;
-        break;
-
-    case 0x60: /* GPIO_CLEARIRQENABLE1 */
-        s->mask[0] &= ~value;
-        omap_gpio_module_int_update(s, 0);
-        break;
-
-    case 0x64: /* GPIO_SETIRQENABLE1 */
-        s->mask[0] |= value;
-        omap_gpio_module_int_update(s, 0);
-        break;
-
-    case 0x70: /* GPIO_CLEARIRQENABLE2 */
-        s->mask[1] &= ~value;
-        omap_gpio_module_int_update(s, 1);
-        break;
-
-    case 0x74: /* GPIO_SETIREQNEABLE2 */
-        s->mask[1] |= value;
-        omap_gpio_module_int_update(s, 1);
-        break;
-
-    case 0x80: /* GPIO_CLEARWKUENA */
-        s->wumask &= ~value;
-        break;
-
-    case 0x84: /* GPIO_SETWKUENA */
-        s->wumask |= value;
-        break;
-
-    case 0x90: /* GPIO_CLEARDATAOUT */
-        omap_gpio_module_out_update(s, s->outputs & value);
-        break;
-
-    case 0x94: /* GPIO_SETDATAOUT */
-        omap_gpio_module_out_update(s, ~s->outputs & value);
-        break;
-
-    default:
-        OMAP_BAD_REG(addr);
-        return;
-    }
-}
-
-static uint32_t omap_gpio_module_readp(void *opaque, target_phys_addr_t addr)
-{
-    return omap_gpio_module_readp(opaque, addr) >> ((addr & 3) << 3);
-}
-
-static void omap_gpio_module_writep(void *opaque, target_phys_addr_t addr,
-                uint32_t value)
-{
-    uint32_t cur = 0;
-    uint32_t mask = 0xffff;
-
-    switch (addr & ~3) {
-    case 0x00: /* GPIO_REVISION */
-    case 0x14: /* GPIO_SYSSTATUS */
-    case 0x38: /* GPIO_DATAIN */
-        OMAP_RO_REG(addr);
-        break;
-
-    case 0x10: /* GPIO_SYSCONFIG */
-    case 0x1c: /* GPIO_IRQENABLE1 */
-    case 0x20: /* GPIO_WAKEUPENABLE */
-    case 0x2c: /* GPIO_IRQENABLE2 */
-    case 0x30: /* GPIO_CTRL */
-    case 0x34: /* GPIO_OE */
-    case 0x3c: /* GPIO_DATAOUT */
-    case 0x40: /* GPIO_LEVELDETECT0 */
-    case 0x44: /* GPIO_LEVELDETECT1 */
-    case 0x48: /* GPIO_RISINGDETECT */
-    case 0x4c: /* GPIO_FALLINGDETECT */
-    case 0x50: /* GPIO_DEBOUNCENABLE */
-    case 0x54: /* GPIO_DEBOUNCINGTIME */
-        cur = omap_gpio_module_read(opaque, addr & ~3) &
-                ~(mask << ((addr & 3) << 3));
-
-        /* Fall through.  */
-    case 0x18: /* GPIO_IRQSTATUS1 */
-    case 0x28: /* GPIO_IRQSTATUS2 */
-    case 0x60: /* GPIO_CLEARIRQENABLE1 */
-    case 0x64: /* GPIO_SETIRQENABLE1 */
-    case 0x70: /* GPIO_CLEARIRQENABLE2 */
-    case 0x74: /* GPIO_SETIREQNEABLE2 */
-    case 0x80: /* GPIO_CLEARWKUENA */
-    case 0x84: /* GPIO_SETWKUENA */
-    case 0x90: /* GPIO_CLEARDATAOUT */
-    case 0x94: /* GPIO_SETDATAOUT */
-        value <<= (addr & 3) << 3;
-        omap_gpio_module_write(opaque, addr, cur | value);
-        break;
-
-    default:
-        OMAP_BAD_REG(addr);
-        return;
-    }
-}
-
-static CPUReadMemoryFunc * const omap_gpio_module_readfn[] = {
-    omap_gpio_module_readp,
-    omap_gpio_module_readp,
-    omap_gpio_module_read,
-};
-
-static CPUWriteMemoryFunc * const omap_gpio_module_writefn[] = {
-    omap_gpio_module_writep,
-    omap_gpio_module_writep,
-    omap_gpio_module_write,
-};
-
-static void omap_gpio_module_init(struct omap2_gpio_s *s,
-                struct omap_target_agent_s *ta, int region,
-                qemu_irq mpu, qemu_irq dsp, qemu_irq wkup,
-                omap_clk fclk, omap_clk iclk)
-{
-    int iomemtype;
-
-    s->irq[0] = mpu;
-    s->irq[1] = dsp;
-    s->wkup = wkup;
-    s->in = qemu_allocate_irqs(omap_gpio_module_set, s, 32);
-
-    iomemtype = l4_register_io_memory(omap_gpio_module_readfn,
-                    omap_gpio_module_writefn, s);
-    omap_l4_attach(ta, region, iomemtype);
-}
-
-struct omap_gpif_s {
-    struct omap2_gpio_s module[5];
-    int modules;
-
-    int autoidle;
-    int gpo;
-};
-
-static void omap_gpif_reset(struct omap_gpif_s *s)
-{
-    int i;
-
-    for (i = 0; i < s->modules; i ++)
-        omap_gpio_module_reset(s->module + i);
-
-    s->autoidle = 0;
-    s->gpo = 0;
-}
-
-static uint32_t omap_gpif_top_read(void *opaque, target_phys_addr_t addr)
-{
-    struct omap_gpif_s *s = (struct omap_gpif_s *) opaque;
-
-    switch (addr) {
-    case 0x00: /* IPGENERICOCPSPL_REVISION */
-        return 0x18;
-
-    case 0x10: /* IPGENERICOCPSPL_SYSCONFIG */
-        return s->autoidle;
-
-    case 0x14: /* IPGENERICOCPSPL_SYSSTATUS */
-        return 0x01;
-
-    case 0x18: /* IPGENERICOCPSPL_IRQSTATUS */
-        return 0x00;
-
-    case 0x40: /* IPGENERICOCPSPL_GPO */
-        return s->gpo;
-
-    case 0x50: /* IPGENERICOCPSPL_GPI */
-        return 0x00;
-    }
-
-    OMAP_BAD_REG(addr);
-    return 0;
-}
-
-static void omap_gpif_top_write(void *opaque, target_phys_addr_t addr,
-                uint32_t value)
-{
-    struct omap_gpif_s *s = (struct omap_gpif_s *) opaque;
-
-    switch (addr) {
-    case 0x00: /* IPGENERICOCPSPL_REVISION */
-    case 0x14: /* IPGENERICOCPSPL_SYSSTATUS */
-    case 0x18: /* IPGENERICOCPSPL_IRQSTATUS */
-    case 0x50: /* IPGENERICOCPSPL_GPI */
-        OMAP_RO_REG(addr);
-        break;
-
-    case 0x10: /* IPGENERICOCPSPL_SYSCONFIG */
-        if (value & (1 << 1))                                  /* SOFTRESET */
-            omap_gpif_reset(s);
-        s->autoidle = value & 1;
-        break;
-
-    case 0x40: /* IPGENERICOCPSPL_GPO */
-        s->gpo = value & 1;
-        break;
-
-    default:
-        OMAP_BAD_REG(addr);
-        return;
-    }
-}
-
-static CPUReadMemoryFunc * const omap_gpif_top_readfn[] = {
-    omap_gpif_top_read,
-    omap_gpif_top_read,
-    omap_gpif_top_read,
-};
-
-static CPUWriteMemoryFunc * const omap_gpif_top_writefn[] = {
-    omap_gpif_top_write,
-    omap_gpif_top_write,
-    omap_gpif_top_write,
-};
-
-struct omap_gpif_s *omap2_gpio_init(struct omap_target_agent_s *ta,
-                qemu_irq *irq, omap_clk *fclk, omap_clk iclk, int modules)
-{
-    int iomemtype, i;
-    struct omap_gpif_s *s = (struct omap_gpif_s *)
-            qemu_mallocz(sizeof(struct omap_gpif_s));
-    int region[4] = { 0, 2, 4, 5 };
-
-    s->modules = modules;
-    for (i = 0; i < modules; i ++)
-        omap_gpio_module_init(s->module + i, ta, region[i],
-                        irq[i], 0, 0, fclk[i], iclk);
-
-    omap_gpif_reset(s);
-
-    iomemtype = l4_register_io_memory(omap_gpif_top_readfn,
-                    omap_gpif_top_writefn, s);
-    omap_l4_attach(ta, 1, iomemtype);
-
-    return s;
-}
-
-qemu_irq *omap2_gpio_in_get(struct omap_gpif_s *s, int start)
-{
-    if (start >= s->modules * 32 || start < 0)
-        hw_error("%s: No GPIO line %i\n", __FUNCTION__, start);
-    return s->module[start >> 5].in + (start & 31);
-}
-
-void omap2_gpio_out_set(struct omap_gpif_s *s, int line, qemu_irq handler)
-{
-    if (line >= s->modules * 32 || line < 0)
-        hw_error("%s: No GPIO line %i\n", __FUNCTION__, line);
-    s->module[line >> 5].handler[line & 31] = handler;
-}
-
-/* Multichannel SPI */
-struct omap_mcspi_s {
-    qemu_irq irq;
-    int chnum;
-
-    uint32_t sysconfig;
-    uint32_t systest;
-    uint32_t irqst;
-    uint32_t irqen;
-    uint32_t wken;
-    uint32_t control;
-
-    struct omap_mcspi_ch_s {
-        qemu_irq txdrq;
-        qemu_irq rxdrq;
-        uint32_t (*txrx)(void *opaque, uint32_t, int);
-        void *opaque;
-
-        uint32_t tx;
-        uint32_t rx;
-
-        uint32_t config;
-        uint32_t status;
-        uint32_t control;
-    } ch[4];
-};
-
-static inline void omap_mcspi_interrupt_update(struct omap_mcspi_s *s)
-{
-    qemu_set_irq(s->irq, s->irqst & s->irqen);
-}
-
-static inline void omap_mcspi_dmarequest_update(struct omap_mcspi_ch_s *ch)
-{
-    qemu_set_irq(ch->txdrq,
-                    (ch->control & 1) &&               /* EN */
-                    (ch->config & (1 << 14)) &&                /* DMAW */
-                    (ch->status & (1 << 1)) &&         /* TXS */
-                    ((ch->config >> 12) & 3) != 1);    /* TRM */
-    qemu_set_irq(ch->rxdrq,
-                    (ch->control & 1) &&               /* EN */
-                    (ch->config & (1 << 15)) &&                /* DMAW */
-                    (ch->status & (1 << 0)) &&         /* RXS */
-                    ((ch->config >> 12) & 3) != 2);    /* TRM */
-}
-
-static void omap_mcspi_transfer_run(struct omap_mcspi_s *s, int chnum)
-{
-    struct omap_mcspi_ch_s *ch = s->ch + chnum;
-
-    if (!(ch->control & 1))                            /* EN */
-        return;
-    if ((ch->status & (1 << 0)) &&                     /* RXS */
-                    ((ch->config >> 12) & 3) != 2 &&   /* TRM */
-                    !(ch->config & (1 << 19)))         /* TURBO */
-        goto intr_update;
-    if ((ch->status & (1 << 1)) &&                     /* TXS */
-                    ((ch->config >> 12) & 3) != 1)     /* TRM */
-        goto intr_update;
-
-    if (!(s->control & 1) ||                           /* SINGLE */
-                    (ch->config & (1 << 20))) {                /* FORCE */
-        if (ch->txrx)
-            ch->rx = ch->txrx(ch->opaque, ch->tx,      /* WL */
-                            1 + (0x1f & (ch->config >> 7)));
-    }
-
-    ch->tx = 0;
-    ch->status |= 1 << 2;                              /* EOT */
-    ch->status |= 1 << 1;                              /* TXS */
-    if (((ch->config >> 12) & 3) != 2)                 /* TRM */
-        ch->status |= 1 << 0;                          /* RXS */
-
-intr_update:
-    if ((ch->status & (1 << 0)) &&                     /* RXS */
-                    ((ch->config >> 12) & 3) != 2 &&   /* TRM */
-                    !(ch->config & (1 << 19)))         /* TURBO */
-        s->irqst |= 1 << (2 + 4 * chnum);              /* RX_FULL */
-    if ((ch->status & (1 << 1)) &&                     /* TXS */
-                    ((ch->config >> 12) & 3) != 1)     /* TRM */
-        s->irqst |= 1 << (0 + 4 * chnum);              /* TX_EMPTY */
-    omap_mcspi_interrupt_update(s);
-    omap_mcspi_dmarequest_update(ch);
-}
-
-static void omap_mcspi_reset(struct omap_mcspi_s *s)
-{
-    int ch;
-
-    s->sysconfig = 0;
-    s->systest = 0;
-    s->irqst = 0;
-    s->irqen = 0;
-    s->wken = 0;
-    s->control = 4;
-
-    for (ch = 0; ch < 4; ch ++) {
-        s->ch[ch].config = 0x060000;
-        s->ch[ch].status = 2;                          /* TXS */
-        s->ch[ch].control = 0;
-
-        omap_mcspi_dmarequest_update(s->ch + ch);
-    }
-
-    omap_mcspi_interrupt_update(s);
-}
-
-static uint32_t omap_mcspi_read(void *opaque, target_phys_addr_t addr)
-{
-    struct omap_mcspi_s *s = (struct omap_mcspi_s *) opaque;
-    int ch = 0;
-    uint32_t ret;
-
-    switch (addr) {
-    case 0x00: /* MCSPI_REVISION */
-        return 0x91;
-
-    case 0x10: /* MCSPI_SYSCONFIG */
-        return s->sysconfig;
-
-    case 0x14: /* MCSPI_SYSSTATUS */
-        return 1;                                      /* RESETDONE */
-
-    case 0x18: /* MCSPI_IRQSTATUS */
-        return s->irqst;
-
-    case 0x1c: /* MCSPI_IRQENABLE */
-        return s->irqen;
-
-    case 0x20: /* MCSPI_WAKEUPENABLE */
-        return s->wken;
-
-    case 0x24: /* MCSPI_SYST */
-        return s->systest;
-
-    case 0x28: /* MCSPI_MODULCTRL */
-        return s->control;
-
-    case 0x68: ch ++;
-    case 0x54: ch ++;
-    case 0x40: ch ++;
-    case 0x2c: /* MCSPI_CHCONF */
-        return s->ch[ch].config;
-
-    case 0x6c: ch ++;
-    case 0x58: ch ++;
-    case 0x44: ch ++;
-    case 0x30: /* MCSPI_CHSTAT */
-        return s->ch[ch].status;
-
-    case 0x70: ch ++;
-    case 0x5c: ch ++;
-    case 0x48: ch ++;
-    case 0x34: /* MCSPI_CHCTRL */
-        return s->ch[ch].control;
-
-    case 0x74: ch ++;
-    case 0x60: ch ++;
-    case 0x4c: ch ++;
-    case 0x38: /* MCSPI_TX */
-        return s->ch[ch].tx;
-
-    case 0x78: ch ++;
-    case 0x64: ch ++;
-    case 0x50: ch ++;
-    case 0x3c: /* MCSPI_RX */
-        s->ch[ch].status &= ~(1 << 0);                 /* RXS */
-        ret = s->ch[ch].rx;
-        omap_mcspi_transfer_run(s, ch);
-        return ret;
-    }
-
-    OMAP_BAD_REG(addr);
-    return 0;
-}
-
-static void omap_mcspi_write(void *opaque, target_phys_addr_t addr,
-                uint32_t value)
-{
-    struct omap_mcspi_s *s = (struct omap_mcspi_s *) opaque;
-    int ch = 0;
-
-    switch (addr) {
-    case 0x00: /* MCSPI_REVISION */
-    case 0x14: /* MCSPI_SYSSTATUS */
-    case 0x30: /* MCSPI_CHSTAT0 */
-    case 0x3c: /* MCSPI_RX0 */
-    case 0x44: /* MCSPI_CHSTAT1 */
-    case 0x50: /* MCSPI_RX1 */
-    case 0x58: /* MCSPI_CHSTAT2 */
-    case 0x64: /* MCSPI_RX2 */
-    case 0x6c: /* MCSPI_CHSTAT3 */
-    case 0x78: /* MCSPI_RX3 */
-        OMAP_RO_REG(addr);
-        return;
-
-    case 0x10: /* MCSPI_SYSCONFIG */
-        if (value & (1 << 1))                          /* SOFTRESET */
-            omap_mcspi_reset(s);
-        s->sysconfig = value & 0x31d;
-        break;
-
-    case 0x18: /* MCSPI_IRQSTATUS */
-        if (!((s->control & (1 << 3)) && (s->systest & (1 << 11)))) {
-            s->irqst &= ~value;
-            omap_mcspi_interrupt_update(s);
-        }
-        break;
-
-    case 0x1c: /* MCSPI_IRQENABLE */
-        s->irqen = value & 0x1777f;
-        omap_mcspi_interrupt_update(s);
-        break;
-
-    case 0x20: /* MCSPI_WAKEUPENABLE */
-        s->wken = value & 1;
-        break;
-
-    case 0x24: /* MCSPI_SYST */
-        if (s->control & (1 << 3))                     /* SYSTEM_TEST */
-            if (value & (1 << 11)) {                   /* SSB */
-                s->irqst |= 0x1777f;
-                omap_mcspi_interrupt_update(s);
-            }
-        s->systest = value & 0xfff;
-        break;
-
-    case 0x28: /* MCSPI_MODULCTRL */
-        if (value & (1 << 3))                          /* SYSTEM_TEST */
-            if (s->systest & (1 << 11)) {              /* SSB */
-                s->irqst |= 0x1777f;
-                omap_mcspi_interrupt_update(s);
-            }
-        s->control = value & 0xf;
-        break;
-
-    case 0x68: ch ++;
-    case 0x54: ch ++;
-    case 0x40: ch ++;
-    case 0x2c: /* MCSPI_CHCONF */
-        if ((value ^ s->ch[ch].config) & (3 << 14))    /* DMAR | DMAW */
-            omap_mcspi_dmarequest_update(s->ch + ch);
-        if (((value >> 12) & 3) == 3)                  /* TRM */
-            fprintf(stderr, "%s: invalid TRM value (3)\n", __FUNCTION__);
-        if (((value >> 7) & 0x1f) < 3)                 /* WL */
-            fprintf(stderr, "%s: invalid WL value (%i)\n",
-                            __FUNCTION__, (value >> 7) & 0x1f);
-        s->ch[ch].config = value & 0x7fffff;
-        break;
-
-    case 0x70: ch ++;
-    case 0x5c: ch ++;
-    case 0x48: ch ++;
-    case 0x34: /* MCSPI_CHCTRL */
-        if (value & ~s->ch[ch].control & 1) {          /* EN */
-            s->ch[ch].control |= 1;
-            omap_mcspi_transfer_run(s, ch);
-        } else
-            s->ch[ch].control = value & 1;
-        break;
-
-    case 0x74: ch ++;
-    case 0x60: ch ++;
-    case 0x4c: ch ++;
-    case 0x38: /* MCSPI_TX */
-        s->ch[ch].tx = value;
-        s->ch[ch].status &= ~(1 << 1);                 /* TXS */
-        omap_mcspi_transfer_run(s, ch);
-        break;
-
-    default:
-        OMAP_BAD_REG(addr);
-        return;
-    }
-}
-
-static CPUReadMemoryFunc * const omap_mcspi_readfn[] = {
-    omap_badwidth_read32,
-    omap_badwidth_read32,
-    omap_mcspi_read,
-};
-
-static CPUWriteMemoryFunc * const omap_mcspi_writefn[] = {
-    omap_badwidth_write32,
-    omap_badwidth_write32,
-    omap_mcspi_write,
-};
-
-struct omap_mcspi_s *omap_mcspi_init(struct omap_target_agent_s *ta, int chnum,
-                qemu_irq irq, qemu_irq *drq, omap_clk fclk, omap_clk iclk)
-{
-    int iomemtype;
-    struct omap_mcspi_s *s = (struct omap_mcspi_s *)
-            qemu_mallocz(sizeof(struct omap_mcspi_s));
-    struct omap_mcspi_ch_s *ch = s->ch;
 
-    s->irq = irq;
-    s->chnum = chnum;
-    while (chnum --) {
-        ch->txdrq = *drq ++;
-        ch->rxdrq = *drq ++;
-        ch ++;
-    }
-    omap_mcspi_reset(s);
-
-    iomemtype = l4_register_io_memory(omap_mcspi_readfn,
-                    omap_mcspi_writefn, s);
-    omap_l4_attach(ta, 0, iomemtype);
-
-    return s;
-}
-
-void omap_mcspi_attach(struct omap_mcspi_s *s,
-                uint32_t (*txrx)(void *opaque, uint32_t, int), void *opaque,
-                int chipselect)
-{
-    if (chipselect < 0 || chipselect >= s->chnum)
-        hw_error("%s: Bad chipselect %i\n", __FUNCTION__, chipselect);
-
-    s->ch[chipselect].txrx = txrx;
-    s->ch[chipselect].opaque = opaque;
-}
+#include "blockdev.h"
+#include "hw.h"
+#include "arm-misc.h"
+#include "omap.h"
+#include "sysemu.h"
+#include "qemu-timer.h"
+#include "qemu-char.h"
+#include "flash.h"
+#include "soc_dma.h"
+#include "sysbus.h"
+#include "audio/audio.h"
 
 /* Enhanced Audio Controller (CODEC only) */
 struct omap_eac_s {
     qemu_irq irq;
+    MemoryRegion iomem;
 
     uint16_t sysconfig;
     uint8_t config[4];
@@ -1615,13 +243,13 @@ static void omap_eac_format_update(struct omap_eac_s *s)
     if (s->codec.in_voice) {
         AUD_set_active_in(s->codec.in_voice, 0);
         AUD_close_in(&s->codec.card, s->codec.in_voice);
-        s->codec.in_voice = 0;
+        s->codec.in_voice = NULL;
     }
     if (s->codec.out_voice) {
         omap_eac_out_empty(s);
         AUD_set_active_out(s->codec.out_voice, 0);
         AUD_close_out(&s->codec.card, s->codec.out_voice);
-        s->codec.out_voice = 0;
+        s->codec.out_voice = NULL;
         s->codec.txavail = 0;
     }
     /* Discard what couldn't be written */
@@ -1696,11 +324,16 @@ static void omap_eac_reset(struct omap_eac_s *s)
     omap_eac_interrupt_update(s);
 }
 
-static uint32_t omap_eac_read(void *opaque, target_phys_addr_t addr)
+static uint64_t omap_eac_read(void *opaque, target_phys_addr_t addr,
+                              unsigned size)
 {
     struct omap_eac_s *s = (struct omap_eac_s *) opaque;
     uint32_t ret;
 
+    if (size != 2) {
+        return omap_badwidth_read16(opaque, addr);
+    }
+
     switch (addr) {
     case 0x000:        /* CPCFR1 */
         return s->config[0];
@@ -1808,10 +441,14 @@ static uint32_t omap_eac_read(void *opaque, target_phys_addr_t addr)
 }
 
 static void omap_eac_write(void *opaque, target_phys_addr_t addr,
-                uint32_t value)
+                           uint64_t value, unsigned size)
 {
     struct omap_eac_s *s = (struct omap_eac_s *) opaque;
 
+    if (size != 2) {
+        return omap_badwidth_write16(opaque, addr, value);
+    }
+
     switch (addr) {
     case 0x098:        /* APD1LCR */
     case 0x09c:        /* APD1RCR */
@@ -1947,37 +584,28 @@ static void omap_eac_write(void *opaque, target_phys_addr_t addr,
     }
 }
 
-static CPUReadMemoryFunc * const omap_eac_readfn[] = {
-    omap_badwidth_read16,
-    omap_eac_read,
-    omap_badwidth_read16,
+static const MemoryRegionOps omap_eac_ops = {
+    .read = omap_eac_read,
+    .write = omap_eac_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static CPUWriteMemoryFunc * const omap_eac_writefn[] = {
-    omap_badwidth_write16,
-    omap_eac_write,
-    omap_badwidth_write16,
-};
-
-struct omap_eac_s *omap_eac_init(struct omap_target_agent_s *ta,
+static struct omap_eac_s *omap_eac_init(struct omap_target_agent_s *ta,
                 qemu_irq irq, qemu_irq *drq, omap_clk fclk, omap_clk iclk)
 {
-    int iomemtype;
     struct omap_eac_s *s = (struct omap_eac_s *)
-            qemu_mallocz(sizeof(struct omap_eac_s));
+            g_malloc0(sizeof(struct omap_eac_s));
 
     s->irq = irq;
     s->codec.rxdrq = *drq ++;
-    s->codec.txdrq = *drq ++;
+    s->codec.txdrq = *drq;
     omap_eac_reset(s);
 
-#ifdef HAS_AUDIO
     AUD_register_card("OMAP EAC", &s->codec.card);
 
-    iomemtype = cpu_register_io_memory(omap_eac_readfn,
-                    omap_eac_writefn, s);
-    omap_l4_attach(ta, 0, iomemtype);
-#endif
+    memory_region_init_io(&s->iomem, &omap_eac_ops, s, "omap.eac",
+                          omap_l4_region_size(ta, 0));
+    omap_l4_attach(ta, 0, &s->iomem);
 
     return s;
 }
@@ -1985,6 +613,8 @@ struct omap_eac_s *omap_eac_init(struct omap_target_agent_s *ta,
 /* STI/XTI (emulation interface) console - reverse engineered only */
 struct omap_sti_s {
     qemu_irq irq;
+    MemoryRegion iomem;
+    MemoryRegion iomem_fifo;
     CharDriverState *chr;
 
     uint32_t sysconfig;
@@ -2014,10 +644,15 @@ static void omap_sti_reset(struct omap_sti_s *s)
     omap_sti_interrupt_update(s);
 }
 
-static uint32_t omap_sti_read(void *opaque, target_phys_addr_t addr)
+static uint64_t omap_sti_read(void *opaque, target_phys_addr_t addr,
+                              unsigned size)
 {
     struct omap_sti_s *s = (struct omap_sti_s *) opaque;
 
+    if (size != 4) {
+        return omap_badwidth_read32(opaque, addr);
+    }
+
     switch (addr) {
     case 0x00: /* STI_REVISION */
         return 0x10;
@@ -2051,10 +686,14 @@ static uint32_t omap_sti_read(void *opaque, target_phys_addr_t addr)
 }
 
 static void omap_sti_write(void *opaque, target_phys_addr_t addr,
-                uint32_t value)
+                           uint64_t value, unsigned size)
 {
     struct omap_sti_s *s = (struct omap_sti_s *) opaque;
 
+    if (size != 4) {
+        return omap_badwidth_write32(opaque, addr, value);
+    }
+
     switch (addr) {
     case 0x00: /* STI_REVISION */
     case 0x14: /* STI_SYSSTATUS / STI_RX_STATUS / XTI_SYSSTATUS */
@@ -2096,270 +735,78 @@ static void omap_sti_write(void *opaque, target_phys_addr_t addr,
     }
 }
 
-static CPUReadMemoryFunc * const omap_sti_readfn[] = {
-    omap_badwidth_read32,
-    omap_badwidth_read32,
-    omap_sti_read,
-};
-
-static CPUWriteMemoryFunc * const omap_sti_writefn[] = {
-    omap_badwidth_write32,
-    omap_badwidth_write32,
-    omap_sti_write,
+static const MemoryRegionOps omap_sti_ops = {
+    .read = omap_sti_read,
+    .write = omap_sti_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static uint32_t omap_sti_fifo_read(void *opaque, target_phys_addr_t addr)
+static uint64_t omap_sti_fifo_read(void *opaque, target_phys_addr_t addr,
+                                   unsigned size)
 {
     OMAP_BAD_REG(addr);
     return 0;
 }
 
 static void omap_sti_fifo_write(void *opaque, target_phys_addr_t addr,
-                uint32_t value)
+                                uint64_t value, unsigned size)
 {
     struct omap_sti_s *s = (struct omap_sti_s *) opaque;
     int ch = addr >> 6;
     uint8_t byte = value;
 
-    if (ch == STI_TRACE_CONTROL_CHANNEL) {
-        /* Flush channel <i>value</i>.  */
-        qemu_chr_write(s->chr, (const uint8_t *) "\r", 1);
-    } else if (ch == STI_TRACE_CONSOLE_CHANNEL || 1) {
-        if (value == 0xc0 || value == 0xc3) {
-            /* Open channel <i>ch</i>.  */
-        } else if (value == 0x00)
-            qemu_chr_write(s->chr, (const uint8_t *) "\n", 1);
-        else
-            qemu_chr_write(s->chr, &byte, 1);
-    }
-}
-
-static CPUReadMemoryFunc * const omap_sti_fifo_readfn[] = {
-    omap_sti_fifo_read,
-    omap_badwidth_read8,
-    omap_badwidth_read8,
-};
-
-static CPUWriteMemoryFunc * const omap_sti_fifo_writefn[] = {
-    omap_sti_fifo_write,
-    omap_badwidth_write8,
-    omap_badwidth_write8,
-};
-
-static struct omap_sti_s *omap_sti_init(struct omap_target_agent_s *ta,
-                target_phys_addr_t channel_base, qemu_irq irq, omap_clk clk,
-                CharDriverState *chr)
-{
-    int iomemtype;
-    struct omap_sti_s *s = (struct omap_sti_s *)
-            qemu_mallocz(sizeof(struct omap_sti_s));
-
-    s->irq = irq;
-    omap_sti_reset(s);
-
-    s->chr = chr ?: qemu_chr_open("null", "null", NULL);
-
-    iomemtype = l4_register_io_memory(omap_sti_readfn,
-                    omap_sti_writefn, s);
-    omap_l4_attach(ta, 0, iomemtype);
-
-    iomemtype = cpu_register_io_memory(omap_sti_fifo_readfn,
-                    omap_sti_fifo_writefn, s);
-    cpu_register_physical_memory(channel_base, 0x10000, iomemtype);
-
-    return s;
-}
-
-/* L4 Interconnect */
-struct omap_target_agent_s {
-    struct omap_l4_s *bus;
-    int regions;
-    struct omap_l4_region_s *start;
-    target_phys_addr_t base;
-    uint32_t component;
-    uint32_t control;
-    uint32_t status;
-};
-
-struct omap_l4_s {
-    target_phys_addr_t base;
-    int ta_num;
-    struct omap_target_agent_s ta[0];
-};
-
-#ifdef L4_MUX_HACK
-static int omap_l4_io_entries;
-static int omap_cpu_io_entry;
-static struct omap_l4_entry {
-        CPUReadMemoryFunc * const *mem_read;
-        CPUWriteMemoryFunc * const *mem_write;
-        void *opaque;
-} *omap_l4_io_entry;
-static CPUReadMemoryFunc * const *omap_l4_io_readb_fn;
-static CPUReadMemoryFunc * const *omap_l4_io_readh_fn;
-static CPUReadMemoryFunc * const *omap_l4_io_readw_fn;
-static CPUWriteMemoryFunc * const *omap_l4_io_writeb_fn;
-static CPUWriteMemoryFunc * const *omap_l4_io_writeh_fn;
-static CPUWriteMemoryFunc * const *omap_l4_io_writew_fn;
-static void **omap_l4_io_opaque;
-
-int l4_register_io_memory(CPUReadMemoryFunc * const *mem_read,
-                CPUWriteMemoryFunc * const *mem_write, void *opaque)
-{
-    omap_l4_io_entry[omap_l4_io_entries].mem_read = mem_read;
-    omap_l4_io_entry[omap_l4_io_entries].mem_write = mem_write;
-    omap_l4_io_entry[omap_l4_io_entries].opaque = opaque;
-
-    return omap_l4_io_entries ++;
-}
-
-static uint32_t omap_l4_io_readb(void *opaque, target_phys_addr_t addr)
-{
-    unsigned int i = (addr - OMAP2_L4_BASE) >> TARGET_PAGE_BITS;
-
-    return omap_l4_io_readb_fn[i](omap_l4_io_opaque[i], addr);
-}
-
-static uint32_t omap_l4_io_readh(void *opaque, target_phys_addr_t addr)
-{
-    unsigned int i = (addr - OMAP2_L4_BASE) >> TARGET_PAGE_BITS;
-
-    return omap_l4_io_readh_fn[i](omap_l4_io_opaque[i], addr);
-}
-
-static uint32_t omap_l4_io_readw(void *opaque, target_phys_addr_t addr)
-{
-    unsigned int i = (addr - OMAP2_L4_BASE) >> TARGET_PAGE_BITS;
-
-    return omap_l4_io_readw_fn[i](omap_l4_io_opaque[i], addr);
-}
-
-static void omap_l4_io_writeb(void *opaque, target_phys_addr_t addr,
-                uint32_t value)
-{
-    unsigned int i = (addr - OMAP2_L4_BASE) >> TARGET_PAGE_BITS;
-
-    return omap_l4_io_writeb_fn[i](omap_l4_io_opaque[i], addr, value);
-}
-
-static void omap_l4_io_writeh(void *opaque, target_phys_addr_t addr,
-                uint32_t value)
-{
-    unsigned int i = (addr - OMAP2_L4_BASE) >> TARGET_PAGE_BITS;
-
-    return omap_l4_io_writeh_fn[i](omap_l4_io_opaque[i], addr, value);
-}
-
-static void omap_l4_io_writew(void *opaque, target_phys_addr_t addr,
-                uint32_t value)
-{
-    unsigned int i = (addr - OMAP2_L4_BASE) >> TARGET_PAGE_BITS;
-
-    return omap_l4_io_writew_fn[i](omap_l4_io_opaque[i], addr, value);
-}
-
-static CPUReadMemoryFunc * const omap_l4_io_readfn[] = {
-    omap_l4_io_readb,
-    omap_l4_io_readh,
-    omap_l4_io_readw,
-};
-
-static CPUWriteMemoryFunc * const omap_l4_io_writefn[] = {
-    omap_l4_io_writeb,
-    omap_l4_io_writeh,
-    omap_l4_io_writew,
-};
-#endif
-
-struct omap_l4_s *omap_l4_init(target_phys_addr_t base, int ta_num)
-{
-    struct omap_l4_s *bus = qemu_mallocz(
-                    sizeof(*bus) + ta_num * sizeof(*bus->ta));
-
-    bus->ta_num = ta_num;
-    bus->base = base;
-
-#ifdef L4_MUX_HACK
-    omap_l4_io_entries = 1;
-    omap_l4_io_entry = qemu_mallocz(125 * sizeof(*omap_l4_io_entry));
-
-    omap_cpu_io_entry =
-            cpu_register_io_memory(omap_l4_io_readfn,
-                            omap_l4_io_writefn, bus);
-# define L4_PAGES      (0xb4000 / TARGET_PAGE_SIZE)
-    omap_l4_io_readb_fn = qemu_mallocz(sizeof(void *) * L4_PAGES);
-    omap_l4_io_readh_fn = qemu_mallocz(sizeof(void *) * L4_PAGES);
-    omap_l4_io_readw_fn = qemu_mallocz(sizeof(void *) * L4_PAGES);
-    omap_l4_io_writeb_fn = qemu_mallocz(sizeof(void *) * L4_PAGES);
-    omap_l4_io_writeh_fn = qemu_mallocz(sizeof(void *) * L4_PAGES);
-    omap_l4_io_writew_fn = qemu_mallocz(sizeof(void *) * L4_PAGES);
-    omap_l4_io_opaque = qemu_mallocz(sizeof(void *) * L4_PAGES);
-#endif
-
-    return bus;
-}
-
-static uint32_t omap_l4ta_read(void *opaque, target_phys_addr_t addr)
-{
-    struct omap_target_agent_s *s = (struct omap_target_agent_s *) opaque;
-
-    switch (addr) {
-    case 0x00: /* COMPONENT */
-        return s->component;
-
-    case 0x20: /* AGENT_CONTROL */
-        return s->control;
-
-    case 0x28: /* AGENT_STATUS */
-        return s->status;
+    if (size != 1) {
+        return omap_badwidth_write8(opaque, addr, size);
     }
 
-    OMAP_BAD_REG(addr);
-    return 0;
+    if (ch == STI_TRACE_CONTROL_CHANNEL) {
+        /* Flush channel <i>value</i>.  */
+        qemu_chr_fe_write(s->chr, (const uint8_t *) "\r", 1);
+    } else if (ch == STI_TRACE_CONSOLE_CHANNEL || 1) {
+        if (value == 0xc0 || value == 0xc3) {
+            /* Open channel <i>ch</i>.  */
+        } else if (value == 0x00)
+            qemu_chr_fe_write(s->chr, (const uint8_t *) "\n", 1);
+        else
+            qemu_chr_fe_write(s->chr, &byte, 1);
+    }
 }
 
-static void omap_l4ta_write(void *opaque, target_phys_addr_t addr,
-                uint32_t value)
+static const MemoryRegionOps omap_sti_fifo_ops = {
+    .read = omap_sti_fifo_read,
+    .write = omap_sti_fifo_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static struct omap_sti_s *omap_sti_init(struct omap_target_agent_s *ta,
+                MemoryRegion *sysmem,
+                target_phys_addr_t channel_base, qemu_irq irq, omap_clk clk,
+                CharDriverState *chr)
 {
-    struct omap_target_agent_s *s = (struct omap_target_agent_s *) opaque;
+    struct omap_sti_s *s = (struct omap_sti_s *)
+            g_malloc0(sizeof(struct omap_sti_s));
 
-    switch (addr) {
-    case 0x00: /* COMPONENT */
-    case 0x28: /* AGENT_STATUS */
-        OMAP_RO_REG(addr);
-        break;
+    s->irq = irq;
+    omap_sti_reset(s);
 
-    case 0x20: /* AGENT_CONTROL */
-        s->control = value & 0x01000700;
-        if (value & 1)                                 /* OCP_RESET */
-            s->status &= ~1;                           /* REQ_TIMEOUT */
-        break;
+    s->chr = chr ?: qemu_chr_new("null", "null", NULL);
 
-    default:
-        OMAP_BAD_REG(addr);
-    }
-}
+    memory_region_init_io(&s->iomem, &omap_sti_ops, s, "omap.sti",
+                          omap_l4_region_size(ta, 0));
+    omap_l4_attach(ta, 0, &s->iomem);
 
-static CPUReadMemoryFunc * const omap_l4ta_readfn[] = {
-    omap_badwidth_read16,
-    omap_l4ta_read,
-    omap_badwidth_read16,
-};
+    memory_region_init_io(&s->iomem_fifo, &omap_sti_fifo_ops, s,
+                          "omap.sti.fifo", 0x10000);
+    memory_region_add_subregion(sysmem, channel_base, &s->iomem_fifo);
 
-static CPUWriteMemoryFunc * const omap_l4ta_writefn[] = {
-    omap_badwidth_write32,
-    omap_badwidth_write32,
-    omap_l4ta_write,
-};
+    return s;
+}
 
+/* L4 Interconnect */
 #define L4TA(n)                (n)
 #define L4TAO(n)       ((n) + 39)
 
-static struct omap_l4_region_s {
-    target_phys_addr_t offset;
-    size_t size;
-    int access;
-} omap_l4_region[125] = {
+static const struct omap_l4_region_s omap_l4_region[125] = {
     [  1] = { 0x40800,  0x800, 32          }, /* Initiator agent */
     [  2] = { 0x41000, 0x1000, 32          }, /* Link agent */
     [  0] = { 0x40000,  0x800, 32          }, /* Address and protection */
@@ -2487,12 +934,7 @@ static struct omap_l4_region_s {
     [124] = { 0xb3000, 0x1000, 32 | 16 | 8 }, /* L4TA39 */
 };
 
-static struct omap_l4_agent_info_s {
-    int ta;
-    int region;
-    int regions;
-    int ta_region;
-} omap_l4_agent_info[54] = {
+static const struct omap_l4_agent_info_s omap_l4_agent_info[54] = {
     { 0,           0, 3, 2 }, /* L4IA initiatior agent */
     { L4TAO(1),    3, 2, 1 }, /* Control and pinout module */
     { L4TAO(2),    5, 2, 1 }, /* 32K timer */
@@ -2549,172 +991,17 @@ static struct omap_l4_agent_info_s {
     { L4TA(39),  123, 2, 1 }, /* HDQ/1-Wire */
 };
 
-#define omap_l4ta(bus, cs)     omap_l4ta_get(bus, L4TA(cs))
-#define omap_l4tao(bus, cs)    omap_l4ta_get(bus, L4TAO(cs))
-
-struct omap_target_agent_s *omap_l4ta_get(struct omap_l4_s *bus, int cs)
-{
-    int i, iomemtype;
-    struct omap_target_agent_s *ta = 0;
-    struct omap_l4_agent_info_s *info = 0;
-
-    for (i = 0; i < bus->ta_num; i ++)
-        if (omap_l4_agent_info[i].ta == cs) {
-            ta = &bus->ta[i];
-            info = &omap_l4_agent_info[i];
-            break;
-        }
-    if (!ta) {
-        fprintf(stderr, "%s: bad target agent (%i)\n", __FUNCTION__, cs);
-        exit(-1);
-    }
-
-    ta->bus = bus;
-    ta->start = &omap_l4_region[info->region];
-    ta->regions = info->regions;
-
-    ta->component = ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
-    ta->status = 0x00000000;
-    ta->control = 0x00000200;  /* XXX 01000200 for L4TAO */
-
-    iomemtype = l4_register_io_memory(omap_l4ta_readfn,
-                    omap_l4ta_writefn, ta);
-    ta->base = omap_l4_attach(ta, info->ta_region, iomemtype);
-
-    return ta;
-}
-
-target_phys_addr_t omap_l4_attach(struct omap_target_agent_s *ta, int region,
-                int iotype)
-{
-    target_phys_addr_t base;
-    ssize_t size;
-#ifdef L4_MUX_HACK
-    int i;
-#endif
-
-    if (region < 0 || region >= ta->regions) {
-        fprintf(stderr, "%s: bad io region (%i)\n", __FUNCTION__, region);
-        exit(-1);
-    }
-
-    base = ta->bus->base + ta->start[region].offset;
-    size = ta->start[region].size;
-    if (iotype) {
-#ifndef L4_MUX_HACK
-        cpu_register_physical_memory(base, size, iotype);
-#else
-        cpu_register_physical_memory(base, size, omap_cpu_io_entry);
-        i = (base - ta->bus->base) / TARGET_PAGE_SIZE;
-        for (; size > 0; size -= TARGET_PAGE_SIZE, i ++) {
-            omap_l4_io_readb_fn[i] = omap_l4_io_entry[iotype].mem_read[0];
-            omap_l4_io_readh_fn[i] = omap_l4_io_entry[iotype].mem_read[1];
-            omap_l4_io_readw_fn[i] = omap_l4_io_entry[iotype].mem_read[2];
-            omap_l4_io_writeb_fn[i] = omap_l4_io_entry[iotype].mem_write[0];
-            omap_l4_io_writeh_fn[i] = omap_l4_io_entry[iotype].mem_write[1];
-            omap_l4_io_writew_fn[i] = omap_l4_io_entry[iotype].mem_write[2];
-            omap_l4_io_opaque[i] = omap_l4_io_entry[iotype].opaque;
-        }
-#endif
-    }
-
-    return base;
-}
-
-/* TEST-Chip-level TAP */
-static uint32_t omap_tap_read(void *opaque, target_phys_addr_t addr)
-{
-    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
-
-    switch (addr) {
-    case 0x204:        /* IDCODE_reg */
-        switch (s->mpu_model) {
-        case omap2420:
-        case omap2422:
-        case omap2423:
-            return 0x5b5d902f; /* ES 2.2 */
-        case omap2430:
-            return 0x5b68a02f; /* ES 2.2 */
-        case omap3430:
-            return 0x1b7ae02f; /* ES 2 */
-        default:
-            hw_error("%s: Bad mpu model\n", __FUNCTION__);
-        }
-
-    case 0x208:        /* PRODUCTION_ID_reg for OMAP2 */
-    case 0x210:        /* PRODUCTION_ID_reg for OMAP3 */
-        switch (s->mpu_model) {
-        case omap2420:
-            return 0x000254f0; /* POP ESHS2.1.1 in N91/93/95, ES2 in N800 */
-        case omap2422:
-            return 0x000400f0;
-        case omap2423:
-            return 0x000800f0;
-        case omap2430:
-            return 0x000000f0;
-        case omap3430:
-            return 0x000000f0;
-        default:
-            hw_error("%s: Bad mpu model\n", __FUNCTION__);
-        }
-
-    case 0x20c:
-        switch (s->mpu_model) {
-        case omap2420:
-        case omap2422:
-        case omap2423:
-            return 0xcafeb5d9; /* ES 2.2 */
-        case omap2430:
-            return 0xcafeb68a; /* ES 2.2 */
-        case omap3430:
-            return 0xcafeb7ae; /* ES 2 */
-        default:
-            hw_error("%s: Bad mpu model\n", __FUNCTION__);
-        }
-
-    case 0x218:        /* DIE_ID_reg */
-        return ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
-    case 0x21c:        /* DIE_ID_reg */
-        return 0x54 << 24;
-    case 0x220:        /* DIE_ID_reg */
-        return ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
-    case 0x224:        /* DIE_ID_reg */
-        return ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
-    }
-
-    OMAP_BAD_REG(addr);
-    return 0;
-}
-
-static void omap_tap_write(void *opaque, target_phys_addr_t addr,
-                uint32_t value)
-{
-    OMAP_BAD_REG(addr);
-}
-
-static CPUReadMemoryFunc * const omap_tap_readfn[] = {
-    omap_badwidth_read32,
-    omap_badwidth_read32,
-    omap_tap_read,
-};
-
-static CPUWriteMemoryFunc * const omap_tap_writefn[] = {
-    omap_badwidth_write32,
-    omap_badwidth_write32,
-    omap_tap_write,
-};
-
-void omap_tap_init(struct omap_target_agent_s *ta,
-                struct omap_mpu_state_s *mpu)
-{
-    omap_l4_attach(ta, 0, l4_register_io_memory(
-                            omap_tap_readfn, omap_tap_writefn, mpu));
-}
+#define omap_l4ta(bus, cs)     \
+    omap_l4ta_get(bus, omap_l4_region, omap_l4_agent_info, L4TA(cs))
+#define omap_l4tao(bus, cs)    \
+    omap_l4ta_get(bus, omap_l4_region, omap_l4_agent_info, L4TAO(cs))
 
 /* Power, Reset, and Clock Management */
 struct omap_prcm_s {
     qemu_irq irq[3];
     struct omap_mpu_state_s *mpu;
+    MemoryRegion iomem0;
+    MemoryRegion iomem1;
 
     uint32_t irqst[3];
     uint32_t irqen[3];
@@ -2753,11 +1040,16 @@ static void omap_prcm_int_update(struct omap_prcm_s *s, int dom)
     /* XXX or is the mask applied before PRCM_IRQSTATUS_* ? */
 }
 
-static uint32_t omap_prcm_read(void *opaque, target_phys_addr_t addr)
+static uint64_t omap_prcm_read(void *opaque, target_phys_addr_t addr,
+                               unsigned size)
 {
     struct omap_prcm_s *s = (struct omap_prcm_s *) opaque;
     uint32_t ret;
 
+    if (size != 4) {
+        return omap_badwidth_read32(opaque, addr);
+    }
+
     switch (addr) {
     case 0x000:        /* PRCM_REVISION */
         return 0x10;
@@ -3007,7 +1299,7 @@ static void omap_prcm_apll_update(struct omap_prcm_s *s)
     s->apll_lock[1] = (mode[1] == 3);
     /* TODO: update clocks */
 
-    if (mode[0] == 1 || mode[0] == 2 || mode[1] == 1 || mode[2] == 2)
+    if (mode[0] == 1 || mode[0] == 2 || mode[1] == 1 || mode[1] == 2)
         fprintf(stderr, "%s: bad EN_54M_PLL or bad EN_96M_PLL\n",
                         __FUNCTION__);
 }
@@ -3061,10 +1353,14 @@ static void omap_prcm_dpll_update(struct omap_prcm_s *s)
 }
 
 static void omap_prcm_write(void *opaque, target_phys_addr_t addr,
-                uint32_t value)
+                            uint64_t value, unsigned size)
 {
     struct omap_prcm_s *s = (struct omap_prcm_s *) opaque;
 
+    if (size != 4) {
+        return omap_badwidth_write32(opaque, addr, value);
+    }
+
     switch (addr) {
     case 0x000:        /* PRCM_REVISION */
     case 0x054:        /* PRCM_VOLTST */
@@ -3320,7 +1616,7 @@ static void omap_prcm_write(void *opaque, target_phys_addr_t addr,
     case 0x500:        /* CM_CLKEN_PLL */
         if (value & 0xffffff30)
             fprintf(stderr, "%s: write 0s in CM_CLKEN_PLL for "
-                            "future compatiblity\n", __FUNCTION__);
+                            "future compatibility\n", __FUNCTION__);
         if ((s->clken[9] ^ value) & 0xcc) {
             s->clken[9] &= ~0xcc;
             s->clken[9] |= value & 0xcc;
@@ -3339,7 +1635,7 @@ static void omap_prcm_write(void *opaque, target_phys_addr_t addr,
     case 0x540:        /* CM_CLKSEL1_PLL */
         if (value & 0xfc4000d7)
             fprintf(stderr, "%s: write 0s in CM_CLKSEL1_PLL for "
-                            "future compatiblity\n", __FUNCTION__);
+                            "future compatibility\n", __FUNCTION__);
         if ((s->clksel[5] ^ value) & 0x003fff00) {
             s->clksel[5] = value & 0x03bfff28;
             omap_prcm_dpll_update(s);
@@ -3351,7 +1647,7 @@ static void omap_prcm_write(void *opaque, target_phys_addr_t addr,
     case 0x544:        /* CM_CLKSEL2_PLL */
         if (value & ~3)
             fprintf(stderr, "%s: write 0s in CM_CLKSEL2_PLL[31:2] for "
-                            "future compatiblity\n", __FUNCTION__);
+                            "future compatibility\n", __FUNCTION__);
         if (s->clksel[6] != (value & 3)) {
             s->clksel[6] = value & 3;
             omap_prcm_dpll_update(s);
@@ -3414,16 +1710,10 @@ static void omap_prcm_write(void *opaque, target_phys_addr_t addr,
     }
 }
 
-static CPUReadMemoryFunc * const omap_prcm_readfn[] = {
-    omap_badwidth_read32,
-    omap_badwidth_read32,
-    omap_prcm_read,
-};
-
-static CPUWriteMemoryFunc * const omap_prcm_writefn[] = {
-    omap_badwidth_write32,
-    omap_badwidth_write32,
-    omap_prcm_write,
+static const MemoryRegionOps omap_prcm_ops = {
+    .read = omap_prcm_read,
+    .write = omap_prcm_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 static void omap_prcm_reset(struct omap_prcm_s *s)
@@ -3506,13 +1796,12 @@ static void omap_prcm_coldreset(struct omap_prcm_s *s)
     omap_prcm_reset(s);
 }
 
-struct omap_prcm_s *omap_prcm_init(struct omap_target_agent_s *ta,
+static struct omap_prcm_s *omap_prcm_init(struct omap_target_agent_s *ta,
                 qemu_irq mpu_int, qemu_irq dsp_int, qemu_irq iva_int,
                 struct omap_mpu_state_s *mpu)
 {
-    int iomemtype;
     struct omap_prcm_s *s = (struct omap_prcm_s *)
-            qemu_mallocz(sizeof(struct omap_prcm_s));
+            g_malloc0(sizeof(struct omap_prcm_s));
 
     s->irq[0] = mpu_int;
     s->irq[1] = dsp_int;
@@ -3520,10 +1809,12 @@ struct omap_prcm_s *omap_prcm_init(struct omap_target_agent_s *ta,
     s->mpu = mpu;
     omap_prcm_coldreset(s);
 
-    iomemtype = l4_register_io_memory(omap_prcm_readfn,
-                    omap_prcm_writefn, s);
-    omap_l4_attach(ta, 0, iomemtype);
-    omap_l4_attach(ta, 1, iomemtype);
+    memory_region_init_io(&s->iomem0, &omap_prcm_ops, s, "omap.pcrm0",
+                          omap_l4_region_size(ta, 0));
+    memory_region_init_io(&s->iomem1, &omap_prcm_ops, s, "omap.pcrm1",
+                          omap_l4_region_size(ta, 1));
+    omap_l4_attach(ta, 0, &s->iomem0);
+    omap_l4_attach(ta, 1, &s->iomem1);
 
     return s;
 }
@@ -3531,6 +1822,7 @@ struct omap_prcm_s *omap_prcm_init(struct omap_target_agent_s *ta,
 /* System and Pinout control */
 struct omap_sysctl_s {
     struct omap_mpu_state_s *mpu;
+    MemoryRegion iomem;
 
     uint32_t sysconfig;
     uint32_t devconfig;
@@ -3784,16 +2076,20 @@ static void omap_sysctl_write(void *opaque, target_phys_addr_t addr,
     }
 }
 
-static CPUReadMemoryFunc * const omap_sysctl_readfn[] = {
-    omap_sysctl_read8,
-    omap_badwidth_read32,      /* TODO */
-    omap_sysctl_read,
-};
-
-static CPUWriteMemoryFunc * const omap_sysctl_writefn[] = {
-    omap_sysctl_write8,
-    omap_badwidth_write32,     /* TODO */
-    omap_sysctl_write,
+static const MemoryRegionOps omap_sysctl_ops = {
+    .old_mmio = {
+        .read = {
+            omap_sysctl_read8,
+            omap_badwidth_read32,      /* TODO */
+            omap_sysctl_read,
+        },
+        .write = {
+            omap_sysctl_write8,
+            omap_badwidth_write32,     /* TODO */
+            omap_sysctl_write,
+        },
+    },
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 static void omap_sysctl_reset(struct omap_sysctl_s *s)
@@ -3880,569 +2176,27 @@ static void omap_sysctl_reset(struct omap_sysctl_s *s)
     s->padconf[0x44] = 0x00000800;
 }
 
-struct omap_sysctl_s *omap_sysctl_init(struct omap_target_agent_s *ta,
+static struct omap_sysctl_s *omap_sysctl_init(struct omap_target_agent_s *ta,
                 omap_clk iclk, struct omap_mpu_state_s *mpu)
 {
-    int iomemtype;
     struct omap_sysctl_s *s = (struct omap_sysctl_s *)
-            qemu_mallocz(sizeof(struct omap_sysctl_s));
+            g_malloc0(sizeof(struct omap_sysctl_s));
 
     s->mpu = mpu;
     omap_sysctl_reset(s);
 
-    iomemtype = l4_register_io_memory(omap_sysctl_readfn,
-                    omap_sysctl_writefn, s);
-    omap_l4_attach(ta, 0, iomemtype);
-
-    return s;
-}
-
-/* SDRAM Controller Subsystem */
-struct omap_sdrc_s {
-    uint8_t config;
-};
-
-static void omap_sdrc_reset(struct omap_sdrc_s *s)
-{
-    s->config = 0x10;
-}
-
-static uint32_t omap_sdrc_read(void *opaque, target_phys_addr_t addr)
-{
-    struct omap_sdrc_s *s = (struct omap_sdrc_s *) opaque;
-
-    switch (addr) {
-    case 0x00: /* SDRC_REVISION */
-        return 0x20;
-
-    case 0x10: /* SDRC_SYSCONFIG */
-        return s->config;
-
-    case 0x14: /* SDRC_SYSSTATUS */
-        return 1;                                              /* RESETDONE */
-
-    case 0x40: /* SDRC_CS_CFG */
-    case 0x44: /* SDRC_SHARING */
-    case 0x48: /* SDRC_ERR_ADDR */
-    case 0x4c: /* SDRC_ERR_TYPE */
-    case 0x60: /* SDRC_DLLA_SCTRL */
-    case 0x64: /* SDRC_DLLA_STATUS */
-    case 0x68: /* SDRC_DLLB_CTRL */
-    case 0x6c: /* SDRC_DLLB_STATUS */
-    case 0x70: /* SDRC_POWER */
-    case 0x80: /* SDRC_MCFG_0 */
-    case 0x84: /* SDRC_MR_0 */
-    case 0x88: /* SDRC_EMR1_0 */
-    case 0x8c: /* SDRC_EMR2_0 */
-    case 0x90: /* SDRC_EMR3_0 */
-    case 0x94: /* SDRC_DCDL1_CTRL */
-    case 0x98: /* SDRC_DCDL2_CTRL */
-    case 0x9c: /* SDRC_ACTIM_CTRLA_0 */
-    case 0xa0: /* SDRC_ACTIM_CTRLB_0 */
-    case 0xa4: /* SDRC_RFR_CTRL_0 */
-    case 0xa8: /* SDRC_MANUAL_0 */
-    case 0xb0: /* SDRC_MCFG_1 */
-    case 0xb4: /* SDRC_MR_1 */
-    case 0xb8: /* SDRC_EMR1_1 */
-    case 0xbc: /* SDRC_EMR2_1 */
-    case 0xc0: /* SDRC_EMR3_1 */
-    case 0xc4: /* SDRC_ACTIM_CTRLA_1 */
-    case 0xc8: /* SDRC_ACTIM_CTRLB_1 */
-    case 0xd4: /* SDRC_RFR_CTRL_1 */
-    case 0xd8: /* SDRC_MANUAL_1 */
-        return 0x00;
-    }
-
-    OMAP_BAD_REG(addr);
-    return 0;
-}
-
-static void omap_sdrc_write(void *opaque, target_phys_addr_t addr,
-                uint32_t value)
-{
-    struct omap_sdrc_s *s = (struct omap_sdrc_s *) opaque;
-
-    switch (addr) {
-    case 0x00: /* SDRC_REVISION */
-    case 0x14: /* SDRC_SYSSTATUS */
-    case 0x48: /* SDRC_ERR_ADDR */
-    case 0x64: /* SDRC_DLLA_STATUS */
-    case 0x6c: /* SDRC_DLLB_STATUS */
-        OMAP_RO_REG(addr);
-        return;
-
-    case 0x10: /* SDRC_SYSCONFIG */
-        if ((value >> 3) != 0x2)
-            fprintf(stderr, "%s: bad SDRAM idle mode %i\n",
-                            __FUNCTION__, value >> 3);
-        if (value & 2)
-            omap_sdrc_reset(s);
-        s->config = value & 0x18;
-        break;
-
-    case 0x40: /* SDRC_CS_CFG */
-    case 0x44: /* SDRC_SHARING */
-    case 0x4c: /* SDRC_ERR_TYPE */
-    case 0x60: /* SDRC_DLLA_SCTRL */
-    case 0x68: /* SDRC_DLLB_CTRL */
-    case 0x70: /* SDRC_POWER */
-    case 0x80: /* SDRC_MCFG_0 */
-    case 0x84: /* SDRC_MR_0 */
-    case 0x88: /* SDRC_EMR1_0 */
-    case 0x8c: /* SDRC_EMR2_0 */
-    case 0x90: /* SDRC_EMR3_0 */
-    case 0x94: /* SDRC_DCDL1_CTRL */
-    case 0x98: /* SDRC_DCDL2_CTRL */
-    case 0x9c: /* SDRC_ACTIM_CTRLA_0 */
-    case 0xa0: /* SDRC_ACTIM_CTRLB_0 */
-    case 0xa4: /* SDRC_RFR_CTRL_0 */
-    case 0xa8: /* SDRC_MANUAL_0 */
-    case 0xb0: /* SDRC_MCFG_1 */
-    case 0xb4: /* SDRC_MR_1 */
-    case 0xb8: /* SDRC_EMR1_1 */
-    case 0xbc: /* SDRC_EMR2_1 */
-    case 0xc0: /* SDRC_EMR3_1 */
-    case 0xc4: /* SDRC_ACTIM_CTRLA_1 */
-    case 0xc8: /* SDRC_ACTIM_CTRLB_1 */
-    case 0xd4: /* SDRC_RFR_CTRL_1 */
-    case 0xd8: /* SDRC_MANUAL_1 */
-        break;
-
-    default:
-        OMAP_BAD_REG(addr);
-        return;
-    }
-}
-
-static CPUReadMemoryFunc * const omap_sdrc_readfn[] = {
-    omap_badwidth_read32,
-    omap_badwidth_read32,
-    omap_sdrc_read,
-};
-
-static CPUWriteMemoryFunc * const omap_sdrc_writefn[] = {
-    omap_badwidth_write32,
-    omap_badwidth_write32,
-    omap_sdrc_write,
-};
-
-struct omap_sdrc_s *omap_sdrc_init(target_phys_addr_t base)
-{
-    int iomemtype;
-    struct omap_sdrc_s *s = (struct omap_sdrc_s *)
-            qemu_mallocz(sizeof(struct omap_sdrc_s));
-
-    omap_sdrc_reset(s);
-
-    iomemtype = cpu_register_io_memory(omap_sdrc_readfn,
-                    omap_sdrc_writefn, s);
-    cpu_register_physical_memory(base, 0x1000, iomemtype);
-
-    return s;
-}
-
-/* General-Purpose Memory Controller */
-struct omap_gpmc_s {
-    qemu_irq irq;
-
-    uint8_t sysconfig;
-    uint16_t irqst;
-    uint16_t irqen;
-    uint16_t timeout;
-    uint16_t config;
-    uint32_t prefconfig[2];
-    int prefcontrol;
-    int preffifo;
-    int prefcount;
-    struct omap_gpmc_cs_file_s {
-        uint32_t config[7];
-        target_phys_addr_t base;
-        size_t size;
-        int iomemtype;
-        void (*base_update)(void *opaque, target_phys_addr_t new);
-        void (*unmap)(void *opaque);
-        void *opaque;
-    } cs_file[8];
-    int ecc_cs;
-    int ecc_ptr;
-    uint32_t ecc_cfg;
-    ECCState ecc[9];
-};
-
-static void omap_gpmc_int_update(struct omap_gpmc_s *s)
-{
-    qemu_set_irq(s->irq, s->irqen & s->irqst);
-}
-
-static void omap_gpmc_cs_map(struct omap_gpmc_cs_file_s *f, int base, int mask)
-{
-    /* TODO: check for overlapping regions and report access errors */
-    if ((mask != 0x8 && mask != 0xc && mask != 0xe && mask != 0xf) ||
-                    (base < 0 || base >= 0x40) ||
-                    (base & 0x0f & ~mask)) {
-        fprintf(stderr, "%s: wrong cs address mapping/decoding!\n",
-                        __FUNCTION__);
-        return;
-    }
-
-    if (!f->opaque)
-        return;
-
-    f->base = base << 24;
-    f->size = (0x0fffffff & ~(mask << 24)) + 1;
-    /* TODO: rather than setting the size of the mapping (which should be
-     * constant), the mask should cause wrapping of the address space, so
-     * that the same memory becomes accessible at every <i>size</i> bytes
-     * starting from <i>base</i>.  */
-    if (f->iomemtype)
-        cpu_register_physical_memory(f->base, f->size, f->iomemtype);
-
-    if (f->base_update)
-        f->base_update(f->opaque, f->base);
-}
-
-static void omap_gpmc_cs_unmap(struct omap_gpmc_cs_file_s *f)
-{
-    if (f->size) {
-        if (f->unmap)
-            f->unmap(f->opaque);
-        if (f->iomemtype)
-            cpu_register_physical_memory(f->base, f->size, IO_MEM_UNASSIGNED);
-        f->base = 0;
-        f->size = 0;
-    }
-}
-
-static void omap_gpmc_reset(struct omap_gpmc_s *s)
-{
-    int i;
-
-    s->sysconfig = 0;
-    s->irqst = 0;
-    s->irqen = 0;
-    omap_gpmc_int_update(s);
-    s->timeout = 0;
-    s->config = 0xa00;
-    s->prefconfig[0] = 0x00004000;
-    s->prefconfig[1] = 0x00000000;
-    s->prefcontrol = 0;
-    s->preffifo = 0;
-    s->prefcount = 0;
-    for (i = 0; i < 8; i ++) {
-        if (s->cs_file[i].config[6] & (1 << 6))                        /* CSVALID */
-            omap_gpmc_cs_unmap(s->cs_file + i);
-        s->cs_file[i].config[0] = i ? 1 << 12 : 0;
-        s->cs_file[i].config[1] = 0x101001;
-        s->cs_file[i].config[2] = 0x020201;
-        s->cs_file[i].config[3] = 0x10031003;
-        s->cs_file[i].config[4] = 0x10f1111;
-        s->cs_file[i].config[5] = 0;
-        s->cs_file[i].config[6] = 0xf00 | (i ? 0 : 1 << 6);
-        if (s->cs_file[i].config[6] & (1 << 6))                        /* CSVALID */
-            omap_gpmc_cs_map(&s->cs_file[i],
-                            s->cs_file[i].config[6] & 0x1f,    /* MASKADDR */
-                        (s->cs_file[i].config[6] >> 8 & 0xf)); /* BASEADDR */
-    }
-    omap_gpmc_cs_map(s->cs_file, 0, 0xf);
-    s->ecc_cs = 0;
-    s->ecc_ptr = 0;
-    s->ecc_cfg = 0x3fcff000;
-    for (i = 0; i < 9; i ++)
-        ecc_reset(&s->ecc[i]);
-}
-
-static uint32_t omap_gpmc_read(void *opaque, target_phys_addr_t addr)
-{
-    struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
-    int cs;
-    struct omap_gpmc_cs_file_s *f;
-
-    switch (addr) {
-    case 0x000:        /* GPMC_REVISION */
-        return 0x20;
-
-    case 0x010:        /* GPMC_SYSCONFIG */
-        return s->sysconfig;
-
-    case 0x014:        /* GPMC_SYSSTATUS */
-        return 1;                                              /* RESETDONE */
-
-    case 0x018:        /* GPMC_IRQSTATUS */
-        return s->irqst;
-
-    case 0x01c:        /* GPMC_IRQENABLE */
-        return s->irqen;
-
-    case 0x040:        /* GPMC_TIMEOUT_CONTROL */
-        return s->timeout;
-
-    case 0x044:        /* GPMC_ERR_ADDRESS */
-    case 0x048:        /* GPMC_ERR_TYPE */
-        return 0;
-
-    case 0x050:        /* GPMC_CONFIG */
-        return s->config;
-
-    case 0x054:        /* GPMC_STATUS */
-        return 0x001;
-
-    case 0x060 ... 0x1d4:
-        cs = (addr - 0x060) / 0x30;
-        addr -= cs * 0x30;
-        f = s->cs_file + cs;
-        switch (addr) {
-            case 0x60: /* GPMC_CONFIG1 */
-                return f->config[0];
-            case 0x64: /* GPMC_CONFIG2 */
-                return f->config[1];
-            case 0x68: /* GPMC_CONFIG3 */
-                return f->config[2];
-            case 0x6c: /* GPMC_CONFIG4 */
-                return f->config[3];
-            case 0x70: /* GPMC_CONFIG5 */
-                return f->config[4];
-            case 0x74: /* GPMC_CONFIG6 */
-                return f->config[5];
-            case 0x78: /* GPMC_CONFIG7 */
-                return f->config[6];
-            case 0x84: /* GPMC_NAND_DATA */
-                return 0;
-        }
-        break;
-
-    case 0x1e0:        /* GPMC_PREFETCH_CONFIG1 */
-        return s->prefconfig[0];
-    case 0x1e4:        /* GPMC_PREFETCH_CONFIG2 */
-        return s->prefconfig[1];
-    case 0x1ec:        /* GPMC_PREFETCH_CONTROL */
-        return s->prefcontrol;
-    case 0x1f0:        /* GPMC_PREFETCH_STATUS */
-        return (s->preffifo << 24) |
-                ((s->preffifo >
-                  ((s->prefconfig[0] >> 8) & 0x7f) ? 1 : 0) << 16) |
-                s->prefcount;
-
-    case 0x1f4:        /* GPMC_ECC_CONFIG */
-        return s->ecc_cs;
-    case 0x1f8:        /* GPMC_ECC_CONTROL */
-        return s->ecc_ptr;
-    case 0x1fc:        /* GPMC_ECC_SIZE_CONFIG */
-        return s->ecc_cfg;
-    case 0x200 ... 0x220:      /* GPMC_ECC_RESULT */
-        cs = (addr & 0x1f) >> 2;
-        /* TODO: check correctness */
-        return
-                ((s->ecc[cs].cp    &  0x07) <<  0) |
-                ((s->ecc[cs].cp    &  0x38) << 13) |
-                ((s->ecc[cs].lp[0] & 0x1ff) <<  3) |
-                ((s->ecc[cs].lp[1] & 0x1ff) << 19);
-
-    case 0x230:        /* GPMC_TESTMODE_CTRL */
-        return 0;
-    case 0x234:        /* GPMC_PSA_LSB */
-    case 0x238:        /* GPMC_PSA_MSB */
-        return 0x00000000;
-    }
-
-    OMAP_BAD_REG(addr);
-    return 0;
-}
-
-static void omap_gpmc_write(void *opaque, target_phys_addr_t addr,
-                uint32_t value)
-{
-    struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
-    int cs;
-    struct omap_gpmc_cs_file_s *f;
-
-    switch (addr) {
-    case 0x000:        /* GPMC_REVISION */
-    case 0x014:        /* GPMC_SYSSTATUS */
-    case 0x054:        /* GPMC_STATUS */
-    case 0x1f0:        /* GPMC_PREFETCH_STATUS */
-    case 0x200 ... 0x220:      /* GPMC_ECC_RESULT */
-    case 0x234:        /* GPMC_PSA_LSB */
-    case 0x238:        /* GPMC_PSA_MSB */
-        OMAP_RO_REG(addr);
-        break;
-
-    case 0x010:        /* GPMC_SYSCONFIG */
-        if ((value >> 3) == 0x3)
-            fprintf(stderr, "%s: bad SDRAM idle mode %i\n",
-                            __FUNCTION__, value >> 3);
-        if (value & 2)
-            omap_gpmc_reset(s);
-        s->sysconfig = value & 0x19;
-        break;
-
-    case 0x018:        /* GPMC_IRQSTATUS */
-        s->irqen = ~value;
-        omap_gpmc_int_update(s);
-        break;
-
-    case 0x01c:        /* GPMC_IRQENABLE */
-        s->irqen = value & 0xf03;
-        omap_gpmc_int_update(s);
-        break;
-
-    case 0x040:        /* GPMC_TIMEOUT_CONTROL */
-        s->timeout = value & 0x1ff1;
-        break;
-
-    case 0x044:        /* GPMC_ERR_ADDRESS */
-    case 0x048:        /* GPMC_ERR_TYPE */
-        break;
-
-    case 0x050:        /* GPMC_CONFIG */
-        s->config = value & 0xf13;
-        break;
-
-    case 0x060 ... 0x1d4:
-        cs = (addr - 0x060) / 0x30;
-        addr -= cs * 0x30;
-        f = s->cs_file + cs;
-        switch (addr) {
-            case 0x60: /* GPMC_CONFIG1 */
-                f->config[0] = value & 0xffef3e13;
-                break;
-            case 0x64: /* GPMC_CONFIG2 */
-                f->config[1] = value & 0x001f1f8f;
-                break;
-            case 0x68: /* GPMC_CONFIG3 */
-                f->config[2] = value & 0x001f1f8f;
-                break;
-            case 0x6c: /* GPMC_CONFIG4 */
-                f->config[3] = value & 0x1f8f1f8f;
-                break;
-            case 0x70: /* GPMC_CONFIG5 */
-                f->config[4] = value & 0x0f1f1f1f;
-                break;
-            case 0x74: /* GPMC_CONFIG6 */
-                f->config[5] = value & 0x00000fcf;
-                break;
-            case 0x78: /* GPMC_CONFIG7 */
-                if ((f->config[6] ^ value) & 0xf7f) {
-                    if (f->config[6] & (1 << 6))               /* CSVALID */
-                        omap_gpmc_cs_unmap(f);
-                    if (value & (1 << 6))                      /* CSVALID */
-                        omap_gpmc_cs_map(f, value & 0x1f,      /* MASKADDR */
-                                        (value >> 8 & 0xf));   /* BASEADDR */
-                }
-                f->config[6] = value & 0x00000f7f;
-                break;
-            case 0x7c: /* GPMC_NAND_COMMAND */
-            case 0x80: /* GPMC_NAND_ADDRESS */
-            case 0x84: /* GPMC_NAND_DATA */
-                break;
-
-            default:
-                goto bad_reg;
-        }
-        break;
-
-    case 0x1e0:        /* GPMC_PREFETCH_CONFIG1 */
-        s->prefconfig[0] = value & 0x7f8f7fbf;
-        /* TODO: update interrupts, fifos, dmas */
-        break;
-
-    case 0x1e4:        /* GPMC_PREFETCH_CONFIG2 */
-        s->prefconfig[1] = value & 0x3fff;
-        break;
-
-    case 0x1ec:        /* GPMC_PREFETCH_CONTROL */
-        s->prefcontrol = value & 1;
-        if (s->prefcontrol) {
-            if (s->prefconfig[0] & 1)
-                s->preffifo = 0x40;
-            else
-                s->preffifo = 0x00;
-        }
-        /* TODO: start */
-        break;
-
-    case 0x1f4:        /* GPMC_ECC_CONFIG */
-        s->ecc_cs = 0x8f;
-        break;
-    case 0x1f8:        /* GPMC_ECC_CONTROL */
-        if (value & (1 << 8))
-            for (cs = 0; cs < 9; cs ++)
-                ecc_reset(&s->ecc[cs]);
-        s->ecc_ptr = value & 0xf;
-        if (s->ecc_ptr == 0 || s->ecc_ptr > 9) {
-            s->ecc_ptr = 0;
-            s->ecc_cs &= ~1;
-        }
-        break;
-    case 0x1fc:        /* GPMC_ECC_SIZE_CONFIG */
-        s->ecc_cfg = value & 0x3fcff1ff;
-        break;
-    case 0x230:        /* GPMC_TESTMODE_CTRL */
-        if (value & 7)
-            fprintf(stderr, "%s: test mode enable attempt\n", __FUNCTION__);
-        break;
-
-    default:
-    bad_reg:
-        OMAP_BAD_REG(addr);
-        return;
-    }
-}
-
-static CPUReadMemoryFunc * const omap_gpmc_readfn[] = {
-    omap_badwidth_read32,      /* TODO */
-    omap_badwidth_read32,      /* TODO */
-    omap_gpmc_read,
-};
-
-static CPUWriteMemoryFunc * const omap_gpmc_writefn[] = {
-    omap_badwidth_write32,     /* TODO */
-    omap_badwidth_write32,     /* TODO */
-    omap_gpmc_write,
-};
-
-struct omap_gpmc_s *omap_gpmc_init(target_phys_addr_t base, qemu_irq irq)
-{
-    int iomemtype;
-    struct omap_gpmc_s *s = (struct omap_gpmc_s *)
-            qemu_mallocz(sizeof(struct omap_gpmc_s));
-
-    omap_gpmc_reset(s);
-
-    iomemtype = cpu_register_io_memory(omap_gpmc_readfn,
-                    omap_gpmc_writefn, s);
-    cpu_register_physical_memory(base, 0x1000, iomemtype);
+    memory_region_init_io(&s->iomem, &omap_sysctl_ops, s, "omap.sysctl",
+                          omap_l4_region_size(ta, 0));
+    omap_l4_attach(ta, 0, &s->iomem);
 
     return s;
 }
 
-void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, int iomemtype,
-                void (*base_upd)(void *opaque, target_phys_addr_t new),
-                void (*unmap)(void *opaque), void *opaque)
-{
-    struct omap_gpmc_cs_file_s *f;
-
-    if (cs < 0 || cs >= 8) {
-        fprintf(stderr, "%s: bad chip-select %i\n", __FUNCTION__, cs);
-        exit(-1);
-    }
-    f = &s->cs_file[cs];
-
-    f->iomemtype = iomemtype;
-    f->base_update = base_upd;
-    f->unmap = unmap;
-    f->opaque = opaque;
-
-    if (f->config[6] & (1 << 6))                               /* CSVALID */
-        omap_gpmc_cs_map(f, f->config[6] & 0x1f,               /* MASKADDR */
-                        (f->config[6] >> 8 & 0xf));            /* BASEADDR */
-}
-
 /* General chip reset */
 static void omap2_mpu_reset(void *opaque)
 {
     struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
 
-    omap_inth_reset(mpu->ih[0]);
     omap_dma_reset(mpu->dma);
     omap_prcm_reset(mpu->prcm);
     omap_sysctl_reset(mpu->sysc);
@@ -4458,7 +2212,7 @@ static void omap2_mpu_reset(void *opaque)
     omap_gp_timer_reset(mpu->gptimer[9]);
     omap_gp_timer_reset(mpu->gptimer[10]);
     omap_gp_timer_reset(mpu->gptimer[11]);
-    omap_synctimer_reset(&mpu->synctimer);
+    omap_synctimer_reset(mpu->synctimer);
     omap_sdrc_reset(mpu->sdrc);
     omap_gpmc_reset(mpu->gpmc);
     omap_dss_reset(mpu->dss);
@@ -4466,7 +2220,6 @@ static void omap2_mpu_reset(void *opaque)
     omap_uart_reset(mpu->uart[1]);
     omap_uart_reset(mpu->uart[2]);
     omap_mmc_reset(mpu->mmc);
-    omap_gpif_reset(mpu->gpif);
     omap_mcspi_reset(mpu->mcspi[0]);
     omap_mcspi_reset(mpu->mcspi[1]);
     omap_i2c_reset(mpu->i2c[0]);
@@ -4487,17 +2240,18 @@ static const struct dma_irq_map omap2_dma_irq_map[] = {
     { 0, OMAP_INT_24XX_SDMA_IRQ3 },
 };
 
-struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size,
+struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sysmem,
+                unsigned long sdram_size,
                 const char *core)
 {
     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
-            qemu_mallocz(sizeof(struct omap_mpu_state_s));
-    ram_addr_t sram_base, q2_base;
+            g_malloc0(sizeof(struct omap_mpu_state_s));
     qemu_irq *cpu_irq;
     qemu_irq dma_irqs[4];
-    omap_clk gpio_clks[4];
     DriveInfo *dinfo;
     int i;
+    SysBusDevice *busdev;
+    struct omap_target_agent_s *ta;
 
     /* Core */
     s->mpu_model = omap2420;
@@ -4515,135 +2269,179 @@ struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size,
     omap_clk_init(s);
 
     /* Memory-mapped stuff */
-    cpu_register_physical_memory(OMAP2_Q2_BASE, s->sdram_size,
-                    (q2_base = qemu_ram_alloc(s->sdram_size)) | IO_MEM_RAM);
-    cpu_register_physical_memory(OMAP2_SRAM_BASE, s->sram_size,
-                    (sram_base = qemu_ram_alloc(s->sram_size)) | IO_MEM_RAM);
+    memory_region_init_ram(&s->sdram, "omap2.dram", s->sdram_size);
+    vmstate_register_ram_global(&s->sdram);
+    memory_region_add_subregion(sysmem, OMAP2_Q2_BASE, &s->sdram);
+    memory_region_init_ram(&s->sram, "omap2.sram", s->sram_size);
+    vmstate_register_ram_global(&s->sram);
+    memory_region_add_subregion(sysmem, OMAP2_SRAM_BASE, &s->sram);
 
-    s->l4 = omap_l4_init(OMAP2_L4_BASE, 54);
+    s->l4 = omap_l4_init(sysmem, OMAP2_L4_BASE, 54);
 
     /* Actually mapped at any 2K boundary in the ARM11 private-peripheral if */
     cpu_irq = arm_pic_init_cpu(s->env);
-    s->ih[0] = omap2_inth_init(0x480fe000, 0x1000, 3, &s->irq[0],
-                    cpu_irq[ARM_PIC_CPU_IRQ], cpu_irq[ARM_PIC_CPU_FIQ],
-                    omap_findclk(s, "mpu_intc_fclk"),
-                    omap_findclk(s, "mpu_intc_iclk"));
-
+    s->ih[0] = qdev_create(NULL, "omap2-intc");
+    qdev_prop_set_uint8(s->ih[0], "revision", 0x21);
+    qdev_prop_set_ptr(s->ih[0], "fclk", omap_findclk(s, "mpu_intc_fclk"));
+    qdev_prop_set_ptr(s->ih[0], "iclk", omap_findclk(s, "mpu_intc_iclk"));
+    qdev_init_nofail(s->ih[0]);
+    busdev = sysbus_from_qdev(s->ih[0]);
+    sysbus_connect_irq(busdev, 0, cpu_irq[ARM_PIC_CPU_IRQ]);
+    sysbus_connect_irq(busdev, 1, cpu_irq[ARM_PIC_CPU_FIQ]);
+    sysbus_mmio_map(busdev, 0, 0x480fe000);
     s->prcm = omap_prcm_init(omap_l4tao(s->l4, 3),
-                    s->irq[0][OMAP_INT_24XX_PRCM_MPU_IRQ], NULL, NULL, s);
+                             qdev_get_gpio_in(s->ih[0],
+                                              OMAP_INT_24XX_PRCM_MPU_IRQ),
+                             NULL, NULL, s);
 
     s->sysc = omap_sysctl_init(omap_l4tao(s->l4, 1),
                     omap_findclk(s, "omapctrl_iclk"), s);
 
-    for (i = 0; i < 4; i ++)
-        dma_irqs[i] =
-                s->irq[omap2_dma_irq_map[i].ih][omap2_dma_irq_map[i].intr];
-    s->dma = omap_dma4_init(0x48056000, dma_irqs, s, 256, 32,
+    for (i = 0; i < 4; i++) {
+        dma_irqs[i] = qdev_get_gpio_in(s->ih[omap2_dma_irq_map[i].ih],
+                                       omap2_dma_irq_map[i].intr);
+    }
+    s->dma = omap_dma4_init(0x48056000, dma_irqs, sysmem, s, 256, 32,
                     omap_findclk(s, "sdma_iclk"),
                     omap_findclk(s, "sdma_fclk"));
     s->port->addr_valid = omap2_validate_addr;
 
     /* Register SDRAM and SRAM ports for fast DMA transfers.  */
-    soc_dma_port_add_mem_ram(s->dma, q2_base, OMAP2_Q2_BASE, s->sdram_size);
-    soc_dma_port_add_mem_ram(s->dma, sram_base, OMAP2_SRAM_BASE, s->sram_size);
-
-    s->uart[0] = omap2_uart_init(omap_l4ta(s->l4, 19),
-                    s->irq[0][OMAP_INT_24XX_UART1_IRQ],
+    soc_dma_port_add_mem(s->dma, memory_region_get_ram_ptr(&s->sdram),
+                         OMAP2_Q2_BASE, s->sdram_size);
+    soc_dma_port_add_mem(s->dma, memory_region_get_ram_ptr(&s->sram),
+                         OMAP2_SRAM_BASE, s->sram_size);
+
+    s->uart[0] = omap2_uart_init(sysmem, omap_l4ta(s->l4, 19),
+                                 qdev_get_gpio_in(s->ih[0],
+                                                  OMAP_INT_24XX_UART1_IRQ),
                     omap_findclk(s, "uart1_fclk"),
                     omap_findclk(s, "uart1_iclk"),
                     s->drq[OMAP24XX_DMA_UART1_TX],
-                    s->drq[OMAP24XX_DMA_UART1_RX], serial_hds[0]);
-    s->uart[1] = omap2_uart_init(omap_l4ta(s->l4, 20),
-                    s->irq[0][OMAP_INT_24XX_UART2_IRQ],
+                    s->drq[OMAP24XX_DMA_UART1_RX],
+                    "uart1",
+                    serial_hds[0]);
+    s->uart[1] = omap2_uart_init(sysmem, omap_l4ta(s->l4, 20),
+                                 qdev_get_gpio_in(s->ih[0],
+                                                  OMAP_INT_24XX_UART2_IRQ),
                     omap_findclk(s, "uart2_fclk"),
                     omap_findclk(s, "uart2_iclk"),
                     s->drq[OMAP24XX_DMA_UART2_TX],
                     s->drq[OMAP24XX_DMA_UART2_RX],
-                    serial_hds[0] ? serial_hds[1] : 0);
-    s->uart[2] = omap2_uart_init(omap_l4ta(s->l4, 21),
-                    s->irq[0][OMAP_INT_24XX_UART3_IRQ],
+                    "uart2",
+                    serial_hds[0] ? serial_hds[1] : NULL);
+    s->uart[2] = omap2_uart_init(sysmem, omap_l4ta(s->l4, 21),
+                                 qdev_get_gpio_in(s->ih[0],
+                                                  OMAP_INT_24XX_UART3_IRQ),
                     omap_findclk(s, "uart3_fclk"),
                     omap_findclk(s, "uart3_iclk"),
                     s->drq[OMAP24XX_DMA_UART3_TX],
                     s->drq[OMAP24XX_DMA_UART3_RX],
-                    serial_hds[0] && serial_hds[1] ? serial_hds[2] : 0);
+                    "uart3",
+                    serial_hds[0] && serial_hds[1] ? serial_hds[2] : NULL);
 
     s->gptimer[0] = omap_gp_timer_init(omap_l4ta(s->l4, 7),
-                    s->irq[0][OMAP_INT_24XX_GPTIMER1],
+                    qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER1),
                     omap_findclk(s, "wu_gpt1_clk"),
                     omap_findclk(s, "wu_l4_iclk"));
     s->gptimer[1] = omap_gp_timer_init(omap_l4ta(s->l4, 8),
-                    s->irq[0][OMAP_INT_24XX_GPTIMER2],
+                    qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER2),
                     omap_findclk(s, "core_gpt2_clk"),
                     omap_findclk(s, "core_l4_iclk"));
     s->gptimer[2] = omap_gp_timer_init(omap_l4ta(s->l4, 22),
-                    s->irq[0][OMAP_INT_24XX_GPTIMER3],
+                    qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER3),
                     omap_findclk(s, "core_gpt3_clk"),
                     omap_findclk(s, "core_l4_iclk"));
     s->gptimer[3] = omap_gp_timer_init(omap_l4ta(s->l4, 23),
-                    s->irq[0][OMAP_INT_24XX_GPTIMER4],
+                    qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER4),
                     omap_findclk(s, "core_gpt4_clk"),
                     omap_findclk(s, "core_l4_iclk"));
     s->gptimer[4] = omap_gp_timer_init(omap_l4ta(s->l4, 24),
-                    s->irq[0][OMAP_INT_24XX_GPTIMER5],
+                    qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER5),
                     omap_findclk(s, "core_gpt5_clk"),
                     omap_findclk(s, "core_l4_iclk"));
     s->gptimer[5] = omap_gp_timer_init(omap_l4ta(s->l4, 25),
-                    s->irq[0][OMAP_INT_24XX_GPTIMER6],
+                    qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER6),
                     omap_findclk(s, "core_gpt6_clk"),
                     omap_findclk(s, "core_l4_iclk"));
     s->gptimer[6] = omap_gp_timer_init(omap_l4ta(s->l4, 26),
-                    s->irq[0][OMAP_INT_24XX_GPTIMER7],
+                    qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER7),
                     omap_findclk(s, "core_gpt7_clk"),
                     omap_findclk(s, "core_l4_iclk"));
     s->gptimer[7] = omap_gp_timer_init(omap_l4ta(s->l4, 27),
-                    s->irq[0][OMAP_INT_24XX_GPTIMER8],
+                    qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER8),
                     omap_findclk(s, "core_gpt8_clk"),
                     omap_findclk(s, "core_l4_iclk"));
     s->gptimer[8] = omap_gp_timer_init(omap_l4ta(s->l4, 28),
-                    s->irq[0][OMAP_INT_24XX_GPTIMER9],
+                    qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER9),
                     omap_findclk(s, "core_gpt9_clk"),
                     omap_findclk(s, "core_l4_iclk"));
     s->gptimer[9] = omap_gp_timer_init(omap_l4ta(s->l4, 29),
-                    s->irq[0][OMAP_INT_24XX_GPTIMER10],
+                    qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER10),
                     omap_findclk(s, "core_gpt10_clk"),
                     omap_findclk(s, "core_l4_iclk"));
     s->gptimer[10] = omap_gp_timer_init(omap_l4ta(s->l4, 30),
-                    s->irq[0][OMAP_INT_24XX_GPTIMER11],
+                    qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER11),
                     omap_findclk(s, "core_gpt11_clk"),
                     omap_findclk(s, "core_l4_iclk"));
     s->gptimer[11] = omap_gp_timer_init(omap_l4ta(s->l4, 31),
-                    s->irq[0][OMAP_INT_24XX_GPTIMER12],
+                    qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER12),
                     omap_findclk(s, "core_gpt12_clk"),
                     omap_findclk(s, "core_l4_iclk"));
 
     omap_tap_init(omap_l4ta(s->l4, 2), s);
 
-    omap_synctimer_init(omap_l4tao(s->l4, 2), s,
+    s->synctimer = omap_synctimer_init(omap_l4tao(s->l4, 2), s,
                     omap_findclk(s, "clk32-kHz"),
                     omap_findclk(s, "core_l4_iclk"));
 
     s->i2c[0] = omap2_i2c_init(omap_l4tao(s->l4, 5),
-                    s->irq[0][OMAP_INT_24XX_I2C1_IRQ],
+                    qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_I2C1_IRQ),
                     &s->drq[OMAP24XX_DMA_I2C1_TX],
                     omap_findclk(s, "i2c1.fclk"),
                     omap_findclk(s, "i2c1.iclk"));
     s->i2c[1] = omap2_i2c_init(omap_l4tao(s->l4, 6),
-                    s->irq[0][OMAP_INT_24XX_I2C2_IRQ],
+                    qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_I2C2_IRQ),
                     &s->drq[OMAP24XX_DMA_I2C2_TX],
                     omap_findclk(s, "i2c2.fclk"),
                     omap_findclk(s, "i2c2.iclk"));
 
-    gpio_clks[0] = omap_findclk(s, "gpio1_dbclk");
-    gpio_clks[1] = omap_findclk(s, "gpio2_dbclk");
-    gpio_clks[2] = omap_findclk(s, "gpio3_dbclk");
-    gpio_clks[3] = omap_findclk(s, "gpio4_dbclk");
-    s->gpif = omap2_gpio_init(omap_l4ta(s->l4, 3),
-                    &s->irq[0][OMAP_INT_24XX_GPIO_BANK1],
-                    gpio_clks, omap_findclk(s, "gpio_iclk"), 4);
-
-    s->sdrc = omap_sdrc_init(0x68009000);
-    s->gpmc = omap_gpmc_init(0x6800a000, s->irq[0][OMAP_INT_24XX_GPMC_IRQ]);
+    s->gpio = qdev_create(NULL, "omap2-gpio");
+    qdev_prop_set_int32(s->gpio, "mpu_model", s->mpu_model);
+    qdev_prop_set_ptr(s->gpio, "iclk", omap_findclk(s, "gpio_iclk"));
+    qdev_prop_set_ptr(s->gpio, "fclk0", omap_findclk(s, "gpio1_dbclk"));
+    qdev_prop_set_ptr(s->gpio, "fclk1", omap_findclk(s, "gpio2_dbclk"));
+    qdev_prop_set_ptr(s->gpio, "fclk2", omap_findclk(s, "gpio3_dbclk"));
+    qdev_prop_set_ptr(s->gpio, "fclk3", omap_findclk(s, "gpio4_dbclk"));
+    if (s->mpu_model == omap2430) {
+        qdev_prop_set_ptr(s->gpio, "fclk4", omap_findclk(s, "gpio5_dbclk"));
+    }
+    qdev_init_nofail(s->gpio);
+    busdev = sysbus_from_qdev(s->gpio);
+    sysbus_connect_irq(busdev, 0,
+                       qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPIO_BANK1));
+    sysbus_connect_irq(busdev, 3,
+                       qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPIO_BANK2));
+    sysbus_connect_irq(busdev, 6,
+                       qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPIO_BANK3));
+    sysbus_connect_irq(busdev, 9,
+                       qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPIO_BANK4));
+    if (s->mpu_model == omap2430) {
+        sysbus_connect_irq(busdev, 12,
+                           qdev_get_gpio_in(s->ih[0],
+                                            OMAP_INT_243X_GPIO_BANK5));
+    }
+    ta = omap_l4ta(s->l4, 3);
+    sysbus_mmio_map(busdev, 0, omap_l4_region_base(ta, 1));
+    sysbus_mmio_map(busdev, 1, omap_l4_region_base(ta, 0));
+    sysbus_mmio_map(busdev, 2, omap_l4_region_base(ta, 2));
+    sysbus_mmio_map(busdev, 3, omap_l4_region_base(ta, 4));
+    sysbus_mmio_map(busdev, 4, omap_l4_region_base(ta, 5));
+
+    s->sdrc = omap_sdrc_init(sysmem, 0x68009000);
+    s->gpmc = omap_gpmc_init(s, 0x6800a000,
+                             qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPMC_IRQ),
+                             s->drq[OMAP24XX_DMA_GPMC]);
 
     dinfo = drive_get(IF_SD, 0, 0);
     if (!dinfo) {
@@ -4651,36 +2449,38 @@ struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size,
         exit(1);
     }
     s->mmc = omap2_mmc_init(omap_l4tao(s->l4, 9), dinfo->bdrv,
-                    s->irq[0][OMAP_INT_24XX_MMC_IRQ],
+                    qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_MMC_IRQ),
                     &s->drq[OMAP24XX_DMA_MMC1_TX],
                     omap_findclk(s, "mmc_fclk"), omap_findclk(s, "mmc_iclk"));
 
     s->mcspi[0] = omap_mcspi_init(omap_l4ta(s->l4, 35), 4,
-                    s->irq[0][OMAP_INT_24XX_MCSPI1_IRQ],
+                    qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_MCSPI1_IRQ),
                     &s->drq[OMAP24XX_DMA_SPI1_TX0],
                     omap_findclk(s, "spi1_fclk"),
                     omap_findclk(s, "spi1_iclk"));
     s->mcspi[1] = omap_mcspi_init(omap_l4ta(s->l4, 36), 2,
-                    s->irq[0][OMAP_INT_24XX_MCSPI2_IRQ],
+                    qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_MCSPI2_IRQ),
                     &s->drq[OMAP24XX_DMA_SPI2_TX0],
                     omap_findclk(s, "spi2_fclk"),
                     omap_findclk(s, "spi2_iclk"));
 
-    s->dss = omap_dss_init(omap_l4ta(s->l4, 10), 0x68000800,
+    s->dss = omap_dss_init(omap_l4ta(s->l4, 10), sysmem, 0x68000800,
                     /* XXX wire M_IRQ_25, D_L2_IRQ_30 and I_IRQ_13 together */
-                    s->irq[0][OMAP_INT_24XX_DSS_IRQ], s->drq[OMAP24XX_DMA_DSS],
+                    qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_DSS_IRQ),
+                           s->drq[OMAP24XX_DMA_DSS],
                     omap_findclk(s, "dss_clk1"), omap_findclk(s, "dss_clk2"),
                     omap_findclk(s, "dss_54m_clk"),
                     omap_findclk(s, "dss_l3_iclk"),
                     omap_findclk(s, "dss_l4_iclk"));
 
-    omap_sti_init(omap_l4ta(s->l4, 18), 0x54000000,
-                    s->irq[0][OMAP_INT_24XX_STI], omap_findclk(s, "emul_ck"),
+    omap_sti_init(omap_l4ta(s->l4, 18), sysmem, 0x54000000,
+                  qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_STI),
+                  omap_findclk(s, "emul_ck"),
                     serial_hds[0] && serial_hds[1] && serial_hds[2] ?
-                    serial_hds[3] : 0);
+                    serial_hds[3] : NULL);
 
     s->eac = omap_eac_init(omap_l4ta(s->l4, 32),
-                    s->irq[0][OMAP_INT_24XX_EAC_IRQ],
+                           qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_EAC_IRQ),
                     /* Ten consecutive lines */
                     &s->drq[OMAP24XX_DMA_EAC_AC_RD],
                     omap_findclk(s, "func_96m_clk"),