Commit ffb62da7 authored by Anthony Liguori's avatar Anthony Liguori
Browse files

Merge remote-tracking branch 'jliu/or32' into staging



# By Sebastian Macke
# Via Jia Liu
* jliu/or32:
  target-openrisc: Correct carry flag check of l.addc and l.addic test cases
  target-openrisc: Correct memory bounds checking for the tlb buffers
  openrisc-timer: Reduce overhead, Separate clock update functions
  target-openrisc: Correct wrong epcr register in interrupt handler
  target-openrisc: Remove executable flag for every page
  target-openrisc: Remove unnecessary code generated by jump instructions
  target-openrisc: Speed up move instruction

Message-id: 1384958318-9145-1-git-send-email-proljc@gmail.com
Signed-off-by: default avatarAnthony Liguori <aliguori@amazon.com>
parents 425ff510 14a650ec
Loading
Loading
Loading
Loading
+19 −10
Original line number Diff line number Diff line
@@ -30,19 +30,28 @@ static int is_counting;

void cpu_openrisc_count_update(OpenRISCCPU *cpu)
{
    uint64_t now, next;
    uint32_t wait;
    uint64_t now;

    now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
    if (!is_counting) {
        timer_del(cpu->env.timer);
        last_clk = now;
        return;
    }

    now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
    cpu->env.ttcr += (uint32_t)muldiv64(now - last_clk, TIMER_FREQ,
                                        get_ticks_per_sec());
    last_clk = now;
}

void cpu_openrisc_timer_update(OpenRISCCPU *cpu)
{
    uint32_t wait;
    uint64_t now, next;

    if (!is_counting) {
        return;
    }

    cpu_openrisc_count_update(cpu);
    now = last_clk;

    if ((cpu->env.ttmr & TTMR_TP) <= (cpu->env.ttcr & TTMR_TP)) {
        wait = TTMR_TP - (cpu->env.ttcr & TTMR_TP) + 1;
@@ -50,7 +59,6 @@ void cpu_openrisc_count_update(OpenRISCCPU *cpu)
    } else {
        wait = (cpu->env.ttmr & TTMR_TP) - (cpu->env.ttcr & TTMR_TP);
    }

    next = now + muldiv64(wait, get_ticks_per_sec(), TIMER_FREQ);
    timer_mod(cpu->env.timer, next);
}
@@ -63,8 +71,9 @@ void cpu_openrisc_count_start(OpenRISCCPU *cpu)

void cpu_openrisc_count_stop(OpenRISCCPU *cpu)
{
    is_counting = 0;
    timer_del(cpu->env.timer);
    cpu_openrisc_count_update(cpu);
    is_counting = 0;
}

static void openrisc_timer_cb(void *opaque)
@@ -84,15 +93,15 @@ static void openrisc_timer_cb(void *opaque)
        break;
    case TIMER_INTR:
        cpu->env.ttcr = 0;
        cpu_openrisc_count_start(cpu);
        break;
    case TIMER_SHOT:
        cpu_openrisc_count_stop(cpu);
        break;
    case TIMER_CONT:
        cpu_openrisc_count_start(cpu);
        break;
    }

    cpu_openrisc_timer_update(cpu);
}

void cpu_openrisc_clock_init(OpenRISCCPU *cpu)
+1 −0
Original line number Diff line number Diff line
@@ -373,6 +373,7 @@ void cpu_openrisc_pic_init(OpenRISCCPU *cpu);
/* hw/openrisc_timer.c */
void cpu_openrisc_clock_init(OpenRISCCPU *cpu);
void cpu_openrisc_count_update(OpenRISCCPU *cpu);
void cpu_openrisc_timer_update(OpenRISCCPU *cpu);
void cpu_openrisc_count_start(OpenRISCCPU *cpu);
void cpu_openrisc_count_stop(OpenRISCCPU *cpu);

+7 −18
Original line number Diff line number Diff line
@@ -30,26 +30,15 @@ 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->epcr = env->pc;
    if (env->flags & D_FLAG) {
        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;
        env->epcr -= 4;
    }
    if (env->exception_index == EXCP_SYSCALL) {
        env->epcr += 4;
    }

    /* For machine-state changed between user-mode and supervisor mode,
+2 −2
Original line number Diff line number Diff line
@@ -32,7 +32,7 @@ int cpu_openrisc_get_phys_nommu(OpenRISCCPU *cpu,
                                int *prot, target_ulong address, int rw)
{
    *physical = address;
    *prot = PAGE_READ | PAGE_WRITE;
    *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
    return TLBRET_MATCH;
}

@@ -187,7 +187,7 @@ int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env,

    if (ret == TLBRET_MATCH) {
        tlb_set_page(env, address & TARGET_PAGE_MASK,
                     physical & TARGET_PAGE_MASK, prot | PAGE_EXEC,
                     physical & TARGET_PAGE_MASK, prot,
                     mmu_idx, TARGET_PAGE_SIZE);
        ret = 0;
    } else if (ret < 0) {
+26 −28
Original line number Diff line number Diff line
@@ -81,7 +81,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
    case TO_SPR(0, 64): /* ESR */
        env->esr = rb;
        break;
    case TO_SPR(1, 512) ... TO_SPR(1, 639): /* DTLBW0MR 0-127 */
    case TO_SPR(1, 512) ... TO_SPR(1, 512+DTLB_SIZE-1): /* DTLBW0MR 0-127 */
        idx = spr - TO_SPR(1, 512);
        if (!(rb & 1)) {
            tlb_flush_page(env, env->tlb->dtlb[0][idx].mr & TARGET_PAGE_MASK);
@@ -89,7 +89,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
        env->tlb->dtlb[0][idx].mr = rb;
        break;

    case TO_SPR(1, 640) ... TO_SPR(1, 767): /* DTLBW0TR 0-127 */
    case TO_SPR(1, 640) ... TO_SPR(1, 640+DTLB_SIZE-1): /* DTLBW0TR 0-127 */
        idx = spr - TO_SPR(1, 640);
        env->tlb->dtlb[0][idx].tr = rb;
        break;
@@ -100,7 +100,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
    case TO_SPR(1, 1280) ... TO_SPR(1, 1407): /* DTLBW3MR 0-127 */
    case TO_SPR(1, 1408) ... TO_SPR(1, 1535): /* DTLBW3TR 0-127 */
        break;
    case TO_SPR(2, 512) ... TO_SPR(2, 639):   /* ITLBW0MR 0-127 */
    case TO_SPR(2, 512) ... TO_SPR(2, 512+ITLB_SIZE-1):   /* ITLBW0MR 0-127 */
        idx = spr - TO_SPR(2, 512);
        if (!(rb & 1)) {
            tlb_flush_page(env, env->tlb->itlb[0][idx].mr & TARGET_PAGE_MASK);
@@ -108,7 +108,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
        env->tlb->itlb[0][idx].mr = rb;
        break;

    case TO_SPR(2, 640) ... TO_SPR(2, 767): /* ITLBW0TR 0-127 */
    case TO_SPR(2, 640) ... TO_SPR(2, 640+ITLB_SIZE-1): /* ITLBW0TR 0-127 */
        idx = spr - TO_SPR(2, 640);
        env->tlb->itlb[0][idx].tr = rb;
        break;
@@ -127,27 +127,13 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
        break;
    case TO_SPR(10, 0): /* TTMR */
        {
            int ip = env->ttmr & TTMR_IP;

            if (rb & TTMR_IP) {    /* Keep IP bit.  */
                env->ttmr = (rb & ~TTMR_IP) + ip;
            } else {    /* Clear IP bit.  */
                env->ttmr = rb & ~TTMR_IP;
                cs->interrupt_request &= ~CPU_INTERRUPT_TIMER;
            }

            cpu_openrisc_count_update(cpu);

            switch (env->ttmr & TTMR_M) {
            if ((env->ttmr & TTMR_M) ^ (rb & TTMR_M)) {
                switch (rb & TTMR_M) {
                case TIMER_NONE:
                    cpu_openrisc_count_stop(cpu);
                    break;
                case TIMER_INTR:
                cpu_openrisc_count_start(cpu);
                break;
                case TIMER_SHOT:
                cpu_openrisc_count_start(cpu);
                break;
                case TIMER_CONT:
                    cpu_openrisc_count_start(cpu);
                    break;
@@ -155,6 +141,18 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
                    break;
                }
            }

            int ip = env->ttmr & TTMR_IP;

            if (rb & TTMR_IP) {    /* Keep IP bit.  */
                env->ttmr = (rb & ~TTMR_IP) | ip;
            } else {    /* Clear IP bit.  */
                env->ttmr = rb & ~TTMR_IP;
                cs->interrupt_request &= ~CPU_INTERRUPT_TIMER;
            }

            cpu_openrisc_timer_update(cpu);
        }
        break;

    case TO_SPR(10, 1): /* TTCR */
@@ -162,7 +160,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
        if (env->ttmr & TIMER_NONE) {
            return;
        }
        cpu_openrisc_count_start(cpu);
        cpu_openrisc_timer_update(cpu);
        break;
    default:

@@ -214,11 +212,11 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env,
    case TO_SPR(0, 64): /* ESR */
        return env->esr;

    case TO_SPR(1, 512) ... TO_SPR(1, 639): /* DTLBW0MR 0-127 */
    case TO_SPR(1, 512) ... TO_SPR(1, 512+DTLB_SIZE-1): /* DTLBW0MR 0-127 */
        idx = spr - TO_SPR(1, 512);
        return env->tlb->dtlb[0][idx].mr;

    case TO_SPR(1, 640) ... TO_SPR(1, 767): /* DTLBW0TR 0-127 */
    case TO_SPR(1, 640) ... TO_SPR(1, 640+DTLB_SIZE-1): /* DTLBW0TR 0-127 */
        idx = spr - TO_SPR(1, 640);
        return env->tlb->dtlb[0][idx].tr;

@@ -230,11 +228,11 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env,
    case TO_SPR(1, 1408) ... TO_SPR(1, 1535): /* DTLBW3TR 0-127 */
        break;

    case TO_SPR(2, 512) ... TO_SPR(2, 639): /* ITLBW0MR 0-127 */
    case TO_SPR(2, 512) ... TO_SPR(2, 512+ITLB_SIZE-1): /* ITLBW0MR 0-127 */
        idx = spr - TO_SPR(2, 512);
        return env->tlb->itlb[0][idx].mr;

    case TO_SPR(2, 640) ... TO_SPR(2, 767): /* ITLBW0TR 0-127 */
    case TO_SPR(2, 640) ... TO_SPR(2, 640+ITLB_SIZE-1): /* ITLBW0TR 0-127 */
        idx = spr - TO_SPR(2, 640);
        return env->tlb->itlb[0][idx].tr;

Loading