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#define FLASHCMD_8(base,offset,value) \
65	li	t0,value 	; \
66	ADD	base,((offset)<<1) ; \
67	xori	base,3 		; \
68	sb	t0,0(base) 	; \
69	xori	base,3 		; \
70	SUB	base,((offset)<<1)
71
72#define FLASHCMD_16(base,offset,value) \
73	li	t0,value 	; \
74	ADD	base,((offset)<<1) ; \
75	xori	base,2 		; \
76	sh	t0,0(base) 	; \
77	xori	base,2 		; \
78	SUB	base,((offset)<<1)
79
80#define FLASHCMD_16B(base,offset,value) \
81	li	t0,value 	; \
82	ADD	base,((offset)<<1) ; \
83	xori	base,3 		; \
84	sb	t0,0(base) 	; \
85	xori	base,3 		; \
86	SUB	base,((offset)<<1)
87
88#else
89
90#define FLASHCMD_8(base,offset,value) \
91	li	t0,value ;	      \
92	sb	t0,offset(base)
93
94#define FLASHCMD_16(base,offset,value) \
95	li	t0,value ;	      \
96	sh	t0,((offset)<<1)(base)
97
98#define FLASHCMD_16B(base,offset,value) \
99	li	t0,value ;	      \
100	sb	t0,((offset)<<1)(base)
101
102#endif
103
104/*  *********************************************************************
105    *  flashop_engine
106    *
107    *  This routine is written in a PIC method to allow us to do
108    *  flash operations without any help from CFE.  We need to do
109    *  this when we're not relocated and want to muck with the
110    *  flash we're running from.
111    *
112    *  This routine follows some simple instructions in a table,
113    *  so you can batch up the operations in one place.
114    *
115    *  Input parameters:
116    *  	   a0 - pointer to instruction list
117    *
118    *  Return value:
119    *  	   v0 - 0 if all instructions succeeded
120    *  	   else less than zero, # of failing instructions
121    ********************************************************************* */
122
123                .text
124
125#define reg_op		  t3
126#define reg_base	  t4
127#define reg_dest	  t5
128#define reg_src		  t6
129#define reg_cnt		  t7
130
131LEAF(flashop_engine)
132
133instloop:	LR	reg_op,FEINST_OP(a0)	   /* Load instruction */
134		LR	reg_base,FEINST_BASE(a0)
135		LR	reg_dest,FEINST_DEST(a0)
136		LR	reg_src,FEINST_SRC(a0)
137		LR	reg_cnt,FEINST_CNT(a0)
138		li	v0,0			   /* total of result values */
139		li	v1,0			   /* result for this function */
140
141#ifdef __long64
142		dli	t0,0x9000000000000000	   /* uncached - XKPHYS */
143		or	reg_base,t0		   /* so we can access flash beyond KSEG */
144#else
145		or	reg_base,K1BASE		   /* 32-bit, regular KSEG */
146#endif
147
148/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
149		bne	reg_op,FEOP_RETURN,99f	   /* Return to main prog */
150
151		j	ra
152/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
15399:		bne	reg_op,FEOP_REBOOT,99f	   /* restart system  */
154
155		li	t0,0xBFC00000		   /* jump to boot vector */
156		j	t0
157/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
15899:		bne	reg_op,FEOP_READ8,99f	   /* Read, 8-bit mode */
159
160		ADD	reg_src,reg_src,reg_base
161
1621:		lbu	t0,0(reg_src)		   /* Copy user data */
163		sb	t0,0(reg_dest)
164		ADD	reg_src,1
165		add	reg_dest,1
166		sub	reg_cnt,1
167		bgt	reg_cnt,zero,1b
168
169		b	nextinst
170/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
17199:		bne	reg_op,FEOP_READ16,99f	   /* Read, 16-bit mode */
172
173		ADD	reg_src,reg_src,reg_base
174
175		li	t0,1			   /* test bottom bit */
176		and	t0,t0,reg_src		   /* t0 == 1 if odd */
177		beq	t0,zero,1f		   /* no odd byte to worry about */
178
179		SUB	reg_src,reg_src,t0	   /* make even value */
180		lh	t0,0(reg_src)		   /* interesting byte is odd */
181#ifdef __MIPSEB
182		sb	t0,0(reg_dest)		   /* interesting byte in low 8 bits */
183#else
184		srl	t0,t0,8			   /* little endian */
185		sb	t0,0(reg_dest)		   /* interesting byte is high 8 bits */
186#endif
187
188		ADD	reg_src,2		   /* advance one word (we made addr even above) */
189		add	reg_dest,1		   /* dest always written by bytes */
190		sub	reg_cnt,1
191
1921:		beq	reg_cnt,zero,nextinst
193
194		lh	t0,0(reg_src)		   /* Copy user data */
195
196#ifdef __MIPSEB
197		sb	t0,1(reg_dest)		   /* Big endian to memory */
198		srl	t0,t0,8			   /* t0 = 0x1234 -> 0x12 0x34 */
199		sb	t0,0(reg_dest)
200#else
201		sb	t0,0(reg_dest)		   /* little endian */
202		srl	t0,t0,8			   /* t0 = 0x1234 -> 0x34 0x12 */
203		sb	t0,1(reg_dest)
204#endif
205
206		ADD	reg_src,2
207		add	reg_dest,2
208		sub	reg_cnt,2
209		bgt	reg_cnt,1,1b
210
211		beq	reg_cnt,zero,nextinst	   /* no straggler */
212
213		lh	t0,0(reg_src)		   /* interesting byte is odd */
214#ifdef __MIPSEB
215		srl	t0,t0,8			   /* little endian */
216		sb	t0,0(reg_dest)		   /* interesting byte in high 8 bits */
217#else
218		sb	t0,0(reg_dest)		   /* interesting byte is low 8 bits */
219#endif
220
221		b	nextinst
222/* CFI - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
223#if (FLASH_DRIVERS & FLASH_DRIVER_CFI)
22499:		bne	reg_op,FEOP_CFIQUERY8,99f   /* CFI Query 8-bit */
225
226		ADD	reg_src,reg_src,reg_base
227
228		FLASHCMD_8(reg_base,FLASH_CFI_QUERY_ADDR,FLASH_CFI_QUERY_MODE)
229
2301:		lbu	t0,0(reg_src)		   /* Copy CFI data */
231		sb	t0,0(reg_dest)
232		ADD	reg_src,1
233		add	reg_dest,1
234		sub	reg_cnt,1
235		bgt	reg_cnt,zero,1b
236
237		FLASHCMD_8(reg_base,FLASH_CFI_QUERY_ADDR,FLASH_CFI_QUERY_EXIT)
238
239		b	nextinst
240/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
24199:		bne	reg_op,FEOP_CFIQUERY16,99f   /* CFI Query 16-bit in word mode */
242
243		ADD	reg_src,reg_src,reg_base
244
245		FLASHCMD_16(reg_base,FLASH_CFI_QUERY_ADDR,FLASH_CFI_QUERY_MODE)
246
2471:		lh	t0,0(reg_src)		   /* Copy CFI data */
248		sb	t0,0(reg_dest)
249		ADD	reg_src,2
250		add	reg_dest,2
251		sub	reg_cnt,2
252		bgt	reg_cnt,zero,1b
253
254		FLASHCMD_16(reg_base,FLASH_CFI_QUERY_ADDR,FLASH_CFI_QUERY_EXIT)
255
256		b	nextinst
257/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
25899:		bne	reg_op,FEOP_CFIQUERY16B,99f   /* CFI Query 16-bit in byte mode */
259
260		ADD	reg_src,reg_src,reg_base
261
262		FLASHCMD_16B(reg_base,FLASH_CFI_QUERY_ADDR,FLASH_CFI_QUERY_MODE)
263
2641:		lb	t0,0(reg_src)		   /* Copy CFI data */
265		sb	t0,0(reg_dest)
266		ADD	reg_src,1
267		add	reg_dest,1
268		sub	reg_cnt,1
269		bgt	reg_cnt,zero,1b
270
271		FLASHCMD_16B(reg_base,FLASH_CFI_QUERY_ADDR,FLASH_CFI_QUERY_EXIT)
272
273		b	nextinst
274#endif
275
276/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
27799:		bne	reg_op,FEOP_MEMCPY,99f   /* Generic memcpy */
278
2791:		lbu	t0,0(reg_src)
280		sb	t0,0(reg_dest)
281		add	reg_src,1
282		add	reg_dest,1
283		sub	reg_cnt,1
284		bgt	reg_cnt,zero,1b
285
286		b	nextinst
287
288
289/* AMD  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
290#if (FLASH_DRIVERS & FLASH_DRIVER_AMD)
29199:		bne	reg_op,FEOP_AMD_ERASE8,99f   /* AMD erase (8-bit) */
292
293		ADD	reg_dest,reg_dest,reg_base
294
295	/* Do an "unlock write" sequence  (cycles 1-2) */
296
297		FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
298		FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
299
300	/* send the erase command (cycle 3) */
301
302		FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_ERASE_3)
303
304	/* Do an "unlock write" sequence (cycles 4-5) */
305
306		FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
307		FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
308
309        /* Send the "erase sector" qualifier (cycle 6) */
310
311		FLASHCMD_8(reg_dest,0,AMD_FLASH_ERASE_SEC_6)
312
313	/* Wait for the erase to complete */
314
3151:		lb	t0,0(reg_dest)		# get byte
316		and	t0,0xFF			# test hi byte
317		bne	t0,0xFF,1b		# go till bit is set
318
319		b	nextinst
320/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
32199:		bne	reg_op,FEOP_AMD_ERASE16,99f   /* AMD erase (16-bit in word mode) */
322
323		ADD	reg_dest,reg_dest,reg_base
324
325	/* Do an "unlock write" sequence  (cycles 1-2) */
326
327		FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
328		FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
329
330	/* send the erase command (cycle 3) */
331
332		FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_ERASE_3)
333
334	/* Do an "unlock write" sequence (cycles 4-5) */
335
336		FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
337		FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
338
339        /* Send the "erase sector" qualifier (cycle 6) */
340
341		FLASHCMD_16(reg_dest,0,AMD_FLASH_ERASE_SEC_6)
342
343	/* Wait for the erase to complete */
344
3451:		lh	t0,0(reg_dest)		# get word
346		and	t0,0xFF			# test byte
347		bne	t0,0xFF,1b		# go till erased
348
349		b	nextinst
350
351/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
35299:		bne	reg_op,FEOP_AMD_ERASE16B,99f   /* AMD erase (16-bit in byte mode) */
353
354		ADD	reg_dest,reg_dest,reg_base
355
356	/* Do an "unlock write" sequence  (cycles 1-2) */
357
358		FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
359		FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
360
361	/* send the erase command (cycle 3) */
362
363		FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_ERASE_3)
364
365	/* Do an "unlock write" sequence (cycles 4-5) */
366
367		FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
368		FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
369
370        /* Send the "erase sector" qualifier (cycle 6) */
371
372		FLASHCMD_16B(reg_dest,0,AMD_FLASH_ERASE_SEC_6)
373
374	/* Wait for the erase to complete */
375
3761:		lh	t0,0(reg_dest)		# get word
377		and	t0,0xFF			# test byte
378		bne	t0,0xFF,1b		# go till erased
379
380		b	nextinst
381/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
38299:		bne	reg_op,FEOP_AMD_PGM8,99f	/* AMD 8-bit program */
383
384		ADD	reg_dest,reg_dest,reg_base
385
386	/* Do an "unlock write" sequence  (cycles 1-2) */
38711:
388		FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
389		FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
390
391	/* Send a program command (cycle 3) */
392
393	 	FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_PROGRAM)
394
395	/* Write a byte (cycle 4) */
396
397		lbu	t0,0(reg_src)
398		sb	t0,0(reg_dest)	# t0 = byte written to flash
399
400	/* Wait for write to complete */
401
4021:		lbu	t2,0(reg_dest)	# t2 = byte from flash
403
404		and	t1,t2,0x80	# done if bit7 of flash
405		and	t0,t0,0x80	# is same as bit7 of data
406		beq	t1,t0,2f
407
408		and	t1,t2,0x20	# not done if bit5
409		bne	t1,0x20,1b	# is still set
4102:
411
412	/* next byte...	 */
413
414		add	reg_src,1	# next source byte
415		ADD	reg_dest,1	# next dest byte
416		sub	reg_cnt,1	# one less count
417		bgt	reg_cnt,0,11b
418
419
420		b	nextinst
421/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
42299:		bne	reg_op,FEOP_AMD_PGM16,99f	/* AMD 16-bit program */
423
424		ADD	reg_dest,reg_dest,reg_base
425
426	/* Do an "unlock write" sequence  (cycles 1-2) */
42711:
428		FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
429		FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
430
431	/* Send a program command (cycle 3) */
432
433	 	FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_PROGRAM)
434
435	/* Write a byte (cycle 4) */
436
437		lh	t0,0(reg_src)
438		sh	t0,0(reg_dest)	# t0 = byte written to flash
439
440	/* Wait for write to complete */
441
4421:		lh	t2,0(reg_dest)	# t2 = byte from flash
443
444		and	t1,t2,0x80	# done if bit7 of flash
445		and	t0,t0,0x80	# is same as bit7 of data
446		beq	t1,t0,2f
447
448		and	t1,t2,0x20	# not done if bit5
449		bne	t1,0x20,1b	# is still set
4502:
451
452	/* next byte...	 */
453
454		add	reg_src,2	# next source word
455		ADD	reg_dest,2	# next dest word
456		sub	reg_cnt,2	# one less count
457		bgt	reg_cnt,0,11b
458
459		b	nextinst
460/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
46199:		bne	reg_op,FEOP_AMD_PGM16B,99f	/* AMD 16-bit pgm in 8-bit mode */
462
463		ADD	reg_dest,reg_dest,reg_base
464
465	/* Do an "unlock write" sequence  (cycles 1-2) */
46611:
467		FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
468		FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
469
470	/* Send a program command (cycle 3) */
471
472	 	FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_PROGRAM)
473
474	/* Write a byte (cycle 4) */
475
476		lb	t0,0(reg_src)
477		sb	t0,0(reg_dest)	# t0 = byte written to flash
478
479	/* Wait for write to complete */
480
4811:		lb	t2,0(reg_dest)	# t2 = byte from flash
482
483		and	t1,t2,0x80	# done if bit7 of flash
484		and	t0,t0,0x80	# is same as bit7 of data
485		beq	t1,t0,2f
486
487		and	t1,t2,0x20	# not done if bit5
488		bne	t1,0x20,1b	# is still set
4892:
490
491	/* next byte...	 */
492
493		add	reg_src,1	# next source word
494		ADD	reg_dest,1	# next dest word
495		sub	reg_cnt,1	# one less count
496		bgt	reg_cnt,0,11b
497
498		b	nextinst
499
500/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
50199:           bne     reg_op,FEOP_AMD_DEVCODE8,99f   /* AMD 8-bit - Boot Block Location */
502
503              ADD     reg_src,reg_src,reg_base
504
505              FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
506              FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
507              FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_AUTOSEL)
508
509              lbu     t0,AMD_FLASH_DEVCODE8(reg_src)
510              sb      t0,0(reg_dest)
511              li      t0,AMD_FLASH_RESET
512              sb      t0,0(reg_src)
513
514
515              b       nextinst
516/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
51799:           bne     reg_op,FEOP_AMD_DEVCODE16,99f   /* AMD 8-bit - Boot Block Location */
518
519              ADD     reg_src,reg_src,reg_base
520
521              FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
522              FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
523              FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_AUTOSEL)
524
525              lw      t0,0(reg_src)
526#ifdef __MIPSEB
527	      srl     t0,t0,8	/* ((3-AMD_FLASH_DEVCODE16)*8) */
528#else
529	      srl     t0,t0,16	/* (AMD_FLASH_DEVCODE16*8) */
530#endif
531              sb      t0,0(reg_dest)
532              li      t0,AMD_FLASH_RESET
533              sb      t0,0(reg_src)
534
535              b       nextinst
536/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
53799:           bne     reg_op,FEOP_AMD_DEVCODE16B,99f   /* AMD 8-bit - Boot Block Location */
538
539              ADD     reg_src,reg_src,reg_base
540
541              FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
542              FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
543              FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_AUTOSEL)
544
545              lw      t0,0(reg_src)
546#ifdef __MIPSEB
547#else
548	      srl     t0,t0,16			/* (AMD_FLASH_DEVCODE16B*8)*/
549#endif
550
551              sb      t0,0(reg_dest)
552              li      t0,AMD_FLASH_RESET
553              sb      t0,0(reg_src)
554
555              b       nextinst
556/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
55799:           bne     reg_op,FEOP_AMD_MANID8,99f   /* AMD 8-bit - Boot Block Location */
558
559              ADD     reg_src,reg_src,reg_base
560
561              FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
562              FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
563              FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_AUTOSEL)
564
565              lbu     t0,AMD_FLASH_MANID(reg_src)
566              sb      t0,0(reg_dest)
567              li      t0,AMD_FLASH_RESET
568              sb      t0,0(reg_src)
569
570
571              b       nextinst
572/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
57399:           bne     reg_op,FEOP_AMD_MANID16,99f   /* AMD 8-bit - Boot Block Location */
574
575              ADD     reg_src,reg_src,reg_base
576
577              FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
578              FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
579              FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_AUTOSEL)
580
581              lw      t0,0(reg_src)
582#ifdef __MIPSEB
583	      srl     t0,t0,((3-AMD_FLASH_MANID)*8)
584#else
585	      srl     t0,t0,(AMD_FLASH_MANID*8)
586#endif
587              sb      t0,0(reg_dest)
588              li      t0,AMD_FLASH_RESET
589              sb      t0,0(reg_src)
590
591              b       nextinst
592/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
59399:           bne     reg_op,FEOP_AMD_MANID16B,99f   /* AMD 8-bit - Boot Block Location */
594
595              ADD     reg_src,reg_src,reg_base
596
597              FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
598              FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
599              FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_AUTOSEL)
600
601              lbu     t0,AMD_FLASH_MANID(reg_src)
602
603              sb      t0,0(reg_dest)
604              li      t0,AMD_FLASH_RESET
605              sb      t0,0(reg_src)
606
607              b       nextinst
608
609#endif
610
611/* INTEL  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
612#if (FLASH_DRIVERS & FLASH_DRIVER_INTEL)
61399:		bne	reg_op,FEOP_INTEL_ERASE8,99f	/* Intel erase 8-bit */
614
615		ADD	reg_dest,reg_dest,reg_base
616
617		FLASHCMD_8(reg_dest,0,INTEL_FLASH_ERASE_BLOCK)
618		FLASHCMD_8(reg_dest,0,INTEL_FLASH_ERASE_CONFIRM)
619
6201:		lbu	t0,0(reg_dest)	/* loop till bit 7 is set */
621		andi	t0,0x80
622		beq	t0,zero,1b
623
624		FLASHCMD_8(reg_dest,0,INTEL_FLASH_READ_MODE)
625
626		b	nextinst
627/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
62899:		bne	reg_op,FEOP_INTEL_ERASE16,99f	/* Intel erase 16-bit */
629
630		ADD	reg_dest,reg_dest,reg_base
631
632
633		FLASHCMD_8(reg_dest,0,INTEL_FLASH_ERASE_BLOCK)
634		FLASHCMD_8(reg_dest,0,INTEL_FLASH_ERASE_CONFIRM)
635
6361:		lbu	t0,0(reg_dest)	/* loop till bit 7 is set */
637		andi	t0,0x80
638		beq	t0,zero,1b
639
640		FLASHCMD_8(reg_dest,0,INTEL_FLASH_READ_MODE)
641
642		b	nextinst
643/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
64499:		bne	reg_op,FEOP_INTEL_PGM8,99f     /* Intel 8-bit program */
645
646		ADD	reg_dest,reg_dest,reg_base
647
64811:		FLASHCMD_8(reg_dest,0,INTEL_FLASH_PROGRAM)
649
650		lbu	t0,0(reg_src)
651		sb	t0,0(reg_dest)
652
6531:		lbu	t0,0(reg_dest)	/* loop till bit 7 is set */
654		andi	t0,0x80
655		beq	t0,zero,1b
656
657		lbu	t0,0(reg_dest)	/* contains final result */
658		/* If good, bits 1, 3, 4 will not be set */
659
660		add     reg_src,1
661		ADD     reg_dest,1
662		sub     reg_cnt,1
663		bgt	reg_cnt,zero,11b
664
665		FLASHCMD_8(reg_dest,0,INTEL_FLASH_READ_MODE)
666
667		b	nextinst
668/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
66999:		bne	reg_op,FEOP_INTEL_PGM16,99f    /* Intel 16-bit prog */
670
671		ADD	reg_dest,reg_dest,reg_base
672
67311:		FLASHCMD_16(reg_dest,0,INTEL_FLASH_PROGRAM)
674
675		lh	t0,0(reg_src)
676		sh	t0,0(reg_dest)
677
6781:		lh	t0,0(reg_dest)	/* loop till bit 7 is set */
679		andi	t0,0x80
680		beq	t0,zero,1b
681
682		lh	t0,0(reg_dest)	/* contains final result */
683		/* If good, bits 1, 3, 4 will not be set */
684
685		FLASHCMD_16(reg_dest,0,INTEL_FLASH_READ_MODE)
686
687		add     reg_src,2
688		ADD     reg_dest,2
689		sub     reg_cnt,2
690		bgt	reg_cnt,zero,11b
691
692		b	nextinst
693#endif
694/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
695#if (FLASH_DRIVERS & FLASH_DRIVER_SST)
69699:		bne	reg_op,FEOP_SST_CFIQUERY16,99f   /* SST CFI Query 16-bit in word mode */
697
698		ADD	reg_src,reg_src,reg_base
699
700		FLASHCMD_16(reg_base,SST_FLASH_MAGIC_ADDR_1,SST_FLASH_MAGIC_1)
701		FLASHCMD_16(reg_base,SST_FLASH_MAGIC_ADDR_2,SST_FLASH_MAGIC_2)
702
703                FLASHCMD_16(reg_base,0x5555,FLASH_CFI_QUERY_MODE)
704
7051:		lh	t0,0(reg_src)		   /* Copy CFI data */
706		sb	t0,0(reg_dest)
707		ADD	reg_src,2
708		add	reg_dest,2
709		sub	reg_cnt,2
710		bgt	reg_cnt,zero,1b
711
712		FLASHCMD_16(reg_base,FLASH_CFI_QUERY_ADDR,SST_FLASH_RESET)
713
714		b	nextinst
715/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
71699:		bne	reg_op,FEOP_SST_ERASE16,99f   /* SST erase (16-bit in word mode) */
717
718		ADD	reg_dest,reg_dest,reg_base
719
720	/* Do an "unlock write" sequence  (cycles 1-2) */
721
722		FLASHCMD_16(reg_base,SST_FLASH_MAGIC_ADDR_1,SST_FLASH_MAGIC_1)
723		FLASHCMD_16(reg_base,SST_FLASH_MAGIC_ADDR_2,SST_FLASH_MAGIC_2)
724
725	/* send the erase command (cycle 3) */
726
727		FLASHCMD_16(reg_base,SST_FLASH_MAGIC_ADDR_1,SST_FLASH_ERASE_3)
728
729	/* Do an "unlock write" sequence (cycles 4-5) */
730
731		FLASHCMD_16(reg_base,SST_FLASH_MAGIC_ADDR_1,SST_FLASH_MAGIC_1)
732		FLASHCMD_16(reg_base,SST_FLASH_MAGIC_ADDR_2,SST_FLASH_MAGIC_2)
733
734        /* Send the "erase sector" qualifier (cycle 6) */
735
736		FLASHCMD_16(reg_dest,0,SST_FLASH_ERASE_SEC_6)
737
738	/* Wait for the erase to complete */
739
7401:		lh	t0,0(reg_dest)		# get word
741		and	t0,0xFF			# test byte
742		bne	t0,0xFF,1b		# go till erased
743
744		b	nextinst
745/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
74699:		bne	reg_op,FEOP_SST_PGM16,99f	/* SST 16-bit program */
747
748		ADD	reg_dest,reg_dest,reg_base
749
750	/* Do an "unlock write" sequence  (cycles 1-2) */
75111:
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 a program command (cycle 3) */
756
757	 	FLASHCMD_16(reg_base,SST_FLASH_MAGIC_ADDR_1,SST_FLASH_PROGRAM)
758
759	/* Write a short (cycle 4) */
760
761		lh	t0,0(reg_src)
762		sh	t0,0(reg_dest)	# t0 = byte written to flash
763
764	/* Wait for write to complete */
765
7661:		lh	t2,0(reg_dest)	# t2 = byte from flash
767
768		and	t1,t2,0x80	# done if bit7 of flash
769		and	t0,t0,0x80	# is same as bit7 of data
770		bne	t1,t0,1b
771
772
773	/* next short...	 */
774
775		add	reg_src,2	# next source word
776		ADD	reg_dest,2	# next dest word
777		sub	reg_cnt,2	# one less count
778		bgt	reg_cnt,0,11b
779
780		b	nextinst
781#endif
782/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
78399:		li      v1,-1			  /* invalid command */
784
785nextinst:	SR	v1,FEINST_RESULT(a0)	  /* store result of instruction */
786		ADD	v0,v0,v1		  /* add to total */
787		ADD	a0,FEINST_SIZE		  /* advance to next instr. */
788		b	instloop
789
790flashop_engine_end:
791		nop
792
793END(flashop_engine)
794
795		.sdata
796
797		.globl	flashop_engine_ptr
798		.globl	flashop_engine_len
799
800flashop_engine_ptr:
801		_VECT_	flashop_engine
802flashop_engine_len:
803		.word	flashop_engine_end-flashop_engine
804
805
806
807/*  *********************************************************************
808    *  end
809    ********************************************************************* */
810
811
812