• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/cfe/cfe/arch/mips/common/src/
1/*  *********************************************************************
2    *  Broadcom Common Firmware Environment (CFE)
3    *
4    *  Flash "self-write" module	File: dev_flashop_engine.S
5    *
6    *  This module takes care of the case of writing to the flash
7    *  memory that CFE is currently reading its code from.
8    *
9    *  Note: this code is written to be position-independent, even
10    *  for non-PIC versions of CFE!  It will be copied (with memcpy)
11    *  into the heap for execution.
12    *
13    *  Author:  Mitch Lichtenberg (mpl@broadcom.com)
14    *
15    *********************************************************************
16    *
17    *  Copyright 2000,2001,2002,2003
18    *  Broadcom Corporation. All rights reserved.
19    *
20    *  This software is furnished under license and may be used and
21    *  copied only in accordance with the following terms and
22    *  conditions.  Subject to these conditions, you may download,
23    *  copy, install, use, modify and distribute modified or unmodified
24    *  copies of this software in source and/or binary form.  No title
25    *  or ownership is transferred hereby.
26    *
27    *  1) Any source code used, modified or distributed must reproduce
28    *     and retain this copyright notice and list of conditions
29    *     as they appear in the source file.
30    *
31    *  2) No right is granted to use any trade name, trademark, or
32    *     logo of Broadcom Corporation.  The "Broadcom Corporation"
33    *     name may not be used to endorse or promote products derived
34    *     from this software without the prior written permission of
35    *     Broadcom Corporation.
36    *
37    *  3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
38    *     IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
39    *     WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
40    *     PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
41    *     SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
42    *     PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
43    *     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
44    *     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
45    *     GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
46    *     BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
47    *     OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
48    *     TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
49    *     THE POSSIBILITY OF SUCH DAMAGE.
50    ********************************************************************* */
51
52#include "sbmips.h"
53#include "mipsmacros.h"
54
55#include "bsp_config.h"
56#include "dev_newflash.h"
57
58/*  *********************************************************************
59    *  Macros
60    ********************************************************************* */
61
62#if defined(__MIPSEB) && defined(_MIPSEB_DATA_INVARIANT_)
63
64#ifdef	BCMHND74K
65
66#define FLASHCMD_8(base,offset,value) \
67	li	t0,value 	; \
68	ADD	base,((offset)<<1) ; \
69	xori	base,7 		; \
70	sb	t0,0(base) 	; \
71	xori	base,7 		; \
72	SUB	base,((offset)<<1)
73
74#define FLASHCMD_16(base,offset,value) \
75	li	t0,value 	; \
76	ADD	base,((offset)<<1) ; \
77	xori	base,6 		; \
78	sh	t0,0(base) 	; \
79	xori	base,6 		; \
80	SUB	base,((offset)<<1)
81
82#define FLASHCMD_16B(base,offset,value) \
83	li	t0,value 	; \
84	ADD	base,((offset)<<1) ; \
85	xori	base,7 		; \
86	sb	t0,0(base) 	; \
87	xori	base,7 		; \
88	SUB	base,((offset)<<1)
89
90#else	/* Not 74K, bcm33xx */
91
92#define FLASHCMD_8(base,offset,value) \
93	li	t0,value 	; \
94	ADD	base,((offset)<<1) ; \
95	xori	base,3 		; \
96	sb	t0,0(base) 	; \
97	xori	base,3 		; \
98	SUB	base,((offset)<<1)
99
100#define FLASHCMD_16(base,offset,value) \
101	li	t0,value 	; \
102	ADD	base,((offset)<<1) ; \
103	xori	base,2 		; \
104	sh	t0,0(base) 	; \
105	xori	base,2 		; \
106	SUB	base,((offset)<<1)
107
108#define FLASHCMD_16B(base,offset,value) \
109	li	t0,value 	; \
110	ADD	base,((offset)<<1) ; \
111	xori	base,3 		; \
112	sb	t0,0(base) 	; \
113	xori	base,3 		; \
114	SUB	base,((offset)<<1)
115
116#endif	/* BCMHND74K */
117
118#else
119
120#define FLASHCMD_8(base,offset,value) \
121	li	t0,value ;	      \
122	sb	t0,offset(base)
123
124#define FLASHCMD_16(base,offset,value) \
125	li	t0,value ;	      \
126	sh	t0,((offset)<<1)(base)
127
128#define FLASHCMD_16B(base,offset,value) \
129	li	t0,value ;	      \
130	sb	t0,((offset)<<1)(base)
131
132#endif
133
134/*  *********************************************************************
135    *  flashop_engine
136    *
137    *  This routine is written in a PIC method to allow us to do
138    *  flash operations without any help from CFE.  We need to do
139    *  this when we're not relocated and want to muck with the
140    *  flash we're running from.
141    *
142    *  This routine follows some simple instructions in a table,
143    *  so you can batch up the operations in one place.
144    *
145    *  Input parameters:
146    *  	   a0 - pointer to instruction list
147    *
148    *  Return value:
149    *  	   v0 - 0 if all instructions succeeded
150    *  	   else less than zero, # of failing instructions
151    ********************************************************************* */
152
153                .text
154
155#define reg_op		  t3
156#define reg_base	  t4
157#define reg_dest	  t5
158#define reg_src		  t6
159#define reg_cnt		  t7
160
161LEAF(flashop_engine)
162
163instloop:	LR	reg_op,FEINST_OP(a0)	   /* Load instruction */
164		LR	reg_base,FEINST_BASE(a0)
165		LR	reg_dest,FEINST_DEST(a0)
166		LR	reg_src,FEINST_SRC(a0)
167		LR	reg_cnt,FEINST_CNT(a0)
168		li	v0,0			   /* total of result values */
169		li	v1,0			   /* result for this function */
170
171#ifdef __long64
172		dli	t0,0x9000000000000000	   /* uncached - XKPHYS */
173		or	reg_base,t0		   /* so we can access flash beyond KSEG */
174#else
175		or	reg_base,K1BASE		   /* 32-bit, regular KSEG */
176#endif
177
178/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
179		bne	reg_op,FEOP_RETURN,99f	   /* Return to main prog */
180
181		j	ra
182/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
18399:		bne	reg_op,FEOP_REBOOT,99f	   /* restart system  */
184
185		li	t0,0xBFC00000		   /* jump to boot vector */
186		j	t0
187/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
18899:		bne	reg_op,FEOP_READ8,99f	   /* Read, 8-bit mode */
189
190		ADD	reg_src,reg_src,reg_base
191
1921:		lbu	t0,0(reg_src)		   /* Copy user data */
193		sb	t0,0(reg_dest)
194		ADD	reg_src,1
195		add	reg_dest,1
196		sub	reg_cnt,1
197		bgt	reg_cnt,zero,1b
198
199		b	nextinst
200/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
20199:		bne	reg_op,FEOP_READ16,99f	   /* Read, 16-bit mode */
202
203		ADD	reg_src,reg_src,reg_base
204
205		li	t0,1			   /* test bottom bit */
206		and	t0,t0,reg_src		   /* t0 == 1 if odd */
207		beq	t0,zero,1f		   /* no odd byte to worry about */
208
209		SUB	reg_src,reg_src,t0	   /* make even value */
210		lh	t0,0(reg_src)		   /* interesting byte is odd */
211#ifdef __MIPSEB
212		sb	t0,0(reg_dest)		   /* interesting byte in low 8 bits */
213#else
214		srl	t0,t0,8			   /* little endian */
215		sb	t0,0(reg_dest)		   /* interesting byte is high 8 bits */
216#endif
217
218		ADD	reg_src,2		   /* advance one word (we made addr even above) */
219		add	reg_dest,1		   /* dest always written by bytes */
220		sub	reg_cnt,1
221
2221:		beq	reg_cnt,zero,nextinst
223
224		lh	t0,0(reg_src)		   /* Copy user data */
225
226#ifdef __MIPSEB
227		sb	t0,1(reg_dest)		   /* Big endian to memory */
228		srl	t0,t0,8			   /* t0 = 0x1234 -> 0x12 0x34 */
229		sb	t0,0(reg_dest)
230#else
231		sb	t0,0(reg_dest)		   /* little endian */
232		srl	t0,t0,8			   /* t0 = 0x1234 -> 0x34 0x12 */
233		sb	t0,1(reg_dest)
234#endif
235
236		ADD	reg_src,2
237		add	reg_dest,2
238		sub	reg_cnt,2
239		bgt	reg_cnt,1,1b
240
241		beq	reg_cnt,zero,nextinst	   /* no straggler */
242
243		lh	t0,0(reg_src)		   /* interesting byte is odd */
244#ifdef __MIPSEB
245		srl	t0,t0,8			   /* little endian */
246		sb	t0,0(reg_dest)		   /* interesting byte in high 8 bits */
247#else
248		sb	t0,0(reg_dest)		   /* interesting byte is low 8 bits */
249#endif
250
251		b	nextinst
252/* CFI - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
253#if (FLASH_DRIVERS & FLASH_DRIVER_CFI)
25499:		bne	reg_op,FEOP_CFIQUERY8,99f   /* CFI Query 8-bit */
255
256		ADD	reg_src,reg_src,reg_base
257
258		FLASHCMD_8(reg_base,FLASH_CFI_QUERY_ADDR,FLASH_CFI_QUERY_MODE)
259
2601:		lbu	t0,0(reg_src)		   /* Copy CFI data */
261		sb	t0,0(reg_dest)
262		ADD	reg_src,1
263		add	reg_dest,1
264		sub	reg_cnt,1
265		bgt	reg_cnt,zero,1b
266
267		FLASHCMD_8(reg_base,FLASH_CFI_QUERY_ADDR,FLASH_CFI_QUERY_EXIT)
268
269		b	nextinst
270/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
27199:		bne	reg_op,FEOP_CFIQUERY16,99f   /* CFI Query 16-bit in word mode */
272
273		ADD	reg_src,reg_src,reg_base
274
275		FLASHCMD_16(reg_base,FLASH_CFI_QUERY_ADDR,FLASH_CFI_QUERY_MODE)
276
2771:		lh	t0,0(reg_src)		   /* Copy CFI data */
278		sb	t0,0(reg_dest)
279		ADD	reg_src,2
280		add	reg_dest,2
281		sub	reg_cnt,2
282		bgt	reg_cnt,zero,1b
283
284		FLASHCMD_16(reg_base,FLASH_CFI_QUERY_ADDR,FLASH_CFI_QUERY_EXIT)
285
286		b	nextinst
287/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
28899:		bne	reg_op,FEOP_CFIQUERY16B,99f   /* CFI Query 16-bit in byte mode */
289
290		ADD	reg_src,reg_src,reg_base
291
292		FLASHCMD_16B(reg_base,FLASH_CFI_QUERY_ADDR,FLASH_CFI_QUERY_MODE)
293
2941:		lb	t0,0(reg_src)		   /* Copy CFI data */
295		sb	t0,0(reg_dest)
296		ADD	reg_src,1
297		add	reg_dest,1
298		sub	reg_cnt,1
299		bgt	reg_cnt,zero,1b
300
301		FLASHCMD_16B(reg_base,FLASH_CFI_QUERY_ADDR,FLASH_CFI_QUERY_EXIT)
302
303		b	nextinst
304#endif
305
306/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
30799:		bne	reg_op,FEOP_MEMCPY,99f   /* Generic memcpy */
308
3091:		lbu	t0,0(reg_src)
310		sb	t0,0(reg_dest)
311		add	reg_src,1
312		add	reg_dest,1
313		sub	reg_cnt,1
314		bgt	reg_cnt,zero,1b
315
316		b	nextinst
317
318
319/* AMD  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
320#if (FLASH_DRIVERS & FLASH_DRIVER_AMD)
32199:		bne	reg_op,FEOP_AMD_ERASE8,99f   /* AMD erase (8-bit) */
322
323		ADD	reg_dest,reg_dest,reg_base
324
325	/* Do an "unlock write" sequence  (cycles 1-2) */
326
327		FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
328		FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
329
330	/* send the erase command (cycle 3) */
331
332		FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_ERASE_3)
333
334	/* Do an "unlock write" sequence (cycles 4-5) */
335
336		FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
337		FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
338
339        /* Send the "erase sector" qualifier (cycle 6) */
340
341		FLASHCMD_8(reg_dest,0,AMD_FLASH_ERASE_SEC_6)
342
343	/* Wait for the erase to complete */
344
3451:		lb	t0,0(reg_dest)		# get byte
346		and	t0,0xFF			# test hi byte
347		bne	t0,0xFF,1b		# go till bit is set
348
349		b	nextinst
350/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
35199:		bne	reg_op,FEOP_AMD_ERASE16,99f   /* AMD erase (16-bit in word mode) */
352
353		ADD	reg_dest,reg_dest,reg_base
354
355	/* Do an "unlock write" sequence  (cycles 1-2) */
356
357		FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
358		FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
359
360	/* send the erase command (cycle 3) */
361
362		FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_ERASE_3)
363
364	/* Do an "unlock write" sequence (cycles 4-5) */
365
366		FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
367		FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
368
369        /* Send the "erase sector" qualifier (cycle 6) */
370
371		FLASHCMD_16(reg_dest,0,AMD_FLASH_ERASE_SEC_6)
372
373	/* Wait for the erase to complete */
374
3751:		lh	t0,0(reg_dest)		# get word
376		and	t0,0xFF			# test byte
377		bne	t0,0xFF,1b		# go till erased
378
379		b	nextinst
380
381/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
38299:		bne	reg_op,FEOP_AMD_ERASE16B,99f   /* AMD erase (16-bit in byte mode) */
383
384		ADD	reg_dest,reg_dest,reg_base
385
386	/* Do an "unlock write" sequence  (cycles 1-2) */
387
388		FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
389		FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
390
391	/* send the erase command (cycle 3) */
392
393		FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_ERASE_3)
394
395	/* Do an "unlock write" sequence (cycles 4-5) */
396
397		FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
398		FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
399
400        /* Send the "erase sector" qualifier (cycle 6) */
401
402		FLASHCMD_16B(reg_dest,0,AMD_FLASH_ERASE_SEC_6)
403
404	/* Wait for the erase to complete */
405
4061:		lh	t0,0(reg_dest)		# get word
407		and	t0,0xFF			# test byte
408		bne	t0,0xFF,1b		# go till erased
409
410		b	nextinst
411/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
41299:		bne	reg_op,FEOP_AMD_PGM8,99f	/* AMD 8-bit program */
413
414		ADD	reg_dest,reg_dest,reg_base
415
416	/* Do an "unlock write" sequence  (cycles 1-2) */
41711:
418		FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
419		FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
420
421	/* Send a program command (cycle 3) */
422
423	 	FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_PROGRAM)
424
425	/* Write a byte (cycle 4) */
426
427		lbu	t0,0(reg_src)
428		sb	t0,0(reg_dest)	# t0 = byte written to flash
429
430	/* Wait for write to complete */
431
4321:		lbu	t2,0(reg_dest)	# t2 = byte from flash
433
434		and	t1,t2,0x80	# done if bit7 of flash
435		and	t0,t0,0x80	# is same as bit7 of data
436		beq	t1,t0,2f
437
438		and	t1,t2,0x20	# not done if bit5
439		bne	t1,0x20,1b	# is still set
4402:
441
442	/* next byte...	 */
443
444		add	reg_src,1	# next source byte
445		ADD	reg_dest,1	# next dest byte
446		sub	reg_cnt,1	# one less count
447		bgt	reg_cnt,0,11b
448
449
450		b	nextinst
451/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
45299:		bne	reg_op,FEOP_AMD_PGM16,99f	/* AMD 16-bit program */
453
454		ADD	reg_dest,reg_dest,reg_base
455
456	/* Do an "unlock write" sequence  (cycles 1-2) */
45711:
458		FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
459		FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
460
461	/* Send a program command (cycle 3) */
462
463	 	FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_PROGRAM)
464
465	/* Write a byte (cycle 4) */
466
467		lh	t0,0(reg_src)
468		sh	t0,0(reg_dest)	# t0 = byte written to flash
469
470	/* Wait for write to complete */
471
4721:		lh	t2,0(reg_dest)	# t2 = byte from flash
473
474		and	t1,t2,0x80	# done if bit7 of flash
475		and	t0,t0,0x80	# is same as bit7 of data
476		beq	t1,t0,2f
477
478		and	t1,t2,0x20	# not done if bit5
479		bne	t1,0x20,1b	# is still set
4802:
481
482	/* next byte...	 */
483
484		add	reg_src,2	# next source word
485		ADD	reg_dest,2	# next dest word
486		sub	reg_cnt,2	# one less count
487		bgt	reg_cnt,0,11b
488
489		b	nextinst
490/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
49199:		bne	reg_op,FEOP_AMD_PGM16B,99f	/* AMD 16-bit pgm in 8-bit mode */
492
493		ADD	reg_dest,reg_dest,reg_base
494
495	/* Do an "unlock write" sequence  (cycles 1-2) */
49611:
497		FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
498		FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
499
500	/* Send a program command (cycle 3) */
501
502	 	FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_PROGRAM)
503
504	/* Write a byte (cycle 4) */
505
506		lb	t0,0(reg_src)
507		sb	t0,0(reg_dest)	# t0 = byte written to flash
508
509	/* Wait for write to complete */
510
5111:		lb	t2,0(reg_dest)	# t2 = byte from flash
512
513		and	t1,t2,0x80	# done if bit7 of flash
514		and	t0,t0,0x80	# is same as bit7 of data
515		beq	t1,t0,2f
516
517		and	t1,t2,0x20	# not done if bit5
518		bne	t1,0x20,1b	# is still set
5192:
520
521	/* next byte...	 */
522
523		add	reg_src,1	# next source word
524		ADD	reg_dest,1	# next dest word
525		sub	reg_cnt,1	# one less count
526		bgt	reg_cnt,0,11b
527
528		b	nextinst
529
530/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
53199:           bne     reg_op,FEOP_AMD_DEVCODE8,99f   /* AMD 8-bit - Boot Block Location */
532
533              ADD     reg_src,reg_src,reg_base
534
535              FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
536              FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
537              FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_AUTOSEL)
538
539              lbu     t0,AMD_FLASH_DEVCODE8(reg_src)
540              sb      t0,0(reg_dest)
541              li      t0,AMD_FLASH_RESET
542              sb      t0,0(reg_src)
543
544
545              b       nextinst
546/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
54799:           bne     reg_op,FEOP_AMD_DEVCODE16,99f   /* AMD 8-bit - Boot Block Location */
548
549              ADD     reg_src,reg_src,reg_base
550
551              FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
552              FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
553              FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_AUTOSEL)
554
555              lw      t0,0(reg_src)
556#ifdef __MIPSEB
557	      srl     t0,t0,8	/* ((3-AMD_FLASH_DEVCODE16)*8) */
558#else
559	      srl     t0,t0,16	/* (AMD_FLASH_DEVCODE16*8) */
560#endif
561              sb      t0,0(reg_dest)
562              li      t0,AMD_FLASH_RESET
563              sb      t0,0(reg_src)
564
565              b       nextinst
566/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
56799:           bne     reg_op,FEOP_AMD_DEVCODE16B,99f   /* AMD 8-bit - Boot Block Location */
568
569              ADD     reg_src,reg_src,reg_base
570
571              FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
572              FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
573              FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_AUTOSEL)
574
575              lw      t0,0(reg_src)
576#ifdef __MIPSEB
577#else
578	      srl     t0,t0,16			/* (AMD_FLASH_DEVCODE16B*8)*/
579#endif
580
581              sb      t0,0(reg_dest)
582              li      t0,AMD_FLASH_RESET
583              sb      t0,0(reg_src)
584
585              b       nextinst
586/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
58799:           bne     reg_op,FEOP_AMD_MANID8,99f   /* AMD 8-bit - Boot Block Location */
588
589              ADD     reg_src,reg_src,reg_base
590
591              FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
592              FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
593              FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_AUTOSEL)
594
595              lbu     t0,AMD_FLASH_MANID(reg_src)
596              sb      t0,0(reg_dest)
597              li      t0,AMD_FLASH_RESET
598              sb      t0,0(reg_src)
599
600
601              b       nextinst
602/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
60399:           bne     reg_op,FEOP_AMD_MANID16,99f   /* AMD 8-bit - Boot Block Location */
604
605              ADD     reg_src,reg_src,reg_base
606
607              FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
608              FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
609              FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_AUTOSEL)
610
611              lw      t0,0(reg_src)
612#ifdef __MIPSEB
613	      srl     t0,t0,((3-AMD_FLASH_MANID)*8)
614#else
615	      srl     t0,t0,(AMD_FLASH_MANID*8)
616#endif
617              sb      t0,0(reg_dest)
618              li      t0,AMD_FLASH_RESET
619              sb      t0,0(reg_src)
620
621              b       nextinst
622/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
62399:           bne     reg_op,FEOP_AMD_MANID16B,99f   /* AMD 8-bit - Boot Block Location */
624
625              ADD     reg_src,reg_src,reg_base
626
627              FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
628              FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
629              FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_AUTOSEL)
630
631              lbu     t0,AMD_FLASH_MANID(reg_src)
632
633              sb      t0,0(reg_dest)
634              li      t0,AMD_FLASH_RESET
635              sb      t0,0(reg_src)
636
637              b       nextinst
638
639#endif
640
641/* INTEL  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
642#if (FLASH_DRIVERS & FLASH_DRIVER_INTEL)
64399:		bne	reg_op,FEOP_INTEL_ERASE8,99f	/* Intel erase 8-bit */
644
645		ADD	reg_dest,reg_dest,reg_base
646
647		FLASHCMD_8(reg_dest,0,INTEL_FLASH_ERASE_BLOCK)
648		FLASHCMD_8(reg_dest,0,INTEL_FLASH_ERASE_CONFIRM)
649
6501:		lbu	t0,0(reg_dest)	/* loop till bit 7 is set */
651		andi	t0,0x80
652		beq	t0,zero,1b
653
654		FLASHCMD_8(reg_dest,0,INTEL_FLASH_READ_MODE)
655
656		b	nextinst
657/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
65899:		bne	reg_op,FEOP_INTEL_ERASE16,99f	/* Intel erase 16-bit */
659
660		ADD	reg_dest,reg_dest,reg_base
661
662
663		FLASHCMD_8(reg_dest,0,INTEL_FLASH_ERASE_BLOCK)
664		FLASHCMD_8(reg_dest,0,INTEL_FLASH_ERASE_CONFIRM)
665
6661:		lbu	t0,0(reg_dest)	/* loop till bit 7 is set */
667		andi	t0,0x80
668		beq	t0,zero,1b
669
670		FLASHCMD_8(reg_dest,0,INTEL_FLASH_READ_MODE)
671
672		b	nextinst
673/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
67499:		bne	reg_op,FEOP_INTEL_PGM8,99f     /* Intel 8-bit program */
675
676		ADD	reg_dest,reg_dest,reg_base
677
67811:		FLASHCMD_8(reg_dest,0,INTEL_FLASH_PROGRAM)
679
680		lbu	t0,0(reg_src)
681		sb	t0,0(reg_dest)
682
6831:		lbu	t0,0(reg_dest)	/* loop till bit 7 is set */
684		andi	t0,0x80
685		beq	t0,zero,1b
686
687		lbu	t0,0(reg_dest)	/* contains final result */
688		/* If good, bits 1, 3, 4 will not be set */
689
690		add     reg_src,1
691		ADD     reg_dest,1
692		sub     reg_cnt,1
693		bgt	reg_cnt,zero,11b
694
695		FLASHCMD_8(reg_dest,0,INTEL_FLASH_READ_MODE)
696
697		b	nextinst
698/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
69999:		bne	reg_op,FEOP_INTEL_PGM16,99f    /* Intel 16-bit prog */
700
701		ADD	reg_dest,reg_dest,reg_base
702
70311:		FLASHCMD_16(reg_dest,0,INTEL_FLASH_PROGRAM)
704
705		lh	t0,0(reg_src)
706		sh	t0,0(reg_dest)
707
7081:		lh	t0,0(reg_dest)	/* loop till bit 7 is set */
709		andi	t0,0x80
710		beq	t0,zero,1b
711
712		lh	t0,0(reg_dest)	/* contains final result */
713		/* If good, bits 1, 3, 4 will not be set */
714
715		FLASHCMD_16(reg_dest,0,INTEL_FLASH_READ_MODE)
716
717		add     reg_src,2
718		ADD     reg_dest,2
719		sub     reg_cnt,2
720		bgt	reg_cnt,zero,11b
721
722		b	nextinst
723#endif
724/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
725#if (FLASH_DRIVERS & FLASH_DRIVER_SST)
72699:		bne	reg_op,FEOP_SST_CFIQUERY16,99f   /* SST CFI Query 16-bit in word mode */
727
728		ADD	reg_src,reg_src,reg_base
729
730		FLASHCMD_16(reg_base,SST_FLASH_MAGIC_ADDR_1,SST_FLASH_MAGIC_1)
731		FLASHCMD_16(reg_base,SST_FLASH_MAGIC_ADDR_2,SST_FLASH_MAGIC_2)
732
733                FLASHCMD_16(reg_base,0x5555,FLASH_CFI_QUERY_MODE)
734
7351:		lh	t0,0(reg_src)		   /* Copy CFI data */
736		sb	t0,0(reg_dest)
737		ADD	reg_src,2
738		add	reg_dest,2
739		sub	reg_cnt,2
740		bgt	reg_cnt,zero,1b
741
742		FLASHCMD_16(reg_base,FLASH_CFI_QUERY_ADDR,SST_FLASH_RESET)
743
744		b	nextinst
745/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
74699:		bne	reg_op,FEOP_SST_ERASE16,99f   /* SST erase (16-bit in word mode) */
747
748		ADD	reg_dest,reg_dest,reg_base
749
750	/* Do an "unlock write" sequence  (cycles 1-2) */
751
752		FLASHCMD_16(reg_base,SST_FLASH_MAGIC_ADDR_1,SST_FLASH_MAGIC_1)
753		FLASHCMD_16(reg_base,SST_FLASH_MAGIC_ADDR_2,SST_FLASH_MAGIC_2)
754
755	/* send the erase command (cycle 3) */
756
757		FLASHCMD_16(reg_base,SST_FLASH_MAGIC_ADDR_1,SST_FLASH_ERASE_3)
758
759	/* Do an "unlock write" sequence (cycles 4-5) */
760
761		FLASHCMD_16(reg_base,SST_FLASH_MAGIC_ADDR_1,SST_FLASH_MAGIC_1)
762		FLASHCMD_16(reg_base,SST_FLASH_MAGIC_ADDR_2,SST_FLASH_MAGIC_2)
763
764        /* Send the "erase sector" qualifier (cycle 6) */
765
766		FLASHCMD_16(reg_dest,0,SST_FLASH_ERASE_SEC_6)
767
768	/* Wait for the erase to complete */
769
7701:		lh	t0,0(reg_dest)		# get word
771		and	t0,0xFF			# test byte
772		bne	t0,0xFF,1b		# go till erased
773
774		b	nextinst
775/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
77699:		bne	reg_op,FEOP_SST_PGM16,99f	/* SST 16-bit program */
777
778		ADD	reg_dest,reg_dest,reg_base
779
780	/* Do an "unlock write" sequence  (cycles 1-2) */
78111:
782		FLASHCMD_16(reg_base,SST_FLASH_MAGIC_ADDR_1,SST_FLASH_MAGIC_1)
783		FLASHCMD_16(reg_base,SST_FLASH_MAGIC_ADDR_2,SST_FLASH_MAGIC_2)
784
785	/* Send a program command (cycle 3) */
786
787	 	FLASHCMD_16(reg_base,SST_FLASH_MAGIC_ADDR_1,SST_FLASH_PROGRAM)
788
789	/* Write a short (cycle 4) */
790
791		lh	t0,0(reg_src)
792		sh	t0,0(reg_dest)	# t0 = byte written to flash
793
794	/* Wait for write to complete */
795
7961:		lh	t2,0(reg_dest)	# t2 = byte from flash
797
798		and	t1,t2,0x80	# done if bit7 of flash
799		and	t0,t0,0x80	# is same as bit7 of data
800		bne	t1,t0,1b
801
802
803	/* next short...	 */
804
805		add	reg_src,2	# next source word
806		ADD	reg_dest,2	# next dest word
807		sub	reg_cnt,2	# one less count
808		bgt	reg_cnt,0,11b
809
810		b	nextinst
811#endif
812/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
81399:		li      v1,-1			  /* invalid command */
814
815nextinst:	SR	v1,FEINST_RESULT(a0)	  /* store result of instruction */
816		ADD	v0,v0,v1		  /* add to total */
817		ADD	a0,FEINST_SIZE		  /* advance to next instr. */
818		b	instloop
819
820flashop_engine_end:
821		nop
822
823END(flashop_engine)
824
825		.sdata
826
827		.globl	flashop_engine_ptr
828		.globl	flashop_engine_len
829
830flashop_engine_ptr:
831		_VECT_	flashop_engine
832flashop_engine_len:
833		.word	flashop_engine_end-flashop_engine
834
835
836
837/*  *********************************************************************
838    *  end
839    ********************************************************************* */
840