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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [io/] [flash/] [current/] [src/] [flashiodevlegacy.c] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//      flashiodev.c
4
//
5
//      Old flash device interface to I/O subsystem
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, 2004, 2009, 2010 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):    jlarmour
43
// Contributors: woehler, Andrew Lunn
44
// Date:         2002-01-16
45
// Purpose:      
46
// Description:  
47
//              
48
//####DESCRIPTIONEND####
49
//
50
//==========================================================================
51
 
52
#define _FLASH_PRIVATE_
53
#include <pkgconf/io_flash.h>
54
 
55
#include <errno.h>
56
#include <cyg/infra/cyg_type.h>
57
#include <cyg/io/devtab.h>
58
#include <cyg/io/config_keys.h>
59
#include <cyg/io/flash.h>
60
#include <string.h> // memcpy
61
#include <cyg/hal/hal_if.h>
62
 
63
#define MIN(x,y) ((x)<(y) ? (x) : (y))
64
#define MAX(x,y) ((x)>(y) ? (x) : (y))
65
 
66
struct flashiodev_priv_t{
67
  cyg_flashaddr_t start;
68
  cyg_flashaddr_t end;
69
  cyg_bool        use_fis;
70
  cyg_bool        use_absolute;
71
  cyg_bool        use_offset;
72
  char *          fis_name;
73
  cyg_uint32      block_size;
74
  cyg_bool        init;
75
};
76
 
77
static bool
78
flashiodev_init( struct cyg_devtab_entry *tab )
79
{
80
  int stat = cyg_flash_init(NULL);
81
 
82
  return (stat == CYG_FLASH_ERR_OK);
83
} // flashiodev_init()
84
 
85
static Cyg_ErrNo
86
flashiodev_lookup(struct cyg_devtab_entry **tab,
87
                  struct cyg_devtab_entry  *sub_tab,
88
                  const char *name)
89
{
90
  struct flashiodev_priv_t *dev = (struct flashiodev_priv_t *)(*tab)->priv;
91
  cyg_flash_info_t info;
92
  cyg_uint32 i;
93
  int stat;
94
 
95
  if (dev->init)
96
    return ENOERR;
97
 
98
  if (dev->use_fis) {
99
    CYG_ADDRESS flash_base;
100
    unsigned long       size;
101
 
102
    if(!CYGACC_CALL_IF_FLASH_FIS_OP(CYGNUM_CALL_IF_FLASH_FIS_GET_FLASH_BASE,
103
                                    dev->fis_name,
104
                                    &flash_base))
105
      return ENOERR;
106
 // Strange, yes, but needed since we have to do a lookup in order to
107
 // set the name using cyg_io_config_set. If we fail here you cannot
108
 // do a set. Since dev->init will still be false and attempts to
109
 // actually use the device will fail, so it is safe.
110
 
111
    if(!CYGACC_CALL_IF_FLASH_FIS_OP(CYGNUM_CALL_IF_FLASH_FIS_GET_SIZE,
112
                                    dev->fis_name,
113
                                    &size))
114
      return ENOERR; // Ditto.
115
    dev->start = flash_base;
116
    dev->end = flash_base + size;
117
  }
118
  if (dev->use_offset) {
119
    // dev->start contains the offset to the beginning of the block
120
    // dev->end is the length of the block
121
    cyg_flash_info_t info;
122
 
123
    cyg_flash_get_info(0, &info);
124
    dev->start = dev->start + info.start;
125
    dev->end = dev->start + dev->end;
126
  }
127
  if (dev->use_absolute) {
128
    // dev->start is the absolute address of the start
129
    // dev->end is the length;
130
    dev->end = dev->start + dev->end;
131
  }
132
 
133
  stat = cyg_flash_get_info_addr(dev->start, &info);
134
  if (stat != CYG_FLASH_ERR_OK) {
135
    return ENODEV;
136
    }
137
  dev->block_size = 0;
138
  for (i=0; i < info.num_block_infos; i++){
139
    dev->block_size = MAX(dev->block_size, info.block_info[i].block_size);
140
  }
141
 
142
  dev->init = 1;
143
  return ENOERR;
144
} // flashiodev_lookup()
145
 
146
static Cyg_ErrNo
147
flashiodev_bread( cyg_io_handle_t handle, void *buf, cyg_uint32 *len,
148
                  cyg_uint32 pos)
149
{
150
  struct cyg_devtab_entry *tab = (struct cyg_devtab_entry *)handle;
151
  struct flashiodev_priv_t *dev = (struct flashiodev_priv_t *)tab->priv;
152
 
153
  cyg_flashaddr_t startpos = dev->start + pos;
154
  Cyg_ErrNo err;
155
 
156
  if (!dev->init) {
157
    return -EINVAL;
158
  }
159
 
160
#ifdef CYGPKG_INFRA_DEBUG // don't bother checking this all the time
161
  cyg_flashaddr_t endpos = startpos + *len - 1;
162
  if ( startpos < dev->start )
163
    return -EINVAL;
164
  if ( endpos > dev->end )
165
    return -EINVAL;
166
#endif
167
 
168
  err = cyg_flash_read( startpos,(void *)buf, *len, NULL );
169
 
170
  if ( err != CYG_FLASH_ERR_OK )
171
    err = -EIO; // just something sane
172
  return err;
173
} // flashiodev_bread()
174
 
175
static Cyg_ErrNo
176
flashiodev_bwrite( cyg_io_handle_t handle, const void *buf, cyg_uint32 *len,
177
                   cyg_uint32 pos )
178
{
179
  struct cyg_devtab_entry *tab = (struct cyg_devtab_entry *)handle;
180
  struct flashiodev_priv_t *dev = (struct flashiodev_priv_t *)tab->priv;
181
 
182
  Cyg_ErrNo err;
183
  cyg_flashaddr_t startpos = dev->start + pos;
184
 
185
  if (!dev->init) {
186
    return -EINVAL;
187
  }
188
 
189
#ifdef CYGPKG_INFRA_DEBUG // don't bother checking this all the time
190
  cyg_flashaddr_t endpos = startpos + *len - 1;
191
  if ( startpos < dev->start )
192
    return -EINVAL;
193
  if ( endpos > dev->end )
194
    return -EINVAL;
195
#endif
196
  err = cyg_flash_program( startpos, (void *)buf, *len, NULL );
197
 
198
  if ( err )
199
    err = -EIO; // just something sane
200
  return err;
201
} // flashiodev_bwrite()
202
 
203
static Cyg_ErrNo
204
flashiodev_get_config( cyg_io_handle_t handle,
205
                       cyg_uint32 key,
206
                       void* buf,
207
                       cyg_uint32* len)
208
{
209
  struct cyg_devtab_entry *tab = (struct cyg_devtab_entry *)handle;
210
  struct flashiodev_priv_t *dev = (struct flashiodev_priv_t *)tab->priv;
211
 
212
  if (!dev->init) {
213
    return -EINVAL;
214
  }
215
 
216
  switch (key) {
217
  case CYG_IO_GET_CONFIG_FLASH_ERASE:
218
    {
219
      if (*len != sizeof( cyg_io_flash_getconfig_erase_t ) )
220
        return -EINVAL;
221
      {
222
        cyg_io_flash_getconfig_erase_t *e = (cyg_io_flash_getconfig_erase_t *)buf;
223
        cyg_flashaddr_t startpos = dev->start + e->offset;
224
 
225
#ifdef CYGPKG_INFRA_DEBUG // don't bother checking this all the time
226
        cyg_flashaddr_t endpos = startpos + e->len - 1;
227
        if ( startpos < dev->start )
228
          return -EINVAL;
229
        if ( endpos > dev->end )
230
          return -EINVAL;
231
#endif
232
        e->flasherr = cyg_flash_erase( startpos, e->len, e->err_address );
233
      }
234
      return ENOERR;
235
    }
236
  case CYG_IO_GET_CONFIG_FLASH_DEVSIZE:
237
    {
238
      if ( *len != sizeof( cyg_io_flash_getconfig_devsize_t ) )
239
        return -EINVAL;
240
      {
241
        cyg_io_flash_getconfig_devsize_t *d =
242
          (cyg_io_flash_getconfig_devsize_t *)buf;
243
 
244
        d->dev_size = dev->end - dev->start;
245
      }
246
      return ENOERR;
247
    }
248
 
249
  case CYG_IO_GET_CONFIG_FLASH_BLOCKSIZE:
250
    {
251
      cyg_io_flash_getconfig_blocksize_t *b =
252
        (cyg_io_flash_getconfig_blocksize_t *)buf;
253
#ifdef CYGPKG_INFRA_DEBUG // don't bother checking this all the time
254
      cyg_flashaddr_t startpos = dev->start + b->offset;
255
 
256
      if ( startpos < dev->start )
257
        return -EINVAL;
258
      if ( startpos > dev->end )
259
        return -EINVAL;
260
#endif  
261
      if ( *len != sizeof( cyg_io_flash_getconfig_blocksize_t ) )
262
        return -EINVAL;
263
 
264
      // offset unused for now
265
      b->block_size = dev->block_size;
266
      return ENOERR;
267
    }
268
 
269
  default:
270
    return -EINVAL;
271
  }
272
} // flashiodev_get_config()
273
 
274
static Cyg_ErrNo
275
flashiodev_set_config( cyg_io_handle_t handle,
276
                       cyg_uint32 key,
277
                       const void* buf,
278
                       cyg_uint32* len)
279
{
280
  struct cyg_devtab_entry *tab = (struct cyg_devtab_entry *)handle;
281
  struct flashiodev_priv_t *dev = (struct flashiodev_priv_t *)tab->priv;
282
 
283
  switch (key) {
284
  case CYG_IO_SET_CONFIG_FLASH_FIS_NAME:
285
    {
286
      cyg_flashaddr_t flash_base;
287
      unsigned long size;
288
      cyg_flash_info_t info;
289
      cyg_uint32 i;
290
      int stat;
291
 
292
      if(!CYGACC_CALL_IF_FLASH_FIS_OP(CYGNUM_CALL_IF_FLASH_FIS_GET_FLASH_BASE,
293
                                      (char *)buf, &flash_base))
294
        return -ENOENT;
295
 
296
      if(!CYGACC_CALL_IF_FLASH_FIS_OP(CYGNUM_CALL_IF_FLASH_FIS_GET_SIZE,
297
                                      (char *)buf, &size))
298
        return -ENOENT;
299
 
300
      dev->start = flash_base;
301
      dev->end = flash_base + size;
302
 
303
      stat = cyg_flash_get_info_addr(dev->start, &info);
304
 
305
      if (stat != CYG_FLASH_ERR_OK) {
306
        return -ENOENT;
307
      }
308
      dev->block_size = 0;
309
      for (i=0; i < info.num_block_infos; i++){
310
        dev->block_size = MAX(dev->block_size, info.block_info[i].block_size);
311
      }
312
      dev->init = 1;
313
 
314
      return ENOERR;
315
    }
316
  default:
317
    return -EINVAL;
318
  }
319
} // flashiodev_set_config()
320
 
321
// get_config/set_config should be added later to provide the other flash
322
// operations possible, like erase etc.
323
 
324
#define CYG_FLASHIODEV_DEV(start, end, fis, static, offset, name) \
325
   { start, end, fis, static, offset, name, 0, 0 }
326
 
327
#ifdef CYGNUM_IO_FLASH_BLOCK_CFG_FIS_1
328
static struct flashiodev_priv_t priv1 = CYG_FLASHIODEV_DEV(
329
  0,       // start
330
  0,       // end
331
  1,       // use_fis
332
  0,       // use_static
333
  0,       // use_offset
334
  CYGDAT_IO_FLASH_BLOCK_FIS_NAME_1);
335
#endif
336
 
337
#ifdef CYGNUM_IO_FLASH_BLOCK_CFG_STATIC_ABSOLUTE_1 
338
static struct flashiodev_priv_t priv1 = CYG_FLASHIODEV_DEV(
339
  CYGNUM_IO_FLASH_BLOCK_ABSOLUTE_START_1,       // start
340
  CYGNUM_IO_FLASH_BLOCK_ABSOLUTE_LENGTH_1,      // end
341
  0,       // use_fis
342
  1,       // use_static
343
  0,       // use_offset
344
  "");     // fis_name
345
#endif
346
 
347
#ifdef CYGNUM_IO_FLASH_BLOCK_CFG_STATIC_1
348
static struct flashiodev_priv_t priv1 = CYG_FLASHIODEV_DEV(
349
  CYGNUM_IO_FLASH_BLOCK_OFFSET_1,       // start
350
  CYGNUM_IO_FLASH_BLOCK_LENGTH_1,       // end 
351
  0,       // use_fis
352
  0,       // use_static
353
  1,       // use_offset
354
  "");     // fis_name
355
#endif
356
 
357
BLOCK_DEVIO_TABLE( cyg_io_flashdev1_ops,
358
                   &flashiodev_bwrite,
359
                   &flashiodev_bread,
360
                   0, // no select
361
                   &flashiodev_get_config,
362
                   &flashiodev_set_config
363
                   );
364
 
365
 
366
BLOCK_DEVTAB_ENTRY( cyg_io_flashdev1,
367
                    CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1,
368
                    0,
369
                    &cyg_io_flashdev1_ops,
370
                    &flashiodev_init,
371
                    &flashiodev_lookup,
372
                    &priv1 );
373
 
374
#ifdef CYGSEM_IO_FLASH_BLOCK_DEVICE_2 
375
#ifdef CYGNUM_IO_FLASH_BLOCK_CFG_FIS_2
376
static struct flashiodev_priv_t priv2 = CYG_FLASHIODEV_DEV(
377
  0,       // start
378
  0,       // end
379
  1,       // use_fis
380
  0,       // use_static
381
  0,       // use_offset
382
  CYGDAT_IO_FLASH_BLOCK_FIS_NAME_2);
383
#endif
384
 
385
#ifdef CYGNUM_IO_FLASH_BLOCK_CFG_STATIC_ABSOLUTE_2 
386
static struct flashiodev_priv_t priv2 = CYG_FLASHIODEV_DEV(
387
  CYGNUM_IO_FLASH_BLOCK_ABSOLUTE_START_2,       // start
388
  CYGNUM_IO_FLASH_BLOCK_ABSOLUTE_LENGTH_2,      // end
389
  0,       // use_fis
390
  1,       // use_static
391
  0,       // use_offset
392
  "");     // fis_name
393
#endif
394
 
395
#ifdef CYGNUM_IO_FLASH_BLOCK_CFG_STATIC_2
396
static struct flashiodev_priv_t priv2 = CYG_FLASHIODEV_DEV(
397
  CYGNUM_IO_FLASH_BLOCK_OFFSET_2,       // start
398
  CYGNUM_IO_FLASH_BLOCK_LENGTH_2,       // end 
399
  0,       // use_fis
400
  0,       // use_static
401
  1,       // use_offset
402
  "");     // fis_name
403
#endif
404
 
405
BLOCK_DEVTAB_ENTRY( cyg_io_flashdev2,
406
                    CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_2,
407
                    0,
408
                    &cyg_io_flashdev1_ops,
409
                    &flashiodev_init,
410
                    &flashiodev_lookup,
411
                    &priv2 );
412
#endif
413
 
414
// EOF flashiodev.c

powered by: WebSVN 2.1.0

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