/*
 * include/asm-s390/lc_trace.h
 *
 * S390 version
 *   Copyright (C) 2001 IBM Deutschland Entwicklung GmbH,
 *                      IBM Corporation
 *
 * Derived from include/asm-i386/lc_trace.h
 *   Copyright 1999 Silicon Graphics, Inc. All rights reserved.
 */

#define STACK_SEGMENTS	 2
#define STACK_SIZE	 KSTACK_SIZE
#define STD_SFRAME_SIZE  96
#define ADDR_MASK        0x7fffffffUL
#define RA_OFFSET        56
#define CURRENT_TASK(SP) ((SP) & 0xffffe000UL)
#define IS_USER_PSW(PSW) ((PSW) & 0x10000UL)

/* Stack frame
 */
typedef struct sframe_rec {
	struct sframe_rec      *next;
	struct sframe_rec      *prev;
	int			flag;
	int			level;
	char		       *funcname;
	char		       *srcfile;
	int			line_no;
	kaddr_t			pc;
	kaddr_t			ra;
	kaddr_t			sp;
	kaddr_t			fp;
	uaddr_t	               *asp;
	int			frame_size;
	int			ptr;
	uint64_t		error;
} sframe_t;

/* Stack segment structure
 */
struct stack_s {
	int			type;
	uint32_t		size;
	kaddr_t			addr;
	uint32_t	       *ptr;
};

/* Stack trace header
 */
typedef struct trace_rec {
	int			flags;
	kaddr_t			task;
	void			*tsp;
	struct stack_s		stack[STACK_SEGMENTS];
	int			stackcnt;
	sframe_t	       *frame;
	int			nframes;
} trace_t;

#define TF_TRACEREC_VALID  0x01 /* The trace_rec_s has been setup already!   */
#define TF_SUPPRESS_HEADER 0x02 /* Suppress header output from trace cmds    */

/* Stack types 
 */
#define S_USERSTACK	0
#define S_KERNELSTACK	1
#define S_ASYNCSTACK    2

/* Stack frame updating macro
 */
#define UPDATE_FRAME(FUNCNAME, PC, RA, SP, FP, ASP, SRCNAME, LINE_NO, SIZE) \
        curframe->funcname = FUNCNAME; \
        curframe->pc = PC; \
        curframe->sp = SP; \
        curframe->ra = RA; \
        curframe->fp = FP; \
        curframe->asp = ASP; \
        curframe->srcfile = SRCNAME; \
        curframe->line_no = LINE_NO; \
        curframe->frame_size = SIZE; \
        curframe->ptr = curstkidx; \
        kl_enqueue((element_t **)&trace->frame, (element_t *)curframe); \
        trace->nframes++; \

/* Function prototypes
 */
void print_pc(
	kaddr_t 	/* PC */, 
	FILE *		/* output file pointer */);

trace_t *alloc_trace_rec(
	int 		/* flag */);

int setup_trace_rec(kaddr_t, kaddr_t, int, trace_t *);
int find_trace(kaddr_t, kaddr_t, kaddr_t, kaddr_t, trace_t *, int);
void trace_banner(FILE *);
int print_traces(kaddr_t, int, int, FILE *);
void print_trace(trace_t *, int, FILE *);
void free_trace_rec(trace_t *t);
int task_trace(kaddr_t, int, FILE *);
int do_list(kaddr_t, int, FILE *);
void live_vmdump(int, int);
int do_report(int, FILE *);
void stab_type_banner(FILE *, int);
void ktype_banner(FILE *, int);
void print_stab_type(stab_type_t *, int, FILE *);
void print_ktype(kltype_t *, int, FILE *);
void walk_ktype(kltype_t *, int, FILE *);
int list_stab_types(int, FILE *);
int list_ktypes(int, FILE *);
void structlist(FILE *);
int walk_structs(char *, char *, int, kaddr_t, int, FILE *);
sframe_t *alloc_sframe(trace_t *, int);
int add_frame(trace_t *, kaddr_t, kaddr_t);
void finish_trace(trace_t *);
int dumptask_trace(kaddr_t, dump_header_asm_t *, int, FILE *);
