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