static uint32_t goldfish_timer_read(void *opaque, target_phys_addr_t offset)
{
    struct timer_state *s = (struct timer_state *)opaque;
    switch(offset) {
        case TIMER_TIME_LOW:
            s->now_ns = tks2ns(qemu_get_clock(vm_clock));
            return s->now_ns;
        case TIMER_TIME_HIGH:
            return s->now_ns >> 32;
        default:
            cpu_abort (cpu_single_env, "goldfish_timer_read: Bad offset %x\n", offset);
            return 0;
    }
}
static uint32_t goldfish_rtc_read(void *opaque, target_phys_addr_t offset)
{
    struct rtc_state *s = (struct rtc_state *)opaque;
    switch(offset) {
        case 0x0:
            s->now = (int64_t)time(NULL) * 1000000000;
            return s->now;
        case 0x4:
            return s->now >> 32;
        default:
            cpu_abort (cpu_single_env, "goldfish_rtc_read: Bad offset %x\n", offset);
            return 0;
    }
}
Пример #3
0
static uint32_t goldfish_tty_read(void *opaque, target_phys_addr_t offset)
{
    struct tty_state *s = (struct tty_state *)opaque;

    //printf("goldfish_tty_read %x %x\n", offset, size);

    switch (offset) {
        case TTY_BYTES_READY:
            return s->data_count;
    default:
        cpu_abort (cpu_single_env, "goldfish_tty_read: Bad offset %x\n", offset);
        return 0;
    }
}
/* I/O read */
static uint32_t trace_dev_read(void *opaque, target_phys_addr_t offset)
{
    trace_dev_state *s = (trace_dev_state *)opaque;

    offset -= s->base;
    switch (offset >> 2) {
    case TRACE_DEV_REG_ENABLE:          // tracing enable
        return tracing;
    default:
        cpu_abort(cpu_single_env, "trace_dev_read: Bad offset %x\n", offset);
        return 0;
    }
    return 0;
}
Пример #5
0
LowCore *cpu_map_lowcore(CPUS390XState *env)
{
    S390CPU *cpu = s390_env_get_cpu(env);
    LowCore *lowcore;
    hwaddr len = sizeof(LowCore);

    lowcore = cpu_physical_memory_map(env->psa, &len, 1);

    if (len < sizeof(LowCore)) {
        cpu_abort(CPU(cpu), "Could not map lowcore\n");
    }

    return lowcore;
}
Пример #6
0
static void goldfish_battery_write(void *opaque, target_phys_addr_t offset, uint32_t val)
{
    struct goldfish_battery_state *s = opaque;

    switch(offset) {
        case BATTERY_INT_ENABLE:
            
            s->int_enable = val;
            break;

        default:
            cpu_abort (cpu_single_env, "goldfish_audio_write: Bad offset %x\n", offset);
    }
}
Пример #7
0
void openrisc_cpu_do_interrupt(CPUState *cs)
{
    OpenRISCCPU *cpu = OPENRISC_CPU(cs);
    CPUOpenRISCState *env = &cpu->env;
#ifndef CONFIG_USER_ONLY
    if (env->flags & D_FLAG) { /* Delay Slot insn */
        env->flags &= ~D_FLAG;
        env->sr |= SR_DSX;
        if (env->exception_index == EXCP_TICK    ||
            env->exception_index == EXCP_INT     ||
            env->exception_index == EXCP_SYSCALL ||
            env->exception_index == EXCP_FPE) {
            env->epcr = env->jmp_pc;
        } else {
            env->epcr = env->pc - 4;
        }
    } else {
        if (env->exception_index == EXCP_TICK    ||
            env->exception_index == EXCP_INT     ||
            env->exception_index == EXCP_SYSCALL ||
            env->exception_index == EXCP_FPE) {
            env->epcr = env->npc;
        } else {
            env->epcr = env->pc;
        }
    }

    /* For machine-state changed between user-mode and supervisor mode,
       we need flush TLB when we enter&exit EXCP.  */
    tlb_flush(env, 1);

    env->esr = env->sr;
    env->sr &= ~SR_DME;
    env->sr &= ~SR_IME;
    env->sr |= SR_SM;
    env->sr &= ~SR_IEE;
    env->sr &= ~SR_TEE;
    env->tlb->cpu_openrisc_map_address_data = &cpu_openrisc_get_phys_nommu;
    env->tlb->cpu_openrisc_map_address_code = &cpu_openrisc_get_phys_nommu;

    if (env->exception_index > 0 && env->exception_index < EXCP_NR) {
        env->pc = (env->exception_index << 8);
    } else {
        cpu_abort(env, "Unhandled exception 0x%x\n", env->exception_index);
    }
#endif

    env->exception_index = -1;
}
Пример #8
0
static void arm_timer_write(void *opaque, target_phys_addr_t offset,
                            uint32_t value)
{
    arm_timer_state *s = (arm_timer_state *)opaque;
    int freq;

    switch (offset >> 2) {
    case 0: /* TimerLoad */
        s->limit = value;
        arm_timer_recalibrate(s, 1);
        break;
    case 1: /* TimerValue */
        /* ??? Linux seems to want to write to this readonly register.
           Ignore it.  */
        break;
    case 2: /* TimerControl */
        if (s->control & TIMER_CTRL_ENABLE) {
            /* Pause the timer if it is running.  This may cause some
               inaccuracy dure to rounding, but avoids a whole lot of other
               messyness.  */
            ptimer_stop(s->timer);
        }
        s->control = value;
        freq = s->freq;
        /* ??? Need to recalculate expiry time after changing divisor.  */
        switch ((value >> 2) & 3) {
        case 1: freq >>= 4; break;
        case 2: freq >>= 8; break;
        }
        arm_timer_recalibrate(s, 0);
        ptimer_set_freq(s->timer, freq);
        if (s->control & TIMER_CTRL_ENABLE) {
            /* Restart the timer if still enabled.  */
            ptimer_run(s->timer, (s->control & TIMER_CTRL_ONESHOT) != 0);
        }
        break;
    case 3: /* TimerIntClr */
        s->int_level = 0;
        break;
    case 6: /* TimerBGLoad */
        s->limit = value;
        arm_timer_recalibrate(s, 0);
        break;
    default:
        cpu_abort (cpu_single_env, "arm_timer_write: Bad offset %x\n",
                   (int)offset);
    }
    arm_timer_update(s);
}
Пример #9
0
static inline int float_comp_to_cc(CPUS390XState *env, int float_compare)
{
    switch (float_compare) {
    case float_relation_equal:
        return 0;
    case float_relation_less:
        return 1;
    case float_relation_greater:
        return 2;
    case float_relation_unordered:
        return 3;
    default:
        cpu_abort(env, "unknown return value for float compare\n");
    }
}
Пример #10
0
static void goldfish_sensor_write(void *opaque, target_phys_addr_t offset, uint32_t val)
{
    struct goldfish_sensor_state *s = opaque;
    offset -= s->dev.base;

    switch(offset) {
        case INT_ENABLE:
            /* enable interrupts */
            s->int_enable = val;
            break;

        default:
            cpu_abort (cpu_single_env, "goldfish_sensor_write: Bad offset %x\n", offset);
    }
}
Пример #11
0
static void goldfish_battery_write(void *opaque, target_phys_addr_t offset, uint32_t val)
{
    GoldfishBatteryDevice *s = (GoldfishBatteryDevice *)opaque;

    switch(offset) {
        case BATTERY_INT_ENABLE:
            /* enable interrupts */
            s->int_enable = val;
//            s->int_status = (AUDIO_INT_WRITE_BUFFER_1_EMPTY | AUDIO_INT_WRITE_BUFFER_2_EMPTY);
//            goldfish_device_set_irq(&s->dev, 0, (s->int_status & s->int_enable));
            break;

        default:
            cpu_abort (cpu_single_env, "goldfish_audio_write: Bad offset %x\n", offset);
    }
}
Пример #12
0
static void pl031_write(void * opaque, target_phys_addr_t offset,
                        uint32_t value)
{
    pl031_state *s = (pl031_state *)opaque;

    offset -= s->base;

    switch (offset) {
    case RTC_LR:
        s->tick_offset += value - pl031_get_count(s);
        pl031_set_alarm(s);
        break;
    case RTC_MR:
        s->mr = value;
        pl031_set_alarm(s);
        break;
    case RTC_IMSC:
        s->im = value & 1;
        DPRINTF("Interrupt mask %d\n", s->im);
        pl031_update(s);
        break;
    case RTC_ICR:
        /* The PL031 documentation (DDI0224B) states that the interupt is
           cleared when bit 0 of the written value is set.  However the
           arm926e documentation (DDI0287B) states that the interrupt is
           cleared when any value is written.  */
        DPRINTF("Interrupt cleared");
        s->is = 0;
        pl031_update(s);
        break;
    case RTC_CR:
        /* Written value is ignored.  */
        break;

    case RTC_DR:
    case RTC_MIS:
    case RTC_RIS:
        fprintf(stderr, "qemu: pl031_write: Unexpected offset 0x%x\n",
                (int)offset);
        break;

    default:
        cpu_abort(cpu_single_env, "pl031_write: Bad offset 0x%x\n",
                  (int)offset);
        break;
    }
}
Пример #13
0
static void syborg_keyboard_write(void *opaque, target_phys_addr_t offset,
                                  uint32_t value)
{
    SyborgKeyboardState *s = (SyborgKeyboardState *)opaque;

    DPRINTF("reg write %d\n", (int)offset);
    offset &= 0xfff;
    switch (offset >> 2) {
    case KBD_INT_ENABLE:
        s->int_enabled = value;
        syborg_keyboard_update(s);
        break;
    default:
        cpu_abort(cpu_single_env, "syborg_keyboard_write: Bad offset %x\n",
                  (int)offset);
    }
}
Пример #14
0
/* I/O read */
static uint32_t nand_dev_read(void *opaque, target_phys_addr_t offset)
{
    nand_dev_controller_state *s = (nand_dev_controller_state *)opaque;
    nand_dev *dev;

    switch (offset) {
    case NAND_VERSION:
        return NAND_VERSION_CURRENT;
    case NAND_NUM_DEV:
        return nand_dev_count;
    case NAND_RESULT:
        return s->result;
    }

    if(s->dev >= nand_dev_count)
        return 0;

    dev = nand_devs + s->dev;

    switch (offset) {
    case NAND_DEV_FLAGS:
        return dev->flags;

    case NAND_DEV_NAME_LEN:
        return dev->devname_len;

    case NAND_DEV_PAGE_SIZE:
        return dev->page_size;

    case NAND_DEV_EXTRA_SIZE:
        return dev->extra_size;

    case NAND_DEV_ERASE_SIZE:
        return dev->erase_size;

    case NAND_DEV_SIZE_LOW:
        return (uint32_t)dev->max_size;

    case NAND_DEV_SIZE_HIGH:
        return (uint32_t)(dev->max_size >> 32);

    default:
        cpu_abort(cpu_single_env, "nand_dev_read: Bad offset %x\n", offset);
        return 0;
    }
}
Пример #15
0
static uint32_t syborg_rtc_read(void *opaque, target_phys_addr_t offset)
{
    SyborgRTCState *s = (SyborgRTCState *)opaque;
    offset &= 0xfff;
    switch (offset >> 2) {
    case RTC_ID:
        return SYBORG_ID_RTC;
    case RTC_DATA_LOW:
        return (uint32_t)s->data;
    case RTC_DATA_HIGH:
        return (uint32_t)(s->data >> 32);
    default:
        cpu_abort(cpu_single_env, "syborg_rtc_read: Bad offset %x\n",
                  (int)offset);
        return 0;
    }
}
Пример #16
0
static void goldfish_battery_write(void *opaque, hwaddr offset, uint32_t val)
{
    struct goldfish_battery_state *s = opaque;

    switch(offset) {
        case BATTERY_INT_ENABLE:
            /* enable interrupts */
            s->int_enable = val;
//            s->int_status = (AUDIO_INT_WRITE_BUFFER_1_EMPTY | AUDIO_INT_WRITE_BUFFER_2_EMPTY);
//            goldfish_device_set_irq(&s->dev, 0, (s->int_status & s->int_enable));
            break;

        default:
            cpu_abort(cpu_single_env,
                      "goldfish_audio_write: Bad offset %" HWADDR_PRIx "\n",
                      offset);
    }
}
Пример #17
0
void HELPER(movec)(CPUM68KState *env, uint32_t reg, uint32_t val)
{
    switch (reg) {
    case 0x02: /* CACR */
        env->cacr = val;
        m68k_switch_sp(env);
        break;
    case 0x04: case 0x05: case 0x06: case 0x07: /* ACR[0-3] */
        /* TODO: Implement Access Control Registers.  */
        break;
    case 0x801: /* VBR */
        env->vbr = val;
        break;
    /* TODO: Implement control registers.  */
    default:
        cpu_abort(env, "Unimplemented control register write 0x%x = 0x%x\n",
                  reg, val);
    }
}
Пример #18
0
static uint32_t pl022_read(void *opaque, target_phys_addr_t offset)
{
    pl022_state *s = (pl022_state *)opaque;
    int val;

    offset -= s->base;
    if (offset >= 0xfe0 && offset < 0x1000) {
        return pl022_id[(offset - 0xfe0) >> 2];
    }
    switch (offset) {
    case 0x00: /* CR0 */
      return s->cr0;
    case 0x04: /* CR1 */
      return s->cr1;
    case 0x08: /* DR */
        if (s->rx_fifo_len) {
            val = s->rx_fifo[(s->rx_fifo_head - s->rx_fifo_len) & 7];
            DPRINTF("RX %02x\n", val);
            s->rx_fifo_len--;
            pl022_xfer(s);
        } else {
            val = 0;
        }
        return val;
    case 0x0c: /* SR */
        return s->sr;
    case 0x10: /* CPSR */
        return s->cpsr;
    case 0x14: /* IMSC */
        return s->im;
    case 0x18: /* RIS */
        return s->is;
    case 0x1c: /* MIS */
        return s->im & s->is;
    case 0x20: /* DMACR */
        /* Not implemented.  */
        return 0;
    default:
        cpu_abort (cpu_single_env, "pl022_read: Bad offset %x\n",
                   (int)offset);
        return 0;
    }
}
Пример #19
0
void openrisc_cpu_do_interrupt(CPUState *cs)
{
#ifndef CONFIG_USER_ONLY
    OpenRISCCPU *cpu = OPENRISC_CPU(cs);
    CPUOpenRISCState *env = &cpu->env;

    env->epcr = env->pc;
    if (env->flags & D_FLAG) {
        env->flags &= ~D_FLAG;
        env->sr |= SR_DSX;
        env->epcr -= 4;
    }
    if (cs->exception_index == EXCP_SYSCALL) {
        env->epcr += 4;
    }

    /* For machine-state changed between user-mode and supervisor mode,
       we need flush TLB when we enter&exit EXCP.  */
    tlb_flush(cs, 1);

    env->esr = env->sr;
    env->sr &= ~SR_DME;
    env->sr &= ~SR_IME;
    env->sr |= SR_SM;
    env->sr &= ~SR_IEE;
    env->sr &= ~SR_TEE;
    env->tlb->cpu_openrisc_map_address_data = &cpu_openrisc_get_phys_nommu;
    env->tlb->cpu_openrisc_map_address_code = &cpu_openrisc_get_phys_nommu;

    if (cs->exception_index > 0 && cs->exception_index < EXCP_NR) {
#ifdef OR32_ARCH_DEFAULT
        env->pc = (cs->exception_index << 8);
#else
        env->pc = 0x100000 + (cs->exception_index << 8);
#endif
        //printf("pc = 0x%x\n", env->pc);
    } else {
        cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
    }
#endif

    cs->exception_index = -1;
}
Пример #20
0
static void syborg_int_write(void *opaque, hwaddr offset,
                             uint64_t value, unsigned size)
{
    SyborgIntState *s = (SyborgIntState *)opaque;
    int i;
    offset &= 0xfff;

    DPRINTF("syborg_int_write offset=%d val=%d\n", (int)offset, (int)value);
    switch (offset >> 2) {
    case INT_DISABLE_ALL:
        s->pending_count = 0;
        for (i = 0; i < s->num_irqs; i++)
            s->flags[i].enabled = 0;
        break;

    case INT_DISABLE:
        if (value >= s->num_irqs)
            break;
        if (s->flags[value].enabled) {
            if (s->flags[value].enabled)
                s->pending_count--;
            s->flags[value].enabled = 0;
        }
        break;

    case INT_ENABLE:
      if (value >= s->num_irqs)
          break;
      if (!(s->flags[value].enabled)) {
          if(s->flags[value].level)
              s->pending_count++;
          s->flags[value].enabled = 1;
      }
      break;

    default:
        cpu_abort(cpu_single_env, "syborg_int_write: Bad offset %x\n",
                  (int)offset);
        return;
    }
    syborg_int_update(s);
}
Пример #21
0
/* I/O read */
static uint32_t trace_dev_read(void *opaque, hwaddr offset)
{
    trace_dev_state *s = (trace_dev_state *)opaque;

    (void)s;

    switch (offset >> 2) {
    case TRACE_DEV_REG_ENABLE:          // tracing enable
        return tracing;

    default:
        if (offset < 4096) {
            cpu_abort(cpu_single_env, "trace_dev_read: Bad offset %x\n", offset);
        } else {
            D("%s: offset=%d (0x%x)\n", __FUNCTION__, offset, offset);
        }
        return 0;
    }
    return 0;
}
Пример #22
0
static uint32_t
goldfish_rfkill_read(void *opaque,
                     target_phys_addr_t offset)
{
    struct rfkill_state *s = opaque;

    switch(offset) {
        case OFFSET_INT:
            D("read inta 0x%08x\n", s->inta);
            return s->inta;

        case OFFSET_HWBLOCK:
            D("read hw_block 0x%08x\n", s->hw_block);
            return s->hw_block;

        default:
            cpu_abort (cpu_single_env, "goldfish_rfkill_read: bad offset %x\n", offset);
            return 0;
    }
}
Пример #23
0
static void gptm_tick(void *opaque)
{
    gptm_state **p = (gptm_state **)opaque;
    gptm_state *s;
    int n;

    s = *p;
    n = p - s->opaque;
    if (s->config == 0) {
        s->state |= 1;
        if ((s->control & 0x20)) {
            /* Output trigger.  */
	    qemu_irq_raise(s->trigger);
	    qemu_irq_lower(s->trigger);
        }
        if (s->mode[0] & 1) {
            /* One-shot.  */
            s->control &= ~1;
        } else {
            /* Periodic.  */
            gptm_reload(s, 0, 0);
        }
    } else if (s->config == 1) {
        /* RTC.  */
        uint32_t match;
        s->rtc++;
        match = s->match[0] | (s->match[1] << 16);
        if (s->rtc > match)
            s->rtc = 0;
        if (s->rtc == 0) {
            s->state |= 8;
        }
        gptm_reload(s, 0, 0);
    } else if (s->mode[n] == 0xa) {
        /* PWM mode.  Not implemented.  */
    } else {
        cpu_abort(cpu_single_env, "TODO: 16-bit timer mode 0x%x\n",
                  s->mode[n]);
    }
    gptm_update_irq(s);
}
Пример #24
0
static uint32_t goldfish_bus_read(void *opaque, hwaddr offset)
{
    struct bus_state *s = (struct bus_state *)opaque;

    switch (offset) {
    case PDEV_BUS_OP:
        if(s->current) {
            s->current->reported_state = 1;
            s->current = s->current->next;
        }
        else {
            s->current = first_device;
        }
        while(s->current && s->current->reported_state == 1)
            s->current = s->current->next;
        if(s->current)
            return PDEV_BUS_OP_ADD_DEV;
        else {
            goldfish_device_set_irq(&s->dev, 0, 0);
            return PDEV_BUS_OP_DONE;
        }

    case PDEV_BUS_NAME_LEN:
        return s->current ? strlen(s->current->name) : 0;
    case PDEV_BUS_ID:
        return s->current ? s->current->id : 0;
    case PDEV_BUS_IO_BASE:
        return s->current ? s->current->base : 0;
    case PDEV_BUS_IO_SIZE:
        return s->current ? s->current->size : 0;
    case PDEV_BUS_IRQ:
        return s->current ? s->current->irq : 0;
    case PDEV_BUS_IRQ_COUNT:
        return s->current ? s->current->irq_count : 0;
    default:
        cpu_abort(cpu_single_env,
                  "goldfish_bus_read: Bad offset %" HWADDR_PRIx "\n",
                  offset);
        return 0;
    }
}
Пример #25
0
static void arm_pic_cpu_handler(void *opaque, int irq, int level)
{
    arm_pic_cpu_state *s = (arm_pic_cpu_state *)opaque;
    switch (irq) {
    case ARM_PIC_CPU_IRQ:
        if (level)
            cpu_interrupt(s->cpu_env, CPU_INTERRUPT_HARD);
        else
            cpu_reset_interrupt(s->cpu_env, CPU_INTERRUPT_HARD);
        break;
    case ARM_PIC_CPU_FIQ:
        if (level)
            cpu_interrupt(s->cpu_env, CPU_INTERRUPT_FIQ);
        else
            cpu_reset_interrupt(s->cpu_env, CPU_INTERRUPT_FIQ);
        break;
    default:
        cpu_abort(s->cpu_env, "arm_pic_cpu_handler: Bad interrput line %d\n",
                  irq);
    }
}
Пример #26
0
static uint32_t goldfish_int_read(void *opaque, target_phys_addr_t offset)
{
    GoldfishInterruptDevice *s = (GoldfishInterruptDevice *)opaque;

    switch (offset) {
    case INTERRUPT_STATUS: /* IRQ_STATUS */
        return s->pending_count;
    case INTERRUPT_NUMBER: {
        int i;
        uint32_t pending = s->level & s->irq_enabled;
        for(i = 0; i < 32; i++) {
            if(pending & (1U << i))
                return i;
        }
        return 0;
    }
    default:
        cpu_abort (cpu_single_env, "goldfish_int_read: Bad offset %x\n", offset);
        return 0;
    }
}
Пример #27
0
static void mvc_fast_memset(CPUS390XState *env, uint32_t l, uint64_t dest,
                            uint8_t byte)
{
    hwaddr dest_phys;
    hwaddr len = l;
    void *dest_p;
    uint64_t asc = env->psw.mask & PSW_MASK_ASC;
    int flags;

    if (mmu_translate(env, dest, 1, asc, &dest_phys, &flags)) {
        cpu_stb_data(env, dest, byte);
        cpu_abort(env, "should never reach here");
    }
    dest_phys |= dest & ~TARGET_PAGE_MASK;

    dest_p = cpu_physical_memory_map(dest_phys, &len, 1);

    memset(dest_p, byte, len);

    cpu_physical_memory_unmap(dest_p, 1, len, len);
}
Пример #28
0
void lm32_cpu_do_interrupt(CPUState *cs)
{
    LM32CPU *cpu = LM32_CPU(cs);
    CPULM32State *env = &cpu->env;

    qemu_log_mask(CPU_LOG_INT,
            "exception at pc=%x type=%x\n", env->pc, env->exception_index);

    switch (env->exception_index) {
    case EXCP_INSN_BUS_ERROR:
    case EXCP_DATA_BUS_ERROR:
    case EXCP_DIVIDE_BY_ZERO:
    case EXCP_IRQ:
    case EXCP_SYSTEMCALL:
        /* non-debug exceptions */
        env->regs[R_EA] = env->pc;
        env->ie |= (env->ie & IE_IE) ? IE_EIE : 0;
        env->ie &= ~IE_IE;
        if (env->dc & DC_RE) {
            env->pc = env->deba + (env->exception_index * 32);
        } else {
            env->pc = env->eba + (env->exception_index * 32);
        }
        log_cpu_state_mask(CPU_LOG_INT, env, 0);
        break;
    case EXCP_BREAKPOINT:
    case EXCP_WATCHPOINT:
        /* debug exceptions */
        env->regs[R_BA] = env->pc;
        env->ie |= (env->ie & IE_IE) ? IE_BIE : 0;
        env->ie &= ~IE_IE;
        env->pc = env->deba + (env->exception_index * 32);
        log_cpu_state_mask(CPU_LOG_INT, env, 0);
        break;
    default:
        cpu_abort(env, "unhandled exception type=%d\n",
                  env->exception_index);
        break;
    }
}
static void goldfish_rtc_write(void *opaque, target_phys_addr_t offset, uint32_t value)
{
    struct rtc_state *s = (struct rtc_state *)opaque;
    int64_t alarm;
    switch(offset) {
        case 0x8:
            s->alarm_low = value;
            alarm = s->alarm_low | (int64_t)s->alarm_high << 32;
            //printf("next alarm at %lld, tps %lld\n", alarm, ticks_per_sec);
            //qemu_mod_timer(s->timer, alarm);
            break;
        case 0xc:
            s->alarm_high = value;
            //printf("alarm_high %d\n", s->alarm_high);
            break;
        case 0x10:
            goldfish_device_set_irq(&s->dev, 0, 0);
            break;
        default:
            cpu_abort (cpu_single_env, "goldfish_rtc_write: Bad offset %x\n", offset);
    }
}
Пример #30
0
static uint32_t goldfish_sensor_read(void *opaque, target_phys_addr_t offset)
{
    uint32_t ret;
    struct goldfish_sensor_state *s = opaque;
    offset -= s->dev.base;
    switch(offset) {
        case INT_ENABLE:
            // return current buffer status flags
            ret = s->int_status & s->int_enable;
            if (ret) {
                goldfish_device_set_irq(&s->dev, 0, 0);
                s->int_status = 0;
            }
            return ret;

        case ACCEL_X:
            return s->accel_x;
        case ACCEL_Y:
            return s->accel_y;
        case ACCEL_Z:
            return s->accel_z;
        case COMPASS_X:
            return s->compass_x;
        case COMPASS_Y:
            return s->compass_y;
        case COMPASS_Z:
            return s->compass_z;
        case ORIENT_X:
            return s->orient_x;
        case ORIENT_Y:
            return s->orient_y;
        case ORIENT_Z:
            return s->orient_z;
        default:
            cpu_abort (cpu_single_env, "goldfish_sensor_read: Bad offset %x\n", offset);
            return 0;
    }
}