xref: /csrg-svn/sys/tahoe/align/exception.c (revision 45760)
1*45760Sbostic /*-
2*45760Sbostic  * Copyright (c) 1986 The Regents of the University of California.
3*45760Sbostic  * All rights reserved.
4*45760Sbostic  *
5*45760Sbostic  * This code is derived from software contributed to Berkeley by
6*45760Sbostic  * Computer Consoles Inc.
7*45760Sbostic  *
8*45760Sbostic  * %sccs.include.redist.c%
9*45760Sbostic  *
10*45760Sbostic  *	@(#)exception.c	7.1 (Berkeley) 12/06/90
11*45760Sbostic  */
1229647Ssam 
1345699Sbostic #include "align.h"
1429647Ssam 
1529647Ssam /*
1629647Ssam  * Signal an exception. It will be handled by 'locore.s'. Here, I:
1729647Ssam  *	1) Put the exception code where it belongs on the stack.
1829647Ssam  *	2) Restore pc and sp to show that the current opcode
1929647Ssam  *		'was not executed'.
2029647Ssam  *	3) Execute one big non-local-goto. In the process we take care
2129647Ssam  *		to reset the current HW fp such that 'alignment' will
2229647Ssam  *		indeed return to 'locore.s'.
2329647Ssam  *		IMPORTANT NOTE : the process I use will NOT restore
2429647Ssam  *		all registers (like normal returns) so the call to the
2529647Ssam  *		handling routine HAS TO BE the last thing in 'alignment'.
2629647Ssam  *		Otherwise, all its own register variables will be a mess !!
2729647Ssam  *		I also know that 'alignment' itself WILL restore all
2829647Ssam  *		registers for 'locore.s' since its entry mask is all-1.
2929647Ssam  */
exception(infop,type,param1,param2)3029647Ssam exception(infop, type, param1, param2)
3129647Ssam process_info *infop;
3229647Ssam int	type, param1, param2;
3329647Ssam {
3429647Ssam 	register long *my_fp;
3529647Ssam 	register long *current_fp, *prev_fp;
3629647Ssam 
3729647Ssam 	my_fp = (long *)&infop-1 ;
3829647Ssam 	infop->ret_exception = type;
3929647Ssam 	switch (type) {
4029647Ssam 	case ARITHMETIC:
4129647Ssam 		infop->ret_code = param1;
4229647Ssam 		break;
4329647Ssam 	case ILL_ACCESS:
4429647Ssam 		infop->ret_addr = param1;
4529647Ssam 		infop->ret_code = param2;
4629647Ssam 		break;
4729647Ssam 	case ALIGNMENT:
4829647Ssam 	case ILL_ADDRMOD:
4929647Ssam 	case ILL_OPRND:
5029647Ssam 		break;
5129647Ssam 	default :
5229647Ssam 		printf ("Bad exception type %d (alignment code)\n", type);
5329647Ssam 		break;
5429647Ssam 	}
5529647Ssam /*
5629647Ssam  * Now the big trick. Look up the stack until the frame of
5729647Ssam  * 'alignment' is found. prev_fp will point to it and current_fp
5829647Ssam  * will then point to the frame of whoever 'alignment' called.
5929647Ssam  * This should better work ...
6029647Ssam  */
6129647Ssam 	prev_fp = my_fp;
6229647Ssam 	while (prev_fp != &fp) {
6329647Ssam 		current_fp = prev_fp;
6429647Ssam 		prev_fp = (long *) *prev_fp;
6529647Ssam 	}
6629647Ssam /*
6729647Ssam  * Found it. Now fool the HW into thinking that 'alignment' called
6829647Ssam  * us directly here, so this routine's 'return' will go back
6929647Ssam  * all the way to 'alignment', stopping any further emulation
7029647Ssam  * for the current offending opcode.
7129647Ssam  *  "fool the HW..." ha ha, am I realy fooling myself ?
7229647Ssam  */
7329647Ssam 	*my_fp = *current_fp;
7429647Ssam 	*(my_fp - 2) = *(current_fp -2);	/* Alter program counter */
7529647Ssam /*
7629647Ssam  * Without further ado, just go back now !!!!
7729647Ssam  */
7829647Ssam }
7929647Ssam 
not_needed(infop)8029647Ssam not_needed (infop)
8129647Ssam process_info *infop;
8229647Ssam {
8329647Ssam /*
8429647Ssam  * Shouldn't ever come to this routine.
8529647Ssam  */
8629647Ssam 
8729647Ssam 	printf ("Opcode 0x%x should not trap to alignment code.",
8829647Ssam 		opCODE);
8929647Ssam 	printf (" OS or machine problem!! \n");
9029647Ssam }
9129647Ssam 
9229647Ssam 
cannot_do(infop)9329647Ssam cannot_do (infop)
9429647Ssam process_info *infop;
9529647Ssam {
9629647Ssam /*
9729647Ssam  * Some opcode-caused alignments cannot be emulated. See table.c for
9829647Ssam  * specific reasons. Reflect this back to the process as alignment
9929647Ssam  * exception.
10029647Ssam  */
10129647Ssam 	exception (infop, ALIGNMENT);
10229647Ssam }
103