* add p cc
[mascara-docs.git] / i386 / linux / linux-2.3.21 / arch / arm / lib / io-acorn.S
blobbf2dd63332f85803c7b0a868a1a69cafaf8d7eee
1 /*
2  * linux/arch/arm/lib/io.S
3  *
4  * Copyright (C) 1995, 1996 Russell King
5  */
6 #include <linux/config.h> /* for CONFIG_CPU_nn */
7 #include <linux/linkage.h>
8 #include <asm/assembler.h>
9 #include <asm/hardware.h>
11                 .text
12                 .align
14                 .equ    diff_pcio_base, PCIO_BASE - IO_BASE
16                 .macro  outw2   rd
17                 mov     r8, \rd, lsl #16
18                 orr     r8, r8, r8, lsr #16
19                 str     r8, [r3, r0, lsl #2]
20                 mov     r8, \rd, lsr #16
21                 orr     r8, r8, r8, lsl #16
22                 str     r8, [r3, r0, lsl #2]
23                 .endm
25                 .macro  inw2    rd, mask, temp
26                 ldr     \rd, [r0]
27                 and     \rd, \rd, \mask
28                 ldr     \temp, [r0]
29                 orr     \rd, \rd, \temp, lsl #16
30                 .endm
32                 .macro  addr    rd
33                 tst     \rd, #0x80000000
34                 mov     \rd, \rd, lsl #2
35                 add     \rd, \rd, #IO_BASE
36                 addeq   \rd, \rd, #diff_pcio_base
37                 .endm
39 .iosw_bad_align_msg:
40                 .ascii  "insw: bad buffer alignment (%p), called from %08lX\n\0"
41 .iosl_warning:
42                 .ascii  "<4>insl/outsl not implemented, called from %08lX\0"
43                 .align
46  * These make no sense on Acorn machines.
47  * Print a warning message.
48  */
49 ENTRY(insl)
50 ENTRY(outsl)
51                 adr     r0, .iosl_warning
52                 mov     r1, lr
53                 b       SYMBOL_NAME(printk)
55 .iosw_bad_alignment:
56                 adr     r0, .iosw_bad_align_msg
57                 mov     r2, lr
58                 b       SYMBOL_NAME(panic)
61 /* Purpose: read a block of data from a hardware register to memory.
62  * Proto  : void insw(int from_port, void *to, int len_in_words);
63  * Notes  : increment to, 'to' must be 16-bit aligned
64  */
66 .insw_align:    tst     r1, #1
67                 bne     .iosw_bad_alignment
69                 ldr     r3, [r0]
70                 strb    r3, [r1], #1
71                 mov     r3, r3, lsr #8
72                 strb    r3, [r1], #1
74                 subs    r2, r2, #1
75                 bne     .insw_aligned
77 ENTRY(insw)
78                 teq     r2, #0
79                 RETINSTR(moveq,pc,lr)
80                 addr    r0
81                 tst     r1, #3
82                 bne     .insw_align
84 .insw_aligned:  mov     ip, #0xff
85                 orr     ip, ip, ip, lsl #8
86                 stmfd   sp!, {r4, r5, r6, lr}
88                 subs    r2, r2, #8
89                 bmi     .no_insw_8
91 .insw_8_lp:     ldr     r3, [r0]
92                 and     r3, r3, ip
93                 ldr     r4, [r0]
94                 orr     r3, r3, r4, lsl #16
96                 ldr     r4, [r0]
97                 and     r4, r4, ip
98                 ldr     r5, [r0]
99                 orr     r4, r4, r5, lsl #16
101                 ldr     r5, [r0]
102                 and     r5, r5, ip
103                 ldr     r6, [r0]
104                 orr     r5, r5, r6, lsl #16
106                 ldr     r6, [r0]
107                 and     r6, r6, ip
108                 ldr     lr, [r0]
109                 orr     r6, r6, lr, lsl #16
111                 stmia   r1!, {r3 - r6}
112                 subs    r2, r2, #8
113                 bpl     .insw_8_lp
114                 tst     r2, #7
115                 LOADREGS(eqfd, sp!, {r4, r5, r6, pc})
117 .no_insw_8:     tst     r2, #4
118                 beq     .no_insw_4
120                 ldr     r3, [r0]
121                 and     r3, r3, ip
122                 ldr     r4, [r0]
123                 orr     r3, r3, r4, lsl #16
125                 ldr     r4, [r0]
126                 and     r4, r4, ip
127                 ldr     r5, [r0]
128                 orr     r4, r4, r5, lsl #16
130                 stmia   r1!, {r3, r4}
132 .no_insw_4:     tst     r2, #2
133                 beq     .no_insw_2
135                 ldr     r3, [r0]
136                 and     r3, r3, ip
137                 ldr     r4, [r0]
138                 orr     r3, r3, r4, lsl #16
140                 str     r3, [r1], #4
142 .no_insw_2:     tst     r2, #1
143                 ldrne   r3, [r0]
144                 strneb  r3, [r1], #1
145                 movne   r3, r3, lsr #8
146                 strneb  r3, [r1]
147                 LOADREGS(fd, sp!, {r4, r5, r6, pc})
149 @ Purpose: write a block of data from memory to a hardware register.
150 @ Proto  : outsw(int to_reg, void *from, int len_in_words);
151 @ Notes  : increments from
153 .outsw_align:   tst     r1, #1
154                 bne     .iosw_bad_alignment
156                 add     r1, r1, #2
158                 ldr     r3, [r1, #-4]
159                 mov     r3, r3, lsr #16
160                 orr     r3, r3, r3, lsl #16
161                 str     r3, [r0]
162                 subs    r2, r2, #1
163                 bne     .outsw_aligned
165 ENTRY(outsw)
166                 teq     r2, #0
167                 RETINSTR(moveq,pc,lr)
168                 addr    r0
169                 tst     r1, #3
170                 bne     .outsw_align
172 .outsw_aligned: stmfd   sp!, {r4, r5, r6, lr}
174                 subs    r2, r2, #8
175                 bmi     .no_outsw_8
176 .outsw_8_lp:    ldmia   r1!, {r3, r4, r5, r6}
178                 mov     ip, r3, lsl #16
179                 orr     ip, ip, ip, lsr #16
180                 str     ip, [r0]
182                 mov     ip, r3, lsr #16
183                 orr     ip, ip, ip, lsl #16
184                 str     ip, [r0]
186                 mov     ip, r4, lsl #16
187                 orr     ip, ip, ip, lsr #16
188                 str     ip, [r0]
190                 mov     ip, r4, lsr #16
191                 orr     ip, ip, ip, lsl #16
192                 str     ip, [r0]
194                 mov     ip, r5, lsl #16
195                 orr     ip, ip, ip, lsr #16
196                 str     ip, [r0]
198                 mov     ip, r5, lsr #16
199                 orr     ip, ip, ip, lsl #16
200                 str     ip, [r0]
202                 mov     ip, r6, lsl #16
203                 orr     ip, ip, ip, lsr #16
204                 str     ip, [r0]
206                 mov     ip, r6, lsr #16
207                 orr     ip, ip, ip, lsl #16
208                 str     ip, [r0]
210                 subs    r2, r2, #8
211                 bpl     .outsw_8_lp
212                 tst     r2, #7
213                 LOADREGS(eqfd, sp!, {r4, r5, r6, pc})
215 .no_outsw_8:    tst     r2, #4
216                 beq     .no_outsw_4
218                 ldmia   r1!, {r3, r4}
220                 mov     ip, r3, lsl #16
221                 orr     ip, ip, ip, lsr #16
222                 str     ip, [r0]
224                 mov     ip, r3, lsr #16
225                 orr     ip, ip, ip, lsl #16
226                 str     ip, [r0]
228                 mov     ip, r4, lsl #16
229                 orr     ip, ip, ip, lsr #16
230                 str     ip, [r0]
232                 mov     ip, r4, lsr #16
233                 orr     ip, ip, ip, lsl #16
234                 str     ip, [r0]
236 .no_outsw_4:    tst     r2, #2
237                 beq     .no_outsw_2
239                 ldr     r3, [r1], #4
241                 mov     ip, r3, lsl #16
242                 orr     ip, ip, ip, lsr #16
243                 str     ip, [r0]
245                 mov     ip, r3, lsr #16
246                 orr     ip, ip, ip, lsl #16
247                 str     ip, [r0]
249 .no_outsw_2:    tst     r2, #1
251                 ldrne   r3, [r1]
253                 movne   ip, r3, lsl #16
254                 orrne   ip, ip, ip, lsr #16
255                 strne   ip, [r0]
257                 LOADREGS(fd, sp!, {r4, r5, r6, pc})
259 .insb_align:    rsb     ip, ip, #4
260                 cmp     ip, r2
261                 movgt   ip, r2
262                 cmp     ip, #2
263                 ldrb    r3, [r0]
264                 strb    r3, [r1], #1
265                 ldrgeb  r3, [r0]
266                 strgeb  r3, [r1], #1
267                 ldrgtb  r3, [r0]
268                 strgtb  r3, [r1], #1
269                 subs    r2, r2, ip
270                 bne     .insb_aligned
272 ENTRY(insb)
273                 teq     r2, #0
274                 moveq   pc, lr
275                 addr    r0
276                 ands    ip, r1, #3
277                 bne     .insb_align
279 .insb_aligned:  stmfd   sp!, {r4 - r6, lr}
281                 subs    r2, r2, #16
282                 bmi     .insb_no_16
284 .insb_16_lp:    ldrb    r3, [r0]
285                 ldrb    r4, [r0]
286                 orr     r3, r3, r4, lsl #8
287                 ldrb    r4, [r0]
288                 orr     r3, r3, r4, lsl #16
289                 ldrb    r4, [r0]
290                 orr     r3, r3, r4, lsl #24
291                 ldrb    r4, [r0]
292                 ldrb    r5, [r0]
293                 orr     r4, r4, r5, lsl #8
294                 ldrb    r5, [r0]
295                 orr     r4, r4, r5, lsl #16
296                 ldrb    r5, [r0]
297                 orr     r4, r4, r5, lsl #24
298                 ldrb    r5, [r0]
299                 ldrb    r6, [r0]
300                 orr     r5, r5, r6, lsl #8
301                 ldrb    r6, [r0]
302                 orr     r5, r5, r6, lsl #16
303                 ldrb    r6, [r0]
304                 orr     r5, r5, r6, lsl #24
305                 ldrb    r6, [r0]
306                 ldrb    ip, [r0]
307                 orr     r6, r6, ip, lsl #8
308                 ldrb    ip, [r0]
309                 orr     r6, r6, ip, lsl #16
310                 ldrb    ip, [r0]
311                 orr     r6, r6, ip, lsl #24
312                 stmia   r1!, {r3 - r6}
313                 subs    r2, r2, #16
314                 bpl     .insb_16_lp
316                 tst     r2, #15
317                 LOADREGS(eqfd, sp!, {r4 - r6, pc})
319 .insb_no_16:    tst     r2, #8
320                 beq     .insb_no_8
322                 ldrb    r3, [r0]
323                 ldrb    r4, [r0]
324                 orr     r3, r3, r4, lsl #8
325                 ldrb    r4, [r0]
326                 orr     r3, r3, r4, lsl #16
327                 ldrb    r4, [r0]
328                 orr     r3, r3, r4, lsl #24
329                 ldrb    r4, [r0]
330                 ldrb    r5, [r0]
331                 orr     r4, r4, r5, lsl #8
332                 ldrb    r5, [r0]
333                 orr     r4, r4, r5, lsl #16
334                 ldrb    r5, [r0]
335                 orr     r4, r4, r5, lsl #24
336                 stmia   r1!, {r3, r4}
338 .insb_no_8:     tst     r2, #4
339                 bne     .insb_no_4
341                 ldrb    r3, [r0]
342                 ldrb    r4, [r0]
343                 orr     r3, r3, r4, lsl #8
344                 ldrb    r4, [r0]
345                 orr     r3, r3, r4, lsl #16
346                 ldrb    r4, [r0]
347                 orr     r3, r3, r4, lsl #24
348                 str     r3, [r1], #4
350 .insb_no_4:     ands    r2, r2, #3
351                 LOADREGS(eqfd, sp!, {r4 - r6, pc})
352                 cmp     r2, #2
353                 ldrb    r3, [r0]
354                 strb    r3, [r1], #1
355                 ldrgeb  r3, [r0]
356                 strgeb  r3, [r1], #1
357                 ldrgtb  r3, [r0]
358                 strgtb  r3, [r1]
359                 LOADREGS(fd, sp!, {r4 - r6, pc})
363 .outsb_align:   rsb     ip, ip, #4
364                 cmp     ip, r2
365                 mov     ip, r2
366                 cmp     ip, #2
367                 ldrb    r3, [r1], #1
368                 strb    r3, [r0]
369                 ldrgeb  r3, [r1], #1
370                 strgeb  r3, [r0]
371                 ldrgtb  r3, [r1], #1
372                 strgtb  r3, [r0]
373                 subs    r2, r2, ip
374                 bne     .outsb_aligned
376 ENTRY(outsb)
377                 teq     r2, #0
378                 moveq   pc, lr
379                 addr    r0
380                 ands    ip, r1, #3
381                 bne     .outsb_align
383 .outsb_aligned: stmfd   sp!, {r4 - r6, lr}
385                 subs    r2, r2, #16
386                 bmi     .outsb_no_16
388 .outsb_16_lp:   ldmia   r1!, {r3 - r6}
389                 strb    r3, [r0]
390                 mov     r3, r3, lsr #8
391                 strb    r3, [r0]
392                 mov     r3, r3, lsr #8
393                 strb    r3, [r0]
394                 mov     r3, r3, lsr #8
395                 strb    r3, [r0]
397                 strb    r4, [r0]
398                 mov     r4, r4, lsr #8
399                 strb    r4, [r0]
400                 mov     r4, r4, lsr #8
401                 strb    r4, [r0]
402                 mov     r4, r4, lsr #8
403                 strb    r4, [r0]
405                 strb    r5, [r0]
406                 mov     r5, r5, lsr #8
407                 strb    r5, [r0]
408                 mov     r5, r5, lsr #8
409                 strb    r5, [r0]
410                 mov     r5, r5, lsr #8
411                 strb    r5, [r0]
413                 strb    r6, [r0]
414                 mov     r6, r6, lsr #8
415                 strb    r6, [r0]
416                 mov     r6, r6, lsr #8
417                 strb    r6, [r0]
418                 mov     r6, r6, lsr #8
419                 strb    r6, [r0]
420                 subs    r2, r2, #16
421                 bpl     .outsb_16_lp
423                 tst     r2, #15
424                 LOADREGS(eqfd, sp!, {r4 - r6, pc})
426 .outsb_no_16:   tst     r2, #8
427                 beq     .outsb_no_8
429                 ldmia   r1, {r3, r4}
430                 strb    r3, [r0]
431                 mov     r3, r3, lsr #8
432                 strb    r3, [r0]
433                 mov     r3, r3, lsr #8
434                 strb    r3, [r0]
435                 mov     r3, r3, lsr #8
436                 strb    r3, [r0]
438                 strb    r4, [r0]
439                 mov     r4, r4, lsr #8
440                 strb    r4, [r0]
441                 mov     r4, r4, lsr #8
442                 strb    r4, [r0]
443                 mov     r4, r4, lsr #8
444                 strb    r4, [r0]
446 .outsb_no_8:    tst     r2, #4
447                 bne     .outsb_no_4
449                 ldr     r3, [r1], #4
450                 strb    r3, [r0]
451                 mov     r3, r3, lsr #8
452                 strb    r3, [r0]
453                 mov     r3, r3, lsr #8
454                 strb    r3, [r0]
455                 mov     r3, r3, lsr #8
456                 strb    r3, [r0]
458 .outsb_no_4:    ands    r2, r2, #3
459                 LOADREGS(eqfd, sp!, {r4 - r6, pc})
460                 cmp     r2, #2
461                 ldrb    r3, [r1], #1
462                 strb    r3, [r0]
463                 ldrgeb  r3, [r1], #1
464                 strgeb  r3, [r0]
465                 ldrgtb  r3, [r1]
466                 strgtb  r3, [r0]
467                 LOADREGS(fd, sp!, {r4 - r6, pc})
472 @ Purpose: write a memc register
473 @ Proto  : void memc_write(int register, int value);
474 @ Returns: nothing
476 #if defined(CONFIG_CPU_26)
477 ENTRY(memc_write)
478                 cmp     r0, #7
479                 RETINSTR(movgt,pc,lr)
480                 mov     r0, r0, lsl #17
481                 mov     r1, r1, lsl #15
482                 mov     r1, r1, lsr #17
483                 orr     r0, r0, r1, lsl #2
484                 add     r0, r0, #0x03600000
485                 strb    r0, [r0]
486                 RETINSTR(mov,pc,lr)
487 #define CPSR2SPSR(rt)
488 #else
489 #define CPSR2SPSR(rt) \
490                 mrs     rt, cpsr; \
491                 msr     spsr, rt
492 #endif
494 @ Purpose: call an expansion card loader to read bytes.
495 @ Proto  : char read_loader(int offset, char *card_base, char *loader);
496 @ Returns: byte read
498 ENTRY(ecard_loader_read)
499                 stmfd   sp!, {r4 - r12, lr}
500                 mov     r11, r1
501                 mov     r1, r0
502                 CPSR2SPSR(r0)
503                 mov     lr, pc
504                 mov     pc, r2
505                 LOADREGS(fd, sp!, {r4 - r12, pc})
507 @ Purpose: call an expansion card loader to reset the card
508 @ Proto  : void read_loader(int card_base, char *loader);
509 @ Returns: byte read
511 ENTRY(ecard_loader_reset)
512                 stmfd   sp!, {r4 - r12, lr}
513                 mov     r11, r0
514                 CPSR2SPSR(r0)
515                 mov     lr, pc
516                 add     pc, r1, #8
517                 LOADREGS(fd, sp!, {r4 - r12, pc})
520 #if 0
521                 mov     r2, r2, lsl#1
522                 mov     ip, sp
523                 stmfd   sp!, {r4 - r10, fp, ip, lr, pc}
524                 sub     fp, ip, #4
525                 addr    r3, r0
526                 add     r0, r3, r0, lsl #2
527                 tst     r1, #3
528                 beq     Linswok
529                 tst     r1, #1
530                 bne     Linsw_notaligned
531                 cmp     r2, #1
532                 ldrge   r4, [r0]
533                 strgeb  r4, [r1], #1
534                 movgt   r4, r4, LSR#8
535                 strgtb  r4, [r1], #1
536                 LOADREGS(leea, fp, {r4 - r10, fp, sp, pc})
537                 sub     r2, r2, #2
538 Linswok:        mov     ip, #0xFF
539                 orr     ip, ip, ip, lsl #8
540 Linswlp:        subs    r2, r2, #64
541                 bmi     Linsw_toosmall
542                 IN(r3)
543                 IN(r4)
544                 IN(r5)
545                 IN(r6)
546                 IN(r7)
547                 IN(r8)
548                 IN(r9)
549                 IN(r10)
550                 stmia   r1!, {r3 - r10}
551                 IN(r3)
552                 IN(r4)
553                 IN(r5)
554                 IN(r6)
555                 IN(r7)
556                 IN(r8)
557                 IN(r9)
558                 IN(r10)
559                 stmia   r1!, {r3 - r10}
560                 bne     Linswlp
561                 LOADREGS(ea, fp, {r4 - r10, fp, sp, pc})
562 Linsw_toosmall:
563                 adds    r2, r2, #32
564                 bmi     Linsw_toosmall2
565 Linsw2lp:       IN(r3)
566                 IN(r4)
567                 IN(r5)
568                 IN(r6)
569                 IN(r7)
570                 IN(r8)
571                 IN(r9)
572                 IN(r10)
573                 stmia   r1!, {r3 - r10}
574                 LOADREGS(eqea, fp, {r4 - r10, fp, sp, pc})
575                 b       Linsw_notaligned
576 Linsw_toosmall2:
577                 add     r2, r2, #32
578 Linsw_notaligned:
579                 cmp     r2, #1
580                 LOADREGS(ltea, fp, {r4 - r10, fp, sp, pc})
581                 ldr     r4, [r0]
582                 strb    r4, [r1], #1
583                 movgt   r4, r4, LSR#8
584                 strgtb  r4, [r1], #1
585                 subs    r2, r2, #2
586                 bgt     Linsw_notaligned
587                 LOADREGS(ea, fp, {r4 - r10, fp, sp, pc})
590 ENTRY(outsw)
591                 mov     r2, r2, lsl#1
592                 mov     ip, sp
593                 stmfd   sp!, {r4 - r8, fp, ip, lr, pc}
594                 sub     fp, ip, #4
595                 addr    r3, r0
596                 tst     r1, #2
597                 beq     1f
598                 ldr     r4, [r1], #2
599                 mov     r4, r4, lsl #16
600                 orr     r4, r4, r4, lsr #16
601                 str     r4, [r3, r0, lsl #2]
602                 subs    r2, r2, #2
603                 LOADREGS(eqea, fp, {r4 - r8, fp, sp, pc})
604 1:              subs    r2, r2, #32
605                 blt     2f
606                 ldmia   r1!, {r4, r5, r6, r7}
607                 OUT(r4)
608                 OUT(r5)
609                 OUT(r6)
610                 OUT(r7)
611                 ldmia   r1!, {r4, r5, r6, r7}
612                 OUT(r4)
613                 OUT(r5)
614                 OUT(r6)
615                 OUT(r7)
616                 bne     1b
617                 LOADREGS(ea, fp, {r4 - r8, fp, sp, pc})
618 2:              adds    r2, r2, #32
619                 LOADREGS(eqea, fp, {r4 - r8, fp, sp, pc})
620 3:              ldr     r4, [r1],#2
621                 mov     r4, r4, lsl#16
622                 orr     r4, r4, r4, lsr#16
623                 str     r4, [r3, r0, lsl#2]
624                 subs    r2, r2, #2
625                 bgt     3b
626                 LOADREGS(ea, fp, {r4 - r8, fp, sp, pc})
628 #endif