Revision 00108f2d

b/target-arm/helper.c
743 743

  
744 744
#ifndef CONFIG_USER_ONLY
745 745

  
746
static CPAccessResult gt_cntfrq_access(CPUARMState *env, const ARMCPRegInfo *ri)
747
{
748
    /* CNTFRQ: not visible from PL0 if both PL0PCTEN and PL0VCTEN are zero */
749
    if (arm_current_pl(env) == 0 && !extract32(env->cp15.c14_cntkctl, 0, 2)) {
750
        return CP_ACCESS_TRAP;
751
    }
752
    return CP_ACCESS_OK;
753
}
754

  
755
static CPAccessResult gt_counter_access(CPUARMState *env, int timeridx)
756
{
757
    /* CNT[PV]CT: not visible from PL0 if ELO[PV]CTEN is zero */
758
    if (arm_current_pl(env) == 0 &&
759
        !extract32(env->cp15.c14_cntkctl, timeridx, 1)) {
760
        return CP_ACCESS_TRAP;
761
    }
762
    return CP_ACCESS_OK;
763
}
764

  
765
static CPAccessResult gt_timer_access(CPUARMState *env, int timeridx)
766
{
767
    /* CNT[PV]_CVAL, CNT[PV]_CTL, CNT[PV]_TVAL: not visible from PL0 if
768
     * EL0[PV]TEN is zero.
769
     */
770
    if (arm_current_pl(env) == 0 &&
771
        !extract32(env->cp15.c14_cntkctl, 9 - timeridx, 1)) {
772
        return CP_ACCESS_TRAP;
773
    }
774
    return CP_ACCESS_OK;
775
}
776

  
777
static CPAccessResult gt_pct_access(CPUARMState *env,
778
                                         const ARMCPRegInfo *ri)
779
{
780
    return gt_counter_access(env, GTIMER_PHYS);
781
}
782

  
783
static CPAccessResult gt_vct_access(CPUARMState *env,
784
                                         const ARMCPRegInfo *ri)
785
{
786
    return gt_counter_access(env, GTIMER_VIRT);
787
}
788

  
789
static CPAccessResult gt_ptimer_access(CPUARMState *env, const ARMCPRegInfo *ri)
790
{
791
    return gt_timer_access(env, GTIMER_PHYS);
792
}
793

  
794
static CPAccessResult gt_vtimer_access(CPUARMState *env, const ARMCPRegInfo *ri)
795
{
796
    return gt_timer_access(env, GTIMER_VIRT);
797
}
798

  
746 799
static uint64_t gt_get_countervalue(CPUARMState *env)
747 800
{
748 801
    return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / GTIMER_SCALE;
......
788 841
    }
789 842
}
790 843

  
791
static int gt_cntfrq_read(CPUARMState *env, const ARMCPRegInfo *ri,
792
                          uint64_t *value)
793
{
794
    /* Not visible from PL0 if both PL0PCTEN and PL0VCTEN are zero */
795
    if (arm_current_pl(env) == 0 && !extract32(env->cp15.c14_cntkctl, 0, 2)) {
796
        return EXCP_UDEF;
797
    }
798
    *value = env->cp15.c14_cntfrq;
799
    return 0;
800
}
801

  
802 844
static void gt_cnt_reset(CPUARMState *env, const ARMCPRegInfo *ri)
803 845
{
804 846
    ARMCPU *cpu = arm_env_get_cpu(env);
......
810 852
static int gt_cnt_read(CPUARMState *env, const ARMCPRegInfo *ri,
811 853
                       uint64_t *value)
812 854
{
813
    int timeridx = ri->opc1 & 1;
814

  
815
    if (arm_current_pl(env) == 0 &&
816
        !extract32(env->cp15.c14_cntkctl, timeridx, 1)) {
817
        return EXCP_UDEF;
818
    }
819 855
    *value = gt_get_countervalue(env);
820 856
    return 0;
821 857
}
822 858

  
823
static int gt_cval_read(CPUARMState *env, const ARMCPRegInfo *ri,
824
                        uint64_t *value)
825
{
826
    int timeridx = ri->opc1 & 1;
827

  
828
    if (arm_current_pl(env) == 0 &&
829
        !extract32(env->cp15.c14_cntkctl, 9 - timeridx, 1)) {
830
        return EXCP_UDEF;
831
    }
832
    *value = env->cp15.c14_timer[timeridx].cval;
833
    return 0;
834
}
835

  
836 859
static int gt_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
837 860
                         uint64_t value)
838 861
{
......
847 870
{
848 871
    int timeridx = ri->crm & 1;
849 872

  
850
    if (arm_current_pl(env) == 0 &&
851
        !extract32(env->cp15.c14_cntkctl, 9 - timeridx, 1)) {
852
        return EXCP_UDEF;
853
    }
854 873
    *value = (uint32_t)(env->cp15.c14_timer[timeridx].cval -
855 874
                        gt_get_countervalue(env));
856 875
    return 0;
......
867 886
    return 0;
868 887
}
869 888

  
870
static int gt_ctl_read(CPUARMState *env, const ARMCPRegInfo *ri,
871
                       uint64_t *value)
872
{
873
    int timeridx = ri->crm & 1;
874

  
875
    if (arm_current_pl(env) == 0 &&
876
        !extract32(env->cp15.c14_cntkctl, 9 - timeridx, 1)) {
877
        return EXCP_UDEF;
878
    }
879
    *value = env->cp15.c14_timer[timeridx].ctl;
880
    return 0;
881
}
882

  
883 889
static int gt_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
884 890
                        uint64_t value)
885 891
{
......
924 930
      .access = PL1_RW | PL0_R,
925 931
      .fieldoffset = offsetof(CPUARMState, cp15.c14_cntfrq),
926 932
      .resetvalue = (1000 * 1000 * 1000) / GTIMER_SCALE,
927
      .readfn = gt_cntfrq_read, .raw_readfn = raw_read,
933
      .accessfn = gt_cntfrq_access,
928 934
    },
929 935
    /* overall control: mostly access permissions */
930 936
    { .name = "CNTKCTL", .cp = 15, .crn = 14, .crm = 1, .opc1 = 0, .opc2 = 0,
......
937 943
      .type = ARM_CP_IO, .access = PL1_RW | PL0_R,
938 944
      .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].ctl),
939 945
      .resetvalue = 0,
940
      .readfn = gt_ctl_read, .writefn = gt_ctl_write,
941
      .raw_readfn = raw_read, .raw_writefn = raw_write,
946
      .accessfn = gt_ptimer_access,
947
      .writefn = gt_ctl_write, .raw_writefn = raw_write,
942 948
    },
943 949
    { .name = "CNTV_CTL", .cp = 15, .crn = 14, .crm = 3, .opc1 = 0, .opc2 = 1,
944 950
      .type = ARM_CP_IO, .access = PL1_RW | PL0_R,
945 951
      .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].ctl),
946 952
      .resetvalue = 0,
947
      .readfn = gt_ctl_read, .writefn = gt_ctl_write,
948
      .raw_readfn = raw_read, .raw_writefn = raw_write,
953
      .accessfn = gt_vtimer_access,
954
      .writefn = gt_ctl_write, .raw_writefn = raw_write,
949 955
    },
950 956
    /* TimerValue views: a 32 bit downcounting view of the underlying state */
951 957
    { .name = "CNTP_TVAL", .cp = 15, .crn = 14, .crm = 2, .opc1 = 0, .opc2 = 0,
952 958
      .type = ARM_CP_NO_MIGRATE | ARM_CP_IO, .access = PL1_RW | PL0_R,
959
      .accessfn = gt_ptimer_access,
953 960
      .readfn = gt_tval_read, .writefn = gt_tval_write,
954 961
    },
955 962
    { .name = "CNTV_TVAL", .cp = 15, .crn = 14, .crm = 3, .opc1 = 0, .opc2 = 0,
956 963
      .type = ARM_CP_NO_MIGRATE | ARM_CP_IO, .access = PL1_RW | PL0_R,
964
      .accessfn = gt_vtimer_access,
957 965
      .readfn = gt_tval_read, .writefn = gt_tval_write,
958 966
    },
959 967
    /* The counter itself */
960 968
    { .name = "CNTPCT", .cp = 15, .crm = 14, .opc1 = 0,
961 969
      .access = PL0_R, .type = ARM_CP_64BIT | ARM_CP_NO_MIGRATE | ARM_CP_IO,
970
      .accessfn = gt_pct_access,
962 971
      .readfn = gt_cnt_read, .resetfn = gt_cnt_reset,
963 972
    },
964 973
    { .name = "CNTVCT", .cp = 15, .crm = 14, .opc1 = 1,
965 974
      .access = PL0_R, .type = ARM_CP_64BIT | ARM_CP_NO_MIGRATE | ARM_CP_IO,
975
      .accessfn = gt_vct_access,
966 976
      .readfn = gt_cnt_read, .resetfn = gt_cnt_reset,
967 977
    },
968 978
    /* Comparison value, indicating when the timer goes off */
......
971 981
      .type = ARM_CP_64BIT | ARM_CP_IO,
972 982
      .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].cval),
973 983
      .resetvalue = 0,
974
      .readfn = gt_cval_read, .writefn = gt_cval_write,
975
      .raw_readfn = raw_read, .raw_writefn = raw_write,
984
      .accessfn = gt_ptimer_access,
985
      .writefn = gt_cval_write, .raw_writefn = raw_write,
976 986
    },
977 987
    { .name = "CNTV_CVAL", .cp = 15, .crm = 14, .opc1 = 3,
978 988
      .access = PL1_RW | PL0_R,
979 989
      .type = ARM_CP_64BIT | ARM_CP_IO,
980 990
      .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].cval),
981 991
      .resetvalue = 0,
982
      .readfn = gt_cval_read, .writefn = gt_cval_write,
983
      .raw_readfn = raw_read, .raw_writefn = raw_write,
992
      .accessfn = gt_vtimer_access,
993
      .writefn = gt_cval_write, .raw_writefn = raw_write,
984 994
    },
985 995
    REGINFO_SENTINEL
986 996
};

Also available in: Unified diff