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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [hal/] [v85x/] [v850/] [v2_0/] [src/] [v850_stub.c] - Blame information for rev 475

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
//========================================================================
2
//
3
//      v850_stub.c
4
//
5
//      Helper functions for stub, generic to all NEC processors
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):     Red Hat, gthomas, jlarmour
44
// Contributors:  Red Hat, gthomas, jskov
45
// Date:          1998-11-26
46
// Purpose:       
47
// Description:   Helper functions for stub, generic to all NEC processors
48
// Usage:         
49
//
50
//####DESCRIPTIONEND####
51
//
52
//========================================================================
53
 
54
#include <stddef.h>
55
 
56
#include <pkgconf/hal.h>
57
#ifdef CYGPKG_CYGMON
58
#include <pkgconf/cygmon.h>
59
#endif
60
 
61
#ifdef CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT
62
#include <cyg/hal/dbg-threads-api.h>
63
#endif
64
 
65
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
66
 
67
#include <cyg/hal/hal_stub.h>
68
#include <cyg/hal/hal_arch.h>
69
#include <cyg/hal/hal_intr.h>
70
 
71
#ifndef FALSE
72
#define FALSE 0
73
#define TRUE  1
74
#endif
75
 
76
/* Given a trap value TRAP, return the corresponding signal. */
77
 
78
int __computeSignal (unsigned int trap_number)
79
{
80
    unsigned short curins, *pc;
81
    switch (trap_number) {
82
    case CYGNUM_HAL_VECTOR_INTWDT: // watchdog timer NMI
83
        pc = (unsigned short *)_hal_registers->pc;
84
        curins = *pc;
85
        if (curins == 0x0585) {
86
            // "br *" - used for breakpoint
87
            return SIGTRAP;
88
        } else {
89
            // Anything else - just ignore it happened
90
            return 0;
91
        }
92
    case CYGNUM_HAL_VECTOR_NMI:
93
        return SIGINT;
94
    default:
95
        return SIGTRAP;
96
    }
97
}
98
 
99
 
100
/* Return the trap number corresponding to the last-taken trap. */
101
int __get_trap_number (void)
102
{
103
    // The vector is not not part of the GDB register set so get it
104
    // directly from the save context.
105
    return _hal_registers->vector;
106
}
107
 
108
/* Set the currently-saved pc register value to PC. */
109
 
110
void set_pc (target_register_t pc)
111
{
112
    put_register (PC, pc);
113
}
114
 
115
 
116
/*----------------------------------------------------------------------
117
 * Single-step support
118
 */
119
 
120
/* Set things up so that the next user resume will execute one instruction.
121
   This may be done by setting breakpoints or setting a single step flag
122
   in the saved user registers, for example. */
123
 
124
static unsigned short *ss_saved_pc = 0;
125
static unsigned short  ss_saved_instr[2];
126
static int             ss_saved_instr_size;
127
 
128
#define FIXME() {diag_printf("FIXME - %s\n", __FUNCTION__); }
129
 
130
static unsigned short *
131
next_pc(unsigned short *pc)
132
{
133
    unsigned short curins = *pc;
134
    unsigned short *newpc = pc;
135
 
136
    switch ((curins & 0x0780) >> 7) {
137
    case 0x0:
138
        if ((curins & 0x60) == 0x60) {
139
            int Rn = curins & 0x1F;
140
            newpc = (unsigned short *)get_register(Rn);
141
        } else {
142
            newpc = pc+1;
143
        }
144
        break;
145
    case 0x1:
146
    case 0x2:
147
    case 0x3:
148
    case 0x4:
149
    case 0x5:
150
        // Arithmetic - no branch opcodes
151
        newpc = pc+1;
152
        break;
153
    case 0x6:
154
    case 0x7:
155
    case 0x8:
156
    case 0x9:
157
    case 0xA:
158
        // Load and store - no branch opcodes
159
        newpc = pc+2;
160
        break;
161
    case 0xB:
162
        // Conditional branch
163
        if (1) {
164
            unsigned long psw = get_register(PSW);
165
#define PSW_SAT 0x10
166
#define PSW_CY  0x08
167
#define PSW_OV  0x04
168
#define PSW_S   0x02
169
#define PSW_Z   0x01
170
            long disp = ((curins & 0xF800) >> 8) | ((curins & 0x70) >> 4);
171
            int cc = curins & 0x0F;
172
            int S = (psw & PSW_S) != 0;
173
            int Z = (psw & PSW_Z) != 0;
174
            int OV = (psw & PSW_OV) != 0;
175
            int CY = (psw & PSW_CY) != 0;
176
            int do_branch = 0;
177
            if (curins & 0x8000) disp |= 0xFFFFFF00;
178
            switch (cc) {
179
            case 0x0: // BV
180
                do_branch = (OV == 1);
181
                break;
182
            case 0x1: // BL
183
                do_branch = (CY == 1);
184
                break;
185
            case 0x2: // BE
186
                do_branch = (Z == 1);
187
                break;
188
            case 0x3: // BNH
189
                do_branch = ((CY | Z) == 1);
190
                break;
191
            case 0x4: // BN
192
                do_branch = (S == 1);
193
                break;
194
            case 0x5: // - always
195
                do_branch = 1;
196
                break;
197
            case 0x6: // BLT
198
                do_branch = ((S ^ OV) == 1);
199
                break;
200
            case 0x7: // BLE
201
                do_branch = (((S ^ OV) | Z) == 1);
202
                break;
203
            case 0x8: // BNV
204
                do_branch = (OV == 0);
205
                break;
206
            case 0x9: // BNL
207
                do_branch = (CY == 0);
208
                break;
209
            case 0xA: // BNE
210
                do_branch = (Z == 0);
211
                break;
212
            case 0xB: // BH
213
                do_branch = ((CY | Z) == 0);
214
                break;
215
            case 0xC: // BP
216
                do_branch = (S == 0);
217
                break;
218
            case 0xD: // BSA
219
                do_branch = ((psw & PSW_SAT) != 0);
220
                break;
221
            case 0xE: // BGE
222
                do_branch = ((S ^ OV) == 0);
223
                break;
224
            case 0xF: // BGT
225
                do_branch = (((S ^ OV) | Z) == 0);
226
                break;
227
            }
228
            if (do_branch) {
229
                newpc = pc + disp;
230
            } else {
231
                newpc = pc + 1;
232
            }
233
        }
234
        break;
235
    case 0xC:
236
    case 0xD:
237
    case 0xE:
238
        // Arithmetic & load/store - no branch opcodes
239
        newpc = pc+2;
240
        break;
241
    case 0xF:
242
        if ((curins & 0x60) >= 0x40) {
243
            // Bitfield and extended instructions - no branch opcodes
244
            newpc = pc+2;
245
        } else {
246
            // JR/JARL
247
            long disp = ((curins & 0x3F) << 16) | *(pc+1);
248
            if (curins & 0x20) disp |= 0xFFC00000;
249
            newpc = pc + (disp>>1);
250
        }
251
    }
252
    return newpc;
253
}
254
 
255
void __single_step (void)
256
{
257
    unsigned short *pc = (unsigned short *)get_register(PC);
258
    unsigned short *break_pc;
259
    unsigned short  _breakpoint[] = {0x07E0, 0x0780};
260
    unsigned short *breakpoint = _breakpoint;
261
    // If the current instruction is a branch, decide if the branch will
262
    // be taken to determine where to set the breakpoint.
263
    break_pc = next_pc(pc);
264
    // Now see what kind of breakpoint can be used.
265
    // Note: since this is a single step, always use the 32 bit version.
266
    ss_saved_pc = break_pc;
267
    ss_saved_instr_size = 2;
268
    ss_saved_instr[0] = *break_pc;
269
    *break_pc++ = *breakpoint++;
270
    ss_saved_instr[1] = *break_pc;
271
    *break_pc++ = *breakpoint++;
272
}
273
 
274
/* Clear the single-step state. */
275
 
276
void __clear_single_step (void)
277
{
278
    unsigned short *pc, *val;
279
    int i;
280
    if (ss_saved_instr_size != 0) {
281
        pc = ss_saved_pc;
282
        val = ss_saved_instr;
283
        for (i = 0;  i < ss_saved_instr_size;  i++) {
284
            *pc++ = *val++;
285
        }
286
        ss_saved_instr_size = 0;
287
    }
288
}
289
 
290
#if !defined(CYGPKG_CYGMON)
291
void __install_breakpoints (void)
292
{
293
//    FIXME();
294
}
295
 
296
void __clear_breakpoints (void)
297
{
298
//    FIXME();
299
}
300
#endif // !CYGPKG_CYGMON
301
 
302
/* If the breakpoint we hit is in the breakpoint() instruction, return a
303
   non-zero value. */
304
 
305
int
306
__is_breakpoint_function ()
307
{
308
    return get_register (PC) == (target_register_t)&_breakinst;
309
}
310
 
311
 
312
/* Skip the current instruction.  Since this is only called by the
313
   stub when the PC points to a breakpoint or trap instruction,
314
*/
315
 
316
void __skipinst (void)
317
{
318
    unsigned short *pc = (unsigned short *)get_register(PC);
319
    pc = next_pc(pc);
320
    put_register(PC, (unsigned long)pc);
321
}
322
 
323
 
324
#endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
325
 
326
// EOF v850_stub.c

powered by: WebSVN 2.1.0

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