aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--asm/head.S16
-rw-r--r--core/opal.c27
2 files changed, 33 insertions, 10 deletions
diff --git a/asm/head.S b/asm/head.S
index ccf0948..a786ba1 100644
--- a/asm/head.S
+++ b/asm/head.S
@@ -930,8 +930,7 @@ opal_entry:
std %r1,STACK_GPR1(%r12)
mr %r1,%r12
- /* May save arguments for tracing */
-#ifdef OPAL_TRACE_ENTRY
+ /* Save arguments because we call C */
std %r3,STACK_GPR3(%r1)
std %r4,STACK_GPR4(%r1)
std %r5,STACK_GPR5(%r1)
@@ -940,7 +939,7 @@ opal_entry:
std %r8,STACK_GPR8(%r1)
std %r9,STACK_GPR9(%r1)
std %r10,STACK_GPR10(%r1)
-#endif
+
/* Save Token (r0), LR and r13 */
mflr %r12
std %r0,STACK_GPR0(%r1)
@@ -967,9 +966,12 @@ opal_entry:
cmpwi %r12,0
bne 3f
-#ifdef OPAL_TRACE_ENTRY
+ /* Check entry */
mr %r3,%r1
- bl opal_trace_entry
+ bl opal_entry_check
+ cmpdi %r3,0
+ bne 1f
+
ld %r0,STACK_GPR0(%r1)
ld %r3,STACK_GPR3(%r1)
ld %r4,STACK_GPR4(%r1)
@@ -979,7 +981,6 @@ opal_entry:
ld %r8,STACK_GPR8(%r1)
ld %r9,STACK_GPR9(%r1)
ld %r10,STACK_GPR10(%r1)
-#endif /* OPAL_TRACE_ENTRY */
/* Convert our token into a table entry and get the
* function pointer. Also check the token.
@@ -997,6 +998,9 @@ opal_entry:
/* Jump ! */
bctrl
+ mr %r4,%r1
+ bl opal_exit_check
+
1: ld %r12,STACK_LR(%r1)
mtlr %r12
ld %r13,STACK_GPR13(%r1)
diff --git a/core/opal.c b/core/opal.c
index 8095f73..5143692 100644
--- a/core/opal.c
+++ b/core/opal.c
@@ -92,11 +92,9 @@ long opal_bad_token(uint64_t token)
return OPAL_PARAMETER;
}
-/* Called from head.S, thus no prototype */
-void opal_trace_entry(struct stack_frame *eframe);
-
-void opal_trace_entry(struct stack_frame *eframe)
+static void opal_trace_entry(struct stack_frame *eframe __unused)
{
+#ifdef OPAL_TRACE_ENTRY
union trace t;
unsigned nargs, i;
@@ -117,6 +115,27 @@ void opal_trace_entry(struct stack_frame *eframe)
t.opal.r3_to_11[i] = cpu_to_be64(eframe->gpr[3+i]);
trace_add(&t, TRACE_OPAL, offsetof(struct trace_opal, r3_to_11[nargs]));
+#endif
+}
+
+/* Called from head.S, thus no prototype */
+int64_t opal_entry_check(struct stack_frame *eframe);
+
+int64_t __attrconst opal_entry_check(struct stack_frame *eframe)
+{
+ uint64_t token = eframe->gpr[0];
+
+ opal_trace_entry(eframe);
+
+ return OPAL_SUCCESS;
+}
+
+void opal_exit_check(int64_t retval, struct stack_frame *eframe);
+
+void __attrconst opal_exit_check(int64_t retval, struct stack_frame *eframe)
+{
+ (void)retval;
+ (void)eframe;
}
void __opal_register(uint64_t token, void *func, unsigned int nargs)