[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v10 06/10] target-avr: adding helpers for IN, OU
From: |
Richard Henderson |
Subject: |
Re: [Qemu-devel] [PATCH v10 06/10] target-avr: adding helpers for IN, OUT, SLEEP, WBR & unsupported instructions |
Date: |
Tue, 12 Jul 2016 10:22:18 -0700 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.1.1 |
On 07/06/2016 03:33 PM, Michael Rolnik wrote:
> Signed-off-by: Michael Rolnik <address@hidden>
> ---
> target-avr/helper.c | 222
> +++++++++++++++++++++++++++++++++++++++++++++++++---
> target-avr/helper.h | 6 ++
> 2 files changed, 215 insertions(+), 13 deletions(-)
>
> diff --git a/target-avr/helper.c b/target-avr/helper.c
> index 060b2f0..1a324cb 100644
> --- a/target-avr/helper.c
> +++ b/target-avr/helper.c
> @@ -42,14 +42,14 @@ bool avr_cpu_exec_interrupt(CPUState *cs, int
> interrupt_request)
> cs->exception_index = EXCP_RESET;
> cc->do_interrupt(cs);
>
> - cs->interrupt_request &= ~CPU_INTERRUPT_RESET;
> + cs->interrupt_request &= ~CPU_INTERRUPT_RESET;
>
> ret = true;
> }
> }
> if (interrupt_request & CPU_INTERRUPT_HARD) {
> if (cpu_interrupts_enabled(env) && env->intsrc != 0) {
> - int index = ctz32(env->intsrc);
> + int index = ctz32(env->intsrc);
> cs->exception_index = EXCP_INT(index);
> cc->do_interrupt(cs);
>
> @@ -64,8 +64,8 @@ bool avr_cpu_exec_interrupt(CPUState *cs, int
> interrupt_request)
>
> void avr_cpu_do_interrupt(CPUState *cs)
> {
> - AVRCPU *cpu = AVR_CPU(cs);
> - CPUAVRState *env = &cpu->env;
> + AVRCPU *cpu = AVR_CPU(cs);
> + CPUAVRState *env = &cpu->env;
>
> uint32_t ret = env->pc_w;
> int vector = 0;
> @@ -79,14 +79,14 @@ void avr_cpu_do_interrupt(CPUState *cs)
> }
>
> if (avr_feature(env, AVR_FEATURE_3_BYTE_PC)) {
> - stb_phys(cs->as, env->sp--, (ret & 0x0000ff));
> - stb_phys(cs->as, env->sp--, (ret & 0x00ff00) >> 8);
> - stb_phys(cs->as, env->sp--, (ret & 0xff0000) >> 16);
> + cpu_stb_data(env, env->sp--, (ret & 0x0000ff));
> + cpu_stb_data(env, env->sp--, (ret & 0x00ff00) >> 8);
> + cpu_stb_data(env, env->sp--, (ret & 0xff0000) >> 16);
> } else if (avr_feature(env, AVR_FEATURE_2_BYTE_PC)) {
> - stb_phys(cs->as, env->sp--, (ret & 0x0000ff));
> - stb_phys(cs->as, env->sp--, (ret & 0x00ff00) >> 8);
> + cpu_stb_data(env, env->sp--, (ret & 0x0000ff));
> + cpu_stb_data(env, env->sp--, (ret & 0x00ff00) >> 8);
> } else {
> - stb_phys(cs->as, env->sp--, (ret & 0x0000ff));
> + cpu_stb_data(env, env->sp--, (ret & 0x0000ff));
> }
>
> env->pc_w = base + vector * size;
> @@ -124,15 +124,55 @@ void tlb_fill(CPUState *cs, target_ulong vaddr, int
> is_write,
> vaddr &= TARGET_PAGE_MASK;
>
> if (mmu_idx == MMU_CODE_IDX) {
> - paddr = PHYS_BASE_CODE + vaddr;
> + paddr = PHYS_BASE_CODE + vaddr - VIRT_BASE_CODE;
> prot = PAGE_READ | PAGE_EXEC;
> } else {
> - paddr = PHYS_BASE_DATA + vaddr;
> - prot = PAGE_READ | PAGE_WRITE;
> +#if VIRT_BASE_REGS == 0
> + if (vaddr < VIRT_BASE_REGS + SIZE_REGS) {
> +#else
> + if (VIRT_BASE_REGS <= vaddr && vaddr < VIRT_BASE_REGS + SIZE_REGS) {
> +#endif
if (vaddr - VIRT_BASE_REGS < SIZE_REGS)
> + /*
> + this is a write into CPU registers, exit and rebuilt this TB
> + to use full write
> + */
> + AVRCPU *cpu = AVR_CPU(cs);
> + CPUAVRState *env = &cpu->env;
> + env->fullwr = 1;
> + cpu_loop_exit_restore(cs, retaddr);
> + } else {
> + /*
> + this is a write into memory. nothing special
> + */
> + paddr = PHYS_BASE_DATA + vaddr - VIRT_BASE_DATA;
> + prot = PAGE_READ | PAGE_WRITE;
> + }
> }
Everything above here should be folded back into a previous patch.
r~
>
> tlb_set_page_with_attrs(cs, vaddr, paddr, attrs, prot, mmu_idx,
> page_size);
> }
> +void helper_sleep(CPUAVRState *env)
> +{
> + CPUState *cs = CPU(avr_env_get_cpu(env));
> +
> + cs->exception_index = EXCP_HLT;
> + cpu_loop_exit(cs);
> +}
> +void helper_unsupported(CPUAVRState *env)
> +{
> + CPUState *cs = CPU(avr_env_get_cpu(env));
> +
> + /*
> + I count not find what happens on the real platform, so
> + it's EXCP_DEBUG for meanwhile
> + */
> + cs->exception_index = EXCP_DEBUG;
> + if (qemu_loglevel_mask(LOG_UNIMP)) {
> + qemu_log("UNSUPPORTED\n");
> + cpu_dump_state(cs, qemu_logfile, fprintf, 0);
> + }
> + cpu_loop_exit(cs);
> +}
>
> void helper_debug(CPUAVRState *env)
> {
> @@ -142,3 +182,159 @@ void helper_debug(CPUAVRState *env)
> cpu_loop_exit(cs);
> }
>
> +void helper_wdr(CPUAVRState *env)
> +{
> + CPUState *cs = CPU(avr_env_get_cpu(env));
> +
> + /*
> + WD is not implemented yet, placeholder
> + */
> + cs->exception_index = EXCP_DEBUG;
> + cpu_loop_exit(cs);
> +}
> +
> +target_ulong helper_inb(CPUAVRState *env, uint32_t port)
> +{
> + target_ulong data = 0;
> +
> + switch (port) {
> + case 0x38: {
> + data = 0xff & (env->rampD >> 16); /* RAMPD */
> + break;
> + }
> + case 0x39: {
> + data = 0xff & (env->rampX >> 16); /* RAMPX */
> + break;
> + }
> + case 0x3a: {
> + data = 0xff & (env->rampY >> 16); /* RAMPY */
> + break;
> + }
> + case 0x3b: {
> + data = 0xff & (env->rampZ >> 16); /* RAMPZ */
> + break;
> + }
> + case 0x3c: {
> + data = 0xff & (env->eind >> 16); /* EIND */
> + break;
> + }
> + case 0x3d: { /* SPL */
> + data = env->sp & 0x00ff;
> + break;
> + }
> + case 0x3e: { /* SPH */
> + data = env->sp >> 8;
> + break;
> + }
> + case 0x3f: { /* SREG */
> + data = cpu_get_sreg(env);
> + break;
> + }
> + default: {
> + /*
> + CPU does not know how to read this register, pass it to the
> + device/board
> + */
> +
> + cpu_physical_memory_read(PHYS_BASE_REGS + port + OFFS_IOREGS,
> + &data,
> 1);
> + }
> + }
> +
> + if (port < IO_REGS) {
> + env->io[port] = data; /* make a copy for SBI, SBIC, SBIS & CBI
> */
> + }
> +
> + return data;
> +}
> +
> +void helper_fullwr(CPUAVRState *env, uint32_t data, uint32_t addr)
> +{
> +#if VIRT_BASE_REGS == 0
> + if (addr <= VIRT_BASE_REGS + SIZE_REGS) {
> +#else
> + if (VIRT_BASE_REGS <= addr && addr <= VIRT_BASE_REGS + SIZE_REGS) {
> +#endif
> + /*
> + write CPU REGS/IO REGS/EXT IO REGS
> + */
> + cpu_physical_memory_write(PHYS_BASE_REGS + addr - VIRT_BASE_REGS,
> + &data,
> 1);
> + } else {
> + /*
> + write memory
> + */
> + cpu_physical_memory_write(PHYS_BASE_DATA + addr - VIRT_BASE_DATA,
> + &data,
> 1);
> + }
> +}
> +
> +void helper_outb(CPUAVRState *env, uint32_t port, uint32_t data)
> +{
> + data &= 0x000000ff;
> +
> + switch (port) {
> + case 0x04: {
> + qemu_irq irq;
> + CPUState *cpu = CPU(avr_env_get_cpu(env));
> + irq = qdev_get_gpio_in(DEVICE(cpu), 3);
> + qemu_set_irq(irq, 1);
> + break;
> + }
> + case 0x38: {
> + if (avr_feature(env, AVR_FEATURE_RAMPD)) {
> + env->rampD = (data & 0xff) << 16; /* RAMPD */
> + }
> + break;
> + }
> + case 0x39: {
> + if (avr_feature(env, AVR_FEATURE_RAMPX)) {
> + env->rampX = (data & 0xff) << 16; /* RAMPX */
> + }
> + break;
> + }
> + case 0x3a: {
> + if (avr_feature(env, AVR_FEATURE_RAMPY)) {
> + env->rampY = (data & 0xff) << 16; /* RAMPY */
> + }
> + break;
> + }
> + case 0x3b: {
> + if (avr_feature(env, AVR_FEATURE_RAMPZ)) {
> + env->rampZ = (data & 0xff) << 16; /* RAMPZ */
> + }
> + break;
> + }
> + case 0x3c: {
> + env->eind = (data & 0xff) << 16; /* EIDN */
> + break;
> + }
> + case 0x3d: { /* SPL */
> + env->sp = (env->sp & 0xff00) | (data);
> + break;
> + }
> + case 0x3e: { /* SPH */
> + if (avr_feature(env, AVR_FEATURE_2_BYTE_SP)) {
> + env->sp = (env->sp & 0x00ff) | (data << 8);
> + }
> + break;
> + }
> + case 0x3f: { /* SREG */
> + cpu_set_sreg(env, data);
> + break;
> + }
> + default: {
> + /*
> + CPU does not know how to write this register, pass it to the
> + device/board
> + */
> + cpu_physical_memory_write(PHYS_BASE_REGS + port + OFFS_IOREGS,
> + &data,
> 1);
> + }
> + }
> +
> + if (port < IO_REGS) {
> + env->io[port] = data; /* make a copy for SBI, SBIC, SBIS & CBI
> */
> + }
> +}
> +
> diff --git a/target-avr/helper.h b/target-avr/helper.h
> index b5ef3bf..19e0ab7 100644
> --- a/target-avr/helper.h
> +++ b/target-avr/helper.h
> @@ -18,4 +18,10 @@
> * <http://www.gnu.org/licenses/lgpl-2.1.html>
> */
>
> +DEF_HELPER_1(wdr, void, env)
> DEF_HELPER_1(debug, void, env)
> +DEF_HELPER_1(sleep, void, env)
> +DEF_HELPER_1(unsupported, void, env)
> +DEF_HELPER_3(outb, void, env, i32, i32)
> +DEF_HELPER_2(inb, tl, env, i32)
> +DEF_HELPER_3(fullwr, void, env, i32, i32)
>
- [Qemu-devel] [PATCH v10 03/10] target-avr: adding a sample AVR board, (continued)
- [Qemu-devel] [PATCH v10 03/10] target-avr: adding a sample AVR board, Michael Rolnik, 2016/07/06
- [Qemu-devel] [PATCH v10 01/10] target-avr: AVR cores support is added., Michael Rolnik, 2016/07/06
- Re: [Qemu-devel] [PATCH v10 01/10] target-avr: AVR cores support is added., Richard Henderson, 2016/07/12
- Re: [Qemu-devel] [PATCH v10 01/10] target-avr: AVR cores support is added., Michael Rolnik, 2016/07/12
- Re: [Qemu-devel] [PATCH v10 01/10] target-avr: AVR cores support is added., Richard Henderson, 2016/07/13
- Re: [Qemu-devel] [PATCH v10 01/10] target-avr: AVR cores support is added., Michael Rolnik, 2016/07/13
- Re: [Qemu-devel] [PATCH v10 01/10] target-avr: AVR cores support is added., Michael Rolnik, 2016/07/13
- Re: [Qemu-devel] [PATCH v10 01/10] target-avr: AVR cores support is added., Richard Henderson, 2016/07/13
[Qemu-devel] [PATCH v10 05/10] target-avr: adding AVR interrupt handling, Michael Rolnik, 2016/07/06
[Qemu-devel] [PATCH v10 06/10] target-avr: adding helpers for IN, OUT, SLEEP, WBR & unsupported instructions, Michael Rolnik, 2016/07/06
- Re: [Qemu-devel] [PATCH v10 06/10] target-avr: adding helpers for IN, OUT, SLEEP, WBR & unsupported instructions,
Richard Henderson <=
[Qemu-devel] [PATCH v10 04/10] target-avr: adding instructions encodings, Michael Rolnik, 2016/07/06
[Qemu-devel] [PATCH v10 07/10] target-avr: adding instruction decoder, Michael Rolnik, 2016/07/06
[Qemu-devel] [PATCH v10 09/10] target-avr: updating translate.c to use instructions translation, Michael Rolnik, 2016/07/06
[Qemu-devel] [PATCH v10 10/10] target-avr: instruction decoder generator, Michael Rolnik, 2016/07/06
[Qemu-devel] [PATCH v10 08/10] target-avr: adding instruction translation, Michael Rolnik, 2016/07/06