1/*
2 * Copyright (C) 2000 Anton Blanchard (anton@linuxcare.com)
3 */
4
5#ifndef _ASM_KERNPROF_H
6#define _ASM_KERNPROF_H
7
8#ifdef __KERNEL__
9
10#include <asm/system.h>
11#include <asm/ptrace.h>
12
13#define DFL_PC_RES 4		/* default PC resolution for this platform */
14
15#define in_firmware(regs) 0	/* never in the PROM during normal execution */
16
17struct frame_info {
18	struct reg_window *rw;
19	unsigned long pc;
20};
21
22typedef struct frame_info frame_info_t;
23
24static __inline__ int build_fake_frame(frame_info_t *frame)
25{
26	flush_register_windows(); /* make sure reg windows have real data */
27
28	/* flush_register_windows() does not flush the current window's registers,
29	 * so we need this first frame to be "magic". rw is set to NULL.
30	 * get_next_frame() will special case this and look at %i6/%i7 to make
31	 * the next frame.
32	 */
33
34	frame->pc = (unsigned long)current_text_addr();
35	frame->rw = NULL;
36
37	return 1;
38}
39
40static __inline__ void get_top_frame(struct pt_regs *regs, frame_info_t *p)
41{
42	p->pc = instruction_pointer(regs);
43	p->rw = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS);
44}
45
46/* This macro determines whether there are more frames to go on the stack */
47#define last_frame(p) \
48	(((char *)(p)->rw) < ((char *)current) || \
49	((char *)(p)->rw) >= ((char *)current + (2 * PAGE_SIZE) - TRACEREG_SZ - REGWIN_SZ))
50
51static __inline__ int get_next_frame(frame_info_t *p)
52{
53	if (p->rw == NULL) {
54		unsigned long reg;
55
56		__asm__ __volatile__("mov %%i6, %0" : "=r" (reg));
57		p->rw = (struct reg_window *)(reg + STACK_BIAS);
58		__asm__ __volatile__("mov %%i7, %0" : "=r" (reg));
59		p->pc = reg;
60		return 1;
61	}
62
63	if (last_frame(p)) {
64		return 0;
65	}
66
67	p->pc = (p->rw)->ins[7];
68
69	p->rw = (struct reg_window *)((p->rw)->ins[6] + STACK_BIAS);
70
71	return 1;
72}
73
74#define frame_get_pc(p)	((p)->pc)
75
76#define supports_call_graph prof_have_mcount
77
78/* No performance counters for the time being */
79#define have_perfctr() 0
80#define valid_perfctr_event(e) 0
81#define valid_perfctr_freq(n) 0
82#define perfctr_reload(x)
83#define __perfctr_stop()
84#define __perfctr_commence(x,y)
85
86#ifdef CONFIG_SMP
87#define prof_multiplier(__cpu) cpu_data[(__cpu)].multiplier
88#define get_prof_freq() (HZ * prof_multiplier(0))
89extern int setup_profiling_timer(unsigned int);
90#else
91#define get_prof_freq() (HZ)
92#define setup_profiling_timer(x) (-EINVAL)
93#endif
94
95#endif /* __KERNEL__ */
96
97#endif /* !_ASM_KERNPROF_H */
98