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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [hal/] [common/] [current/] [src/] [bplist-dynamic.c] - Blame information for rev 839

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

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//      bplist-dynamic.c
4
//
5
//      Dynamic breakpoint list.
6
//      Currently only statically allocated.  (ie NO_MALLOC is assumed)
7
//
8
//==========================================================================
9
// ####ECOSGPLCOPYRIGHTBEGIN####                                            
10
// -------------------------------------------                              
11
// This file is part of eCos, the Embedded Configurable Operating System.   
12
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
13
//
14
// eCos is free software; you can redistribute it and/or modify it under    
15
// the terms of the GNU General Public License as published by the Free     
16
// Software Foundation; either version 2 or (at your option) any later      
17
// version.                                                                 
18
//
19
// eCos is distributed in the hope that it will be useful, but WITHOUT      
20
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
21
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
22
// for more details.                                                        
23
//
24
// You should have received a copy of the GNU General Public License        
25
// along with eCos; if not, write to the Free Software Foundation, Inc.,    
26
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
27
//
28
// As a special exception, if other files instantiate templates or use      
29
// macros or inline functions from this file, or you compile this file      
30
// and link it with other works to produce a work based on this file,       
31
// this file does not by itself cause the resulting work to be covered by   
32
// the GNU General Public License. However the source code for this file    
33
// must still be made available in accordance with section (3) of the GNU   
34
// General Public License v2.                                               
35
//
36
// This exception does not invalidate any other reasons why a work based    
37
// on this file might be covered by the GNU General Public License.         
38
// -------------------------------------------                              
39
// ####ECOSGPLCOPYRIGHTEND####                                              
40
//==========================================================================
41
//#####DESCRIPTIONBEGIN####
42
//
43
// Author(s):    
44
// Contributors: dmoseley
45
// Date:         2000-07-11
46
// Purpose:      Dynamic breakpoint list.
47
// Description:  
48
//               
49
//
50
//####DESCRIPTIONEND####
51
//
52
//=========================================================================
53
 
54
#include <pkgconf/system.h>
55
#include <pkgconf/hal.h>
56
 
57
#if defined(CYGNUM_HAL_BREAKPOINT_LIST_SIZE) && (CYGNUM_HAL_BREAKPOINT_LIST_SIZE > 0) && defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS)
58
 
59
#define CYGARC_HAL_COMMON_EXPORT_CPU_MACROS
60
#include <cyg/hal/hal_stub.h>
61
#include <cyg/hal/hal_arch.h>
62
#include <cyg/hal/hal_cache.h>
63
 
64
#ifdef TARGET_HAS_HARVARD_MEMORY
65
#define __read_mem_safe __read_progmem_safe
66
#define __write_mem_safe __write_progmem_safe
67
#endif
68
 
69
/*
70
 * A simple target breakpoint list without using malloc.
71
 * To use this package, you must define HAL_BREAKINST_SIZE to be the size
72
 * in bytes of a trap instruction (max if there's more than one),
73
 * HAL_BREAKINST to the opcode value of the instruction, and
74
 * HAL_BREAKINST_TYPE to be the type necessary to hold the opcode value.
75
 */
76
 
77
struct breakpoint_list {
78
  target_register_t  addr;
79
  char old_contents [HAL_BREAKINST_SIZE];
80
  struct breakpoint_list *next;
81
  char in_memory;
82
  char length;
83
} *breakpoint_list = NULL;
84
 
85
#ifndef HAL_BREAKINST_ADDR
86
static HAL_BREAKINST_TYPE break_inst = HAL_BREAKINST;
87
#define HAL_BREAKINST_ADDR(x) ((void*)&break_inst)
88
#endif
89
 
90
static struct breakpoint_list bp_list [CYGNUM_HAL_BREAKPOINT_LIST_SIZE];
91
static struct breakpoint_list *free_bp_list = NULL;
92
static int curr_bp_num = 0;
93
 
94
int
95
__set_breakpoint (target_register_t addr, target_register_t len)
96
{
97
  struct breakpoint_list **addent = &breakpoint_list;
98
  struct breakpoint_list *l = breakpoint_list;
99
  struct breakpoint_list *newent;
100
 
101
  while (l != NULL && l->addr < addr)
102
    {
103
      addent = &l->next;
104
      l =  l->next;
105
    }
106
 
107
  if (l != NULL && l->addr == addr)
108
    return 2;
109
 
110
  if (free_bp_list != NULL)
111
    {
112
      newent = free_bp_list;
113
      free_bp_list = free_bp_list->next;
114
    }
115
  else
116
    {
117
      if (curr_bp_num < CYGNUM_HAL_BREAKPOINT_LIST_SIZE)
118
        {
119
          newent = &bp_list[curr_bp_num++];
120
        }
121
      else
122
        {
123
          return 1;
124
        }
125
    }
126
 
127
  newent->addr = addr;
128
  newent->in_memory = 0;
129
  newent->next = l;
130
  newent->length = len;
131
  *addent = newent;
132
 
133
  return 0;
134
}
135
 
136
int
137
__remove_breakpoint (target_register_t addr, target_register_t len)
138
{
139
  struct breakpoint_list *l = breakpoint_list;
140
  struct breakpoint_list *prev = NULL;
141
 
142
  while (l != NULL && l->addr < addr)
143
    {
144
      prev = l;
145
      l = l->next;
146
    }
147
 
148
  if ((l == NULL) || (l->addr != addr))
149
    return 1;
150
 
151
  if (l->in_memory)
152
    {
153
      __write_mem_safe (&l->old_contents[0],
154
                        (void*)l->addr,
155
                        sizeof (l->old_contents));
156
    }
157
 
158
  if (prev == NULL)
159
    breakpoint_list = l->next;
160
  else
161
    prev->next = l->next;
162
 
163
  l->next = free_bp_list;
164
  free_bp_list = l;
165
 
166
  return 0;
167
}
168
 
169
#if defined(HAL_STUB_HW_BREAKPOINT_LIST_SIZE) && (HAL_STUB_HW_BREAKPOINT_LIST_SIZE > 0)
170
#ifndef HAL_STUB_HW_BREAKPOINT
171
#error "Must define HAL_STUB_HW_BREAKPOINT"
172
#endif
173
struct hw_breakpoint_list {
174
  target_register_t  addr;
175
  target_register_t  len;
176
  char used;
177
  char installed;
178
};
179
static struct hw_breakpoint_list hw_bp_list [HAL_STUB_HW_BREAKPOINT_LIST_SIZE];
180
 
181
int
182
__set_hw_breakpoint (target_register_t addr, target_register_t len)
183
{
184
  int i;
185
 
186
  for (i = 0; i < HAL_STUB_HW_BREAKPOINT_LIST_SIZE; i++)
187
    {
188
      if (hw_bp_list[i].used == 0)
189
        {
190
          hw_bp_list[i].addr = addr;
191
          hw_bp_list[i].len = len;
192
          hw_bp_list[i].used = 1;
193
          hw_bp_list[i].installed = 0;
194
          return 0;
195
        }
196
    }
197
  return -1;
198
}
199
 
200
int
201
__remove_hw_breakpoint (target_register_t addr, target_register_t len)
202
{
203
  int i;
204
 
205
  for (i = 0; i < HAL_STUB_HW_BREAKPOINT_LIST_SIZE; i++)
206
    {
207
      if (hw_bp_list[i].used && hw_bp_list[i].addr == addr
208
          && hw_bp_list[i].len == len)
209
        {
210
          if (hw_bp_list[i].installed)
211
            HAL_STUB_HW_BREAKPOINT(0, (void *)addr, (int)len);
212
          hw_bp_list[i].used = 0;
213
          return 0;
214
        }
215
    }
216
  return -1;
217
}
218
 
219
static void
220
__install_hw_breakpoint_list (void)
221
{
222
  int i;
223
 
224
  for (i = 0; i < HAL_STUB_HW_BREAKPOINT_LIST_SIZE; i++)
225
    {
226
      if (hw_bp_list[i].used && hw_bp_list[i].installed == 0)
227
        {
228
          HAL_STUB_HW_BREAKPOINT(1, (void *)hw_bp_list[i].addr,
229
                                 (int)hw_bp_list[i].len);
230
          hw_bp_list[i].installed = 1;
231
        }
232
    }
233
}
234
 
235
static void
236
__clear_hw_breakpoint_list (void)
237
{
238
  int i;
239
 
240
  for (i = 0; i < HAL_STUB_HW_BREAKPOINT_LIST_SIZE; i++)
241
    {
242
      if (hw_bp_list[i].used && hw_bp_list[i].installed)
243
        {
244
          HAL_STUB_HW_BREAKPOINT(0, (void *)hw_bp_list[i].addr,
245
                                 (int)hw_bp_list[i].len);
246
          hw_bp_list[i].installed = 0;
247
        }
248
    }
249
}
250
#endif // HAL_STUB_HW_BREAKPOINT_LIST_SIZE
251
 
252
#if defined(HAL_STUB_HW_WATCHPOINT_LIST_SIZE) && (HAL_STUB_HW_WATCHPOINT_LIST_SIZE > 0)
253
#ifndef HAL_STUB_HW_WATCHPOINT
254
#error "Must define HAL_STUB_HW_WATCHPOINT"
255
#endif
256
struct hw_watchpoint_list {
257
  target_register_t  addr;
258
  target_register_t  len;
259
  int ztype;
260
  char used;
261
  char installed;
262
};
263
static struct hw_watchpoint_list hw_wp_list [HAL_STUB_HW_WATCHPOINT_LIST_SIZE];
264
 
265
int
266
__set_hw_watchpoint (target_register_t addr, target_register_t len, int ztype)
267
{
268
  int i;
269
 
270
  for (i = 0; i < HAL_STUB_HW_WATCHPOINT_LIST_SIZE; i++)
271
    {
272
      if (hw_wp_list[i].used == 0)
273
        {
274
          hw_wp_list[i].addr = addr;
275
          hw_wp_list[i].len = len;
276
          hw_wp_list[i].ztype = ztype;
277
          hw_wp_list[i].used = 1;
278
          hw_wp_list[i].installed = 0;
279
          return 0;
280
        }
281
    }
282
  return -1;
283
}
284
 
285
int
286
__remove_hw_watchpoint (target_register_t addr, target_register_t len, int ztype)
287
{
288
  int i;
289
 
290
  for (i = 0; i < HAL_STUB_HW_WATCHPOINT_LIST_SIZE; i++)
291
    {
292
      if (hw_wp_list[i].used && hw_wp_list[i].addr == addr
293
          && hw_wp_list[i].len == len && hw_wp_list[i].ztype == ztype )
294
        {
295
          if (hw_wp_list[i].installed)
296
            HAL_STUB_HW_WATCHPOINT(0, (void *)addr, (int)len, ztype);
297
          hw_wp_list[i].used = 0;
298
          return 0;
299
        }
300
    }
301
  return -1;
302
}
303
 
304
static void
305
__install_hw_watchpoint_list (void)
306
{
307
  int i;
308
 
309
  for (i = 0; i < HAL_STUB_HW_WATCHPOINT_LIST_SIZE; i++)
310
    {
311
      if (hw_wp_list[i].used && hw_wp_list[i].installed == 0)
312
        {
313
          HAL_STUB_HW_WATCHPOINT(1, (void *)hw_wp_list[i].addr,
314
                                 (int)hw_wp_list[i].len, hw_wp_list[i].ztype);
315
          hw_wp_list[i].installed = 1;
316
        }
317
    }
318
}
319
 
320
static void
321
__clear_hw_watchpoint_list (void)
322
{
323
  int i;
324
 
325
  for (i = 0; i < HAL_STUB_HW_WATCHPOINT_LIST_SIZE; i++)
326
    {
327
      if (hw_wp_list[i].used && hw_wp_list[i].installed)
328
        {
329
          HAL_STUB_HW_WATCHPOINT(0, (void *)hw_wp_list[i].addr,
330
                                 (int)hw_wp_list[i].len, hw_wp_list[i].ztype);
331
          hw_wp_list[i].installed = 0;
332
        }
333
    }
334
}
335
#endif // HAL_STUB_HW_WATCHPOINT_LIST_SIZE
336
 
337
 
338
 
339
void
340
__install_breakpoint_list (void)
341
{
342
  struct breakpoint_list *l = breakpoint_list;
343
 
344
  while (l != NULL)
345
    {
346
      if (! l->in_memory)
347
        {
348
          int len = sizeof (l->old_contents);
349
          if (__read_mem_safe (&l->old_contents[0], (void*)l->addr, len) == len)
350
            {
351
              if (__write_mem_safe (HAL_BREAKINST_ADDR(l->length),
352
                                    (void*)l->addr, l->length) == l->length)
353
                {
354
                  l->in_memory = 1;
355
                }
356
            }
357
        }
358
      l = l->next;
359
    }
360
#if defined(HAL_STUB_HW_BREAKPOINT_LIST_SIZE) && (HAL_STUB_HW_BREAKPOINT_LIST_SIZE > 0)
361
  __install_hw_breakpoint_list();
362
#endif
363
#if defined(HAL_STUB_HW_WATCHPOINT_LIST_SIZE) && (HAL_STUB_HW_WATCHPOINT_LIST_SIZE > 0)
364
  __install_hw_watchpoint_list();
365
#endif
366
  HAL_ICACHE_SYNC();
367
}
368
 
369
void
370
__clear_breakpoint_list (void)
371
{
372
  struct breakpoint_list *l = breakpoint_list;
373
 
374
  while (l != NULL)
375
    {
376
      if (l->in_memory)
377
        {
378
          int len = sizeof (l->old_contents);
379
          if (__write_mem_safe (&l->old_contents[0], (void*)l->addr, len) == len)
380
            {
381
              l->in_memory = 0;
382
            }
383
        }
384
      l = l->next;
385
    }
386
#if defined(HAL_STUB_HW_BREAKPOINT_LIST_SIZE) && (HAL_STUB_HW_BREAKPOINT_LIST_SIZE > 0)
387
  __clear_hw_breakpoint_list();
388
#endif
389
#if defined(HAL_STUB_HW_WATCHPOINT_LIST_SIZE) && (HAL_STUB_HW_WATCHPOINT_LIST_SIZE > 0)
390
  __clear_hw_watchpoint_list();
391
#endif
392
  HAL_ICACHE_INVALIDATE_ALL();
393
}
394
 
395
int
396
__display_breakpoint_list (void (*print_func)(target_register_t))
397
{
398
  struct breakpoint_list *l = breakpoint_list;
399
 
400
  while (l != NULL)
401
    {
402
      print_func(l->addr);
403
      l = l->next;
404
    }
405
 
406
  return 0;
407
}
408
#else  // (CYGNUM_HAL_BREAKPOINT_LIST_SIZE == 0) or UNDEFINED
409
 
410
#include <cyg/hal/hal_stub.h>           // Our header
411
 
412
#ifndef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
413
// We don't know that type target_register_t is yet.
414
// Let's just pick a type so we can compile.  Since
415
// these versions of the functions don't actually do
416
// anything with the parameters, the actualy types
417
// don't matter.
418
typedef unsigned long target_register_t;
419
#endif
420
 
421
int
422
__set_breakpoint (target_register_t addr, target_register_t len)
423
{
424
  return 1;
425
}
426
 
427
int
428
__remove_breakpoint (target_register_t addr, target_register_t len)
429
{
430
  return 1;
431
}
432
 
433
void
434
__install_breakpoint_list (void)
435
{
436
}
437
 
438
void
439
__clear_breakpoint_list (void)
440
{
441
}
442
 
443
int
444
__display_breakpoint_list (void (*print_func)(target_register_t))
445
{
446
    return 0;
447
}
448
#endif // (CYGNUM_HAL_BREAKPOINT_LIST_SIZE > 0)
449
 

powered by: WebSVN 2.1.0

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