1 #include <string.h>
2 #include <stdlib.h>
3 #include <time.h>
4 #include <pthread.h>
5 #include <errno.h>
6 #include <unistd.h>
7 #include <hal_timer.h>
8 #include <hal_cmd.h>
9 
10 #include "inter.h"
11 
12 #define NOR_CMD_BLK_LOCK_ALL (0x7E)
13 #define NOR_CMD_BLK_UNLOCK_ALL (0x98)
14 
15 /* #define DEBUG_WRLOCK */
16 
17 #ifdef DEBUG_WRLOCK
18 int skip_lock = 0;
19 #endif
20 
nor_wr_lock_init(struct nor_flash * nor)21 int nor_wr_lock_init(struct nor_flash *nor)
22 {
23     if (nor->factory->init_lock)
24         return nor->factory->init_lock(nor);
25     return 0;
26 }
27 
nor_wr_lock_deinit(struct nor_flash * nor)28 void nor_wr_lock_deinit(struct nor_flash *nor)
29 {
30     if (nor->factory->deinit_lock)
31         nor->factory->deinit_lock(nor);
32 }
33 
nor_wr_islock(struct nor_flash * nor,unsigned int addr,unsigned int len)34 bool nor_wr_islock(struct nor_flash *nor, unsigned int addr, unsigned int len)
35 {
36     unsigned int align_size;
37     unsigned int align_addr;
38     bool ret = false;
39 
40     if (nor->factory->islock) {
41         while (len) {
42             /* the first and the last block (64K) is lock on sector (4K) unit */
43             if (addr >= nor->total_size - SZ_64K || addr < SZ_64K)
44                 align_size = SZ_4K;
45             else
46                 align_size = SZ_64K;
47             align_addr = ALIGN_DOWN(addr, align_size);
48 
49             ret = nor->factory->islock(nor, align_addr, align_size);
50             if (ret)
51                 break;
52 
53             len -= MIN(align_size, len);
54             addr += MIN(align_size, len);
55         }
56     }
57     return ret;
58 }
59 
nor_wr_lock(struct nor_flash * nor,unsigned int addr,unsigned int len)60 int nor_wr_lock(struct nor_flash *nor, unsigned int addr, unsigned int len)
61 {
62     unsigned int align_size;
63     unsigned int align_addr;
64     int ret = 0;
65 
66 #ifdef DEBUG_WRLOCK
67     if (skip_lock == 1) {
68         printf("skip handle lock\n");
69         return 0;
70     }
71 #endif
72 
73     if (nor->factory->lock) {
74         while (len) {
75             /* the first and the last block (64K) is lock on sector (4K) unit */
76             if (addr >= nor->total_size - SZ_64K || addr < SZ_64K)
77                 align_size = SZ_4K;
78             else
79                 align_size = SZ_64K;
80             align_addr = ALIGN_DOWN(addr, align_size);
81 
82             ret = nor->factory->lock(nor, align_addr, align_size);
83             if (ret)
84                 break;
85 
86             len -= MIN(align_size, len);
87             addr += MIN(align_size, len);
88         }
89     }
90     return ret;
91 }
92 
nor_wr_unlock(struct nor_flash * nor,unsigned int addr,unsigned int len)93 int nor_wr_unlock(struct nor_flash *nor, unsigned int addr, unsigned int len)
94 {
95     unsigned int align_size;
96     unsigned int align_addr;
97     int ret = 0;
98 
99 #ifdef DEBUG_WRLOCK
100     if (skip_lock == 1) {
101         printf("skip handle lock\n");
102         return 0;
103     }
104 #endif
105 
106     if (nor->factory->unlock) {
107         while (len) {
108             /* the first and the last block (64K) is lock on sector (4K) unit */
109             if (addr >= nor->total_size - SZ_64K || addr < SZ_64K)
110                 align_size = SZ_4K;
111             else
112                 align_size = SZ_64K;
113             align_addr = ALIGN_DOWN(addr, align_size);
114 
115             ret = nor->factory->unlock(nor, align_addr, align_size);
116             if (ret)
117                 break;
118 
119             len -= MIN(align_size, len);
120             addr += MIN(align_size, len);
121         }
122     }
123     return ret;
124 }
125 
nor_wr_unlock_all(struct nor_flash * nor)126 int nor_wr_unlock_all(struct nor_flash *nor)
127 {
128     int ret;
129 
130 #ifdef DEBUG_WRLOCK
131     if (skip_lock == 1) {
132         printf("skip handle lock\n");
133         return 0;
134     }
135 #endif
136 
137     ret = nor_write_enable();
138     if (ret)
139         return ret;
140 
141     ret = nor_send_cmd(NOR_CMD_BLK_UNLOCK_ALL);
142     if (ret) {
143         SPINOR_ERR("unlock all block failed - %d\n", ret);
144         return ret;
145     }
146     return 0;
147 }
148 
nor_wr_lock_all(struct nor_flash * nor)149 int nor_wr_lock_all(struct nor_flash *nor)
150 {
151     int ret;
152 
153 #ifdef DEBUG_WRLOCK
154     if (skip_lock == 1) {
155         printf("skip handle lock\n");
156         return 0;
157     }
158 #endif
159 
160     ret = nor_write_enable();
161     if (ret)
162         return ret;
163 
164     ret = nor_send_cmd(NOR_CMD_BLK_LOCK_ALL);
165     if (ret) {
166         SPINOR_ERR("lock all block failed - %d\n", ret);
167         return ret;
168     }
169     return 0;
170 }
171 
172 
173 #ifdef DEBUG_WRLOCK
cmd_skip_lock(int argc,char ** argv)174 int cmd_skip_lock(int argc, char ** argv)
175 {
176     printf("skip lock\n");
177     skip_lock = 1;
178 }
FINSH_FUNCTION_EXPORT_CMD(cmd_skip_lock,skip_lock,skip lock)179 FINSH_FUNCTION_EXPORT_CMD(cmd_skip_lock, skip_lock, skip lock)
180 
181 int cmd_not_skip_lock(int argc, char ** argv)
182 {
183     printf("not skip lock\n");
184     skip_lock = 0;
185 }
186 FINSH_FUNCTION_EXPORT_CMD(cmd_not_skip_lock, not_skip_lock, not skip lock)
187 #endif
188