1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2007 by Jens Arnold
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
23 #if CONFIG_CPU == PP5002
24 /* Causes ATA retries on iPod G3 probably related to improper controller
25 * setup. Needs investigation. */
26 .section .icode,"ax",%progbits
27 .equ .ata_port, 0xc00031e0
28 #elif defined CPU_PP502x
29 /* Verified working on (PP5020, PP5022) targets */
30 .section .icode,"ax",%progbits
31 .equ .ata_port, 0xc30001e0
32 #elif CONFIG_CPU == S3C2440
35 .equ .ata_port, 0x18000000
39 .global copy_read_sectors
40 .type copy_read_sectors,%function
42 /* Read a number of words from the ATA data port
44 * Optimised for speed; assumes wordcount >= 10
51 * r0 - current address
54 * r3..r6, lr - read buffers
58 stmfd sp!, {r4, r5, r6, lr}
60 tst r0, #1 /* 16 bit aligned? */
63 /* not 16-bit aligned */
64 sub r1, r1, #1 /* one halfword is handled unconditionally */
65 ldrh r3, [r2] /* read first halfword */
66 strb r3, [r0], #1 /* store low byte */
69 tst r0, #2 /* 32 bit aligned? */
71 ldrh r4, [r2] /* read second halfword */
72 orr r3, r3, r4, lsl #8 /* combine with old byte */
73 strh r3, [r0], #2 /* store */
75 sub r1, r1, #1 /* another halfword taken */
78 sub r1, r1, #8 /* adjust for zero-check and doing 8 halfwords/loop */
80 ldrh r4, [r2] /* Read 8 halfwords and combine them into */
81 orr r3, r3, r4, lsl #8 /* 4 words so that they're properly aligned */
82 ldrh r4, [r2] /* in memory. Bottom byte of first word is */
83 orr r3, r3, r4, lsl #24 /* the top byte from the last round. Write */
84 mov r4, r4, lsr #8 /* all 4 words at once. */
86 orr r4, r4, r5, lsl #8
88 orr r4, r4, r5, lsl #24
91 orr r5, r5, r6, lsl #8
93 orr r5, r5, r6, lsl #24
96 orr r6, r6, lr, lsl #8
98 orr r6, r6, lr, lsl #24
99 stmia r0!, {r3, r4, r5, r6}
101 subs r1, r1, #8 /* 8 or more halfwords left? */
104 /* No need to adjust the count, only checking bits from now on. */
105 tst r1, #4 /* 4 or more halfwords left? */
108 orr r3, r3, r4, lsl #8
110 orr r3, r3, r4, lsl #24
113 orr r4, r4, r5, lsl #8
115 orr r4, r4, r5, lsl #24
120 tst r1, #2 /* 2 or more halfwords left? */
123 orr r3, r3, r4, lsl #8
125 orr r3, r3, r4, lsl #24
130 tst r1, #1 /* one halfword left? */
132 orrne r3, r3, r4, lsl #8
136 strb r3, [r0], #1 /* store final byte */
138 ldmfd sp!, {r4, r5, r6, pc}
142 tst r0, #2 /* 32 bit aligned? */
143 ldrneh r3, [r2] /* no: read first halfword */
144 strneh r3, [r0], #2 /* store */
145 subne r1, r1, #1 /* one halfword taken */
147 sub r1, r1, #8 /* adjust for zero-check and doing 8 halfwords/loop */
149 ldrh r3, [r2] /* Read 8 halfwords and combine each pair */
150 ldrh r4, [r2] /* into a word, then store all at once. */
151 orr r3, r3, r4, lsl #16
154 orr r4, r4, r5, lsl #16
157 orr r5, r5, r6, lsl #16
160 orr r6, r6, lr, lsl #16
161 stmia r0!, {r3, r4, r5, r6}
162 subs r1, r1, #8 /* 8 or more halfwords left? */
165 /* No need to adjust the count, only checking bits from now on. */
166 tst r1, #4 /* 4 or more halfwords left? */
170 orr r3, r3, r4, lsl #16
173 orr r4, r4, r5, lsl #16
177 tst r1, #2 /* 2 or more halfwords left? */
180 orrne r3, r3, r4, lsl #16
183 tst r1, #1 /* one halfword left? */
187 ldmfd sp!, {r4, r5, r6, pc}
190 .size copy_read_sectors,.r_end-copy_read_sectors
193 .global copy_write_sectors
194 .type copy_write_sectors,%function
196 /* Write a number of words to the ATA data port
198 * Optimised for speed; assumes wordcount >= 10
201 * r0 - buffer address
205 * r0 - current address
208 * r3..r6, lr - read buffers
212 stmfd sp!, {r4, r5, r6, lr}
214 tst r0, #1 /* 16 bit aligned? */
217 /* not 16-bit aligned */
218 sub r1, r1, #1 /* one halfword is done unconditionally */
219 ldrb r3, [r0], #1 /* load 1st byte, now halfword aligned. */
221 tst r0, #2 /* 32 bit aligned? */
223 ldrh r4, [r0], #2 /* load a halfword */
224 orr r3, r3, r4, lsl #8 /* combine with old byte */
225 strh r3, [r2] /* write halfword */
227 sub r1, r1, #1 /* another halfword taken */
230 sub r1, r1, #8 /* adjust for zero-check and doing 8 halfwords/loop */
232 ldmia r0!, {r4, r5, r6, lr}
233 orr r3, r3, r4, lsl #8 /* Load 4 words at once and decompose them */
234 strh r3, [r2] /* into 8 halfwords in a way that the words */
235 mov r3, r3, lsr #16 /* are shifted by 8 bits, putting the high */
236 strh r3, [r2] /* byte of one word into the low byte of */
237 mov r4, r4, lsr #24 /* the next. High byte of last word becomes */
238 orr r4, r4, r5, lsl #8 /* low byte of next round. */
243 orr r5, r5, r6, lsl #8
248 orr r6, r6, lr, lsl #8
253 subs r1, r1, #8 /* 8 or more halfwords left? */
256 /* No need to adjust the count, only checking bits from now on. */
257 tst r1, #4 /* 4 or more halfwords left? */
260 orr r3, r3, r4, lsl #8
265 orr r4, r4, r5, lsl #8
272 tst r1, #2 /* 2 or more halfwords left? */
275 orr r3, r3, r4, lsl #8
282 tst r1, #1 /* one halfword left? */
284 orrne r3, r3, r4, lsl #8
286 movne r3, r3, lsr #16
288 ldrb r4, [r0], #1 /* load final byte */
289 orr r3, r3, r4, lsl #8
290 strh r3, [r2] /* write final halfword */
292 ldmfd sp!, {r4, r5, r6, pc}
296 tst r0, #2 /* 32 bit aligned? */
297 ldrneh r3, [r0], #2 /* no: load first halfword */
298 strneh r3, [r2] /* write */
299 subne r1, r1, #1 /* one halfword taken */
301 sub r1, r1, #8 /* adjust for zero-check and doing 8 halfwords/loop */
303 ldmia r0!, {r3, r4, r5, r6}
304 strh r3, [r2] /* Load 4 words and decompose them into */
305 mov r3, r3, lsr #16 /* 2 halfwords each, and write those. */
316 subs r1, r1, #8 /* 8 or more halfwords left? */
319 /* No need to adjust the count, only checking bits from now on. */
320 tst r1, #4 /* 4 or more halfwords left? */
331 tst r1, #2 /* 2 or more halfwords left? */
334 movne r3, r3, lsr #16
337 tst r1, #1 /* one halfword left? */
341 ldmfd sp!, {r4, r5, r6, pc}
344 .size copy_write_sectors,.w_end-copy_write_sectors