summaryrefslogtreecommitdiffstats
path: root/sys/ia64
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2004-07-10 22:59:30 +0000
committermarcel <marcel@FreeBSD.org>2004-07-10 22:59:30 +0000
commit7c010da81a215361ead99eb4a876af2ffb16348d (patch)
treec8b0f04d69769973cb6fe1928ec74a9b9e908db4 /sys/ia64
parent95c6c430069ffa4db994a89c4ccbf54ff21dc643 (diff)
downloadFreeBSD-src-7c010da81a215361ead99eb4a876af2ffb16348d.zip
FreeBSD-src-7c010da81a215361ead99eb4a876af2ffb16348d.tar.gz
Update for the KDB framework:
o ksym_start and ksym_end changed type to vm_offset_t. o Make debugging support conditional upon KDB instead of DDB. o Call kdb_enter() instead of breakpoint(). o Remove implementation of Debugger(). o Call kdb_trap() according to the new world order. unwinder: o s/db_active/kdb_active/g o Various s/ddb/kdb/g o Add support for unwinding from the PCB as well as the trapframe. Abuse a spare field in the special register set to flag whether the PCB was actually constructed from a trapframe so that we can make the necessary adjustments. md_var.h: o Add RSE convenience macros. o Add ia64_bsp_adjust() to add or subtract from BSP while taking NaT collections into account.
Diffstat (limited to 'sys/ia64')
-rw-r--r--sys/ia64/ia64/machdep.c26
-rw-r--r--sys/ia64/ia64/trap.c23
-rw-r--r--sys/ia64/ia64/unwind.c249
-rw-r--r--sys/ia64/include/md_var.h37
-rw-r--r--sys/ia64/include/unwind.h6
5 files changed, 224 insertions, 117 deletions
diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c
index 5c39d05..9fed902 100644
--- a/sys/ia64/ia64/machdep.c
+++ b/sys/ia64/ia64/machdep.c
@@ -35,6 +35,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/eventhandler.h>
+#include <sys/kdb.h>
#include <sys/sysproto.h>
#include <sys/signalvar.h>
#include <sys/imgact.h>
@@ -126,8 +127,7 @@ SYSCTL_STRING(_hw, OID_AUTO, family, CTLFLAG_RD, cpu_family, 0,
"The CPU family name");
#ifdef DDB
-/* start and end of kernel symbol table */
-void *ksym_start, *ksym_end;
+extern vm_offset_t ksym_start, ksym_end;
#endif
static void cpu_startup(void *);
@@ -586,8 +586,8 @@ ia64_init(void)
*/
kernstart = trunc_page(kernel_text);
#ifdef DDB
- ksym_start = (void *)bootinfo.bi_symtab;
- ksym_end = (void *)bootinfo.bi_esymtab;
+ ksym_start = bootinfo.bi_symtab;
+ ksym_end = bootinfo.bi_esymtab;
kernend = (vm_offset_t)round_page(ksym_end);
#else
kernend = (vm_offset_t)round_page(_end);
@@ -766,13 +766,13 @@ ia64_init(void)
/*
* Initialize debuggers, and break into them if appropriate.
*/
-#ifdef DDB
kdb_init();
- if (boothowto & RB_KDB) {
- printf("Boot flags requested debugger\n");
- breakpoint();
- }
+
+#ifdef KDB
+ if (boothowto & RB_KDB)
+ kdb_enter("Boot flags requested debugger\n");
#endif
+
ia64_set_tpr(0);
/*
@@ -1380,14 +1380,6 @@ ia64_highfp_save(struct thread *td)
return (1);
}
-#ifndef DDB
-void
-Debugger(const char *msg)
-{
- printf("Debugger(\"%s\") called.\n", msg);
-}
-#endif /* no DDB */
-
int
sysbeep(int pitch, int period)
{
diff --git a/sys/ia64/ia64/trap.c b/sys/ia64/ia64/trap.c
index 0145ed2..9c5c615 100644
--- a/sys/ia64/ia64/trap.c
+++ b/sys/ia64/ia64/trap.c
@@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/kdb.h>
#include <sys/ktr.h>
#include <sys/sysproto.h>
#include <sys/kernel.h>
@@ -75,10 +76,6 @@ __FBSDID("$FreeBSD$");
#include <sys/ktrace.h>
#endif
-#ifdef DDB
-#include <ddb/ddb.h>
-#endif
-
static int print_usertrap = 0;
SYSCTL_INT(_machdep, OID_AUTO, print_usertrap,
CTLFLAG_RW, &print_usertrap, 0, "");
@@ -316,8 +313,8 @@ trap_panic(int vector, struct trapframe *tf)
{
printtrap(vector, tf, 1, TRAPF_USERMODE(tf));
-#ifdef DDB
- kdb_trap(vector, tf);
+#ifdef KDB
+ kdb_trap(vector, 0, tf);
#endif
panic("trap");
}
@@ -374,6 +371,10 @@ trap(int vector, struct trapframe *tf)
sticks = 0; /* XXX bogus -Wuninitialized warning */
KASSERT(cold || td->td_ucred != NULL,
("kernel trap doesn't have ucred"));
+#ifdef KDB
+ if (kdb_active)
+ kdb_reenter();
+#endif
}
sig = 0;
@@ -498,8 +499,8 @@ trap(int vector, struct trapframe *tf)
} else
sig = SIGILL;
} else {
-#ifdef DDB
- if (kdb_trap(vector, tf))
+#ifdef KDB
+ if (kdb_trap(vector, 0, tf))
return;
panic("trap");
#else
@@ -663,8 +664,8 @@ trap(int vector, struct trapframe *tf)
case IA64_VEC_SINGLE_STEP_TRAP:
tf->tf_special.psr &= ~IA64_PSR_SS;
if (!user) {
-#ifdef DDB
- if (kdb_trap(vector, tf))
+#ifdef KDB
+ if (kdb_trap(vector, 0, tf))
return;
panic("trap");
#else
@@ -939,9 +940,9 @@ syscall(struct trapframe *tf)
atomic_add_int(&cnt.v_syscall, 1);
td = curthread;
+ td->td_frame = tf;
p = td->td_proc;
- td->td_frame = tf;
sticks = td->td_sticks;
if (td->td_ucred != p->p_ucred)
cred_update_thread(td);
diff --git a/sys/ia64/ia64/unwind.c b/sys/ia64/ia64/unwind.c
index 4200a54..a0099c3 100644
--- a/sys/ia64/ia64/unwind.c
+++ b/sys/ia64/ia64/unwind.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003 Marcel Moolenaar
+ * Copyright (c) 2003, 2004 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -27,15 +27,16 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include "opt_ddb.h"
-
#include <sys/param.h>
+#include <sys/kdb.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/queue.h>
#include <machine/frame.h>
+#include <machine/md_var.h>
+#include <machine/pcb.h>
#include <machine/unwind.h>
#include <uwx.h>
@@ -60,8 +61,8 @@ LIST_HEAD(unw_table_list, unw_table);
static struct unw_table_list unw_tables;
-#ifdef DDB
-#define DDBHEAPSZ 8192
+#ifdef KDB
+#define KDBHEAPSZ 8192
struct mhdr {
uint32_t sig;
@@ -72,35 +73,33 @@ struct mhdr {
int32_t prev;
};
-extern int db_active;
-
-static struct mhdr *ddbheap;
-#endif /* DDB */
+static struct mhdr *kdbheap;
+#endif /* KDB */
static void *
unw_alloc(size_t sz)
{
-#ifdef DDB
+#ifdef KDB
struct mhdr *hdr, *hfree;
- if (db_active) {
+ if (kdb_active) {
sz = (sz + 15) >> 4;
- hdr = ddbheap;
+ hdr = kdbheap;
while (hdr->sig != MSIG_FREE || hdr->size < sz) {
if (hdr->next == -1)
return (NULL);
- hdr = ddbheap + hdr->next;
+ hdr = kdbheap + hdr->next;
}
if (hdr->size > sz + 1) {
hfree = hdr + sz + 1;
hfree->sig = MSIG_FREE;
hfree->size = hdr->size - sz - 1;
- hfree->prev = hdr - ddbheap;
+ hfree->prev = hdr - kdbheap;
hfree->next = hdr->next;
hdr->size = sz;
- hdr->next = hfree - ddbheap;
+ hdr->next = hfree - kdbheap;
if (hfree->next >= 0) {
- hfree = ddbheap + hfree->next;
+ hfree = kdbheap + hfree->next;
hfree->prev = hdr->next;
}
}
@@ -114,30 +113,30 @@ unw_alloc(size_t sz)
static void
unw_free(void *p)
{
-#ifdef DDB
+#ifdef KDB
struct mhdr *hdr, *hfree;
- if (db_active) {
+ if (kdb_active) {
hdr = (struct mhdr*)p - 1;
if (hdr->sig != MSIG_USED)
return;
hdr->sig = MSIG_FREE;
- if (hdr->prev >= 0 && ddbheap[hdr->prev].sig == MSIG_FREE) {
- hfree = ddbheap + hdr->prev;
+ if (hdr->prev >= 0 && kdbheap[hdr->prev].sig == MSIG_FREE) {
+ hfree = kdbheap + hdr->prev;
hfree->size += hdr->size + 1;
hfree->next = hdr->next;
if (hdr->next >= 0) {
- hfree = ddbheap + hdr->next;
+ hfree = kdbheap + hdr->next;
hfree->prev = hdr->prev;
}
} else if (hdr->next >= 0 &&
- ddbheap[hdr->next].sig == MSIG_FREE) {
- hfree = ddbheap + hdr->next;
+ kdbheap[hdr->next].sig == MSIG_FREE) {
+ hfree = kdbheap + hdr->next;
hdr->size += hfree->size + 1;
hdr->next = hfree->next;
if (hdr->next >= 0) {
- hfree = ddbheap + hdr->next;
- hfree->prev = hdr - ddbheap;
+ hfree = kdbheap + hdr->next;
+ hfree->prev = hdr - kdbheap;
}
}
return;
@@ -158,11 +157,101 @@ unw_table_lookup(uint64_t ip)
return (NULL);
}
+static uint64_t
+unw_copyin_from_frame(struct trapframe *tf, uint64_t from)
+{
+ uint64_t val;
+ int reg;
+
+ if (from == UWX_REG_AR_PFS)
+ val = tf->tf_special.pfs;
+ else if (from == UWX_REG_PREDS)
+ val = tf->tf_special.pr;
+ else if (from == UWX_REG_AR_RNAT)
+ val = tf->tf_special.rnat;
+ else if (from == UWX_REG_AR_UNAT)
+ val = tf->tf_special.unat;
+ else if (from >= UWX_REG_GR(0) && from <= UWX_REG_GR(127)) {
+ reg = from - UWX_REG_GR(0);
+ if (reg == 1)
+ val = tf->tf_special.gp;
+ else if (reg == 12)
+ val = tf->tf_special.sp;
+ else if (reg == 13)
+ val = tf->tf_special.tp;
+ else if (reg >= 2 && reg <= 3)
+ val = (&tf->tf_scratch.gr2)[reg - 2];
+ else if (reg >= 8 && reg <= 11)
+ val = (&tf->tf_scratch.gr8)[reg - 8];
+ else if (reg >= 14 && reg <= 31)
+ val = (&tf->tf_scratch.gr14)[reg - 14];
+ else
+ goto oops;
+ } else if (from >= UWX_REG_BR(0) && from <= UWX_REG_BR(7)) {
+ reg = from - UWX_REG_BR(0);
+ if (reg == 0)
+ val = tf->tf_special.rp;
+ else if (reg >= 6 && reg <= 7)
+ val = (&tf->tf_scratch.br6)[reg - 6];
+ else
+ goto oops;
+ } else
+ goto oops;
+ return (val);
+
+ oops:
+ printf("UNW: %s(%p, %lx)\n", __func__, tf, from);
+ return (0UL);
+}
+
+static uint64_t
+unw_copyin_from_pcb(struct pcb *pcb, uint64_t from)
+{
+ uint64_t val;
+ int reg;
+
+ if (from == UWX_REG_AR_PFS)
+ val = pcb->pcb_special.pfs;
+ else if (from == UWX_REG_PREDS)
+ val = pcb->pcb_special.pr;
+ else if (from == UWX_REG_AR_RNAT)
+ val = pcb->pcb_special.rnat;
+ else if (from == UWX_REG_AR_UNAT)
+ val = pcb->pcb_special.unat;
+ else if (from >= UWX_REG_GR(0) && from <= UWX_REG_GR(127)) {
+ reg = from - UWX_REG_GR(0);
+ if (reg == 1)
+ val = pcb->pcb_special.gp;
+ else if (reg == 12)
+ val = pcb->pcb_special.sp;
+ else if (reg == 13)
+ val = pcb->pcb_special.tp;
+ else if (reg >= 4 && reg <= 7)
+ val = (&pcb->pcb_preserved.gr4)[reg - 4];
+ else
+ goto oops;
+ } else if (from >= UWX_REG_BR(0) && from <= UWX_REG_BR(7)) {
+ reg = from - UWX_REG_BR(0);
+ if (reg == 0)
+ val = pcb->pcb_special.rp;
+ else if (reg >= 1 && reg <= 5)
+ val = (&pcb->pcb_preserved.br1)[reg - 1];
+ else
+ goto oops;
+ } else
+ goto oops;
+ return (val);
+
+ oops:
+ printf("UNW: %s(%p, %lx)\n", __func__, pcb, from);
+ return (0UL);
+}
+
static int
unw_cb_copyin(int req, char *to, uint64_t from, int len, intptr_t tok)
{
struct unw_regstate *rs = (void*)tok;
- int reg;
+ uint64_t val;
switch (req) {
case UWX_COPYIN_UINFO:
@@ -174,49 +263,19 @@ unw_cb_copyin(int req, char *to, uint64_t from, int len, intptr_t tok)
*((uint64_t*)to) = *((uint64_t*)from);
return (8);
case UWX_COPYIN_REG:
- if (from == UWX_REG_AR_PFS)
- from = rs->frame->tf_special.pfs;
- else if (from == UWX_REG_PREDS)
- from = rs->frame->tf_special.pr;
- else if (from == UWX_REG_AR_RNAT)
- from = rs->frame->tf_special.rnat;
- else if (from == UWX_REG_AR_UNAT)
- from = rs->frame->tf_special.unat;
- else if (from >= UWX_REG_GR(0) && from <= UWX_REG_GR(127)) {
- reg = from - UWX_REG_GR(0);
- if (reg == 1)
- from = rs->frame->tf_special.gp;
- else if (reg == 12)
- from = rs->frame->tf_special.sp;
- else if (reg == 13)
- from = rs->frame->tf_special.tp;
- else if (reg >= 2 && reg <= 3)
- from = (&rs->frame->tf_scratch.gr2)[reg - 2];
- else if (reg >= 8 && reg <= 11)
- from = (&rs->frame->tf_scratch.gr8)[reg - 8];
- else if (reg >= 14 && reg <= 31)
- from = (&rs->frame->tf_scratch.gr14)[reg - 14];
- else
- goto oops;
- } else if (from >= UWX_REG_BR(0) && from <= UWX_REG_BR(7)) {
- reg = from - UWX_REG_BR(0);
- if (reg == 0)
- from = rs->frame->tf_special.rp;
- else if (reg >= 6 && reg <= 7)
- from = (&rs->frame->tf_scratch.br6)[reg - 6];
- else
- goto oops;
- } else
+ if (rs->frame != NULL)
+ val = unw_copyin_from_frame(rs->frame, from);
+ else if (rs->pcb != NULL)
+ val = unw_copyin_from_pcb(rs->pcb, from);
+ else
goto oops;
-
- *((uint64_t*)to) = from;
+ *((uint64_t*)to) = val;
return (len);
}
oops:
printf("UNW: %s(%d, %p, %lx, %d, %lx)\n", __func__, req, to, from,
len, tok);
-
return (0);
}
@@ -249,17 +308,13 @@ unw_cb_lookup(int req, uint64_t ip, intptr_t tok, uint64_t **vec)
}
int
-unw_create(struct unw_regstate *rs, struct trapframe *tf)
+unw_create_from_frame(struct unw_regstate *rs, struct trapframe *tf)
{
- struct unw_table *ut;
- uint64_t bsp;
- int nats, sof, uwxerr;
-
- ut = unw_table_lookup(tf->tf_special.iip);
- if (ut == NULL)
- return (ENOENT);
+ uint64_t bsp, ip;
+ int uwxerr;
rs->frame = tf;
+ rs->pcb = NULL;
rs->env = uwx_init();
if (rs->env == NULL)
return (ENOMEM);
@@ -270,10 +325,44 @@ unw_create(struct unw_regstate *rs, struct trapframe *tf)
return (EINVAL); /* XXX */
bsp = tf->tf_special.bspstore + tf->tf_special.ndirty;
- sof = (int)(tf->tf_special.cfm & 0x7f);
- nats = (sof + 63 - ((int)(bsp >> 3) & 0x3f)) / 63;
- uwxerr = uwx_init_context(rs->env, tf->tf_special.iip,
- tf->tf_special.sp, bsp - ((sof + nats) << 3), tf->tf_special.cfm);
+ bsp = ia64_bsp_adjust(bsp, -IA64_CFM_SOF(tf->tf_special.cfm));
+ ip = tf->tf_special.iip + ((tf->tf_special.psr >> 41) & 3);
+
+ uwxerr = uwx_init_context(rs->env, ip, tf->tf_special.sp, bsp,
+ tf->tf_special.cfm);
+
+ return ((uwxerr) ? EINVAL : 0); /* XXX */
+}
+
+int
+unw_create_from_pcb(struct unw_regstate *rs, struct pcb *pcb)
+{
+ uint64_t bsp, cfm, ip;
+ int uwxerr;
+
+ rs->frame = NULL;
+ rs->pcb = pcb;
+ rs->env = uwx_init();
+ if (rs->env == NULL)
+ return (ENOMEM);
+
+ uwxerr = uwx_register_callbacks(rs->env, (intptr_t)rs,
+ unw_cb_copyin, unw_cb_lookup);
+ if (uwxerr)
+ return (EINVAL); /* XXX */
+
+ bsp = pcb->pcb_special.bspstore;
+ if (pcb->pcb_special.__spare == ~0UL) {
+ ip = pcb->pcb_special.iip + ((pcb->pcb_special.psr >> 41) & 3);
+ cfm = pcb->pcb_special.cfm;
+ bsp += pcb->pcb_special.ndirty;
+ bsp = ia64_bsp_adjust(bsp, -IA64_CFM_SOF(cfm));
+ } else {
+ ip = pcb->pcb_special.rp;
+ cfm = pcb->pcb_special.pfs;
+ bsp = ia64_bsp_adjust(bsp, -IA64_CFM_SOL(cfm));
+ }
+ uwxerr = uwx_init_context(rs->env, ip, pcb->pcb_special.sp, bsp, cfm);
return ((uwxerr) ? EINVAL : 0); /* XXX */
}
@@ -372,12 +461,12 @@ unw_initialize(void *dummy __unused)
LIST_INIT(&unw_tables);
uwx_register_alloc_cb(unw_alloc, unw_free);
-#ifdef DDB
- ddbheap = malloc(DDBHEAPSZ, M_UNWIND, M_WAITOK);
- ddbheap->sig = MSIG_FREE;
- ddbheap->size = (DDBHEAPSZ - sizeof(struct mhdr)) >> 4;
- ddbheap->next = -1;
- ddbheap->prev = -1;
+#ifdef KDB
+ kdbheap = malloc(KDBHEAPSZ, M_UNWIND, M_WAITOK);
+ kdbheap->sig = MSIG_FREE;
+ kdbheap->size = (KDBHEAPSZ - sizeof(struct mhdr)) >> 4;
+ kdbheap->next = -1;
+ kdbheap->prev = -1;
#endif
}
SYSINIT(unwind, SI_SUB_KMEM, SI_ORDER_ANY, unw_initialize, 0);
diff --git a/sys/ia64/include/md_var.h b/sys/ia64/include/md_var.h
index 4946709..99d03dd42 100644
--- a/sys/ia64/include/md_var.h
+++ b/sys/ia64/include/md_var.h
@@ -33,6 +33,33 @@
* Miscellaneous machine-dependent declarations.
*/
+struct ia64_fdesc {
+ uint64_t func;
+ uint64_t gp;
+};
+
+#define FDESC_FUNC(fn) (((struct ia64_fdesc *) fn)->func)
+#define FDESC_GP(fn) (((struct ia64_fdesc *) fn)->gp)
+
+/* Convenience macros to decompose CFM & ar.pfs. */
+#define IA64_CFM_SOF(x) ((x) & 0x7f)
+#define IA64_CFM_SOL(x) (((x) >> 7) & 0x7f)
+#define IA64_CFM_SOR(x) (((x) >> 14) & 0x0f)
+#define IA64_CFM_RRB_GR(x) (((x) >> 18) & 0x7f)
+#define IA64_CFM_RRB_FR(x) (((x) >> 25) & 0x7f)
+#define IA64_CFM_RRB_PR(x) (((x) >> 32) & 0x3f)
+
+/* Concenience function (inline) to adjust backingstore pointers. */
+static __inline uint64_t
+ia64_bsp_adjust(uint64_t bsp, int nslots)
+{
+ int bias = ((unsigned int)bsp & 0x1f8) >> 3;
+ nslots += (nslots + bias + 63*8) / 63 - 8;
+ return bsp + (nslots << 3);
+}
+
+#ifdef _KERNEL
+
extern char sigcode[];
extern char esigcode[];
extern int szsigcode;
@@ -43,14 +70,6 @@ struct reg;
struct thread;
struct trapframe;
-struct ia64_fdesc {
- u_int64_t func;
- u_int64_t gp;
-};
-
-#define FDESC_FUNC(fn) (((struct ia64_fdesc *) fn)->func)
-#define FDESC_GP(fn) (((struct ia64_fdesc *) fn)->gp)
-
void busdma_swi(void);
int copyout_regstack(struct thread *, uint64_t *, uint64_t *);
void cpu_mp_add(u_int, u_int, u_int);
@@ -70,4 +89,6 @@ int syscall(struct trapframe *);
void trap(int, struct trapframe *);
int unaligned_fixup(struct trapframe *, struct thread *);
+#endif /* _KERNEL */
+
#endif /* !_MACHINE_MD_VAR_H_ */
diff --git a/sys/ia64/include/unwind.h b/sys/ia64/include/unwind.h
index 4ae85ec..f203434 100644
--- a/sys/ia64/include/unwind.h
+++ b/sys/ia64/include/unwind.h
@@ -29,15 +29,19 @@
#ifndef _MACHINE_UNWIND_H_
#define _MACHINE_UNWIND_H_
+struct pcb;
+struct trapframe;
struct uwx_env;
struct unw_regstate {
+ struct pcb *pcb;
struct trapframe *frame;
struct uwx_env *env;
uint64_t keyval[8];
};
-int unw_create(struct unw_regstate *s, struct trapframe *tf);
+int unw_create_from_pcb(struct unw_regstate *s, struct pcb *pcb);
+int unw_create_from_frame(struct unw_regstate *s, struct trapframe *tf);
void unw_delete(struct unw_regstate *s);
int unw_step(struct unw_regstate *s);
OpenPOWER on IntegriCloud