OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [hal/] [openrisc/] [arch/] [current/] [src/] [openrisc_stub.c] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//========================================================================
2
//
3
//      openrisc_stub.c
4
//
5
//      OpenRISC-specific code for remote debugging via gdb
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 Free Software Foundation, 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      
16
// version.                                                                 
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT      
19
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
20
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
21
// for more details.                                                        
22
//
23
// You should have received a copy of the GNU General Public License        
24
// along with eCos; if not, write to the Free Software Foundation, Inc.,    
25
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
26
//
27
// As a special exception, if other files instantiate templates or use      
28
// macros or inline functions from this file, or you compile this file      
29
// and link it with other works to produce a work based on this file,       
30
// this file does not by itself cause the resulting work to be covered by   
31
// the GNU General Public License. However the source code for this file    
32
// must still be made available in accordance with section (3) of the GNU   
33
// General Public License v2.                                               
34
//
35
// This exception does not invalidate any other reasons why a work based    
36
// on this file might be covered by the GNU General Public License.         
37
// -------------------------------------------                              
38
// ####ECOSGPLCOPYRIGHTEND####                                              
39
//========================================================================
40
//#####DESCRIPTIONBEGIN####
41
//
42
// Author(s):     sfurman
43
// Contributors:  Red Hat, jskov, gthomas
44
// Date:          2003-02-07
45
// Purpose:       
46
// Description:   Helper functions for gdb stub for OpenRISC processors
47
// Usage:         
48
//
49
//####DESCRIPTIONEND####
50
//
51
//========================================================================
52
 
53
#include <stddef.h>
54
 
55
#include <pkgconf/hal.h>
56
 
57
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
58
 
59
#define CYGARC_HAL_COMMON_EXPORT_CPU_MACROS
60
 
61
#include <cyg/hal/hal_stub.h>
62
#include <cyg/hal/hal_arch.h>
63
#include <cyg/hal/hal_intr.h>
64
#include <cyg/hal/openrisc_opcode.h>
65
#include <cyg/infra/cyg_ass.h>          // assertion macros
66
 
67
#ifdef CYGNUM_HAL_NO_VECTOR_TRACE
68
#define USE_BREAKPOINTS_FOR_SINGLE_STEP
69
#endif
70
 
71
#ifdef CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT
72
#include <cyg/hal/dbg-threads-api.h>    // dbg_currthread_id
73
#endif
74
 
75
/* Given a trap value TRAP, return the corresponding signal. */
76
 
77
int __computeSignal (unsigned int trap_number)
78
{
79
    switch (trap_number)
80
    {
81
        // Either no matching page-table entry or protection fault
82
        // while executing load/store operation
83
    case CYGNUM_HAL_VECTOR_DATA_PAGE_FAULT:
84
        // Either no matching page-table entry or protection fault
85
        // while executing load/store operation
86
    case CYGNUM_HAL_VECTOR_INSTR_PAGE_FAULT:
87
        return SIGSEGV;
88
 
89
        // No matching entry in D-TLB
90
    case CYGNUM_HAL_VECTOR_DTLB_MISS:
91
        // No matching entry in I-TLB
92
    case CYGNUM_HAL_VECTOR_ITLB_MISS:
93
        // Unaligned load/store memory access
94
    case CYGNUM_HAL_VECTOR_UNALIGNED_ACCESS:
95
        // Access to non-existent physical memory/device
96
    case CYGNUM_HAL_VECTOR_BUS_ERROR:
97
        return SIGBUS;
98
 
99
        // TRAP instruction executed
100
    case CYGNUM_HAL_VECTOR_TRAP:
101
        return SIGTRAP;
102
 
103
        /* System call instruction executed */
104
    case CYGNUM_HAL_VECTOR_SYSTEM_CALL:
105
        return SIGSYS;
106
 
107
        /* Tick timer interrupt fired */
108
    case CYGNUM_HAL_VECTOR_TICK_TIMER:
109
        return SIGALRM;
110
 
111
        /* External interrupt */
112
    case CYGNUM_HAL_VECTOR_INTERRUPT:
113
      return SIGINT;
114
 
115
      // Illegal or reserved instruction
116
    case CYGNUM_HAL_VECTOR_RESERVED_INSTRUCTION:
117
        return SIGILL;
118
 
119
        // Numeric overflow, etc.
120
    case CYGNUM_HAL_VECTOR_RANGE:
121
        return SIGFPE;
122
 
123
    default:
124
        return SIGTERM;
125
    }
126
}
127
 
128
 
129
/* Return the trap number corresponding to the last-taken trap. */
130
 
131
int __get_trap_number (void)
132
{
133
    // The vector is not not part of the GDB register set so get it
134
    // directly from the save context.
135
    return _hal_registers->vector;
136
}
137
 
138
/* Set the currently-saved pc register value to PC. This also updates NPC
139
   as needed. */
140
 
141
void set_pc (target_register_t pc)
142
{
143
    put_register (PC, pc);
144
}
145
 
146
 
147
 
148
/*----------------------------------------------------------------------
149
 * Single-step support
150
 */
151
 
152
// Type of a single OpenRISC instruction
153
typedef cyg_uint32 t_inst;
154
 
155
/* Saved instruction data for single step support.  */
156
static struct
157
{
158
  t_inst *targetAddr;
159
  t_inst savedInstr;
160
} instrBuffer;
161
 
162
 
163
/* Set things up so that the next user resume will execute one instruction.
164
   This may be done by setting breakpoints or setting a single step flag
165
   in the saved user registers, for example. */
166
 
167
void __single_step (void)
168
{
169
  t_inst *pc = (t_inst *) get_register (PC);
170
  t_inst *targetAddr;
171
  InstFmt insn;
172
  int flag;
173
 
174
  targetAddr = pc + 1;              /* set default */
175
 
176
  insn.word = *pc;
177
  switch (insn.JType.op) {
178
  case OP_J:
179
  case OP_JAL:
180
    targetAddr = pc + insn.JType.target;
181
    break;
182
 
183
  case OP_BNF:
184
    flag = get_register(SR) & SPR_SR_F;
185
    if (!flag)
186
      targetAddr = pc + insn.JType.target;
187
    break;
188
 
189
  case OP_BF:
190
    flag = get_register(SR) & SPR_SR_F;
191
    if (flag)
192
      targetAddr = pc + insn.JType.target;
193
    break;
194
 
195
  case OP_JR:
196
  case OP_JALR:
197
    targetAddr = (t_inst*)get_register(insn.JRType.rB);
198
    break;
199
 
200
    /* We don't step into interrupts, syscalls or traps */
201
  default:
202
    break;
203
  }
204
 
205
  instrBuffer.targetAddr = targetAddr;
206
  instrBuffer.savedInstr = *targetAddr;
207
  *targetAddr = __break_opcode ();
208
 
209
  // No need to flush caches; Generic stub code will handle this.
210
}
211
 
212
/* Clear the single-step state. */
213
void __clear_single_step (void)
214
{
215
  if (instrBuffer.targetAddr != NULL)
216
    {
217
      *instrBuffer.targetAddr = instrBuffer.savedInstr;
218
      instrBuffer.targetAddr = NULL;
219
      instrBuffer.savedInstr = 0;
220
    }
221
}
222
 
223
 
224
void __install_breakpoints ()
225
{
226
  /*  if (instrBuffer.targetAddr != NULL)
227
    {
228
      instrBuffer.savedInstr = *instrBuffer.targetAddr;
229
      *instrBuffer.targetAddr = __break_opcode ();
230
      } */
231
 
232
  /* Install the breakpoints in the breakpoint list */
233
  __install_breakpoint_list();
234
 
235
  // No need to flush caches here; Generic stub code will handle this.
236
}
237
 
238
void __clear_breakpoints (void)
239
{
240
  __clear_breakpoint_list();
241
}
242
 
243
/* If the breakpoint we hit is in the breakpoint() instruction, return a
244
   non-zero value. */
245
 
246
int
247
__is_breakpoint_function ()
248
{
249
    return get_register (PC) == (target_register_t)&_breakinst;
250
}
251
 
252
 
253
/* Skip the current instruction.  Since this is only called by the
254
   stub when the PC points to a breakpoint or trap instruction,
255
   we can safely just skip 4. */
256
 
257
void __skipinst (void)
258
{
259
    put_register (PC, get_register (PC) + 4);
260
}
261
 
262
target_register_t
263
get_register (regnames_t reg)
264
{
265
    GDB_Registers* gdb_regs;
266
 
267
    gdb_regs = (GDB_Registers*)_registers;
268
 
269
    if (reg >= R0 && reg <= R31)
270
        return gdb_regs->r[reg];
271
    if (reg == PC)
272
        return gdb_regs->pc;
273
    if (reg == SR)
274
        return gdb_regs->sr;
275
    return 0xdeadbeef;
276
}
277
 
278
void
279
put_register (regnames_t reg, target_register_t value)
280
{
281
    GDB_Registers* gdb_regs;
282
 
283
    gdb_regs = (GDB_Registers*)_registers;
284
 
285
    if (reg >= R0 && reg <= R31) {
286
        gdb_regs->r[reg] = value;
287
    } else if (reg == PC) {
288
        gdb_regs->pc = value;
289
    } else if (reg == SR) {
290
        gdb_regs->sr = value;
291
    } else {
292
        CYG_FAIL("Attempt to write to non-existent register ");
293
    }
294
}
295
 
296
#endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
297
 
298
// EOF openrisc_stub.c

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.