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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//========================================================================
2
//
3
//      calm16-stub.h
4
//
5
//      Helper functions for stub, generic to all CalmRISC16 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 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):     Red Hat, msalter
43
// Contributors:  Red Hat, msalter
44
// Date:          2001-02-12
45
// Purpose:       
46
// Description:   Helper functions for stub, generic to CalmRISC16 processors
47
// Usage:         
48
//
49
//####DESCRIPTIONEND####
50
//
51
//========================================================================
52
 
53
#include <stddef.h>
54
 
55
#include <pkgconf/hal.h>
56
 
57
#ifdef CYGPKG_REDBOOT
58
#include <pkgconf/redboot.h>
59
#endif
60
 
61
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
62
 
63
#include <cyg/hal/hal_stub.h>
64
 
65
#define CYGARC_HAL_COMMON_EXPORT_CPU_MACROS
66
 
67
#include <cyg/hal/hal_arch.h>
68
#include <cyg/hal/hal_intr.h>
69
 
70
typedef cyg_uint16 t_inst;
71
 
72
/*----------------------------------------------------------------------
73
 * Asynchronous interrupt support
74
 */
75
 
76
static struct
77
{
78
  t_inst *targetAddr;
79
  t_inst savedInstr;
80
} asyncBuffer;
81
 
82
/* Called to asynchronously interrupt a running program.
83
   Must be passed address of instruction interrupted.
84
   This is typically called in response to a debug port
85
   receive interrupt.
86
*/
87
 
88
void
89
install_async_breakpoint(void *pc)
90
{
91
  asyncBuffer.targetAddr = pc;
92
  asyncBuffer.savedInstr = *(t_inst *)pc;
93
  *(t_inst *)pc = *(t_inst *)_breakinst;
94
  __instruction_cache(CACHE_FLUSH);
95
  __data_cache(CACHE_FLUSH);
96
}
97
 
98
/*--------------------------------------------------------------------*/
99
/* Given a trap value TRAP, return the corresponding signal. */
100
 
101
int __computeSignal (unsigned int trap_number)
102
{
103
    switch (trap_number) {
104
      case CYGNUM_HAL_VECTOR_FIQ:
105
//    case CYGNUM_HAL_VECTOR_IRQ:
106
        return SIGINT;
107
    }
108
    return SIGTRAP;
109
}
110
 
111
/* Return the trap number corresponding to the last-taken trap. */
112
 
113
int __get_trap_number (void)
114
{
115
    // The vector is not not part of the GDB register set so get it
116
    // directly from the save context.
117
    return _hal_registers->vector;
118
}
119
 
120
#if defined(CYGSEM_REDBOOT_BSP_SYSCALLS)
121
int __is_bsp_syscall(void)
122
{
123
    return __get_trap_number() >= CYGNUM_HAL_VECTOR_SWI;
124
}
125
#endif
126
 
127
 
128
/* Set the current pc register value based on current vector. */
129
 
130
void set_pc (target_register_t pc)
131
{
132
    put_register (REG_PC, pc);
133
    switch (__get_trap_number()) {
134
      case CYGNUM_HAL_VECTOR_FIQ:
135
        put_register (REG_SPC_FIQ, pc);
136
        break;
137
      case CYGNUM_HAL_VECTOR_SWI:
138
        put_register (REG_LR, pc);
139
        break;
140
      default:
141
        put_register (REG_SPC_IRQ, pc);
142
        break;
143
    }
144
}
145
 
146
/* Get the current pc register value based on current vector. */
147
 
148
target_register_t get_pc(void)
149
{
150
    switch (__get_trap_number()) {
151
      case CYGNUM_HAL_VECTOR_SWI:
152
        return get_register (REG_LR);
153
      case CYGNUM_HAL_VECTOR_FIQ:
154
        return get_register (REG_SPC_FIQ);
155
      default:
156
        break;
157
    }
158
    return get_register (REG_SPC_IRQ);
159
}
160
 
161
 
162
/*----------------------------------------------------------------------
163
 * Single-step support
164
 */
165
 
166
/* Set things up so that the next user resume will execute one instruction.
167
   This may be done by setting breakpoints or setting a single step flag
168
   in the saved user registers, for example. */
169
 
170
void __single_step (void)
171
{
172
    put_register(REG_SR, get_register(REG_SR) | ((target_register_t)CYGARC_SR_TE << 16));
173
}
174
 
175
 
176
/* Clear the single-step state. */
177
 
178
void __clear_single_step (void)
179
{
180
    put_register(REG_SR, get_register(REG_SR) & ~((target_register_t)CYGARC_SR_TE << 16));
181
}
182
 
183
 
184
void __install_breakpoints ()
185
{
186
  /* Install the breakpoints in the breakpoint list */
187
  __install_breakpoint_list();
188
}
189
 
190
void __clear_breakpoints (void)
191
{
192
  __clear_breakpoint_list();
193
}
194
 
195
 
196
/* If the breakpoint we hit is in the breakpoint() instruction, return a
197
   non-zero value. */
198
 
199
int
200
__is_breakpoint_function ()
201
{
202
    return get_pc() == (target_register_t)(unsigned long)&_breakinst;
203
}
204
 
205
 
206
/* Skip the current instruction.  Since this is only called by the
207
   stub when the PC points to a breakpoint or trap instruction,
208
   we can safely just skip 2. */
209
 
210
void __skipinst (void)
211
{
212
    set_pc(get_pc() + 2);
213
}
214
 
215
unsigned short __read_prog_uint16(void *addr)
216
{
217
    unsigned val;
218
    asm("ldc %0, @%1" : "=r"(val) : "r"(addr) );
219
    return val;
220
}
221
 
222
unsigned char __read_prog_uint8(void *addr)
223
{
224
    unsigned short s;
225
    int is_odd = ((unsigned long)addr & 1) == 1;
226
 
227
    s = __read_prog_uint16((void *)((unsigned long)addr & ~1));
228
    if (is_odd)
229
        return s & 0xff;
230
    else
231
        return (s >> 8) & 0xff;
232
}
233
 
234
unsigned long __read_prog_uint32(void *addr)
235
{
236
    unsigned long u;
237
 
238
    u = (unsigned long)__read_prog_uint16(addr) << 16;
239
    u |= __read_prog_uint16((void *)((unsigned long)addr + 2));
240
 
241
    return u;
242
}
243
 
244
void __write_prog_uint16(void *addr, unsigned short val)
245
{
246
    hal_plf_write_prog_halfword((unsigned long)addr, val);
247
}
248
 
249
void __write_prog_uint32(void *addr, unsigned long val)
250
{
251
    hal_plf_write_prog_halfword((unsigned long)addr, (val >> 16) & 0xffff);
252
    hal_plf_write_prog_halfword((unsigned long)addr + 2, val & 0xffff);
253
}
254
 
255
void __write_prog_uint8(void *addr, unsigned char val)
256
{
257
    unsigned short s;
258
    int is_odd = ((unsigned long)addr & 1) == 1;
259
 
260
    s = __read_prog_uint16((void *)((unsigned long)addr & ~1));
261
 
262
    if (is_odd)
263
        s = (s & 0xff00) | val;
264
    else
265
        s = (s & 0xff) | (val << 8);
266
 
267
    hal_plf_write_prog_halfword((unsigned long)addr & ~1, s);
268
}
269
 
270
#endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS

powered by: WebSVN 2.1.0

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