diff --git a/asm/head.S b/asm/head.S
index 8049d785..ad306252 100644
--- a/asm/head.S
+++ b/asm/head.S
@@ -359,7 +359,10 @@ boot_entry:
 	/* Get ready for C code: get a stack */
 2:	GET_STACK(%r1,%r31)
 
-	/* Clear up initial frame */
+	/* Clear up initial frame.
+	 * Zero back chain indicates stack entry from boot,
+	 * non-zero indicates entry from OS (see backtrace code).
+	 */
 	li	%r3,0
 	std	%r3,0(%r1)
 	std	%r3,8(%r1)
@@ -965,6 +968,7 @@ opal_entry:
 	stdu	%r12,-STACK_FRAMESIZE(%r12)
 
 	/* Save caller r1, establish new r1 */
+	std	%r1,0(%r12)
 	std	%r1,STACK_GPR1(%r12)
 	mr	%r1,%r12
 
diff --git a/core/stack.c b/core/stack.c
index e04a4ddb..10118e42 100644
--- a/core/stack.c
+++ b/core/stack.c
@@ -29,11 +29,14 @@ static struct bt_entry bt_buf[STACK_BUF_ENTRIES];
 extern uint32_t _stext, _etext;
 
 /* Dumps backtrace to buffer */
-void __nomcount __backtrace(struct bt_entry *entries, unsigned int *count)
+void __nomcount ___backtrace(struct bt_entry *entries, unsigned int *count,
+				unsigned long r1,
+				unsigned long *token, unsigned long *r1_caller)
 {
 	unsigned int room = *count;
-	unsigned long *fp = __builtin_frame_address(0);
+	unsigned long *fp = (unsigned long *)r1;
 	unsigned long top_adj = top_of_ram;
+	struct stack_frame *eframe = (struct stack_frame *)fp;
 
 	/* Assume one stack for early backtraces */
 	if (top_of_ram == SKIBOOT_BASE + SKIBOOT_SIZE)
@@ -44,17 +47,26 @@ void __nomcount __backtrace(struct bt_entry *entries, unsigned int *count)
 		fp = (unsigned long *)fp[0];
 		if (!fp || (unsigned long)fp > top_adj)
 			break;
+		eframe = (struct stack_frame *)fp;
 		entries->sp = (unsigned long)fp;
 		entries->pc = fp[2];
 		entries++;
 		*count = (*count) + 1;
 		room--;
 	}
+
+	*r1_caller = eframe->gpr[1];
+
+	if (fp)
+		*token = eframe->gpr[0];
+	else
+		*token = -1UL;
 }
 
-void __print_backtrace(unsigned int pir,
-		       struct bt_entry *entries, unsigned int count,
-		       char *out_buf, unsigned int *len, bool symbols)
+void ___print_backtrace(unsigned int pir, struct bt_entry *entries,
+			      unsigned int count, unsigned long token,
+			      unsigned long r1_caller, char *out_buf,
+			      unsigned int *len, bool symbols)
 {
 	static char bt_text_buf[4096];
 	int i, l = 0, max;
@@ -89,6 +101,10 @@ void __print_backtrace(unsigned int pir,
 		l += snprintf(buf + l, max - l, "\n");
 		entries++;
 	}
+	if (token <= OPAL_LAST)
+		l += snprintf(buf + l, max - l, " --- OPAL call token: 0x%lx caller R1: 0x%016lx ---\n", token, r1_caller);
+	else if (token == -1UL)
+		l += snprintf(buf + l, max - l, " --- OPAL boot ---\n");
 	if (!out_buf)
 		write(stdout->fd, bt_text_buf, l);
 	buf[l++] = 0;
@@ -107,11 +123,14 @@ struct lock bt_lock = LOCK_UNLOCKED;
 void backtrace(void)
 {
 	unsigned int ents = STACK_BUF_ENTRIES;
+	unsigned long token, r1_caller;
 
 	lock(&bt_lock);
 
-	__backtrace(bt_buf, &ents);
-	__print_backtrace(mfspr(SPR_PIR), bt_buf, ents, NULL, NULL, true);
+	___backtrace(bt_buf, &ents, (unsigned long)__builtin_frame_address(0),
+			&token, &r1_caller);
+	___print_backtrace(mfspr(SPR_PIR), bt_buf, ents, token, r1_caller,
+			NULL, NULL, true);
 
 	unlock(&bt_lock);
 }
diff --git a/include/stack.h b/include/stack.h
index df08ac13..4d3e504d 100644
--- a/include/stack.h
+++ b/include/stack.h
@@ -49,6 +49,7 @@
 #ifndef __ASSEMBLY__
 
 #include <stdint.h>
+#include <opal-api.h>
 
 /* This is the struct used to save GPRs etc.. on OPAL entry
  * and from some exceptions. It is not always entirely populated
@@ -108,13 +109,31 @@ struct bt_entry {
 extern void *boot_stack_top;
 
 /* Create a backtrace */
-extern void __backtrace(struct bt_entry *entries, unsigned int *count);
+void ___backtrace(struct bt_entry *entries, unsigned int *count,
+				unsigned long r1,
+				unsigned long *token, unsigned long *r1_caller);
+static inline void __backtrace(struct bt_entry *entries, unsigned int *count)
+{
+	unsigned long token, r1_caller;
+
+	___backtrace(entries, count,
+			(unsigned long)__builtin_frame_address(0),
+			&token, &r1_caller);
+}
 
 /* Convert a backtrace to ASCII */
-extern void __print_backtrace(unsigned int pir, struct bt_entry *entries,
-			      unsigned int count, char *out_buf,
+extern void ___print_backtrace(unsigned int pir, struct bt_entry *entries,
+			      unsigned int count, unsigned long token,
+			      unsigned long r1_caller, char *out_buf,
 			      unsigned int *len, bool symbols);
 
+static inline void __print_backtrace(unsigned int pir, struct bt_entry *entries,
+			      unsigned int count, char *out_buf,
+			      unsigned int *len, bool symbols)
+{
+	___print_backtrace(pir, entries, count, OPAL_LAST + 1, 0, out_buf, len, symbols);
+}
+
 /* For use by debug code, create and print backtrace, uses a static buffer */
 extern void backtrace(void);
 
