cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

omap1.c (118887B)


      1/*
      2 * TI OMAP processors emulation.
      3 *
      4 * Copyright (C) 2006-2008 Andrzej Zaborowski  <balrog@zabor.org>
      5 *
      6 * This program is free software; you can redistribute it and/or
      7 * modify it under the terms of the GNU General Public License as
      8 * published by the Free Software Foundation; either version 2 or
      9 * (at your option) version 3 of the License.
     10 *
     11 * This program is distributed in the hope that it will be useful,
     12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 * GNU General Public License for more details.
     15 *
     16 * You should have received a copy of the GNU General Public License along
     17 * with this program; if not, see <http://www.gnu.org/licenses/>.
     18 */
     19
     20#include "qemu/osdep.h"
     21#include "qemu/error-report.h"
     22#include "qemu/main-loop.h"
     23#include "qapi/error.h"
     24#include "qemu-common.h"
     25#include "cpu.h"
     26#include "exec/address-spaces.h"
     27#include "hw/hw.h"
     28#include "hw/irq.h"
     29#include "hw/qdev-properties.h"
     30#include "hw/arm/boot.h"
     31#include "hw/arm/omap.h"
     32#include "sysemu/blockdev.h"
     33#include "sysemu/sysemu.h"
     34#include "hw/arm/soc_dma.h"
     35#include "sysemu/qtest.h"
     36#include "sysemu/reset.h"
     37#include "sysemu/runstate.h"
     38#include "qemu/range.h"
     39#include "hw/sysbus.h"
     40#include "qemu/cutils.h"
     41#include "qemu/bcd.h"
     42
     43static inline void omap_log_badwidth(const char *funcname, hwaddr addr, int sz)
     44{
     45    qemu_log_mask(LOG_GUEST_ERROR, "%s: %d-bit register %#08" HWADDR_PRIx "\n",
     46                  funcname, 8 * sz, addr);
     47}
     48
     49/* Should signal the TCMI/GPMC */
     50uint32_t omap_badwidth_read8(void *opaque, hwaddr addr)
     51{
     52    uint8_t ret;
     53
     54    omap_log_badwidth(__func__, addr, 1);
     55    cpu_physical_memory_read(addr, &ret, 1);
     56    return ret;
     57}
     58
     59void omap_badwidth_write8(void *opaque, hwaddr addr,
     60                uint32_t value)
     61{
     62    uint8_t val8 = value;
     63
     64    omap_log_badwidth(__func__, addr, 1);
     65    cpu_physical_memory_write(addr, &val8, 1);
     66}
     67
     68uint32_t omap_badwidth_read16(void *opaque, hwaddr addr)
     69{
     70    uint16_t ret;
     71
     72    omap_log_badwidth(__func__, addr, 2);
     73    cpu_physical_memory_read(addr, &ret, 2);
     74    return ret;
     75}
     76
     77void omap_badwidth_write16(void *opaque, hwaddr addr,
     78                uint32_t value)
     79{
     80    uint16_t val16 = value;
     81
     82    omap_log_badwidth(__func__, addr, 2);
     83    cpu_physical_memory_write(addr, &val16, 2);
     84}
     85
     86uint32_t omap_badwidth_read32(void *opaque, hwaddr addr)
     87{
     88    uint32_t ret;
     89
     90    omap_log_badwidth(__func__, addr, 4);
     91    cpu_physical_memory_read(addr, &ret, 4);
     92    return ret;
     93}
     94
     95void omap_badwidth_write32(void *opaque, hwaddr addr,
     96                uint32_t value)
     97{
     98    omap_log_badwidth(__func__, addr, 4);
     99    cpu_physical_memory_write(addr, &value, 4);
    100}
    101
    102/* MPU OS timers */
    103struct omap_mpu_timer_s {
    104    MemoryRegion iomem;
    105    qemu_irq irq;
    106    omap_clk clk;
    107    uint32_t val;
    108    int64_t time;
    109    QEMUTimer *timer;
    110    QEMUBH *tick;
    111    int64_t rate;
    112    int it_ena;
    113
    114    int enable;
    115    int ptv;
    116    int ar;
    117    int st;
    118    uint32_t reset_val;
    119};
    120
    121static inline uint32_t omap_timer_read(struct omap_mpu_timer_s *timer)
    122{
    123    uint64_t distance = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - timer->time;
    124
    125    if (timer->st && timer->enable && timer->rate)
    126        return timer->val - muldiv64(distance >> (timer->ptv + 1),
    127                                     timer->rate, NANOSECONDS_PER_SECOND);
    128    else
    129        return timer->val;
    130}
    131
    132static inline void omap_timer_sync(struct omap_mpu_timer_s *timer)
    133{
    134    timer->val = omap_timer_read(timer);
    135    timer->time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
    136}
    137
    138static inline void omap_timer_update(struct omap_mpu_timer_s *timer)
    139{
    140    int64_t expires;
    141
    142    if (timer->enable && timer->st && timer->rate) {
    143        timer->val = timer->reset_val;	/* Should skip this on clk enable */
    144        expires = muldiv64((uint64_t) timer->val << (timer->ptv + 1),
    145                           NANOSECONDS_PER_SECOND, timer->rate);
    146
    147        /* If timer expiry would be sooner than in about 1 ms and
    148         * auto-reload isn't set, then fire immediately.  This is a hack
    149         * to make systems like PalmOS run in acceptable time.  PalmOS
    150         * sets the interval to a very low value and polls the status bit
    151         * in a busy loop when it wants to sleep just a couple of CPU
    152         * ticks.  */
    153        if (expires > (NANOSECONDS_PER_SECOND >> 10) || timer->ar) {
    154            timer_mod(timer->timer, timer->time + expires);
    155        } else {
    156            qemu_bh_schedule(timer->tick);
    157        }
    158    } else
    159        timer_del(timer->timer);
    160}
    161
    162static void omap_timer_fire(void *opaque)
    163{
    164    struct omap_mpu_timer_s *timer = opaque;
    165
    166    if (!timer->ar) {
    167        timer->val = 0;
    168        timer->st = 0;
    169    }
    170
    171    if (timer->it_ena)
    172        /* Edge-triggered irq */
    173        qemu_irq_pulse(timer->irq);
    174}
    175
    176static void omap_timer_tick(void *opaque)
    177{
    178    struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
    179
    180    omap_timer_sync(timer);
    181    omap_timer_fire(timer);
    182    omap_timer_update(timer);
    183}
    184
    185static void omap_timer_clk_update(void *opaque, int line, int on)
    186{
    187    struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
    188
    189    omap_timer_sync(timer);
    190    timer->rate = on ? omap_clk_getrate(timer->clk) : 0;
    191    omap_timer_update(timer);
    192}
    193
    194static void omap_timer_clk_setup(struct omap_mpu_timer_s *timer)
    195{
    196    omap_clk_adduser(timer->clk,
    197                    qemu_allocate_irq(omap_timer_clk_update, timer, 0));
    198    timer->rate = omap_clk_getrate(timer->clk);
    199}
    200
    201static uint64_t omap_mpu_timer_read(void *opaque, hwaddr addr,
    202                                    unsigned size)
    203{
    204    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
    205
    206    if (size != 4) {
    207        return omap_badwidth_read32(opaque, addr);
    208    }
    209
    210    switch (addr) {
    211    case 0x00:	/* CNTL_TIMER */
    212        return (s->enable << 5) | (s->ptv << 2) | (s->ar << 1) | s->st;
    213
    214    case 0x04:	/* LOAD_TIM */
    215        break;
    216
    217    case 0x08:	/* READ_TIM */
    218        return omap_timer_read(s);
    219    }
    220
    221    OMAP_BAD_REG(addr);
    222    return 0;
    223}
    224
    225static void omap_mpu_timer_write(void *opaque, hwaddr addr,
    226                                 uint64_t value, unsigned size)
    227{
    228    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
    229
    230    if (size != 4) {
    231        omap_badwidth_write32(opaque, addr, value);
    232        return;
    233    }
    234
    235    switch (addr) {
    236    case 0x00:	/* CNTL_TIMER */
    237        omap_timer_sync(s);
    238        s->enable = (value >> 5) & 1;
    239        s->ptv = (value >> 2) & 7;
    240        s->ar = (value >> 1) & 1;
    241        s->st = value & 1;
    242        omap_timer_update(s);
    243        return;
    244
    245    case 0x04:	/* LOAD_TIM */
    246        s->reset_val = value;
    247        return;
    248
    249    case 0x08:	/* READ_TIM */
    250        OMAP_RO_REG(addr);
    251        break;
    252
    253    default:
    254        OMAP_BAD_REG(addr);
    255    }
    256}
    257
    258static const MemoryRegionOps omap_mpu_timer_ops = {
    259    .read = omap_mpu_timer_read,
    260    .write = omap_mpu_timer_write,
    261    .endianness = DEVICE_LITTLE_ENDIAN,
    262};
    263
    264static void omap_mpu_timer_reset(struct omap_mpu_timer_s *s)
    265{
    266    timer_del(s->timer);
    267    s->enable = 0;
    268    s->reset_val = 31337;
    269    s->val = 0;
    270    s->ptv = 0;
    271    s->ar = 0;
    272    s->st = 0;
    273    s->it_ena = 1;
    274}
    275
    276static struct omap_mpu_timer_s *omap_mpu_timer_init(MemoryRegion *system_memory,
    277                hwaddr base,
    278                qemu_irq irq, omap_clk clk)
    279{
    280    struct omap_mpu_timer_s *s = g_new0(struct omap_mpu_timer_s, 1);
    281
    282    s->irq = irq;
    283    s->clk = clk;
    284    s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_timer_tick, s);
    285    s->tick = qemu_bh_new(omap_timer_fire, s);
    286    omap_mpu_timer_reset(s);
    287    omap_timer_clk_setup(s);
    288
    289    memory_region_init_io(&s->iomem, NULL, &omap_mpu_timer_ops, s,
    290                          "omap-mpu-timer", 0x100);
    291
    292    memory_region_add_subregion(system_memory, base, &s->iomem);
    293
    294    return s;
    295}
    296
    297/* Watchdog timer */
    298struct omap_watchdog_timer_s {
    299    struct omap_mpu_timer_s timer;
    300    MemoryRegion iomem;
    301    uint8_t last_wr;
    302    int mode;
    303    int free;
    304    int reset;
    305};
    306
    307static uint64_t omap_wd_timer_read(void *opaque, hwaddr addr,
    308                                   unsigned size)
    309{
    310    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
    311
    312    if (size != 2) {
    313        return omap_badwidth_read16(opaque, addr);
    314    }
    315
    316    switch (addr) {
    317    case 0x00:	/* CNTL_TIMER */
    318        return (s->timer.ptv << 9) | (s->timer.ar << 8) |
    319                (s->timer.st << 7) | (s->free << 1);
    320
    321    case 0x04:	/* READ_TIMER */
    322        return omap_timer_read(&s->timer);
    323
    324    case 0x08:	/* TIMER_MODE */
    325        return s->mode << 15;
    326    }
    327
    328    OMAP_BAD_REG(addr);
    329    return 0;
    330}
    331
    332static void omap_wd_timer_write(void *opaque, hwaddr addr,
    333                                uint64_t value, unsigned size)
    334{
    335    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
    336
    337    if (size != 2) {
    338        omap_badwidth_write16(opaque, addr, value);
    339        return;
    340    }
    341
    342    switch (addr) {
    343    case 0x00:	/* CNTL_TIMER */
    344        omap_timer_sync(&s->timer);
    345        s->timer.ptv = (value >> 9) & 7;
    346        s->timer.ar = (value >> 8) & 1;
    347        s->timer.st = (value >> 7) & 1;
    348        s->free = (value >> 1) & 1;
    349        omap_timer_update(&s->timer);
    350        break;
    351
    352    case 0x04:	/* LOAD_TIMER */
    353        s->timer.reset_val = value & 0xffff;
    354        break;
    355
    356    case 0x08:	/* TIMER_MODE */
    357        if (!s->mode && ((value >> 15) & 1))
    358            omap_clk_get(s->timer.clk);
    359        s->mode |= (value >> 15) & 1;
    360        if (s->last_wr == 0xf5) {
    361            if ((value & 0xff) == 0xa0) {
    362                if (s->mode) {
    363                    s->mode = 0;
    364                    omap_clk_put(s->timer.clk);
    365                }
    366            } else {
    367                /* XXX: on T|E hardware somehow this has no effect,
    368                 * on Zire 71 it works as specified.  */
    369                s->reset = 1;
    370                qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
    371            }
    372        }
    373        s->last_wr = value & 0xff;
    374        break;
    375
    376    default:
    377        OMAP_BAD_REG(addr);
    378    }
    379}
    380
    381static const MemoryRegionOps omap_wd_timer_ops = {
    382    .read = omap_wd_timer_read,
    383    .write = omap_wd_timer_write,
    384    .endianness = DEVICE_NATIVE_ENDIAN,
    385};
    386
    387static void omap_wd_timer_reset(struct omap_watchdog_timer_s *s)
    388{
    389    timer_del(s->timer.timer);
    390    if (!s->mode)
    391        omap_clk_get(s->timer.clk);
    392    s->mode = 1;
    393    s->free = 1;
    394    s->reset = 0;
    395    s->timer.enable = 1;
    396    s->timer.it_ena = 1;
    397    s->timer.reset_val = 0xffff;
    398    s->timer.val = 0;
    399    s->timer.st = 0;
    400    s->timer.ptv = 0;
    401    s->timer.ar = 0;
    402    omap_timer_update(&s->timer);
    403}
    404
    405static struct omap_watchdog_timer_s *omap_wd_timer_init(MemoryRegion *memory,
    406                hwaddr base,
    407                qemu_irq irq, omap_clk clk)
    408{
    409    struct omap_watchdog_timer_s *s = g_new0(struct omap_watchdog_timer_s, 1);
    410
    411    s->timer.irq = irq;
    412    s->timer.clk = clk;
    413    s->timer.timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_timer_tick, &s->timer);
    414    omap_wd_timer_reset(s);
    415    omap_timer_clk_setup(&s->timer);
    416
    417    memory_region_init_io(&s->iomem, NULL, &omap_wd_timer_ops, s,
    418                          "omap-wd-timer", 0x100);
    419    memory_region_add_subregion(memory, base, &s->iomem);
    420
    421    return s;
    422}
    423
    424/* 32-kHz timer */
    425struct omap_32khz_timer_s {
    426    struct omap_mpu_timer_s timer;
    427    MemoryRegion iomem;
    428};
    429
    430static uint64_t omap_os_timer_read(void *opaque, hwaddr addr,
    431                                   unsigned size)
    432{
    433    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
    434    int offset = addr & OMAP_MPUI_REG_MASK;
    435
    436    if (size != 4) {
    437        return omap_badwidth_read32(opaque, addr);
    438    }
    439
    440    switch (offset) {
    441    case 0x00:	/* TVR */
    442        return s->timer.reset_val;
    443
    444    case 0x04:	/* TCR */
    445        return omap_timer_read(&s->timer);
    446
    447    case 0x08:	/* CR */
    448        return (s->timer.ar << 3) | (s->timer.it_ena << 2) | s->timer.st;
    449
    450    default:
    451        break;
    452    }
    453    OMAP_BAD_REG(addr);
    454    return 0;
    455}
    456
    457static void omap_os_timer_write(void *opaque, hwaddr addr,
    458                                uint64_t value, unsigned size)
    459{
    460    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
    461    int offset = addr & OMAP_MPUI_REG_MASK;
    462
    463    if (size != 4) {
    464        omap_badwidth_write32(opaque, addr, value);
    465        return;
    466    }
    467
    468    switch (offset) {
    469    case 0x00:	/* TVR */
    470        s->timer.reset_val = value & 0x00ffffff;
    471        break;
    472
    473    case 0x04:	/* TCR */
    474        OMAP_RO_REG(addr);
    475        break;
    476
    477    case 0x08:	/* CR */
    478        s->timer.ar = (value >> 3) & 1;
    479        s->timer.it_ena = (value >> 2) & 1;
    480        if (s->timer.st != (value & 1) || (value & 2)) {
    481            omap_timer_sync(&s->timer);
    482            s->timer.enable = value & 1;
    483            s->timer.st = value & 1;
    484            omap_timer_update(&s->timer);
    485        }
    486        break;
    487
    488    default:
    489        OMAP_BAD_REG(addr);
    490    }
    491}
    492
    493static const MemoryRegionOps omap_os_timer_ops = {
    494    .read = omap_os_timer_read,
    495    .write = omap_os_timer_write,
    496    .endianness = DEVICE_NATIVE_ENDIAN,
    497};
    498
    499static void omap_os_timer_reset(struct omap_32khz_timer_s *s)
    500{
    501    timer_del(s->timer.timer);
    502    s->timer.enable = 0;
    503    s->timer.it_ena = 0;
    504    s->timer.reset_val = 0x00ffffff;
    505    s->timer.val = 0;
    506    s->timer.st = 0;
    507    s->timer.ptv = 0;
    508    s->timer.ar = 1;
    509}
    510
    511static struct omap_32khz_timer_s *omap_os_timer_init(MemoryRegion *memory,
    512                hwaddr base,
    513                qemu_irq irq, omap_clk clk)
    514{
    515    struct omap_32khz_timer_s *s = g_new0(struct omap_32khz_timer_s, 1);
    516
    517    s->timer.irq = irq;
    518    s->timer.clk = clk;
    519    s->timer.timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_timer_tick, &s->timer);
    520    omap_os_timer_reset(s);
    521    omap_timer_clk_setup(&s->timer);
    522
    523    memory_region_init_io(&s->iomem, NULL, &omap_os_timer_ops, s,
    524                          "omap-os-timer", 0x800);
    525    memory_region_add_subregion(memory, base, &s->iomem);
    526
    527    return s;
    528}
    529
    530/* Ultra Low-Power Device Module */
    531static uint64_t omap_ulpd_pm_read(void *opaque, hwaddr addr,
    532                                  unsigned size)
    533{
    534    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
    535    uint16_t ret;
    536
    537    if (size != 2) {
    538        return omap_badwidth_read16(opaque, addr);
    539    }
    540
    541    switch (addr) {
    542    case 0x14:	/* IT_STATUS */
    543        ret = s->ulpd_pm_regs[addr >> 2];
    544        s->ulpd_pm_regs[addr >> 2] = 0;
    545        qemu_irq_lower(qdev_get_gpio_in(s->ih[1], OMAP_INT_GAUGE_32K));
    546        return ret;
    547
    548    case 0x18:	/* Reserved */
    549    case 0x1c:	/* Reserved */
    550    case 0x20:	/* Reserved */
    551    case 0x28:	/* Reserved */
    552    case 0x2c:	/* Reserved */
    553        OMAP_BAD_REG(addr);
    554        /* fall through */
    555    case 0x00:	/* COUNTER_32_LSB */
    556    case 0x04:	/* COUNTER_32_MSB */
    557    case 0x08:	/* COUNTER_HIGH_FREQ_LSB */
    558    case 0x0c:	/* COUNTER_HIGH_FREQ_MSB */
    559    case 0x10:	/* GAUGING_CTRL */
    560    case 0x24:	/* SETUP_ANALOG_CELL3_ULPD1 */
    561    case 0x30:	/* CLOCK_CTRL */
    562    case 0x34:	/* SOFT_REQ */
    563    case 0x38:	/* COUNTER_32_FIQ */
    564    case 0x3c:	/* DPLL_CTRL */
    565    case 0x40:	/* STATUS_REQ */
    566        /* XXX: check clk::usecount state for every clock */
    567    case 0x48:	/* LOCL_TIME */
    568    case 0x4c:	/* APLL_CTRL */
    569    case 0x50:	/* POWER_CTRL */
    570        return s->ulpd_pm_regs[addr >> 2];
    571    }
    572
    573    OMAP_BAD_REG(addr);
    574    return 0;
    575}
    576
    577static inline void omap_ulpd_clk_update(struct omap_mpu_state_s *s,
    578                uint16_t diff, uint16_t value)
    579{
    580    if (diff & (1 << 4))				/* USB_MCLK_EN */
    581        omap_clk_onoff(omap_findclk(s, "usb_clk0"), (value >> 4) & 1);
    582    if (diff & (1 << 5))				/* DIS_USB_PVCI_CLK */
    583        omap_clk_onoff(omap_findclk(s, "usb_w2fc_ck"), (~value >> 5) & 1);
    584}
    585
    586static inline void omap_ulpd_req_update(struct omap_mpu_state_s *s,
    587                uint16_t diff, uint16_t value)
    588{
    589    if (diff & (1 << 0))				/* SOFT_DPLL_REQ */
    590        omap_clk_canidle(omap_findclk(s, "dpll4"), (~value >> 0) & 1);
    591    if (diff & (1 << 1))				/* SOFT_COM_REQ */
    592        omap_clk_canidle(omap_findclk(s, "com_mclk_out"), (~value >> 1) & 1);
    593    if (diff & (1 << 2))				/* SOFT_SDW_REQ */
    594        omap_clk_canidle(omap_findclk(s, "bt_mclk_out"), (~value >> 2) & 1);
    595    if (diff & (1 << 3))				/* SOFT_USB_REQ */
    596        omap_clk_canidle(omap_findclk(s, "usb_clk0"), (~value >> 3) & 1);
    597}
    598
    599static void omap_ulpd_pm_write(void *opaque, hwaddr addr,
    600                               uint64_t value, unsigned size)
    601{
    602    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
    603    int64_t now, ticks;
    604    int div, mult;
    605    static const int bypass_div[4] = { 1, 2, 4, 4 };
    606    uint16_t diff;
    607
    608    if (size != 2) {
    609        omap_badwidth_write16(opaque, addr, value);
    610        return;
    611    }
    612
    613    switch (addr) {
    614    case 0x00:	/* COUNTER_32_LSB */
    615    case 0x04:	/* COUNTER_32_MSB */
    616    case 0x08:	/* COUNTER_HIGH_FREQ_LSB */
    617    case 0x0c:	/* COUNTER_HIGH_FREQ_MSB */
    618    case 0x14:	/* IT_STATUS */
    619    case 0x40:	/* STATUS_REQ */
    620        OMAP_RO_REG(addr);
    621        break;
    622
    623    case 0x10:	/* GAUGING_CTRL */
    624        /* Bits 0 and 1 seem to be confused in the OMAP 310 TRM */
    625        if ((s->ulpd_pm_regs[addr >> 2] ^ value) & 1) {
    626            now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
    627
    628            if (value & 1)
    629                s->ulpd_gauge_start = now;
    630            else {
    631                now -= s->ulpd_gauge_start;
    632
    633                /* 32-kHz ticks */
    634                ticks = muldiv64(now, 32768, NANOSECONDS_PER_SECOND);
    635                s->ulpd_pm_regs[0x00 >> 2] = (ticks >>  0) & 0xffff;
    636                s->ulpd_pm_regs[0x04 >> 2] = (ticks >> 16) & 0xffff;
    637                if (ticks >> 32)	/* OVERFLOW_32K */
    638                    s->ulpd_pm_regs[0x14 >> 2] |= 1 << 2;
    639
    640                /* High frequency ticks */
    641                ticks = muldiv64(now, 12000000, NANOSECONDS_PER_SECOND);
    642                s->ulpd_pm_regs[0x08 >> 2] = (ticks >>  0) & 0xffff;
    643                s->ulpd_pm_regs[0x0c >> 2] = (ticks >> 16) & 0xffff;
    644                if (ticks >> 32)	/* OVERFLOW_HI_FREQ */
    645                    s->ulpd_pm_regs[0x14 >> 2] |= 1 << 1;
    646
    647                s->ulpd_pm_regs[0x14 >> 2] |= 1 << 0;	/* IT_GAUGING */
    648                qemu_irq_raise(qdev_get_gpio_in(s->ih[1], OMAP_INT_GAUGE_32K));
    649            }
    650        }
    651        s->ulpd_pm_regs[addr >> 2] = value;
    652        break;
    653
    654    case 0x18:	/* Reserved */
    655    case 0x1c:	/* Reserved */
    656    case 0x20:	/* Reserved */
    657    case 0x28:	/* Reserved */
    658    case 0x2c:	/* Reserved */
    659        OMAP_BAD_REG(addr);
    660        /* fall through */
    661    case 0x24:	/* SETUP_ANALOG_CELL3_ULPD1 */
    662    case 0x38:	/* COUNTER_32_FIQ */
    663    case 0x48:	/* LOCL_TIME */
    664    case 0x50:	/* POWER_CTRL */
    665        s->ulpd_pm_regs[addr >> 2] = value;
    666        break;
    667
    668    case 0x30:	/* CLOCK_CTRL */
    669        diff = s->ulpd_pm_regs[addr >> 2] ^ value;
    670        s->ulpd_pm_regs[addr >> 2] = value & 0x3f;
    671        omap_ulpd_clk_update(s, diff, value);
    672        break;
    673
    674    case 0x34:	/* SOFT_REQ */
    675        diff = s->ulpd_pm_regs[addr >> 2] ^ value;
    676        s->ulpd_pm_regs[addr >> 2] = value & 0x1f;
    677        omap_ulpd_req_update(s, diff, value);
    678        break;
    679
    680    case 0x3c:	/* DPLL_CTRL */
    681        /* XXX: OMAP310 TRM claims bit 3 is PLL_ENABLE, and bit 4 is
    682         * omitted altogether, probably a typo.  */
    683        /* This register has identical semantics with DPLL(1:3) control
    684         * registers, see omap_dpll_write() */
    685        diff = s->ulpd_pm_regs[addr >> 2] & value;
    686        s->ulpd_pm_regs[addr >> 2] = value & 0x2fff;
    687        if (diff & (0x3ff << 2)) {
    688            if (value & (1 << 4)) {			/* PLL_ENABLE */
    689                div = ((value >> 5) & 3) + 1;		/* PLL_DIV */
    690                mult = MIN((value >> 7) & 0x1f, 1);	/* PLL_MULT */
    691            } else {
    692                div = bypass_div[((value >> 2) & 3)];	/* BYPASS_DIV */
    693                mult = 1;
    694            }
    695            omap_clk_setrate(omap_findclk(s, "dpll4"), div, mult);
    696        }
    697
    698        /* Enter the desired mode.  */
    699        s->ulpd_pm_regs[addr >> 2] =
    700                (s->ulpd_pm_regs[addr >> 2] & 0xfffe) |
    701                ((s->ulpd_pm_regs[addr >> 2] >> 4) & 1);
    702
    703        /* Act as if the lock is restored.  */
    704        s->ulpd_pm_regs[addr >> 2] |= 2;
    705        break;
    706
    707    case 0x4c:	/* APLL_CTRL */
    708        diff = s->ulpd_pm_regs[addr >> 2] & value;
    709        s->ulpd_pm_regs[addr >> 2] = value & 0xf;
    710        if (diff & (1 << 0))				/* APLL_NDPLL_SWITCH */
    711            omap_clk_reparent(omap_findclk(s, "ck_48m"), omap_findclk(s,
    712                                    (value & (1 << 0)) ? "apll" : "dpll4"));
    713        break;
    714
    715    default:
    716        OMAP_BAD_REG(addr);
    717    }
    718}
    719
    720static const MemoryRegionOps omap_ulpd_pm_ops = {
    721    .read = omap_ulpd_pm_read,
    722    .write = omap_ulpd_pm_write,
    723    .endianness = DEVICE_NATIVE_ENDIAN,
    724};
    725
    726static void omap_ulpd_pm_reset(struct omap_mpu_state_s *mpu)
    727{
    728    mpu->ulpd_pm_regs[0x00 >> 2] = 0x0001;
    729    mpu->ulpd_pm_regs[0x04 >> 2] = 0x0000;
    730    mpu->ulpd_pm_regs[0x08 >> 2] = 0x0001;
    731    mpu->ulpd_pm_regs[0x0c >> 2] = 0x0000;
    732    mpu->ulpd_pm_regs[0x10 >> 2] = 0x0000;
    733    mpu->ulpd_pm_regs[0x18 >> 2] = 0x01;
    734    mpu->ulpd_pm_regs[0x1c >> 2] = 0x01;
    735    mpu->ulpd_pm_regs[0x20 >> 2] = 0x01;
    736    mpu->ulpd_pm_regs[0x24 >> 2] = 0x03ff;
    737    mpu->ulpd_pm_regs[0x28 >> 2] = 0x01;
    738    mpu->ulpd_pm_regs[0x2c >> 2] = 0x01;
    739    omap_ulpd_clk_update(mpu, mpu->ulpd_pm_regs[0x30 >> 2], 0x0000);
    740    mpu->ulpd_pm_regs[0x30 >> 2] = 0x0000;
    741    omap_ulpd_req_update(mpu, mpu->ulpd_pm_regs[0x34 >> 2], 0x0000);
    742    mpu->ulpd_pm_regs[0x34 >> 2] = 0x0000;
    743    mpu->ulpd_pm_regs[0x38 >> 2] = 0x0001;
    744    mpu->ulpd_pm_regs[0x3c >> 2] = 0x2211;
    745    mpu->ulpd_pm_regs[0x40 >> 2] = 0x0000; /* FIXME: dump a real STATUS_REQ */
    746    mpu->ulpd_pm_regs[0x48 >> 2] = 0x960;
    747    mpu->ulpd_pm_regs[0x4c >> 2] = 0x08;
    748    mpu->ulpd_pm_regs[0x50 >> 2] = 0x08;
    749    omap_clk_setrate(omap_findclk(mpu, "dpll4"), 1, 4);
    750    omap_clk_reparent(omap_findclk(mpu, "ck_48m"), omap_findclk(mpu, "dpll4"));
    751}
    752
    753static void omap_ulpd_pm_init(MemoryRegion *system_memory,
    754                hwaddr base,
    755                struct omap_mpu_state_s *mpu)
    756{
    757    memory_region_init_io(&mpu->ulpd_pm_iomem, NULL, &omap_ulpd_pm_ops, mpu,
    758                          "omap-ulpd-pm", 0x800);
    759    memory_region_add_subregion(system_memory, base, &mpu->ulpd_pm_iomem);
    760    omap_ulpd_pm_reset(mpu);
    761}
    762
    763/* OMAP Pin Configuration */
    764static uint64_t omap_pin_cfg_read(void *opaque, hwaddr addr,
    765                                  unsigned size)
    766{
    767    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
    768
    769    if (size != 4) {
    770        return omap_badwidth_read32(opaque, addr);
    771    }
    772
    773    switch (addr) {
    774    case 0x00:	/* FUNC_MUX_CTRL_0 */
    775    case 0x04:	/* FUNC_MUX_CTRL_1 */
    776    case 0x08:	/* FUNC_MUX_CTRL_2 */
    777        return s->func_mux_ctrl[addr >> 2];
    778
    779    case 0x0c:	/* COMP_MODE_CTRL_0 */
    780        return s->comp_mode_ctrl[0];
    781
    782    case 0x10:	/* FUNC_MUX_CTRL_3 */
    783    case 0x14:	/* FUNC_MUX_CTRL_4 */
    784    case 0x18:	/* FUNC_MUX_CTRL_5 */
    785    case 0x1c:	/* FUNC_MUX_CTRL_6 */
    786    case 0x20:	/* FUNC_MUX_CTRL_7 */
    787    case 0x24:	/* FUNC_MUX_CTRL_8 */
    788    case 0x28:	/* FUNC_MUX_CTRL_9 */
    789    case 0x2c:	/* FUNC_MUX_CTRL_A */
    790    case 0x30:	/* FUNC_MUX_CTRL_B */
    791    case 0x34:	/* FUNC_MUX_CTRL_C */
    792    case 0x38:	/* FUNC_MUX_CTRL_D */
    793        return s->func_mux_ctrl[(addr >> 2) - 1];
    794
    795    case 0x40:	/* PULL_DWN_CTRL_0 */
    796    case 0x44:	/* PULL_DWN_CTRL_1 */
    797    case 0x48:	/* PULL_DWN_CTRL_2 */
    798    case 0x4c:	/* PULL_DWN_CTRL_3 */
    799        return s->pull_dwn_ctrl[(addr & 0xf) >> 2];
    800
    801    case 0x50:	/* GATE_INH_CTRL_0 */
    802        return s->gate_inh_ctrl[0];
    803
    804    case 0x60:	/* VOLTAGE_CTRL_0 */
    805        return s->voltage_ctrl[0];
    806
    807    case 0x70:	/* TEST_DBG_CTRL_0 */
    808        return s->test_dbg_ctrl[0];
    809
    810    case 0x80:	/* MOD_CONF_CTRL_0 */
    811        return s->mod_conf_ctrl[0];
    812    }
    813
    814    OMAP_BAD_REG(addr);
    815    return 0;
    816}
    817
    818static inline void omap_pin_funcmux0_update(struct omap_mpu_state_s *s,
    819                uint32_t diff, uint32_t value)
    820{
    821    if (s->compat1509) {
    822        if (diff & (1 << 9))			/* BLUETOOTH */
    823            omap_clk_onoff(omap_findclk(s, "bt_mclk_out"),
    824                            (~value >> 9) & 1);
    825        if (diff & (1 << 7))			/* USB.CLKO */
    826            omap_clk_onoff(omap_findclk(s, "usb.clko"),
    827                            (value >> 7) & 1);
    828    }
    829}
    830
    831static inline void omap_pin_funcmux1_update(struct omap_mpu_state_s *s,
    832                uint32_t diff, uint32_t value)
    833{
    834    if (s->compat1509) {
    835        if (diff & (1U << 31)) {
    836            /* MCBSP3_CLK_HIZ_DI */
    837            omap_clk_onoff(omap_findclk(s, "mcbsp3.clkx"), (value >> 31) & 1);
    838        }
    839        if (diff & (1 << 1)) {
    840            /* CLK32K */
    841            omap_clk_onoff(omap_findclk(s, "clk32k_out"), (~value >> 1) & 1);
    842        }
    843    }
    844}
    845
    846static inline void omap_pin_modconf1_update(struct omap_mpu_state_s *s,
    847                uint32_t diff, uint32_t value)
    848{
    849    if (diff & (1U << 31)) {
    850        /* CONF_MOD_UART3_CLK_MODE_R */
    851        omap_clk_reparent(omap_findclk(s, "uart3_ck"),
    852                          omap_findclk(s, ((value >> 31) & 1) ?
    853                                       "ck_48m" : "armper_ck"));
    854    }
    855    if (diff & (1 << 30))			/* CONF_MOD_UART2_CLK_MODE_R */
    856         omap_clk_reparent(omap_findclk(s, "uart2_ck"),
    857                         omap_findclk(s, ((value >> 30) & 1) ?
    858                                 "ck_48m" : "armper_ck"));
    859    if (diff & (1 << 29))			/* CONF_MOD_UART1_CLK_MODE_R */
    860         omap_clk_reparent(omap_findclk(s, "uart1_ck"),
    861                         omap_findclk(s, ((value >> 29) & 1) ?
    862                                 "ck_48m" : "armper_ck"));
    863    if (diff & (1 << 23))			/* CONF_MOD_MMC_SD_CLK_REQ_R */
    864         omap_clk_reparent(omap_findclk(s, "mmc_ck"),
    865                         omap_findclk(s, ((value >> 23) & 1) ?
    866                                 "ck_48m" : "armper_ck"));
    867    if (diff & (1 << 12))			/* CONF_MOD_COM_MCLK_12_48_S */
    868         omap_clk_reparent(omap_findclk(s, "com_mclk_out"),
    869                         omap_findclk(s, ((value >> 12) & 1) ?
    870                                 "ck_48m" : "armper_ck"));
    871    if (diff & (1 << 9))			/* CONF_MOD_USB_HOST_HHC_UHO */
    872         omap_clk_onoff(omap_findclk(s, "usb_hhc_ck"), (value >> 9) & 1);
    873}
    874
    875static void omap_pin_cfg_write(void *opaque, hwaddr addr,
    876                               uint64_t value, unsigned size)
    877{
    878    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
    879    uint32_t diff;
    880
    881    if (size != 4) {
    882        omap_badwidth_write32(opaque, addr, value);
    883        return;
    884    }
    885
    886    switch (addr) {
    887    case 0x00:	/* FUNC_MUX_CTRL_0 */
    888        diff = s->func_mux_ctrl[addr >> 2] ^ value;
    889        s->func_mux_ctrl[addr >> 2] = value;
    890        omap_pin_funcmux0_update(s, diff, value);
    891        return;
    892
    893    case 0x04:	/* FUNC_MUX_CTRL_1 */
    894        diff = s->func_mux_ctrl[addr >> 2] ^ value;
    895        s->func_mux_ctrl[addr >> 2] = value;
    896        omap_pin_funcmux1_update(s, diff, value);
    897        return;
    898
    899    case 0x08:	/* FUNC_MUX_CTRL_2 */
    900        s->func_mux_ctrl[addr >> 2] = value;
    901        return;
    902
    903    case 0x0c:	/* COMP_MODE_CTRL_0 */
    904        s->comp_mode_ctrl[0] = value;
    905        s->compat1509 = (value != 0x0000eaef);
    906        omap_pin_funcmux0_update(s, ~0, s->func_mux_ctrl[0]);
    907        omap_pin_funcmux1_update(s, ~0, s->func_mux_ctrl[1]);
    908        return;
    909
    910    case 0x10:	/* FUNC_MUX_CTRL_3 */
    911    case 0x14:	/* FUNC_MUX_CTRL_4 */
    912    case 0x18:	/* FUNC_MUX_CTRL_5 */
    913    case 0x1c:	/* FUNC_MUX_CTRL_6 */
    914    case 0x20:	/* FUNC_MUX_CTRL_7 */
    915    case 0x24:	/* FUNC_MUX_CTRL_8 */
    916    case 0x28:	/* FUNC_MUX_CTRL_9 */
    917    case 0x2c:	/* FUNC_MUX_CTRL_A */
    918    case 0x30:	/* FUNC_MUX_CTRL_B */
    919    case 0x34:	/* FUNC_MUX_CTRL_C */
    920    case 0x38:	/* FUNC_MUX_CTRL_D */
    921        s->func_mux_ctrl[(addr >> 2) - 1] = value;
    922        return;
    923
    924    case 0x40:	/* PULL_DWN_CTRL_0 */
    925    case 0x44:	/* PULL_DWN_CTRL_1 */
    926    case 0x48:	/* PULL_DWN_CTRL_2 */
    927    case 0x4c:	/* PULL_DWN_CTRL_3 */
    928        s->pull_dwn_ctrl[(addr & 0xf) >> 2] = value;
    929        return;
    930
    931    case 0x50:	/* GATE_INH_CTRL_0 */
    932        s->gate_inh_ctrl[0] = value;
    933        return;
    934
    935    case 0x60:	/* VOLTAGE_CTRL_0 */
    936        s->voltage_ctrl[0] = value;
    937        return;
    938
    939    case 0x70:	/* TEST_DBG_CTRL_0 */
    940        s->test_dbg_ctrl[0] = value;
    941        return;
    942
    943    case 0x80:	/* MOD_CONF_CTRL_0 */
    944        diff = s->mod_conf_ctrl[0] ^ value;
    945        s->mod_conf_ctrl[0] = value;
    946        omap_pin_modconf1_update(s, diff, value);
    947        return;
    948
    949    default:
    950        OMAP_BAD_REG(addr);
    951    }
    952}
    953
    954static const MemoryRegionOps omap_pin_cfg_ops = {
    955    .read = omap_pin_cfg_read,
    956    .write = omap_pin_cfg_write,
    957    .endianness = DEVICE_NATIVE_ENDIAN,
    958};
    959
    960static void omap_pin_cfg_reset(struct omap_mpu_state_s *mpu)
    961{
    962    /* Start in Compatibility Mode.  */
    963    mpu->compat1509 = 1;
    964    omap_pin_funcmux0_update(mpu, mpu->func_mux_ctrl[0], 0);
    965    omap_pin_funcmux1_update(mpu, mpu->func_mux_ctrl[1], 0);
    966    omap_pin_modconf1_update(mpu, mpu->mod_conf_ctrl[0], 0);
    967    memset(mpu->func_mux_ctrl, 0, sizeof(mpu->func_mux_ctrl));
    968    memset(mpu->comp_mode_ctrl, 0, sizeof(mpu->comp_mode_ctrl));
    969    memset(mpu->pull_dwn_ctrl, 0, sizeof(mpu->pull_dwn_ctrl));
    970    memset(mpu->gate_inh_ctrl, 0, sizeof(mpu->gate_inh_ctrl));
    971    memset(mpu->voltage_ctrl, 0, sizeof(mpu->voltage_ctrl));
    972    memset(mpu->test_dbg_ctrl, 0, sizeof(mpu->test_dbg_ctrl));
    973    memset(mpu->mod_conf_ctrl, 0, sizeof(mpu->mod_conf_ctrl));
    974}
    975
    976static void omap_pin_cfg_init(MemoryRegion *system_memory,
    977                hwaddr base,
    978                struct omap_mpu_state_s *mpu)
    979{
    980    memory_region_init_io(&mpu->pin_cfg_iomem, NULL, &omap_pin_cfg_ops, mpu,
    981                          "omap-pin-cfg", 0x800);
    982    memory_region_add_subregion(system_memory, base, &mpu->pin_cfg_iomem);
    983    omap_pin_cfg_reset(mpu);
    984}
    985
    986/* Device Identification, Die Identification */
    987static uint64_t omap_id_read(void *opaque, hwaddr addr,
    988                             unsigned size)
    989{
    990    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
    991
    992    if (size != 4) {
    993        return omap_badwidth_read32(opaque, addr);
    994    }
    995
    996    switch (addr) {
    997    case 0xfffe1800:	/* DIE_ID_LSB */
    998        return 0xc9581f0e;
    999    case 0xfffe1804:	/* DIE_ID_MSB */
   1000        return 0xa8858bfa;
   1001
   1002    case 0xfffe2000:	/* PRODUCT_ID_LSB */
   1003        return 0x00aaaafc;
   1004    case 0xfffe2004:	/* PRODUCT_ID_MSB */
   1005        return 0xcafeb574;
   1006
   1007    case 0xfffed400:	/* JTAG_ID_LSB */
   1008        switch (s->mpu_model) {
   1009        case omap310:
   1010            return 0x03310315;
   1011        case omap1510:
   1012            return 0x03310115;
   1013        default:
   1014            hw_error("%s: bad mpu model\n", __func__);
   1015        }
   1016        break;
   1017
   1018    case 0xfffed404:	/* JTAG_ID_MSB */
   1019        switch (s->mpu_model) {
   1020        case omap310:
   1021            return 0xfb57402f;
   1022        case omap1510:
   1023            return 0xfb47002f;
   1024        default:
   1025            hw_error("%s: bad mpu model\n", __func__);
   1026        }
   1027        break;
   1028    }
   1029
   1030    OMAP_BAD_REG(addr);
   1031    return 0;
   1032}
   1033
   1034static void omap_id_write(void *opaque, hwaddr addr,
   1035                          uint64_t value, unsigned size)
   1036{
   1037    if (size != 4) {
   1038        omap_badwidth_write32(opaque, addr, value);
   1039        return;
   1040    }
   1041
   1042    OMAP_BAD_REG(addr);
   1043}
   1044
   1045static const MemoryRegionOps omap_id_ops = {
   1046    .read = omap_id_read,
   1047    .write = omap_id_write,
   1048    .endianness = DEVICE_NATIVE_ENDIAN,
   1049};
   1050
   1051static void omap_id_init(MemoryRegion *memory, struct omap_mpu_state_s *mpu)
   1052{
   1053    memory_region_init_io(&mpu->id_iomem, NULL, &omap_id_ops, mpu,
   1054                          "omap-id", 0x100000000ULL);
   1055    memory_region_init_alias(&mpu->id_iomem_e18, NULL, "omap-id-e18", &mpu->id_iomem,
   1056                             0xfffe1800, 0x800);
   1057    memory_region_add_subregion(memory, 0xfffe1800, &mpu->id_iomem_e18);
   1058    memory_region_init_alias(&mpu->id_iomem_ed4, NULL, "omap-id-ed4", &mpu->id_iomem,
   1059                             0xfffed400, 0x100);
   1060    memory_region_add_subregion(memory, 0xfffed400, &mpu->id_iomem_ed4);
   1061    if (!cpu_is_omap15xx(mpu)) {
   1062        memory_region_init_alias(&mpu->id_iomem_ed4, NULL, "omap-id-e20",
   1063                                 &mpu->id_iomem, 0xfffe2000, 0x800);
   1064        memory_region_add_subregion(memory, 0xfffe2000, &mpu->id_iomem_e20);
   1065    }
   1066}
   1067
   1068/* MPUI Control (Dummy) */
   1069static uint64_t omap_mpui_read(void *opaque, hwaddr addr,
   1070                               unsigned size)
   1071{
   1072    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
   1073
   1074    if (size != 4) {
   1075        return omap_badwidth_read32(opaque, addr);
   1076    }
   1077
   1078    switch (addr) {
   1079    case 0x00:	/* CTRL */
   1080        return s->mpui_ctrl;
   1081    case 0x04:	/* DEBUG_ADDR */
   1082        return 0x01ffffff;
   1083    case 0x08:	/* DEBUG_DATA */
   1084        return 0xffffffff;
   1085    case 0x0c:	/* DEBUG_FLAG */
   1086        return 0x00000800;
   1087    case 0x10:	/* STATUS */
   1088        return 0x00000000;
   1089
   1090    /* Not in OMAP310 */
   1091    case 0x14:	/* DSP_STATUS */
   1092    case 0x18:	/* DSP_BOOT_CONFIG */
   1093        return 0x00000000;
   1094    case 0x1c:	/* DSP_MPUI_CONFIG */
   1095        return 0x0000ffff;
   1096    }
   1097
   1098    OMAP_BAD_REG(addr);
   1099    return 0;
   1100}
   1101
   1102static void omap_mpui_write(void *opaque, hwaddr addr,
   1103                            uint64_t value, unsigned size)
   1104{
   1105    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
   1106
   1107    if (size != 4) {
   1108        omap_badwidth_write32(opaque, addr, value);
   1109        return;
   1110    }
   1111
   1112    switch (addr) {
   1113    case 0x00:	/* CTRL */
   1114        s->mpui_ctrl = value & 0x007fffff;
   1115        break;
   1116
   1117    case 0x04:	/* DEBUG_ADDR */
   1118    case 0x08:	/* DEBUG_DATA */
   1119    case 0x0c:	/* DEBUG_FLAG */
   1120    case 0x10:	/* STATUS */
   1121    /* Not in OMAP310 */
   1122    case 0x14:	/* DSP_STATUS */
   1123        OMAP_RO_REG(addr);
   1124        break;
   1125    case 0x18:	/* DSP_BOOT_CONFIG */
   1126    case 0x1c:	/* DSP_MPUI_CONFIG */
   1127        break;
   1128
   1129    default:
   1130        OMAP_BAD_REG(addr);
   1131    }
   1132}
   1133
   1134static const MemoryRegionOps omap_mpui_ops = {
   1135    .read = omap_mpui_read,
   1136    .write = omap_mpui_write,
   1137    .endianness = DEVICE_NATIVE_ENDIAN,
   1138};
   1139
   1140static void omap_mpui_reset(struct omap_mpu_state_s *s)
   1141{
   1142    s->mpui_ctrl = 0x0003ff1b;
   1143}
   1144
   1145static void omap_mpui_init(MemoryRegion *memory, hwaddr base,
   1146                struct omap_mpu_state_s *mpu)
   1147{
   1148    memory_region_init_io(&mpu->mpui_iomem, NULL, &omap_mpui_ops, mpu,
   1149                          "omap-mpui", 0x100);
   1150    memory_region_add_subregion(memory, base, &mpu->mpui_iomem);
   1151
   1152    omap_mpui_reset(mpu);
   1153}
   1154
   1155/* TIPB Bridges */
   1156struct omap_tipb_bridge_s {
   1157    qemu_irq abort;
   1158    MemoryRegion iomem;
   1159
   1160    int width_intr;
   1161    uint16_t control;
   1162    uint16_t alloc;
   1163    uint16_t buffer;
   1164    uint16_t enh_control;
   1165};
   1166
   1167static uint64_t omap_tipb_bridge_read(void *opaque, hwaddr addr,
   1168                                      unsigned size)
   1169{
   1170    struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
   1171
   1172    if (size < 2) {
   1173        return omap_badwidth_read16(opaque, addr);
   1174    }
   1175
   1176    switch (addr) {
   1177    case 0x00:	/* TIPB_CNTL */
   1178        return s->control;
   1179    case 0x04:	/* TIPB_BUS_ALLOC */
   1180        return s->alloc;
   1181    case 0x08:	/* MPU_TIPB_CNTL */
   1182        return s->buffer;
   1183    case 0x0c:	/* ENHANCED_TIPB_CNTL */
   1184        return s->enh_control;
   1185    case 0x10:	/* ADDRESS_DBG */
   1186    case 0x14:	/* DATA_DEBUG_LOW */
   1187    case 0x18:	/* DATA_DEBUG_HIGH */
   1188        return 0xffff;
   1189    case 0x1c:	/* DEBUG_CNTR_SIG */
   1190        return 0x00f8;
   1191    }
   1192
   1193    OMAP_BAD_REG(addr);
   1194    return 0;
   1195}
   1196
   1197static void omap_tipb_bridge_write(void *opaque, hwaddr addr,
   1198                                   uint64_t value, unsigned size)
   1199{
   1200    struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
   1201
   1202    if (size < 2) {
   1203        omap_badwidth_write16(opaque, addr, value);
   1204        return;
   1205    }
   1206
   1207    switch (addr) {
   1208    case 0x00:	/* TIPB_CNTL */
   1209        s->control = value & 0xffff;
   1210        break;
   1211
   1212    case 0x04:	/* TIPB_BUS_ALLOC */
   1213        s->alloc = value & 0x003f;
   1214        break;
   1215
   1216    case 0x08:	/* MPU_TIPB_CNTL */
   1217        s->buffer = value & 0x0003;
   1218        break;
   1219
   1220    case 0x0c:	/* ENHANCED_TIPB_CNTL */
   1221        s->width_intr = !(value & 2);
   1222        s->enh_control = value & 0x000f;
   1223        break;
   1224
   1225    case 0x10:	/* ADDRESS_DBG */
   1226    case 0x14:	/* DATA_DEBUG_LOW */
   1227    case 0x18:	/* DATA_DEBUG_HIGH */
   1228    case 0x1c:	/* DEBUG_CNTR_SIG */
   1229        OMAP_RO_REG(addr);
   1230        break;
   1231
   1232    default:
   1233        OMAP_BAD_REG(addr);
   1234    }
   1235}
   1236
   1237static const MemoryRegionOps omap_tipb_bridge_ops = {
   1238    .read = omap_tipb_bridge_read,
   1239    .write = omap_tipb_bridge_write,
   1240    .endianness = DEVICE_NATIVE_ENDIAN,
   1241};
   1242
   1243static void omap_tipb_bridge_reset(struct omap_tipb_bridge_s *s)
   1244{
   1245    s->control = 0xffff;
   1246    s->alloc = 0x0009;
   1247    s->buffer = 0x0000;
   1248    s->enh_control = 0x000f;
   1249}
   1250
   1251static struct omap_tipb_bridge_s *omap_tipb_bridge_init(
   1252    MemoryRegion *memory, hwaddr base,
   1253    qemu_irq abort_irq, omap_clk clk)
   1254{
   1255    struct omap_tipb_bridge_s *s = g_new0(struct omap_tipb_bridge_s, 1);
   1256
   1257    s->abort = abort_irq;
   1258    omap_tipb_bridge_reset(s);
   1259
   1260    memory_region_init_io(&s->iomem, NULL, &omap_tipb_bridge_ops, s,
   1261                          "omap-tipb-bridge", 0x100);
   1262    memory_region_add_subregion(memory, base, &s->iomem);
   1263
   1264    return s;
   1265}
   1266
   1267/* Dummy Traffic Controller's Memory Interface */
   1268static uint64_t omap_tcmi_read(void *opaque, hwaddr addr,
   1269                               unsigned size)
   1270{
   1271    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
   1272    uint32_t ret;
   1273
   1274    if (size != 4) {
   1275        return omap_badwidth_read32(opaque, addr);
   1276    }
   1277
   1278    switch (addr) {
   1279    case 0x00:	/* IMIF_PRIO */
   1280    case 0x04:	/* EMIFS_PRIO */
   1281    case 0x08:	/* EMIFF_PRIO */
   1282    case 0x0c:	/* EMIFS_CONFIG */
   1283    case 0x10:	/* EMIFS_CS0_CONFIG */
   1284    case 0x14:	/* EMIFS_CS1_CONFIG */
   1285    case 0x18:	/* EMIFS_CS2_CONFIG */
   1286    case 0x1c:	/* EMIFS_CS3_CONFIG */
   1287    case 0x24:	/* EMIFF_MRS */
   1288    case 0x28:	/* TIMEOUT1 */
   1289    case 0x2c:	/* TIMEOUT2 */
   1290    case 0x30:	/* TIMEOUT3 */
   1291    case 0x3c:	/* EMIFF_SDRAM_CONFIG_2 */
   1292    case 0x40:	/* EMIFS_CFG_DYN_WAIT */
   1293        return s->tcmi_regs[addr >> 2];
   1294
   1295    case 0x20:	/* EMIFF_SDRAM_CONFIG */
   1296        ret = s->tcmi_regs[addr >> 2];
   1297        s->tcmi_regs[addr >> 2] &= ~1; /* XXX: Clear SLRF on SDRAM access */
   1298        /* XXX: We can try using the VGA_DIRTY flag for this */
   1299        return ret;
   1300    }
   1301
   1302    OMAP_BAD_REG(addr);
   1303    return 0;
   1304}
   1305
   1306static void omap_tcmi_write(void *opaque, hwaddr addr,
   1307                            uint64_t value, unsigned size)
   1308{
   1309    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
   1310
   1311    if (size != 4) {
   1312        omap_badwidth_write32(opaque, addr, value);
   1313        return;
   1314    }
   1315
   1316    switch (addr) {
   1317    case 0x00:	/* IMIF_PRIO */
   1318    case 0x04:	/* EMIFS_PRIO */
   1319    case 0x08:	/* EMIFF_PRIO */
   1320    case 0x10:	/* EMIFS_CS0_CONFIG */
   1321    case 0x14:	/* EMIFS_CS1_CONFIG */
   1322    case 0x18:	/* EMIFS_CS2_CONFIG */
   1323    case 0x1c:	/* EMIFS_CS3_CONFIG */
   1324    case 0x20:	/* EMIFF_SDRAM_CONFIG */
   1325    case 0x24:	/* EMIFF_MRS */
   1326    case 0x28:	/* TIMEOUT1 */
   1327    case 0x2c:	/* TIMEOUT2 */
   1328    case 0x30:	/* TIMEOUT3 */
   1329    case 0x3c:	/* EMIFF_SDRAM_CONFIG_2 */
   1330    case 0x40:	/* EMIFS_CFG_DYN_WAIT */
   1331        s->tcmi_regs[addr >> 2] = value;
   1332        break;
   1333    case 0x0c:	/* EMIFS_CONFIG */
   1334        s->tcmi_regs[addr >> 2] = (value & 0xf) | (1 << 4);
   1335        break;
   1336
   1337    default:
   1338        OMAP_BAD_REG(addr);
   1339    }
   1340}
   1341
   1342static const MemoryRegionOps omap_tcmi_ops = {
   1343    .read = omap_tcmi_read,
   1344    .write = omap_tcmi_write,
   1345    .endianness = DEVICE_NATIVE_ENDIAN,
   1346};
   1347
   1348static void omap_tcmi_reset(struct omap_mpu_state_s *mpu)
   1349{
   1350    mpu->tcmi_regs[0x00 >> 2] = 0x00000000;
   1351    mpu->tcmi_regs[0x04 >> 2] = 0x00000000;
   1352    mpu->tcmi_regs[0x08 >> 2] = 0x00000000;
   1353    mpu->tcmi_regs[0x0c >> 2] = 0x00000010;
   1354    mpu->tcmi_regs[0x10 >> 2] = 0x0010fffb;
   1355    mpu->tcmi_regs[0x14 >> 2] = 0x0010fffb;
   1356    mpu->tcmi_regs[0x18 >> 2] = 0x0010fffb;
   1357    mpu->tcmi_regs[0x1c >> 2] = 0x0010fffb;
   1358    mpu->tcmi_regs[0x20 >> 2] = 0x00618800;
   1359    mpu->tcmi_regs[0x24 >> 2] = 0x00000037;
   1360    mpu->tcmi_regs[0x28 >> 2] = 0x00000000;
   1361    mpu->tcmi_regs[0x2c >> 2] = 0x00000000;
   1362    mpu->tcmi_regs[0x30 >> 2] = 0x00000000;
   1363    mpu->tcmi_regs[0x3c >> 2] = 0x00000003;
   1364    mpu->tcmi_regs[0x40 >> 2] = 0x00000000;
   1365}
   1366
   1367static void omap_tcmi_init(MemoryRegion *memory, hwaddr base,
   1368                struct omap_mpu_state_s *mpu)
   1369{
   1370    memory_region_init_io(&mpu->tcmi_iomem, NULL, &omap_tcmi_ops, mpu,
   1371                          "omap-tcmi", 0x100);
   1372    memory_region_add_subregion(memory, base, &mpu->tcmi_iomem);
   1373    omap_tcmi_reset(mpu);
   1374}
   1375
   1376/* Digital phase-locked loops control */
   1377struct dpll_ctl_s {
   1378    MemoryRegion iomem;
   1379    uint16_t mode;
   1380    omap_clk dpll;
   1381};
   1382
   1383static uint64_t omap_dpll_read(void *opaque, hwaddr addr,
   1384                               unsigned size)
   1385{
   1386    struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
   1387
   1388    if (size != 2) {
   1389        return omap_badwidth_read16(opaque, addr);
   1390    }
   1391
   1392    if (addr == 0x00)	/* CTL_REG */
   1393        return s->mode;
   1394
   1395    OMAP_BAD_REG(addr);
   1396    return 0;
   1397}
   1398
   1399static void omap_dpll_write(void *opaque, hwaddr addr,
   1400                            uint64_t value, unsigned size)
   1401{
   1402    struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
   1403    uint16_t diff;
   1404    static const int bypass_div[4] = { 1, 2, 4, 4 };
   1405    int div, mult;
   1406
   1407    if (size != 2) {
   1408        omap_badwidth_write16(opaque, addr, value);
   1409        return;
   1410    }
   1411
   1412    if (addr == 0x00) {	/* CTL_REG */
   1413        /* See omap_ulpd_pm_write() too */
   1414        diff = s->mode & value;
   1415        s->mode = value & 0x2fff;
   1416        if (diff & (0x3ff << 2)) {
   1417            if (value & (1 << 4)) {			/* PLL_ENABLE */
   1418                div = ((value >> 5) & 3) + 1;		/* PLL_DIV */
   1419                mult = MIN((value >> 7) & 0x1f, 1);	/* PLL_MULT */
   1420            } else {
   1421                div = bypass_div[((value >> 2) & 3)];	/* BYPASS_DIV */
   1422                mult = 1;
   1423            }
   1424            omap_clk_setrate(s->dpll, div, mult);
   1425        }
   1426
   1427        /* Enter the desired mode.  */
   1428        s->mode = (s->mode & 0xfffe) | ((s->mode >> 4) & 1);
   1429
   1430        /* Act as if the lock is restored.  */
   1431        s->mode |= 2;
   1432    } else {
   1433        OMAP_BAD_REG(addr);
   1434    }
   1435}
   1436
   1437static const MemoryRegionOps omap_dpll_ops = {
   1438    .read = omap_dpll_read,
   1439    .write = omap_dpll_write,
   1440    .endianness = DEVICE_NATIVE_ENDIAN,
   1441};
   1442
   1443static void omap_dpll_reset(struct dpll_ctl_s *s)
   1444{
   1445    s->mode = 0x2002;
   1446    omap_clk_setrate(s->dpll, 1, 1);
   1447}
   1448
   1449static struct dpll_ctl_s  *omap_dpll_init(MemoryRegion *memory,
   1450                           hwaddr base, omap_clk clk)
   1451{
   1452    struct dpll_ctl_s *s = g_malloc0(sizeof(*s));
   1453    memory_region_init_io(&s->iomem, NULL, &omap_dpll_ops, s, "omap-dpll", 0x100);
   1454
   1455    s->dpll = clk;
   1456    omap_dpll_reset(s);
   1457
   1458    memory_region_add_subregion(memory, base, &s->iomem);
   1459    return s;
   1460}
   1461
   1462/* MPU Clock/Reset/Power Mode Control */
   1463static uint64_t omap_clkm_read(void *opaque, hwaddr addr,
   1464                               unsigned size)
   1465{
   1466    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
   1467
   1468    if (size != 2) {
   1469        return omap_badwidth_read16(opaque, addr);
   1470    }
   1471
   1472    switch (addr) {
   1473    case 0x00:	/* ARM_CKCTL */
   1474        return s->clkm.arm_ckctl;
   1475
   1476    case 0x04:	/* ARM_IDLECT1 */
   1477        return s->clkm.arm_idlect1;
   1478
   1479    case 0x08:	/* ARM_IDLECT2 */
   1480        return s->clkm.arm_idlect2;
   1481
   1482    case 0x0c:	/* ARM_EWUPCT */
   1483        return s->clkm.arm_ewupct;
   1484
   1485    case 0x10:	/* ARM_RSTCT1 */
   1486        return s->clkm.arm_rstct1;
   1487
   1488    case 0x14:	/* ARM_RSTCT2 */
   1489        return s->clkm.arm_rstct2;
   1490
   1491    case 0x18:	/* ARM_SYSST */
   1492        return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start;
   1493
   1494    case 0x1c:	/* ARM_CKOUT1 */
   1495        return s->clkm.arm_ckout1;
   1496
   1497    case 0x20:	/* ARM_CKOUT2 */
   1498        break;
   1499    }
   1500
   1501    OMAP_BAD_REG(addr);
   1502    return 0;
   1503}
   1504
   1505static inline void omap_clkm_ckctl_update(struct omap_mpu_state_s *s,
   1506                uint16_t diff, uint16_t value)
   1507{
   1508    omap_clk clk;
   1509
   1510    if (diff & (1 << 14)) {				/* ARM_INTHCK_SEL */
   1511        if (value & (1 << 14))
   1512            /* Reserved */;
   1513        else {
   1514            clk = omap_findclk(s, "arminth_ck");
   1515            omap_clk_reparent(clk, omap_findclk(s, "tc_ck"));
   1516        }
   1517    }
   1518    if (diff & (1 << 12)) {				/* ARM_TIMXO */
   1519        clk = omap_findclk(s, "armtim_ck");
   1520        if (value & (1 << 12))
   1521            omap_clk_reparent(clk, omap_findclk(s, "clkin"));
   1522        else
   1523            omap_clk_reparent(clk, omap_findclk(s, "ck_gen1"));
   1524    }
   1525    /* XXX: en_dspck */
   1526    if (diff & (3 << 10)) {				/* DSPMMUDIV */
   1527        clk = omap_findclk(s, "dspmmu_ck");
   1528        omap_clk_setrate(clk, 1 << ((value >> 10) & 3), 1);
   1529    }
   1530    if (diff & (3 << 8)) {				/* TCDIV */
   1531        clk = omap_findclk(s, "tc_ck");
   1532        omap_clk_setrate(clk, 1 << ((value >> 8) & 3), 1);
   1533    }
   1534    if (diff & (3 << 6)) {				/* DSPDIV */
   1535        clk = omap_findclk(s, "dsp_ck");
   1536        omap_clk_setrate(clk, 1 << ((value >> 6) & 3), 1);
   1537    }
   1538    if (diff & (3 << 4)) {				/* ARMDIV */
   1539        clk = omap_findclk(s, "arm_ck");
   1540        omap_clk_setrate(clk, 1 << ((value >> 4) & 3), 1);
   1541    }
   1542    if (diff & (3 << 2)) {				/* LCDDIV */
   1543        clk = omap_findclk(s, "lcd_ck");
   1544        omap_clk_setrate(clk, 1 << ((value >> 2) & 3), 1);
   1545    }
   1546    if (diff & (3 << 0)) {				/* PERDIV */
   1547        clk = omap_findclk(s, "armper_ck");
   1548        omap_clk_setrate(clk, 1 << ((value >> 0) & 3), 1);
   1549    }
   1550}
   1551
   1552static inline void omap_clkm_idlect1_update(struct omap_mpu_state_s *s,
   1553                uint16_t diff, uint16_t value)
   1554{
   1555    omap_clk clk;
   1556
   1557    if (value & (1 << 11)) {                            /* SETARM_IDLE */
   1558        cpu_interrupt(CPU(s->cpu), CPU_INTERRUPT_HALT);
   1559    }
   1560    if (!(value & (1 << 10))) {                         /* WKUP_MODE */
   1561        /* XXX: disable wakeup from IRQ */
   1562        qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
   1563    }
   1564
   1565#define SET_CANIDLE(clock, bit)				\
   1566    if (diff & (1 << bit)) {				\
   1567        clk = omap_findclk(s, clock);			\
   1568        omap_clk_canidle(clk, (value >> bit) & 1);	\
   1569    }
   1570    SET_CANIDLE("mpuwd_ck", 0)				/* IDLWDT_ARM */
   1571    SET_CANIDLE("armxor_ck", 1)				/* IDLXORP_ARM */
   1572    SET_CANIDLE("mpuper_ck", 2)				/* IDLPER_ARM */
   1573    SET_CANIDLE("lcd_ck", 3)				/* IDLLCD_ARM */
   1574    SET_CANIDLE("lb_ck", 4)				/* IDLLB_ARM */
   1575    SET_CANIDLE("hsab_ck", 5)				/* IDLHSAB_ARM */
   1576    SET_CANIDLE("tipb_ck", 6)				/* IDLIF_ARM */
   1577    SET_CANIDLE("dma_ck", 6)				/* IDLIF_ARM */
   1578    SET_CANIDLE("tc_ck", 6)				/* IDLIF_ARM */
   1579    SET_CANIDLE("dpll1", 7)				/* IDLDPLL_ARM */
   1580    SET_CANIDLE("dpll2", 7)				/* IDLDPLL_ARM */
   1581    SET_CANIDLE("dpll3", 7)				/* IDLDPLL_ARM */
   1582    SET_CANIDLE("mpui_ck", 8)				/* IDLAPI_ARM */
   1583    SET_CANIDLE("armtim_ck", 9)				/* IDLTIM_ARM */
   1584}
   1585
   1586static inline void omap_clkm_idlect2_update(struct omap_mpu_state_s *s,
   1587                uint16_t diff, uint16_t value)
   1588{
   1589    omap_clk clk;
   1590
   1591#define SET_ONOFF(clock, bit)				\
   1592    if (diff & (1 << bit)) {				\
   1593        clk = omap_findclk(s, clock);			\
   1594        omap_clk_onoff(clk, (value >> bit) & 1);	\
   1595    }
   1596    SET_ONOFF("mpuwd_ck", 0)				/* EN_WDTCK */
   1597    SET_ONOFF("armxor_ck", 1)				/* EN_XORPCK */
   1598    SET_ONOFF("mpuper_ck", 2)				/* EN_PERCK */
   1599    SET_ONOFF("lcd_ck", 3)				/* EN_LCDCK */
   1600    SET_ONOFF("lb_ck", 4)				/* EN_LBCK */
   1601    SET_ONOFF("hsab_ck", 5)				/* EN_HSABCK */
   1602    SET_ONOFF("mpui_ck", 6)				/* EN_APICK */
   1603    SET_ONOFF("armtim_ck", 7)				/* EN_TIMCK */
   1604    SET_CANIDLE("dma_ck", 8)				/* DMACK_REQ */
   1605    SET_ONOFF("arm_gpio_ck", 9)				/* EN_GPIOCK */
   1606    SET_ONOFF("lbfree_ck", 10)				/* EN_LBFREECK */
   1607}
   1608
   1609static inline void omap_clkm_ckout1_update(struct omap_mpu_state_s *s,
   1610                uint16_t diff, uint16_t value)
   1611{
   1612    omap_clk clk;
   1613
   1614    if (diff & (3 << 4)) {				/* TCLKOUT */
   1615        clk = omap_findclk(s, "tclk_out");
   1616        switch ((value >> 4) & 3) {
   1617        case 1:
   1618            omap_clk_reparent(clk, omap_findclk(s, "ck_gen3"));
   1619            omap_clk_onoff(clk, 1);
   1620            break;
   1621        case 2:
   1622            omap_clk_reparent(clk, omap_findclk(s, "tc_ck"));
   1623            omap_clk_onoff(clk, 1);
   1624            break;
   1625        default:
   1626            omap_clk_onoff(clk, 0);
   1627        }
   1628    }
   1629    if (diff & (3 << 2)) {				/* DCLKOUT */
   1630        clk = omap_findclk(s, "dclk_out");
   1631        switch ((value >> 2) & 3) {
   1632        case 0:
   1633            omap_clk_reparent(clk, omap_findclk(s, "dspmmu_ck"));
   1634            break;
   1635        case 1:
   1636            omap_clk_reparent(clk, omap_findclk(s, "ck_gen2"));
   1637            break;
   1638        case 2:
   1639            omap_clk_reparent(clk, omap_findclk(s, "dsp_ck"));
   1640            break;
   1641        case 3:
   1642            omap_clk_reparent(clk, omap_findclk(s, "ck_ref14"));
   1643            break;
   1644        }
   1645    }
   1646    if (diff & (3 << 0)) {				/* ACLKOUT */
   1647        clk = omap_findclk(s, "aclk_out");
   1648        switch ((value >> 0) & 3) {
   1649        case 1:
   1650            omap_clk_reparent(clk, omap_findclk(s, "ck_gen1"));
   1651            omap_clk_onoff(clk, 1);
   1652            break;
   1653        case 2:
   1654            omap_clk_reparent(clk, omap_findclk(s, "arm_ck"));
   1655            omap_clk_onoff(clk, 1);
   1656            break;
   1657        case 3:
   1658            omap_clk_reparent(clk, omap_findclk(s, "ck_ref14"));
   1659            omap_clk_onoff(clk, 1);
   1660            break;
   1661        default:
   1662            omap_clk_onoff(clk, 0);
   1663        }
   1664    }
   1665}
   1666
   1667static void omap_clkm_write(void *opaque, hwaddr addr,
   1668                            uint64_t value, unsigned size)
   1669{
   1670    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
   1671    uint16_t diff;
   1672    omap_clk clk;
   1673    static const char *clkschemename[8] = {
   1674        "fully synchronous", "fully asynchronous", "synchronous scalable",
   1675        "mix mode 1", "mix mode 2", "bypass mode", "mix mode 3", "mix mode 4",
   1676    };
   1677
   1678    if (size != 2) {
   1679        omap_badwidth_write16(opaque, addr, value);
   1680        return;
   1681    }
   1682
   1683    switch (addr) {
   1684    case 0x00:	/* ARM_CKCTL */
   1685        diff = s->clkm.arm_ckctl ^ value;
   1686        s->clkm.arm_ckctl = value & 0x7fff;
   1687        omap_clkm_ckctl_update(s, diff, value);
   1688        return;
   1689
   1690    case 0x04:	/* ARM_IDLECT1 */
   1691        diff = s->clkm.arm_idlect1 ^ value;
   1692        s->clkm.arm_idlect1 = value & 0x0fff;
   1693        omap_clkm_idlect1_update(s, diff, value);
   1694        return;
   1695
   1696    case 0x08:	/* ARM_IDLECT2 */
   1697        diff = s->clkm.arm_idlect2 ^ value;
   1698        s->clkm.arm_idlect2 = value & 0x07ff;
   1699        omap_clkm_idlect2_update(s, diff, value);
   1700        return;
   1701
   1702    case 0x0c:	/* ARM_EWUPCT */
   1703        s->clkm.arm_ewupct = value & 0x003f;
   1704        return;
   1705
   1706    case 0x10:	/* ARM_RSTCT1 */
   1707        diff = s->clkm.arm_rstct1 ^ value;
   1708        s->clkm.arm_rstct1 = value & 0x0007;
   1709        if (value & 9) {
   1710            qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
   1711            s->clkm.cold_start = 0xa;
   1712        }
   1713        if (diff & ~value & 4) {				/* DSP_RST */
   1714            omap_mpui_reset(s);
   1715            omap_tipb_bridge_reset(s->private_tipb);
   1716            omap_tipb_bridge_reset(s->public_tipb);
   1717        }
   1718        if (diff & 2) {						/* DSP_EN */
   1719            clk = omap_findclk(s, "dsp_ck");
   1720            omap_clk_canidle(clk, (~value >> 1) & 1);
   1721        }
   1722        return;
   1723
   1724    case 0x14:	/* ARM_RSTCT2 */
   1725        s->clkm.arm_rstct2 = value & 0x0001;
   1726        return;
   1727
   1728    case 0x18:	/* ARM_SYSST */
   1729        if ((s->clkm.clocking_scheme ^ (value >> 11)) & 7) {
   1730            s->clkm.clocking_scheme = (value >> 11) & 7;
   1731            printf("%s: clocking scheme set to %s\n", __func__,
   1732                   clkschemename[s->clkm.clocking_scheme]);
   1733        }
   1734        s->clkm.cold_start &= value & 0x3f;
   1735        return;
   1736
   1737    case 0x1c:	/* ARM_CKOUT1 */
   1738        diff = s->clkm.arm_ckout1 ^ value;
   1739        s->clkm.arm_ckout1 = value & 0x003f;
   1740        omap_clkm_ckout1_update(s, diff, value);
   1741        return;
   1742
   1743    case 0x20:	/* ARM_CKOUT2 */
   1744    default:
   1745        OMAP_BAD_REG(addr);
   1746    }
   1747}
   1748
   1749static const MemoryRegionOps omap_clkm_ops = {
   1750    .read = omap_clkm_read,
   1751    .write = omap_clkm_write,
   1752    .endianness = DEVICE_NATIVE_ENDIAN,
   1753};
   1754
   1755static uint64_t omap_clkdsp_read(void *opaque, hwaddr addr,
   1756                                 unsigned size)
   1757{
   1758    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
   1759    CPUState *cpu = CPU(s->cpu);
   1760
   1761    if (size != 2) {
   1762        return omap_badwidth_read16(opaque, addr);
   1763    }
   1764
   1765    switch (addr) {
   1766    case 0x04:	/* DSP_IDLECT1 */
   1767        return s->clkm.dsp_idlect1;
   1768
   1769    case 0x08:	/* DSP_IDLECT2 */
   1770        return s->clkm.dsp_idlect2;
   1771
   1772    case 0x14:	/* DSP_RSTCT2 */
   1773        return s->clkm.dsp_rstct2;
   1774
   1775    case 0x18:	/* DSP_SYSST */
   1776        return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start |
   1777                (cpu->halted << 6);      /* Quite useless... */
   1778    }
   1779
   1780    OMAP_BAD_REG(addr);
   1781    return 0;
   1782}
   1783
   1784static inline void omap_clkdsp_idlect1_update(struct omap_mpu_state_s *s,
   1785                uint16_t diff, uint16_t value)
   1786{
   1787    omap_clk clk;
   1788
   1789    SET_CANIDLE("dspxor_ck", 1);			/* IDLXORP_DSP */
   1790}
   1791
   1792static inline void omap_clkdsp_idlect2_update(struct omap_mpu_state_s *s,
   1793                uint16_t diff, uint16_t value)
   1794{
   1795    omap_clk clk;
   1796
   1797    SET_ONOFF("dspxor_ck", 1);				/* EN_XORPCK */
   1798}
   1799
   1800static void omap_clkdsp_write(void *opaque, hwaddr addr,
   1801                              uint64_t value, unsigned size)
   1802{
   1803    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
   1804    uint16_t diff;
   1805
   1806    if (size != 2) {
   1807        omap_badwidth_write16(opaque, addr, value);
   1808        return;
   1809    }
   1810
   1811    switch (addr) {
   1812    case 0x04:	/* DSP_IDLECT1 */
   1813        diff = s->clkm.dsp_idlect1 ^ value;
   1814        s->clkm.dsp_idlect1 = value & 0x01f7;
   1815        omap_clkdsp_idlect1_update(s, diff, value);
   1816        break;
   1817
   1818    case 0x08:	/* DSP_IDLECT2 */
   1819        s->clkm.dsp_idlect2 = value & 0x0037;
   1820        diff = s->clkm.dsp_idlect1 ^ value;
   1821        omap_clkdsp_idlect2_update(s, diff, value);
   1822        break;
   1823
   1824    case 0x14:	/* DSP_RSTCT2 */
   1825        s->clkm.dsp_rstct2 = value & 0x0001;
   1826        break;
   1827
   1828    case 0x18:	/* DSP_SYSST */
   1829        s->clkm.cold_start &= value & 0x3f;
   1830        break;
   1831
   1832    default:
   1833        OMAP_BAD_REG(addr);
   1834    }
   1835}
   1836
   1837static const MemoryRegionOps omap_clkdsp_ops = {
   1838    .read = omap_clkdsp_read,
   1839    .write = omap_clkdsp_write,
   1840    .endianness = DEVICE_NATIVE_ENDIAN,
   1841};
   1842
   1843static void omap_clkm_reset(struct omap_mpu_state_s *s)
   1844{
   1845    if (s->wdt && s->wdt->reset)
   1846        s->clkm.cold_start = 0x6;
   1847    s->clkm.clocking_scheme = 0;
   1848    omap_clkm_ckctl_update(s, ~0, 0x3000);
   1849    s->clkm.arm_ckctl = 0x3000;
   1850    omap_clkm_idlect1_update(s, s->clkm.arm_idlect1 ^ 0x0400, 0x0400);
   1851    s->clkm.arm_idlect1 = 0x0400;
   1852    omap_clkm_idlect2_update(s, s->clkm.arm_idlect2 ^ 0x0100, 0x0100);
   1853    s->clkm.arm_idlect2 = 0x0100;
   1854    s->clkm.arm_ewupct = 0x003f;
   1855    s->clkm.arm_rstct1 = 0x0000;
   1856    s->clkm.arm_rstct2 = 0x0000;
   1857    s->clkm.arm_ckout1 = 0x0015;
   1858    s->clkm.dpll1_mode = 0x2002;
   1859    omap_clkdsp_idlect1_update(s, s->clkm.dsp_idlect1 ^ 0x0040, 0x0040);
   1860    s->clkm.dsp_idlect1 = 0x0040;
   1861    omap_clkdsp_idlect2_update(s, ~0, 0x0000);
   1862    s->clkm.dsp_idlect2 = 0x0000;
   1863    s->clkm.dsp_rstct2 = 0x0000;
   1864}
   1865
   1866static void omap_clkm_init(MemoryRegion *memory, hwaddr mpu_base,
   1867                hwaddr dsp_base, struct omap_mpu_state_s *s)
   1868{
   1869    memory_region_init_io(&s->clkm_iomem, NULL, &omap_clkm_ops, s,
   1870                          "omap-clkm", 0x100);
   1871    memory_region_init_io(&s->clkdsp_iomem, NULL, &omap_clkdsp_ops, s,
   1872                          "omap-clkdsp", 0x1000);
   1873
   1874    s->clkm.arm_idlect1 = 0x03ff;
   1875    s->clkm.arm_idlect2 = 0x0100;
   1876    s->clkm.dsp_idlect1 = 0x0002;
   1877    omap_clkm_reset(s);
   1878    s->clkm.cold_start = 0x3a;
   1879
   1880    memory_region_add_subregion(memory, mpu_base, &s->clkm_iomem);
   1881    memory_region_add_subregion(memory, dsp_base, &s->clkdsp_iomem);
   1882}
   1883
   1884/* MPU I/O */
   1885struct omap_mpuio_s {
   1886    qemu_irq irq;
   1887    qemu_irq kbd_irq;
   1888    qemu_irq *in;
   1889    qemu_irq handler[16];
   1890    qemu_irq wakeup;
   1891    MemoryRegion iomem;
   1892
   1893    uint16_t inputs;
   1894    uint16_t outputs;
   1895    uint16_t dir;
   1896    uint16_t edge;
   1897    uint16_t mask;
   1898    uint16_t ints;
   1899
   1900    uint16_t debounce;
   1901    uint16_t latch;
   1902    uint8_t event;
   1903
   1904    uint8_t buttons[5];
   1905    uint8_t row_latch;
   1906    uint8_t cols;
   1907    int kbd_mask;
   1908    int clk;
   1909};
   1910
   1911static void omap_mpuio_set(void *opaque, int line, int level)
   1912{
   1913    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
   1914    uint16_t prev = s->inputs;
   1915
   1916    if (level)
   1917        s->inputs |= 1 << line;
   1918    else
   1919        s->inputs &= ~(1 << line);
   1920
   1921    if (((1 << line) & s->dir & ~s->mask) && s->clk) {
   1922        if ((s->edge & s->inputs & ~prev) | (~s->edge & ~s->inputs & prev)) {
   1923            s->ints |= 1 << line;
   1924            qemu_irq_raise(s->irq);
   1925            /* TODO: wakeup */
   1926        }
   1927        if ((s->event & (1 << 0)) &&		/* SET_GPIO_EVENT_MODE */
   1928                (s->event >> 1) == line)	/* PIN_SELECT */
   1929            s->latch = s->inputs;
   1930    }
   1931}
   1932
   1933static void omap_mpuio_kbd_update(struct omap_mpuio_s *s)
   1934{
   1935    int i;
   1936    uint8_t *row, rows = 0, cols = ~s->cols;
   1937
   1938    for (row = s->buttons + 4, i = 1 << 4; i; row --, i >>= 1)
   1939        if (*row & cols)
   1940            rows |= i;
   1941
   1942    qemu_set_irq(s->kbd_irq, rows && !s->kbd_mask && s->clk);
   1943    s->row_latch = ~rows;
   1944}
   1945
   1946static uint64_t omap_mpuio_read(void *opaque, hwaddr addr,
   1947                                unsigned size)
   1948{
   1949    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
   1950    int offset = addr & OMAP_MPUI_REG_MASK;
   1951    uint16_t ret;
   1952
   1953    if (size != 2) {
   1954        return omap_badwidth_read16(opaque, addr);
   1955    }
   1956
   1957    switch (offset) {
   1958    case 0x00:	/* INPUT_LATCH */
   1959        return s->inputs;
   1960
   1961    case 0x04:	/* OUTPUT_REG */
   1962        return s->outputs;
   1963
   1964    case 0x08:	/* IO_CNTL */
   1965        return s->dir;
   1966
   1967    case 0x10:	/* KBR_LATCH */
   1968        return s->row_latch;
   1969
   1970    case 0x14:	/* KBC_REG */
   1971        return s->cols;
   1972
   1973    case 0x18:	/* GPIO_EVENT_MODE_REG */
   1974        return s->event;
   1975
   1976    case 0x1c:	/* GPIO_INT_EDGE_REG */
   1977        return s->edge;
   1978
   1979    case 0x20:	/* KBD_INT */
   1980        return (~s->row_latch & 0x1f) && !s->kbd_mask;
   1981
   1982    case 0x24:	/* GPIO_INT */
   1983        ret = s->ints;
   1984        s->ints &= s->mask;
   1985        if (ret)
   1986            qemu_irq_lower(s->irq);
   1987        return ret;
   1988
   1989    case 0x28:	/* KBD_MASKIT */
   1990        return s->kbd_mask;
   1991
   1992    case 0x2c:	/* GPIO_MASKIT */
   1993        return s->mask;
   1994
   1995    case 0x30:	/* GPIO_DEBOUNCING_REG */
   1996        return s->debounce;
   1997
   1998    case 0x34:	/* GPIO_LATCH_REG */
   1999        return s->latch;
   2000    }
   2001
   2002    OMAP_BAD_REG(addr);
   2003    return 0;
   2004}
   2005
   2006static void omap_mpuio_write(void *opaque, hwaddr addr,
   2007                             uint64_t value, unsigned size)
   2008{
   2009    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
   2010    int offset = addr & OMAP_MPUI_REG_MASK;
   2011    uint16_t diff;
   2012    int ln;
   2013
   2014    if (size != 2) {
   2015        omap_badwidth_write16(opaque, addr, value);
   2016        return;
   2017    }
   2018
   2019    switch (offset) {
   2020    case 0x04:	/* OUTPUT_REG */
   2021        diff = (s->outputs ^ value) & ~s->dir;
   2022        s->outputs = value;
   2023        while ((ln = ctz32(diff)) != 32) {
   2024            if (s->handler[ln])
   2025                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
   2026            diff &= ~(1 << ln);
   2027        }
   2028        break;
   2029
   2030    case 0x08:	/* IO_CNTL */
   2031        diff = s->outputs & (s->dir ^ value);
   2032        s->dir = value;
   2033
   2034        value = s->outputs & ~s->dir;
   2035        while ((ln = ctz32(diff)) != 32) {
   2036            if (s->handler[ln])
   2037                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
   2038            diff &= ~(1 << ln);
   2039        }
   2040        break;
   2041
   2042    case 0x14:	/* KBC_REG */
   2043        s->cols = value;
   2044        omap_mpuio_kbd_update(s);
   2045        break;
   2046
   2047    case 0x18:	/* GPIO_EVENT_MODE_REG */
   2048        s->event = value & 0x1f;
   2049        break;
   2050
   2051    case 0x1c:	/* GPIO_INT_EDGE_REG */
   2052        s->edge = value;
   2053        break;
   2054
   2055    case 0x28:	/* KBD_MASKIT */
   2056        s->kbd_mask = value & 1;
   2057        omap_mpuio_kbd_update(s);
   2058        break;
   2059
   2060    case 0x2c:	/* GPIO_MASKIT */
   2061        s->mask = value;
   2062        break;
   2063
   2064    case 0x30:	/* GPIO_DEBOUNCING_REG */
   2065        s->debounce = value & 0x1ff;
   2066        break;
   2067
   2068    case 0x00:	/* INPUT_LATCH */
   2069    case 0x10:	/* KBR_LATCH */
   2070    case 0x20:	/* KBD_INT */
   2071    case 0x24:	/* GPIO_INT */
   2072    case 0x34:	/* GPIO_LATCH_REG */
   2073        OMAP_RO_REG(addr);
   2074        return;
   2075
   2076    default:
   2077        OMAP_BAD_REG(addr);
   2078        return;
   2079    }
   2080}
   2081
   2082static const MemoryRegionOps omap_mpuio_ops  = {
   2083    .read = omap_mpuio_read,
   2084    .write = omap_mpuio_write,
   2085    .endianness = DEVICE_NATIVE_ENDIAN,
   2086};
   2087
   2088static void omap_mpuio_reset(struct omap_mpuio_s *s)
   2089{
   2090    s->inputs = 0;
   2091    s->outputs = 0;
   2092    s->dir = ~0;
   2093    s->event = 0;
   2094    s->edge = 0;
   2095    s->kbd_mask = 0;
   2096    s->mask = 0;
   2097    s->debounce = 0;
   2098    s->latch = 0;
   2099    s->ints = 0;
   2100    s->row_latch = 0x1f;
   2101    s->clk = 1;
   2102}
   2103
   2104static void omap_mpuio_onoff(void *opaque, int line, int on)
   2105{
   2106    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
   2107
   2108    s->clk = on;
   2109    if (on)
   2110        omap_mpuio_kbd_update(s);
   2111}
   2112
   2113static struct omap_mpuio_s *omap_mpuio_init(MemoryRegion *memory,
   2114                hwaddr base,
   2115                qemu_irq kbd_int, qemu_irq gpio_int, qemu_irq wakeup,
   2116                omap_clk clk)
   2117{
   2118    struct omap_mpuio_s *s = g_new0(struct omap_mpuio_s, 1);
   2119
   2120    s->irq = gpio_int;
   2121    s->kbd_irq = kbd_int;
   2122    s->wakeup = wakeup;
   2123    s->in = qemu_allocate_irqs(omap_mpuio_set, s, 16);
   2124    omap_mpuio_reset(s);
   2125
   2126    memory_region_init_io(&s->iomem, NULL, &omap_mpuio_ops, s,
   2127                          "omap-mpuio", 0x800);
   2128    memory_region_add_subregion(memory, base, &s->iomem);
   2129
   2130    omap_clk_adduser(clk, qemu_allocate_irq(omap_mpuio_onoff, s, 0));
   2131
   2132    return s;
   2133}
   2134
   2135qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s)
   2136{
   2137    return s->in;
   2138}
   2139
   2140void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler)
   2141{
   2142    if (line >= 16 || line < 0)
   2143        hw_error("%s: No GPIO line %i\n", __func__, line);
   2144    s->handler[line] = handler;
   2145}
   2146
   2147void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down)
   2148{
   2149    if (row >= 5 || row < 0)
   2150        hw_error("%s: No key %i-%i\n", __func__, col, row);
   2151
   2152    if (down)
   2153        s->buttons[row] |= 1 << col;
   2154    else
   2155        s->buttons[row] &= ~(1 << col);
   2156
   2157    omap_mpuio_kbd_update(s);
   2158}
   2159
   2160/* MicroWire Interface */
   2161struct omap_uwire_s {
   2162    MemoryRegion iomem;
   2163    qemu_irq txirq;
   2164    qemu_irq rxirq;
   2165    qemu_irq txdrq;
   2166
   2167    uint16_t txbuf;
   2168    uint16_t rxbuf;
   2169    uint16_t control;
   2170    uint16_t setup[5];
   2171
   2172    uWireSlave *chip[4];
   2173};
   2174
   2175static void omap_uwire_transfer_start(struct omap_uwire_s *s)
   2176{
   2177    int chipselect = (s->control >> 10) & 3;		/* INDEX */
   2178    uWireSlave *slave = s->chip[chipselect];
   2179
   2180    if ((s->control >> 5) & 0x1f) {			/* NB_BITS_WR */
   2181        if (s->control & (1 << 12))			/* CS_CMD */
   2182            if (slave && slave->send)
   2183                slave->send(slave->opaque,
   2184                                s->txbuf >> (16 - ((s->control >> 5) & 0x1f)));
   2185        s->control &= ~(1 << 14);			/* CSRB */
   2186        /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
   2187         * a DRQ.  When is the level IRQ supposed to be reset?  */
   2188    }
   2189
   2190    if ((s->control >> 0) & 0x1f) {			/* NB_BITS_RD */
   2191        if (s->control & (1 << 12))			/* CS_CMD */
   2192            if (slave && slave->receive)
   2193                s->rxbuf = slave->receive(slave->opaque);
   2194        s->control |= 1 << 15;				/* RDRB */
   2195        /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
   2196         * a DRQ.  When is the level IRQ supposed to be reset?  */
   2197    }
   2198}
   2199
   2200static uint64_t omap_uwire_read(void *opaque, hwaddr addr,
   2201                                unsigned size)
   2202{
   2203    struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
   2204    int offset = addr & OMAP_MPUI_REG_MASK;
   2205
   2206    if (size != 2) {
   2207        return omap_badwidth_read16(opaque, addr);
   2208    }
   2209
   2210    switch (offset) {
   2211    case 0x00:	/* RDR */
   2212        s->control &= ~(1 << 15);			/* RDRB */
   2213        return s->rxbuf;
   2214
   2215    case 0x04:	/* CSR */
   2216        return s->control;
   2217
   2218    case 0x08:	/* SR1 */
   2219        return s->setup[0];
   2220    case 0x0c:	/* SR2 */
   2221        return s->setup[1];
   2222    case 0x10:	/* SR3 */
   2223        return s->setup[2];
   2224    case 0x14:	/* SR4 */
   2225        return s->setup[3];
   2226    case 0x18:	/* SR5 */
   2227        return s->setup[4];
   2228    }
   2229
   2230    OMAP_BAD_REG(addr);
   2231    return 0;
   2232}
   2233
   2234static void omap_uwire_write(void *opaque, hwaddr addr,
   2235                             uint64_t value, unsigned size)
   2236{
   2237    struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
   2238    int offset = addr & OMAP_MPUI_REG_MASK;
   2239
   2240    if (size != 2) {
   2241        omap_badwidth_write16(opaque, addr, value);
   2242        return;
   2243    }
   2244
   2245    switch (offset) {
   2246    case 0x00:	/* TDR */
   2247        s->txbuf = value;				/* TD */
   2248        if ((s->setup[4] & (1 << 2)) &&			/* AUTO_TX_EN */
   2249                        ((s->setup[4] & (1 << 3)) ||	/* CS_TOGGLE_TX_EN */
   2250                         (s->control & (1 << 12)))) {	/* CS_CMD */
   2251            s->control |= 1 << 14;			/* CSRB */
   2252            omap_uwire_transfer_start(s);
   2253        }
   2254        break;
   2255
   2256    case 0x04:	/* CSR */
   2257        s->control = value & 0x1fff;
   2258        if (value & (1 << 13))				/* START */
   2259            omap_uwire_transfer_start(s);
   2260        break;
   2261
   2262    case 0x08:	/* SR1 */
   2263        s->setup[0] = value & 0x003f;
   2264        break;
   2265
   2266    case 0x0c:	/* SR2 */
   2267        s->setup[1] = value & 0x0fc0;
   2268        break;
   2269
   2270    case 0x10:	/* SR3 */
   2271        s->setup[2] = value & 0x0003;
   2272        break;
   2273
   2274    case 0x14:	/* SR4 */
   2275        s->setup[3] = value & 0x0001;
   2276        break;
   2277
   2278    case 0x18:	/* SR5 */
   2279        s->setup[4] = value & 0x000f;
   2280        break;
   2281
   2282    default:
   2283        OMAP_BAD_REG(addr);
   2284        return;
   2285    }
   2286}
   2287
   2288static const MemoryRegionOps omap_uwire_ops = {
   2289    .read = omap_uwire_read,
   2290    .write = omap_uwire_write,
   2291    .endianness = DEVICE_NATIVE_ENDIAN,
   2292};
   2293
   2294static void omap_uwire_reset(struct omap_uwire_s *s)
   2295{
   2296    s->control = 0;
   2297    s->setup[0] = 0;
   2298    s->setup[1] = 0;
   2299    s->setup[2] = 0;
   2300    s->setup[3] = 0;
   2301    s->setup[4] = 0;
   2302}
   2303
   2304static struct omap_uwire_s *omap_uwire_init(MemoryRegion *system_memory,
   2305                                            hwaddr base,
   2306                                            qemu_irq txirq, qemu_irq rxirq,
   2307                                            qemu_irq dma,
   2308                                            omap_clk clk)
   2309{
   2310    struct omap_uwire_s *s = g_new0(struct omap_uwire_s, 1);
   2311
   2312    s->txirq = txirq;
   2313    s->rxirq = rxirq;
   2314    s->txdrq = dma;
   2315    omap_uwire_reset(s);
   2316
   2317    memory_region_init_io(&s->iomem, NULL, &omap_uwire_ops, s, "omap-uwire", 0x800);
   2318    memory_region_add_subregion(system_memory, base, &s->iomem);
   2319
   2320    return s;
   2321}
   2322
   2323void omap_uwire_attach(struct omap_uwire_s *s,
   2324                uWireSlave *slave, int chipselect)
   2325{
   2326    if (chipselect < 0 || chipselect > 3) {
   2327        error_report("%s: Bad chipselect %i", __func__, chipselect);
   2328        exit(-1);
   2329    }
   2330
   2331    s->chip[chipselect] = slave;
   2332}
   2333
   2334/* Pseudonoise Pulse-Width Light Modulator */
   2335struct omap_pwl_s {
   2336    MemoryRegion iomem;
   2337    uint8_t output;
   2338    uint8_t level;
   2339    uint8_t enable;
   2340    int clk;
   2341};
   2342
   2343static void omap_pwl_update(struct omap_pwl_s *s)
   2344{
   2345    int output = (s->clk && s->enable) ? s->level : 0;
   2346
   2347    if (output != s->output) {
   2348        s->output = output;
   2349        printf("%s: Backlight now at %i/256\n", __func__, output);
   2350    }
   2351}
   2352
   2353static uint64_t omap_pwl_read(void *opaque, hwaddr addr,
   2354                              unsigned size)
   2355{
   2356    struct omap_pwl_s *s = (struct omap_pwl_s *) opaque;
   2357    int offset = addr & OMAP_MPUI_REG_MASK;
   2358
   2359    if (size != 1) {
   2360        return omap_badwidth_read8(opaque, addr);
   2361    }
   2362
   2363    switch (offset) {
   2364    case 0x00:	/* PWL_LEVEL */
   2365        return s->level;
   2366    case 0x04:	/* PWL_CTRL */
   2367        return s->enable;
   2368    }
   2369    OMAP_BAD_REG(addr);
   2370    return 0;
   2371}
   2372
   2373static void omap_pwl_write(void *opaque, hwaddr addr,
   2374                           uint64_t value, unsigned size)
   2375{
   2376    struct omap_pwl_s *s = (struct omap_pwl_s *) opaque;
   2377    int offset = addr & OMAP_MPUI_REG_MASK;
   2378
   2379    if (size != 1) {
   2380        omap_badwidth_write8(opaque, addr, value);
   2381        return;
   2382    }
   2383
   2384    switch (offset) {
   2385    case 0x00:	/* PWL_LEVEL */
   2386        s->level = value;
   2387        omap_pwl_update(s);
   2388        break;
   2389    case 0x04:	/* PWL_CTRL */
   2390        s->enable = value & 1;
   2391        omap_pwl_update(s);
   2392        break;
   2393    default:
   2394        OMAP_BAD_REG(addr);
   2395        return;
   2396    }
   2397}
   2398
   2399static const MemoryRegionOps omap_pwl_ops = {
   2400    .read = omap_pwl_read,
   2401    .write = omap_pwl_write,
   2402    .endianness = DEVICE_NATIVE_ENDIAN,
   2403};
   2404
   2405static void omap_pwl_reset(struct omap_pwl_s *s)
   2406{
   2407    s->output = 0;
   2408    s->level = 0;
   2409    s->enable = 0;
   2410    s->clk = 1;
   2411    omap_pwl_update(s);
   2412}
   2413
   2414static void omap_pwl_clk_update(void *opaque, int line, int on)
   2415{
   2416    struct omap_pwl_s *s = (struct omap_pwl_s *) opaque;
   2417
   2418    s->clk = on;
   2419    omap_pwl_update(s);
   2420}
   2421
   2422static struct omap_pwl_s *omap_pwl_init(MemoryRegion *system_memory,
   2423                                        hwaddr base,
   2424                                        omap_clk clk)
   2425{
   2426    struct omap_pwl_s *s = g_malloc0(sizeof(*s));
   2427
   2428    omap_pwl_reset(s);
   2429
   2430    memory_region_init_io(&s->iomem, NULL, &omap_pwl_ops, s,
   2431                          "omap-pwl", 0x800);
   2432    memory_region_add_subregion(system_memory, base, &s->iomem);
   2433
   2434    omap_clk_adduser(clk, qemu_allocate_irq(omap_pwl_clk_update, s, 0));
   2435    return s;
   2436}
   2437
   2438/* Pulse-Width Tone module */
   2439struct omap_pwt_s {
   2440    MemoryRegion iomem;
   2441    uint8_t frc;
   2442    uint8_t vrc;
   2443    uint8_t gcr;
   2444    omap_clk clk;
   2445};
   2446
   2447static uint64_t omap_pwt_read(void *opaque, hwaddr addr,
   2448                              unsigned size)
   2449{
   2450    struct omap_pwt_s *s = (struct omap_pwt_s *) opaque;
   2451    int offset = addr & OMAP_MPUI_REG_MASK;
   2452
   2453    if (size != 1) {
   2454        return omap_badwidth_read8(opaque, addr);
   2455    }
   2456
   2457    switch (offset) {
   2458    case 0x00:	/* FRC */
   2459        return s->frc;
   2460    case 0x04:	/* VCR */
   2461        return s->vrc;
   2462    case 0x08:	/* GCR */
   2463        return s->gcr;
   2464    }
   2465    OMAP_BAD_REG(addr);
   2466    return 0;
   2467}
   2468
   2469static void omap_pwt_write(void *opaque, hwaddr addr,
   2470                           uint64_t value, unsigned size)
   2471{
   2472    struct omap_pwt_s *s = (struct omap_pwt_s *) opaque;
   2473    int offset = addr & OMAP_MPUI_REG_MASK;
   2474
   2475    if (size != 1) {
   2476        omap_badwidth_write8(opaque, addr, value);
   2477        return;
   2478    }
   2479
   2480    switch (offset) {
   2481    case 0x00:	/* FRC */
   2482        s->frc = value & 0x3f;
   2483        break;
   2484    case 0x04:	/* VRC */
   2485        if ((value ^ s->vrc) & 1) {
   2486            if (value & 1)
   2487                printf("%s: %iHz buzz on\n", __func__, (int)
   2488                                /* 1.5 MHz from a 12-MHz or 13-MHz PWT_CLK */
   2489                                ((omap_clk_getrate(s->clk) >> 3) /
   2490                                 /* Pre-multiplexer divider */
   2491                                 ((s->gcr & 2) ? 1 : 154) /
   2492                                 /* Octave multiplexer */
   2493                                 (2 << (value & 3)) *
   2494                                 /* 101/107 divider */
   2495                                 ((value & (1 << 2)) ? 101 : 107) *
   2496                                 /*  49/55 divider */
   2497                                 ((value & (1 << 3)) ?  49 : 55) *
   2498                                 /*  50/63 divider */
   2499                                 ((value & (1 << 4)) ?  50 : 63) *
   2500                                 /*  80/127 divider */
   2501                                 ((value & (1 << 5)) ?  80 : 127) /
   2502                                 (107 * 55 * 63 * 127)));
   2503            else
   2504                printf("%s: silence!\n", __func__);
   2505        }
   2506        s->vrc = value & 0x7f;
   2507        break;
   2508    case 0x08:	/* GCR */
   2509        s->gcr = value & 3;
   2510        break;
   2511    default:
   2512        OMAP_BAD_REG(addr);
   2513        return;
   2514    }
   2515}
   2516
   2517static const MemoryRegionOps omap_pwt_ops = {
   2518    .read =omap_pwt_read,
   2519    .write = omap_pwt_write,
   2520    .endianness = DEVICE_NATIVE_ENDIAN,
   2521};
   2522
   2523static void omap_pwt_reset(struct omap_pwt_s *s)
   2524{
   2525    s->frc = 0;
   2526    s->vrc = 0;
   2527    s->gcr = 0;
   2528}
   2529
   2530static struct omap_pwt_s *omap_pwt_init(MemoryRegion *system_memory,
   2531                                        hwaddr base,
   2532                                        omap_clk clk)
   2533{
   2534    struct omap_pwt_s *s = g_malloc0(sizeof(*s));
   2535    s->clk = clk;
   2536    omap_pwt_reset(s);
   2537
   2538    memory_region_init_io(&s->iomem, NULL, &omap_pwt_ops, s,
   2539                          "omap-pwt", 0x800);
   2540    memory_region_add_subregion(system_memory, base, &s->iomem);
   2541    return s;
   2542}
   2543
   2544/* Real-time Clock module */
   2545struct omap_rtc_s {
   2546    MemoryRegion iomem;
   2547    qemu_irq irq;
   2548    qemu_irq alarm;
   2549    QEMUTimer *clk;
   2550
   2551    uint8_t interrupts;
   2552    uint8_t status;
   2553    int16_t comp_reg;
   2554    int running;
   2555    int pm_am;
   2556    int auto_comp;
   2557    int round;
   2558    struct tm alarm_tm;
   2559    time_t alarm_ti;
   2560
   2561    struct tm current_tm;
   2562    time_t ti;
   2563    uint64_t tick;
   2564};
   2565
   2566static void omap_rtc_interrupts_update(struct omap_rtc_s *s)
   2567{
   2568    /* s->alarm is level-triggered */
   2569    qemu_set_irq(s->alarm, (s->status >> 6) & 1);
   2570}
   2571
   2572static void omap_rtc_alarm_update(struct omap_rtc_s *s)
   2573{
   2574    s->alarm_ti = mktimegm(&s->alarm_tm);
   2575    if (s->alarm_ti == -1)
   2576        printf("%s: conversion failed\n", __func__);
   2577}
   2578
   2579static uint64_t omap_rtc_read(void *opaque, hwaddr addr,
   2580                              unsigned size)
   2581{
   2582    struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
   2583    int offset = addr & OMAP_MPUI_REG_MASK;
   2584    uint8_t i;
   2585
   2586    if (size != 1) {
   2587        return omap_badwidth_read8(opaque, addr);
   2588    }
   2589
   2590    switch (offset) {
   2591    case 0x00:	/* SECONDS_REG */
   2592        return to_bcd(s->current_tm.tm_sec);
   2593
   2594    case 0x04:	/* MINUTES_REG */
   2595        return to_bcd(s->current_tm.tm_min);
   2596
   2597    case 0x08:	/* HOURS_REG */
   2598        if (s->pm_am)
   2599            return ((s->current_tm.tm_hour > 11) << 7) |
   2600                    to_bcd(((s->current_tm.tm_hour - 1) % 12) + 1);
   2601        else
   2602            return to_bcd(s->current_tm.tm_hour);
   2603
   2604    case 0x0c:	/* DAYS_REG */
   2605        return to_bcd(s->current_tm.tm_mday);
   2606
   2607    case 0x10:	/* MONTHS_REG */
   2608        return to_bcd(s->current_tm.tm_mon + 1);
   2609
   2610    case 0x14:	/* YEARS_REG */
   2611        return to_bcd(s->current_tm.tm_year % 100);
   2612
   2613    case 0x18:	/* WEEK_REG */
   2614        return s->current_tm.tm_wday;
   2615
   2616    case 0x20:	/* ALARM_SECONDS_REG */
   2617        return to_bcd(s->alarm_tm.tm_sec);
   2618
   2619    case 0x24:	/* ALARM_MINUTES_REG */
   2620        return to_bcd(s->alarm_tm.tm_min);
   2621
   2622    case 0x28:	/* ALARM_HOURS_REG */
   2623        if (s->pm_am)
   2624            return ((s->alarm_tm.tm_hour > 11) << 7) |
   2625                    to_bcd(((s->alarm_tm.tm_hour - 1) % 12) + 1);
   2626        else
   2627            return to_bcd(s->alarm_tm.tm_hour);
   2628
   2629    case 0x2c:	/* ALARM_DAYS_REG */
   2630        return to_bcd(s->alarm_tm.tm_mday);
   2631
   2632    case 0x30:	/* ALARM_MONTHS_REG */
   2633        return to_bcd(s->alarm_tm.tm_mon + 1);
   2634
   2635    case 0x34:	/* ALARM_YEARS_REG */
   2636        return to_bcd(s->alarm_tm.tm_year % 100);
   2637
   2638    case 0x40:	/* RTC_CTRL_REG */
   2639        return (s->pm_am << 3) | (s->auto_comp << 2) |
   2640                (s->round << 1) | s->running;
   2641
   2642    case 0x44:	/* RTC_STATUS_REG */
   2643        i = s->status;
   2644        s->status &= ~0x3d;
   2645        return i;
   2646
   2647    case 0x48:	/* RTC_INTERRUPTS_REG */
   2648        return s->interrupts;
   2649
   2650    case 0x4c:	/* RTC_COMP_LSB_REG */
   2651        return ((uint16_t) s->comp_reg) & 0xff;
   2652
   2653    case 0x50:	/* RTC_COMP_MSB_REG */
   2654        return ((uint16_t) s->comp_reg) >> 8;
   2655    }
   2656
   2657    OMAP_BAD_REG(addr);
   2658    return 0;
   2659}
   2660
   2661static void omap_rtc_write(void *opaque, hwaddr addr,
   2662                           uint64_t value, unsigned size)
   2663{
   2664    struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
   2665    int offset = addr & OMAP_MPUI_REG_MASK;
   2666    struct tm new_tm;
   2667    time_t ti[2];
   2668
   2669    if (size != 1) {
   2670        omap_badwidth_write8(opaque, addr, value);
   2671        return;
   2672    }
   2673
   2674    switch (offset) {
   2675    case 0x00:	/* SECONDS_REG */
   2676#ifdef ALMDEBUG
   2677        printf("RTC SEC_REG <-- %02x\n", value);
   2678#endif
   2679        s->ti -= s->current_tm.tm_sec;
   2680        s->ti += from_bcd(value);
   2681        return;
   2682
   2683    case 0x04:	/* MINUTES_REG */
   2684#ifdef ALMDEBUG
   2685        printf("RTC MIN_REG <-- %02x\n", value);
   2686#endif
   2687        s->ti -= s->current_tm.tm_min * 60;
   2688        s->ti += from_bcd(value) * 60;
   2689        return;
   2690
   2691    case 0x08:	/* HOURS_REG */
   2692#ifdef ALMDEBUG
   2693        printf("RTC HRS_REG <-- %02x\n", value);
   2694#endif
   2695        s->ti -= s->current_tm.tm_hour * 3600;
   2696        if (s->pm_am) {
   2697            s->ti += (from_bcd(value & 0x3f) & 12) * 3600;
   2698            s->ti += ((value >> 7) & 1) * 43200;
   2699        } else
   2700            s->ti += from_bcd(value & 0x3f) * 3600;
   2701        return;
   2702
   2703    case 0x0c:	/* DAYS_REG */
   2704#ifdef ALMDEBUG
   2705        printf("RTC DAY_REG <-- %02x\n", value);
   2706#endif
   2707        s->ti -= s->current_tm.tm_mday * 86400;
   2708        s->ti += from_bcd(value) * 86400;
   2709        return;
   2710
   2711    case 0x10:	/* MONTHS_REG */
   2712#ifdef ALMDEBUG
   2713        printf("RTC MTH_REG <-- %02x\n", value);
   2714#endif
   2715        memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
   2716        new_tm.tm_mon = from_bcd(value);
   2717        ti[0] = mktimegm(&s->current_tm);
   2718        ti[1] = mktimegm(&new_tm);
   2719
   2720        if (ti[0] != -1 && ti[1] != -1) {
   2721            s->ti -= ti[0];
   2722            s->ti += ti[1];
   2723        } else {
   2724            /* A less accurate version */
   2725            s->ti -= s->current_tm.tm_mon * 2592000;
   2726            s->ti += from_bcd(value) * 2592000;
   2727        }
   2728        return;
   2729
   2730    case 0x14:	/* YEARS_REG */
   2731#ifdef ALMDEBUG
   2732        printf("RTC YRS_REG <-- %02x\n", value);
   2733#endif
   2734        memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
   2735        new_tm.tm_year += from_bcd(value) - (new_tm.tm_year % 100);
   2736        ti[0] = mktimegm(&s->current_tm);
   2737        ti[1] = mktimegm(&new_tm);
   2738
   2739        if (ti[0] != -1 && ti[1] != -1) {
   2740            s->ti -= ti[0];
   2741            s->ti += ti[1];
   2742        } else {
   2743            /* A less accurate version */
   2744            s->ti -= (time_t)(s->current_tm.tm_year % 100) * 31536000;
   2745            s->ti += (time_t)from_bcd(value) * 31536000;
   2746        }
   2747        return;
   2748
   2749    case 0x18:	/* WEEK_REG */
   2750        return;	/* Ignored */
   2751
   2752    case 0x20:	/* ALARM_SECONDS_REG */
   2753#ifdef ALMDEBUG
   2754        printf("ALM SEC_REG <-- %02x\n", value);
   2755#endif
   2756        s->alarm_tm.tm_sec = from_bcd(value);
   2757        omap_rtc_alarm_update(s);
   2758        return;
   2759
   2760    case 0x24:	/* ALARM_MINUTES_REG */
   2761#ifdef ALMDEBUG
   2762        printf("ALM MIN_REG <-- %02x\n", value);
   2763#endif
   2764        s->alarm_tm.tm_min = from_bcd(value);
   2765        omap_rtc_alarm_update(s);
   2766        return;
   2767
   2768    case 0x28:	/* ALARM_HOURS_REG */
   2769#ifdef ALMDEBUG
   2770        printf("ALM HRS_REG <-- %02x\n", value);
   2771#endif
   2772        if (s->pm_am)
   2773            s->alarm_tm.tm_hour =
   2774                    ((from_bcd(value & 0x3f)) % 12) +
   2775                    ((value >> 7) & 1) * 12;
   2776        else
   2777            s->alarm_tm.tm_hour = from_bcd(value);
   2778        omap_rtc_alarm_update(s);
   2779        return;
   2780
   2781    case 0x2c:	/* ALARM_DAYS_REG */
   2782#ifdef ALMDEBUG
   2783        printf("ALM DAY_REG <-- %02x\n", value);
   2784#endif
   2785        s->alarm_tm.tm_mday = from_bcd(value);
   2786        omap_rtc_alarm_update(s);
   2787        return;
   2788
   2789    case 0x30:	/* ALARM_MONTHS_REG */
   2790#ifdef ALMDEBUG
   2791        printf("ALM MON_REG <-- %02x\n", value);
   2792#endif
   2793        s->alarm_tm.tm_mon = from_bcd(value);
   2794        omap_rtc_alarm_update(s);
   2795        return;
   2796
   2797    case 0x34:	/* ALARM_YEARS_REG */
   2798#ifdef ALMDEBUG
   2799        printf("ALM YRS_REG <-- %02x\n", value);
   2800#endif
   2801        s->alarm_tm.tm_year = from_bcd(value);
   2802        omap_rtc_alarm_update(s);
   2803        return;
   2804
   2805    case 0x40:	/* RTC_CTRL_REG */
   2806#ifdef ALMDEBUG
   2807        printf("RTC CONTROL <-- %02x\n", value);
   2808#endif
   2809        s->pm_am = (value >> 3) & 1;
   2810        s->auto_comp = (value >> 2) & 1;
   2811        s->round = (value >> 1) & 1;
   2812        s->running = value & 1;
   2813        s->status &= 0xfd;
   2814        s->status |= s->running << 1;
   2815        return;
   2816
   2817    case 0x44:	/* RTC_STATUS_REG */
   2818#ifdef ALMDEBUG
   2819        printf("RTC STATUSL <-- %02x\n", value);
   2820#endif
   2821        s->status &= ~((value & 0xc0) ^ 0x80);
   2822        omap_rtc_interrupts_update(s);
   2823        return;
   2824
   2825    case 0x48:	/* RTC_INTERRUPTS_REG */
   2826#ifdef ALMDEBUG
   2827        printf("RTC INTRS <-- %02x\n", value);
   2828#endif
   2829        s->interrupts = value;
   2830        return;
   2831
   2832    case 0x4c:	/* RTC_COMP_LSB_REG */
   2833#ifdef ALMDEBUG
   2834        printf("RTC COMPLSB <-- %02x\n", value);
   2835#endif
   2836        s->comp_reg &= 0xff00;
   2837        s->comp_reg |= 0x00ff & value;
   2838        return;
   2839
   2840    case 0x50:	/* RTC_COMP_MSB_REG */
   2841#ifdef ALMDEBUG
   2842        printf("RTC COMPMSB <-- %02x\n", value);
   2843#endif
   2844        s->comp_reg &= 0x00ff;
   2845        s->comp_reg |= 0xff00 & (value << 8);
   2846        return;
   2847
   2848    default:
   2849        OMAP_BAD_REG(addr);
   2850        return;
   2851    }
   2852}
   2853
   2854static const MemoryRegionOps omap_rtc_ops = {
   2855    .read = omap_rtc_read,
   2856    .write = omap_rtc_write,
   2857    .endianness = DEVICE_NATIVE_ENDIAN,
   2858};
   2859
   2860static void omap_rtc_tick(void *opaque)
   2861{
   2862    struct omap_rtc_s *s = opaque;
   2863
   2864    if (s->round) {
   2865        /* Round to nearest full minute.  */
   2866        if (s->current_tm.tm_sec < 30)
   2867            s->ti -= s->current_tm.tm_sec;
   2868        else
   2869            s->ti += 60 - s->current_tm.tm_sec;
   2870
   2871        s->round = 0;
   2872    }
   2873
   2874    localtime_r(&s->ti, &s->current_tm);
   2875
   2876    if ((s->interrupts & 0x08) && s->ti == s->alarm_ti) {
   2877        s->status |= 0x40;
   2878        omap_rtc_interrupts_update(s);
   2879    }
   2880
   2881    if (s->interrupts & 0x04)
   2882        switch (s->interrupts & 3) {
   2883        case 0:
   2884            s->status |= 0x04;
   2885            qemu_irq_pulse(s->irq);
   2886            break;
   2887        case 1:
   2888            if (s->current_tm.tm_sec)
   2889                break;
   2890            s->status |= 0x08;
   2891            qemu_irq_pulse(s->irq);
   2892            break;
   2893        case 2:
   2894            if (s->current_tm.tm_sec || s->current_tm.tm_min)
   2895                break;
   2896            s->status |= 0x10;
   2897            qemu_irq_pulse(s->irq);
   2898            break;
   2899        case 3:
   2900            if (s->current_tm.tm_sec ||
   2901                            s->current_tm.tm_min || s->current_tm.tm_hour)
   2902                break;
   2903            s->status |= 0x20;
   2904            qemu_irq_pulse(s->irq);
   2905            break;
   2906        }
   2907
   2908    /* Move on */
   2909    if (s->running)
   2910        s->ti ++;
   2911    s->tick += 1000;
   2912
   2913    /*
   2914     * Every full hour add a rough approximation of the compensation
   2915     * register to the 32kHz Timer (which drives the RTC) value. 
   2916     */
   2917    if (s->auto_comp && !s->current_tm.tm_sec && !s->current_tm.tm_min)
   2918        s->tick += s->comp_reg * 1000 / 32768;
   2919
   2920    timer_mod(s->clk, s->tick);
   2921}
   2922
   2923static void omap_rtc_reset(struct omap_rtc_s *s)
   2924{
   2925    struct tm tm;
   2926
   2927    s->interrupts = 0;
   2928    s->comp_reg = 0;
   2929    s->running = 0;
   2930    s->pm_am = 0;
   2931    s->auto_comp = 0;
   2932    s->round = 0;
   2933    s->tick = qemu_clock_get_ms(rtc_clock);
   2934    memset(&s->alarm_tm, 0, sizeof(s->alarm_tm));
   2935    s->alarm_tm.tm_mday = 0x01;
   2936    s->status = 1 << 7;
   2937    qemu_get_timedate(&tm, 0);
   2938    s->ti = mktimegm(&tm);
   2939
   2940    omap_rtc_alarm_update(s);
   2941    omap_rtc_tick(s);
   2942}
   2943
   2944static struct omap_rtc_s *omap_rtc_init(MemoryRegion *system_memory,
   2945                                        hwaddr base,
   2946                                        qemu_irq timerirq, qemu_irq alarmirq,
   2947                                        omap_clk clk)
   2948{
   2949    struct omap_rtc_s *s = g_new0(struct omap_rtc_s, 1);
   2950
   2951    s->irq = timerirq;
   2952    s->alarm = alarmirq;
   2953    s->clk = timer_new_ms(rtc_clock, omap_rtc_tick, s);
   2954
   2955    omap_rtc_reset(s);
   2956
   2957    memory_region_init_io(&s->iomem, NULL, &omap_rtc_ops, s,
   2958                          "omap-rtc", 0x800);
   2959    memory_region_add_subregion(system_memory, base, &s->iomem);
   2960
   2961    return s;
   2962}
   2963
   2964/* Multi-channel Buffered Serial Port interfaces */
   2965struct omap_mcbsp_s {
   2966    MemoryRegion iomem;
   2967    qemu_irq txirq;
   2968    qemu_irq rxirq;
   2969    qemu_irq txdrq;
   2970    qemu_irq rxdrq;
   2971
   2972    uint16_t spcr[2];
   2973    uint16_t rcr[2];
   2974    uint16_t xcr[2];
   2975    uint16_t srgr[2];
   2976    uint16_t mcr[2];
   2977    uint16_t pcr;
   2978    uint16_t rcer[8];
   2979    uint16_t xcer[8];
   2980    int tx_rate;
   2981    int rx_rate;
   2982    int tx_req;
   2983    int rx_req;
   2984
   2985    I2SCodec *codec;
   2986    QEMUTimer *source_timer;
   2987    QEMUTimer *sink_timer;
   2988};
   2989
   2990static void omap_mcbsp_intr_update(struct omap_mcbsp_s *s)
   2991{
   2992    int irq;
   2993
   2994    switch ((s->spcr[0] >> 4) & 3) {			/* RINTM */
   2995    case 0:
   2996        irq = (s->spcr[0] >> 1) & 1;			/* RRDY */
   2997        break;
   2998    case 3:
   2999        irq = (s->spcr[0] >> 3) & 1;			/* RSYNCERR */
   3000        break;
   3001    default:
   3002        irq = 0;
   3003        break;
   3004    }
   3005
   3006    if (irq)
   3007        qemu_irq_pulse(s->rxirq);
   3008
   3009    switch ((s->spcr[1] >> 4) & 3) {			/* XINTM */
   3010    case 0:
   3011        irq = (s->spcr[1] >> 1) & 1;			/* XRDY */
   3012        break;
   3013    case 3:
   3014        irq = (s->spcr[1] >> 3) & 1;			/* XSYNCERR */
   3015        break;
   3016    default:
   3017        irq = 0;
   3018        break;
   3019    }
   3020
   3021    if (irq)
   3022        qemu_irq_pulse(s->txirq);
   3023}
   3024
   3025static void omap_mcbsp_rx_newdata(struct omap_mcbsp_s *s)
   3026{
   3027    if ((s->spcr[0] >> 1) & 1)				/* RRDY */
   3028        s->spcr[0] |= 1 << 2;				/* RFULL */
   3029    s->spcr[0] |= 1 << 1;				/* RRDY */
   3030    qemu_irq_raise(s->rxdrq);
   3031    omap_mcbsp_intr_update(s);
   3032}
   3033
   3034static void omap_mcbsp_source_tick(void *opaque)
   3035{
   3036    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
   3037    static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
   3038
   3039    if (!s->rx_rate)
   3040        return;
   3041    if (s->rx_req)
   3042        printf("%s: Rx FIFO overrun\n", __func__);
   3043
   3044    s->rx_req = s->rx_rate << bps[(s->rcr[0] >> 5) & 7];
   3045
   3046    omap_mcbsp_rx_newdata(s);
   3047    timer_mod(s->source_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
   3048                   NANOSECONDS_PER_SECOND);
   3049}
   3050
   3051static void omap_mcbsp_rx_start(struct omap_mcbsp_s *s)
   3052{
   3053    if (!s->codec || !s->codec->rts)
   3054        omap_mcbsp_source_tick(s);
   3055    else if (s->codec->in.len) {
   3056        s->rx_req = s->codec->in.len;
   3057        omap_mcbsp_rx_newdata(s);
   3058    }
   3059}
   3060
   3061static void omap_mcbsp_rx_stop(struct omap_mcbsp_s *s)
   3062{
   3063    timer_del(s->source_timer);
   3064}
   3065
   3066static void omap_mcbsp_rx_done(struct omap_mcbsp_s *s)
   3067{
   3068    s->spcr[0] &= ~(1 << 1);				/* RRDY */
   3069    qemu_irq_lower(s->rxdrq);
   3070    omap_mcbsp_intr_update(s);
   3071}
   3072
   3073static void omap_mcbsp_tx_newdata(struct omap_mcbsp_s *s)
   3074{
   3075    s->spcr[1] |= 1 << 1;				/* XRDY */
   3076    qemu_irq_raise(s->txdrq);
   3077    omap_mcbsp_intr_update(s);
   3078}
   3079
   3080static void omap_mcbsp_sink_tick(void *opaque)
   3081{
   3082    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
   3083    static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
   3084
   3085    if (!s->tx_rate)
   3086        return;
   3087    if (s->tx_req)
   3088        printf("%s: Tx FIFO underrun\n", __func__);
   3089
   3090    s->tx_req = s->tx_rate << bps[(s->xcr[0] >> 5) & 7];
   3091
   3092    omap_mcbsp_tx_newdata(s);
   3093    timer_mod(s->sink_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
   3094                   NANOSECONDS_PER_SECOND);
   3095}
   3096
   3097static void omap_mcbsp_tx_start(struct omap_mcbsp_s *s)
   3098{
   3099    if (!s->codec || !s->codec->cts)
   3100        omap_mcbsp_sink_tick(s);
   3101    else if (s->codec->out.size) {
   3102        s->tx_req = s->codec->out.size;
   3103        omap_mcbsp_tx_newdata(s);
   3104    }
   3105}
   3106
   3107static void omap_mcbsp_tx_done(struct omap_mcbsp_s *s)
   3108{
   3109    s->spcr[1] &= ~(1 << 1);				/* XRDY */
   3110    qemu_irq_lower(s->txdrq);
   3111    omap_mcbsp_intr_update(s);
   3112    if (s->codec && s->codec->cts)
   3113        s->codec->tx_swallow(s->codec->opaque);
   3114}
   3115
   3116static void omap_mcbsp_tx_stop(struct omap_mcbsp_s *s)
   3117{
   3118    s->tx_req = 0;
   3119    omap_mcbsp_tx_done(s);
   3120    timer_del(s->sink_timer);
   3121}
   3122
   3123static void omap_mcbsp_req_update(struct omap_mcbsp_s *s)
   3124{
   3125    int prev_rx_rate, prev_tx_rate;
   3126    int rx_rate = 0, tx_rate = 0;
   3127    int cpu_rate = 1500000;	/* XXX */
   3128
   3129    /* TODO: check CLKSTP bit */
   3130    if (s->spcr[1] & (1 << 6)) {			/* GRST */
   3131        if (s->spcr[0] & (1 << 0)) {			/* RRST */
   3132            if ((s->srgr[1] & (1 << 13)) &&		/* CLKSM */
   3133                            (s->pcr & (1 << 8))) {	/* CLKRM */
   3134                if (~s->pcr & (1 << 7))			/* SCLKME */
   3135                    rx_rate = cpu_rate /
   3136                            ((s->srgr[0] & 0xff) + 1);	/* CLKGDV */
   3137            } else
   3138                if (s->codec)
   3139                    rx_rate = s->codec->rx_rate;
   3140        }
   3141
   3142        if (s->spcr[1] & (1 << 0)) {			/* XRST */
   3143            if ((s->srgr[1] & (1 << 13)) &&		/* CLKSM */
   3144                            (s->pcr & (1 << 9))) {	/* CLKXM */
   3145                if (~s->pcr & (1 << 7))			/* SCLKME */
   3146                    tx_rate = cpu_rate /
   3147                            ((s->srgr[0] & 0xff) + 1);	/* CLKGDV */
   3148            } else
   3149                if (s->codec)
   3150                    tx_rate = s->codec->tx_rate;
   3151        }
   3152    }
   3153    prev_tx_rate = s->tx_rate;
   3154    prev_rx_rate = s->rx_rate;
   3155    s->tx_rate = tx_rate;
   3156    s->rx_rate = rx_rate;
   3157
   3158    if (s->codec)
   3159        s->codec->set_rate(s->codec->opaque, rx_rate, tx_rate);
   3160
   3161    if (!prev_tx_rate && tx_rate)
   3162        omap_mcbsp_tx_start(s);
   3163    else if (s->tx_rate && !tx_rate)
   3164        omap_mcbsp_tx_stop(s);
   3165
   3166    if (!prev_rx_rate && rx_rate)
   3167        omap_mcbsp_rx_start(s);
   3168    else if (prev_tx_rate && !tx_rate)
   3169        omap_mcbsp_rx_stop(s);
   3170}
   3171
   3172static uint64_t omap_mcbsp_read(void *opaque, hwaddr addr,
   3173                                unsigned size)
   3174{
   3175    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
   3176    int offset = addr & OMAP_MPUI_REG_MASK;
   3177    uint16_t ret;
   3178
   3179    if (size != 2) {
   3180        return omap_badwidth_read16(opaque, addr);
   3181    }
   3182
   3183    switch (offset) {
   3184    case 0x00:	/* DRR2 */
   3185        if (((s->rcr[0] >> 5) & 7) < 3)			/* RWDLEN1 */
   3186            return 0x0000;
   3187        /* Fall through.  */
   3188    case 0x02:	/* DRR1 */
   3189        if (s->rx_req < 2) {
   3190            printf("%s: Rx FIFO underrun\n", __func__);
   3191            omap_mcbsp_rx_done(s);
   3192        } else {
   3193            s->tx_req -= 2;
   3194            if (s->codec && s->codec->in.len >= 2) {
   3195                ret = s->codec->in.fifo[s->codec->in.start ++] << 8;
   3196                ret |= s->codec->in.fifo[s->codec->in.start ++];
   3197                s->codec->in.len -= 2;
   3198            } else
   3199                ret = 0x0000;
   3200            if (!s->tx_req)
   3201                omap_mcbsp_rx_done(s);
   3202            return ret;
   3203        }
   3204        return 0x0000;
   3205
   3206    case 0x04:	/* DXR2 */
   3207    case 0x06:	/* DXR1 */
   3208        return 0x0000;
   3209
   3210    case 0x08:	/* SPCR2 */
   3211        return s->spcr[1];
   3212    case 0x0a:	/* SPCR1 */
   3213        return s->spcr[0];
   3214    case 0x0c:	/* RCR2 */
   3215        return s->rcr[1];
   3216    case 0x0e:	/* RCR1 */
   3217        return s->rcr[0];
   3218    case 0x10:	/* XCR2 */
   3219        return s->xcr[1];
   3220    case 0x12:	/* XCR1 */
   3221        return s->xcr[0];
   3222    case 0x14:	/* SRGR2 */
   3223        return s->srgr[1];
   3224    case 0x16:	/* SRGR1 */
   3225        return s->srgr[0];
   3226    case 0x18:	/* MCR2 */
   3227        return s->mcr[1];
   3228    case 0x1a:	/* MCR1 */
   3229        return s->mcr[0];
   3230    case 0x1c:	/* RCERA */
   3231        return s->rcer[0];
   3232    case 0x1e:	/* RCERB */
   3233        return s->rcer[1];
   3234    case 0x20:	/* XCERA */
   3235        return s->xcer[0];
   3236    case 0x22:	/* XCERB */
   3237        return s->xcer[1];
   3238    case 0x24:	/* PCR0 */
   3239        return s->pcr;
   3240    case 0x26:	/* RCERC */
   3241        return s->rcer[2];
   3242    case 0x28:	/* RCERD */
   3243        return s->rcer[3];
   3244    case 0x2a:	/* XCERC */
   3245        return s->xcer[2];
   3246    case 0x2c:	/* XCERD */
   3247        return s->xcer[3];
   3248    case 0x2e:	/* RCERE */
   3249        return s->rcer[4];
   3250    case 0x30:	/* RCERF */
   3251        return s->rcer[5];
   3252    case 0x32:	/* XCERE */
   3253        return s->xcer[4];
   3254    case 0x34:	/* XCERF */
   3255        return s->xcer[5];
   3256    case 0x36:	/* RCERG */
   3257        return s->rcer[6];
   3258    case 0x38:	/* RCERH */
   3259        return s->rcer[7];
   3260    case 0x3a:	/* XCERG */
   3261        return s->xcer[6];
   3262    case 0x3c:	/* XCERH */
   3263        return s->xcer[7];
   3264    }
   3265
   3266    OMAP_BAD_REG(addr);
   3267    return 0;
   3268}
   3269
   3270static void omap_mcbsp_writeh(void *opaque, hwaddr addr,
   3271                uint32_t value)
   3272{
   3273    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
   3274    int offset = addr & OMAP_MPUI_REG_MASK;
   3275
   3276    switch (offset) {
   3277    case 0x00:	/* DRR2 */
   3278    case 0x02:	/* DRR1 */
   3279        OMAP_RO_REG(addr);
   3280        return;
   3281
   3282    case 0x04:	/* DXR2 */
   3283        if (((s->xcr[0] >> 5) & 7) < 3)			/* XWDLEN1 */
   3284            return;
   3285        /* Fall through.  */
   3286    case 0x06:	/* DXR1 */
   3287        if (s->tx_req > 1) {
   3288            s->tx_req -= 2;
   3289            if (s->codec && s->codec->cts) {
   3290                s->codec->out.fifo[s->codec->out.len ++] = (value >> 8) & 0xff;
   3291                s->codec->out.fifo[s->codec->out.len ++] = (value >> 0) & 0xff;
   3292            }
   3293            if (s->tx_req < 2)
   3294                omap_mcbsp_tx_done(s);
   3295        } else
   3296            printf("%s: Tx FIFO overrun\n", __func__);
   3297        return;
   3298
   3299    case 0x08:	/* SPCR2 */
   3300        s->spcr[1] &= 0x0002;
   3301        s->spcr[1] |= 0x03f9 & value;
   3302        s->spcr[1] |= 0x0004 & (value << 2);		/* XEMPTY := XRST */
   3303        if (~value & 1)					/* XRST */
   3304            s->spcr[1] &= ~6;
   3305        omap_mcbsp_req_update(s);
   3306        return;
   3307    case 0x0a:	/* SPCR1 */
   3308        s->spcr[0] &= 0x0006;
   3309        s->spcr[0] |= 0xf8f9 & value;
   3310        if (value & (1 << 15))				/* DLB */
   3311            printf("%s: Digital Loopback mode enable attempt\n", __func__);
   3312        if (~value & 1) {				/* RRST */
   3313            s->spcr[0] &= ~6;
   3314            s->rx_req = 0;
   3315            omap_mcbsp_rx_done(s);
   3316        }
   3317        omap_mcbsp_req_update(s);
   3318        return;
   3319
   3320    case 0x0c:	/* RCR2 */
   3321        s->rcr[1] = value & 0xffff;
   3322        return;
   3323    case 0x0e:	/* RCR1 */
   3324        s->rcr[0] = value & 0x7fe0;
   3325        return;
   3326    case 0x10:	/* XCR2 */
   3327        s->xcr[1] = value & 0xffff;
   3328        return;
   3329    case 0x12:	/* XCR1 */
   3330        s->xcr[0] = value & 0x7fe0;
   3331        return;
   3332    case 0x14:	/* SRGR2 */
   3333        s->srgr[1] = value & 0xffff;
   3334        omap_mcbsp_req_update(s);
   3335        return;
   3336    case 0x16:	/* SRGR1 */
   3337        s->srgr[0] = value & 0xffff;
   3338        omap_mcbsp_req_update(s);
   3339        return;
   3340    case 0x18:	/* MCR2 */
   3341        s->mcr[1] = value & 0x03e3;
   3342        if (value & 3)					/* XMCM */
   3343            printf("%s: Tx channel selection mode enable attempt\n", __func__);
   3344        return;
   3345    case 0x1a:	/* MCR1 */
   3346        s->mcr[0] = value & 0x03e1;
   3347        if (value & 1)					/* RMCM */
   3348            printf("%s: Rx channel selection mode enable attempt\n", __func__);
   3349        return;
   3350    case 0x1c:	/* RCERA */
   3351        s->rcer[0] = value & 0xffff;
   3352        return;
   3353    case 0x1e:	/* RCERB */
   3354        s->rcer[1] = value & 0xffff;
   3355        return;
   3356    case 0x20:	/* XCERA */
   3357        s->xcer[0] = value & 0xffff;
   3358        return;
   3359    case 0x22:	/* XCERB */
   3360        s->xcer[1] = value & 0xffff;
   3361        return;
   3362    case 0x24:	/* PCR0 */
   3363        s->pcr = value & 0x7faf;
   3364        return;
   3365    case 0x26:	/* RCERC */
   3366        s->rcer[2] = value & 0xffff;
   3367        return;
   3368    case 0x28:	/* RCERD */
   3369        s->rcer[3] = value & 0xffff;
   3370        return;
   3371    case 0x2a:	/* XCERC */
   3372        s->xcer[2] = value & 0xffff;
   3373        return;
   3374    case 0x2c:	/* XCERD */
   3375        s->xcer[3] = value & 0xffff;
   3376        return;
   3377    case 0x2e:	/* RCERE */
   3378        s->rcer[4] = value & 0xffff;
   3379        return;
   3380    case 0x30:	/* RCERF */
   3381        s->rcer[5] = value & 0xffff;
   3382        return;
   3383    case 0x32:	/* XCERE */
   3384        s->xcer[4] = value & 0xffff;
   3385        return;
   3386    case 0x34:	/* XCERF */
   3387        s->xcer[5] = value & 0xffff;
   3388        return;
   3389    case 0x36:	/* RCERG */
   3390        s->rcer[6] = value & 0xffff;
   3391        return;
   3392    case 0x38:	/* RCERH */
   3393        s->rcer[7] = value & 0xffff;
   3394        return;
   3395    case 0x3a:	/* XCERG */
   3396        s->xcer[6] = value & 0xffff;
   3397        return;
   3398    case 0x3c:	/* XCERH */
   3399        s->xcer[7] = value & 0xffff;
   3400        return;
   3401    }
   3402
   3403    OMAP_BAD_REG(addr);
   3404}
   3405
   3406static void omap_mcbsp_writew(void *opaque, hwaddr addr,
   3407                uint32_t value)
   3408{
   3409    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
   3410    int offset = addr & OMAP_MPUI_REG_MASK;
   3411
   3412    if (offset == 0x04) {				/* DXR */
   3413        if (((s->xcr[0] >> 5) & 7) < 3)			/* XWDLEN1 */
   3414            return;
   3415        if (s->tx_req > 3) {
   3416            s->tx_req -= 4;
   3417            if (s->codec && s->codec->cts) {
   3418                s->codec->out.fifo[s->codec->out.len ++] =
   3419                        (value >> 24) & 0xff;
   3420                s->codec->out.fifo[s->codec->out.len ++] =
   3421                        (value >> 16) & 0xff;
   3422                s->codec->out.fifo[s->codec->out.len ++] =
   3423                        (value >> 8) & 0xff;
   3424                s->codec->out.fifo[s->codec->out.len ++] =
   3425                        (value >> 0) & 0xff;
   3426            }
   3427            if (s->tx_req < 4)
   3428                omap_mcbsp_tx_done(s);
   3429        } else
   3430            printf("%s: Tx FIFO overrun\n", __func__);
   3431        return;
   3432    }
   3433
   3434    omap_badwidth_write16(opaque, addr, value);
   3435}
   3436
   3437static void omap_mcbsp_write(void *opaque, hwaddr addr,
   3438                             uint64_t value, unsigned size)
   3439{
   3440    switch (size) {
   3441    case 2:
   3442        omap_mcbsp_writeh(opaque, addr, value);
   3443        break;
   3444    case 4:
   3445        omap_mcbsp_writew(opaque, addr, value);
   3446        break;
   3447    default:
   3448        omap_badwidth_write16(opaque, addr, value);
   3449    }
   3450}
   3451
   3452static const MemoryRegionOps omap_mcbsp_ops = {
   3453    .read = omap_mcbsp_read,
   3454    .write = omap_mcbsp_write,
   3455    .endianness = DEVICE_NATIVE_ENDIAN,
   3456};
   3457
   3458static void omap_mcbsp_reset(struct omap_mcbsp_s *s)
   3459{
   3460    memset(&s->spcr, 0, sizeof(s->spcr));
   3461    memset(&s->rcr, 0, sizeof(s->rcr));
   3462    memset(&s->xcr, 0, sizeof(s->xcr));
   3463    s->srgr[0] = 0x0001;
   3464    s->srgr[1] = 0x2000;
   3465    memset(&s->mcr, 0, sizeof(s->mcr));
   3466    memset(&s->pcr, 0, sizeof(s->pcr));
   3467    memset(&s->rcer, 0, sizeof(s->rcer));
   3468    memset(&s->xcer, 0, sizeof(s->xcer));
   3469    s->tx_req = 0;
   3470    s->rx_req = 0;
   3471    s->tx_rate = 0;
   3472    s->rx_rate = 0;
   3473    timer_del(s->source_timer);
   3474    timer_del(s->sink_timer);
   3475}
   3476
   3477static struct omap_mcbsp_s *omap_mcbsp_init(MemoryRegion *system_memory,
   3478                                            hwaddr base,
   3479                                            qemu_irq txirq, qemu_irq rxirq,
   3480                                            qemu_irq *dma, omap_clk clk)
   3481{
   3482    struct omap_mcbsp_s *s = g_new0(struct omap_mcbsp_s, 1);
   3483
   3484    s->txirq = txirq;
   3485    s->rxirq = rxirq;
   3486    s->txdrq = dma[0];
   3487    s->rxdrq = dma[1];
   3488    s->sink_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_mcbsp_sink_tick, s);
   3489    s->source_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_mcbsp_source_tick, s);
   3490    omap_mcbsp_reset(s);
   3491
   3492    memory_region_init_io(&s->iomem, NULL, &omap_mcbsp_ops, s, "omap-mcbsp", 0x800);
   3493    memory_region_add_subregion(system_memory, base, &s->iomem);
   3494
   3495    return s;
   3496}
   3497
   3498static void omap_mcbsp_i2s_swallow(void *opaque, int line, int level)
   3499{
   3500    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
   3501
   3502    if (s->rx_rate) {
   3503        s->rx_req = s->codec->in.len;
   3504        omap_mcbsp_rx_newdata(s);
   3505    }
   3506}
   3507
   3508static void omap_mcbsp_i2s_start(void *opaque, int line, int level)
   3509{
   3510    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
   3511
   3512    if (s->tx_rate) {
   3513        s->tx_req = s->codec->out.size;
   3514        omap_mcbsp_tx_newdata(s);
   3515    }
   3516}
   3517
   3518void omap_mcbsp_i2s_attach(struct omap_mcbsp_s *s, I2SCodec *slave)
   3519{
   3520    s->codec = slave;
   3521    slave->rx_swallow = qemu_allocate_irq(omap_mcbsp_i2s_swallow, s, 0);
   3522    slave->tx_start = qemu_allocate_irq(omap_mcbsp_i2s_start, s, 0);
   3523}
   3524
   3525/* LED Pulse Generators */
   3526struct omap_lpg_s {
   3527    MemoryRegion iomem;
   3528    QEMUTimer *tm;
   3529
   3530    uint8_t control;
   3531    uint8_t power;
   3532    int64_t on;
   3533    int64_t period;
   3534    int clk;
   3535    int cycle;
   3536};
   3537
   3538static void omap_lpg_tick(void *opaque)
   3539{
   3540    struct omap_lpg_s *s = opaque;
   3541
   3542    if (s->cycle)
   3543        timer_mod(s->tm, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + s->period - s->on);
   3544    else
   3545        timer_mod(s->tm, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + s->on);
   3546
   3547    s->cycle = !s->cycle;
   3548    printf("%s: LED is %s\n", __func__, s->cycle ? "on" : "off");
   3549}
   3550
   3551static void omap_lpg_update(struct omap_lpg_s *s)
   3552{
   3553    int64_t on, period = 1, ticks = 1000;
   3554    static const int per[8] = { 1, 2, 4, 8, 12, 16, 20, 24 };
   3555
   3556    if (~s->control & (1 << 6))					/* LPGRES */
   3557        on = 0;
   3558    else if (s->control & (1 << 7))				/* PERM_ON */
   3559        on = period;
   3560    else {
   3561        period = muldiv64(ticks, per[s->control & 7],		/* PERCTRL */
   3562                        256 / 32);
   3563        on = (s->clk && s->power) ? muldiv64(ticks,
   3564                        per[(s->control >> 3) & 7], 256) : 0;	/* ONCTRL */
   3565    }
   3566
   3567    timer_del(s->tm);
   3568    if (on == period && s->on < s->period)
   3569        printf("%s: LED is on\n", __func__);
   3570    else if (on == 0 && s->on)
   3571        printf("%s: LED is off\n", __func__);
   3572    else if (on && (on != s->on || period != s->period)) {
   3573        s->cycle = 0;
   3574        s->on = on;
   3575        s->period = period;
   3576        omap_lpg_tick(s);
   3577        return;
   3578    }
   3579
   3580    s->on = on;
   3581    s->period = period;
   3582}
   3583
   3584static void omap_lpg_reset(struct omap_lpg_s *s)
   3585{
   3586    s->control = 0x00;
   3587    s->power = 0x00;
   3588    s->clk = 1;
   3589    omap_lpg_update(s);
   3590}
   3591
   3592static uint64_t omap_lpg_read(void *opaque, hwaddr addr,
   3593                              unsigned size)
   3594{
   3595    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
   3596    int offset = addr & OMAP_MPUI_REG_MASK;
   3597
   3598    if (size != 1) {
   3599        return omap_badwidth_read8(opaque, addr);
   3600    }
   3601
   3602    switch (offset) {
   3603    case 0x00:	/* LCR */
   3604        return s->control;
   3605
   3606    case 0x04:	/* PMR */
   3607        return s->power;
   3608    }
   3609
   3610    OMAP_BAD_REG(addr);
   3611    return 0;
   3612}
   3613
   3614static void omap_lpg_write(void *opaque, hwaddr addr,
   3615                           uint64_t value, unsigned size)
   3616{
   3617    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
   3618    int offset = addr & OMAP_MPUI_REG_MASK;
   3619
   3620    if (size != 1) {
   3621        omap_badwidth_write8(opaque, addr, value);
   3622        return;
   3623    }
   3624
   3625    switch (offset) {
   3626    case 0x00:	/* LCR */
   3627        if (~value & (1 << 6))					/* LPGRES */
   3628            omap_lpg_reset(s);
   3629        s->control = value & 0xff;
   3630        omap_lpg_update(s);
   3631        return;
   3632
   3633    case 0x04:	/* PMR */
   3634        s->power = value & 0x01;
   3635        omap_lpg_update(s);
   3636        return;
   3637
   3638    default:
   3639        OMAP_BAD_REG(addr);
   3640        return;
   3641    }
   3642}
   3643
   3644static const MemoryRegionOps omap_lpg_ops = {
   3645    .read = omap_lpg_read,
   3646    .write = omap_lpg_write,
   3647    .endianness = DEVICE_NATIVE_ENDIAN,
   3648};
   3649
   3650static void omap_lpg_clk_update(void *opaque, int line, int on)
   3651{
   3652    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
   3653
   3654    s->clk = on;
   3655    omap_lpg_update(s);
   3656}
   3657
   3658static struct omap_lpg_s *omap_lpg_init(MemoryRegion *system_memory,
   3659                                        hwaddr base, omap_clk clk)
   3660{
   3661    struct omap_lpg_s *s = g_new0(struct omap_lpg_s, 1);
   3662
   3663    s->tm = timer_new_ms(QEMU_CLOCK_VIRTUAL, omap_lpg_tick, s);
   3664
   3665    omap_lpg_reset(s);
   3666
   3667    memory_region_init_io(&s->iomem, NULL, &omap_lpg_ops, s, "omap-lpg", 0x800);
   3668    memory_region_add_subregion(system_memory, base, &s->iomem);
   3669
   3670    omap_clk_adduser(clk, qemu_allocate_irq(omap_lpg_clk_update, s, 0));
   3671
   3672    return s;
   3673}
   3674
   3675/* MPUI Peripheral Bridge configuration */
   3676static uint64_t omap_mpui_io_read(void *opaque, hwaddr addr,
   3677                                  unsigned size)
   3678{
   3679    if (size != 2) {
   3680        return omap_badwidth_read16(opaque, addr);
   3681    }
   3682
   3683    if (addr == OMAP_MPUI_BASE)	/* CMR */
   3684        return 0xfe4d;
   3685
   3686    OMAP_BAD_REG(addr);
   3687    return 0;
   3688}
   3689
   3690static void omap_mpui_io_write(void *opaque, hwaddr addr,
   3691                               uint64_t value, unsigned size)
   3692{
   3693    /* FIXME: infinite loop */
   3694    omap_badwidth_write16(opaque, addr, value);
   3695}
   3696
   3697static const MemoryRegionOps omap_mpui_io_ops = {
   3698    .read = omap_mpui_io_read,
   3699    .write = omap_mpui_io_write,
   3700    .endianness = DEVICE_NATIVE_ENDIAN,
   3701};
   3702
   3703static void omap_setup_mpui_io(MemoryRegion *system_memory,
   3704                               struct omap_mpu_state_s *mpu)
   3705{
   3706    memory_region_init_io(&mpu->mpui_io_iomem, NULL, &omap_mpui_io_ops, mpu,
   3707                          "omap-mpui-io", 0x7fff);
   3708    memory_region_add_subregion(system_memory, OMAP_MPUI_BASE,
   3709                                &mpu->mpui_io_iomem);
   3710}
   3711
   3712/* General chip reset */
   3713static void omap1_mpu_reset(void *opaque)
   3714{
   3715    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
   3716
   3717    omap_dma_reset(mpu->dma);
   3718    omap_mpu_timer_reset(mpu->timer[0]);
   3719    omap_mpu_timer_reset(mpu->timer[1]);
   3720    omap_mpu_timer_reset(mpu->timer[2]);
   3721    omap_wd_timer_reset(mpu->wdt);
   3722    omap_os_timer_reset(mpu->os_timer);
   3723    omap_lcdc_reset(mpu->lcd);
   3724    omap_ulpd_pm_reset(mpu);
   3725    omap_pin_cfg_reset(mpu);
   3726    omap_mpui_reset(mpu);
   3727    omap_tipb_bridge_reset(mpu->private_tipb);
   3728    omap_tipb_bridge_reset(mpu->public_tipb);
   3729    omap_dpll_reset(mpu->dpll[0]);
   3730    omap_dpll_reset(mpu->dpll[1]);
   3731    omap_dpll_reset(mpu->dpll[2]);
   3732    omap_uart_reset(mpu->uart[0]);
   3733    omap_uart_reset(mpu->uart[1]);
   3734    omap_uart_reset(mpu->uart[2]);
   3735    omap_mmc_reset(mpu->mmc);
   3736    omap_mpuio_reset(mpu->mpuio);
   3737    omap_uwire_reset(mpu->microwire);
   3738    omap_pwl_reset(mpu->pwl);
   3739    omap_pwt_reset(mpu->pwt);
   3740    omap_rtc_reset(mpu->rtc);
   3741    omap_mcbsp_reset(mpu->mcbsp1);
   3742    omap_mcbsp_reset(mpu->mcbsp2);
   3743    omap_mcbsp_reset(mpu->mcbsp3);
   3744    omap_lpg_reset(mpu->led[0]);
   3745    omap_lpg_reset(mpu->led[1]);
   3746    omap_clkm_reset(mpu);
   3747    cpu_reset(CPU(mpu->cpu));
   3748}
   3749
   3750static const struct omap_map_s {
   3751    hwaddr phys_dsp;
   3752    hwaddr phys_mpu;
   3753    uint32_t size;
   3754    const char *name;
   3755} omap15xx_dsp_mm[] = {
   3756    /* Strobe 0 */
   3757    { 0xe1010000, 0xfffb0000, 0x800, "UART1 BT" },		/* CS0 */
   3758    { 0xe1010800, 0xfffb0800, 0x800, "UART2 COM" },		/* CS1 */
   3759    { 0xe1011800, 0xfffb1800, 0x800, "McBSP1 audio" },		/* CS3 */
   3760    { 0xe1012000, 0xfffb2000, 0x800, "MCSI2 communication" },	/* CS4 */
   3761    { 0xe1012800, 0xfffb2800, 0x800, "MCSI1 BT u-Law" },	/* CS5 */
   3762    { 0xe1013000, 0xfffb3000, 0x800, "uWire" },			/* CS6 */
   3763    { 0xe1013800, 0xfffb3800, 0x800, "I^2C" },			/* CS7 */
   3764    { 0xe1014000, 0xfffb4000, 0x800, "USB W2FC" },		/* CS8 */
   3765    { 0xe1014800, 0xfffb4800, 0x800, "RTC" },			/* CS9 */
   3766    { 0xe1015000, 0xfffb5000, 0x800, "MPUIO" },			/* CS10 */
   3767    { 0xe1015800, 0xfffb5800, 0x800, "PWL" },			/* CS11 */
   3768    { 0xe1016000, 0xfffb6000, 0x800, "PWT" },			/* CS12 */
   3769    { 0xe1017000, 0xfffb7000, 0x800, "McBSP3" },		/* CS14 */
   3770    { 0xe1017800, 0xfffb7800, 0x800, "MMC" },			/* CS15 */
   3771    { 0xe1019000, 0xfffb9000, 0x800, "32-kHz timer" },		/* CS18 */
   3772    { 0xe1019800, 0xfffb9800, 0x800, "UART3" },			/* CS19 */
   3773    { 0xe101c800, 0xfffbc800, 0x800, "TIPB switches" },		/* CS25 */
   3774    /* Strobe 1 */
   3775    { 0xe101e000, 0xfffce000, 0x800, "GPIOs" },			/* CS28 */
   3776
   3777    { 0 }
   3778};
   3779
   3780static void omap_setup_dsp_mapping(MemoryRegion *system_memory,
   3781                                   const struct omap_map_s *map)
   3782{
   3783    MemoryRegion *io;
   3784
   3785    for (; map->phys_dsp; map ++) {
   3786        io = g_new(MemoryRegion, 1);
   3787        memory_region_init_alias(io, NULL, map->name,
   3788                                 system_memory, map->phys_mpu, map->size);
   3789        memory_region_add_subregion(system_memory, map->phys_dsp, io);
   3790    }
   3791}
   3792
   3793void omap_mpu_wakeup(void *opaque, int irq, int req)
   3794{
   3795    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
   3796    CPUState *cpu = CPU(mpu->cpu);
   3797
   3798    if (cpu->halted) {
   3799        cpu_interrupt(cpu, CPU_INTERRUPT_EXITTB);
   3800    }
   3801}
   3802
   3803static const struct dma_irq_map omap1_dma_irq_map[] = {
   3804    { 0, OMAP_INT_DMA_CH0_6 },
   3805    { 0, OMAP_INT_DMA_CH1_7 },
   3806    { 0, OMAP_INT_DMA_CH2_8 },
   3807    { 0, OMAP_INT_DMA_CH3 },
   3808    { 0, OMAP_INT_DMA_CH4 },
   3809    { 0, OMAP_INT_DMA_CH5 },
   3810    { 1, OMAP_INT_1610_DMA_CH6 },
   3811    { 1, OMAP_INT_1610_DMA_CH7 },
   3812    { 1, OMAP_INT_1610_DMA_CH8 },
   3813    { 1, OMAP_INT_1610_DMA_CH9 },
   3814    { 1, OMAP_INT_1610_DMA_CH10 },
   3815    { 1, OMAP_INT_1610_DMA_CH11 },
   3816    { 1, OMAP_INT_1610_DMA_CH12 },
   3817    { 1, OMAP_INT_1610_DMA_CH13 },
   3818    { 1, OMAP_INT_1610_DMA_CH14 },
   3819    { 1, OMAP_INT_1610_DMA_CH15 }
   3820};
   3821
   3822/* DMA ports for OMAP1 */
   3823static int omap_validate_emiff_addr(struct omap_mpu_state_s *s,
   3824                hwaddr addr)
   3825{
   3826    return range_covers_byte(OMAP_EMIFF_BASE, s->sdram_size, addr);
   3827}
   3828
   3829static int omap_validate_emifs_addr(struct omap_mpu_state_s *s,
   3830                hwaddr addr)
   3831{
   3832    return range_covers_byte(OMAP_EMIFS_BASE, OMAP_EMIFF_BASE - OMAP_EMIFS_BASE,
   3833                             addr);
   3834}
   3835
   3836static int omap_validate_imif_addr(struct omap_mpu_state_s *s,
   3837                hwaddr addr)
   3838{
   3839    return range_covers_byte(OMAP_IMIF_BASE, s->sram_size, addr);
   3840}
   3841
   3842static int omap_validate_tipb_addr(struct omap_mpu_state_s *s,
   3843                hwaddr addr)
   3844{
   3845    return range_covers_byte(0xfffb0000, 0xffff0000 - 0xfffb0000, addr);
   3846}
   3847
   3848static int omap_validate_local_addr(struct omap_mpu_state_s *s,
   3849                hwaddr addr)
   3850{
   3851    return range_covers_byte(OMAP_LOCALBUS_BASE, 0x1000000, addr);
   3852}
   3853
   3854static int omap_validate_tipb_mpui_addr(struct omap_mpu_state_s *s,
   3855                hwaddr addr)
   3856{
   3857    return range_covers_byte(0xe1010000, 0xe1020004 - 0xe1010000, addr);
   3858}
   3859
   3860struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *dram,
   3861                const char *cpu_type)
   3862{
   3863    int i;
   3864    struct omap_mpu_state_s *s = g_new0(struct omap_mpu_state_s, 1);
   3865    qemu_irq dma_irqs[6];
   3866    DriveInfo *dinfo;
   3867    SysBusDevice *busdev;
   3868    MemoryRegion *system_memory = get_system_memory();
   3869
   3870    /* Core */
   3871    s->mpu_model = omap310;
   3872    s->cpu = ARM_CPU(cpu_create(cpu_type));
   3873    s->sdram_size = memory_region_size(dram);
   3874    s->sram_size = OMAP15XX_SRAM_SIZE;
   3875
   3876    s->wakeup = qemu_allocate_irq(omap_mpu_wakeup, s, 0);
   3877
   3878    /* Clocks */
   3879    omap_clk_init(s);
   3880
   3881    /* Memory-mapped stuff */
   3882    memory_region_init_ram(&s->imif_ram, NULL, "omap1.sram", s->sram_size,
   3883                           &error_fatal);
   3884    memory_region_add_subregion(system_memory, OMAP_IMIF_BASE, &s->imif_ram);
   3885
   3886    omap_clkm_init(system_memory, 0xfffece00, 0xe1008000, s);
   3887
   3888    s->ih[0] = qdev_new("omap-intc");
   3889    qdev_prop_set_uint32(s->ih[0], "size", 0x100);
   3890    omap_intc_set_iclk(OMAP_INTC(s->ih[0]), omap_findclk(s, "arminth_ck"));
   3891    busdev = SYS_BUS_DEVICE(s->ih[0]);
   3892    sysbus_realize_and_unref(busdev, &error_fatal);
   3893    sysbus_connect_irq(busdev, 0,
   3894                       qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ));
   3895    sysbus_connect_irq(busdev, 1,
   3896                       qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_FIQ));
   3897    sysbus_mmio_map(busdev, 0, 0xfffecb00);
   3898    s->ih[1] = qdev_new("omap-intc");
   3899    qdev_prop_set_uint32(s->ih[1], "size", 0x800);
   3900    omap_intc_set_iclk(OMAP_INTC(s->ih[1]), omap_findclk(s, "arminth_ck"));
   3901    busdev = SYS_BUS_DEVICE(s->ih[1]);
   3902    sysbus_realize_and_unref(busdev, &error_fatal);
   3903    sysbus_connect_irq(busdev, 0,
   3904                       qdev_get_gpio_in(s->ih[0], OMAP_INT_15XX_IH2_IRQ));
   3905    /* The second interrupt controller's FIQ output is not wired up */
   3906    sysbus_mmio_map(busdev, 0, 0xfffe0000);
   3907
   3908    for (i = 0; i < 6; i++) {
   3909        dma_irqs[i] = qdev_get_gpio_in(s->ih[omap1_dma_irq_map[i].ih],
   3910                                       omap1_dma_irq_map[i].intr);
   3911    }
   3912    s->dma = omap_dma_init(0xfffed800, dma_irqs, system_memory,
   3913                           qdev_get_gpio_in(s->ih[0], OMAP_INT_DMA_LCD),
   3914                           s, omap_findclk(s, "dma_ck"), omap_dma_3_1);
   3915
   3916    s->port[emiff    ].addr_valid = omap_validate_emiff_addr;
   3917    s->port[emifs    ].addr_valid = omap_validate_emifs_addr;
   3918    s->port[imif     ].addr_valid = omap_validate_imif_addr;
   3919    s->port[tipb     ].addr_valid = omap_validate_tipb_addr;
   3920    s->port[local    ].addr_valid = omap_validate_local_addr;
   3921    s->port[tipb_mpui].addr_valid = omap_validate_tipb_mpui_addr;
   3922
   3923    /* Register SDRAM and SRAM DMA ports for fast transfers.  */
   3924    soc_dma_port_add_mem(s->dma, memory_region_get_ram_ptr(dram),
   3925                         OMAP_EMIFF_BASE, s->sdram_size);
   3926    soc_dma_port_add_mem(s->dma, memory_region_get_ram_ptr(&s->imif_ram),
   3927                         OMAP_IMIF_BASE, s->sram_size);
   3928
   3929    s->timer[0] = omap_mpu_timer_init(system_memory, 0xfffec500,
   3930                    qdev_get_gpio_in(s->ih[0], OMAP_INT_TIMER1),
   3931                    omap_findclk(s, "mputim_ck"));
   3932    s->timer[1] = omap_mpu_timer_init(system_memory, 0xfffec600,
   3933                    qdev_get_gpio_in(s->ih[0], OMAP_INT_TIMER2),
   3934                    omap_findclk(s, "mputim_ck"));
   3935    s->timer[2] = omap_mpu_timer_init(system_memory, 0xfffec700,
   3936                    qdev_get_gpio_in(s->ih[0], OMAP_INT_TIMER3),
   3937                    omap_findclk(s, "mputim_ck"));
   3938
   3939    s->wdt = omap_wd_timer_init(system_memory, 0xfffec800,
   3940                    qdev_get_gpio_in(s->ih[0], OMAP_INT_WD_TIMER),
   3941                    omap_findclk(s, "armwdt_ck"));
   3942
   3943    s->os_timer = omap_os_timer_init(system_memory, 0xfffb9000,
   3944                    qdev_get_gpio_in(s->ih[1], OMAP_INT_OS_TIMER),
   3945                    omap_findclk(s, "clk32-kHz"));
   3946
   3947    s->lcd = omap_lcdc_init(system_memory, 0xfffec000,
   3948                            qdev_get_gpio_in(s->ih[0], OMAP_INT_LCD_CTRL),
   3949                            omap_dma_get_lcdch(s->dma),
   3950                            omap_findclk(s, "lcd_ck"));
   3951
   3952    omap_ulpd_pm_init(system_memory, 0xfffe0800, s);
   3953    omap_pin_cfg_init(system_memory, 0xfffe1000, s);
   3954    omap_id_init(system_memory, s);
   3955
   3956    omap_mpui_init(system_memory, 0xfffec900, s);
   3957
   3958    s->private_tipb = omap_tipb_bridge_init(system_memory, 0xfffeca00,
   3959                    qdev_get_gpio_in(s->ih[0], OMAP_INT_BRIDGE_PRIV),
   3960                    omap_findclk(s, "tipb_ck"));
   3961    s->public_tipb = omap_tipb_bridge_init(system_memory, 0xfffed300,
   3962                    qdev_get_gpio_in(s->ih[0], OMAP_INT_BRIDGE_PUB),
   3963                    omap_findclk(s, "tipb_ck"));
   3964
   3965    omap_tcmi_init(system_memory, 0xfffecc00, s);
   3966
   3967    s->uart[0] = omap_uart_init(0xfffb0000,
   3968                                qdev_get_gpio_in(s->ih[1], OMAP_INT_UART1),
   3969                    omap_findclk(s, "uart1_ck"),
   3970                    omap_findclk(s, "uart1_ck"),
   3971                    s->drq[OMAP_DMA_UART1_TX], s->drq[OMAP_DMA_UART1_RX],
   3972                    "uart1",
   3973                    serial_hd(0));
   3974    s->uart[1] = omap_uart_init(0xfffb0800,
   3975                                qdev_get_gpio_in(s->ih[1], OMAP_INT_UART2),
   3976                    omap_findclk(s, "uart2_ck"),
   3977                    omap_findclk(s, "uart2_ck"),
   3978                    s->drq[OMAP_DMA_UART2_TX], s->drq[OMAP_DMA_UART2_RX],
   3979                    "uart2",
   3980                    serial_hd(0) ? serial_hd(1) : NULL);
   3981    s->uart[2] = omap_uart_init(0xfffb9800,
   3982                                qdev_get_gpio_in(s->ih[0], OMAP_INT_UART3),
   3983                    omap_findclk(s, "uart3_ck"),
   3984                    omap_findclk(s, "uart3_ck"),
   3985                    s->drq[OMAP_DMA_UART3_TX], s->drq[OMAP_DMA_UART3_RX],
   3986                    "uart3",
   3987                    serial_hd(0) && serial_hd(1) ? serial_hd(2) : NULL);
   3988
   3989    s->dpll[0] = omap_dpll_init(system_memory, 0xfffecf00,
   3990                                omap_findclk(s, "dpll1"));
   3991    s->dpll[1] = omap_dpll_init(system_memory, 0xfffed000,
   3992                                omap_findclk(s, "dpll2"));
   3993    s->dpll[2] = omap_dpll_init(system_memory, 0xfffed100,
   3994                                omap_findclk(s, "dpll3"));
   3995
   3996    dinfo = drive_get(IF_SD, 0, 0);
   3997    if (!dinfo && !qtest_enabled()) {
   3998        warn_report("missing SecureDigital device");
   3999    }
   4000    s->mmc = omap_mmc_init(0xfffb7800, system_memory,
   4001                           dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
   4002                           qdev_get_gpio_in(s->ih[1], OMAP_INT_OQN),
   4003                           &s->drq[OMAP_DMA_MMC_TX],
   4004                    omap_findclk(s, "mmc_ck"));
   4005
   4006    s->mpuio = omap_mpuio_init(system_memory, 0xfffb5000,
   4007                               qdev_get_gpio_in(s->ih[1], OMAP_INT_KEYBOARD),
   4008                               qdev_get_gpio_in(s->ih[1], OMAP_INT_MPUIO),
   4009                               s->wakeup, omap_findclk(s, "clk32-kHz"));
   4010
   4011    s->gpio = qdev_new("omap-gpio");
   4012    qdev_prop_set_int32(s->gpio, "mpu_model", s->mpu_model);
   4013    omap_gpio_set_clk(OMAP1_GPIO(s->gpio), omap_findclk(s, "arm_gpio_ck"));
   4014    sysbus_realize_and_unref(SYS_BUS_DEVICE(s->gpio), &error_fatal);
   4015    sysbus_connect_irq(SYS_BUS_DEVICE(s->gpio), 0,
   4016                       qdev_get_gpio_in(s->ih[0], OMAP_INT_GPIO_BANK1));
   4017    sysbus_mmio_map(SYS_BUS_DEVICE(s->gpio), 0, 0xfffce000);
   4018
   4019    s->microwire = omap_uwire_init(system_memory, 0xfffb3000,
   4020                                   qdev_get_gpio_in(s->ih[1], OMAP_INT_uWireTX),
   4021                                   qdev_get_gpio_in(s->ih[1], OMAP_INT_uWireRX),
   4022                    s->drq[OMAP_DMA_UWIRE_TX], omap_findclk(s, "mpuper_ck"));
   4023
   4024    s->pwl = omap_pwl_init(system_memory, 0xfffb5800,
   4025                           omap_findclk(s, "armxor_ck"));
   4026    s->pwt = omap_pwt_init(system_memory, 0xfffb6000,
   4027                           omap_findclk(s, "armxor_ck"));
   4028
   4029    s->i2c[0] = qdev_new("omap_i2c");
   4030    qdev_prop_set_uint8(s->i2c[0], "revision", 0x11);
   4031    omap_i2c_set_fclk(OMAP_I2C(s->i2c[0]), omap_findclk(s, "mpuper_ck"));
   4032    busdev = SYS_BUS_DEVICE(s->i2c[0]);
   4033    sysbus_realize_and_unref(busdev, &error_fatal);
   4034    sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(s->ih[1], OMAP_INT_I2C));
   4035    sysbus_connect_irq(busdev, 1, s->drq[OMAP_DMA_I2C_TX]);
   4036    sysbus_connect_irq(busdev, 2, s->drq[OMAP_DMA_I2C_RX]);
   4037    sysbus_mmio_map(busdev, 0, 0xfffb3800);
   4038
   4039    s->rtc = omap_rtc_init(system_memory, 0xfffb4800,
   4040                           qdev_get_gpio_in(s->ih[1], OMAP_INT_RTC_TIMER),
   4041                           qdev_get_gpio_in(s->ih[1], OMAP_INT_RTC_ALARM),
   4042                    omap_findclk(s, "clk32-kHz"));
   4043
   4044    s->mcbsp1 = omap_mcbsp_init(system_memory, 0xfffb1800,
   4045                                qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP1TX),
   4046                                qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP1RX),
   4047                    &s->drq[OMAP_DMA_MCBSP1_TX], omap_findclk(s, "dspxor_ck"));
   4048    s->mcbsp2 = omap_mcbsp_init(system_memory, 0xfffb1000,
   4049                                qdev_get_gpio_in(s->ih[0],
   4050                                                 OMAP_INT_310_McBSP2_TX),
   4051                                qdev_get_gpio_in(s->ih[0],
   4052                                                 OMAP_INT_310_McBSP2_RX),
   4053                    &s->drq[OMAP_DMA_MCBSP2_TX], omap_findclk(s, "mpuper_ck"));
   4054    s->mcbsp3 = omap_mcbsp_init(system_memory, 0xfffb7000,
   4055                                qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP3TX),
   4056                                qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP3RX),
   4057                    &s->drq[OMAP_DMA_MCBSP3_TX], omap_findclk(s, "dspxor_ck"));
   4058
   4059    s->led[0] = omap_lpg_init(system_memory,
   4060                              0xfffbd000, omap_findclk(s, "clk32-kHz"));
   4061    s->led[1] = omap_lpg_init(system_memory,
   4062                              0xfffbd800, omap_findclk(s, "clk32-kHz"));
   4063
   4064    /* Register mappings not currenlty implemented:
   4065     * MCSI2 Comm	fffb2000 - fffb27ff (not mapped on OMAP310)
   4066     * MCSI1 Bluetooth	fffb2800 - fffb2fff (not mapped on OMAP310)
   4067     * USB W2FC		fffb4000 - fffb47ff
   4068     * Camera Interface	fffb6800 - fffb6fff
   4069     * USB Host		fffba000 - fffba7ff
   4070     * FAC		fffba800 - fffbafff
   4071     * HDQ/1-Wire	fffbc000 - fffbc7ff
   4072     * TIPB switches	fffbc800 - fffbcfff
   4073     * Mailbox		fffcf000 - fffcf7ff
   4074     * Local bus IF	fffec100 - fffec1ff
   4075     * Local bus MMU	fffec200 - fffec2ff
   4076     * DSP MMU		fffed200 - fffed2ff
   4077     */
   4078
   4079    omap_setup_dsp_mapping(system_memory, omap15xx_dsp_mm);
   4080    omap_setup_mpui_io(system_memory, s);
   4081
   4082    qemu_register_reset(omap1_mpu_reset, s);
   4083
   4084    return s;
   4085}