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