aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/stack.c53
-rw-r--r--include/stack.h40
2 files changed, 54 insertions, 39 deletions
diff --git a/core/stack.c b/core/stack.c
index 5e4cf4b..773d91e 100644
--- a/core/stack.c
+++ b/core/stack.c
@@ -27,10 +27,9 @@
static struct bt_entry bt_buf[STACK_BUF_ENTRIES];
/* Dumps backtrace to buffer */
-void __nomcount ___backtrace(struct bt_entry *entries, unsigned int *count,
- unsigned long *token, unsigned long *r1_caller)
+void __nomcount ___backtrace(struct bt_entry *entries, unsigned int max_ents,
+ struct bt_metadata *metadata)
{
- unsigned int room = *count;
unsigned long *fp = __builtin_frame_address(0);
unsigned long top_adj = top_of_ram;
struct stack_frame *eframe = (struct stack_frame *)fp;
@@ -39,8 +38,8 @@ void __nomcount ___backtrace(struct bt_entry *entries, unsigned int *count,
if (top_of_ram == SKIBOOT_BASE + SKIBOOT_SIZE)
top_adj = top_of_ram + STACK_SIZE;
- *count = 0;
- while(room) {
+ metadata->ents = 0;
+ while (max_ents) {
fp = (unsigned long *)fp[0];
if (!fp || (unsigned long)fp > top_adj)
break;
@@ -48,22 +47,20 @@ void __nomcount ___backtrace(struct bt_entry *entries, unsigned int *count,
entries->sp = (unsigned long)fp;
entries->pc = fp[2];
entries++;
- *count = (*count) + 1;
- room--;
+ metadata->ents++;
+ max_ents--;
}
- *r1_caller = eframe->gpr[1];
+ metadata->r1_caller = eframe->gpr[1];
if (fp)
- *token = eframe->gpr[0];
+ metadata->token = eframe->gpr[0];
else
- *token = -1UL;
+ metadata->token = -1UL;
}
-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)
+void ___print_backtrace(struct bt_entry *entries, struct bt_metadata *metadata,
+ char *out_buf, unsigned int *len, bool symbols)
{
static char bt_text_buf[4096];
int i, l = 0, max;
@@ -77,14 +74,14 @@ void ___print_backtrace(unsigned int pir, struct bt_entry *entries,
} else
max = *len - 1;
- bottom = cpu_stack_bottom(pir);
- normal_top = cpu_stack_top(pir);
- top = cpu_emergency_stack_top(pir);
+ bottom = cpu_stack_bottom(metadata->pir);
+ normal_top = cpu_stack_top(metadata->pir);
+ top = cpu_emergency_stack_top(metadata->pir);
tbot = SKIBOOT_BASE;
ttop = (unsigned long)&_etext;
- l += snprintf(buf, max, "CPU %04x Backtrace:\n", pir);
- for (i = 0; i < count && l < max; i++) {
+ l += snprintf(buf, max, "CPU %04lx Backtrace:\n", metadata->pir);
+ for (i = 0; i < metadata->ents && l < max; i++) {
if (entries->sp < bottom || entries->sp > top)
mark = '!';
else if (entries->sp > normal_top)
@@ -101,9 +98,11 @@ void ___print_backtrace(unsigned int pir, struct bt_entry *entries,
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)
+ if (metadata->token <= OPAL_LAST)
+ l += snprintf(buf + l, max - l,
+ " --- OPAL call token: 0x%lx caller R1: 0x%016lx ---\n",
+ metadata->token, metadata->r1_caller);
+ else if (metadata->token == -1UL)
l += snprintf(buf + l, max - l, " --- OPAL boot ---\n");
if (!out_buf)
write(stdout->fd, bt_text_buf, l);
@@ -122,14 +121,14 @@ struct lock bt_lock = LOCK_UNLOCKED;
void backtrace(void)
{
- unsigned int ents = STACK_BUF_ENTRIES;
- unsigned long token, r1_caller;
+ struct bt_metadata metadata = {
+ .pir = mfspr(SPR_PIR),
+ };
lock(&bt_lock);
- ___backtrace(bt_buf, &ents, &token, &r1_caller);
- ___print_backtrace(mfspr(SPR_PIR), bt_buf, ents, token, r1_caller,
- NULL, NULL, true);
+ ___backtrace(bt_buf, STACK_BUF_ENTRIES, &metadata);
+ ___print_backtrace(bt_buf, &metadata, NULL, NULL, true);
unlock(&bt_lock);
}
diff --git a/include/stack.h b/include/stack.h
index ae910a3..d8baf8d 100644
--- a/include/stack.h
+++ b/include/stack.h
@@ -107,36 +107,52 @@ struct stack_frame {
uint64_t dar;
} __attribute__((aligned(16)));
-/* Backtrace */
+/* Backtrace entry */
struct bt_entry {
unsigned long sp;
unsigned long pc;
};
+/* Backtrace metadata */
+struct bt_metadata {
+ unsigned int ents;
+ unsigned long token;
+ unsigned long r1_caller;
+ unsigned long pir;
+};
+
/* Boot stack top */
extern void *boot_stack_top;
/* Create a backtrace */
-void ___backtrace(struct bt_entry *entries, unsigned int *count,
- unsigned long *token, unsigned long *r1_caller);
+void ___backtrace(struct bt_entry *entries, unsigned int max_ents,
+ struct bt_metadata *metadata);
+
static inline void __backtrace(struct bt_entry *entries, unsigned int *count)
{
- unsigned long token, r1_caller;
+ struct bt_metadata metadata;
+
+ ___backtrace(entries, *count, &metadata);
- ___backtrace(entries, count, &token, &r1_caller);
+ *count = metadata.ents;
}
/* Convert a backtrace to ASCII */
-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);
+extern void ___print_backtrace(struct bt_entry *entries,
+ struct bt_metadata *metadata, 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)
+ unsigned int count, char *out_buf,
+ unsigned int *len, bool symbols)
{
- ___print_backtrace(pir, entries, count, OPAL_LAST + 1, 0, out_buf, len, symbols);
+ struct bt_metadata metadata = {
+ .ents = count,
+ .token = OPAL_LAST + 1,
+ .r1_caller = 0,
+ .pir = pir
+ };
+ ___print_backtrace(entries, &metadata, out_buf, len, symbols);
}
/* For use by debug code, create and print backtrace, uses a static buffer */