Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 09a07294 authored by Paul Mundt's avatar Paul Mundt
Browse files

sh: hw-breakpoints: Add preliminary support for SH-4A UBC.



This adds preliminary support for the SH-4A UBC to the hw-breakpoints API.
Presently only a single channel is implemented, and the ptrace interface
still needs to be converted. This is the first step to cleaning up the
long-standing UBC mess, making the UBC more generally accessible, and
finally making it SMP safe.

An additional abstraction will be layered on top of this as with the perf
events code to permit the various CPU families to wire up support for
their own specific UBCs, as many variations exist.

Signed-off-by: default avatarPaul Mundt <lethal@linux-sh.org>
parent 6ec22f9b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ config SUPERH32
	select HAVE_FUNCTION_TRACE_MCOUNT_TEST
	select HAVE_FUNCTION_GRAPH_TRACER
	select HAVE_ARCH_KGDB
	select HAVE_HW_BREAKPOINT if CPU_SH4A
	select ARCH_HIBERNATION_POSSIBLE if MMU

config SUPERH64
+3 −1
Original line number Diff line number Diff line
include include/asm-generic/Kbuild.asm

header-y += cachectl.h cpu-features.h
header-y += cachectl.h
header-y += cpu-features.h
header-y += hw_breakpoint.h

unifdef-y += unistd_32.h
unifdef-y += unistd_64.h
+53 −0
Original line number Diff line number Diff line
#ifndef __ASM_SH_HW_BREAKPOINT_H
#define __ASM_SH_HW_BREAKPOINT_H

#include <linux/kdebug.h>
#include <linux/types.h>
#include <asm/ubc.h>

#ifdef __KERNEL__
#define __ARCH_HW_BREAKPOINT_H

struct arch_hw_breakpoint {
	char		*name; /* Contains name of the symbol to set bkpt */
	unsigned long	address;
	unsigned long	asid;
	u16		len;
	u16		type;
};

enum {
	SH_BREAKPOINT_READ	= (1 << 1),
	SH_BREAKPOINT_WRITE	= (1 << 2),
	SH_BREAKPOINT_RW	= SH_BREAKPOINT_READ | SH_BREAKPOINT_WRITE,

	SH_BREAKPOINT_LEN_1	= (1 << 12),
	SH_BREAKPOINT_LEN_2	= (1 << 13),
	SH_BREAKPOINT_LEN_4	= SH_BREAKPOINT_LEN_1 | SH_BREAKPOINT_LEN_2,
	SH_BREAKPOINT_LEN_8	= (1 << 14),
};

/* Total number of available UBC channels */
#define HBP_NUM		1 /* XXX */

struct perf_event;
struct task_struct;
struct pmu;

extern int arch_check_va_in_userspace(unsigned long va, u16 hbp_len);
extern int arch_validate_hwbkpt_settings(struct perf_event *bp,
					 struct task_struct *tsk);
extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
					   unsigned long val, void *data);

int arch_install_hw_breakpoint(struct perf_event *bp);
void arch_uninstall_hw_breakpoint(struct perf_event *bp);
void hw_breakpoint_pmu_read(struct perf_event *bp);
void hw_breakpoint_pmu_unthrottle(struct perf_event *bp);

extern void arch_fill_perf_breakpoint(struct perf_event *bp);

extern struct pmu perf_ops_bp;

#endif /* __KERNEL__ */
#endif /* __ASM_SH_HW_BREAKPOINT_H */
+2 −0
Original line number Diff line number Diff line
@@ -6,6 +6,8 @@ enum die_val {
	DIE_TRAP,
	DIE_NMI,
	DIE_OOPS,
	DIE_BREAKPOINT,
	DIE_SSTEP,
};

#endif /* __ASM_SH_KDEBUG_H */
+3 −5
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
#include <asm/page.h>
#include <asm/types.h>
#include <asm/ptrace.h>
#include <asm/ubc.h>

/*
 * Default implementation of macro that returns current
@@ -99,8 +100,8 @@ struct thread_struct {
	unsigned long sp;
	unsigned long pc;

	/* Hardware debugging registers */
	unsigned long ubc_pc;
	/* Save middle states of ptrace breakpoints */
	struct perf_event	*ptrace_bps[NR_UBC_CHANNELS];

	/* floating point info */
	union sh_fpu_union fpu;
@@ -111,9 +112,6 @@ struct thread_struct {
#endif
};

/* Count of active tasks with UBC settings */
extern int ubc_usercnt;

#define INIT_THREAD  {						\
	.sp = sizeof(init_stack) + (long) &init_stack,		\
}
Loading