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