URL
https://opencores.org/ocsvn/or1k_old/or1k_old/trunk
Subversion Repositories or1k_old
Compare Revisions
- This comparison shows the changes necessary to convert path
/or1k_old/trunk/rc203soc/sw/uClinux/arch/armnommu/lib
- from Rev 1765 to Rev 1782
- ↔ Reverse comparison
Rev 1765 → Rev 1782
/irqs-acorn.S
0,0 → 1,378
/* |
* linux/arch/arm/lib/irqs.S |
* |
* Copyright (C) 1995, 1996 Russell King. (rmk@ecs.soton.ac.uk) |
* |
* Interrupt wrappers - handles disabling & re-enabling interrupts |
* |
* Changes: |
* 09/02/1996 RMK Stream-lined normal interrupt wrapper - now uses 78 |
* cycles instead of 85 and 3 less instructions. |
* 08/09/1996 RMK Changed spec - now does not allow for disable & enable |
* of the executing interrupt. |
* IRQ13 is special - it always is entered with IRQs disabled. |
* IRQ14 & 15 are special - the IRQ is disabled in IOC |
* but interrupts are enabled. It is expected that the |
* interrupt routine will re-enable the relevent IRQ... |
*/ |
|
#include <asm/assembler.h> |
|
@ IRQ stubs |
|
@ IRQ stubs entered with: |
@ r1 = IOC |
@ r2 = IRQ number |
@ return 0 for normal irq |
|
.text |
#define BAD_IRQ(n, msk, reg) \ |
.global _bad_IRQ##n##_interrupt ;\ |
_bad_IRQ##n##_interrupt: ;\ |
stmfd sp!, {lr} ;\ |
ldrb r0, [r4, $reg] ;\ |
bic r0, r0, $msk ;\ |
strb r0, [r4, $reg] ;\ |
bl _bad_IRQ ;\ |
mov r0, $1 ;\ |
LOADREGS(fd, sp!, {pc}) |
|
BAD_IRQ( 0, 0x01, 0x18) |
BAD_IRQ( 1, 0x02, 0x18) |
BAD_IRQ( 2, 0x04, 0x18) |
BAD_IRQ( 3, 0x08, 0x18) |
BAD_IRQ( 4, 0x10, 0x18) |
BAD_IRQ( 5, 0x20, 0x18) |
BAD_IRQ( 6, 0x40, 0x18) |
BAD_IRQ( 7, 0x80, 0x18) |
BAD_IRQ( 8, 0x01, 0x28) |
BAD_IRQ( 9, 0x02, 0x28) |
BAD_IRQ(10, 0x04, 0x28) |
BAD_IRQ(11, 0x08, 0x28) |
BAD_IRQ(12, 0x10, 0x28) |
BAD_IRQ(13, 0x20, 0x28) |
BAD_IRQ(14, 0x40, 0x28) |
BAD_IRQ(15, 0x80, 0x28) |
BAD_IRQ(16, 0x01, 0x1f8) |
BAD_IRQ(17, 0x02, 0x1f8) |
BAD_IRQ(18, 0x04, 0x1f8) |
BAD_IRQ(19, 0x08, 0x1f8) |
BAD_IRQ(20, 0x10, 0x1f8) |
BAD_IRQ(21, 0x20, 0x1f8) |
BAD_IRQ(22, 0x40, 0x1f8) |
BAD_IRQ(23, 0x80, 0x1f8) |
|
#define FAST_IRQ8(n) \ |
.globl _fast_IRQ##n##_interrupt ;\ |
_fast_IRQ##n##_interrupt: ;\ |
mov r9, lr ;\ |
ldrb r2, [r4, $0x18] ;\ |
bic r2, r2, $1 << n ;\ |
strb r2, [r4, $0x18] ;\ |
mov r6, $1 << n ;\ |
strb r6, [r4, $0x14] ;\ |
ldr r5, LC1 ;\ |
ldr r7, [r5] ;\ |
add r2, r7, $1 ;\ |
str r2, [r5] ;\ |
bl _do_fast_IRQ ;\ |
DISABLEIRQS(r0) ;\ |
str r7, [r5] ;\ |
ldrb r0, [r4, $0x18] ;\ |
orr r0, r0, $1 << n ;\ |
strb r0, [r4, $0x18] ;\ |
mov r0, $1 ;\ |
RETINSTR(mov,pc,r9) |
|
#define FAST_IRQ16(n) \ |
.globl _fast_IRQ##n##_interrupt ;\ |
_fast_IRQ##n##_interrupt: ;\ |
mov r9, lr ;\ |
ldrb r2, [r4, $0x28] ;\ |
bic r2, r2, $1 << (n - 8) ;\ |
strb r2, [r4, $0x28] ;\ |
ldr r5, LC1 ;\ |
ldr r7, [r5] ;\ |
add r2, r7, $1 ;\ |
str r2, [r5] ;\ |
bl _do_fast_IRQ ;\ |
DISABLEIRQS(r0) ;\ |
str r7, [r5] ;\ |
ldrb r0, [r4, $0x28] ;\ |
orr r0, r0, $1 << (n - 8) ;\ |
strb r0, [r4, $0x28] ;\ |
mov r0, $1 ;\ |
RETINSTR(mov,pc,r9) |
|
#define FAST_IRQ24(n) \ |
.globl _fast_IRQ##n##_interrupt ;\ |
_fast_IRQ##n##_interrupt: ;\ |
mov r9, lr ;\ |
ldrb r2, [r4, $0x1f8] ;\ |
bic r2, r2, $1 << (n - 16) ;\ |
strb r2, [r4, $0x1f8] ;\ |
ldr r5, LC1 ;\ |
ldr r7, [r5] ;\ |
add r2, r7, $1 ;\ |
str r2, [r5] ;\ |
bl _do_fast_IRQ ;\ |
DISABLEIRQS(r0) ;\ |
str r7, [r5] ;\ |
ldrb r0, [r4, $0x1f8] ;\ |
orr r0, r0, $1 << (n - 16) ;\ |
strb r0, [r4, $0x1f8] ;\ |
mov r0, $1 ;\ |
RETINSTR(mov,pc,r9) |
|
FAST_IRQ8 ( 0) |
FAST_IRQ8 ( 1) |
FAST_IRQ8 ( 2) |
FAST_IRQ8 ( 3) |
FAST_IRQ8 ( 4) |
FAST_IRQ8 ( 5) |
FAST_IRQ8 ( 6) |
FAST_IRQ8 ( 7) |
FAST_IRQ16( 8) |
FAST_IRQ16( 9) |
FAST_IRQ16(10) |
FAST_IRQ16(11) |
FAST_IRQ16(12) |
|
LC1: .word _intr_count |
|
.globl _fast_IRQ13_interrupt |
_fast_IRQ13_interrupt: |
mov r9, lr |
ldr r5, LC1 |
ldr r7, [r5] |
add r2, r7, #1 |
str r2, [r5] |
bl _do_fast_IRQ |
str r7, [r5] |
mov r0, #1 |
RETINSTR(mov,pc,r9) |
|
.globl _fast_IRQ14_interrupt |
_fast_IRQ14_interrupt: |
mov r9, lr |
ldrb r2, [r4, #0x28] |
bic r2, r2, #1 << 6 |
strb r2, [r4, #0x28] |
ldr r5, LC1 |
ldr r7, [r5] |
add r2, r7, #1 |
str r2, [r5] |
bl _do_fast_IRQ |
str r7, [r5] |
mov r0, #1 |
RETINSTR(mov,pc,r9) |
|
FAST_IRQ16(15) |
FAST_IRQ24(16) |
FAST_IRQ24(17) |
FAST_IRQ24(18) |
FAST_IRQ24(19) |
FAST_IRQ24(20) |
FAST_IRQ24(21) |
FAST_IRQ24(22) |
FAST_IRQ24(23) |
|
#define NORM_IRQ8(n) \ |
.global _IRQ##n##_interrupt ;\ |
_IRQ##n##_interrupt: ;\ |
mov r9, lr ;\ |
ldrb r2, [r4, $0x18] ;\ |
bic r2, r2, $1 << n ;\ |
strb r2, [r4, $0x18] ;\ |
mov r6, $1 << n ;\ |
strb r6, [r4, $0x14] ;\ |
ldr r5, LC2 ;\ |
ldr r7, [r5] ;\ |
add r2, r7, $1 ;\ |
str r2, [r5] ;\ |
ENABLEIRQS(r2) ;\ |
bl _do_IRQ ;\ |
DISABLEIRQS(r0) ;\ |
str r7, [r5] ;\ |
ldrb r0, [r4, $0x18] ;\ |
orr r0, r0, $1 << n ;\ |
strb r0, [r4, $0x18] ;\ |
mov r0, $0 ;\ |
RETINSTR(mov,pc,r9) |
|
#define NORM_IRQ16(n) \ |
.global _IRQ##n##_interrupt ;\ |
_IRQ##n##_interrupt: ;\ |
mov r9, lr ;\ |
ldrb r2, [r4, $0x28] ;\ |
bic r2, r2, $1 << (n - 8) ;\ |
strb r2, [r4, $0x28] ;\ |
ldr r5, LC2 ;\ |
ldr r7, [r5] ;\ |
add r2, r7, $1 ;\ |
str r2, [r5] ;\ |
ENABLEIRQS(r2) ;\ |
bl _do_IRQ ;\ |
DISABLEIRQS(r2) ;\ |
str r7, [r5] ;\ |
ldrb r0, [r4, $0x28] ;\ |
orr r0, r0, $1 << (n - 8) ;\ |
strb r0, [r4, $0x28] ;\ |
mov r0, $0 ;\ |
RETINSTR(mov,pc,r9) |
|
#define NORM_IRQ24(n) \ |
.globl _IRQ##n##_interrupt ;\ |
_IRQ##n##_interrupt: ;\ |
mov r9, lr ;\ |
ldrb r2, [r4, $0x1f8] ;\ |
bic r2, r2, $1 << (n - 16) ;\ |
strb r2, [r4, $0x1f8] ;\ |
ldr r5, LC2 ;\ |
ldr r7, [r5] ;\ |
add r2, r7, $1 ;\ |
str r2, [r5] ;\ |
ENABLEIRQS(r2) ;\ |
bl _do_IRQ ;\ |
DISABLEIRQS(r2) ;\ |
str r7, [r5] ;\ |
ldrb r0, [r4, $0x1f8] ;\ |
orr r0, r0, $1 << (n - 16) ;\ |
strb r0, [r4, $0x1f8] ;\ |
mov r0, $0 ;\ |
RETINSTR(mov,pc,r9) |
|
NORM_IRQ8 ( 0) |
NORM_IRQ8 ( 1) |
NORM_IRQ8 ( 2) |
NORM_IRQ8 ( 3) |
NORM_IRQ8 ( 4) |
|
.globl _timer_IRQ_interrupt |
_timer_IRQ_interrupt: |
mov r9, lr |
ldrb r2, [r4, #0x18] |
bic r2, r2, #1 << 5 |
strb r2, [r4, #0x18] |
mov r2, #1 << 5 |
strb r2, [r4, #0x14] |
ldr r5, LC1 |
ldr r7, [r5] |
add r2, r7, #1 |
str r2, [r5] |
bl _do_IRQ |
str r7, [r5] |
ldrb r2, [r4, #0x18] |
orr r2, r2, #1 << 5 |
strb r2, [r4, #0x18] |
mov r0, #0 |
RETINSTR(mov,pc,r9) |
|
NORM_IRQ8 ( 6) |
NORM_IRQ8 ( 7) |
NORM_IRQ16( 8) |
NORM_IRQ16( 9) |
NORM_IRQ16(10) |
NORM_IRQ16(11) |
NORM_IRQ16(12) |
|
LC2: .word _intr_count |
|
.globl _IRQ13_interrupt |
_IRQ13_interrupt: |
mov r9, lr |
ldr r5, LC2 |
ldr r7, [r5] |
add r2, r7, #1 |
str r2, [r5] |
bl _do_IRQ |
str r7, [r5] |
mov r0, #0 |
RETINSTR(mov,pc,r9) |
|
.globl _IRQ14_interrupt |
_IRQ14_interrupt: |
mov r9, lr |
ldrb r2, [r4, #0x28] |
bic r2, r2, #1 << 6 |
strb r2, [r4, #0x28] |
ldr r5, LC2 |
ldr r7, [r5] |
add r2, r7, #1 |
str r2, [r5] |
bl _do_IRQ |
str r7, [r5] |
mov r0, #0 |
RETINSTR(mov,pc,r9) |
|
NORM_IRQ16(15) |
NORM_IRQ24(16) |
NORM_IRQ24(17) |
NORM_IRQ24(18) |
NORM_IRQ24(19) |
NORM_IRQ24(20) |
NORM_IRQ24(21) |
NORM_IRQ24(22) |
NORM_IRQ24(23) |
|
#define PROBE_IRQ8(n, v1) \ |
.global _probe_IRQ##n##_interrupt ;\ |
_probe_IRQ##n##_interrupt: ;\ |
ldrb r0, [r4, $0x18] ;\ |
bic r0, r0, $ v1 ;\ |
strb r0, [r4, $0x18] ;\ |
mov r0, $ v1 ;\ |
strb r0, [r4, $0x14] ;\ |
mov r0, $1 ;\ |
RETINSTR(mov,pc,lr) |
|
#define PROBE_IRQ16(n, v1) \ |
.global _probe_IRQ##n##_interrupt ;\ |
_probe_IRQ##n##_interrupt: ;\ |
ldrb r0, [r4, $0x28] ;\ |
bic r0, r0, $ v1 ;\ |
strb r0, [r4, $0x28] ;\ |
mov r0, $1 ;\ |
RETINSTR(mov,pc,lr) |
|
#define PROBE_IRQ24(n, v1) \ |
.global _probe_IRQ##n##_interrupt ;\ |
_probe_IRQ##n##_interrupt: ;\ |
ldrb r0, [r4, $0x1f8] ;\ |
bic r0, r0, $ v1 ;\ |
strb r0, [r4, $0x1f8] ;\ |
mov r0, $1 ;\ |
RETINSTR(mov,pc,lr) |
|
PROBE_IRQ8 ( 0, 1) |
PROBE_IRQ8 ( 1, 2) |
PROBE_IRQ8 ( 2, 4) |
PROBE_IRQ8 ( 3, 8) |
PROBE_IRQ8 ( 4, 16) |
PROBE_IRQ8 ( 5, 32) |
PROBE_IRQ8 ( 6, 64) |
PROBE_IRQ8 ( 7, 128) |
PROBE_IRQ16( 8, 1) |
PROBE_IRQ16( 9, 2) |
PROBE_IRQ16(10, 4) |
PROBE_IRQ16(11, 8) |
PROBE_IRQ16(12, 16) |
PROBE_IRQ16(13, 32) |
PROBE_IRQ16(14, 64) |
PROBE_IRQ16(15, 128) |
PROBE_IRQ24(16, 1) |
PROBE_IRQ24(17, 2) |
PROBE_IRQ24(18, 4) |
PROBE_IRQ24(19, 8) |
PROBE_IRQ24(20, 16) |
PROBE_IRQ24(21, 32) |
PROBE_IRQ24(22, 64) |
PROBE_IRQ24(23, 128) |
|
.global _bad_IRQ |
_bad_IRQ: adr r0, Lmsg |
mov r1, r2 |
b _printk |
|
Lmsg: .ascii "Bad interrupt %d received!\n\0" |
.align |
/backtrace.S
0,0 → 1,108
/* |
* linux/arch/arm/lib/backtrace.S |
* |
* Copyright (C) 1995, 1996 Russell King |
*/ |
|
#include <asm/assembler.h> |
.text |
|
@ fp is 0 or stack frame |
|
#define frame r4 |
#define next r5 |
#define save r6 |
#define mask r7 |
#define offset r8 |
|
.global ___backtrace,__backtrace |
__backtrace: |
___backtrace: |
#ifdef __arm6__ |
mrs r1, cpsr |
#else |
mov r1, pc |
and r1, r1, #0xfc000003 |
#endif |
mov r0, fp |
|
.global _c_backtrace,c_backtrace |
c_backtrace: |
_c_backtrace: stmfd sp!, {r4 - r8, lr} @ Save an extra register so we have a location... |
tst r1, #0x10 @ 26 or 32-bit? |
moveq mask, #0xfc000003 |
movne mask, #0 |
tst mask, r0 |
movne r0, #0 |
movs frame, r0 |
Lbadbacktrace: moveq r0, #-2 |
LOADREGS(eqfd, sp!, {r4 - r8, pc}) |
|
Lst: stmfd sp!, {pc} @ calculate offset of PC in STMIA instruction |
ldr r0, [sp], #4 |
adr r1, Lst - 4 |
sub offset, r0, r1 |
|
Lloop: tst frame, mask @ Check for address exceptions... |
bne Lbadbacktrace |
|
ldmda frame, {r0, r1, r2, r3} @ fp, sp, lr, pc |
mov next, r0 |
|
sub save, r3, offset @ Correct PC for prefetching |
bic save, save, mask |
adr r0, Lfe |
mov r1, save |
bic r2, r2, mask |
bl printk |
|
sub r0, frame, #16 |
ldr r1, [save, #4] |
mov r3, r1, lsr #10 |
ldr r2, Ldsi+4 |
teq r3, r2 @ Check for stmia sp!, {args} |
addeq save, save, #4 @ next instruction |
bleq Ldumpstm |
|
ldr r1, [save, #4] @ Get 'stmia sp!, {rlist, fp, ip, lr, pc}' instruction |
mov r3, r1, lsr #10 |
ldr r2, Ldsi |
teq r3, r2 |
bleq Ldumpstm |
|
teq frame, next |
movne frame, next |
teqne frame, #0 |
bne Lloop |
LOADREGS(fd, sp!, {r4 - r8, pc}) |
|
|
#define instr r4 |
#define reg r5 |
#define stack r6 |
|
Ldumpstm: stmfd sp!, {instr, reg, stack, lr} |
mov stack, r0 |
mov instr, r1 |
mov reg, #9 |
|
1: mov r3, #1 |
tst instr, r3, lsl reg |
beq 2f |
ldr r2, [stack], #-4 |
mov r1, reg |
adr r0, Lfp |
bl printk |
2: subs reg, reg, #1 |
bpl 1b |
|
mov r0, stack |
LOADREGS(fd, sp!, {instr, reg, stack, pc}) |
|
Lfe: .ascii "Function entered at [<%p>] from [<%p>]\n" |
.byte 0 |
Lfp: .ascii " r%d = %p\n" |
.byte 0 |
.align |
Ldsi: .word 0x00e92dd8 >> 2 |
.word 0x00e92d00 >> 2 |
/io-ebsa.S
0,0 → 1,149
/* |
* linux/arch/arm/lib/io.S |
* |
* Copyright (C) 1995, 1996 Russell King |
*/ |
|
#include <asm/assembler.h> |
.text |
.align |
|
#define OUT(reg) \ |
mov r8, reg, lsl $16 ;\ |
orr r8, r8, r8, lsr $16 ;\ |
str r8, [r3, r0, lsl $2] ;\ |
mov r8, reg, lsr $16 ;\ |
orr r8, r8, r8, lsl $16 ;\ |
str r8, [r3, r0, lsl $2] |
|
#define IN(reg) \ |
ldr reg, [r0] ;\ |
and reg, reg, ip ;\ |
ldr lr, [r0] ;\ |
orr reg, reg, lr, lsl $16 |
|
@ Purpose: read a block of data from a hardware register to memory. |
@ Proto : insw(int from_port, void *to, int len_in_words); |
@ Proto : inswb(int from_port, void *to, int len_in_bytes); |
@ Notes : increment to |
|
.global _insw |
.global _inswb |
_insw: mov r2, r2, lsl#1 |
_inswb: mov ip, sp |
stmfd sp!, {r4 - r10 ,fp ,ip ,lr ,pc} |
sub fp, ip, #4 |
cmp r0, #0x00c00000 |
movge r3, #0 |
movlt r3, #0xf0000000 |
add r0, r3, r0, lsl #2 |
tst r1, #3 |
beq Linswok |
tst r1, #1 |
bne Linsw_notaligned |
cmp r2, #1 |
ldrge r4, [r0] |
strgeb r4, [r1], #1 |
movgt r4, r4, LSR#8 |
strgtb r4, [r1], #1 |
ldmleea fp, {r4 - r10, fp, sp, pc}^ |
sub r2, r2, #2 |
Linswok: mov ip, #0xFF |
orr ip, ip, ip, lsl #8 |
Linswlp: subs r2, r2, #64 |
bmi Linsw_toosmall |
IN(r3) |
IN(r4) |
IN(r5) |
IN(r6) |
IN(r7) |
IN(r8) |
IN(r9) |
IN(r10) |
stmia r1!, {r3 - r10} |
IN(r3) |
IN(r4) |
IN(r5) |
IN(r6) |
IN(r7) |
IN(r8) |
IN(r9) |
IN(r10) |
stmia r1!, {r3 - r10} |
bne Linswlp |
LOADREGS(ea, fp, {r4 - r10, fp, sp, pc}) |
Linsw_toosmall: |
add r2, r2, #32 |
bmi Linsw_toosmall2 |
Linsw2lp: IN(r3) |
IN(r4) |
IN(r5) |
IN(r6) |
IN(r7) |
IN(r8) |
IN(r9) |
IN(r10) |
stmia r1!, {r3 - r10} |
LOADREGS(eqea, fp, {r4 - r10, fp, sp, pc}) |
b Linsw_notaligned |
Linsw_toosmall2: |
add r2, r2, #32 |
Linsw_notaligned: |
cmp r2, #1 |
LOADREGS(ltea, fp, {r4 - r10, fp, sp, pc}) |
ldr r4, [r0] |
strb r4, [r1], #1 |
movgt r4, r4, LSR#8 |
strgtb r4, [r1], #1 |
subs r2, r2, #2 |
bgt Linsw_notaligned |
LOADREGS(ea, fp, {r4 - r10, fp, sp, pc}) |
|
@ Purpose: write a block of data from memory to a hardware register. |
@ Proto : outsw(int to_reg, void *from, int len_in_words); |
@ Proto : outswb(int to_reg, void *from, int len_in_bytes); |
@ Notes : increments from |
|
.global _outsw |
.global _outswb |
_outsw: mov r2, r2, LSL#1 |
_outswb: mov ip, sp |
stmfd sp!, {r4 - r8, fp, ip, lr, pc} |
sub fp, ip, #4 |
cmp r0, #0x00c00000 |
movge r3, #0 |
movlt r3, #0xf0000000 |
tst r1, #2 |
beq Loutsw32lp |
ldr r4, [r1], #2 |
mov r4, r4, lsl #16 |
orr r4, r4, r4, lsr #16 |
str r4, [r3, r0, lsl #2] |
sub r2, r2, #2 |
teq r2, #0 |
LOADREGS(eqea, fp, {r4 - r8, fp, sp, pc}) |
Loutsw32lp: subs r2,r2,#32 |
blt Loutsw_toosmall |
ldmia r1!,{r4,r5,r6,r7} |
OUT(r4) |
OUT(r5) |
OUT(r6) |
OUT(r7) |
ldmia r1!,{r4,r5,r6,r7} |
OUT(r4) |
OUT(r5) |
OUT(r6) |
OUT(r7) |
LOADREGS(eqea, fp, {r4 - r8, fp, sp, pc}) |
b Loutsw32lp |
Loutsw_toosmall: |
adds r2,r2,#32 |
LOADREGS(eqea, fp, {r4 - r8, fp, sp, pc}) |
Llpx: ldr r4,[r1],#2 |
mov r4,r4,LSL#16 |
orr r4,r4,r4,LSR#16 |
str r4,[r3,r0,LSL#2] |
subs r2,r2,#2 |
bgt Llpx |
LOADREGS(ea, fp, {r4 - r8, fp, sp, pc}) |
|
/fp_support.c
0,0 → 1,30
/* |
* linux/arch/arm/lib/fp_support.c |
* |
* Copyright (C) 1995, 1996 Russell King |
*/ |
|
#include <linux/sched.h> |
|
extern void (*fp_save)(struct fp_soft_struct *); |
#if 0 |
__asm__( |
".stabs \"fp_printk\", 11, 0, 0, 0\n\t" |
".stabs \"printk\", 1, 0, 0, 0\n\t" |
".stabs \"fp_current\", 11, 0, 0, 0\n\t" |
".stabs \"current_set\", 1, 0, 0, 0\n\t" |
".stabs \"fp_send_sig\", 11, 0, 0, 0\n\t" |
".stabs \"send_sig\", 1, 0, 0, 0\n\t"); |
#endif |
|
void fp_setup(void) |
{ |
struct task_struct **p; |
|
p = task; |
do { |
if(*p) |
fp_save(&(*p)->tss.fpstate.soft); |
} |
while (++p < task + NR_TASKS); |
} |
/system.S
0,0 → 1,32
/* |
* linux/arch/arm/lib/system.S |
* |
* Copyright (C) 1995, 1996 Russell King |
* |
* 07/06/96: Now support tasks running in SVC mode. |
*/ |
|
#include <linux/config.h> |
#include <asm/assembler.h> |
|
.text |
.global _abort |
_abort: adr r0, Labort_msg |
mov r1, lr |
b _panic |
|
Labort_msg: .ascii "Eek! Got to an abort() from %p! " |
.ascii "(Please report to rmk@ecs.soton.ac.uk)\n\0" |
.align |
|
#ifdef CONFIG_ARCH_EBSA |
/* |
* The StrongARM evaluation board doesn't have these, so |
* we make dummy functions in here until we sort them out |
*/ |
.globl _ecard_reset |
.globl _ecard_init |
_ecard_reset: |
_ecard_init: |
mov pc, lr |
#endif |
/extractinfo.perl
0,0 → 1,39
#!/usr/bin/perl |
|
$OBJDUMP=$ARGV[0]; |
|
sub swapdata { |
local ($num) = @_; |
|
return substr($num, 6, 2).substr($num, 4, 2).substr ($num, 2, 2).substr ($num, 0, 2); |
} |
|
open (DATA, $OBJDUMP.' --full-contents --section=.data getconsdata.o | grep \'^ 00\' |') || |
die ('Cant objdump!'); |
#print "phase 1\n"; |
while (<DATA>) { |
($addr, $data0, $data1, $data2, $data3) = split (' '); |
# print "$addr, $data0, $data1, $data2, $data3\n"; |
$dat[hex($addr)] = hex(&swapdata($data0)); |
$dat[hex($addr)+4] = hex(&swapdata($data1)); |
$dat[hex($addr)+8] = hex(&swapdata($data2)); |
$dat[hex($addr)+12] = hex(&swapdata($data3)); |
} |
close (DATA); |
|
# print "phase 2\n"; |
open (DATA, $OBJDUMP.' --syms getconsdata.o | grep \' O .data\' |') || |
die ('Cant objdump!'); |
while (<DATA>) { |
($addr, $flag1, $flag2, $sect, $size, $name) = split (' '); |
# print "$addr, $flag1, $flag2, $sect, $size, $name\n"; |
$nam[hex($addr)] = $name; |
} |
close (DATA); |
|
# print "phase 3\n"; |
print "/*\n * *** THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT! ***\n */\n"; |
for ($i = 0; $i < hex($addr)+12; $i ++) { |
print "unsigned long $nam[$i] = $dat[$i];\n" if $dat[$i]; |
print "#define __HAS_$nam[$i]\n" if $dat[$i]; |
} |
/irqs-ebsa.S
0,0 → 1,114
/* |
* linux/arch/arm/lib/irqs.S |
* |
* Copyright (C) 1995, 1996 Russell King. (rmk@ecs.soton.ac.uk) |
* |
* Interrupt wrappers - handles disabling & re-enabling interrupts |
*/ |
|
#include <asm/assembler.h> |
|
@ IRQ stubs |
|
@ IRQ stubs entered with: |
@ r0 = IRQ number |
@ r1 = regs |
@ r4 = IRQ_MSKD (only for CTB_OS) |
@ return 0 for normal irq |
|
.text |
/* |
* Disable interrupt & print a message |
*/ |
LC0: .long _intr_count |
|
.globl _bad_IRQ_interrupt |
_bad_IRQ_interrupt: |
mov r9, lr |
mov r5, #1 |
mov r5, r5, lsl r0 |
strb r5, [r4] |
bl _bad_IRQ |
mov r0, #0 |
mov pc, r9 |
|
.globl _fast_IRQ_interrupt |
_fast_IRQ_interrupt: |
mov r9, lr |
mov r5, #1 |
mov r5, r5, lsl r0 |
strb r5, [r4] |
ldr r6, LC0 |
ldr r7, [r6] |
add r2, r7, #1 |
str r2, [r6] |
bl _do_IRQ |
mrs r2, cpsr |
orr r2, r2, #I_BIT |
msr cpsr, r2 |
str r7, [r6] |
sub r4, r4, #0x400000 |
strb r5, [r4] |
mov r0, #1 |
mov pc, r9 |
|
.globl _IRQ_interrupt |
_IRQ_interrupt: |
mov r9, lr |
mov r5, #1 |
mov r5, r5, lsl r0 |
strb r5, [r4] @ Disable interrupt source |
ldr r6, LC0 |
ldr r7, [r6] |
add r2, r7, #1 |
str r2, [r6] |
mrs r8, cpsr @ Enable interrupts |
bic r2, r8, #I_BIT |
msr cpsr, r2 |
bl _do_IRQ |
msr cpsr, r8 @ Restore interrupts |
str r7, [r6] |
sub r4, r4, #0x400000 |
strb r5, [r4] @ Re-enable interrupt source |
mov r0, #0 |
mov pc, r9 |
|
.globl _timer_IRQ_interrupt |
_timer_IRQ_interrupt: |
mov r9, lr |
mov r5, #1 |
mov r5, r5, lsl r0 |
strb r5, [r4] @ Disable interrupt source |
ldr r6, LC0 |
ldr r7, [r6] |
add r2, r7, #1 |
str r2, [r6] |
mrs r8, cpsr |
bl _do_IRQ |
msr cpsr, r8 @ Restore interrupts |
str r7, [r6] |
sub r4, r4, #0x400000 |
strb r5, [r4] @ Re-enable interrupt source |
mov r0, #0 |
mov pc, r9 |
|
.globl _probe_IRQ_interrupt |
_probe_IRQ_interrupt: |
mov r9, lr |
mov r5, #1 |
mov r5, r5, lsl r0 |
add r6, r4, #0x400000 |
strb r5, [r6] |
ldr r6, LC0+4 |
ldrb r4, [r6] |
bic r4, r4, r5 |
strb r4, [r6] |
mov pc, r9 |
|
.global _bad_IRQ |
_bad_IRQ: mov r1, r0 |
adr r0, Lmsg |
b _printk |
|
Lmsg: .ascii "Bad interrupt %d received!\n\0" |
.align |
/loaders.S
0,0 → 1,52
/* |
* linux/arch/arm/lib/loaders.S |
* |
* This file contains the ROM loaders for buggy cards |
*/ |
#include <asm/assembler.h> |
|
/* |
* Oak SCSI |
*/ |
.globl _oak_scsi_loader |
_oak_scsi_loader: b Loak_scsi_read |
.word 0 |
Loak_scsi_reset: bic r10, r11, #0x00ff0000 |
ldr r2, [r10] |
RETINSTR(mov,pc,lr) |
|
Loak_scsi_read: mov r2, r1, lsr #3 |
and r2, r2, #15 << 9 |
bic r10, r11, #0x00ff0000 |
ldr r2, [r10, r2] |
mov r2, r1, lsl #20 |
ldrb r0, [r11, r2, lsr #18] |
ldr r2, [r10] |
RETINSTR(mov,pc,lr) |
|
.globl _atomwide_serial_loader |
_atomwide_serial_loader: |
b Latomwide_serial_read |
.word 0 |
Latomwide_serial_reset: mov r2, #0x3c00 |
strb r2, [r11, r2] |
RETINSTR(mov,pc,lr) |
|
Latomwide_serial_read: cmp r1, #0x8000 |
RETINSTR(movhi,pc,lr) |
add r0, r1, #0x800 |
mov r0, r0, lsr #11 |
mov r3, #0x3c00 |
strb r0, [r11, r3] |
mov r2, r1, lsl #21 |
ldrb r0, [r11, r2, lsr #19] |
strb r2, [r11, r3] |
RETINSTR(mov,pc,lr) |
|
/* |
* Cards we don't know about yet |
*/ |
.globl _noloader |
_noloader: mov r0, r0 |
mov r0, #0 |
RETINSTR(mov,pc,lr) |
/floppydma.S
0,0 → 1,61
/* |
* linux/arch/arm/lib/floppydma.S |
* |
* Copyright (C) 1995, 1996 Russell King |
*/ |
|
#include <asm/assembler.h> |
.text |
|
.global _floppy_fiqin_start |
.global _floppy_fiqin_end |
_floppy_fiqin_start: |
subs r9, r9, #1 |
ldrgtb r12, [r11, #-4] |
ldrleb r12, [r11], #0 |
strb r12, [r10], #1 |
subs pc, lr, #4 |
_floppy_fiqin_end: |
|
.global _floppy_fiqout_start |
.global _floppy_fiqout_end |
_floppy_fiqout_start: |
subs r9, r9, #1 |
ldrgeb r12, [r10], #1 |
movlt r12, #0 |
strleb r12, [r11], #0 |
subles pc, lr, #4 |
strb r12, [r11, #-4] |
subs pc, lr, #4 |
_floppy_fiqout_end: |
|
@ Params: |
@ r0 = length |
@ r1 = address |
@ r2 = floppy port |
@ Puts these into R9_fiq, R10_fiq, R11_fiq |
.global _floppy_fiqsetup |
_floppy_fiqsetup: |
mov ip, sp |
stmfd sp!, {fp, ip, lr, pc} |
sub fp, ip, #4 |
MODE(r3,ip,I_BIT|F_BIT|DEFAULT_FIQ) @ disable FIQs, IRQs, FIQ mode |
mov r0, r0 |
mov r9, r0 |
mov r10, r1 |
mov r11, r2 |
RESTOREMODE(r3) @ back to normal |
mov r0, r0 |
LOADREGS(ea,fp,{fp, sp, pc}) |
|
.global _floppy_fiqresidual |
_floppy_fiqresidual: |
mov ip, sp |
stmfd sp!, {fp, ip, lr, pc} |
sub fp, ip, #4 |
MODE(r3,ip,I_BIT|F_BIT|DEFAULT_FIQ) @ disable FIQs, IRQs, FIQ mode |
mov r0, r0 |
mov r0, r9 |
RESTOREMODE(r3) |
mov r0, r0 |
LOADREGS(ea,fp,{fp, sp, pc}) |
/getconstants.c
0,0 → 1,76
/* |
* linux/arch/arm/lib/getconstants.c |
* |
* Copyright (C) 1995, 1996 Russell King |
*/ |
|
#include <linux/mm.h> |
#include <asm/pgtable.h> |
#include <stdio.h> |
#include <linux/unistd.h> |
|
void printdef(char *def, int no) |
{ |
printf("#define %s\t%d\n", def, no); |
} |
|
#include "getconstants.h" |
|
int main() |
{ |
printf("/*\n * contants.h generated by getconstants\n * DO NOT EDIT!\n */\n"); |
|
printf("#define _current\t_%s\n", "current_set"); |
|
#ifdef _PAGE_PRESENT |
printdef("PAGE_PRESENT", _PAGE_PRESENT); |
#endif |
#ifdef _PAGE_RW |
printdef("PAGE_RW", _PAGE_RW); |
#endif |
#ifdef _PAGE_USER |
printdef("PAGE_USER", _PAGE_USER); |
#endif |
#ifdef _PAGE_ACCESSED |
printdef("PAGE_ACCESSED", _PAGE_ACCESSED); |
#endif |
#ifdef _PAGE_DIRTY |
printdef("PAGE_DIRTY", _PAGE_DIRTY); |
#endif |
#ifdef _PAGE_READONLY |
printdef("PAGE_READONLY", _PAGE_READONLY); |
#endif |
#ifdef _PAGE_NOT_USER |
printdef("PAGE_NOT_USER", _PAGE_NOT_USER); |
#endif |
#ifdef _PAGE_OLD |
printdef("PAGE_OLD", _PAGE_OLD); |
#endif |
#ifdef _PAGE_CLEAN |
printdef("PAGE_CLEAN", _PAGE_CLEAN); |
#endif |
#ifdef __HAS_tss_memmap |
printdef("TSS_MEMMAP", (int)tss_memmap); |
#endif |
#ifdef __HAS_tss_save |
printdef("TSS_SAVE", (int)tss_save); |
#endif |
#ifdef __HAS_tss_memcmap |
printdef("TSS_MEMCMAP", (int)tss_memcmap); |
#endif |
#ifdef __HAS_tss_fpesave |
printdef("TSS_FPESAVE", (int)tss_fpesave); |
#endif |
#ifdef __HAS_mm |
printdef("MM", (int)mm); |
#endif |
|
#ifdef __HAS_pgd |
printdef("PGD", (int)pgd); |
#endif |
|
printf("#define KSWI_BASE 0x900000\n"); |
printf("#define KSWI_SYS_BASE 0x9F0000\n"); |
printf("#define SYS_ERROR0 0x9F0000\n"); |
return 0; |
} |
/delay.S
0,0 → 1,45
/* |
* linux/arch/arm/lib/delay.S |
* |
* Copyright (C) 1995, 1996 Russell King |
*/ |
|
#include <asm/assembler.h> |
.text |
|
LC0: .word loops_per_sec |
|
.global _udelay,udelay |
udelay: |
_udelay: mov r2, #0x1000 |
orr r2, r2, #0x00c6 |
mul r1, r0, r2 |
ldr r2, LC0 |
ldr r2, [r2] |
mov r1, r1, lsr #11 |
mov r2, r2, lsr #11 |
mul r0, r1, r2 |
movs r0, r0, lsr #10 |
RETINSTR(moveq,pc,lr) |
|
@ Delay routine |
.global ___delay,__delay |
__delay: |
___delay: subs r0, r0, #1 |
RETINSTR(movcc,pc,lr) |
subs r0, r0, #1 |
RETINSTR(movcc,pc,lr) |
subs r0, r0, #1 |
RETINSTR(movcc,pc,lr) |
subs r0, r0, #1 |
RETINSTR(movcc,pc,lr) |
subs r0, r0, #1 |
RETINSTR(movcc,pc,lr) |
subs r0, r0, #1 |
RETINSTR(movcc,pc,lr) |
subs r0, r0, #1 |
RETINSTR(movcc,pc,lr) |
subs r0, r0, #1 |
bcs ___delay |
RETINSTR(mov,pc,lr) |
|
/bitops.S
0,0 → 1,122
/* |
* linux/arch/arm/lib/bitops.S |
* |
* Copyright (C) 1995, 1996 Russell King |
*/ |
|
#include <asm/assembler.h> |
.text |
|
@ Purpose : Function to set a bit |
@ Prototype: int set_bit(int bit,int *addr) |
|
.globl _set_bit,set_bit |
set_bit: |
_set_bit: add r1, r1, r0, lsr #3 @ Get byte offset |
and r3, r0, #7 @ Get bit offset |
mov r0, #1 |
SAVEIRQS(ip) |
DISABLEIRQS(ip) |
ldrb r2, [r1] |
tst r2, r0, lsl r3 |
orr r2, r2, r0, lsl r3 |
moveq r0, #0 |
strb r2, [r1] |
RESTOREIRQS(ip) |
RETINSTR(mov,pc,lr) |
|
@ Purpose : Function to clear a bit |
@ Prototype: int clear_bit(int bit,int *addr) |
|
.globl _clear_bit,clear_bit |
clear_bit: |
_clear_bit: add r1, r1, r0, lsr #3 @ Get byte offset |
and r3, r0, #7 @ Get bit offset |
mov r0, #1 |
SAVEIRQS(ip) |
DISABLEIRQS(ip) |
ldrb r2, [r1] |
tst r2, r0, lsl r3 |
bic r2, r2, r0, lsl r3 |
moveq r0, #0 |
strb r2, [r1] |
RESTOREIRQS(ip) |
RETINSTR(mov,pc,lr) |
|
/* Purpose : Function to change a bit |
* Prototype: int change_bit(int bit,int *addr) |
*/ |
.globl _change_bit,change_bit |
change_bit: |
_change_bit: add r1, r1, r0, lsr #3 |
and r3, r0, #7 |
mov r0, #1 |
SAVEIRQS(ip) |
DISABLEIRQS(ip) |
ldrb r2, [r1] |
tst r2, r0, lsl r3 |
eor r2, r2, r0, lsl r3 |
moveq r0, #0 |
strb r2, [r1] |
RESTOREIRQS(ip) |
RETINSTR(mov,pc,lr) |
|
@ Purpose : Find a 'zero' bit |
@ Prototype: int find_first_zero_bit(char *addr,int maxbit); |
|
.globl _find_first_zero_bit,find_first_zero_bit |
find_first_zero_bit: |
_find_first_zero_bit: |
mov r2, #0 @ Initialise bit position |
Lfindzbit1lp: ldrb r3, [r0, r2, lsr #3] @ Check byte, if 0xFF, then all bits set |
teq r3, #0xFF |
bne Lfoundzbit |
add r2, r2, #8 |
cmp r2, r1 @ Check to see if we have come to the end |
bcc Lfindzbit1lp |
add r0, r1, #1 @ Make sure that we flag an error |
RETINSTR(mov,pc,lr) |
Lfoundzbit: tst r3, #1 @ Check individual bits |
moveq r0, r2 |
RETINSTR(moveq,pc,lr) |
tst r3, #2 |
addeq r0, r2, #1 |
RETINSTR(moveq,pc,lr) |
tst r3, #4 |
addeq r0, r2, #2 |
RETINSTR(moveq,pc,lr) |
tst r3, #8 |
addeq r0, r2, #3 |
RETINSTR(moveq,pc,lr) |
tst r3, #16 |
addeq r0, r2, #4 |
RETINSTR(moveq,pc,lr) |
tst r3, #32 |
addeq r0, r2, #5 |
RETINSTR(moveq,pc,lr) |
tst r3, #64 |
addeq r0, r2, #6 |
RETINSTR(moveq,pc,lr) |
add r0, r2, #7 |
RETINSTR(mov,pc,lr) |
|
@ Purpose : Find next 'zero' bit |
@ Prototype: int find_next_zero_bit(char *addr,int maxbit,int offset) |
|
.globl _find_next_zero_bit,find_next_zero_bit |
find_next_zero_bit: |
_find_next_zero_bit: |
tst r2, #7 |
beq Lfindzbit1lp @ If new byte, goto old routine |
ldrb r3, [r0, r2, lsr#3] |
orr r3, r3, #0xFF00 @ Set top bits so we wont get confused |
stmfd sp!, {r4} |
and r4, r2, #7 |
mov r3, r3, lsr r4 @ Shift right by no. of bits |
ldmfd sp!, {r4} |
and r3, r3, #0xFF |
teq r3, #0xFF |
orreq r2, r2, #7 |
addeq r2, r2, #1 |
beq Lfindzbit1lp @ If all bits are set, goto old routine |
b Lfoundzbit |
/segment.S
0,0 → 1,612
/* |
* linux/arch/arm/lib/segment.S |
* |
* Copyright (C) 1995, 1996 Russell King |
* Except memcpy/memmove routine. |
*/ |
|
#include <asm/assembler.h> |
.text |
#define ENTER \ |
MOV ip,sp ;\ |
STMFD sp!,{r4-r9,fp,ip,lr,pc} ;\ |
SUB fp,ip,#4 |
|
#define EXIT \ |
LOADREGS(ea, fp, {r4 - r9, fp, sp, pc}) |
|
#define EXITEQ \ |
LOADREGS(eqea, fp, {r4 - r9, fp, sp, pc}) |
|
# Prototype: void memcpy_tofs(void *to,const void *from,unsigned long n); |
|
Lmtfs_dest_not_aligned: |
rsb ip, ip, #4 |
cmp ip, #2 |
ldrb r3, [r1], #1 |
strbt r3, [r0], #1 |
ldrgeb r3, [r1], #1 |
strgebt r3, [r0], #1 |
ldrgtb r3, [r1], #1 |
strgtbt r3, [r0], #1 |
sub r2, r2, ip |
b Lmtfs_dest_aligned |
|
.global ___memcpy_tofs,__memcpy_tofs |
__memcpy_tofs: |
___memcpy_tofs: |
cmp r0, #0x02000000 @ PHYS check |
bge _memcpy_fromfs |
stmfd sp!, {lr} |
cmp r2, #4 |
blt Lmtfs_not_enough |
ands ip, r0, #3 |
bne Lmtfs_dest_not_aligned |
Lmtfs_dest_aligned: |
stmfd sp!, {r4 - r7} |
ands ip, r1, #3 |
bne Lmtfs_src_not_aligned |
/* |
* Seeing as there has to be at least 8 bytes to copy, we can |
* copy one word, and force a user-mode page fault... |
*/ |
|
Lmtfs_0fupi: subs r2, r2, #4 |
addmi ip, r2, #4 |
bmi Lmtfs_0nowords |
ldr r3, [r1], #4 |
strt r3, [r0], #4 |
mov ip, r0, lsl #17 |
rsb ip, ip, #0 |
movs ip, ip, lsr #17 |
beq Lmtfs_0fupi |
/* |
* ip = max no. of bytes to copy before needing another "strt" insn |
*/ |
cmp r2, ip |
movlt ip, r2 |
sub r2, r2, ip |
subs ip, ip, #32 |
blt Lmtfs_0rem8lp |
|
Lmtfs_0cpy8lp: ldmia r1!, {r3 - r6} |
stmia r0!, {r3 - r6} |
ldmia r1!, {r3 - r6} |
stmia r0!, {r3 - r6} |
subs ip, ip, #32 |
bpl Lmtfs_0cpy8lp |
Lmtfs_0rem8lp: cmn ip, #16 |
ldmgeia r1!, {r3 - r6} |
stmgeia r0!, {r3 - r6} |
tst ip, #8 |
ldmneia r1!, {r3 - r4} |
stmneia r0!, {r3 - r4} |
tst ip, #4 |
ldrne r3, [r1], #4 |
strnet r3, [r0], #4 |
ands ip, ip, #3 |
beq Lmtfs_0fupi |
Lmtfs_0nowords: ldmfd sp!, {r4 - r7} |
teq ip, #0 |
LOADREGS(eqfd,sp!,{pc}) |
Lmtfs_nowords: cmp ip, #2 |
ldrb r3, [r1], #1 |
strbt r3, [r0], #1 |
ldrgeb r3, [r1], #1 |
strgebt r3, [r0], #1 |
ldrgtb r3, [r1], #1 |
strgtbt r3, [r0], #1 |
LOADREGS(fd,sp!,{pc}) |
|
Lmtfs_not_enough: |
movs ip, r2 |
bne Lmtfs_nowords |
LOADREGS(fd,sp!,{pc}) |
|
Lmtfs_src_not_aligned: |
bic r1, r1, #3 |
ldr r7, [r1], #4 |
cmp ip, #2 |
bgt Lmtfs_3fupi |
beq Lmtfs_2fupi |
Lmtfs_1fupi: subs r2, r2, #4 |
addmi ip, r2, #4 |
bmi Lmtfs_1nowords |
mov r3, r7, lsr #8 |
ldr r7, [r1], #4 |
orr r3, r3, r7, lsl #24 |
strt r3, [r0], #4 |
mov ip, r0, lsl #17 |
rsb ip, ip, #0 |
movs ip, ip, lsr #17 |
beq Lmtfs_1fupi |
cmp r2, ip |
movlt ip, r2 |
sub r2, r2, ip |
subs ip, ip, #16 |
blt Lmtfs_1rem8lp |
|
Lmtfs_1cpy8lp: mov r3, r7, lsr #8 |
ldmia r1!, {r4 - r7} |
orr r3, r3, r4, lsl #24 |
mov r4, r4, lsr #8 |
orr r4, r4, r5, lsl #24 |
mov r5, r5, lsr #8 |
orr r5, r5, r6, lsl #24 |
mov r6, r6, lsr #8 |
orr r6, r6, r7, lsl #24 |
stmia r0!, {r3 - r6} |
subs ip, ip, #16 |
bpl Lmtfs_1cpy8lp |
Lmtfs_1rem8lp: tst ip, #8 |
movne r3, r7, lsr #8 |
ldmneia r1!, {r4, r7} |
orrne r3, r3, r4, lsl #24 |
movne r4, r4, lsr #8 |
orrne r4, r4, r7, lsl #24 |
stmneia r0!, {r3 - r4} |
tst ip, #4 |
movne r3, r7, lsr #8 |
ldrne r7, [r1], #4 |
orrne r3, r3, r7, lsl #24 |
strnet r3, [r0], #4 |
ands ip, ip, #3 |
beq Lmtfs_1fupi |
Lmtfs_1nowords: teq ip, #0 |
LOADREGS(eqfd,sp!,{r4 - r7, pc}) |
mov r3, r7, lsr #8 |
cmp ip, #2 |
strbt r3, [r0], #1 |
movge r3, r3, lsr #8 |
strgebt r3, [r0], #1 |
movgt r3, r3, lsr #8 |
strgtbt r3, [r0], #1 |
LOADREGS(fd,sp!, {r4 - r7, pc}) |
|
Lmtfs_2fupi: subs r2, r2, #4 |
addmi ip, r2, #4 |
bmi Lmtfs_2nowords |
mov r3, r7, lsr #16 |
ldr r7, [r1], #4 |
orr r3, r3, r7, lsl #16 |
strt r3, [r0], #4 |
mov ip, r0, lsl #17 |
rsb ip, ip, #0 |
movs ip, ip, lsr #17 |
beq Lmtfs_2fupi |
cmp r2, ip |
movlt ip, r2 |
sub r2, r2, ip |
subs ip, ip, #16 |
blt Lmtfs_2rem8lp |
|
Lmtfs_2cpy8lp: mov r3, r7, lsr #16 |
ldmia r1!, {r4 - r7} |
orr r3, r3, r4, lsl #16 |
mov r4, r4, lsr #16 |
orr r4, r4, r5, lsl #16 |
mov r5, r5, lsr #16 |
orr r5, r5, r6, lsl #16 |
mov r6, r6, lsr #16 |
orr r6, r6, r7, lsl #16 |
stmia r0!, {r3 - r6} |
subs ip, ip, #16 |
bpl Lmtfs_2cpy8lp |
Lmtfs_2rem8lp: tst ip, #8 |
movne r3, r7, lsr #16 |
ldmneia r1!, {r4, r7} |
orrne r3, r3, r4, lsl #16 |
movne r4, r4, lsr #16 |
orrne r4, r4, r7, lsl #16 |
stmneia r0!, {r3 - r4} |
tst ip, #4 |
movne r3, r7, lsr #16 |
ldrne r7, [r1], #4 |
orrne r3, r3, r7, lsl #16 |
strnet r3, [r0], #4 |
ands ip, ip, #3 |
beq Lmtfs_2fupi |
Lmtfs_2nowords: teq ip, #0 |
LOADREGS(eqfd,sp!,{r4 - r7, pc}) |
mov r3, r7, lsr #16 |
cmp ip, #2 |
strbt r3, [r0], #1 |
movge r3, r3, lsr #8 |
strgebt r3, [r0], #1 |
ldrgtb r3, [r1], #0 |
strgtbt r3, [r0], #1 |
LOADREGS(fd,sp!,{r4 - r7, pc}) |
|
Lmtfs_3fupi: subs r2, r2, #4 |
addmi ip, r2, #4 |
bmi Lmtfs_3nowords |
mov r3, r7, lsr #24 |
ldr r7, [r1], #4 |
orr r3, r3, r7, lsl #8 |
strt r3, [r0], #4 |
mov ip, r0, lsl #17 |
rsb ip, ip, #0 |
movs ip, ip, lsr #17 |
beq Lmtfs_3fupi |
cmp r2, ip |
movlt ip, r2 |
sub r2, r2, ip |
subs ip, ip, #16 |
blt Lmtfs_3rem8lp |
|
Lmtfs_3cpy8lp: mov r3, r7, lsr #24 |
ldmia r1!, {r4 - r7} |
orr r3, r3, r4, lsl #8 |
mov r4, r4, lsr #24 |
orr r4, r4, r5, lsl #8 |
mov r5, r5, lsr #24 |
orr r5, r5, r6, lsl #8 |
mov r6, r6, lsr #24 |
orr r6, r6, r7, lsl #8 |
stmia r0!, {r3 - r6} |
subs ip, ip, #16 |
bpl Lmtfs_3cpy8lp |
Lmtfs_3rem8lp: tst ip, #8 |
movne r3, r7, lsr #24 |
ldmneia r1!, {r4, r7} |
orrne r3, r3, r4, lsl #8 |
movne r4, r4, lsr #24 |
orrne r4, r4, r7, lsl #8 |
stmneia r0!, {r3 - r4} |
tst ip, #4 |
movne r3, r7, lsr #24 |
ldrne r7, [r1], #4 |
orrne r3, r3, r7, lsl #8 |
strnet r3, [r0], #4 |
ands ip, ip, #3 |
beq Lmtfs_3fupi |
Lmtfs_3nowords: teq ip, #0 |
LOADREGS(eqfd,sp!,{r4 - r7, pc}) |
mov r3, r7, lsr #24 |
cmp ip, #2 |
strbt r3, [r0], #1 |
ldrge r3, [r1], #0 |
strgebt r3, [r0], #1 |
movgt r3, r3, lsr #8 |
strgtbt r3, [r0], #1 |
LOADREGS(fd,sp!, {r4 - r7, pc}) |
|
# Prototype: void memcpy_fromfs(void *to,const void *from,unsigned long n); |
# ARM3: cant use memcopy here!!! |
|
.global _memcpy,memcpy |
.global _memmove,memmove |
.global _memcpy_fromfs,memcpy_fromfs |
_memcpy: |
_memmove: |
_memcpy_fromfs: |
memcpy: |
memmove: |
memcpy_fromfs: |
|
ENTER |
cmp r1, r0 |
bcc Lother_copy |
subs r2, r2, #4 |
blt Lup_no_double_words |
ands ip, r0, #3 |
bne Lup_dest_not_aligned |
ands ip, r1, #3 |
bne Lup_src_not_aligned |
|
Lup_rest: subs r2, r2, #8 |
blt Lup_cpy_2_lp |
subs r2, r2, #0x14 |
blt Lup_not_long_copy |
|
Lup_cpy_8_lp: ldmia r1!,{r3 - r9, ip} |
stmia r0!,{r3 - r9, ip} |
subs r2, r2, #32 |
bge Lup_cpy_8_lp |
cmn r2, #16 |
ldmgeia r1!, {r3 - r6} |
stmgeia r0!, {r3 - r6} |
subge r2, r2, #0x10 |
Lup_not_long_copy: |
adds r2, r2, #0x14 |
|
Lup_cpy_3_lp: ldmgeia r1!, {r3 - r5} |
stmgeia r0!, {r3 - r5} |
subges r2, r2, #12 |
bge Lup_cpy_3_lp |
|
Lup_cpy_2_lp: adds r2, r2, #8 |
blt Lup_no_double_words |
subs r2, r2, #4 |
ldrlt r3, [r1], #4 |
strlt r3, [r0], #4 |
ldmgeia r1!, {r3, r4} |
stmgeia r0!, {r3, r4} |
subge r2, r2, #4 |
|
Lup_no_double_words: |
adds r2, r2, #4 |
EXITEQ |
cmp r2, #2 |
ldrb r3, [r1], #1 |
strb r3, [r0], #1 |
ldrgeb r3, [r1], #1 |
strgeb r3, [r0], #1 |
ldrgtb r3, [r1], #1 |
strgtb r3, [r0], #1 |
EXIT |
Lup_dest_not_aligned: |
rsb ip, ip, #4 |
cmp ip, #2 |
ldrb r3, [r1], #1 |
strb r3, [r0], #1 |
ldrgeb r3, [r1], #1 |
strgeb r3, [r0], #1 |
ldrgtb r3, [r1], #1 |
strgtb r3, [r0], #1 |
subs r2, r2, ip |
blt Lup_no_double_words |
ands ip, r1, #3 |
beq Lup_rest |
Lup_src_not_aligned: |
bic r1, r1, #3 |
ldr r7, [r1], #4 |
cmp ip, #2 |
bgt Lup_cpy_4_3 |
beq Lup_cpy_4_2 |
cmp r2, #12 |
blt Lup_cpy_x_1_lp |
sub r2, r2, #12 |
|
Lup_cpy_4_1_lp: mov r3, r7, lsr #8 |
ldmia r1!, {r4 - r7} |
orr r3, r3, r4, lsl #24 |
mov r4, r4, lsr #8 |
orr r4, r4, r5, lsl #24 |
mov r5, r5, lsr #8 |
orr r5, r5, r6, lsl #24 |
mov r6, r6, lsr #8 |
orr r6, r6, r7, lsl #24 |
stmia r0!, {r3 - r6} |
subs r2, r2, #16 |
bge Lup_cpy_4_1_lp |
adds r2, r2, #12 |
blt Lup_rest1 |
|
Lup_cpy_x_1_lp: mov r3, r7, lsr #8 |
ldr r7, [r1], #4 |
orr r3, r3, r7, lsl #24 |
str r3, [r0], #4 |
subs r2, r2, #4 |
bge Lup_cpy_x_1_lp |
|
Lup_rest1: sub r1, r1, #3 |
b Lup_no_double_words |
|
Lup_cpy_4_2: cmp r2, #12 |
blt Lup_cpy_x_2_lp |
sub r2, r2, #12 |
|
Lup_cpy_4_2_lp: mov r3, r7, lsr #16 |
ldmia r1!, {r4 - r7} |
orr r3, r3, r4, lsl #16 |
mov r4, r4, lsr #16 |
orr r4, r4, r5, lsl #16 |
mov r5, r5, lsr #16 |
orr r5, r5, r6, lsl #16 |
mov r6, r6, lsr #16 |
orr r6, r6, r7,LSL#16 |
stmia r0!, {r3 - r6} |
subs r2, r2, #16 |
bge Lup_cpy_4_2_lp |
adds r2, r2, #12 |
blt Lup_rest2 |
|
Lup_cpy_x_2_lp: mov r3, r7, lsr #16 |
ldr r7, [r1], #4 |
orr r3, r3, r7, lsl #16 |
str r3, [r0], #4 |
subs r2, r2, #4 |
bge Lup_cpy_x_2_lp |
|
Lup_rest2: sub r1, r1, #2 |
b Lup_no_double_words |
|
Lup_cpy_4_3: cmp r2, #12 |
blt Lup_cpy_x_3_lp |
sub r2, r2, #12 |
|
Lup_cpy_4_3_lp: mov r3, r7, lsr #24 |
ldmia r1!,{r4 - r7} |
orr r3, r3, r4, lsl #8 |
mov r4, r4, lsr #24 |
orr r4, r4, r5, lsl #8 |
mov r5, r5, lsr #24 |
orr r5, r5, r6, lsl #8 |
mov r6, r6, lsr #24 |
orr r6, r6, r7, lsl #8 |
stmia r0!, {r3 - r6} |
subs r2, r2, #16 |
bge Lup_cpy_4_3_lp |
adds r2, r2, #12 |
blt Lup_rest3 |
|
Lup_cpy_x_3_lp: mov r3, r7, lsr #24 |
ldr r7, [r1], #4 |
orr r3, r3, r7, lsl#8 |
str r3, [r0], #4 |
subs r2, r2, #4 |
bge Lup_cpy_x_3_lp |
|
Lup_rest3: sub r1, r1, #1 |
b Lup_no_double_words |
|
|
Lother_copy: add r1, r1, r2 |
add r0, r0, r2 |
subs r2, r2, #4 |
blt Ldown_no_double_words |
ands ip, r0, #3 |
bne Ldown_dest_not_aligned |
ands ip, r1, #3 |
bne Ldown_src_not_aligned |
|
Ldown_rest: |
subs r2, r2, #8 |
blt Ldown_cpy_2_lp |
subs r2, r2, #0x14 |
blt Ldown_not_long_copy |
Ldown_cpy_8_lp: |
ldmdb r1!, {r3 - r9, ip} |
stmdb r0!, {r3 - r9, ip} |
subs r2, r2, #32 |
bge Ldown_cpy_8_lp |
|
Ldown_not_long_copy: |
cmn r2, #16 |
ldmgedb r1!, {r3 - r6} |
stmgedb r0!, {r3 - r6} |
subge r2, r2, #16 |
adds r2, r2, #20 |
ldmgedb r1!, {r3 - r5} |
stmgedb r0!, {r3 - r5} |
subge r2, r2, #12 |
Ldown_cpy_2_lp: |
adds r2, r2, #8 |
blt Ldown_no_double_words |
subs r2, r2, #4 |
ldrlt r3, [r1, #-4]! |
strlt r3, [r0, #-4]! |
ldmgedb r1!, {r3, r4} |
stmgedb r0!, {r3, r4} |
subge r2, r2, #4 |
|
Ldown_no_double_words: |
adds r2, r2, #4 |
EXITEQ |
cmp r2, #2 |
ldrb r3, [r1, #-1]! |
strb r3, [r0, #-1]! |
ldrgeb r3, [r1, #-1]! |
strgeb r3, [r0, #-1]! |
ldrgtb r3, [r1, #-1]! |
strgtb r3, [r0, #-1]! |
EXIT |
|
Ldown_dest_not_aligned: |
CMP ip,#2 |
LDRB r3,[r1,#-1]! |
STRB r3,[r0,#-1]! |
LDRGEB r3,[r1,#-1]! |
STRGEB r3,[r0,#-1]! |
LDRGTB r3,[r1,#-1]! |
STRGTB r3,[r0,#-1]! |
SUBS r2,r2,ip |
BLT Ldown_no_double_words |
ANDS ip,r1,#3 |
BEQ Ldown_rest |
|
Ldown_src_not_aligned: |
BIC r1,r1,#3 |
LDR r3,[r1],#0 |
CMP ip,#2 |
BLT Ldown_cpy_4_3 |
BEQ Ldown_cpy_4_2 |
CMP r2,#12 |
BLT Ldown_cpy_x_1_lp |
SUB r2,r2,#12 |
|
Ldown_cpy_4_1_lp: |
MOV r7,r3,LSL#8 |
LDMDB r1!,{r3,r4,r5,r6} |
ORR r7,r7,r6,LSR#24 |
MOV r6,r6,LSL#8 |
ORR r6,r6,r5,LSR#24 |
MOV r5,r5,LSL#8 |
ORR r5,r5,r4,LSR#24 |
MOV r4,r4,LSL#8 |
ORR r4,r4,r3,LSR#24 |
STMDB r0!,{r4,r5,r6,r7} |
SUBS r2,r2,#16 |
BGE Ldown_cpy_4_1_lp |
ADDS r2,r2,#12 |
BLT Ldown_rest1 |
|
Ldown_cpy_x_1_lp: |
MOV ip,r3,LSL#8 |
LDR r3,[r1,#-4]! |
ORR ip,ip,r3,LSR#24 |
STR ip,[r0,#-4]! |
SUBS r2,r2,#4 |
BGE Ldown_cpy_x_1_lp |
|
Ldown_rest1: |
ADD r1,r1,#3 |
B Ldown_no_double_words |
|
Ldown_cpy_4_2: |
CMP r2,#12 |
BLT Ldown_cpy_x_2_lp |
SUB r2,r2,#12 |
|
Ldown_cpy_4_2_lp: |
MOV r7,r3,LSL#16 |
LDMDB r1!,{r3,r4,r5,r6} |
ORR r7,r7,r6,LSR#16 |
MOV r6,r6,LSL#16 |
ORR r6,r6,r5,LSR#16 |
MOV r5,r5,LSL#16 |
ORR r5,r5,r4,LSR#16 |
MOV r4,r4,LSL#16 |
ORR r4,r4,r3,LSR#16 |
STMDB r0!,{r4,r5,r6,r7} |
SUBS r2,r2,#16 |
BGE Ldown_cpy_4_2_lp |
ADDS r2,r2,#12 |
BLT Ldown_rest2 |
|
Ldown_cpy_x_2_lp: |
MOV ip,r3,LSL#16 |
LDR r3,[r1,#-4]! |
ORR ip,ip,r3,LSR#16 |
STR ip,[r0,#-4]! |
SUBS r2,r2,#4 |
BGE Ldown_cpy_x_2_lp |
|
Ldown_rest2: |
ADD r1,r1,#2 |
B Ldown_no_double_words |
|
Ldown_cpy_4_3: |
CMP r2,#12 |
BLT Ldown_cpy_x_3_lp |
SUB r2,r2,#12 |
|
Ldown_cpy_4_3_lp: |
MOV r7,r3,LSL#24 |
LDMDB r1!,{r3,r4,r5,r6} |
ORR r7,r7,r6,LSR#8 |
MOV r6,r6,LSL#24 |
ORR r6,r6,r5,LSR#8 |
MOV r5,r5,LSL#24 |
ORR r5,r5,r4,LSR#8 |
MOV r4,r4,LSL#24 |
ORR r4,r4,r3,LSR#8 |
STMDB r0!,{r4,r5,r6,r7} |
SUBS r2,r2,#16 |
BGE Ldown_cpy_4_3_lp |
ADDS r2,r2,#12 |
BLT Ldown_rest3 |
Ldown_cpy_x_3_lp: |
MOV ip,r3,LSL#24 |
LDR r3,[r1,#-4]! |
ORR ip,ip,r3,LSR#8 |
STR ip,[r0,#-4]! |
SUBS r2,r2,#4 |
BGE Ldown_cpy_x_3_lp |
Ldown_rest3: |
ADD r1,r1,#1 |
B Ldown_no_double_words |
|
.align |
|
/checksum.S
0,0 → 1,578
/* |
* linux/arch/arm/lib/iputils.S |
* |
* Copyright (C) 1995, 1996 Russell King |
*/ |
|
#include <asm/assembler.h> |
.text |
@ r0 = buffer |
@ r1 = len |
@ r2 = sum |
.global _csum_partial,csum_partial |
csum_partial: |
_csum_partial: tst r0, #2 |
beq Lalignok |
subs r1, r1, #2 |
addmi r1, r1, #2 |
bmi Lnobits32 |
bic r0, r0, #3 |
ldr r3, [r0], #4 |
adds r2, r2, r3, lsr #16 |
adcs r2, r2, #0 |
Lalignok: adds r2, r2, #0 |
bics ip, r1, #31 |
beq Lnobits32 |
stmfd sp!, {r4 - r6} |
Llp32: ldmia r0!, {r3 - r6} |
adcs r2, r2, r3 |
adcs r2, r2, r4 |
adcs r2, r2, r5 |
adcs r2, r2, r6 |
ldmia r0!, {r3 - r6} |
adcs r2, r2, r3 |
adcs r2, r2, r4 |
adcs r2, r2, r5 |
adcs r2, r2, r6 |
sub ip, ip, #32 |
teq ip, #0 |
bne Llp32 |
adcs r2, r2, #0 |
ldmfd sp!, {r4 - r6} |
Lnobits32: ands ip, r1, #0x1c |
beq Lnobits4 |
Lbits32lp: ldr r3, [r0], #4 |
adcs r2, r2, r3 |
sub ip, ip, #4 |
teq ip, #0 |
bne Lbits32lp |
adcs r2, r2, #0 |
Lnobits4: ands ip, r1, #3 |
moveq r0, r2 |
RETINSTR(moveq,pc,lr) |
mov ip, ip, lsl #3 |
rsb ip, ip, #32 |
ldr r3, [r0] |
mov r3, r3, lsl ip |
adds r2, r2, r3, lsr ip |
adc r0, r2, #0 |
RETINSTR(mov,pc,lr) |
|
@ r0 = src |
@ r1 = dst (should be aligned on 16-bit) |
@ r2 = len |
@ r3 = sum |
.global ___csum_partial_copy_fromuser,__csum_partial_copy_fromuser |
__csum_partial_copy_fromuser: |
___csum_partial_copy_fromuser: |
mov ip, sp |
stmfd sp!, {r4 - r8, fp, ip, lr, pc} |
sub fp, ip, #4 |
cmp r2, #4 |
blt Ltoo_small_user |
tst r1, #2 @ Test destination alignment |
beq Ldst_aligned_user |
subs r2, r2, #2 @ We dont know if SRC is aligned... |
ldrbt ip, [r0], #1 |
ldrbt r8, [r0], #1 |
orr ip, ip, r8, lsl #8 |
adds r3, r3, ip |
adcs r3, r3, #0 |
strb ip, [r1], #1 |
mov ip, ip, lsr #8 |
strb ip, [r1], #1 @ Destination now aligned |
Ldst_aligned_user: |
tst r0, #3 |
bne Lsrc_not_aligned_user |
adds r3, r3, #0 |
bics ip, r2, #15 @ Routine for src & dst aligned |
beq 2f |
1: ldrt r4, [r0], #4 |
ldrt r5, [r0], #4 |
ldrt r6, [r0], #4 |
ldrt r7, [r0], #4 |
stmia r1!, {r4, r5, r6, r7} |
adcs r3, r3, r4 |
adcs r3, r3, r5 |
adcs r3, r3, r6 |
adcs r3, r3, r7 |
sub ip, ip, #16 |
teq ip, #0 |
bne 1b |
2: ands ip, r2, #12 |
beq 4f |
tst ip, #8 |
beq 3f |
ldrt r4, [r0], #4 |
ldrt r5, [r0], #4 |
stmia r1!, {r4, r5} |
adcs r3, r3, r4 |
adcs r3, r3, r5 |
tst ip, #4 |
beq 4f |
3: ldrt r4, [r0], #4 |
str r4, [r1], #4 |
adcs r3, r3, r4 |
4: ands r2, r2, #3 |
adceq r0, r3, #0 |
LOADREGS(eqea,fp,{r4 - r8, fp, sp, pc}) |
ldrt r4, [r0], #4 |
tst r2, #2 |
beq Lexit |
adcs r3, r3, r4, lsl #16 |
strb r4, [r1], #1 |
mov r4, r4, lsr #8 |
strb r4, [r1], #1 |
mov r4, r4, lsr #8 |
Lexit: tst r2, #1 |
strneb r4, [r1], #1 |
andne r4, r4, #255 |
adcnes r3, r3, r4 |
adcs r0, r3, #0 |
LOADREGS(ea,fp,{r4 - r8, fp, sp, pc}) |
|
Ltoo_small_user: |
teq r2, #0 |
LOADREGS(eqea,fp,{r4 - r8, fp, sp, pc}) |
cmp r2, #2 |
blt Ltoo_small_user1 |
ldrbt ip, [r0], #1 |
ldrbt r8, [r0], #1 |
orr ip, ip, r8, lsl #8 |
adds r3, r3, ip |
strb ip, [r1], #1 |
strb r8, [r1], #1 |
tst r2, #1 |
Ltoo_small_user1: |
ldrnebt ip, [r0], #1 |
strneb ip, [r1], #1 |
adcnes r3, r3, ip |
adcs r0, r3, #0 |
LOADREGS(ea,fp,{r4 - r8, fp, sp, pc}) |
|
Lsrc_not_aligned_user: |
cmp r2, #4 |
blt Ltoo_small_user |
and ip, r0, #3 |
bic r0, r0, #3 |
ldrt r4, [r0], #4 |
cmp ip, #2 |
beq Lsrc2_aligned_user |
bhi Lsrc3_aligned_user |
mov r4, r4, lsr #8 |
adds r3, r3, #0 |
bics ip, r2, #15 |
beq 2f |
1: ldrt r5, [r0], #4 |
ldrt r6, [r0], #4 |
ldrt r7, [r0], #4 |
ldrt r8, [r0], #4 |
orr r4, r4, r5, lsl #24 |
mov r5, r5, lsr #8 |
orr r5, r5, r6, lsl #24 |
mov r6, r6, lsr #8 |
orr r6, r6, r7, lsl #24 |
mov r7, r7, lsr #8 |
orr r7, r7, r8, lsl #24 |
stmia r1!, {r4, r5, r6, r7} |
adcs r3, r3, r4 |
adcs r3, r3, r5 |
adcs r3, r3, r6 |
adcs r3, r3, r7 |
mov r4, r8, lsr #8 |
sub ip, ip, #16 |
teq ip, #0 |
bne 1b |
2: ands ip, r2, #12 |
beq 4f |
tst ip, #8 |
beq 3f |
ldrt r5, [r0], #4 |
ldrt r6, [r0], #4 |
orr r4, r4, r5, lsl #24 |
mov r5, r5, lsr #8 |
orr r5, r5, r6, lsl #24 |
stmia r1!, {r4, r5} |
adcs r3, r3, r4 |
adcs r3, r3, r5 |
mov r4, r6, lsr #8 |
tst ip, #4 |
beq 4f |
3: ldrt r5, [r0], #4 |
orr r4, r4, r5, lsl #24 |
str r4, [r1], #4 |
adcs r3, r3, r4 |
mov r4, r5, lsr #8 |
4: ands r2, r2, #3 |
adceq r0, r3, #0 |
LOADREGS(eqea,fp,{r4 - r8, fp, sp, pc}) |
tst r2, #2 |
beq Lexit |
adcs r3, r3, r4, lsl #16 |
strb r4, [r1], #1 |
mov r4, r4, lsr #8 |
strb r4, [r1], #1 |
mov r4, r4, lsr #8 |
b Lexit |
|
Lsrc2_aligned_user: |
mov r4, r4, lsr #16 |
adds r3, r3, #0 |
bics ip, r2, #15 |
beq 2f |
1: ldrt r5, [r0], #4 |
ldrt r6, [r0], #4 |
ldrt r7, [r0], #4 |
ldrt r8, [r0], #4 |
orr r4, r4, r5, lsl #16 |
mov r5, r5, lsr #16 |
orr r5, r5, r6, lsl #16 |
mov r6, r6, lsr #16 |
orr r6, r6, r7, lsl #16 |
mov r7, r7, lsr #16 |
orr r7, r7, r8, lsl #16 |
stmia r1!, {r4, r5, r6, r7} |
adcs r3, r3, r4 |
adcs r3, r3, r5 |
adcs r3, r3, r6 |
adcs r3, r3, r7 |
mov r4, r8, lsr #16 |
sub ip, ip, #16 |
teq ip, #0 |
bne 1b |
2: ands ip, r2, #12 |
beq 4f |
tst ip, #8 |
beq 3f |
ldrt r5, [r0], #4 |
ldrt r6, [r0], #4 |
orr r4, r4, r5, lsl #16 |
mov r5, r5, lsr #16 |
orr r5, r5, r6, lsl #16 |
stmia r1!, {r4, r5} |
adcs r3, r3, r4 |
adcs r3, r3, r5 |
mov r4, r6, lsr #16 |
tst ip, #4 |
beq 4f |
3: ldrt r5, [r0], #4 |
orr r4, r4, r5, lsl #16 |
str r4, [r1], #4 |
adcs r3, r3, r4 |
mov r4, r5, lsr #16 |
4: ands r2, r2, #3 |
adceq r0, r3, #0 |
LOADREGS(eqea,fp,{r4 - r8, fp, sp, pc}) |
tst r2, #2 |
beq Lexit |
adcs r3, r3, r4, lsl #16 |
strb r4, [r1], #1 |
mov r4, r4, lsr #8 |
strb r4, [r1], #1 |
ldrb r4, [r0], #1 |
b Lexit |
|
Lsrc3_aligned_user: |
mov r4, r4, lsr #24 |
adds r3, r3, #0 |
bics ip, r2, #15 |
beq 2f |
1: ldrt r5, [r0], #4 |
ldrt r6, [r0], #4 |
ldrt r7, [r0], #4 |
ldrt r8, [r0], #4 |
orr r4, r4, r5, lsl #8 |
mov r5, r5, lsr #24 |
orr r5, r5, r6, lsl #8 |
mov r6, r6, lsr #24 |
orr r6, r6, r7, lsl #8 |
mov r7, r7, lsr #24 |
orr r7, r7, r8, lsl #8 |
stmia r1!, {r4, r5, r6, r7} |
adcs r3, r3, r4 |
adcs r3, r3, r5 |
adcs r3, r3, r6 |
adcs r3, r3, r7 |
mov r4, r8, lsr #24 |
sub ip, ip, #16 |
teq ip, #0 |
bne 1b |
2: ands ip, r2, #12 |
beq 4f |
tst ip, #8 |
beq 3f |
ldrt r5, [r0], #4 |
ldrt r6, [r0], #4 |
orr r4, r4, r5, lsl #8 |
mov r5, r5, lsr #24 |
orr r5, r5, r6, lsl #8 |
stmia r1!, {r4, r5} |
adcs r3, r3, r4 |
adcs r3, r3, r5 |
mov r4, r6, lsr #24 |
tst ip, #4 |
beq 4f |
3: ldrt r5, [r0], #4 |
orr r4, r4, r5, lsl #8 |
str r4, [r1], #4 |
adcs r3, r3, r4 |
mov r4, r5, lsr #24 |
4: ands r2, r2, #3 |
adceq r0, r3, #0 |
LOADREGS(eqea,fp,{r4 - r8, fp, sp, pc}) |
tst r2, #2 |
beq Lexit |
adcs r3, r3, r4, lsl #16 |
strb r4, [r1], #1 |
ldrt r4, [r0], #4 |
strb r4, [r1], #1 |
adcs r3, r3, r4, lsl #24 |
mov r4, r4, lsr #8 |
b Lexit |
|
@ r0 = src |
@ r1 = dst |
@ r2 = len |
@ r3 = sum |
|
.global _csum_partial_copy,csum_partial_copy |
csum_partial_copy: |
_csum_partial_copy: |
mov ip, sp |
stmfd sp!, {r4 - r8, fp, ip, lr, pc} |
sub fp, ip, #4 |
cmp r2, #4 |
blt Ltoo_small |
tst r1, #2 @ Test destination alignment |
beq Ldst_aligned |
subs r2, r2, #2 @ We dont know if SRC is aligned... |
ldrb ip, [r0], #1 |
ldrb r8, [r0], #1 |
orr ip, ip, r8, lsl #8 |
adds r3, r3, ip |
adcs r3, r3, #0 |
strb ip, [r1], #1 |
mov ip, ip, lsr #8 |
strb ip, [r1], #1 @ Destination now aligned |
Ldst_aligned: tst r0, #3 |
bne Lsrc_not_aligned |
adds r3, r3, #0 |
bics ip, r2, #15 @ Routine for src & dst aligned |
beq 3f |
1: ldmia r0!, {r4, r5, r6, r7} |
stmia r1!, {r4, r5, r6, r7} |
adcs r3, r3, r4 |
adcs r3, r3, r5 |
adcs r3, r3, r6 |
adcs r3, r3, r7 |
sub ip, ip, #16 |
teq ip, #0 |
bne 1b |
3: ands ip, r2, #12 |
beq 5f |
tst ip, #8 |
beq 4f |
ldmia r0!, {r4, r5} |
stmia r1!, {r4, r5} |
adcs r3, r3, r4 |
adcs r3, r3, r5 |
tst ip, #4 |
beq 5f |
4: ldr r4, [r0], #4 |
str r4, [r1], #4 |
adcs r3, r3, r4 |
5: ands r2, r2, #3 |
adceq r0, r3, #0 |
LOADREGS(eqea,fp,{r4 - r8, fp, sp, pc}) |
ldr r4, [r0], #4 |
tst r2, #2 |
beq Lexit |
adcs r3, r3, r4, lsl #16 |
strb r4, [r1], #1 |
mov r4, r4, lsr #8 |
strb r4, [r1], #1 |
mov r4, r4, lsr #8 |
b Lexit |
|
Ltoo_small: teq r2, #0 |
LOADREGS(eqea,fp,{r8, fp, sp, pc}) |
cmp r2, #2 |
blt Ltoo_small1 |
ldrb ip, [r0], #1 |
ldrb r8, [r0], #1 |
orr ip, ip, r8, lsl #8 |
adds r3, r3, ip |
strb ip, [r1], #1 |
strb r8, [r1], #1 |
tst r2, #1 |
Ltoo_small1: ldrneb ip, [r0], #1 |
strneb ip, [r1], #1 |
adcnes r3, r3, ip |
adcs r0, r3, #0 |
LOADREGS(ea,fp,{r8, fp, sp, pc}) |
|
Lsrc_not_aligned: |
cmp r2, #4 |
blt Ltoo_small |
and ip, r0, #3 |
bic r0, r0, #3 |
ldr r4, [r0], #4 |
cmp ip, #2 |
beq Lsrc2_aligned |
bhi Lsrc3_aligned |
mov r4, r4, lsr #8 |
adds r3, r3, #0 |
bics ip, r2, #15 |
beq 2f |
1: ldmia r0!, {r5, r6, r7, r8} |
orr r4, r4, r5, lsl #24 |
mov r5, r5, lsr #8 |
orr r5, r5, r6, lsl #24 |
mov r6, r6, lsr #8 |
orr r6, r6, r7, lsl #24 |
mov r7, r7, lsr #8 |
orr r7, r7, r8, lsl #24 |
stmia r1!, {r4, r5, r6, r7} |
adcs r3, r3, r4 |
adcs r3, r3, r5 |
adcs r3, r3, r6 |
adcs r3, r3, r7 |
mov r4, r8, lsr #8 |
sub ip, ip, #16 |
teq ip, #0 |
bne 1b |
2: ands ip, r2, #12 |
beq 4f |
tst ip, #8 |
beq 3f |
ldmia r0!, {r5, r6} |
orr r4, r4, r5, lsl #24 |
mov r5, r5, lsr #8 |
orr r5, r5, r6, lsl #24 |
stmia r1!, {r4, r5} |
adcs r3, r3, r4 |
adcs r3, r3, r5 |
mov r4, r6, lsr #8 |
tst ip, #4 |
beq 4f |
3: ldr r5, [r0], #4 |
orr r4, r4, r5, lsl #24 |
str r4, [r1], #4 |
adcs r3, r3, r4 |
mov r4, r5, lsr #8 |
4: ands r2, r2, #3 |
adceq r0, r3, #0 |
LOADREGS(eqea,fp,{r4 - r8, fp, sp, pc}) |
tst r2, #2 |
beq Lexit |
adcs r3, r3, r4, lsl #16 |
strb r4, [r1], #1 |
mov r4, r4, lsr #8 |
strb r4, [r1], #1 |
mov r4, r4, lsr #8 |
b Lexit |
|
Lsrc2_aligned: mov r4, r4, lsr #16 |
adds r3, r3, #0 |
bics ip, r2, #15 |
beq 2f |
1: ldmia r0!, {r5, r6, r7, r8} |
orr r4, r4, r5, lsl #16 |
mov r5, r5, lsr #16 |
orr r5, r5, r6, lsl #16 |
mov r6, r6, lsr #16 |
orr r6, r6, r7, lsl #16 |
mov r7, r7, lsr #16 |
orr r7, r7, r8, lsl #16 |
stmia r1!, {r4, r5, r6, r7} |
adcs r3, r3, r4 |
adcs r3, r3, r5 |
adcs r3, r3, r6 |
adcs r3, r3, r7 |
mov r4, r8, lsr #16 |
sub ip, ip, #16 |
teq ip, #0 |
bne 1b |
2: ands ip, r2, #12 |
beq 4f |
tst ip, #8 |
beq 3f |
ldmia r0!, {r5, r6} |
orr r4, r4, r5, lsl #16 |
mov r5, r5, lsr #16 |
orr r5, r5, r6, lsl #16 |
stmia r1!, {r4, r5} |
adcs r3, r3, r4 |
adcs r3, r3, r5 |
mov r4, r6, lsr #16 |
tst ip, #4 |
beq 4f |
3: ldr r5, [r0], #4 |
orr r4, r4, r5, lsl #16 |
str r4, [r1], #4 |
adcs r3, r3, r4 |
mov r4, r5, lsr #16 |
4: ands r2, r2, #3 |
adceq r0, r3, #0 |
LOADREGS(eqea,fp,{r4 - r8, fp, sp, pc}) |
tst r2, #2 |
beq Lexit |
adcs r3, r3, r4, lsl #16 |
strb r4, [r1], #1 |
mov r4, r4, lsr #8 |
strb r4, [r1], #1 |
ldrb r4, [r0], #1 |
b Lexit |
|
Lsrc3_aligned: mov r4, r4, lsr #24 |
adds r3, r3, #0 |
bics ip, r2, #15 |
beq 2f |
1: ldmia r0!, {r5, r6, r7, r8} |
orr r4, r4, r5, lsl #8 |
mov r5, r5, lsr #24 |
orr r5, r5, r6, lsl #8 |
mov r6, r6, lsr #24 |
orr r6, r6, r7, lsl #8 |
mov r7, r7, lsr #24 |
orr r7, r7, r8, lsl #8 |
stmia r1!, {r4, r5, r6, r7} |
adcs r3, r3, r4 |
adcs r3, r3, r5 |
adcs r3, r3, r6 |
adcs r3, r3, r7 |
mov r4, r8, lsr #24 |
sub ip, ip, #16 |
teq ip, #0 |
bne 1b |
2: ands ip, r2, #12 |
beq 4f |
tst ip, #8 |
beq 3f |
ldmia r0!, {r5, r6} |
orr r4, r4, r5, lsl #8 |
mov r5, r5, lsr #24 |
orr r5, r5, r6, lsl #8 |
stmia r1!, {r4, r5} |
adcs r3, r3, r4 |
adcs r3, r3, r5 |
mov r4, r6, lsr #24 |
tst ip, #4 |
beq 4f |
3: ldr r5, [r0], #4 |
orr r4, r4, r5, lsl #8 |
str r4, [r1], #4 |
adcs r3, r3, r4 |
mov r4, r5, lsr #24 |
4: ands r2, r2, #3 |
adceq r0, r3, #0 |
LOADREGS(eqea,fp,{r4 - r8, fp, sp, pc}) |
tst r2, #2 |
beq Lexit |
adcs r3, r3, r4, lsl #16 |
strb r4, [r1], #1 |
ldr r4, [r0], #4 |
strb r4, [r1], #1 |
adcs r3, r3, r4, lsl #24 |
mov r4, r4, lsr #8 |
b Lexit |
/io-trio.c
0,0 → 1,40
#include <asm/hardware.h> |
#include <asm/io.h> |
|
static __inline__ void do_outw(unsigned int reg, const void* buf, unsigned int count) |
{ |
register const unsigned short* wbuf = (const unsigned short*) buf; |
while(count--) |
outw(*wbuf++, reg); |
} |
|
static __inline__ void do_inw(unsigned int reg, void* buf, unsigned int count) |
{ |
register unsigned short* wbuf = (unsigned short*) buf; |
while(count--) |
*wbuf++ = inw(reg); |
} |
|
|
void outsw(unsigned to_reg, const void *from, int len_in_words) |
{ |
do_outw(to_reg, from, len_in_words); |
} |
|
void outswb(unsigned to_reg, const void *from, int len_in_bytes) |
{ |
do_outw(to_reg, from, len_in_bytes/2); |
} |
|
|
|
void insw(unsigned from_port, void *to, int len_in_words) |
{ |
do_inw(from_port, to, len_in_words); |
} |
|
void inswb(unsigned from_port, void *to, int len_in_bytes) |
{ |
do_inw(from_port, to, len_in_bytes/2); |
} |
|
/string.S
0,0 → 1,123
/* |
* linux/arch/arm/lib/string.S |
* |
* Copyright (C) 1995, 1996 Russell King |
*/ |
|
#include <asm/assembler.h> |
.text |
# Prototype: char *strrchr(const char *s,char c); |
|
@ r0 = pointer, r1 = length |
.global _memzero,memzero |
memzero: |
_memzero: stmfd sp!, {lr} |
mov r2, #0 |
mov r3, #0 |
mov ip, #0 |
mov lr, #0 |
Lgfpmemzerolp: subs r1, r1, #4*8 |
stmgeia r0!, {r2, r3, ip, lr} |
stmgeia r0!, {r2, r3, ip, lr} |
bgt Lgfpmemzerolp |
LOADREGS(fd, sp!, {pc}) |
|
.global ___page_memcpy,__page_memcpy |
__page_memcpy: |
___page_memcpy: stmfd sp!, {r4, r5, lr} |
Lpagememcpylp: subs r2, r2, #4*8 |
ldmgeia r1!, {r3, r4, r5, ip} |
stmgeia r0!, {r3, r4, r5, ip} |
ldmgeia r1!, {r3, r4, r5, ip} |
stmgeia r0!, {r3, r4, r5, ip} |
bgt Lpagememcpylp |
LOADREGS(fd, sp!, {r4, r5, pc}) |
|
.global _memset,memset |
memset: |
_memset: mov r3, r0 |
cmp r2, #16 |
blt Lmemsetbytelp |
ands ip, r3, #3 |
beq Laligned |
cmp ip, #2 |
strltb r1, [r3], #1 @ Align destination |
strleb r1, [r3], #1 |
strb r1, [r3], #1 |
rsb ip, ip, #4 |
sub r2, r2, ip |
Laligned: orr r1, r1, r1, lsl #8 |
orr r1, r1, r1, lsl #16 |
cmp r2, #256 |
blt Lmemsetnotopt1 |
stmfd sp!, {r4, r5, lr} |
mov r4, r1 |
mov r5, r1 |
mov lr, r1 |
mov ip, r2, lsr #6 |
sub r2, r2, ip, lsl #6 |
Lmemset64lp1: stmia r3!, {r1, r4, r5, lr} @ 64 bytes at a time. |
stmia r3!, {r1, r4, r5, lr} |
stmia r3!, {r1, r4, r5, lr} |
stmia r3!, {r1, r4, r5, lr} |
subs ip, ip, #1 |
bne Lmemset64lp1 |
teq r2, #0 |
LOADREGS(eqfd, sp!, {r4, r5, pc}) @ Now <64 bytes to go. |
tst r2, #32 |
stmneia r3!, {r1, r4, r5, lr} |
stmneia r3!, {r1, r4, r5, lr} |
tst r2, #16 |
stmneia r3!, {r1, r4, r5, lr} |
ldmia sp!, {r4, r5} |
Lmemsetexit: tst r2, #8 |
stmneia r3!, {r1, lr} |
tst r2, #4 |
strne r1, [r3], #4 |
tst r2, #2 |
strneb r1, [r3], #1 |
strneb r1, [r3], #1 |
tst r2, #1 |
strneb r1, [r3], #1 |
LOADREGS(fd, sp!, {pc}) |
|
Lmemsetnotopt1: movs ip, r2, lsr #3 |
beq Lmemsetexit |
sub r2, r2, ip, lsl #3 |
stmfd sp!, {lr} |
mov lr, r1 |
subs ip, ip, #4 |
Lmemset1616lp: stmgeia r3!, {r1, lr} |
stmgeia r3!, {r1, lr} |
stmgeia r3!, {r1, lr} |
stmgeia r3!, {r1, lr} |
subges ip, ip, #4 |
bge Lmemset1616lp |
tst ip, #2 |
stmneia r3!, {r1, lr} |
stmneia r3!, {r1, lr} |
tst ip, #1 |
stmneia r3!, {r1, lr} |
teq r2, #0 |
LOADREGS(eqfd, sp!, {pc}) |
b Lmemsetexit |
|
Lmemsetbytelp: |
Lmemsetlp: subs r2, r2, #1 |
strgeb r1, [r3], #1 |
bgt Lmemsetlp |
RETINSTR(mov, pc, lr) |
|
.global _strrchr,strrchr |
strrchr: |
_strrchr: stmfd sp!,{lr} |
mov r3,#0 |
Lstrrchrlp: ldrb r2,[r0],#1 |
teq r2,r1 |
moveq r3,r0 |
teq r2,#0 |
bne Lstrrchrlp |
mov r0,r3 |
LOADREGS(fd, sp!, {pc}) |
|
|
/io-acorn.S
0,0 → 1,257
/* |
* linux/arch/arm/lib/io.S |
* |
* Copyright (C) 1995, 1996 Russell King |
*/ |
#include <linux/autoconf.h> |
#include <asm/assembler.h> |
#include <asm/hardware.h> |
|
.text |
.align |
|
#define OUT(reg) \ |
mov r8, reg, lsl $16 ;\ |
orr r8, r8, r8, lsr $16 ;\ |
str r8, [r3, r0, lsl $2] ;\ |
mov r8, reg, lsr $16 ;\ |
orr r8, r8, r8, lsl $16 ;\ |
str r8, [r3, r0, lsl $2] |
|
#define IN(reg) \ |
ldr reg, [r0] ;\ |
and reg, reg, ip ;\ |
ldr lr, [r0] ;\ |
orr reg, reg, lr, lsl $16 |
|
#if (IO_BASE == (PCIO_BASE & 0xff000000)) |
#define ADDR(off,reg) \ |
tst off, $0x80000000 ;\ |
mov reg, $IO_BASE ;\ |
orreq reg, reg, $(PCIO_BASE & 0x00ff0000) |
#else |
#define ADDR(off,reg) \ |
tst off, $0x80000000 ;\ |
movne reg, $IO_BASE ;\ |
moveq reg, $(PCIO_BASE & 0xff000000) ;\ |
orreq reg, reg, $(PCIO_BASE & 0x00ff0000) |
#endif |
|
@ purpose: read a byte from a hardware register. |
@ Proto : unsigned char inb(int address); |
|
.global ___inb |
.global ___inb_p |
.global ___inbc |
.global ___inbc_p |
___inb: |
___inb_p: |
___inbc: |
___inbc_p: |
ADDR(r0,r2) |
ldrb r0, [r2, r0, lsl#2] |
RETINSTR(mov,pc,lr) |
|
@ purpose: read a short word from a hardware register. |
@ Proto : unsigned short inw(int address); |
|
.global ___inw |
___inw: ADDR(r0,r2) |
ldr r0, [r2, r0, lsl#2] |
bic r0, r0, #0xff000000 |
bic r0, r0, #0x00ff0000 |
RETINSTR(mov,pc,lr) |
|
@ Purpose: write a byte to a hardware register. |
@ Proto : outb(unsigned char c,int address); |
|
.global ___outb |
.global ___outb_p |
.global ___outbc |
.global ___outbc_p |
___outb: |
___outb_p: |
___outbc: |
___outbc_p: |
ADDR(r1,r2) |
strb r0,[r2,r1,LSL#2] |
RETINSTR(mov,pc,lr) |
|
@ Purpose: write a short to a hardware register. |
@ Proto : outw(unsigned short c,int address); |
|
.global ___outw |
___outw: ADDR(r1,r2) |
orr r0, r0, r0, lsl#16 |
str r0, [r2, r1, lsl#2] |
RETINSTR(mov,pc,lr) |
|
@ Purpose: read a block of data from a hardware register to memory. |
@ Proto : insw(int from_port, void *to, int len_in_words); |
@ Proto : inswb(int from_port, void *to, int len_in_bytes); |
@ Notes : increment to |
|
.global _insw |
.global _inswb |
_insw: mov r2, r2, lsl#1 |
_inswb: mov ip, sp |
stmfd sp!, {r4 - r10 ,fp ,ip ,lr ,pc} |
sub fp, ip, #4 |
ADDR(r0,r3) |
add r0, r3, r0, lsl #2 |
tst r1, #3 |
beq Linswok |
tst r1, #1 |
bne Linsw_notaligned |
cmp r2, #1 |
ldrge r4, [r0] |
strgeb r4, [r1], #1 |
movgt r4, r4, LSR#8 |
strgtb r4, [r1], #1 |
ldmleea fp, {r4 - r10, fp, sp, pc}^ |
sub r2, r2, #2 |
Linswok: mov ip, #0xFF |
orr ip, ip, ip, lsl #8 |
Linswlp: subs r2, r2, #64 |
bmi Linsw_toosmall |
IN(r3) |
IN(r4) |
IN(r5) |
IN(r6) |
IN(r7) |
IN(r8) |
IN(r9) |
IN(r10) |
stmia r1!, {r3 - r10} |
IN(r3) |
IN(r4) |
IN(r5) |
IN(r6) |
IN(r7) |
IN(r8) |
IN(r9) |
IN(r10) |
stmia r1!, {r3 - r10} |
bne Linswlp |
LOADREGS(ea, fp, {r4 - r10, fp, sp, pc}) |
Linsw_toosmall: |
adds r2, r2, #32 |
bmi Linsw_toosmall2 |
Linsw2lp: IN(r3) |
IN(r4) |
IN(r5) |
IN(r6) |
IN(r7) |
IN(r8) |
IN(r9) |
IN(r10) |
stmia r1!, {r3 - r10} |
LOADREGS(eqea, fp, {r4 - r10, fp, sp, pc}) |
b Linsw_notaligned |
Linsw_toosmall2: |
add r2, r2, #32 |
Linsw_notaligned: |
cmp r2, #1 |
LOADREGS(ltea, fp, {r4 - r10, fp, sp, pc}) |
ldr r4, [r0] |
strb r4, [r1], #1 |
movgt r4, r4, LSR#8 |
strgtb r4, [r1], #1 |
subs r2, r2, #2 |
bgt Linsw_notaligned |
LOADREGS(ea, fp, {r4 - r10, fp, sp, pc}) |
|
@ Purpose: write a block of data from memory to a hardware register. |
@ Proto : outsw(int to_reg, void *from, int len_in_words); |
@ Proto : outswb(int to_reg, void *from, int len_in_bytes); |
@ Notes : increments from |
|
.global _outsw |
.global _outswb |
_outsw: mov r2, r2, LSL#1 |
_outswb: mov ip, sp |
stmfd sp!, {r4 - r8, fp, ip, lr, pc} |
sub fp, ip, #4 |
ADDR(r0,r3) |
tst r1, #2 |
beq Loutsw32lp |
ldr r4, [r1], #2 |
mov r4, r4, lsl #16 |
orr r4, r4, r4, lsr #16 |
str r4, [r3, r0, lsl #2] |
sub r2, r2, #2 |
teq r2, #0 |
LOADREGS(eqea, fp, {r4 - r8, fp, sp, pc}) |
Loutsw32lp: subs r2,r2,#32 |
blt Loutsw_toosmall |
ldmia r1!,{r4,r5,r6,r7} |
OUT(r4) |
OUT(r5) |
OUT(r6) |
OUT(r7) |
ldmia r1!,{r4,r5,r6,r7} |
OUT(r4) |
OUT(r5) |
OUT(r6) |
OUT(r7) |
LOADREGS(eqea, fp, {r4 - r8, fp, sp, pc}) |
b Loutsw32lp |
Loutsw_toosmall: |
adds r2,r2,#32 |
LOADREGS(eqea, fp, {r4 - r8, fp, sp, pc}) |
Llpx: ldr r4,[r1],#2 |
mov r4,r4,LSL#16 |
orr r4,r4,r4,LSR#16 |
str r4,[r3,r0,LSL#2] |
subs r2,r2,#2 |
bgt Llpx |
LOADREGS(ea, fp, {r4 - r8, fp, sp, pc}) |
|
@ Purpose: write a memc register |
@ Proto : void memc_write(int register, int value); |
@ Returns: nothing |
|
#ifndef CONFIG_ARCH_RPC |
.globl _memc_write |
_memc_write: cmp r0, #7 |
RETINSTR(movgt,pc,lr) |
mov r0, r0, lsl #17 |
mov r1, r1, lsl #15 |
mov r1, r1, lsr #17 |
orr r0, r0, r1, lsl #2 |
add r0, r0, #0x03600000 |
strb r0, [r0] |
RETINSTR(mov,pc,lr) |
#define CPSR2SPSR(rt) |
#else |
#define CPSR2SPSR(rt) \ |
mrs rt, cpsr; \ |
msr spsr, rt |
#endif |
|
@ Purpose: call an expansion card loader to read bytes. |
@ Proto : char read_loader(int offset, char *card_base, char *loader); |
@ Returns: byte read |
|
.global _ecard_loader_read |
_ecard_loader_read: |
stmfd sp!, {r4 - r12, lr} |
mov r11, r1 |
mov r1, r0 |
CPSR2SPSR(r0) |
mov lr, pc |
mov pc, r2 |
LOADREGS(fd, sp!, {r4 - r12, pc}) |
|
@ Purpose: call an expansion card loader to reset the card |
@ Proto : void read_loader(int card_base, char *loader); |
@ Returns: byte read |
|
.global _ecard_loader_reset |
_ecard_loader_reset: |
stmfd sp!, {r4 - r12, lr} |
mov r11, r0 |
CPSR2SPSR(r0) |
mov lr, pc |
add pc, r1, #8 |
LOADREGS(fd, sp!, {r4 - r12, pc}) |
/memfastset.S
0,0 → 1,39
/* |
* linux/arch/arm/lib/memfastset.S |
* |
* Copyright (C) 1995, 1996 Russell King |
*/ |
|
#include <asm/assembler.h> |
.text |
@ Prototype: void memsetl (unsigned long *d, unsigned long c, size_t n); |
|
.global _memsetl,memsetl |
|
memsetl: |
_memsetl: stmfd sp!, {lr} |
cmp r2, #16 |
blt Lmemfastsetlp |
mov r3, r1 |
mov ip, r1 |
mov lr, r1 |
subs r2, r2, #32 |
bmi Lmemfastl32 |
Lmemfast32setlp: |
stmia r0!, {r1, r3, ip, lr} |
stmia r0!, {r1, r3, ip, lr} |
LOADREGS(eqfd, sp!, {pc}) |
subs r2, r2, #32 |
bpl Lmemfast32setlp |
Lmemfastl32: adds r2, r2, #16 |
bmi Lmemfastl16 |
Lmemfast16setlp: |
stmia r0!, {r1, r3, ip, lr} |
LOADREGS(eqfd, sp!, {pc}) |
subs r2, r2, #16 |
bpl Lmemfast16setlp |
Lmemfastl16: add r2, r2, #16 |
Lmemfastsetlp: subs r2, r2, #4 |
strge r1, [r0], #4 |
bgt Lmemfastsetlp |
LOADREGS(fd, sp!, {pc}) |
/irqs-trio.c
0,0 → 1,143
#include <linux/sched.h> |
#include <linux/interrupt.h> |
|
#include <asm/io.h> |
#include <asm/system.h> |
#include <asm/hardware.h> |
#include <asm/irq.h> |
#include <asm/arch/irq.h> |
|
|
|
/* The trio AIC need to recive EOI command at the end of interrupt handler, |
These command is compossed from previous IRQ nr and previous IRQ priority. |
So we maintain this value in the trio_irq_prority variable. |
|
The trio_irq_prtable contains the priority<<5 for each IRQ |
*/ |
|
volatile unsigned char trio_irq_priority = 0; /* Current IRQ number and priority */ |
unsigned char trio_irq_prtable[16] = { |
7, /* FIQ */ |
0, /* WDIRQ */ |
0, /* SWIRQ */ |
2, /* UAIRQ */ |
0, /* TC0 (Timer 0 used for DRAM refresh */ |
1, /* TC1IRQ */ |
0, /* TC2IRQ */ |
0, /* PIOAIRQ */ |
0, /* LCDIRQ not used */ |
5, /* SPIIRQ */ |
4, /* IRQ0, (ETHERNET? )*/ |
0, /* IRQ1 */ |
6, /* OAKAIRQ */ |
6, /* OAKBIRQ */ |
3, /* UBIRQ */ |
5 /* PIOBIRQ */ |
|
}; |
|
void do_IRQ(int irq, struct pt_regs * regs); |
|
|
inline void irq_ack(int priority) |
{ |
outl(priority, AIC_EOICR); |
} |
|
asmlinkage int probe_IRQ_interrupt(int irq, struct pt_regs * regs) |
{ |
mask_irq(irq); |
irq_ack(trio_irq_priority); |
return 0; |
} |
|
asmlinkage int bad_IRQ_interrupt(int irqn, struct pt_regs * regs) |
{ |
printk("bad interrupt %d recieved!\n", irqn); |
irq_ack(trio_irq_priority); |
return 0; |
} |
|
asmlinkage int IRQ_interrupt(int irq, struct pt_regs * regs) |
{ |
register unsigned long flags; |
register unsigned long saved_count; |
register unsigned char spr = trio_irq_priority; |
|
trio_irq_priority = ((unsigned char)irq) | trio_irq_prtable[irq]; |
|
|
saved_count = intr_count; |
intr_count = saved_count + 1; |
|
save_flags(flags); |
sti(); |
do_IRQ(irq, regs); |
restore_flags(flags); |
intr_count = saved_count; |
trio_irq_priority = spr; |
irq_ack(spr); |
return 0; |
} |
|
|
asmlinkage int timer_IRQ_interrupt(int irq, struct pt_regs * regs) |
{ |
register unsigned long flags; |
register unsigned long saved_count; |
register unsigned char spr = trio_irq_priority; |
|
trio_irq_priority = ((unsigned char)irq) | trio_irq_prtable[irq]; |
|
|
|
saved_count = intr_count; |
intr_count = saved_count + 1; |
|
save_flags(flags); |
do_IRQ(irq, regs); |
restore_flags(flags); |
intr_count = saved_count; |
trio_irq_priority = spr; |
irq_ack(spr); |
return 0; |
} |
|
|
asmlinkage int fast_IRQ_interrupt(int irq, struct pt_regs * regs) |
{ |
register unsigned long saved_count; |
|
saved_count = intr_count; |
intr_count = saved_count + 1; |
|
do_IRQ(irq, regs); |
cli(); |
intr_count = saved_count; |
inl(AIC_FVR); |
return 1; |
} |
|
void trio_init_aic() |
{ |
int irqno; |
|
// Disable all interrupts |
outl(0xFFFFFFFF, AIC_IDCR); |
|
// Clear all interrupts |
outl(0xFFFFFFFF, AIC_ICCR); |
|
for ( irqno = 0 ; irqno < 8 ; irqno++ ) |
{ |
outl(irqno, AIC_EOICR); |
} |
|
|
|
for ( irqno = 0 ; irqno < 16 ; irqno++ ) |
{ |
outl(trio_irq_prtable[irqno] | (1 << 5), AIC_SMR(irqno)); |
} |
} |
/getconsdata.c
0,0 → 1,25
/* |
* linux/arch/arm/lib/getconsdata.c |
* |
* Copyright (C) 1995, 1996 Russell King |
*/ |
|
#include <linux/config.h> |
#include <linux/sched.h> |
#include <linux/mm.h> |
#include <asm/pgtable.h> |
#include <linux/unistd.h> |
|
#define OFF_TSK(n) (unsigned long)&(((struct task_struct *)0)->n) |
#define OFF_MM(n) (unsigned long)&(((struct mm_struct *)0)->n) |
|
#ifndef NO_MM |
unsigned long tss_memmap = OFF_TSK(tss.memmap); |
unsigned long pgd = OFF_MM(pgd); |
#endif |
unsigned long mm = OFF_TSK(mm); |
unsigned long tss_save = OFF_TSK(tss.save); |
unsigned long tss_fpesave = OFF_TSK(tss.fpstate.soft.save); |
#if defined(CONFIG_CPU_ARM2) || defined(CONFIG_CPU_ARM3) |
unsigned long tss_memcmap = OFF_TSK(tss.memcmap); |
#endif |
/Makefile
0,0 → 1,52
# |
# linux/arch/arm/lib/Makefile |
# |
# Copyright (C) 1995, 1996 Russell King |
# |
|
L_TARGET := lib.a |
L_OBJS := backtrace.o bitops.o checksum.o delay.o fp_support.o \ |
loaders.o memfastset.o segment.o system.o string.o |
|
ifdef CONFIG_ARCH_ACORN |
L_OBJS += ll_char_wr.o io-acorn.o irqs-acorn.o |
ifdef CONFIG_ARCH_A5K |
L_OBJS += floppydma.o |
endif |
ifdef CONFIG_ARCH_RPC |
L_OBJS += floppydma.o |
endif |
endif |
|
ifeq ($(MACHINE),ebsa110) |
L_OBJS += io-ebsa.o irqs-ebsa.o |
endif |
|
ifeq ($(MACHINE),trio) |
L_OBJS += irqs-trio.o io-trio.o |
endif |
|
include $(TOPDIR)/Rules.make |
|
constants.h: getconstants |
./getconstants > constants.h |
|
getconstants: getconstants.c getconstants.h |
$(HOSTCC) -D__KERNEL__ -o getconstants getconstants.c |
|
getconstants.h: getconsdata.c |
$(CC) $(CFLAGS) -c getconsdata.c |
$(PERL) extractinfo.perl $(OBJDUMP) > $@ |
|
ifneq ($(CONFIG_BINUTILS_NEW),y) |
%.o: %.S |
$(CC) $(CFLAGS) -D__ASSEMBLY__ -E $< | tr ';$$' '\n#' > ..tmp.$<.s |
$(CC) $(CFLAGS:-pipe=) -c -o $@ ..tmp.$<.s |
$(RM) ..tmp.$<.s |
else |
%.o: %.S |
$(CC) $(CFLAGS) -D__ASSEMBLY__ -c -o $@ $< |
endif |
|
clean: |
$(RM) getconstants constants.h getconstants.h |
/ll_char_wr.S
0,0 → 1,158
/* |
* linux/arch/arm/lib/ll_char_wr.S |
* |
* Copyright (C) 1995, 1996 Russell King. |
* |
* Speedups & 1bpp code (C) 1996 Philip Blundel & Russell King. |
* |
* 10-04-96 RMK Various cleanups & reduced register usage. |
*/ |
|
@ Regs: [] = corruptable |
@ {} = used |
@ () = dont use |
|
#include <asm/assembler.h> |
.text |
|
.global ll_write_char |
|
#define BOLD 0x01 |
#define ITALIC 0x02 |
#define UNDERLINE 0x04 |
#define FLASH 0x08 |
#define INVERSE 0x10 |
|
LC0: .word bytes_per_char_h |
.word video_size_row |
.word cmap_80 |
.word con_charconvtable |
|
ll_write_char: stmfd sp!, {r4 - r7, lr} |
@ |
@ Smashable regs: {r0 - r3}, [r4 - r7], (r8 - fp), [ip], (sp), [lr], (pc) |
@ |
eor ip, r1, #UNDERLINE << 24 |
/* |
* calculate colours |
*/ |
tst r1, #INVERSE << 24 |
moveq r2, r1, lsr #8 |
moveq r3, r1, lsr #16 |
movne r2, r1, lsr #16 |
movne r3, r1, lsr #8 |
and r3, r3, #255 |
and r2, r2, #255 |
/* |
* calculate offset into character table |
*/ |
and r1, r1, #255 |
mov r1, r1, lsl #3 |
/* |
* calculate offset required for each row [maybe I should make this an argument to this fn. |
* Have to see what the register usage is like in the calling routines. |
*/ |
adr r4, LC0 |
ldmia r4, {r4, r5, r6, lr} |
ldr r4, [r4] |
ldr r5, [r5] |
/* |
* Go to resolution-dependent routine... |
*/ |
cmp r4, #4 |
blt Lrow1bpp |
eor r2, r3, r2 @ Create eor mask to change colour from bg |
orr r3, r3, r3, lsl #8 @ to fg. |
orr r3, r3, r3, lsl #16 |
add r0, r0, r5, lsl #3 @ Move to bottom of character |
add r1, r1, #7 |
ldrb r7, [r6, r1] |
tst ip, #UNDERLINE << 24 |
eoreq r7, r7, #255 |
teq r4, #8 |
beq Lrow8bpplp |
@ |
@ Smashable regs: {r0 - r3}, [r4], {r5 - r7}, (r8 - fp), [ip], (sp), {lr}, (pc) |
@ |
orr r3, r3, r3, lsl #4 |
Lrow4bpplp: ldr r7, [lr, r7, lsl #2] |
mul r7, r2, r7 |
tst r1, #7 @ avoid using r7 directly after |
eor ip, r3, r7 |
str ip, [r0, -r5]! |
LOADREGS(eqfd, sp!, {r4 - r7, pc}) |
sub r1, r1, #1 |
ldrb r7, [r6, r1] |
ldr r7, [lr, r7, lsl #2] |
mul r7, r2, r7 |
tst r1, #7 @ avoid using r7 directly after |
eor ip, r3, r7 |
str ip, [r0, -r5]! |
subne r1, r1, #1 |
ldrneb r7, [r6, r1] |
bne Lrow4bpplp |
LOADREGS(fd, sp!, {r4 - r7, pc}) |
|
@ |
@ Smashable regs: {r0 - r3}, [r4], {r5 - r7}, (r8 - fp), [ip], (sp), {lr}, (pc) |
@ |
Lrow8bpplp: mov ip, r7, lsr #4 |
ldr ip, [lr, ip, lsl #2] |
mul r4, r2, ip |
and ip, r7, #15 |
eor r4, r3, r4 |
ldr ip, [lr, ip, lsl #2] |
mul ip, r2, ip |
tst r1, #7 |
eor ip, r3, ip |
sub r0, r0, r5 |
stmia r0, {r4, ip} |
LOADREGS(eqfd, sp!, {r4 - r7, pc}) |
sub r1, r1, #1 |
ldrb r7, [r6, r1] |
mov ip, r7, lsr #4 |
ldr ip, [lr, ip, lsl #2] |
mul r4, r2, ip |
and ip, r7, #15 |
eor r4, r3, r4 |
ldr ip, [lr, ip, lsl #2] |
mul ip, r2, ip |
tst r1, #7 |
eor ip, r3, ip |
sub r0, r0, r5 |
stmia r0, {r4, ip} |
subne r1, r1, #1 |
ldrneb r7, [r6, r1] |
bne Lrow8bpplp |
LOADREGS(fd, sp!, {r4 - r7, pc}) |
|
@ |
@ Smashable regs: {r0 - r3}, [r4], {r5, r6}, [r7], (r8 - fp), [ip], (sp), [lr], (pc) |
@ |
Lrow1bpp: add r6, r6, r1 |
ldmia r6, {r4, r7} |
tst ip, #INVERSE << 24 |
mvnne r4, r4 |
mvnne r7, r7 |
strb r4, [r0], r5 |
mov r4, r4, lsr #8 |
strb r4, [r0], r5 |
mov r4, r4, lsr #8 |
strb r4, [r0], r5 |
mov r4, r4, lsr #8 |
strb r4, [r0], r5 |
strb r7, [r0], r5 |
mov r7, r7, lsr #8 |
strb r7, [r0], r5 |
mov r7, r7, lsr #8 |
strb r7, [r0], r5 |
mov r7, r7, lsr #8 |
tst ip, #UNDERLINE << 24 |
mvneq r7, r7 |
strb r7, [r0], r5 |
LOADREGS(fd, sp!, {r4 - r7, pc}) |
|
.globl con_charconvtable |
.bss |
con_charconvtable: |
.space 1024 |
/testm.c
0,0 → 1,81
char buffer[1036]; |
char buffer2[1036]; |
|
int main () |
{ |
char *p; |
int i, o, o2, l; |
|
printf ("Testing memset\n"); |
for (l = 1; l < 1020; l ++) { |
for (o = 0; o < 4; o++) { |
p = buffer + o + 4; |
for (i = 0; i < l + 12; i++) |
buffer[i] = 0x55; |
|
memset (p, 0xaa, l); |
|
for (i = 0; i < l; i++) |
if (p[i] != 0xaa) |
printf ("Error: %X+%d\n", p, i); |
if (p[-1] != 0x55 || p[-2] != 0x55 || p[-3] != 0x55 || p[-4] != 0x55) |
printf ("Error before %X\n", p); |
if (p[l] != 0x55 || p[l+1] != 0x55 || p[l+2] != 0x55 || p[l+3] != 0x55) |
printf ("Error at end: %p: %02X %02X %02X %02X\n", p+l, p[l], p[l+1], p[l+2], p[l+3]); |
} |
} |
|
printf ("Testing memcpy s > d\n"); |
for (l = 1; l < 1020; l++) { |
for (o = 0; o < 4; o++) { |
for (o2 = 0; o2 < 4; o2++) { |
char *d, *s; |
|
for (i = 0; i < l + 12; i++) |
buffer[i] = (i & 0x3f) + 0x40; |
for (i = 0; i < 1036; i++) |
buffer2[i] = 0; |
|
s = buffer + o; |
d = buffer2 + o2 + 4; |
|
memcpy (d, s, l); |
|
for (i = 0; i < l; i++) |
if (s[i] != d[i]) |
printf ("Error at %X+%d -> %X+%d (%02X != %02X)\n", s, i, d, i, s[i], d[i]); |
if (d[-1] || d[-2] || d[-3] || d[-4]) |
printf ("Error before %X\n", d); |
if (d[l] || d[l+1] || d[l+2] || d[l+3]) |
printf ("Error after %X\n", d+l); |
} |
} |
} |
|
printf ("Testing memcpy s < d\n"); |
for (l = 1; l < 1020; l++) { |
for (o = 0; o < 4; o++) { |
for (o2 = 0; o2 < 4; o2++) { |
char *d, *s; |
|
for (i = 0; i < l + 12; i++) |
buffer2[i] = (i & 0x3f) + 0x40; |
for (i = 0; i < 1036; i++) |
buffer[i] = 0; |
|
s = buffer2 + o; |
d = buffer + o2 + 4; |
|
memcpy (d, s, l); |
|
for (i = 0; i < l; i++) |
if (s[i] != d[i]) |
printf ("Error at %X+%d -> %X+%d (%02X != %02X)\n", s, i, d, i, s[i], d[i]); |
if (d[-1] || d[-2] || d[-3] || d[-4]) |
printf ("Error before %X\n", d); |
if (d[l] || d[l+1] || d[l+2] || d[l+3]) |
printf ("Error after %X\n", d+l); |
} |
} |
} |
} |