diff options
author | marcel <marcel@FreeBSD.org> | 2004-07-10 22:59:30 +0000 |
---|---|---|
committer | marcel <marcel@FreeBSD.org> | 2004-07-10 22:59:30 +0000 |
commit | 7c010da81a215361ead99eb4a876af2ffb16348d (patch) | |
tree | c8b0f04d69769973cb6fe1928ec74a9b9e908db4 /sys/ia64 | |
parent | 95c6c430069ffa4db994a89c4ccbf54ff21dc643 (diff) | |
download | FreeBSD-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.c | 26 | ||||
-rw-r--r-- | sys/ia64/ia64/trap.c | 23 | ||||
-rw-r--r-- | sys/ia64/ia64/unwind.c | 249 | ||||
-rw-r--r-- | sys/ia64/include/md_var.h | 37 | ||||
-rw-r--r-- | sys/ia64/include/unwind.h | 6 |
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); |