OpenCores
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);
}
}
}
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.