Mercurial > flash_v2
annotate packages/hal/arm/arch/current/src/arm_stub.c @ 1777:c16341b1bac6 default tip
* Added execute permissions to files missed in conversion from CVS
| author | alexs |
|---|---|
| date | Mon, 12 Oct 2009 02:26:09 +0100 |
| parents | 609c8b1447ee |
| children |
| rev | line source |
|---|---|
|
64
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
54
diff
changeset
|
1 //======================================================================== |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
54
diff
changeset
|
2 // |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
54
diff
changeset
|
3 // arm_stub.c |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
54
diff
changeset
|
4 // |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
54
diff
changeset
|
5 // Helper functions for stub, generic to all ARM processors |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
54
diff
changeset
|
6 // |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
54
diff
changeset
|
7 //======================================================================== |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
8 //####ECOSGPLCOPYRIGHTBEGIN#### |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
9 // ------------------------------------------- |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
10 // This file is part of eCos, the Embedded Configurable Operating System. |
| 1002 | 11 // Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc. |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
12 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
13 // eCos is free software; you can redistribute it and/or modify it under |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
14 // the terms of the GNU General Public License as published by the Free |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
15 // Software Foundation; either version 2 or (at your option) any later version. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
16 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
19 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
20 // for more details. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
21 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
22 // You should have received a copy of the GNU General Public License along |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
23 // with eCos; if not, write to the Free Software Foundation, Inc., |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
25 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
26 // As a special exception, if other files instantiate templates or use macros |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
27 // or inline functions from this file, or you compile this file and link it |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
28 // with other works to produce a work based on this file, this file does not |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
29 // by itself cause the resulting work to be covered by the GNU General Public |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
30 // License. However the source code for this file must still be made available |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
31 // in accordance with section (3) of the GNU General Public License. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
32 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
33 // This exception does not invalidate any other reasons why a work based on |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
34 // this file might be covered by the GNU General Public License. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
35 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
|
210
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
37 // at http://sources.redhat.com/ecos/ecos-license/ |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
38 // ------------------------------------------- |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
39 //####ECOSGPLCOPYRIGHTEND#### |
|
64
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
54
diff
changeset
|
40 //======================================================================== |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
54
diff
changeset
|
41 //#####DESCRIPTIONBEGIN#### |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
54
diff
changeset
|
42 // |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
54
diff
changeset
|
43 // Author(s): Red Hat, gthomas |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
54
diff
changeset
|
44 // Contributors: Red Hat, gthomas, jskov |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
54
diff
changeset
|
45 // Date: 1998-11-26 |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
54
diff
changeset
|
46 // Purpose: |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
54
diff
changeset
|
47 // Description: Helper functions for stub, generic to all ARM processors |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
54
diff
changeset
|
48 // Usage: |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
54
diff
changeset
|
49 // |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
54
diff
changeset
|
50 //####DESCRIPTIONEND#### |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
54
diff
changeset
|
51 // |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
54
diff
changeset
|
52 //======================================================================== |
| 2 | 53 |
| 54 #include <stddef.h> | |
| 55 | |
| 56 #include <pkgconf/hal.h> | |
| 57 | |
|
136
a9ac27ec7abc
Merge from eCos master repository on 2000-11-17-18:24:25-GMT
jlarmour
parents:
132
diff
changeset
|
58 #ifdef CYGPKG_REDBOOT |
|
a9ac27ec7abc
Merge from eCos master repository on 2000-11-17-18:24:25-GMT
jlarmour
parents:
132
diff
changeset
|
59 #include <pkgconf/redboot.h> |
|
a9ac27ec7abc
Merge from eCos master repository on 2000-11-17-18:24:25-GMT
jlarmour
parents:
132
diff
changeset
|
60 #endif |
|
a9ac27ec7abc
Merge from eCos master repository on 2000-11-17-18:24:25-GMT
jlarmour
parents:
132
diff
changeset
|
61 |
| 2 | 62 #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS |
| 63 | |
|
72
da3908c9cd10
Merge from eCos master repository on 2000-02-17-18:56:14-GMT
jlarmour
parents:
66
diff
changeset
|
64 #ifdef CYGPKG_HAL_ARM_SIM |
| 2 | 65 #error "GDB Stub support not implemented for ARM SIM" |
| 66 #endif | |
| 67 | |
| 68 #include <cyg/hal/hal_stub.h> | |
| 69 #include <cyg/hal/hal_arch.h> | |
| 70 #include <cyg/hal/hal_intr.h> | |
| 71 | |
| 72 #ifndef FALSE | |
| 73 #define FALSE 0 | |
| 74 #define TRUE 1 | |
| 75 #endif | |
| 76 | |
|
76
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
77 // Use bit 0 as a thumb-mode flag for next address to be executed. |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
78 // Alternative would be to keep track of it using a C variable, but |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
79 // since bit 0 is used by the BX instruction, we might as well do the |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
80 // same thing and thus avoid checking two different flags. |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
81 #define IS_THUMB_ADDR(addr) ((addr) & 1) |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
82 #define MAKE_THUMB_ADDR(addr) ((addr) | 1) |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
83 #define UNMAKE_THUMB_ADDR(addr) ((addr) & ~1) |
|
36
e97d78785e2d
Merge from eCos master repository on 1999-09-12-15:40:34-BST
jlarmour
parents:
34
diff
changeset
|
84 |
| 2 | 85 #ifdef CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT |
| 86 #include <cyg/hal/dbg-threads-api.h> // dbg_currthread_id | |
| 87 #endif | |
| 88 | |
|
151
25e238959bae
Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
136
diff
changeset
|
89 #if defined(CYGNUM_HAL_BREAKPOINT_LIST_SIZE) && (CYGNUM_HAL_BREAKPOINT_LIST_SIZE > 0) |
|
25e238959bae
Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
136
diff
changeset
|
90 cyg_uint32 __arm_breakinst = HAL_BREAKINST_ARM; |
|
25e238959bae
Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
136
diff
changeset
|
91 cyg_uint16 __thumb_breakinst = HAL_BREAKINST_THUMB; |
|
25e238959bae
Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
136
diff
changeset
|
92 #endif |
|
25e238959bae
Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
136
diff
changeset
|
93 |
| 2 | 94 /* Given a trap value TRAP, return the corresponding signal. */ |
| 95 | |
| 96 int __computeSignal (unsigned int trap_number) | |
| 97 { | |
|
132
0ae0bc38e387
Merge from eCos master repository on 2000-10-31-00:30:36-GMT
jlarmour
parents:
115
diff
changeset
|
98 // Check to see if we stopped because of a hw watchpoint/breakpoint. |
|
0ae0bc38e387
Merge from eCos master repository on 2000-10-31-00:30:36-GMT
jlarmour
parents:
115
diff
changeset
|
99 #ifdef HAL_STUB_IS_STOPPED_BY_HARDWARE |
|
136
a9ac27ec7abc
Merge from eCos master repository on 2000-11-17-18:24:25-GMT
jlarmour
parents:
132
diff
changeset
|
100 { |
|
a9ac27ec7abc
Merge from eCos master repository on 2000-11-17-18:24:25-GMT
jlarmour
parents:
132
diff
changeset
|
101 void *daddr; |
|
a9ac27ec7abc
Merge from eCos master repository on 2000-11-17-18:24:25-GMT
jlarmour
parents:
132
diff
changeset
|
102 if (HAL_STUB_IS_STOPPED_BY_HARDWARE(daddr)) |
|
a9ac27ec7abc
Merge from eCos master repository on 2000-11-17-18:24:25-GMT
jlarmour
parents:
132
diff
changeset
|
103 return SIGTRAP; |
|
a9ac27ec7abc
Merge from eCos master repository on 2000-11-17-18:24:25-GMT
jlarmour
parents:
132
diff
changeset
|
104 } |
|
132
0ae0bc38e387
Merge from eCos master repository on 2000-10-31-00:30:36-GMT
jlarmour
parents:
115
diff
changeset
|
105 #endif |
|
36
e97d78785e2d
Merge from eCos master repository on 1999-09-12-15:40:34-BST
jlarmour
parents:
34
diff
changeset
|
106 // should also catch CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION here but we |
|
e97d78785e2d
Merge from eCos master repository on 1999-09-12-15:40:34-BST
jlarmour
parents:
34
diff
changeset
|
107 // can't tell the different between a real one and a breakpoint :-( |
| 2 | 108 switch (trap_number) { |
|
36
e97d78785e2d
Merge from eCos master repository on 1999-09-12-15:40:34-BST
jlarmour
parents:
34
diff
changeset
|
109 case CYGNUM_HAL_VECTOR_ABORT_PREFETCH: // Fall through |
|
e97d78785e2d
Merge from eCos master repository on 1999-09-12-15:40:34-BST
jlarmour
parents:
34
diff
changeset
|
110 case CYGNUM_HAL_VECTOR_ABORT_DATA: // Fall through |
|
e97d78785e2d
Merge from eCos master repository on 1999-09-12-15:40:34-BST
jlarmour
parents:
34
diff
changeset
|
111 case CYGNUM_HAL_VECTOR_reserved: |
|
e97d78785e2d
Merge from eCos master repository on 1999-09-12-15:40:34-BST
jlarmour
parents:
34
diff
changeset
|
112 return SIGBUS; |
|
e97d78785e2d
Merge from eCos master repository on 1999-09-12-15:40:34-BST
jlarmour
parents:
34
diff
changeset
|
113 case CYGNUM_HAL_VECTOR_IRQ: |
|
e97d78785e2d
Merge from eCos master repository on 1999-09-12-15:40:34-BST
jlarmour
parents:
34
diff
changeset
|
114 case CYGNUM_HAL_VECTOR_FIQ: |
|
e97d78785e2d
Merge from eCos master repository on 1999-09-12-15:40:34-BST
jlarmour
parents:
34
diff
changeset
|
115 return SIGINT; |
| 2 | 116 default: |
| 117 return SIGTRAP; | |
| 118 } | |
| 119 } | |
| 120 | |
| 121 | |
| 122 /* Return the trap number corresponding to the last-taken trap. */ | |
| 123 int __get_trap_number (void) | |
| 124 { | |
| 125 // The vector is not not part of the GDB register set so get it | |
| 126 // directly from the save context. | |
|
36
e97d78785e2d
Merge from eCos master repository on 1999-09-12-15:40:34-BST
jlarmour
parents:
34
diff
changeset
|
127 return _hal_registers->vector; |
| 2 | 128 } |
| 129 | |
|
136
a9ac27ec7abc
Merge from eCos master repository on 2000-11-17-18:24:25-GMT
jlarmour
parents:
132
diff
changeset
|
130 |
|
a9ac27ec7abc
Merge from eCos master repository on 2000-11-17-18:24:25-GMT
jlarmour
parents:
132
diff
changeset
|
131 #if defined(CYGSEM_REDBOOT_BSP_SYSCALLS) |
|
a9ac27ec7abc
Merge from eCos master repository on 2000-11-17-18:24:25-GMT
jlarmour
parents:
132
diff
changeset
|
132 int __is_bsp_syscall(void) |
|
a9ac27ec7abc
Merge from eCos master repository on 2000-11-17-18:24:25-GMT
jlarmour
parents:
132
diff
changeset
|
133 { |
|
151
25e238959bae
Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
136
diff
changeset
|
134 unsigned long pc = get_register(PC); |
|
25e238959bae
Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
136
diff
changeset
|
135 unsigned long cpsr = get_register(PS); // condition codes |
|
25e238959bae
Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
136
diff
changeset
|
136 |
|
25e238959bae
Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
136
diff
changeset
|
137 if (_hal_registers->vector == CYGNUM_HAL_EXCEPTION_INTERRUPT) { |
|
25e238959bae
Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
136
diff
changeset
|
138 if (cpsr & CPSR_THUMB_ENABLE) |
|
25e238959bae
Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
136
diff
changeset
|
139 return *(unsigned short *)pc == 0xdf18; |
|
25e238959bae
Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
136
diff
changeset
|
140 else |
|
25e238959bae
Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
136
diff
changeset
|
141 return *(unsigned *)pc == 0xef180001; |
|
25e238959bae
Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
136
diff
changeset
|
142 } |
|
25e238959bae
Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
136
diff
changeset
|
143 return 0; |
|
136
a9ac27ec7abc
Merge from eCos master repository on 2000-11-17-18:24:25-GMT
jlarmour
parents:
132
diff
changeset
|
144 } |
|
a9ac27ec7abc
Merge from eCos master repository on 2000-11-17-18:24:25-GMT
jlarmour
parents:
132
diff
changeset
|
145 #endif |
|
a9ac27ec7abc
Merge from eCos master repository on 2000-11-17-18:24:25-GMT
jlarmour
parents:
132
diff
changeset
|
146 |
|
76
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
147 /* Set the currently-saved pc register value to PC. */ |
| 2 | 148 |
| 149 void set_pc (target_register_t pc) | |
| 150 { | |
| 151 put_register (PC, pc); | |
| 152 } | |
| 153 | |
| 304 | 154 // Calculate byte offset a given register from start of register save area. |
| 155 static int | |
| 156 reg_offset(regnames_t reg) | |
| 157 { | |
| 158 int base_offset; | |
| 159 | |
| 160 if (reg < F0) | |
| 161 return reg * 4; | |
| 162 | |
| 163 base_offset = 16 * 4; | |
| 164 | |
| 165 if (reg < FPS) | |
| 166 return base_offset + ((reg - F0) * 12); | |
| 167 | |
| 168 base_offset += (8 * 12); | |
| 169 | |
| 170 if (reg <= PS) | |
| 171 return base_offset + ((reg - FPS) * 4); | |
| 172 | |
| 173 return -1; // Should never happen! | |
| 174 } | |
| 175 | |
| 176 | |
| 177 // Return the currently-saved value corresponding to register REG of | |
| 178 // the exception context. | |
| 179 target_register_t | |
| 180 get_register (regnames_t reg) | |
| 181 { | |
| 182 target_register_t val; | |
| 183 int offset = reg_offset(reg); | |
| 184 | |
| 185 if (REGSIZE(reg) > sizeof(target_register_t) || offset == -1) | |
| 186 return -1; | |
| 187 | |
| 188 val = _registers[offset/sizeof(target_register_t)]; | |
| 189 | |
| 190 return val; | |
| 191 } | |
| 192 | |
| 193 // Store VALUE in the register corresponding to WHICH in the exception | |
| 194 // context. | |
| 195 void | |
| 196 put_register (regnames_t which, target_register_t value) | |
| 197 { | |
| 198 int offset = reg_offset(which); | |
| 199 | |
| 200 if (REGSIZE(which) > sizeof(target_register_t) || offset == -1) | |
| 201 return; | |
| 202 | |
| 203 _registers[offset/sizeof(target_register_t)] = value; | |
| 204 } | |
| 205 | |
| 206 // Write the contents of register WHICH into VALUE as raw bytes. This | |
| 207 // is only used for registers larger than sizeof(target_register_t). | |
| 208 // Return non-zero if it is a valid register. | |
| 209 int | |
| 210 get_register_as_bytes (regnames_t which, char *value) | |
| 211 { | |
| 212 int offset = reg_offset(which); | |
| 213 | |
| 214 if (offset != -1) { | |
| 215 memcpy (value, (char *)_registers + offset, REGSIZE(which)); | |
| 216 return 1; | |
| 217 } | |
| 218 return 0; | |
| 219 } | |
| 220 | |
| 221 // Alter the contents of saved register WHICH to contain VALUE. This | |
| 222 // is only used for registers larger than sizeof(target_register_t). | |
| 223 // Return non-zero if it is a valid register. | |
| 224 int | |
| 225 put_register_as_bytes (regnames_t which, char *value) | |
| 226 { | |
| 227 int offset = reg_offset(which); | |
| 228 | |
| 229 if (offset != -1) { | |
| 230 memcpy ((char *)_registers + offset, value, REGSIZE(which)); | |
| 231 return 1; | |
| 232 } | |
| 233 return 0; | |
| 234 } | |
| 2 | 235 |
| 236 /*---------------------------------------------------------------------- | |
| 237 * Single-step support | |
| 238 */ | |
| 239 | |
| 240 /* Set things up so that the next user resume will execute one instruction. | |
| 241 This may be done by setting breakpoints or setting a single step flag | |
| 242 in the saved user registers, for example. */ | |
| 243 | |
|
54
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
244 static unsigned long ss_saved_pc = 0; |
|
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
245 static unsigned long ss_saved_instr; |
|
76
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
246 static unsigned short ss_saved_thumb_instr; |
|
36
e97d78785e2d
Merge from eCos master repository on 1999-09-12-15:40:34-BST
jlarmour
parents:
34
diff
changeset
|
247 |
| 2 | 248 #define FIXME() {diag_printf("FIXME - %s\n", __FUNCTION__); } |
| 249 | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
250 // return non-zero for v5 and later |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
251 static int |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
252 v5T_semantics(void) |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
253 { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
254 unsigned id; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
255 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
256 asm volatile ("mrc p15,0,%0,c0,c0,0\n" |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
257 : "=r" (id) : /* no inputs */); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
258 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
259 return ((id >> 16) & 0xff) >= 5; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
260 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
261 |
| 2 | 262 static int |
| 263 ins_will_execute(unsigned long ins) | |
| 264 { | |
| 265 unsigned long psr = get_register(PS); // condition codes | |
| 266 int res = 0; | |
| 267 switch ((ins & 0xF0000000) >> 28) { | |
| 268 case 0x0: // EQ | |
| 269 res = (psr & PS_Z) != 0; | |
| 270 break; | |
| 271 case 0x1: // NE | |
| 272 res = (psr & PS_Z) == 0; | |
| 273 break; | |
| 274 case 0x2: // CS | |
| 275 res = (psr & PS_C) != 0; | |
| 276 break; | |
| 277 case 0x3: // CC | |
| 278 res = (psr & PS_C) == 0; | |
| 279 break; | |
| 280 case 0x4: // MI | |
| 281 res = (psr & PS_N) != 0; | |
| 282 break; | |
| 283 case 0x5: // PL | |
| 284 res = (psr & PS_N) == 0; | |
| 285 break; | |
| 286 case 0x6: // VS | |
| 287 res = (psr & PS_V) != 0; | |
| 288 break; | |
| 289 case 0x7: // VC | |
| 290 res = (psr & PS_V) == 0; | |
| 291 break; | |
| 292 case 0x8: // HI | |
|
34
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
2
diff
changeset
|
293 res = ((psr & PS_C) != 0) && ((psr & PS_Z) == 0); |
| 2 | 294 break; |
| 295 case 0x9: // LS | |
|
34
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
2
diff
changeset
|
296 res = ((psr & PS_C) == 0) || ((psr & PS_Z) != 0); |
| 2 | 297 break; |
| 298 case 0xA: // GE | |
| 299 res = ((psr & (PS_N|PS_V)) == (PS_N|PS_V)) || | |
| 300 ((psr & (PS_N|PS_V)) == 0); | |
| 301 break; | |
| 302 case 0xB: // LT | |
| 303 res = ((psr & (PS_N|PS_V)) == PS_N) || | |
| 304 ((psr & (PS_N|PS_V)) == PS_V); | |
| 305 break; | |
| 306 case 0xC: // GT | |
| 307 res = ((psr & (PS_N|PS_V)) == (PS_N|PS_V)) || | |
| 308 ((psr & (PS_N|PS_V)) == 0); | |
| 309 res = ((psr & PS_Z) == 0) && res; | |
| 310 break; | |
| 311 case 0xD: // LE | |
| 312 res = ((psr & (PS_N|PS_V)) == PS_N) || | |
| 313 ((psr & (PS_N|PS_V)) == PS_V); | |
| 314 res = ((psr & PS_Z) == PS_Z) || res; | |
| 315 break; | |
| 316 case 0xE: // AL | |
| 317 res = TRUE; | |
| 318 break; | |
| 319 case 0xF: // NV | |
|
158
f2545e5de153
Merge from eCos master repository on 2001-04-24-11:22:42-BST
jlarmour
parents:
151
diff
changeset
|
320 if (((ins & 0x0E000000) >> 24) == 0xA) |
|
f2545e5de153
Merge from eCos master repository on 2001-04-24-11:22:42-BST
jlarmour
parents:
151
diff
changeset
|
321 res = TRUE; |
|
f2545e5de153
Merge from eCos master repository on 2001-04-24-11:22:42-BST
jlarmour
parents:
151
diff
changeset
|
322 else |
|
f2545e5de153
Merge from eCos master repository on 2001-04-24-11:22:42-BST
jlarmour
parents:
151
diff
changeset
|
323 res = FALSE; |
| 2 | 324 break; |
| 325 } | |
| 326 return res; | |
| 327 } | |
| 328 | |
| 329 static unsigned long | |
| 330 RmShifted(int shift) | |
| 331 { | |
| 332 unsigned long Rm = get_register(shift & 0x00F); | |
| 333 int shift_count; | |
| 334 if ((shift & 0x010) == 0) { | |
| 335 shift_count = (shift & 0xF80) >> 7; | |
| 336 } else { | |
| 337 shift_count = get_register((shift & 0xF00) >> 8); | |
| 338 } | |
| 339 switch ((shift & 0x060) >> 5) { | |
| 340 case 0x0: // Logical left | |
| 341 Rm <<= shift_count; | |
| 342 break; | |
| 343 case 0x1: // Logical right | |
| 344 Rm >>= shift_count; | |
| 345 break; | |
| 346 case 0x2: // Arithmetic right | |
| 347 Rm = (unsigned long)((long)Rm >> shift_count); | |
| 348 break; | |
| 349 case 0x3: // Rotate right | |
| 350 if (shift_count == 0) { | |
| 351 // Special case, RORx | |
| 352 Rm >>= 1; | |
| 353 if (get_register(PS) & PS_C) Rm |= 0x80000000; | |
| 354 } else { | |
| 355 Rm = (Rm >> shift_count) | (Rm << (32-shift_count)); | |
| 356 } | |
| 357 break; | |
| 358 } | |
| 359 return Rm; | |
| 360 } | |
| 361 | |
| 362 // Decide the next instruction to be executed for a given instruction | |
| 363 static unsigned long * | |
| 364 target_ins(unsigned long *pc, unsigned long ins) | |
| 365 { | |
| 366 unsigned long new_pc, offset, op2; | |
| 367 unsigned long Rn; | |
| 368 int i, reg_count, c; | |
|
158
f2545e5de153
Merge from eCos master repository on 2001-04-24-11:22:42-BST
jlarmour
parents:
151
diff
changeset
|
369 |
| 2 | 370 switch ((ins & 0x0C000000) >> 26) { |
| 371 case 0x0: | |
|
158
f2545e5de153
Merge from eCos master repository on 2001-04-24-11:22:42-BST
jlarmour
parents:
151
diff
changeset
|
372 // BX or BLX |
|
f2545e5de153
Merge from eCos master repository on 2001-04-24-11:22:42-BST
jlarmour
parents:
151
diff
changeset
|
373 if ((ins & 0x0FFFFFD0) == 0x012FFF10) { |
|
76
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
374 new_pc = (unsigned long)get_register(ins & 0x0000000F); |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
375 return ((unsigned long *)new_pc); |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
376 } |
| 2 | 377 // Data processing |
| 378 new_pc = (unsigned long)(pc+1); | |
| 379 if ((ins & 0x0000F000) == 0x0000F000) { | |
| 380 // Destination register is PC | |
| 381 if ((ins & 0x0FBF0000) != 0x010F0000) { | |
| 382 Rn = (unsigned long)get_register((ins & 0x000F0000) >> 16); | |
| 415 | 383 if ((ins & 0x000F0000) == 0x000F0000) Rn += 8; // PC prefetch! |
| 2 | 384 if ((ins & 0x02000000) == 0) { |
| 385 op2 = RmShifted(ins & 0x00000FFF); | |
| 386 } else { | |
| 387 op2 = ins & 0x000000FF; | |
| 388 i = (ins & 0x00000F00) >> 8; // Rotate count | |
| 389 op2 = (op2 >> (i*2)) | (op2 << (32-(i*2))); | |
| 390 } | |
| 391 switch ((ins & 0x01E00000) >> 21) { | |
| 392 case 0x0: // AND | |
| 393 new_pc = Rn & op2; | |
| 394 break; | |
| 395 case 0x1: // EOR | |
| 396 new_pc = Rn ^ op2; | |
| 397 break; | |
| 398 case 0x2: // SUB | |
| 399 new_pc = Rn - op2; | |
| 400 break; | |
| 401 case 0x3: // RSB | |
| 402 new_pc = op2 - Rn; | |
| 403 break; | |
| 404 case 0x4: // ADD | |
| 405 new_pc = Rn + op2; | |
| 406 break; | |
| 407 case 0x5: // ADC | |
| 408 c = (get_register(PS) & PS_C) != 0; | |
| 409 new_pc = Rn + op2 + c; | |
| 410 break; | |
| 411 case 0x6: // SBC | |
| 412 c = (get_register(PS) & PS_C) != 0; | |
| 413 new_pc = Rn - op2 + c - 1; | |
| 414 break; | |
| 415 case 0x7: // RSC | |
| 416 c = (get_register(PS) & PS_C) != 0; | |
| 417 new_pc = op2 - Rn +c - 1; | |
| 418 break; | |
| 419 case 0x8: // TST | |
| 420 case 0x9: // TEQ | |
| 421 case 0xA: // CMP | |
| 422 case 0xB: // CMN | |
| 423 break; // PC doesn't change | |
| 424 case 0xC: // ORR | |
| 425 new_pc = Rn | op2; | |
| 426 break; | |
| 427 case 0xD: // MOV | |
| 428 new_pc = op2; | |
| 429 break; | |
| 430 case 0xE: // BIC | |
| 431 new_pc = Rn & ~op2; | |
| 432 break; | |
| 433 case 0xF: // MVN | |
| 434 new_pc = ~op2; | |
| 435 break; | |
| 436 } | |
| 437 } | |
| 438 } | |
| 439 return ((unsigned long *)new_pc); | |
| 440 case 0x1: | |
| 441 if ((ins & 0x02000010) == 0x02000010) { | |
| 442 // Undefined! | |
| 443 return (pc+1); | |
| 444 } else { | |
| 445 if ((ins & 0x00100000) == 0) { | |
| 446 // STR | |
| 447 return (pc+1); | |
| 448 } else { | |
| 449 // LDR | |
| 450 if ((ins & 0x0000F000) != 0x0000F000) { | |
| 451 // Rd not PC | |
| 452 return (pc+1); | |
| 453 } else { | |
| 454 Rn = (unsigned long)get_register((ins & 0x000F0000) >> 16); | |
| 455 if ((ins & 0x000F0000) == 0x000F0000) Rn += 8; // PC prefetch! | |
| 456 if (ins & 0x01000000) { | |
| 457 // Add/subtract offset before | |
| 458 if ((ins & 0x02000000) == 0) { | |
| 459 // Immediate offset | |
| 460 if (ins & 0x00800000) { | |
| 461 // Add offset | |
| 462 Rn += (ins & 0x00000FFF); | |
| 463 } else { | |
| 464 // Subtract offset | |
| 465 Rn -= (ins & 0x00000FFF); | |
| 466 } | |
| 467 } else { | |
| 468 // Offset is in a register | |
| 469 if (ins & 0x00800000) { | |
| 470 // Add offset | |
| 471 Rn += RmShifted(ins & 0x00000FFF); | |
| 472 } else { | |
| 473 // Subtract offset | |
| 474 Rn -= RmShifted(ins & 0x00000FFF); | |
| 475 } | |
| 476 } | |
| 477 } | |
| 478 return ((unsigned long *)*(unsigned long *)Rn); | |
| 479 } | |
| 480 } | |
| 481 } | |
| 482 return (pc+1); | |
| 483 case 0x2: // Branch, LDM/STM | |
| 484 if ((ins & 0x02000000) == 0) { | |
| 485 // LDM/STM | |
| 486 if ((ins & 0x00100000) == 0) { | |
| 487 // STM | |
| 488 return (pc+1); | |
| 489 } else { | |
| 490 // LDM | |
| 491 if ((ins & 0x00008000) == 0) { | |
| 492 // PC not in list | |
| 493 return (pc+1); | |
| 494 } else { | |
| 495 Rn = (unsigned long)get_register((ins & 0x000F0000) >> 16); | |
| 496 if ((ins & 0x000F0000) == 0x000F0000) Rn += 8; // PC prefetch! | |
| 497 offset = ins & 0x0000FFFF; | |
| 498 reg_count = 0; | |
| 499 for (i = 0; i < 15; i++) { | |
| 500 if (offset & (1<<i)) reg_count++; | |
| 501 } | |
| 502 if (ins & 0x00800000) { | |
| 503 // Add offset | |
| 504 Rn += reg_count*4; | |
| 505 } else { | |
| 506 // Subtract offset | |
| 507 Rn -= 4; | |
| 508 } | |
| 509 return ((unsigned long *)*(unsigned long *)Rn); | |
| 510 } | |
| 511 } | |
| 512 } else { | |
| 513 // Branch | |
|
34
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
2
diff
changeset
|
514 if (ins_will_execute(ins)) { |
|
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
2
diff
changeset
|
515 offset = (ins & 0x00FFFFFF) << 2; |
|
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
2
diff
changeset
|
516 if (ins & 0x00800000) offset |= 0xFC000000; // sign extend |
|
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
2
diff
changeset
|
517 new_pc = (unsigned long)(pc+2) + offset; |
|
158
f2545e5de153
Merge from eCos master repository on 2001-04-24-11:22:42-BST
jlarmour
parents:
151
diff
changeset
|
518 // If its BLX, make new_pc a thumb address. |
|
f2545e5de153
Merge from eCos master repository on 2001-04-24-11:22:42-BST
jlarmour
parents:
151
diff
changeset
|
519 if ((ins & 0xFE000000) == 0xFA000000) { |
|
f2545e5de153
Merge from eCos master repository on 2001-04-24-11:22:42-BST
jlarmour
parents:
151
diff
changeset
|
520 if ((ins & 0x01000000) == 0x01000000) |
|
f2545e5de153
Merge from eCos master repository on 2001-04-24-11:22:42-BST
jlarmour
parents:
151
diff
changeset
|
521 new_pc |= 2; |
|
f2545e5de153
Merge from eCos master repository on 2001-04-24-11:22:42-BST
jlarmour
parents:
151
diff
changeset
|
522 new_pc = MAKE_THUMB_ADDR(new_pc); |
|
f2545e5de153
Merge from eCos master repository on 2001-04-24-11:22:42-BST
jlarmour
parents:
151
diff
changeset
|
523 } |
|
34
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
2
diff
changeset
|
524 return ((unsigned long *)new_pc); |
|
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
2
diff
changeset
|
525 } else { |
|
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
2
diff
changeset
|
526 // Falls through |
|
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
2
diff
changeset
|
527 return (pc+1); |
|
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
2
diff
changeset
|
528 } |
| 2 | 529 } |
| 530 case 0x3: // Coprocessor & SWI | |
| 1002 | 531 if (((ins & 0x03000000) == 0x03000000) && ins_will_execute(ins)) { |
| 532 // SWI | |
| 533 return (CYGNUM_HAL_VECTOR_SOFTWARE_INTERRUPT * 4); | |
| 534 } else { | |
| 535 return (pc+1); | |
| 536 } | |
|
78
59d97b6ba612
Merge from eCos master repository on 2000-03-28-19:50:47-BST
jlarmour
parents:
76
diff
changeset
|
537 default: |
|
59d97b6ba612
Merge from eCos master repository on 2000-03-28-19:50:47-BST
jlarmour
parents:
76
diff
changeset
|
538 // Never reached - but fixes compiler warning. |
|
59d97b6ba612
Merge from eCos master repository on 2000-03-28-19:50:47-BST
jlarmour
parents:
76
diff
changeset
|
539 return 0; |
| 2 | 540 } |
| 541 } | |
| 542 | |
|
76
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
543 // FIXME: target_ins also needs to check for CPSR/THUMB being set and |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
544 // set the thumb bit accordingly. |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
545 |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
546 static unsigned long |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
547 target_thumb_ins(unsigned long pc, unsigned short ins) |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
548 { |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
549 unsigned long new_pc = MAKE_THUMB_ADDR(pc+2); // default is fall-through |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
550 // to next thumb instruction |
|
182
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
158
diff
changeset
|
551 unsigned long offset, arm_ins, sp; |
|
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
158
diff
changeset
|
552 int i; |
|
76
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
553 |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
554 switch ((ins & 0xf000) >> 12) { |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
555 case 0x4: |
|
158
f2545e5de153
Merge from eCos master repository on 2001-04-24-11:22:42-BST
jlarmour
parents:
151
diff
changeset
|
556 // Check for BX or BLX |
|
f2545e5de153
Merge from eCos master repository on 2001-04-24-11:22:42-BST
jlarmour
parents:
151
diff
changeset
|
557 if ((ins & 0xff07) == 0x4700) |
|
76
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
558 new_pc = (unsigned long)get_register((ins & 0x00078) >> 3); |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
559 break; |
|
182
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
158
diff
changeset
|
560 case 0xb: |
|
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
158
diff
changeset
|
561 // push/pop |
|
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
158
diff
changeset
|
562 // Look for "pop {...,pc}" |
|
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
158
diff
changeset
|
563 if ((ins & 0xf00) == 0xd00) { |
|
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
158
diff
changeset
|
564 // find PC |
|
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
158
diff
changeset
|
565 sp = (unsigned long)get_register(SP); |
|
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
158
diff
changeset
|
566 |
|
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
158
diff
changeset
|
567 for (offset = i = 0; i < 8; i++) |
|
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
158
diff
changeset
|
568 if (ins & (1 << i)) |
|
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
158
diff
changeset
|
569 offset += 4; |
|
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
158
diff
changeset
|
570 |
|
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
158
diff
changeset
|
571 new_pc = *(cyg_uint32 *)(sp + offset); |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
572 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
573 if (!v5T_semantics()) |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
574 new_pc = MAKE_THUMB_ADDR(new_pc); |
|
182
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
158
diff
changeset
|
575 } |
|
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
158
diff
changeset
|
576 break; |
|
76
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
577 case 0xd: |
| 1002 | 578 // Bcc | SWI |
|
76
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
579 // Use ARM function to check condition |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
580 arm_ins = ((unsigned long)(ins & 0x0f00)) << 20; |
| 1002 | 581 if ((arm_ins & 0xF0000000) == 0xF0000000) { |
| 582 // SWI | |
| 583 new_pc = CYGNUM_HAL_VECTOR_SOFTWARE_INTERRUPT * 4; | |
| 584 } else if (ins_will_execute(arm_ins)) { | |
|
76
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
585 offset = (ins & 0x00FF) << 1; |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
586 if (ins & 0x0080) offset |= 0xFFFFFE00; // sign extend |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
587 new_pc = MAKE_THUMB_ADDR((unsigned long)(pc+4) + offset); |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
588 } |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
589 break; |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
590 case 0xe: |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
591 // check for B |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
592 if ((ins & 0x0800) == 0) { |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
593 offset = (ins & 0x07FF) << 1; |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
594 if (ins & 0x0400) offset |= 0xFFFFF800; // sign extend |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
595 new_pc = MAKE_THUMB_ADDR((unsigned long)(pc+4) + offset); |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
596 } |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
597 break; |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
598 case 0xf: |
|
158
f2545e5de153
Merge from eCos master repository on 2001-04-24-11:22:42-BST
jlarmour
parents:
151
diff
changeset
|
599 // BL/BLX (4byte instruction!) |
|
76
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
600 // First instruction (bit 11 == 0) holds top-part of offset |
|
158
f2545e5de153
Merge from eCos master repository on 2001-04-24-11:22:42-BST
jlarmour
parents:
151
diff
changeset
|
601 if ((ins & 0x0800) == 0) { |
|
f2545e5de153
Merge from eCos master repository on 2001-04-24-11:22:42-BST
jlarmour
parents:
151
diff
changeset
|
602 offset = (ins & 0x07FF) << 12; |
|
f2545e5de153
Merge from eCos master repository on 2001-04-24-11:22:42-BST
jlarmour
parents:
151
diff
changeset
|
603 if (ins & 0x0400) offset |= 0xFF800000; // sign extend |
|
f2545e5de153
Merge from eCos master repository on 2001-04-24-11:22:42-BST
jlarmour
parents:
151
diff
changeset
|
604 // Get second instruction |
|
f2545e5de153
Merge from eCos master repository on 2001-04-24-11:22:42-BST
jlarmour
parents:
151
diff
changeset
|
605 // Second instruction (bit 11 == 1) holds bottom-part of offset |
|
f2545e5de153
Merge from eCos master repository on 2001-04-24-11:22:42-BST
jlarmour
parents:
151
diff
changeset
|
606 ins = *(unsigned short*)(pc+2); |
|
f2545e5de153
Merge from eCos master repository on 2001-04-24-11:22:42-BST
jlarmour
parents:
151
diff
changeset
|
607 // Check for BL/BLX |
|
f2545e5de153
Merge from eCos master repository on 2001-04-24-11:22:42-BST
jlarmour
parents:
151
diff
changeset
|
608 if ((ins & 0xE800) == 0xE800) { |
|
f2545e5de153
Merge from eCos master repository on 2001-04-24-11:22:42-BST
jlarmour
parents:
151
diff
changeset
|
609 offset |= (ins & 0x07ff) << 1; |
|
f2545e5de153
Merge from eCos master repository on 2001-04-24-11:22:42-BST
jlarmour
parents:
151
diff
changeset
|
610 new_pc = (unsigned long)(pc+4) + offset; |
|
f2545e5de153
Merge from eCos master repository on 2001-04-24-11:22:42-BST
jlarmour
parents:
151
diff
changeset
|
611 // If its BLX, force a full word alignment |
|
f2545e5de153
Merge from eCos master repository on 2001-04-24-11:22:42-BST
jlarmour
parents:
151
diff
changeset
|
612 // Otherwise, its a thumb address. |
|
f2545e5de153
Merge from eCos master repository on 2001-04-24-11:22:42-BST
jlarmour
parents:
151
diff
changeset
|
613 if (!(ins & 0x1000)) |
|
f2545e5de153
Merge from eCos master repository on 2001-04-24-11:22:42-BST
jlarmour
parents:
151
diff
changeset
|
614 new_pc &= ~3; |
|
f2545e5de153
Merge from eCos master repository on 2001-04-24-11:22:42-BST
jlarmour
parents:
151
diff
changeset
|
615 else |
|
f2545e5de153
Merge from eCos master repository on 2001-04-24-11:22:42-BST
jlarmour
parents:
151
diff
changeset
|
616 new_pc = MAKE_THUMB_ADDR(new_pc); |
|
f2545e5de153
Merge from eCos master repository on 2001-04-24-11:22:42-BST
jlarmour
parents:
151
diff
changeset
|
617 } |
|
f2545e5de153
Merge from eCos master repository on 2001-04-24-11:22:42-BST
jlarmour
parents:
151
diff
changeset
|
618 } |
|
76
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
619 break; |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
620 } |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
621 |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
622 return new_pc; |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
623 } |
|
54
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
624 |
| 2 | 625 void __single_step (void) |
| 626 { | |
|
54
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
627 unsigned long pc = get_register(PC); |
|
76
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
628 unsigned long cpsr = get_register(PS); |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
629 |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
630 // Calculate address of next instruction to be executed |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
631 if (cpsr & CPSR_THUMB_ENABLE) { |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
632 // thumb |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
633 ss_saved_pc = target_thumb_ins(pc, *(unsigned short*)pc); |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
634 } else { |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
635 // ARM |
|
54
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
636 unsigned long curins = *(unsigned long*)pc; |
|
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
637 if (ins_will_execute(curins)) { |
|
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
638 // Decode instruction to decide what the next PC will be |
|
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
639 ss_saved_pc = (unsigned long) target_ins((unsigned long*)pc, |
|
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
640 curins); |
|
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
641 } else { |
|
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
642 // The current instruction will not execute (the conditions |
|
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
643 // don't hold) |
|
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
644 ss_saved_pc = pc+4; |
|
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
645 } |
|
76
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
646 } |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
647 |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
648 // Set breakpoint according to type |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
649 if (IS_THUMB_ADDR(ss_saved_pc)) { |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
650 // Thumb instruction |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
651 unsigned long t_pc = UNMAKE_THUMB_ADDR(ss_saved_pc); |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
652 ss_saved_thumb_instr = *(unsigned short*)t_pc; |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
653 *(unsigned short*)t_pc = HAL_BREAKINST_THUMB; |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
654 } else { |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
655 // ARM instruction |
|
54
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
656 ss_saved_instr = *(unsigned long*)ss_saved_pc; |
|
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
657 *(unsigned long*)ss_saved_pc = HAL_BREAKINST_ARM; |
|
76
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
658 } |
| 2 | 659 } |
| 660 | |
| 661 /* Clear the single-step state. */ | |
| 662 | |
| 663 void __clear_single_step (void) | |
| 664 { | |
|
54
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
665 if (ss_saved_pc != 0) { |
|
76
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
666 // Restore instruction according to type |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
667 if (IS_THUMB_ADDR(ss_saved_pc)) { |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
668 // Thumb instruction |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
669 unsigned long t_pc = UNMAKE_THUMB_ADDR(ss_saved_pc); |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
670 *(unsigned short*)t_pc = ss_saved_thumb_instr; |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
671 } else { |
|
54
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
672 // ARM instruction |
|
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
673 *(unsigned long*)ss_saved_pc = ss_saved_instr; |
|
76
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
674 } |
|
54
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
675 ss_saved_pc = 0; |
| 2 | 676 } |
| 677 } | |
| 678 | |
| 679 void __install_breakpoints (void) | |
| 680 { | |
|
132
0ae0bc38e387
Merge from eCos master repository on 2000-10-31-00:30:36-GMT
jlarmour
parents:
115
diff
changeset
|
681 #if defined(CYGNUM_HAL_BREAKPOINT_LIST_SIZE) && (CYGNUM_HAL_BREAKPOINT_LIST_SIZE > 0) |
|
0ae0bc38e387
Merge from eCos master repository on 2000-10-31-00:30:36-GMT
jlarmour
parents:
115
diff
changeset
|
682 /* Install the breakpoints in the breakpoint list */ |
|
0ae0bc38e387
Merge from eCos master repository on 2000-10-31-00:30:36-GMT
jlarmour
parents:
115
diff
changeset
|
683 __install_breakpoint_list(); |
|
0ae0bc38e387
Merge from eCos master repository on 2000-10-31-00:30:36-GMT
jlarmour
parents:
115
diff
changeset
|
684 #endif |
| 2 | 685 } |
| 686 | |
| 687 void __clear_breakpoints (void) | |
| 688 { | |
|
132
0ae0bc38e387
Merge from eCos master repository on 2000-10-31-00:30:36-GMT
jlarmour
parents:
115
diff
changeset
|
689 #if defined(CYGNUM_HAL_BREAKPOINT_LIST_SIZE) && (CYGNUM_HAL_BREAKPOINT_LIST_SIZE > 0) |
|
0ae0bc38e387
Merge from eCos master repository on 2000-10-31-00:30:36-GMT
jlarmour
parents:
115
diff
changeset
|
690 __clear_breakpoint_list(); |
|
0ae0bc38e387
Merge from eCos master repository on 2000-10-31-00:30:36-GMT
jlarmour
parents:
115
diff
changeset
|
691 #endif |
| 2 | 692 } |
| 693 | |
| 694 /* If the breakpoint we hit is in the breakpoint() instruction, return a | |
| 695 non-zero value. */ | |
| 696 | |
| 697 int | |
| 698 __is_breakpoint_function () | |
| 699 { | |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
110
diff
changeset
|
700 return get_register (PC) == (target_register_t)&_breakinst; |
| 2 | 701 } |
| 702 | |
| 703 | |
| 704 /* Skip the current instruction. Since this is only called by the | |
| 705 stub when the PC points to a breakpoint or trap instruction, | |
| 706 we can safely just skip 4. */ | |
| 707 | |
| 708 void __skipinst (void) | |
| 709 { | |
|
54
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
710 unsigned long pc = get_register(PC); |
|
76
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
711 unsigned long cpsr = get_register(PS); |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
712 |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
713 if (cpsr & CPSR_THUMB_ENABLE) |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
714 pc += 2; |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
715 else |
|
54
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
716 pc += 4; |
|
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
717 |
|
f10165814f1e
Merge from eCos master repository on 1999-11-19-22:24:39-GMT
jlarmour
parents:
50
diff
changeset
|
718 put_register(PC, pc); |
| 2 | 719 } |
| 720 | |
|
76
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
721 //----------------------------------------------------------------------- |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
722 // Thumb-aware GDB interrupt handler. |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
723 // This is a brute-force replacement of the ones in hal_stub.c. Need to |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
724 // find a better way of handling it... Maybe... Probably only ARM/thumb |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
725 // that is this weird. |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
726 |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
727 typedef struct |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
728 { |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
729 cyg_uint32 targetAddr; |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
730 union { |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
731 cyg_uint32 arm_instr; |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
732 cyg_uint16 thumb_instr; |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
733 } savedInstr; |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
734 } instrBuffer; |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
735 |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
736 static instrBuffer break_buffer; |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
737 |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
738 volatile int cyg_hal_gdb_running_step = 0; |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
739 |
|
78
59d97b6ba612
Merge from eCos master repository on 2000-03-28-19:50:47-BST
jlarmour
parents:
76
diff
changeset
|
740 // This function is passed thumb/arm information about the PC address |
|
59d97b6ba612
Merge from eCos master repository on 2000-03-28-19:50:47-BST
jlarmour
parents:
76
diff
changeset
|
741 // in bit 0. This information is passed on to the break_buffer. |
|
76
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
742 void |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
743 cyg_hal_gdb_place_break (target_register_t pc) |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
744 { |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
745 // Clear flag that we Continued instead of Stepping |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
746 cyg_hal_gdb_running_step = 0; |
|
78
59d97b6ba612
Merge from eCos master repository on 2000-03-28-19:50:47-BST
jlarmour
parents:
76
diff
changeset
|
747 |
|
76
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
748 if (0 == break_buffer.targetAddr) { |
|
78
59d97b6ba612
Merge from eCos master repository on 2000-03-28-19:50:47-BST
jlarmour
parents:
76
diff
changeset
|
749 // Setting a breakpoint in Thumb or ARM code? |
|
59d97b6ba612
Merge from eCos master repository on 2000-03-28-19:50:47-BST
jlarmour
parents:
76
diff
changeset
|
750 if (IS_THUMB_ADDR(pc)) { |
|
59d97b6ba612
Merge from eCos master repository on 2000-03-28-19:50:47-BST
jlarmour
parents:
76
diff
changeset
|
751 break_buffer.targetAddr = (cyg_uint32)pc; |
|
59d97b6ba612
Merge from eCos master repository on 2000-03-28-19:50:47-BST
jlarmour
parents:
76
diff
changeset
|
752 pc = UNMAKE_THUMB_ADDR(pc); |
|
59d97b6ba612
Merge from eCos master repository on 2000-03-28-19:50:47-BST
jlarmour
parents:
76
diff
changeset
|
753 break_buffer.savedInstr.thumb_instr = *(cyg_uint16*)pc; |
|
59d97b6ba612
Merge from eCos master repository on 2000-03-28-19:50:47-BST
jlarmour
parents:
76
diff
changeset
|
754 *(cyg_uint16*)pc = HAL_BREAKINST_THUMB; |
|
59d97b6ba612
Merge from eCos master repository on 2000-03-28-19:50:47-BST
jlarmour
parents:
76
diff
changeset
|
755 } else { |
|
59d97b6ba612
Merge from eCos master repository on 2000-03-28-19:50:47-BST
jlarmour
parents:
76
diff
changeset
|
756 break_buffer.targetAddr = (cyg_uint32)pc; |
|
59d97b6ba612
Merge from eCos master repository on 2000-03-28-19:50:47-BST
jlarmour
parents:
76
diff
changeset
|
757 break_buffer.savedInstr.arm_instr = *(cyg_uint32*)pc; |
|
59d97b6ba612
Merge from eCos master repository on 2000-03-28-19:50:47-BST
jlarmour
parents:
76
diff
changeset
|
758 *(cyg_uint32*)pc = HAL_BREAKINST_ARM; |
|
59d97b6ba612
Merge from eCos master repository on 2000-03-28-19:50:47-BST
jlarmour
parents:
76
diff
changeset
|
759 } |
|
76
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
760 |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
761 __data_cache(CACHE_FLUSH); |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
762 __instruction_cache(CACHE_FLUSH); |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
763 } |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
764 } |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
765 |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
766 int |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
767 cyg_hal_gdb_remove_break (target_register_t pc) |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
768 { |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
769 if ( cyg_hal_gdb_running_step ) |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
770 return 0; // Do not remove the break: we must hit it! |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
771 |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
772 if (pc == UNMAKE_THUMB_ADDR(break_buffer.targetAddr)) { |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
773 if (IS_THUMB_ADDR(break_buffer.targetAddr)) { |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
774 *(cyg_uint16*)pc = break_buffer.savedInstr.thumb_instr; |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
775 } else { |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
776 *(cyg_uint32*)pc = break_buffer.savedInstr.arm_instr; |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
777 } |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
778 break_buffer.targetAddr = 0; |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
779 |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
780 __data_cache(CACHE_FLUSH); |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
781 __instruction_cache(CACHE_FLUSH); |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
782 return 1; |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
783 } |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
784 return 0; |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
785 } |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
786 |
|
105
5a0cc6c243a9
Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents:
80
diff
changeset
|
787 void |
|
5a0cc6c243a9
Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents:
80
diff
changeset
|
788 cyg_hal_gdb_interrupt (target_register_t pc) |
|
5a0cc6c243a9
Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents:
80
diff
changeset
|
789 { |
|
5a0cc6c243a9
Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents:
80
diff
changeset
|
790 // Clear flag that we Continued instead of Stepping |
|
5a0cc6c243a9
Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents:
80
diff
changeset
|
791 cyg_hal_gdb_running_step = 0; |
|
5a0cc6c243a9
Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents:
80
diff
changeset
|
792 // and override existing break? So that a ^C takes effect... |
|
5a0cc6c243a9
Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents:
80
diff
changeset
|
793 if (0 != break_buffer.targetAddr) |
|
5a0cc6c243a9
Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents:
80
diff
changeset
|
794 cyg_hal_gdb_remove_break( break_buffer.targetAddr ); |
|
5a0cc6c243a9
Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents:
80
diff
changeset
|
795 |
|
5a0cc6c243a9
Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents:
80
diff
changeset
|
796 if (0 == break_buffer.targetAddr) { |
|
5a0cc6c243a9
Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents:
80
diff
changeset
|
797 cyg_uint32 cpsr = get_register(PS); |
|
5a0cc6c243a9
Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents:
80
diff
changeset
|
798 |
|
5a0cc6c243a9
Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents:
80
diff
changeset
|
799 if (cpsr & CPSR_THUMB_ENABLE) { |
|
5a0cc6c243a9
Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents:
80
diff
changeset
|
800 break_buffer.targetAddr = MAKE_THUMB_ADDR((cyg_uint32)pc); |
|
5a0cc6c243a9
Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents:
80
diff
changeset
|
801 break_buffer.savedInstr.thumb_instr = *(cyg_uint16*)pc; |
|
5a0cc6c243a9
Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents:
80
diff
changeset
|
802 *(cyg_uint16*)pc = HAL_BREAKINST_THUMB; |
|
5a0cc6c243a9
Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents:
80
diff
changeset
|
803 } else { |
|
5a0cc6c243a9
Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents:
80
diff
changeset
|
804 break_buffer.targetAddr = (cyg_uint32)pc; |
|
5a0cc6c243a9
Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents:
80
diff
changeset
|
805 break_buffer.savedInstr.arm_instr = *(cyg_uint32*)pc; |
|
5a0cc6c243a9
Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents:
80
diff
changeset
|
806 *(cyg_uint32*)pc = HAL_BREAKINST_ARM; |
|
5a0cc6c243a9
Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents:
80
diff
changeset
|
807 } |
|
5a0cc6c243a9
Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents:
80
diff
changeset
|
808 |
|
5a0cc6c243a9
Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents:
80
diff
changeset
|
809 __data_cache(CACHE_FLUSH); |
|
5a0cc6c243a9
Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents:
80
diff
changeset
|
810 __instruction_cache(CACHE_FLUSH); |
|
5a0cc6c243a9
Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents:
80
diff
changeset
|
811 } |
|
5a0cc6c243a9
Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents:
80
diff
changeset
|
812 } |
|
5a0cc6c243a9
Merge from eCos master repository on 2000-06-30-08:18:49-BST
jlarmour
parents:
80
diff
changeset
|
813 |
|
76
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
814 int |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
815 cyg_hal_gdb_break_is_set (void) |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
816 { |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
817 if (0 != break_buffer.targetAddr) { |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
818 return 1; |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
819 } |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
820 return 0; |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
821 } |
|
435cced73e2f
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
jlarmour
parents:
72
diff
changeset
|
822 |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
823 #ifdef CYGHWR_HAL_ARM_ICE_THREAD_SUPPORT |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
824 #define ICE_THREAD_KEY0 0xDEAD0001 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
825 #define ICE_THREAD_KEY1 0xDEAD0002 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
826 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
827 #define ICE_THREAD_INBUFSIZ 2048 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
828 #define ICE_THREAD_OUTBUFSIZ 2048 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
829 #define ICE_THREAD_STACKSIZE 4096 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
830 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
831 static cyg_uint8 ice_thread_inbuf[ICE_THREAD_INBUFSIZ]; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
832 static cyg_uint8 ice_thread_outbuf[ICE_THREAD_OUTBUFSIZ]; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
833 static cyg_uint8 ice_thread_stack[ICE_THREAD_STACKSIZE]; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
834 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
835 static void ice_thread_proc(void); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
836 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
837 struct { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
838 cyg_uint32 _key0; // Must be ICE_KEY0 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
839 cyg_uint8 *in_buffer; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
840 cyg_int32 in_buffer_size; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
841 cyg_uint8 *out_buffer; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
842 cyg_int32 out_buffer_size; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
843 cyg_uint8 *stack; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
844 cyg_int32 stack_size; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
845 void (*fun)(void); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
846 cyg_uint32 _key1; // Must be ICE_KEY1 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
847 } hal_arm_ice_thread_handler = { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
848 ICE_THREAD_KEY0, |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
849 ice_thread_inbuf, |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
850 ICE_THREAD_INBUFSIZ, |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
851 ice_thread_outbuf, |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
852 ICE_THREAD_OUTBUFSIZ, |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
853 ice_thread_stack, |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
854 ICE_THREAD_STACKSIZE, |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
855 ice_thread_proc, |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
856 ICE_THREAD_KEY1, |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
857 }; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
858 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
859 static int |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
860 ice_thread_query(void) |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
861 { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
862 switch (ice_thread_inbuf[1]) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
863 case 'L': // get thread list |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
864 stub_pkt_getthreadlist(&ice_thread_inbuf[2], ice_thread_outbuf, sizeof(ice_thread_outbuf)); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
865 break; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
866 case 'P': // thread or process information |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
867 stub_pkt_getthreadinfo(&ice_thread_inbuf[2], ice_thread_outbuf, sizeof(ice_thread_outbuf)); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
868 break; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
869 case 'C': // current thread |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
870 stub_pkt_currthread(&ice_thread_inbuf[2], ice_thread_outbuf, sizeof(ice_thread_outbuf)); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
871 break; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
872 default: |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
873 return 0; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
874 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
875 return 1; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
876 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
877 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
878 static int |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
879 ice_thread_set(void) |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
880 { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
881 return 0; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
882 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
883 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
884 static void |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
885 ice_thread_proc(void) |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
886 { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
887 switch (ice_thread_inbuf[0]) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
888 case 'g': // Fetch thread registers |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
889 stub_format_registers(ice_thread_outbuf); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
890 return; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
891 case 'P': // Update a single register |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
892 case 'G': // Update all registers |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
893 stub_update_registers(ice_thread_inbuf, ice_thread_outbuf); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
894 return; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
895 case 'H': // Thread set/query |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
896 stub_pkt_changethread(&ice_thread_inbuf[1], ice_thread_outbuf, sizeof(ice_thread_outbuf)); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
897 return; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
898 case 'q': // Thread queries |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
899 if (ice_thread_query()) return; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
900 break; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
901 case 'Q': // Thread set operations |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
902 if (ice_thread_set()) return; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
903 break; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
904 case 'T': // Thread alive? |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
905 stub_pkt_thread_alive(&ice_thread_inbuf[1], ice_thread_outbuf, sizeof(ice_thread_outbuf)); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
906 return; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
907 default: |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
908 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
909 strcpy(ice_thread_outbuf, "ENN"); // Dunno |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
910 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
911 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
912 #endif // CYGHWR_HAL_ARM_ICE_THREAD_SUPPORT |
|
36
e97d78785e2d
Merge from eCos master repository on 1999-09-12-15:40:34-BST
jlarmour
parents:
34
diff
changeset
|
913 |
| 2 | 914 #endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS |
