mirror of https://github.com/xemu-project/xemu.git
target-arm: Implement AArch64 generic timers
Implement the AArch64 view of the generic timer system registers. Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
4b7fff2fab
commit
a7adc4b779
|
@ -104,7 +104,7 @@ struct arm_boot_info;
|
|||
/* CPU state for each instance of a generic timer (in cp15 c14) */
|
||||
typedef struct ARMGenericTimer {
|
||||
uint64_t cval; /* Timer CompareValue register */
|
||||
uint32_t ctl; /* Timer Control register */
|
||||
uint64_t ctl; /* Timer Control register */
|
||||
} ARMGenericTimer;
|
||||
|
||||
#define GTIMER_PHYS 0
|
||||
|
@ -204,8 +204,8 @@ typedef struct CPUARMState {
|
|||
uint64_t tpidr_el0; /* User RW Thread register. */
|
||||
uint64_t tpidrro_el0; /* User RO Thread register. */
|
||||
uint64_t tpidr_el1; /* Privileged Thread register. */
|
||||
uint32_t c14_cntfrq; /* Counter Frequency register */
|
||||
uint32_t c14_cntkctl; /* Timer Control register */
|
||||
uint64_t c14_cntfrq; /* Counter Frequency register */
|
||||
uint64_t c14_cntkctl; /* Timer Control register */
|
||||
ARMGenericTimer c14_timer[NUM_GTIMERS];
|
||||
uint32_t c15_cpar; /* XScale Coprocessor Access Register */
|
||||
uint32_t c15_ticonfig; /* TI925T configuration byte. */
|
||||
|
|
|
@ -901,30 +901,55 @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
|
|||
* Our reset value matches the fixed frequency we implement the timer at.
|
||||
*/
|
||||
{ .name = "CNTFRQ", .cp = 15, .crn = 14, .crm = 0, .opc1 = 0, .opc2 = 0,
|
||||
.access = PL1_RW | PL0_R,
|
||||
.type = ARM_CP_NO_MIGRATE,
|
||||
.access = PL1_RW | PL0_R, .accessfn = gt_cntfrq_access,
|
||||
.fieldoffset = offsetoflow32(CPUARMState, cp15.c14_cntfrq),
|
||||
.resetfn = arm_cp_reset_ignore,
|
||||
},
|
||||
{ .name = "CNTFRQ_EL0", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 0,
|
||||
.access = PL1_RW | PL0_R, .accessfn = gt_cntfrq_access,
|
||||
.fieldoffset = offsetof(CPUARMState, cp15.c14_cntfrq),
|
||||
.resetvalue = (1000 * 1000 * 1000) / GTIMER_SCALE,
|
||||
.accessfn = gt_cntfrq_access,
|
||||
},
|
||||
/* overall control: mostly access permissions */
|
||||
{ .name = "CNTKCTL", .cp = 15, .crn = 14, .crm = 1, .opc1 = 0, .opc2 = 0,
|
||||
{ .name = "CNTKCTL", .state = ARM_CP_STATE_BOTH,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 14, .crm = 1, .opc2 = 0,
|
||||
.access = PL1_RW,
|
||||
.fieldoffset = offsetof(CPUARMState, cp15.c14_cntkctl),
|
||||
.resetvalue = 0,
|
||||
},
|
||||
/* per-timer control */
|
||||
{ .name = "CNTP_CTL", .cp = 15, .crn = 14, .crm = 2, .opc1 = 0, .opc2 = 1,
|
||||
.type = ARM_CP_IO | ARM_CP_NO_MIGRATE, .access = PL1_RW | PL0_R,
|
||||
.accessfn = gt_ptimer_access,
|
||||
.fieldoffset = offsetoflow32(CPUARMState,
|
||||
cp15.c14_timer[GTIMER_PHYS].ctl),
|
||||
.resetfn = arm_cp_reset_ignore,
|
||||
.writefn = gt_ctl_write, .raw_writefn = raw_write,
|
||||
},
|
||||
{ .name = "CNTP_CTL_EL0", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 2, .opc2 = 1,
|
||||
.type = ARM_CP_IO, .access = PL1_RW | PL0_R,
|
||||
.accessfn = gt_ptimer_access,
|
||||
.fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].ctl),
|
||||
.resetvalue = 0,
|
||||
.accessfn = gt_ptimer_access,
|
||||
.writefn = gt_ctl_write, .raw_writefn = raw_write,
|
||||
},
|
||||
{ .name = "CNTV_CTL", .cp = 15, .crn = 14, .crm = 3, .opc1 = 0, .opc2 = 1,
|
||||
.type = ARM_CP_IO | ARM_CP_NO_MIGRATE, .access = PL1_RW | PL0_R,
|
||||
.accessfn = gt_vtimer_access,
|
||||
.fieldoffset = offsetoflow32(CPUARMState,
|
||||
cp15.c14_timer[GTIMER_VIRT].ctl),
|
||||
.resetfn = arm_cp_reset_ignore,
|
||||
.writefn = gt_ctl_write, .raw_writefn = raw_write,
|
||||
},
|
||||
{ .name = "CNTV_CTL_EL0", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 3, .opc2 = 1,
|
||||
.type = ARM_CP_IO, .access = PL1_RW | PL0_R,
|
||||
.accessfn = gt_vtimer_access,
|
||||
.fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].ctl),
|
||||
.resetvalue = 0,
|
||||
.accessfn = gt_vtimer_access,
|
||||
.writefn = gt_ctl_write, .raw_writefn = raw_write,
|
||||
},
|
||||
/* TimerValue views: a 32 bit downcounting view of the underlying state */
|
||||
|
@ -933,37 +958,73 @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
|
|||
.accessfn = gt_ptimer_access,
|
||||
.readfn = gt_tval_read, .writefn = gt_tval_write,
|
||||
},
|
||||
{ .name = "CNTP_TVAL_EL0", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 2, .opc2 = 0,
|
||||
.type = ARM_CP_NO_MIGRATE | ARM_CP_IO, .access = PL1_RW | PL0_R,
|
||||
.readfn = gt_tval_read, .writefn = gt_tval_write,
|
||||
},
|
||||
{ .name = "CNTV_TVAL", .cp = 15, .crn = 14, .crm = 3, .opc1 = 0, .opc2 = 0,
|
||||
.type = ARM_CP_NO_MIGRATE | ARM_CP_IO, .access = PL1_RW | PL0_R,
|
||||
.accessfn = gt_vtimer_access,
|
||||
.readfn = gt_tval_read, .writefn = gt_tval_write,
|
||||
},
|
||||
{ .name = "CNTV_TVAL_EL0", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 3, .opc2 = 0,
|
||||
.type = ARM_CP_NO_MIGRATE | ARM_CP_IO, .access = PL1_RW | PL0_R,
|
||||
.readfn = gt_tval_read, .writefn = gt_tval_write,
|
||||
},
|
||||
/* The counter itself */
|
||||
{ .name = "CNTPCT", .cp = 15, .crm = 14, .opc1 = 0,
|
||||
.access = PL0_R, .type = ARM_CP_64BIT | ARM_CP_NO_MIGRATE | ARM_CP_IO,
|
||||
.accessfn = gt_pct_access,
|
||||
.readfn = gt_cnt_read, .resetfn = arm_cp_reset_ignore,
|
||||
},
|
||||
{ .name = "CNTPCT_EL0", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 1,
|
||||
.access = PL0_R, .type = ARM_CP_NO_MIGRATE | ARM_CP_IO,
|
||||
.accessfn = gt_pct_access,
|
||||
.readfn = gt_cnt_read, .resetfn = gt_cnt_reset,
|
||||
},
|
||||
{ .name = "CNTVCT", .cp = 15, .crm = 14, .opc1 = 1,
|
||||
.access = PL0_R, .type = ARM_CP_64BIT | ARM_CP_NO_MIGRATE | ARM_CP_IO,
|
||||
.accessfn = gt_vct_access,
|
||||
.readfn = gt_cnt_read, .resetfn = arm_cp_reset_ignore,
|
||||
},
|
||||
{ .name = "CNTVCT_EL0", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 2,
|
||||
.access = PL0_R, .type = ARM_CP_NO_MIGRATE | ARM_CP_IO,
|
||||
.accessfn = gt_vct_access,
|
||||
.readfn = gt_cnt_read, .resetfn = gt_cnt_reset,
|
||||
},
|
||||
/* Comparison value, indicating when the timer goes off */
|
||||
{ .name = "CNTP_CVAL", .cp = 15, .crm = 14, .opc1 = 2,
|
||||
.access = PL1_RW | PL0_R,
|
||||
.type = ARM_CP_64BIT | ARM_CP_IO,
|
||||
.type = ARM_CP_64BIT | ARM_CP_IO | ARM_CP_NO_MIGRATE,
|
||||
.fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].cval),
|
||||
.resetvalue = 0,
|
||||
.accessfn = gt_ptimer_access,
|
||||
.accessfn = gt_ptimer_access, .resetfn = arm_cp_reset_ignore,
|
||||
.writefn = gt_cval_write, .raw_writefn = raw_write,
|
||||
},
|
||||
{ .name = "CNTP_CVAL_EL0", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 2, .opc2 = 2,
|
||||
.access = PL1_RW | PL0_R,
|
||||
.type = ARM_CP_IO,
|
||||
.fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].cval),
|
||||
.resetvalue = 0, .accessfn = gt_vtimer_access,
|
||||
.writefn = gt_cval_write, .raw_writefn = raw_write,
|
||||
},
|
||||
{ .name = "CNTV_CVAL", .cp = 15, .crm = 14, .opc1 = 3,
|
||||
.access = PL1_RW | PL0_R,
|
||||
.type = ARM_CP_64BIT | ARM_CP_IO,
|
||||
.type = ARM_CP_64BIT | ARM_CP_IO | ARM_CP_NO_MIGRATE,
|
||||
.fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].cval),
|
||||
.resetvalue = 0,
|
||||
.accessfn = gt_vtimer_access,
|
||||
.accessfn = gt_vtimer_access, .resetfn = arm_cp_reset_ignore,
|
||||
.writefn = gt_cval_write, .raw_writefn = raw_write,
|
||||
},
|
||||
{ .name = "CNTV_CVAL_EL0", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 3, .opc2 = 2,
|
||||
.access = PL1_RW | PL0_R,
|
||||
.type = ARM_CP_IO,
|
||||
.fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].cval),
|
||||
.resetvalue = 0, .accessfn = gt_vtimer_access,
|
||||
.writefn = gt_cval_write, .raw_writefn = raw_write,
|
||||
},
|
||||
REGINFO_SENTINEL
|
||||
|
|
Loading…
Reference in New Issue