summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiuseppe Calderaro <giuseppe.calderaro@arm.com>2012-05-02 15:43:34 +0100
committerDietmar Eggemann <dietmar.eggemann@arm.com>2012-05-23 12:44:34 +0100
commit2c1558d998bece21208ad9c69be892f27a6d9d93 (patch)
treee758adf0492e8b2868c3ff60b24b58663708ff21
parentf085e47d3dc30aefb0e25129537ab35de56b3265 (diff)
vsm: changed HVC calling convention.
hvc now uses: r0 : hvc number r1 : first argument r2 : second argument [..]
-rw-r--r--big-little/Makefile4
-rw-r--r--big-little/common/hyp_vectors.s15
-rw-r--r--big-little/virtualisor/virt_handle.c62
3 files changed, 64 insertions, 17 deletions
diff --git a/big-little/Makefile b/big-little/Makefile
index 58d8d04..6a88800 100644
--- a/big-little/Makefile
+++ b/big-little/Makefile
@@ -61,7 +61,7 @@ endif
vpath %.c switcher switcher/trigger switcher/context common/ lib/ secure_world/ ../acsr
vpath %.s switcher switcher/trigger switcher/context common/ lib/ secure_world/ ../acsr
-SWITCHER_OBJS = ns_context.o hyp_setup.o pagetable_setup.o virt_helpers.o sync_switchover.o \
+SWITCHER_OBJS = ns_context.o hyp_setup.o pagetable_setup.o virt_helpers.o \
vgiclib.o vgic_handle.o uart.o v7.o gic.o handle_switchover.o tube.o ipi.o v7_c.o \
virt_events.o bakery.o vgic_setup.o async_switchover.o hyp_vectors.o helpers.o
@@ -105,7 +105,7 @@ VIRTUALISOR_ASFLAGS += --pd "CMOP_DEBUG SETL {$(CMOP_DEBUG)}"
vpath %.c virtualisor virtualisor/cpus/a15 virtualisor/cpus/a7
VIRTUALISOR_OBJS += virt_handle.o virt_setup.o virt_context.o cache_geom.o mem_trap.o vgic_trap_handler.o \
- kfscb_trap_handler.o a7.o a15.o
+ kfscb_trap_handler.o pmu_trap_handler.o a7.o a15.o
###############################################################################################################
diff --git a/big-little/common/hyp_vectors.s b/big-little/common/hyp_vectors.s
index 1249b5f..e727b5f 100644
--- a/big-little/common/hyp_vectors.s
+++ b/big-little/common/hyp_vectors.s
@@ -42,11 +42,6 @@
IMPORT bl_rest_init
IMPORT hyp_l1_pagetable
IMPORT find_restore_op_type
-
- IF ASYNC_SWITCH = {FALSE}
- IMPORT is_hvc
- IMPORT HandleHVC
- ENDIF
EXPORT vectors
EXPORT iabt_entry
@@ -320,16 +315,6 @@ hvc_entry
; Virtualisor. It should be possible to cascade an HVC
; across the two, but not for the time being.
; ----------------------------------------------------
- IF ASYNC_SWITCH = {FALSE}
- BL is_hvc
- CMP r0, #0
- BEQ next
- MOV r0, sp
- BL HandleHVC
- TST r0, #1
- BNE out
- ENDIF
-next
MOV r0, sp
BL HandleVirtualisor
out
diff --git a/big-little/virtualisor/virt_handle.c b/big-little/virtualisor/virt_handle.c
index da163cf..684dacb 100644
--- a/big-little/virtualisor/virt_handle.c
+++ b/big-little/virtualisor/virt_handle.c
@@ -32,6 +32,10 @@ extern cache_geometry host_cache_geometry[];
extern cache_geometry target_cache_geometry[];
extern cache_diff cache_delta[NUM_CPUS][MAX_CACHE_LEVELS];
+extern void signal_switchover(void);
+extern unsigned cluster_reset_status(unsigned);
+extern unsigned handle_pmu(unsigned, unsigned, unsigned);
+
void trap_cp15_mrc_mcr_handle(unsigned hsr, gp_regs * regs)
{
unsigned Op1, Op2, CRn, CRm, Rt, write, cpu_id = read_cpuid();
@@ -554,6 +558,61 @@ void trap_dabort_handle(unsigned hsr, gp_regs * regs)
return;
}
+void trap_hvc_handle(unsigned hsr, gp_regs *regs)
+{
+ unsigned opcode = regs->r[0];
+
+ switch (opcode) {
+
+ /*
+ * HVC call to switch to the other cluster. This is done
+ * by sending a switchover IPI to all the cores in the cluster.
+ */
+ case SYNC_SWITCHOVER:
+ /* Do not switch till previous one has not completed */
+ while (FALSE == cluster_reset_status(!read_clusterid()));
+ signal_switchover();
+ break;
+
+ /*
+ * HVC call to return the physical MPIDR
+ */
+ case READ_MPIDR:
+ regs->r[0] = read_mpidr();
+ break;
+
+ case PMCR_READ:
+ case PMCR_WRITE:
+ case PMSELR_READ:
+ case PMSELR_WRITE:
+ case PMXEVTYPER_READ:
+ case PMXEVTYPER_WRITE:
+ case PMCNTENSET_READ:
+ case PMCNTENSET_WRITE:
+ case PMCNTENCLR_READ:
+ case PMCNTENCLR_WRITE:
+ case PMCCNTR_READ:
+ case PMCCNTR_WRITE:
+ case PMOVSR_READ:
+ case PMOVSR_WRITE:
+ case PMXEVCNTR_READ:
+ case PMXEVCNTR_WRITE:
+ case PMINTENSET_READ:
+ case PMINTENSET_WRITE:
+ case PMINTENCLR_READ:
+ case PMINTENCLR_WRITE:
+ case HVC_SWITCH:
+ case GET_COUNTERS_SIZE:
+ case SYNC_PMU_COUNTERS:
+ regs->r[0] = handle_pmu(opcode, regs->r[1], regs->r[2]);
+ break;
+ default:
+ break;
+ }
+
+ return;
+}
+
void HandleVirtualisor(gp_regs * regs)
{
unsigned cpu_id = read_cpuid(), cpu_no = PART_NO(read_midr()), rc = 0;
@@ -574,6 +633,9 @@ void HandleVirtualisor(gp_regs * regs)
case TRAP_CP15_32:
trap_cp15_mrc_mcr_handle(hsr, regs);
break;
+ case TRAP_HVC:
+ trap_hvc_handle(hsr, regs);
+ return;
default:
printf("%s: Unexpected trap", __FUNCTION__);
printf(": HSR=0x%x Regs=0x%x \n", hsr, (unsigned)regs);