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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//      synth.c
4
//
5
//      Flash programming
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):    andrew.lunn@ascom.ch
43
// Contributors: jlarmour
44
// Date:         2001-10-30
45
// Purpose:      
46
// Description:  
47
//              
48
//####DESCRIPTIONEND####
49
//
50
//==========================================================================
51
 
52
#include <pkgconf/devs_flash_synth_v2.h>
53
 
54
#include <cyg/hal/hal_io.h>
55
#include <cyg/infra/cyg_ass.h>
56
#include <string.h>
57
 
58
#include <cyg/io/flash.h>
59
#include <cyg/io/flash_dev.h>
60
#include <cyg/flash/synth.h>
61
 
62
#ifndef MIN
63
#define MIN(x,y) ((x)<(y) ? (x) : (y))
64
#endif
65
 
66
static int
67
synth_flash_init(struct cyg_flash_dev *dev)
68
{
69
    struct cyg_flash_synth_priv *priv =
70
        (struct cyg_flash_synth_priv *) dev->priv;
71
    cyg_flashaddr_t base;
72
    int flags = CYG_HAL_SYS_MAP_SHARED;
73
 
74
    priv->flashfd = cyg_hal_sys_open(
75
        priv->filename,
76
        CYG_HAL_SYS_O_RDWR,
77
        CYG_HAL_SYS_S_IRWXU|CYG_HAL_SYS_S_IRWXG|CYG_HAL_SYS_S_IRWXO);
78
 
79
    if (priv->flashfd == -ENOENT) {
80
        long w, bytesleft;
81
        char buf[128];
82
 
83
        priv->flashfd = cyg_hal_sys_open(
84
            priv->filename,
85
            CYG_HAL_SYS_O_RDWR|CYG_HAL_SYS_O_CREAT,
86
            CYG_HAL_SYS_S_IRWXU|CYG_HAL_SYS_S_IRWXG|CYG_HAL_SYS_S_IRWXO);
87
        CYG_ASSERT(priv->flashfd >= 0,
88
                   "Opening of the file for the synth flash failed!");
89
 
90
        // Fill with 0xff
91
        memset(buf, 0xff, sizeof(buf));
92
        bytesleft = priv->block_size * priv->blocks +
93
            priv->boot_block_size * priv->boot_blocks;
94
        while (bytesleft > 0) {
95
            int bytesneeded;
96
            bytesneeded = bytesleft < sizeof(buf) ? bytesleft : sizeof(buf);
97
            w = cyg_hal_sys_write(priv->flashfd, buf, bytesneeded);
98
            CYG_ASSERT(w == bytesneeded, "initialization of flash file failed");
99
            bytesleft -= bytesneeded;
100
        }
101
    }
102
 
103
    CYG_ASSERT(priv->flashfd >= 0,
104
               "Opening of the file for the synth flash failed!");
105
 
106
    if (priv->flashfd <= 0)
107
        return CYG_FLASH_ERR_HWR;
108
 
109
    if (dev->start != 0)
110
        flags |= CYG_HAL_SYS_MAP_FIXED;
111
 
112
    base = (cyg_flashaddr_t) cyg_hal_sys_mmap(
113
        (void *) dev->start,
114
        priv->blocks * priv->block_size +
115
        priv->boot_block_size * priv->boot_blocks,
116
        CYG_HAL_SYS_PROT_READ,
117
        flags,
118
        priv->flashfd,
119
        0l);
120
    CYG_ASSERT(base != -1, "mmap of flash file failed!");
121
    if (base == -1)
122
        return CYG_FLASH_ERR_HWR;
123
 
124
    dev->start = base;
125
    dev->end = base + (priv->blocks * priv->block_size) +
126
        (priv->boot_blocks * priv->boot_block_size) - 1;
127
    if (priv->boot_blocks) {
128
        if (priv->boot_block_bottom) {
129
            priv->block_info[0].block_size = priv->boot_block_size;
130
            priv->block_info[0].blocks = priv->boot_blocks;
131
            priv->block_info[1].block_size = priv->block_size;
132
            priv->block_info[1].blocks = priv->blocks;
133
        } else {
134
            priv->block_info[0].block_size = priv->block_size;
135
            priv->block_info[0].blocks = priv->blocks;
136
            priv->block_info[1].block_size = priv->boot_block_size;
137
            priv->block_info[1].blocks = priv->boot_blocks;
138
        }
139
        dev->num_block_infos = 2;
140
    } else {
141
        priv->block_info[0].block_size = priv->block_size;
142
        priv->block_info[0].blocks = priv->blocks;
143
        dev->num_block_infos = 1;
144
    }
145
    dev->block_info = &priv->block_info[0];
146
 
147
    return CYG_FLASH_ERR_OK;
148
}
149
 
150
// Return the size of the block which is at the given address.
151
// __inline__ so that we know it will be in RAM, not ROM.
152
static __inline__ size_t
153
flash_block_size(struct cyg_flash_dev *dev, const cyg_flashaddr_t addr)
154
{
155
    int i;
156
    cyg_flashaddr_t offset;
157
 
158
    CYG_ASSERT((addr >= dev->start) && (addr <= dev->end), "Not inside device");
159
 
160
    offset = addr - dev->start;
161
    for (i=0; i < dev->num_block_infos; i++) {
162
        if (offset < (dev->block_info[i].blocks *
163
                      dev->block_info[i].block_size))
164
             return dev->block_info[i].block_size;
165
        offset = offset -
166
            (dev->block_info[i].blocks * dev->block_info[i].block_size);
167
    }
168
    CYG_FAIL("Programming error");
169
    return 0;
170
}
171
 
172
static int
173
synth_flash_erase_block(struct cyg_flash_dev *dev,
174
                        cyg_flashaddr_t block_base)
175
{
176
    const struct cyg_flash_synth_priv *priv = dev->priv;
177
    cyg_flashaddr_t offset = block_base;
178
    size_t remaining;
179
    int write_size;
180
 
181
    // This helps speed up the erasing
182
    static cyg_uint8 empty[4096];
183
    static cyg_bool empty_inited;
184
 
185
    offset -= dev->start;
186
 
187
    cyg_hal_sys_lseek(priv->flashfd, offset, CYG_HAL_SYS_SEEK_SET);
188
 
189
    if (!empty_inited) {
190
        memset(empty, 0xff, sizeof(empty));
191
        empty_inited = true;
192
    }
193
 
194
    remaining = flash_block_size(dev, block_base);
195
 
196
    while (remaining) {
197
      write_size = MIN(remaining, sizeof(empty));
198
      cyg_hal_sys_write(priv->flashfd, empty, write_size);
199
      remaining -= write_size;
200
    }
201
 
202
    return CYG_FLASH_ERR_OK;
203
}
204
 
205
static int
206
synth_flash_program (struct cyg_flash_dev *dev,
207
                     cyg_flashaddr_t base,
208
                     const void* data, size_t len)
209
{
210
    const struct cyg_flash_synth_priv *priv = dev->priv;
211
    cyg_flashaddr_t offset = base;
212
    cyg_uint8 *buf = (cyg_uint8 *) data;
213
 
214
    // This helps speed up the programming
215
    static cyg_uint8 tmp[4096];
216
 
217
    offset -= dev->start;
218
 
219
    while (len > 0) {
220
        int i;
221
        int write_size = MIN(len, sizeof(tmp));
222
        // Writing to NOR flash only sets bits from 1 to 0, not vice-versa
223
        cyg_hal_sys_lseek(priv->flashfd, offset, CYG_HAL_SYS_SEEK_SET);
224
        cyg_hal_sys_read(priv->flashfd, tmp, write_size);
225
        for (i = 0; i < write_size; i++)
226
            tmp[i] = tmp[i] & buf[i];
227
        cyg_hal_sys_lseek(priv->flashfd, offset, CYG_HAL_SYS_SEEK_SET);
228
        cyg_hal_sys_write(priv->flashfd, tmp, write_size);
229
        // Process next chunk
230
        buf += write_size;
231
        offset += write_size;
232
        len -= write_size;
233
    }
234
 
235
    return CYG_FLASH_ERR_OK;
236
}
237
 
238
#define QUERY "Linux Synthetic Flash" 
239
 
240
static size_t
241
synth_flash_query(struct cyg_flash_dev *dev, void * data, size_t len)
242
{
243
    memcpy(data, QUERY, sizeof(QUERY));
244
    return sizeof(QUERY);
245
}
246
 
247
const CYG_FLASH_FUNS(cyg_flash_synth_funs,
248
                     synth_flash_init,
249
                     synth_flash_query,
250
                     synth_flash_erase_block,
251
                     synth_flash_program,
252
                     NULL,                 // read
253
                     cyg_flash_devfn_lock_nop,
254
                     cyg_flash_devfn_unlock_nop);
255
 
256
static struct cyg_flash_synth_priv synth_flash_priv = {
257
    .block_size         = CYGNUM_FLASH_SYNTH_V2_BLOCKSIZE,
258
    .blocks             = CYGNUM_FLASH_SYNTH_V2_NUMBLOCKS,
259
    .boot_block_size    = CYGNUM_FLASH_SYNTH_V2_BOOT_BLOCKSIZE,
260
    .boot_blocks        = CYGNUM_FLASH_SYNTH_V2_NUMBOOT_BLOCKS,
261
    .boot_block_bottom  = CYGNUM_FLASH_SYNTH_V2_BOOT_BLOCK_BOTTOM,
262
    .filename           = CYGDAT_FLASH_SYNTH_V2_FILENAME,
263
    .flashfd            = -1
264
};
265
 
266
CYG_FLASH_DRIVER(cyg_flash_synth_flashdev,
267
                 &cyg_flash_synth_funs,
268
                 0,                             // flags
269
                 CYGMEM_FLASH_SYNTH_V2_BASE,    // Start, if 0 will be updated by init
270
                 0,                             // end, filled in by init
271
                 0,                             // number of block_info's, filled in by init
272
                 synth_flash_priv.block_info,
273
                 &synth_flash_priv);
274
 
275
// EOF synth.c

powered by: WebSVN 2.1.0

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