1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
8 * $Id: ata-as-coldfire.S 17847 2008-06-28 18:10:04Z bagder $
10 * Copyright (C) 2006 by Jens Arnold
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 .section .icode,"ax",@progbits
24 .equ .ata_port, 0x20000020
25 .equ .swapmask, 0x00FF00FF
28 .global copy_read_sectors
29 .type copy_read_sectors,@function
31 /* Read a number of words from the ATA data port
33 * Utilises line bursts, assumes there is at least one full line to copy.
36 * (4,%sp) - buffer address
37 * (8,%sp) - word count
40 * %a0 - current address
45 * %d2-%d6 - read buffers
47 * %d7 - byte swap scrach register
48 * %a3 - byte swap mask
53 movem.l %d2-%d7/%a2-%a3, (%sp)
54 movem.l (36, %sp), %a0-%a1
61 btst.l #0, %d0 /* 16-bit aligned? */
62 jeq .r_aligned /* yes, do word copy */
64 /* not 16-bit aligned */
65 subq.l #1, %a1 /* last byte is done unconditionally */
66 moveq.l #24, %d1 /* preload shift count */
68 move.w (%a2), %d2 /* load initial word */
69 move.b %d2, (%a0)+ /* write high byte of it, aligns dest addr */
70 /* we have byte swapped */
73 btst.l #1, %d0 /* longword aligned? (testing old d0 value!) */
74 bne.b .r_end_u_w1 /* yes, skip leading word handling */
82 move.w %d2, (%a0)+ /* write bytes 2 and 3 as word */
89 and.l #0xFFFFFFF0,%d0 /* d0 == first line bound */
90 cmp.l %a0, %d0 /* any leading longwords? */
91 bls.b .r_end_u_l1 /* no: skip loop */
94 move.w (%a2), %d3 /* load first word */
95 swap %d3 /* move to upper 16 bit */
96 move.w (%a2), %d3 /* load second word */
99 move.l %a3, %d7 /* d7 = 0x00FF00FF */
100 and.l %d3, %d7 /* d7 = .B.D */
101 eor.l %d7, %d3 /* d3 = A.C. */
102 lsl.l #8, %d7 /* d7 = B.D. */
103 lsr.l #8, %d3 /* d3 = .A.C */
104 or.l %d7, %d3 /* d3 = BADC */
110 or.l %d3, %d2 /* combine old low byte with new top 3 bytes */
111 move.l %d2, (%a0)+ /* store as long */
113 cmp.l %a0, %d0 /* run up to first line bound */
117 lea.l (-14, %a1), %a1 /* adjust end addr. to 16 bytes/pass */
120 move.w (%a2), %d3 /* load 1st word */
121 swap %d3 /* move to upper 16 bit */
122 move.w (%a2), %d3 /* load 2nd word */
125 move.l %a3, %d7 /* d7 = 0x00FF00FF */
126 and.l %d3, %d7 /* d7 = .B.D */
127 eor.l %d7, %d3 /* d3 = A.C. */
128 lsl.l #8, %d7 /* d7 = B.D. */
129 lsr.l #8, %d3 /* d3 = .A.C */
130 or.l %d7, %d3 /* d3 = BADC */
136 or.l %d0, %d2 /* combine old low byte with new top 3 bytes */
137 move.w (%a2), %d4 /* load 3rd word */
138 swap %d4 /* move to upper 16 bit */
139 move.w (%a2), %d4 /* load 4th word */
142 move.l %a3, %d7 /* d7 = 0x00FF00FF */
143 and.l %d4, %d7 /* d7 = .B.D */
144 eor.l %d7, %d4 /* d4 = A.C. */
145 lsl.l #8, %d7 /* d7 = B.D. */
146 lsr.l #8, %d4 /* d4 = .A.C */
147 or.l %d7, %d4 /* d4 = BADC */
152 or.l %d0, %d3 /* combine old low byte with new top 3 bytes */
153 move.w (%a2), %d5 /* load 5th word */
154 swap %d5 /* move to upper 16 bit */
155 move.w (%a2), %d5 /* load 6th word */
158 move.l %a3, %d7 /* d7 = 0x00FF00FF */
159 and.l %d5, %d7 /* d7 = .B.D */
160 eor.l %d7, %d5 /* d5 = A.C. */
161 lsl.l #8, %d7 /* d7 = B.D. */
162 lsr.l #8, %d5 /* d5 = .A.C */
163 or.l %d7, %d5 /* d5 = BADC */
168 or.l %d0, %d4 /* combine old low byte with new top 3 bytes */
169 move.w (%a2), %d6 /* load 7th word */
170 swap %d6 /* move to upper 16 bit */
171 move.w (%a2), %d6 /* load 8th word */
174 move.l %a3, %d7 /* d7 = 0x00FF00FF */
175 and.l %d6, %d7 /* d7 = .B.D */
176 eor.l %d7, %d6 /* d6 = A.C. */
177 lsl.l #8, %d7 /* d7 = B.D. */
178 lsr.l #8, %d6 /* d6 = .A.C */
179 or.l %d7, %d6 /* d6 = BADC */
184 or.l %d0, %d5 /* combine old low byte with new top 3 bytes */
185 movem.l %d2-%d5, (%a0) /* store line */
188 cmp.l %a0, %a1 /* run up to last line bound */
191 lea.l (12, %a1), %a1 /* readjust for longword loop */
192 cmp.l %a0, %a1 /* any trailing longwords? */
193 bls.b .r_end_u_l2 /* no: skip loop */
196 move.w (%a2), %d3 /* load first word */
197 swap %d3 /* move to upper 16 bit */
198 move.w (%a2), %d3 /* load second word */
201 move.l %a3, %d7 /* d7 = 0x00FF00FF */
202 and.l %d3, %d7 /* d7 = .B.D */
203 eor.l %d7, %d3 /* d3 = A.C. */
204 lsl.l #8, %d7 /* d7 = B.D. */
205 lsr.l #8, %d3 /* d3 = .A.C */
206 or.l %d7, %d3 /* d3 = BADC */
211 or.l %d3, %d2 /* combine old low byte with new top 3 bytes */
212 move.l %d2, (%a0)+ /* store as long */
214 cmp.l %a0, %a1 /* run up to last long bound */
218 addq.l #2, %a1 /* back to final end address */
219 cmp.l %a0, %a1 /* one word left? */
228 move.w %d2, (%a0)+ /* write bytes 2 and 3 as word */
233 move.b %d2, (%a0)+ /* store final byte */
238 btst.l #1, %d0 /* longword aligned? */
239 beq.b .r_end_a_w1 /* yes, skip leading word handling */
241 /* copy initial word */
242 /* initial word has to be swapped */
251 and.l #0xFFFFFFF0,%d0 /* d0 == first line bound */
252 cmp.l %a0, %d0 /* any leading longwords? */
253 bls.b .r_end_a_l1 /* no: skip loop */
256 move.w (%a2), %d1 /* load first word */
257 swap %d1 /* move it to upper 16 bits */
258 move.w (%a2), %d1 /* load second word */
261 move.l %a3, %d7 /* d7 = 0x00FF00FF */
262 and.l %d1, %d7 /* d7 = .B.D */
263 eor.l %d7, %d1 /* d1 = A.C. */
264 lsl.l #8, %d7 /* d7 = B.D. */
265 lsr.l #8, %d1 /* d1 = .A.C */
266 or.l %d7, %d1 /* d1 = BADC */
268 move.l %d1, (%a0)+ /* store as long */
269 cmp.l %a0, %d0 /* run up to first line bound */
273 lea.l (-14, %a1), %a1 /* adjust end addr. to 16 bytes/pass */
276 move.w (%a2), %d0 /* load 1st word */
277 swap %d0 /* move it to upper 16 bits */
278 move.w (%a2), %d0 /* load 2nd word */
281 move.l %a3, %d7 /* d7 = 0x00FF00FF */
282 and.l %d0, %d7 /* d7 = .B.D */
283 eor.l %d7, %d0 /* d0 = A.C. */
284 lsl.l #8, %d7 /* d7 = B.D. */
285 lsr.l #8, %d0 /* d0 = .A.C */
286 or.l %d7, %d0 /* d0 = BADC */
288 move.w (%a2), %d1 /* load 3rd word */
289 swap %d1 /* move it to upper 16 bits */
290 move.w (%a2), %d1 /* load 4th word */
293 move.l %a3, %d7 /* d7 = 0x00FF00FF */
294 and.l %d1, %d7 /* d7 = .B.D */
295 eor.l %d7, %d1 /* d1 = A.C. */
296 lsl.l #8, %d7 /* d7 = B.D. */
297 lsr.l #8, %d1 /* d1 = .A.C */
298 or.l %d7, %d1 /* d1 = BADC */
300 move.w (%a2), %d2 /* load 5th word */
301 swap %d2 /* move it to upper 16 bits */
302 move.w (%a2), %d2 /* load 6th word */
305 move.l %a3, %d7 /* d7 = 0x00FF00FF */
306 and.l %d2, %d7 /* d7 = .B.D */
307 eor.l %d7, %d2 /* d2 = A.C. */
308 lsl.l #8, %d7 /* d7 = B.D. */
309 lsr.l #8, %d2 /* d2 = .A.C */
310 or.l %d7, %d2 /* d2 = BADC */
312 move.w (%a2), %d3 /* load 7th word */
313 swap %d3 /* move it to upper 16 bits */
314 move.w (%a2), %d3 /* load 8th word */
317 move.l %a3, %d7 /* d7 = 0x00FF00FF */
318 and.l %d3, %d7 /* d7 = .B.D */
319 eor.l %d7, %d3 /* d3 = A.C. */
320 lsl.l #8, %d7 /* d7 = B.D. */
321 lsr.l #8, %d3 /* d3 = .A.C */
322 or.l %d7, %d3 /* d3 = BADC */
324 movem.l %d0-%d3, (%a0) /* store line */
326 cmp.l %a0, %a1 /* run up to last line bound */
329 lea.l (12, %a1), %a1 /* readjust for longword loop */
330 cmp.l %a0, %a1 /* any trailing longwords? */
331 bls.b .r_end_a_l2 /* no: skip loop */
334 move.w (%a2), %d1 /* read first word */
335 swap %d1 /* move it to upper 16 bits */
336 move.w (%a2), %d1 /* read second word */
339 move.l %a3, %d7 /* d7 = 0x00FF00FF */
340 and.l %d1, %d7 /* d7 = .B.D */
341 eor.l %d7, %d1 /* d1 = A.C. */
342 lsl.l #8, %d7 /* d7 = B.D. */
343 lsr.l #8, %d1 /* d1 = .A.C */
344 or.l %d7, %d1 /* d1 = BADC */
346 move.l %d1, (%a0)+ /* store as long */
347 cmp.l %a0, %a1 /* run up to last long bound */
351 addq.l #2, %a1 /* back to final end address */
352 cmp.l %a0, %a1 /* one word left? */
355 /* copy final word */
356 /* final word has to be swapped */
365 movem.l (%sp), %d2-%d7/%a2-%a3
370 .size copy_read_sectors,.r_end-copy_read_sectors
373 .global copy_write_sectors
374 .type copy_write_sectors,@function
376 /* Write a number of words to the ATA data port
378 * Utilises line bursts, assumes there is at least one full line to copy.
381 * (4,%sp) - buffer address
382 * (8,%sp) - word count
385 * %a0 - current address
390 * %d2-%d6 - read buffers
397 lea.l (-32, %sp), %sp
398 movem.l %d2-%d7/%a2-%a3, (%sp)
399 movem.l (36, %sp), %a0-%a1
406 btst.l #0, %d0 /* 16-bit aligned? */
407 beq .w_aligned /* yes, do word copy */
409 /* not 16-bit aligned */
410 subq.l #1, %a1 /* last byte is done unconditionally */
411 moveq.l #24, %d1 /* preload shift count */
415 btst.l #1, %d0 /* longword aligned? (testing old d0 value!) */
416 bne.b .w_end_u_w1 /* yes, skip leading word handling */
423 /* low word of %d3 has to be byte swaped */
424 move.l %a3, %d7 /* d7 = 0x00FF00FF */
425 and.l %d3, %d7 /* d7 = .B.D */
426 eor.l %d7, %d3 /* d3 = A.C. */
427 lsl.l #8, %d7 /* d7 = B.D. */
428 lsr.l #8, %d3 /* d3 = .A.C */
429 or.l %d7, %d3 /* d3 = BADC */
436 and.l #0xFFFFFFF0,%d0 /* d0 == first line bound */
437 cmp.l %a0, %d0 /* any leading longwords? */
438 bls.b .w_end_u_l1 /* no: skip loop */
448 move.l %a3, %d7 /* d7 = 0x00FF00FF */
449 and.l %d2, %d7 /* d7 = .B.D */
450 eor.l %d7, %d2 /* d2 = A.C. */
451 lsl.l #8, %d7 /* d7 = B.D. */
452 lsr.l #8, %d2 /* d2 = .A.C */
453 or.l %d7, %d2 /* d2 = BADC */
460 cmp.l %a0, %d0 /* run up to first line bound */
464 lea.l (-14, %a1), %a1 /* adjust end addr. to 16 bytes/pass */
467 movem.l (%a0), %d3-%d6
475 move.l %a3, %d7 /* d7 = 0x00FF00FF */
476 and.l %d2, %d7 /* d7 = .B.D */
477 eor.l %d7, %d2 /* d2 = A.C. */
478 lsl.l #8, %d7 /* d7 = B.D. */
479 lsr.l #8, %d2 /* d2 = .A.C */
480 or.l %d7, %d2 /* d2 = BADC */
492 move.l %a3, %d7 /* d7 = 0x00FF00FF */
493 and.l %d3, %d7 /* d7 = .B.D */
494 eor.l %d7, %d3 /* d3 = A.C. */
495 lsl.l #8, %d7 /* d7 = B.D. */
496 lsr.l #8, %d3 /* d3 = .A.C */
497 or.l %d7, %d3 /* d3 = BADC */
509 move.l %a3, %d7 /* d7 = 0x00FF00FF */
510 and.l %d4, %d7 /* d7 = .B.D */
511 eor.l %d7, %d4 /* d4 = A.C. */
512 lsl.l #8, %d7 /* d7 = B.D. */
513 lsr.l #8, %d4 /* d4 = .A.C */
514 or.l %d7, %d4 /* d4 = BADC */
526 move.l %a3, %d7 /* d7 = 0x00FF00FF */
527 and.l %d5, %d7 /* d7 = .B.D */
528 eor.l %d7, %d5 /* d5 = A.C. */
529 lsl.l #8, %d7 /* d7 = B.D. */
530 lsr.l #8, %d5 /* d5 = .A.C */
531 or.l %d7, %d5 /* d5 = BADC */
538 cmp.l %a0, %a1 /* run up to last line bound */
541 lea.l (12, %a1), %a1 /* readjust for longword loop */
542 cmp.l %a0, %a1 /* any trailing longwords? */
543 bls.b .w_end_u_l2 /* no: skip loop */
553 move.l %a3, %d7 /* d7 = 0x00FF00FF */
554 and.l %d2, %d7 /* d7 = .B.D */
555 eor.l %d7, %d2 /* d2 = A.C. */
556 lsl.l #8, %d7 /* d7 = B.D. */
557 lsr.l #8, %d2 /* d2 = .A.C */
558 or.l %d7, %d2 /* d2 = BADC */
565 cmp.l %a0, %a1 /* run up to first line bound */
569 addq.l #2, %a1 /* back to final end address */
570 cmp.l %a0, %a1 /* one word left? */
579 move.l %a3, %d7 /* d7 = 0x00FF00FF */
580 and.l %d3, %d7 /* d7 = .B.D */
581 eor.l %d7, %d3 /* d3 = A.C. */
582 lsl.l #8, %d7 /* d7 = B.D. */
583 lsr.l #8, %d3 /* d3 = .A.C */
584 or.l %d7, %d3 /* d3 = BADC */
593 move.l %a3, %d7 /* d7 = 0x00FF00FF */
594 and.l %d2, %d7 /* d7 = .B.D */
595 eor.l %d7, %d2 /* d2 = A.C. */
596 lsl.l #8, %d7 /* d7 = B.D. */
597 lsr.l #8, %d2 /* d2 = .A.C */
598 or.l %d7, %d2 /* d2 = BADC */
608 /* this has to be byte swaped */
609 /* copy initial word */
613 move.l %a3, %d7 /* d7 = $00FF00FF */
614 and.l %d1, %d7 /* d7 = .B.D */
615 eor.l %d7, %d1 /* d1 = A.C. */
616 lsl.l #8, %d7 /* d7 = B.D. */
617 lsr.l #8, %d1 /* d1 = .A.C */
618 or.l %d7, %d1 /* d1 = BADC */
626 and.l #0xFFFFFFF0,%d0 /* d0 == first line bound */
627 cmp.l %a0, %d0 /* any leading longwords? */
628 bls.b .w_end_a_l1 /* no: skip loop */
634 move.l %a3, %d7 /* d7 = 0x00FF00FF */
635 and.l %d1, %d7 /* d7 = .B.D */
636 eor.l %d7, %d1 /* d1 = A.C. */
637 lsl.l #8, %d7 /* d7 = B.D. */
638 lsr.l #8, %d1 /* d1 = .A.C */
639 or.l %d7, %d1 /* d1 = BADC */
645 cmp.l %a0, %d0 /* run up to first line bound */
649 lea.l (-14, %a1), %a1 /* adjust end addr. to 16 bytes/pass */
652 movem.l (%a0), %d0-%d3
654 /* byte swap d0-d3 */
655 move.l %a3, %d7 /* d7 = 0x00FF00FF */
656 and.l %d0, %d7 /* d7 = .B.D */
657 eor.l %d7, %d0 /* d0 = A.C. */
658 lsl.l #8, %d7 /* d7 = B.D. */
659 lsr.l #8, %d0 /* d0 = .A.C */
660 or.l %d7, %d0 /* d0 = BADC */
662 move.l %a3, %d7 /* d7 = 0x00FF00FF */
663 and.l %d1, %d7 /* d7 = .B.D */
664 eor.l %d7, %d1 /* d1 = A.C. */
665 lsl.l #8, %d7 /* d7 = B.D. */
666 lsr.l #8, %d1 /* d1 = .A.C */
667 or.l %d7, %d1 /* d1 = BADC */
669 move.l %a3, %d7 /* d7 = 0x00FF00FF */
670 and.l %d2, %d7 /* d7 = .B.D */
671 eor.l %d7, %d2 /* d2 = A.C. */
672 lsl.l #8, %d7 /* d7 = B.D. */
673 lsr.l #8, %d2 /* d2 = .A.C */
674 or.l %d7, %d2 /* d2 = BADC */
676 move.l %a3, %d7 /* d7 = 0x00FF00FF */
677 and.l %d3, %d7 /* d7 = .B.D */
678 eor.l %d7, %d3 /* d3 = A.C. */
679 lsl.l #8, %d7 /* d7 = B.D. */
680 lsr.l #8, %d3 /* d3 = .A.C */
681 or.l %d7, %d3 /* d3 = BADC */
700 cmp.l %a0, %a1 /* run up to last line bound */
703 lea.l (12, %a1), %a1 /* readjust for longword loop */
704 cmp.l %a0, %a1 /* any trailing longwords? */
705 bls.b .w_end_a_l2 /* no: skip loop */
711 move.l %a3, %d7 /* d7 = 0x00FF00FF */
712 and.l %d1, %d7 /* d7 = .B.D */
713 eor.l %d7, %d1 /* d1 = A.C. */
714 lsl.l #8, %d7 /* d7 = B.D. */
715 lsr.l #8, %d1 /* d1 = .A.C */
716 or.l %d7, %d1 /* d1 = BADC */
722 cmp.l %a0, %a1 /* run up to first line bound */
726 addq.l #2, %a1 /* back to final end address */
727 cmp.l %a0, %a1 /* one word left? */
730 /* this has to be byte swaped */
731 /* copy final word */
744 movem.l (%sp), %d2-%d7/%a2-%a3
749 .size copy_write_sectors,.w_end-copy_write_sectors