169 lines
		
	
	
	
		
			3.1 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			169 lines
		
	
	
	
		
			3.1 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
| /* machdep.S - machine dependent assembly routines for the GDB stub */
 | |
| /*
 | |
|  *  Copyright (C) 2006  Lubomir Kundrak
 | |
|  *
 | |
|  *  This program is free software; you can redistribute it and/or modify
 | |
|  *  it under the terms of the GNU General Public License as published by
 | |
|  *  the Free Software Foundation; either version 2 of the License, or
 | |
|  *  (at your option) any later version.
 | |
|  *
 | |
|  *  This program is distributed in the hope that it will be useful,
 | |
|  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
|  *  GNU General Public License for more details.
 | |
|  *
 | |
|  *  You should have received a copy of the GNU General Public License
 | |
|  *  along with this program; if not, write to the Free Software
 | |
|  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 | |
|  */
 | |
| 
 | |
| #include <grub/cpu/gdb.h>
 | |
| #include <grub/symbol.h>
 | |
| 
 | |
| #define EC_PRESENT	1
 | |
| #define EC_ABSENT	0
 | |
| 
 | |
| #define GRUB_GDB_STACKSIZE	40000
 | |
| 
 | |
| /*
 | |
|  * The .data index for the address vector.
 | |
|  */
 | |
| 
 | |
| #define	VECTOR		1
 | |
| 
 | |
| 	.bss
 | |
| 	.space GRUB_GDB_STACKSIZE
 | |
| VARIABLE(grub_gdb_stack)
 | |
| 
 | |
| /*
 | |
|  * Supplemental macros for register saving/restoration
 | |
|  * on exception handler entry/leave.
 | |
|  */
 | |
| 
 | |
| .macro save32 reg ndx
 | |
| 	movl \reg, EXT_C(grub_gdb_regs)+(\ndx * 4)
 | |
| .endm
 | |
| 
 | |
| .macro save16 reg ndx
 | |
| 	mov $0, %eax
 | |
| 	movw \reg, EXT_C(grub_gdb_regs)+(\ndx * 4)
 | |
| 	movw %ax, EXT_C(grub_gdb_regs)+(\ndx * 4 + 2)
 | |
| 	movl EXT_C(grub_gdb_regs)+(EAX * 4), %eax
 | |
| .endm
 | |
| 
 | |
| .macro load32 ndx reg
 | |
| 	movl EXT_C(grub_gdb_regs)+(\ndx * 4), \reg
 | |
| .endm
 | |
| 
 | |
| .macro load16 ndx reg
 | |
| 	movw EXT_C(grub_gdb_regs)+(\ndx * 4), \reg
 | |
| .endm
 | |
| 
 | |
| .macro save_context
 | |
| 	save32 %eax EAX
 | |
| 	save32 %ecx ECX
 | |
| 	save32 %edx EDX
 | |
| 	save32 %ebx EBX
 | |
| 	save32 %ebp EBP
 | |
| 	save32 %esi ESI
 | |
| 	save32 %edi EDI
 | |
| 
 | |
| 	popl %ebx
 | |
| 	save32 %ebx EIP
 | |
| 	popl %ebx
 | |
| 	save32 %ebx CS
 | |
| 	popl %ebx
 | |
| 	save32 %ebx EFLAGS
 | |
| 
 | |
| 	save32 %esp ESP
 | |
| 
 | |
| 	save16 %ds DS
 | |
| 	save16 %es ES
 | |
| 	save16 %fs FS
 | |
| 	save16 %gs GS
 | |
| 	save16 %ss SS
 | |
| .endm
 | |
| 
 | |
| .macro load_context
 | |
| 	load16 SS %ss
 | |
| 	load32 ESP %esp
 | |
| 
 | |
| 	load32 EBP %ebp
 | |
| 	load32 ESI %esi
 | |
| 	load32 EDI %edi
 | |
| 
 | |
| 	load16 DS %ds
 | |
| 	load16 ES %es
 | |
| 	load16 FS %fs
 | |
| 	load16 GS %gs
 | |
| 
 | |
| 	load32 EFLAGS %eax
 | |
| 	pushl %eax
 | |
| 	load32 CS %eax
 | |
| 	pushl %eax
 | |
| 	load32 EIP %eax
 | |
| 	pushl %eax
 | |
| 
 | |
| 	load32 EBX %ebx
 | |
| 	load32 EDX %edx
 | |
| 	load32 ECX %ecx
 | |
| 	load32 EAX %eax
 | |
| .endm
 | |
| 
 | |
| /*
 | |
|  * This macro creates handlers for a given range of exception numbers
 | |
|  * and adds their addresses to the grub_gdb_trapvec array.
 | |
|  */
 | |
| 
 | |
| .macro ent ec beg end=0
 | |
| 
 | |
| 	/*
 | |
| 	 * Wrapper body itself.
 | |
| 	 */
 | |
| 
 | |
| 	.text
 | |
| 1:	
 | |
| 	.if \ec
 | |
| 		add $4,%esp
 | |
| 	.endif
 | |
| 
 | |
| 	save_context
 | |
| 	mov	$EXT_C(grub_gdb_stack), %esp
 | |
| 	mov	$\beg, %eax	/* trap number */
 | |
| 	call	EXT_C(grub_gdb_trap)
 | |
| 	load_context
 | |
| 	iret
 | |
| 
 | |
| 	/*
 | |
| 	 * Address entry in trapvec array.
 | |
| 	 */
 | |
| 
 | |
| 	.data VECTOR
 | |
| 	.long 1b
 | |
| 
 | |
| 	/*
 | |
| 	 * Next... (recursion).
 | |
| 	 */
 | |
| 
 | |
| 	.if \end-\beg > 0
 | |
| 		ent \ec "(\beg+1)" \end
 | |
| 	.endif
 | |
| .endm
 | |
| 
 | |
| /*
 | |
|  * Here does the actual construction of the address array and handlers
 | |
|  * take place.
 | |
|  */
 | |
| 
 | |
| 	.data VECTOR
 | |
| 
 | |
| VARIABLE(grub_gdb_trapvec)
 | |
| 	ent EC_ABSENT	0 7
 | |
| 	ent EC_PRESENT	8
 | |
| 	ent EC_ABSENT	9
 | |
| 	ent EC_PRESENT	10 14
 | |
| 	/*
 | |
| 	 * You may have to split this further or as(1)
 | |
| 	 * will complain about nesting being too deep.
 | |
| 	 */
 | |
| 	ent EC_ABSENT	15 GRUB_GDB_LAST_TRAP
 |