]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/devs/flash/intel/strata/v2_0/src/flash_unlock_block.c
Initial revision
[karo-tx-redboot.git] / packages / devs / flash / intel / strata / v2_0 / src / flash_unlock_block.c
1 //==========================================================================
2 //
3 //      flash_unlock_block.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 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):    gthomas, hmt
44 // Contributors: gthomas
45 // Date:         2001-02-14
46 // Purpose:      
47 // Description:  
48 //              
49 //####DESCRIPTIONEND####
50 //
51 //==========================================================================
52
53 #include "strata.h"
54
55
56 //
57 // The difficulty with this operation is that the hardware does not support
58 // unlocking single blocks.  However, the logical layer would like this to
59 // be the case, so this routine emulates it.  The hardware can clear all of
60 // the locks in the device at once.  This routine will use that approach and
61 // then reset the regions which are known to be locked.
62 //
63
64 #define FLASH_LOCK_MASK 0x1    // which bit of the read query has the lock bit
65
66 int
67 flash_unlock_block(volatile flash_t *block, int block_size, int blocks)
68         __attribute__ ((section (".2ram.flash_unlock_block")));
69 int
70 flash_unlock_block(volatile flash_t *block, int block_size, int blocks)
71 {
72     volatile flash_t *ROM;
73     flash_t stat;
74     int timeout = 5000000;
75 #ifndef CYGOPT_FLASH_IS_SYNCHRONOUS
76     int i;
77     volatile flash_t *bp, *bpv;
78     unsigned char is_locked[CYGNUM_DEVS_FLASH_STRATA_MAX_BLOCKS];
79 #endif
80
81     // Get base address and map addresses to virtual addresses
82     ROM = FLASH_P2V( CYGNUM_FLASH_BASE_MASK & (unsigned int)block );
83     block = FLASH_P2V(block);
84
85     // Clear any error conditions
86     ROM[0] = FLASH_Clear_Status;
87
88 #ifdef CYGOPT_FLASH_IS_SYNCHRONOUS
89     // Clear lock bit
90     block[0] = FLASH_Clear_Locks;
91     block[0] = FLASH_Clear_Locks_Confirm;  // Confirmation
92     while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
93         if (--timeout == 0) break;
94     }
95 #else
96     // Get current block lock state.  This needs to access each block on
97     // the device so currently locked blocks can be re-locked.
98     bp = ROM;
99     for (i = 0;  i < blocks;  i++) {
100         bpv = FLASH_P2V( bp );
101         *bpv = FLASH_Read_Query;
102         if (bpv == block) {
103             is_locked[i] = 0;
104         } else {
105 #if 8 == CYGNUM_FLASH_WIDTH
106             is_locked[i] = bpv[4] & FLASH_LOCK_MASK;
107 #else
108             is_locked[i] = bpv[2] & FLASH_LOCK_MASK;
109 # endif
110         }
111         bp += block_size / sizeof(*bp);
112     }
113
114     // Clears all lock bits
115     ROM[0] = FLASH_Clear_Locks;
116     ROM[0] = FLASH_Clear_Locks_Confirm;  // Confirmation
117     timeout = 5000000;
118     while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
119         if (--timeout == 0) break;
120     }
121
122     // Restore the lock state
123     bp = ROM;
124     for (i = 0;  i < blocks;  i++) {
125         bpv = FLASH_P2V( bp );
126         if (is_locked[i]) {
127             *bpv = FLASH_Set_Lock;
128             *bpv = FLASH_Set_Lock_Confirm;  // Confirmation
129             timeout = 5000000;
130             while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
131                 if (--timeout == 0) break;
132             }
133         }
134         bp += block_size / sizeof(*bp);
135     }
136 #endif  // CYGOPT_FLASH_IS_SYNCHRONOUS
137
138     // Restore ROM to "normal" mode
139     ROM[0] = FLASH_Reset;
140
141     return stat;
142 }