]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/cygmon/v2_0/misc/bsp/arm/gdb-cpu.c
Initial revision
[karo-tx-redboot.git] / packages / cygmon / v2_0 / misc / bsp / arm / gdb-cpu.c
1 //==========================================================================
2 //
3 //      gdb-cpu.c
4 //
5 //      CPU specific support for GDB stub.
6 //
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12 //
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
16 //
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20 // for more details.
21 //
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 //
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
32 //
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
35 //
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //==========================================================================
41 //#####DESCRIPTIONBEGIN####
42 //
43 // Author(s):    
44 // Contributors: gthomas
45 // Date:         1999-10-20
46 // Purpose:      CPU specific support for GDB stub.
47 // Description:  ARM is a Registered Trademark of Advanced RISC Machines
48 //               Limited.
49 //               Other Brands and Trademarks are the property of their
50 //               respective owners.
51 //
52 //####DESCRIPTIONEND####
53 //
54 //=========================================================================
55
56 #include <bsp/cpu.h>
57 #include <bsp/bsp.h>
58 #include "insn.h"
59 #include "gdb.h"
60
61 /*
62  * Return byte offset within the saved register area of the
63  * given register.
64  */
65 int
66 bsp_regbyte(int regno)
67 {
68     switch(regno)
69     {
70     case REG_R0:   return (int)&(((ex_regs_t*)0)->_r0);   break;
71     case REG_R1:   return (int)&(((ex_regs_t*)0)->_r1);   break;
72     case REG_R2:   return (int)&(((ex_regs_t*)0)->_r2);   break;
73     case REG_R3:   return (int)&(((ex_regs_t*)0)->_r3);   break;
74     case REG_R4:   return (int)&(((ex_regs_t*)0)->_r4);   break;
75     case REG_R5:   return (int)&(((ex_regs_t*)0)->_r5);   break;
76     case REG_R6:   return (int)&(((ex_regs_t*)0)->_r6);   break;
77     case REG_R7:   return (int)&(((ex_regs_t*)0)->_r7);   break;
78     case REG_R8:   return (int)&(((ex_regs_t*)0)->_r8);   break;
79     case REG_R9:   return (int)&(((ex_regs_t*)0)->_r9);   break;
80     case REG_R10:  return (int)&(((ex_regs_t*)0)->_r10);  break;
81     case REG_R11:  return (int)&(((ex_regs_t*)0)->_r11);  break;
82     case REG_R12:  return (int)&(((ex_regs_t*)0)->_r12);  break;
83     case REG_SP:   return (int)&(((ex_regs_t*)0)->_sp);   break;
84     case REG_LR:   return (int)&(((ex_regs_t*)0)->_lr);   break;
85     case REG_PC:   return (int)&(((ex_regs_t*)0)->_pc);   break;
86
87 #ifndef __ECOS__
88     case REG_F0:   return (int)&(((ex_regs_t*)0)->_f0);   break;
89     case REG_F1:   return (int)&(((ex_regs_t*)0)->_f1);   break;
90     case REG_F2:   return (int)&(((ex_regs_t*)0)->_f2);   break;
91     case REG_F3:   return (int)&(((ex_regs_t*)0)->_f3);   break;
92     case REG_F4:   return (int)&(((ex_regs_t*)0)->_f4);   break;
93     case REG_F5:   return (int)&(((ex_regs_t*)0)->_f5);   break;
94     case REG_F6:   return (int)&(((ex_regs_t*)0)->_f6);   break;
95     case REG_F7:   return (int)&(((ex_regs_t*)0)->_f7);   break;
96     case REG_FPS:  return (int)&(((ex_regs_t*)0)->_fps);  break;
97 #endif
98
99     case REG_CPSR: return (int)&(((ex_regs_t*)0)->_cpsr);  break;
100     case REG_SPSVC: return (int)&(((ex_regs_t*)0)->_spsvc);  break;
101     }
102
103     return 0;
104 }
105
106
107 /*
108  * Return size in bytes of given register.
109  */
110 int
111 bsp_regsize(int regno)
112 {
113     switch(regno)
114     {
115     case REG_R0:   return (sizeof (((ex_regs_t*)0)->_r0));   break;
116     case REG_R1:   return (sizeof (((ex_regs_t*)0)->_r1));   break;
117     case REG_R2:   return (sizeof (((ex_regs_t*)0)->_r2));   break;
118     case REG_R3:   return (sizeof (((ex_regs_t*)0)->_r3));   break;
119     case REG_R4:   return (sizeof (((ex_regs_t*)0)->_r4));   break;
120     case REG_R5:   return (sizeof (((ex_regs_t*)0)->_r5));   break;
121     case REG_R6:   return (sizeof (((ex_regs_t*)0)->_r6));   break;
122     case REG_R7:   return (sizeof (((ex_regs_t*)0)->_r7));   break;
123     case REG_R8:   return (sizeof (((ex_regs_t*)0)->_r8));   break;
124     case REG_R9:   return (sizeof (((ex_regs_t*)0)->_r9));   break;
125     case REG_R10:  return (sizeof (((ex_regs_t*)0)->_r10));  break;
126     case REG_R11:  return (sizeof (((ex_regs_t*)0)->_r11));  break;
127     case REG_R12:  return (sizeof (((ex_regs_t*)0)->_r12));  break;
128     case REG_SP:   return (sizeof (((ex_regs_t*)0)->_sp));   break;
129     case REG_LR:   return (sizeof (((ex_regs_t*)0)->_lr));   break;
130     case REG_PC:   return (sizeof (((ex_regs_t*)0)->_pc));   break;
131
132 #ifndef __ECOS__
133     case REG_F0:   return (sizeof (((ex_regs_t*)0)->_f0));   break;
134     case REG_F1:   return (sizeof (((ex_regs_t*)0)->_f1));   break;
135     case REG_F2:   return (sizeof (((ex_regs_t*)0)->_f2));   break;
136     case REG_F3:   return (sizeof (((ex_regs_t*)0)->_f3));   break;
137     case REG_F4:   return (sizeof (((ex_regs_t*)0)->_f4));   break;
138     case REG_F5:   return (sizeof (((ex_regs_t*)0)->_f5));   break;
139     case REG_F6:   return (sizeof (((ex_regs_t*)0)->_f6));   break;
140     case REG_F7:   return (sizeof (((ex_regs_t*)0)->_f7));   break;
141     case REG_FPS:  return (sizeof (((ex_regs_t*)0)->_fps));  break;
142 #endif
143                                                          
144     case REG_CPSR: return (sizeof (((ex_regs_t*)0)->_cpsr)); break;
145     case REG_SPSVC: return (sizeof (((ex_regs_t*)0)->_spsvc)); break;
146     }
147
148     return 0;
149 }
150
151
152 /*
153  *  Given an exception number and a pointer to saved registers,
154  *  return a GDB signal value.
155  */
156 int
157 bsp_get_signal(int exc_nr, void *saved_regs)
158 {
159   int sig = TARGET_SIGNAL_TRAP;
160   ex_regs_t *regs = (ex_regs_t *)saved_regs;
161
162   switch (exc_nr) {
163   case BSP_CORE_EXC_UNDEFINED_INSTRUCTION:
164   {
165       union arm_insn inst;
166       if (bsp_memory_read((void *)regs->_pc, 0, ARM_INST_SIZE * 8, 1, &(inst.word)) != 0)
167       {
168           /*
169            * We were able to read this address. It must be a valid address.
170            */
171           if (inst.word == BREAKPOINT_INSN)
172               sig = TARGET_SIGNAL_TRAP;
173       }
174       else
175           sig = TARGET_SIGNAL_ILL;
176   }
177   break;
178   case BSP_CORE_EXC_SOFTWARE_INTERRUPT:        sig = TARGET_SIGNAL_TRAP;    break;
179   case BSP_CORE_EXC_PREFETCH_ABORT:            sig = TARGET_SIGNAL_BUS;     break;
180   case BSP_CORE_EXC_DATA_ABORT:                sig = TARGET_SIGNAL_BUS;     break;
181   case BSP_CORE_EXC_ADDRESS_ERROR_26_BIT:      sig = TARGET_SIGNAL_BUS;     break;
182   case BSP_CORE_EXC_IRQ:                       sig = TARGET_SIGNAL_INT;     break;
183   case BSP_CORE_EXC_FIQ:                       sig = TARGET_SIGNAL_INT;     break;
184   default:                                     sig = TARGET_SIGNAL_TRAP;    break;
185   }
186
187   return sig;
188 }
189
190
191 /*
192  * Set the PC value in the saved registers.
193  */
194 void
195 bsp_set_pc(unsigned long pc, void *saved_regs)
196 {
197   ((ex_regs_t *)saved_regs)->_pc = pc;
198 }
199
200
201 /*
202  * Get the PC value from the saved registers.
203  */
204 unsigned long
205 bsp_get_pc(void *saved_regs)
206 {
207   return ((ex_regs_t *)saved_regs)->_pc;
208 }