* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "hw.h"
#include "arm-misc.h"
struct omap_intr_handler_s {
qemu_irq *pins;
qemu_irq parent_intr[2];
- target_phys_addr_t base;
unsigned char nbanks;
int level_only;
static uint32_t omap_inth_read(void *opaque, target_phys_addr_t addr)
{
struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
- int i, offset = addr - s->base;
+ int i, offset = addr;
int bank_no = offset >> 8;
int line_no;
struct omap_intr_handler_bank_s *bank = &s->bank[bank_no];
uint32_t value)
{
struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
- int i, offset = addr - s->base;
+ int i, offset = addr;
int bank_no = offset >> 8;
struct omap_intr_handler_bank_s *bank = &s->bank[bank_no];
offset &= 0xff;
s->parent_intr[0] = parent_irq;
s->parent_intr[1] = parent_fiq;
- s->base = base;
s->nbanks = nbanks;
s->pins = qemu_allocate_irqs(omap_set_intr, s, nbanks * 32);
if (pins)
iomemtype = cpu_register_io_memory(0, omap_inth_readfn,
omap_inth_writefn, s);
- cpu_register_physical_memory(s->base, size, iomemtype);
+ cpu_register_physical_memory(base, size, iomemtype);
return s;
}
static uint32_t omap2_inth_read(void *opaque, target_phys_addr_t addr)
{
struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
- int offset = addr - s->base;
+ int offset = addr;
int bank_no, line_no;
struct omap_intr_handler_bank_s *bank = 0;
uint32_t value)
{
struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
- int offset = addr - s->base;
+ int offset = addr;
int bank_no, line_no;
struct omap_intr_handler_bank_s *bank = 0;
s->parent_intr[0] = parent_irq;
s->parent_intr[1] = parent_fiq;
- s->base = base;
s->nbanks = nbanks;
s->level_only = 1;
s->pins = qemu_allocate_irqs(omap_set_intr_noedge, s, nbanks * 32);
iomemtype = cpu_register_io_memory(0, omap2_inth_readfn,
omap2_inth_writefn, s);
- cpu_register_physical_memory(s->base, size, iomemtype);
+ cpu_register_physical_memory(base, size, iomemtype);
return s;
}
struct omap_mpu_timer_s {
qemu_irq irq;
omap_clk clk;
- target_phys_addr_t base;
uint32_t val;
int64_t time;
QEMUTimer *timer;
+ QEMUBH *tick;
int64_t rate;
int it_ena;
* ticks. */
if (expires > (ticks_per_sec >> 10) || timer->ar)
qemu_mod_timer(timer->timer, timer->time + expires);
- else {
- timer->val = 0;
- timer->st = 0;
- if (timer->it_ena)
- /* Edge-triggered irq */
- qemu_irq_pulse(timer->irq);
- }
+ else
+ qemu_bh_schedule(timer->tick);
} else
qemu_del_timer(timer->timer);
}
-static void omap_timer_tick(void *opaque)
+static void omap_timer_fire(void *opaque)
{
- struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
- omap_timer_sync(timer);
+ struct omap_mpu_timer_s *timer = opaque;
if (!timer->ar) {
timer->val = 0;
if (timer->it_ena)
/* Edge-triggered irq */
qemu_irq_pulse(timer->irq);
+}
+
+static void omap_timer_tick(void *opaque)
+{
+ struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
+
+ omap_timer_sync(timer);
+ omap_timer_fire(timer);
omap_timer_update(timer);
}
static uint32_t omap_mpu_timer_read(void *opaque, target_phys_addr_t addr)
{
struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
- int offset = addr - s->base;
- switch (offset) {
+ switch (addr) {
case 0x00: /* CNTL_TIMER */
return (s->enable << 5) | (s->ptv << 2) | (s->ar << 1) | s->st;
uint32_t value)
{
struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
- int offset = addr - s->base;
- switch (offset) {
+ switch (addr) {
case 0x00: /* CNTL_TIMER */
omap_timer_sync(s);
s->enable = (value >> 5) & 1;
s->irq = irq;
s->clk = clk;
- s->base = base;
s->timer = qemu_new_timer(vm_clock, omap_timer_tick, s);
+ s->tick = qemu_bh_new(omap_timer_fire, s);
omap_mpu_timer_reset(s);
omap_timer_clk_setup(s);
iomemtype = cpu_register_io_memory(0, omap_mpu_timer_readfn,
omap_mpu_timer_writefn, s);
- cpu_register_physical_memory(s->base, 0x100, iomemtype);
+ cpu_register_physical_memory(base, 0x100, iomemtype);
return s;
}
static uint32_t omap_wd_timer_read(void *opaque, target_phys_addr_t addr)
{
struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
- int offset = addr - s->timer.base;
- switch (offset) {
+ switch (addr) {
case 0x00: /* CNTL_TIMER */
return (s->timer.ptv << 9) | (s->timer.ar << 8) |
(s->timer.st << 7) | (s->free << 1);
uint32_t value)
{
struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
- int offset = addr - s->timer.base;
- switch (offset) {
+ switch (addr) {
case 0x00: /* CNTL_TIMER */
omap_timer_sync(&s->timer);
s->timer.ptv = (value >> 9) & 7;
s->timer.irq = irq;
s->timer.clk = clk;
- s->timer.base = base;
s->timer.timer = qemu_new_timer(vm_clock, omap_timer_tick, &s->timer);
omap_wd_timer_reset(s);
omap_timer_clk_setup(&s->timer);
iomemtype = cpu_register_io_memory(0, omap_wd_timer_readfn,
omap_wd_timer_writefn, s);
- cpu_register_physical_memory(s->timer.base, 0x100, iomemtype);
+ cpu_register_physical_memory(base, 0x100, iomemtype);
return s;
}
s->timer.irq = irq;
s->timer.clk = clk;
- s->timer.base = base;
s->timer.timer = qemu_new_timer(vm_clock, omap_timer_tick, &s->timer);
omap_os_timer_reset(s);
omap_timer_clk_setup(&s->timer);
iomemtype = cpu_register_io_memory(0, omap_os_timer_readfn,
omap_os_timer_writefn, s);
- cpu_register_physical_memory(s->timer.base, 0x800, iomemtype);
+ cpu_register_physical_memory(base, 0x800, iomemtype);
return s;
}
static uint32_t omap_ulpd_pm_read(void *opaque, target_phys_addr_t addr)
{
struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
- int offset = addr - s->ulpd_pm_base;
uint16_t ret;
- switch (offset) {
+ switch (addr) {
case 0x14: /* IT_STATUS */
- ret = s->ulpd_pm_regs[offset >> 2];
- s->ulpd_pm_regs[offset >> 2] = 0;
+ ret = s->ulpd_pm_regs[addr >> 2];
+ s->ulpd_pm_regs[addr >> 2] = 0;
qemu_irq_lower(s->irq[1][OMAP_INT_GAUGE_32K]);
return ret;
case 0x48: /* LOCL_TIME */
case 0x4c: /* APLL_CTRL */
case 0x50: /* POWER_CTRL */
- return s->ulpd_pm_regs[offset >> 2];
+ return s->ulpd_pm_regs[addr >> 2];
}
OMAP_BAD_REG(addr);
uint32_t value)
{
struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
- int offset = addr - s->ulpd_pm_base;
int64_t now, ticks;
int div, mult;
static const int bypass_div[4] = { 1, 2, 4, 4 };
uint16_t diff;
- switch (offset) {
+ switch (addr) {
case 0x00: /* COUNTER_32_LSB */
case 0x04: /* COUNTER_32_MSB */
case 0x08: /* COUNTER_HIGH_FREQ_LSB */
case 0x10: /* GAUGING_CTRL */
/* Bits 0 and 1 seem to be confused in the OMAP 310 TRM */
- if ((s->ulpd_pm_regs[offset >> 2] ^ value) & 1) {
+ if ((s->ulpd_pm_regs[addr >> 2] ^ value) & 1) {
now = qemu_get_clock(vm_clock);
if (value & 1)
qemu_irq_raise(s->irq[1][OMAP_INT_GAUGE_32K]);
}
}
- s->ulpd_pm_regs[offset >> 2] = value;
+ s->ulpd_pm_regs[addr >> 2] = value;
break;
case 0x18: /* Reserved */
case 0x38: /* COUNTER_32_FIQ */
case 0x48: /* LOCL_TIME */
case 0x50: /* POWER_CTRL */
- s->ulpd_pm_regs[offset >> 2] = value;
+ s->ulpd_pm_regs[addr >> 2] = value;
break;
case 0x30: /* CLOCK_CTRL */
- diff = s->ulpd_pm_regs[offset >> 2] ^ value;
- s->ulpd_pm_regs[offset >> 2] = value & 0x3f;
+ diff = s->ulpd_pm_regs[addr >> 2] ^ value;
+ s->ulpd_pm_regs[addr >> 2] = value & 0x3f;
omap_ulpd_clk_update(s, diff, value);
break;
case 0x34: /* SOFT_REQ */
- diff = s->ulpd_pm_regs[offset >> 2] ^ value;
- s->ulpd_pm_regs[offset >> 2] = value & 0x1f;
+ diff = s->ulpd_pm_regs[addr >> 2] ^ value;
+ s->ulpd_pm_regs[addr >> 2] = value & 0x1f;
omap_ulpd_req_update(s, diff, value);
break;
* omitted altogether, probably a typo. */
/* This register has identical semantics with DPLL(1:3) control
* registers, see omap_dpll_write() */
- diff = s->ulpd_pm_regs[offset >> 2] & value;
- s->ulpd_pm_regs[offset >> 2] = value & 0x2fff;
+ diff = s->ulpd_pm_regs[addr >> 2] & value;
+ s->ulpd_pm_regs[addr >> 2] = value & 0x2fff;
if (diff & (0x3ff << 2)) {
if (value & (1 << 4)) { /* PLL_ENABLE */
div = ((value >> 5) & 3) + 1; /* PLL_DIV */
}
/* Enter the desired mode. */
- s->ulpd_pm_regs[offset >> 2] =
- (s->ulpd_pm_regs[offset >> 2] & 0xfffe) |
- ((s->ulpd_pm_regs[offset >> 2] >> 4) & 1);
+ s->ulpd_pm_regs[addr >> 2] =
+ (s->ulpd_pm_regs[addr >> 2] & 0xfffe) |
+ ((s->ulpd_pm_regs[addr >> 2] >> 4) & 1);
/* Act as if the lock is restored. */
- s->ulpd_pm_regs[offset >> 2] |= 2;
+ s->ulpd_pm_regs[addr >> 2] |= 2;
break;
case 0x4c: /* APLL_CTRL */
- diff = s->ulpd_pm_regs[offset >> 2] & value;
- s->ulpd_pm_regs[offset >> 2] = value & 0xf;
+ diff = s->ulpd_pm_regs[addr >> 2] & value;
+ s->ulpd_pm_regs[addr >> 2] = value & 0xf;
if (diff & (1 << 0)) /* APLL_NDPLL_SWITCH */
omap_clk_reparent(omap_findclk(s, "ck_48m"), omap_findclk(s,
(value & (1 << 0)) ? "apll" : "dpll4"));
int iomemtype = cpu_register_io_memory(0, omap_ulpd_pm_readfn,
omap_ulpd_pm_writefn, mpu);
- mpu->ulpd_pm_base = base;
- cpu_register_physical_memory(mpu->ulpd_pm_base, 0x800, iomemtype);
+ cpu_register_physical_memory(base, 0x800, iomemtype);
omap_ulpd_pm_reset(mpu);
}
static uint32_t omap_pin_cfg_read(void *opaque, target_phys_addr_t addr)
{
struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
- int offset = addr - s->pin_cfg_base;
- switch (offset) {
+ switch (addr) {
case 0x00: /* FUNC_MUX_CTRL_0 */
case 0x04: /* FUNC_MUX_CTRL_1 */
case 0x08: /* FUNC_MUX_CTRL_2 */
- return s->func_mux_ctrl[offset >> 2];
+ return s->func_mux_ctrl[addr >> 2];
case 0x0c: /* COMP_MODE_CTRL_0 */
return s->comp_mode_ctrl[0];
case 0x30: /* FUNC_MUX_CTRL_B */
case 0x34: /* FUNC_MUX_CTRL_C */
case 0x38: /* FUNC_MUX_CTRL_D */
- return s->func_mux_ctrl[(offset >> 2) - 1];
+ return s->func_mux_ctrl[(addr >> 2) - 1];
case 0x40: /* PULL_DWN_CTRL_0 */
case 0x44: /* PULL_DWN_CTRL_1 */
case 0x48: /* PULL_DWN_CTRL_2 */
case 0x4c: /* PULL_DWN_CTRL_3 */
- return s->pull_dwn_ctrl[(offset & 0xf) >> 2];
+ return s->pull_dwn_ctrl[(addr & 0xf) >> 2];
case 0x50: /* GATE_INH_CTRL_0 */
return s->gate_inh_ctrl[0];
uint32_t value)
{
struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
- int offset = addr - s->pin_cfg_base;
uint32_t diff;
- switch (offset) {
+ switch (addr) {
case 0x00: /* FUNC_MUX_CTRL_0 */
- diff = s->func_mux_ctrl[offset >> 2] ^ value;
- s->func_mux_ctrl[offset >> 2] = value;
+ diff = s->func_mux_ctrl[addr >> 2] ^ value;
+ s->func_mux_ctrl[addr >> 2] = value;
omap_pin_funcmux0_update(s, diff, value);
return;
case 0x04: /* FUNC_MUX_CTRL_1 */
- diff = s->func_mux_ctrl[offset >> 2] ^ value;
- s->func_mux_ctrl[offset >> 2] = value;
+ diff = s->func_mux_ctrl[addr >> 2] ^ value;
+ s->func_mux_ctrl[addr >> 2] = value;
omap_pin_funcmux1_update(s, diff, value);
return;
case 0x08: /* FUNC_MUX_CTRL_2 */
- s->func_mux_ctrl[offset >> 2] = value;
+ s->func_mux_ctrl[addr >> 2] = value;
return;
case 0x0c: /* COMP_MODE_CTRL_0 */
case 0x30: /* FUNC_MUX_CTRL_B */
case 0x34: /* FUNC_MUX_CTRL_C */
case 0x38: /* FUNC_MUX_CTRL_D */
- s->func_mux_ctrl[(offset >> 2) - 1] = value;
+ s->func_mux_ctrl[(addr >> 2) - 1] = value;
return;
case 0x40: /* PULL_DWN_CTRL_0 */
case 0x44: /* PULL_DWN_CTRL_1 */
case 0x48: /* PULL_DWN_CTRL_2 */
case 0x4c: /* PULL_DWN_CTRL_3 */
- s->pull_dwn_ctrl[(offset & 0xf) >> 2] = value;
+ s->pull_dwn_ctrl[(addr & 0xf) >> 2] = value;
return;
case 0x50: /* GATE_INH_CTRL_0 */
int iomemtype = cpu_register_io_memory(0, omap_pin_cfg_readfn,
omap_pin_cfg_writefn, mpu);
- mpu->pin_cfg_base = base;
- cpu_register_physical_memory(mpu->pin_cfg_base, 0x800, iomemtype);
+ cpu_register_physical_memory(base, 0x800, iomemtype);
omap_pin_cfg_reset(mpu);
}
{
int iomemtype = cpu_register_io_memory(0, omap_id_readfn,
omap_id_writefn, mpu);
- cpu_register_physical_memory(0xfffe1800, 0x800, iomemtype);
- cpu_register_physical_memory(0xfffed400, 0x100, iomemtype);
+ cpu_register_physical_memory_offset(0xfffe1800, 0x800, iomemtype, 0xfffe1800);
+ cpu_register_physical_memory_offset(0xfffed400, 0x100, iomemtype, 0xfffed400);
if (!cpu_is_omap15xx(mpu))
- cpu_register_physical_memory(0xfffe2000, 0x800, iomemtype);
+ cpu_register_physical_memory_offset(0xfffe2000, 0x800, iomemtype, 0xfffe2000);
}
/* MPUI Control (Dummy) */
static uint32_t omap_mpui_read(void *opaque, target_phys_addr_t addr)
{
struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
- int offset = addr - s->mpui_base;
- switch (offset) {
+ switch (addr) {
case 0x00: /* CTRL */
return s->mpui_ctrl;
case 0x04: /* DEBUG_ADDR */
uint32_t value)
{
struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
- int offset = addr - s->mpui_base;
- switch (offset) {
+ switch (addr) {
case 0x00: /* CTRL */
s->mpui_ctrl = value & 0x007fffff;
break;
int iomemtype = cpu_register_io_memory(0, omap_mpui_readfn,
omap_mpui_writefn, mpu);
- mpu->mpui_base = base;
- cpu_register_physical_memory(mpu->mpui_base, 0x100, iomemtype);
+ cpu_register_physical_memory(base, 0x100, iomemtype);
omap_mpui_reset(mpu);
}
/* TIPB Bridges */
struct omap_tipb_bridge_s {
- target_phys_addr_t base;
qemu_irq abort;
int width_intr;
static uint32_t omap_tipb_bridge_read(void *opaque, target_phys_addr_t addr)
{
struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
- int offset = addr - s->base;
- switch (offset) {
+ switch (addr) {
case 0x00: /* TIPB_CNTL */
return s->control;
case 0x04: /* TIPB_BUS_ALLOC */
uint32_t value)
{
struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
- int offset = addr - s->base;
- switch (offset) {
+ switch (addr) {
case 0x00: /* TIPB_CNTL */
s->control = value & 0xffff;
break;
qemu_mallocz(sizeof(struct omap_tipb_bridge_s));
s->abort = abort_irq;
- s->base = base;
omap_tipb_bridge_reset(s);
iomemtype = cpu_register_io_memory(0, omap_tipb_bridge_readfn,
omap_tipb_bridge_writefn, s);
- cpu_register_physical_memory(s->base, 0x100, iomemtype);
+ cpu_register_physical_memory(base, 0x100, iomemtype);
return s;
}
static uint32_t omap_tcmi_read(void *opaque, target_phys_addr_t addr)
{
struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
- int offset = addr - s->tcmi_base;
uint32_t ret;
- switch (offset) {
+ switch (addr) {
case 0x00: /* IMIF_PRIO */
case 0x04: /* EMIFS_PRIO */
case 0x08: /* EMIFF_PRIO */
case 0x30: /* TIMEOUT3 */
case 0x3c: /* EMIFF_SDRAM_CONFIG_2 */
case 0x40: /* EMIFS_CFG_DYN_WAIT */
- return s->tcmi_regs[offset >> 2];
+ return s->tcmi_regs[addr >> 2];
case 0x20: /* EMIFF_SDRAM_CONFIG */
- ret = s->tcmi_regs[offset >> 2];
- s->tcmi_regs[offset >> 2] &= ~1; /* XXX: Clear SLRF on SDRAM access */
+ ret = s->tcmi_regs[addr >> 2];
+ s->tcmi_regs[addr >> 2] &= ~1; /* XXX: Clear SLRF on SDRAM access */
/* XXX: We can try using the VGA_DIRTY flag for this */
return ret;
}
uint32_t value)
{
struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
- int offset = addr - s->tcmi_base;
- switch (offset) {
+ switch (addr) {
case 0x00: /* IMIF_PRIO */
case 0x04: /* EMIFS_PRIO */
case 0x08: /* EMIFF_PRIO */
case 0x30: /* TIMEOUT3 */
case 0x3c: /* EMIFF_SDRAM_CONFIG_2 */
case 0x40: /* EMIFS_CFG_DYN_WAIT */
- s->tcmi_regs[offset >> 2] = value;
+ s->tcmi_regs[addr >> 2] = value;
break;
case 0x0c: /* EMIFS_CONFIG */
- s->tcmi_regs[offset >> 2] = (value & 0xf) | (1 << 4);
+ s->tcmi_regs[addr >> 2] = (value & 0xf) | (1 << 4);
break;
default:
int iomemtype = cpu_register_io_memory(0, omap_tcmi_readfn,
omap_tcmi_writefn, mpu);
- mpu->tcmi_base = base;
- cpu_register_physical_memory(mpu->tcmi_base, 0x100, iomemtype);
+ cpu_register_physical_memory(base, 0x100, iomemtype);
omap_tcmi_reset(mpu);
}
static uint32_t omap_dpll_read(void *opaque, target_phys_addr_t addr)
{
struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
- int offset = addr - s->base;
- if (offset == 0x00) /* CTL_REG */
+ if (addr == 0x00) /* CTL_REG */
return s->mode;
OMAP_BAD_REG(addr);
{
struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
uint16_t diff;
- int offset = addr - s->base;
static const int bypass_div[4] = { 1, 2, 4, 4 };
int div, mult;
- if (offset == 0x00) { /* CTL_REG */
+ if (addr == 0x00) { /* CTL_REG */
/* See omap_ulpd_pm_write() too */
diff = s->mode & value;
s->mode = value & 0x2fff;
int iomemtype = cpu_register_io_memory(0, omap_dpll_readfn,
omap_dpll_writefn, s);
- s->base = base;
s->dpll = clk;
omap_dpll_reset(s);
- cpu_register_physical_memory(s->base, 0x100, iomemtype);
+ cpu_register_physical_memory(base, 0x100, iomemtype);
}
/* UARTs */
struct omap_uart_s {
+ target_phys_addr_t base;
SerialState *serial; /* TODO */
struct omap_target_agent_s *ta;
- target_phys_addr_t base;
+ omap_clk fclk;
+ qemu_irq irq;
uint8_t eblr;
uint8_t syscontrol;
uint8_t cfps;
uint8_t mdr[2];
uint8_t scr;
+ uint8_t clksel;
};
void omap_uart_reset(struct omap_uart_s *s)
s->syscontrol = 0;
s->wkup = 0x3f;
s->cfps = 0x69;
+ s->clksel = 0;
}
struct omap_uart_s *omap_uart_init(target_phys_addr_t base,
struct omap_uart_s *s = (struct omap_uart_s *)
qemu_mallocz(sizeof(struct omap_uart_s));
+ s->base = base;
+ s->fclk = fclk;
+ s->irq = irq;
s->serial = serial_mm_init(base, 2, irq, omap_clk_getrate(fclk)/16,
- chr ?: qemu_chr_open("null"), 1);
+ chr ?: qemu_chr_open("null", "null", NULL), 1);
return s;
}
static uint32_t omap_uart_read(void *opaque, target_phys_addr_t addr)
{
struct omap_uart_s *s = (struct omap_uart_s *) opaque;
- int offset = addr - s->base;
- switch (offset) {
+ addr &= 0xff;
+ switch (addr) {
case 0x20: /* MDR1 */
return s->mdr[0];
case 0x24: /* MDR2 */
return s->scr;
case 0x44: /* SSR */
return 0x0;
- case 0x48: /* EBLR */
+ case 0x48: /* EBLR (OMAP2) */
return s->eblr;
+ case 0x4C: /* OSC_12M_SEL (OMAP1) */
+ return s->clksel;
case 0x50: /* MVR */
return 0x30;
- case 0x54: /* SYSC */
+ case 0x54: /* SYSC (OMAP2) */
return s->syscontrol;
- case 0x58: /* SYSS */
+ case 0x58: /* SYSS (OMAP2) */
return 1;
- case 0x5c: /* WER */
+ case 0x5c: /* WER (OMAP2) */
return s->wkup;
- case 0x60: /* CFPS */
+ case 0x60: /* CFPS (OMAP2) */
return s->cfps;
}
uint32_t value)
{
struct omap_uart_s *s = (struct omap_uart_s *) opaque;
- int offset = addr - s->base;
- switch (offset) {
+ addr &= 0xff;
+ switch (addr) {
case 0x20: /* MDR1 */
s->mdr[0] = value & 0x7f;
break;
case 0x40: /* SCR */
s->scr = value & 0xff;
break;
- case 0x48: /* EBLR */
+ case 0x48: /* EBLR (OMAP2) */
s->eblr = value & 0xff;
break;
+ case 0x4C: /* OSC_12M_SEL (OMAP1) */
+ s->clksel = value & 1;
+ break;
case 0x44: /* SSR */
case 0x50: /* MVR */
- case 0x58: /* SYSS */
+ case 0x58: /* SYSS (OMAP2) */
OMAP_RO_REG(addr);
break;
- case 0x54: /* SYSC */
+ case 0x54: /* SYSC (OMAP2) */
s->syscontrol = value & 0x1d;
if (value & 2)
omap_uart_reset(s);
break;
- case 0x5c: /* WER */
+ case 0x5c: /* WER (OMAP2) */
s->wkup = value & 0x7f;
break;
- case 0x60: /* CFPS */
+ case 0x60: /* CFPS (OMAP2) */
s->cfps = value & 0xff;
break;
default:
omap_uart_writefn, s);
s->ta = ta;
- s->base = base;
- cpu_register_physical_memory(s->base + 0x20, 0x100, iomemtype);
+ cpu_register_physical_memory(base + 0x20, 0x100, iomemtype);
return s;
}
+void omap_uart_attach(struct omap_uart_s *s, CharDriverState *chr)
+{
+ /* TODO: Should reuse or destroy current s->serial */
+ s->serial = serial_mm_init(s->base, 2, s->irq,
+ omap_clk_getrate(s->fclk) / 16,
+ chr ?: qemu_chr_open("null", "null", NULL), 1);
+}
+
/* MPU Clock/Reset/Power Mode Control */
static uint32_t omap_clkm_read(void *opaque, target_phys_addr_t addr)
{
struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
- int offset = addr - s->clkm.mpu_base;
- switch (offset) {
+ switch (addr) {
case 0x00: /* ARM_CKCTL */
return s->clkm.arm_ckctl;
uint32_t value)
{
struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
- int offset = addr - s->clkm.mpu_base;
uint16_t diff;
omap_clk clk;
static const char *clkschemename[8] = {
"mix mode 1", "mix mode 2", "bypass mode", "mix mode 3", "mix mode 4",
};
- switch (offset) {
+ switch (addr) {
case 0x00: /* ARM_CKCTL */
diff = s->clkm.arm_ckctl ^ value;
s->clkm.arm_ckctl = value & 0x7fff;
static uint32_t omap_clkdsp_read(void *opaque, target_phys_addr_t addr)
{
struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
- int offset = addr - s->clkm.dsp_base;
- switch (offset) {
+ switch (addr) {
case 0x04: /* DSP_IDLECT1 */
return s->clkm.dsp_idlect1;
uint32_t value)
{
struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
- int offset = addr - s->clkm.dsp_base;
uint16_t diff;
- switch (offset) {
+ switch (addr) {
case 0x04: /* DSP_IDLECT1 */
diff = s->clkm.dsp_idlect1 ^ value;
s->clkm.dsp_idlect1 = value & 0x01f7;
cpu_register_io_memory(0, omap_clkdsp_readfn, omap_clkdsp_writefn, s),
};
- s->clkm.mpu_base = mpu_base;
- s->clkm.dsp_base = dsp_base;
s->clkm.arm_idlect1 = 0x03ff;
s->clkm.arm_idlect2 = 0x0100;
s->clkm.dsp_idlect1 = 0x0002;
omap_clkm_reset(s);
s->clkm.cold_start = 0x3a;
- cpu_register_physical_memory(s->clkm.mpu_base, 0x100, iomemtype[0]);
- cpu_register_physical_memory(s->clkm.dsp_base, 0x1000, iomemtype[1]);
+ cpu_register_physical_memory(mpu_base, 0x100, iomemtype[0]);
+ cpu_register_physical_memory(dsp_base, 0x1000, iomemtype[1]);
}
/* MPU I/O */
struct omap_mpuio_s {
- target_phys_addr_t base;
qemu_irq irq;
qemu_irq kbd_irq;
qemu_irq *in;
struct omap_mpuio_s *s = (struct omap_mpuio_s *)
qemu_mallocz(sizeof(struct omap_mpuio_s));
- s->base = base;
s->irq = gpio_int;
s->kbd_irq = kbd_int;
s->wakeup = wakeup;
iomemtype = cpu_register_io_memory(0, omap_mpuio_readfn,
omap_mpuio_writefn, s);
- cpu_register_physical_memory(s->base, 0x800, iomemtype);
+ cpu_register_physical_memory(base, 0x800, iomemtype);
omap_clk_adduser(clk, qemu_allocate_irqs(omap_mpuio_onoff, s, 1)[0]);
/* General-Purpose I/O */
struct omap_gpio_s {
- target_phys_addr_t base;
qemu_irq irq;
qemu_irq *in;
qemu_irq handler[16];
struct omap_gpio_s *s = (struct omap_gpio_s *)
qemu_mallocz(sizeof(struct omap_gpio_s));
- s->base = base;
s->irq = irq;
s->in = qemu_allocate_irqs(omap_gpio_set, s, 16);
omap_gpio_reset(s);
iomemtype = cpu_register_io_memory(0, omap_gpio_readfn,
omap_gpio_writefn, s);
- cpu_register_physical_memory(s->base, 0x1000, iomemtype);
+ cpu_register_physical_memory(base, 0x1000, iomemtype);
return s;
}
/* MicroWire Interface */
struct omap_uwire_s {
- target_phys_addr_t base;
qemu_irq txirq;
qemu_irq rxirq;
qemu_irq txdrq;
struct omap_uwire_s *s = (struct omap_uwire_s *)
qemu_mallocz(sizeof(struct omap_uwire_s));
- s->base = base;
s->txirq = irq[0];
s->rxirq = irq[1];
s->txdrq = dma;
iomemtype = cpu_register_io_memory(0, omap_uwire_readfn,
omap_uwire_writefn, s);
- cpu_register_physical_memory(s->base, 0x800, iomemtype);
+ cpu_register_physical_memory(base, 0x800, iomemtype);
return s;
}
/* Real-time Clock module */
struct omap_rtc_s {
- target_phys_addr_t base;
qemu_irq irq;
qemu_irq alarm;
QEMUTimer *clk;
static void omap_rtc_alarm_update(struct omap_rtc_s *s)
{
- s->alarm_ti = mktime(&s->alarm_tm);
+ s->alarm_ti = mktimegm(&s->alarm_tm);
if (s->alarm_ti == -1)
printf("%s: conversion failed\n", __FUNCTION__);
}
#endif
memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
new_tm.tm_mon = omap_rtc_bin(value);
- ti[0] = mktime(&s->current_tm);
- ti[1] = mktime(&new_tm);
+ ti[0] = mktimegm(&s->current_tm);
+ ti[1] = mktimegm(&new_tm);
if (ti[0] != -1 && ti[1] != -1) {
s->ti -= ti[0];
#endif
memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
new_tm.tm_year += omap_rtc_bin(value) - (new_tm.tm_year % 100);
- ti[0] = mktime(&s->current_tm);
- ti[1] = mktime(&new_tm);
+ ti[0] = mktimegm(&s->current_tm);
+ ti[1] = mktimegm(&new_tm);
if (ti[0] != -1 && ti[1] != -1) {
s->ti -= ti[0];
s->alarm_tm.tm_mday = 0x01;
s->status = 1 << 7;
qemu_get_timedate(&tm, 0);
- s->ti = mktime(&tm);
+ s->ti = mktimegm(&tm);
omap_rtc_alarm_update(s);
omap_rtc_tick(s);
struct omap_rtc_s *s = (struct omap_rtc_s *)
qemu_mallocz(sizeof(struct omap_rtc_s));
- s->base = base;
s->irq = irq[0];
s->alarm = irq[1];
s->clk = qemu_new_timer(rt_clock, omap_rtc_tick, s);
iomemtype = cpu_register_io_memory(0, omap_rtc_readfn,
omap_rtc_writefn, s);
- cpu_register_physical_memory(s->base, 0x800, iomemtype);
+ cpu_register_physical_memory(base, 0x800, iomemtype);
return s;
}
/* Multi-channel Buffered Serial Port interfaces */
struct omap_mcbsp_s {
- target_phys_addr_t base;
qemu_irq txirq;
qemu_irq rxirq;
qemu_irq txdrq;
struct omap_mcbsp_s *s = (struct omap_mcbsp_s *)
qemu_mallocz(sizeof(struct omap_mcbsp_s));
- s->base = base;
s->txirq = irq[0];
s->rxirq = irq[1];
s->txdrq = dma[0];
iomemtype = cpu_register_io_memory(0, omap_mcbsp_readfn,
omap_mcbsp_writefn, s);
- cpu_register_physical_memory(s->base, 0x800, iomemtype);
+ cpu_register_physical_memory(base, 0x800, iomemtype);
return s;
}
/* LED Pulse Generators */
struct omap_lpg_s {
- target_phys_addr_t base;
QEMUTimer *tm;
uint8_t control;
struct omap_lpg_s *s = (struct omap_lpg_s *)
qemu_mallocz(sizeof(struct omap_lpg_s));
- s->base = base;
s->tm = qemu_new_timer(rt_clock, omap_lpg_tick, s);
omap_lpg_reset(s);
iomemtype = cpu_register_io_memory(0, omap_lpg_readfn,
omap_lpg_writefn, s);
- cpu_register_physical_memory(s->base, 0x800, iomemtype);
+ cpu_register_physical_memory(base, 0x800, iomemtype);
omap_clk_adduser(clk, qemu_allocate_irqs(omap_lpg_clk_update, s, 1)[0]);
}
struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
- DisplayState *ds, const char *core)
+ const char *core)
{
int i;
struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
omap_findclk(s, "clk32-kHz"));
s->lcd = omap_lcdc_init(0xfffec000, s->irq[0][OMAP_INT_LCD_CTRL],
- omap_dma_get_lcdch(s->dma), ds, imif_base, emiff_base,
+ omap_dma_get_lcdch(s->dma), imif_base, emiff_base,
omap_findclk(s, "lcd_ck"));
omap_ulpd_pm_init(0xfffe0800, s);
omap_findclk(s, "uart2_ck"),
s->drq[OMAP_DMA_UART2_TX], s->drq[OMAP_DMA_UART2_RX],
serial_hds[0] ? serial_hds[1] : 0);
- s->uart[2] = omap_uart_init(0xe1019800, s->irq[0][OMAP_INT_UART3],
+ s->uart[2] = omap_uart_init(0xfffb9800, s->irq[0][OMAP_INT_UART3],
omap_findclk(s, "uart3_ck"),
omap_findclk(s, "uart3_ck"),
s->drq[OMAP_DMA_UART3_TX], s->drq[OMAP_DMA_UART3_RX],