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

Commit f21a79ca authored by Max Filippov's avatar Max Filippov
Browse files

xtensa: clean up exception handling structure



Instead of using flat array of longs use normal C structure and generate
EXC_TABLE_* constants in the asm-offsets.c

Signed-off-by: default avatarMax Filippov <jcmvbkbc@gmail.com>
parent c130d3be
Loading
Loading
Loading
Loading
+0 −12
Original line number Diff line number Diff line
@@ -39,18 +39,6 @@
 *		+-----------------------+ --------
 */

/*  Offsets for exception_handlers[] (3 x 64-entries x 4-byte tables). */

#define EXC_TABLE_KSTK		0x004	/* Kernel Stack */
#define EXC_TABLE_DOUBLE_SAVE	0x008	/* Double exception save area for a0 */
#define EXC_TABLE_FIXUP		0x00c	/* Fixup handler */
#define EXC_TABLE_PARAM		0x010	/* For passing a parameter to fixup */
#define EXC_TABLE_SYSCALL_SAVE	0x014	/* For fast syscall handler */
#define EXC_TABLE_FAST_USER	0x100	/* Fast user exception handler */
#define EXC_TABLE_FAST_KERNEL	0x200	/* Fast kernel exception handler */
#define EXC_TABLE_DEFAULT	0x300	/* Default C-Handler */
#define EXC_TABLE_SIZE		0x400

#ifndef __ASSEMBLY__

#include <asm/coprocessor.h>
+1 −0
Original line number Diff line number Diff line
@@ -76,6 +76,7 @@
#define EXCCAUSE_COPROCESSOR5_DISABLED		37
#define EXCCAUSE_COPROCESSOR6_DISABLED		38
#define EXCCAUSE_COPROCESSOR7_DISABLED		39
#define EXCCAUSE_N				64

/*  PS register fields.  */

+23 −0
Original line number Diff line number Diff line
@@ -12,6 +12,29 @@

#include <asm/ptrace.h>

/*
 * Per-CPU exception handling data structure.
 * EXCSAVE1 points to it.
 */
struct exc_table {
	/* Kernel Stack */
	void *kstk;
	/* Double exception save area for a0 */
	unsigned long double_save;
	/* Fixup handler */
	void *fixup;
	/* For passing a parameter to fixup */
	void *fixup_param;
	/* For fast syscall handler */
	unsigned long syscall_save;
	/* Fast user exception handlers */
	void *fast_user_handler[EXCCAUSE_N];
	/* Fast kernel exception handlers */
	void *fast_kernel_handler[EXCCAUSE_N];
	/* Default C-Handlers */
	void *default_handler[EXCCAUSE_N];
};

/*
 * handler must be either of the following:
 *  void (*)(struct pt_regs *regs);
+13 −0
Original line number Diff line number Diff line
@@ -132,5 +132,18 @@ int main(void)
	       offsetof(struct debug_table, icount_level_save));
#endif

	/* struct exc_table */
	DEFINE(EXC_TABLE_KSTK, offsetof(struct exc_table, kstk));
	DEFINE(EXC_TABLE_DOUBLE_SAVE, offsetof(struct exc_table, double_save));
	DEFINE(EXC_TABLE_FIXUP, offsetof(struct exc_table, fixup));
	DEFINE(EXC_TABLE_PARAM, offsetof(struct exc_table, fixup_param));
	DEFINE(EXC_TABLE_SYSCALL_SAVE,
	       offsetof(struct exc_table, syscall_save));
	DEFINE(EXC_TABLE_FAST_USER,
	       offsetof(struct exc_table, fast_user_handler));
	DEFINE(EXC_TABLE_FAST_KERNEL,
	       offsetof(struct exc_table, fast_kernel_handler));
	DEFINE(EXC_TABLE_DEFAULT, offsetof(struct exc_table, default_handler));

	return 0;
}
+19 −20
Original line number Diff line number Diff line
@@ -159,8 +159,7 @@ COPROCESSOR(7),
 * 2. it is a temporary memory buffer for the exception handlers.
 */

DEFINE_PER_CPU(unsigned long, exc_table[EXC_TABLE_SIZE/4]);

DEFINE_PER_CPU(struct exc_table, exc_table);
DEFINE_PER_CPU(struct debug_table, debug_table);

void die(const char*, struct pt_regs*, long);
@@ -368,28 +367,28 @@ do_debug(struct pt_regs *regs)
}


static void set_handler(int idx, void *handler)
{
	unsigned int cpu;

	for_each_possible_cpu(cpu)
		per_cpu(exc_table, cpu)[idx] = (unsigned long)handler;
}
#define set_handler(type, cause, handler)				\
	do {								\
		unsigned int cpu;					\
									\
		for_each_possible_cpu(cpu)				\
			per_cpu(exc_table, cpu).type[cause] = (handler);\
	} while (0)

/* Set exception C handler - for temporary use when probing exceptions */

void * __init trap_set_handler(int cause, void *handler)
{
	void *previous = (void *)per_cpu(exc_table, 0)[
		EXC_TABLE_DEFAULT / 4 + cause];
	set_handler(EXC_TABLE_DEFAULT / 4 + cause, handler);
	void *previous = per_cpu(exc_table, 0).default_handler[cause];

	set_handler(default_handler, cause, handler);
	return previous;
}


static void trap_init_excsave(void)
{
	unsigned long excsave1 = (unsigned long)this_cpu_ptr(exc_table);
	unsigned long excsave1 = (unsigned long)this_cpu_ptr(&exc_table);
	__asm__ __volatile__("wsr  %0, excsave1\n" : : "a" (excsave1));
}

@@ -421,10 +420,10 @@ void __init trap_init(void)

	/* Setup default vectors. */

	for(i = 0; i < 64; i++) {
		set_handler(EXC_TABLE_FAST_USER/4   + i, user_exception);
		set_handler(EXC_TABLE_FAST_KERNEL/4 + i, kernel_exception);
		set_handler(EXC_TABLE_DEFAULT/4 + i, do_unhandled);
	for (i = 0; i < EXCCAUSE_N; i++) {
		set_handler(fast_user_handler, i, user_exception);
		set_handler(fast_kernel_handler, i, kernel_exception);
		set_handler(default_handler, i, do_unhandled);
	}

	/* Setup specific handlers. */
@@ -436,11 +435,11 @@ void __init trap_init(void)
		void *handler = dispatch_init_table[i].handler;

		if (fast == 0)
			set_handler (EXC_TABLE_DEFAULT/4 + cause, handler);
			set_handler(default_handler, cause, handler);
		if (fast && fast & USER)
			set_handler (EXC_TABLE_FAST_USER/4 + cause, handler);
			set_handler(fast_user_handler, cause, handler);
		if (fast && fast & KRNL)
			set_handler (EXC_TABLE_FAST_KERNEL/4 + cause, handler);
			set_handler(fast_kernel_handler, cause, handler);
	}

	/* Initialize EXCSAVE_1 to hold the address of the exception table. */