9
0
Fork 0

import io-{read,write}s{b,w} functions from linux

This patch imports:
- io-readsb,
- io-readsw,
- io-writesb,
- io-writesw,
from linux

Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
This commit is contained in:
Marc Kleine-Budde 2008-10-21 15:54:39 +02:00
parent 983630ef2b
commit 5482395b9e
9 changed files with 680 additions and 6 deletions

View File

@ -1,4 +1,5 @@
obj-$(CONFIG_CMD_BOOTM) += armlinux.o
obj-y += _ashldi3.o
obj-y += _ashrdi3.o
obj-y += cache.o
@ -10,6 +11,11 @@ obj-y += _umodsi3.o
obj-y += _lshrdi3.o
obj-y += findbit.o
obj-y += arm.o
obj-y += io-readsb.o
obj-y += io-readsw-armv4.o
obj-y += io-writesb.o
obj-y += io-writesw-armv4.o
obj-$(CONFIG_MODULES) += module.o
extra-$(CONFIG_GENERIC_LINKER_SCRIPT) += u-boot.lds

123
arch/arm/lib/io-readsb.S Normal file
View File

@ -0,0 +1,123 @@
/*
* linux/arch/arm/lib/io-readsb.S
*
* Copyright (C) 1995-2000 Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
.Linsb_align: rsb ip, ip, #4
cmp ip, r2
movgt ip, r2
cmp ip, #2
ldrb r3, [r0]
strb r3, [r1], #1
ldrgeb r3, [r0]
strgeb r3, [r1], #1
ldrgtb r3, [r0]
strgtb r3, [r1], #1
subs r2, r2, ip
bne .Linsb_aligned
ENTRY(__raw_readsb)
teq r2, #0 @ do we have to check for the zero len?
moveq pc, lr
ands ip, r1, #3
bne .Linsb_align
.Linsb_aligned: stmfd sp!, {r4 - r6, lr}
subs r2, r2, #16
bmi .Linsb_no_16
.Linsb_16_lp: ldrb r3, [r0]
ldrb r4, [r0]
ldrb r5, [r0]
mov r3, r3, put_byte_0
ldrb r6, [r0]
orr r3, r3, r4, put_byte_1
ldrb r4, [r0]
orr r3, r3, r5, put_byte_2
ldrb r5, [r0]
orr r3, r3, r6, put_byte_3
ldrb r6, [r0]
mov r4, r4, put_byte_0
ldrb ip, [r0]
orr r4, r4, r5, put_byte_1
ldrb r5, [r0]
orr r4, r4, r6, put_byte_2
ldrb r6, [r0]
orr r4, r4, ip, put_byte_3
ldrb ip, [r0]
mov r5, r5, put_byte_0
ldrb lr, [r0]
orr r5, r5, r6, put_byte_1
ldrb r6, [r0]
orr r5, r5, ip, put_byte_2
ldrb ip, [r0]
orr r5, r5, lr, put_byte_3
ldrb lr, [r0]
mov r6, r6, put_byte_0
orr r6, r6, ip, put_byte_1
ldrb ip, [r0]
orr r6, r6, lr, put_byte_2
orr r6, r6, ip, put_byte_3
stmia r1!, {r3 - r6}
subs r2, r2, #16
bpl .Linsb_16_lp
tst r2, #15
ldmeqfd sp!, {r4 - r6, pc}
.Linsb_no_16: tst r2, #8
beq .Linsb_no_8
ldrb r3, [r0]
ldrb r4, [r0]
ldrb r5, [r0]
mov r3, r3, put_byte_0
ldrb r6, [r0]
orr r3, r3, r4, put_byte_1
ldrb r4, [r0]
orr r3, r3, r5, put_byte_2
ldrb r5, [r0]
orr r3, r3, r6, put_byte_3
ldrb r6, [r0]
mov r4, r4, put_byte_0
ldrb ip, [r0]
orr r4, r4, r5, put_byte_1
orr r4, r4, r6, put_byte_2
orr r4, r4, ip, put_byte_3
stmia r1!, {r3, r4}
.Linsb_no_8: tst r2, #4
beq .Linsb_no_4
ldrb r3, [r0]
ldrb r4, [r0]
ldrb r5, [r0]
ldrb r6, [r0]
mov r3, r3, put_byte_0
orr r3, r3, r4, put_byte_1
orr r3, r3, r5, put_byte_2
orr r3, r3, r6, put_byte_3
str r3, [r1], #4
.Linsb_no_4: ands r2, r2, #3
ldmeqfd sp!, {r4 - r6, pc}
cmp r2, #2
ldrb r3, [r0]
strb r3, [r1], #1
ldrgeb r3, [r0]
strgeb r3, [r1], #1
ldrgtb r3, [r0]
strgtb r3, [r1]
ldmfd sp!, {r4 - r6, pc}
ENDPROC(__raw_readsb)

View File

@ -0,0 +1,131 @@
/*
* linux/arch/arm/lib/io-readsw-armv4.S
*
* Copyright (C) 1995-2000 Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
.macro pack, rd, hw1, hw2
#ifndef __ARMEB__
orr \rd, \hw1, \hw2, lsl #16
#else
orr \rd, \hw2, \hw1, lsl #16
#endif
.endm
.Linsw_align: movs ip, r1, lsl #31
bne .Linsw_noalign
ldrh ip, [r0]
sub r2, r2, #1
strh ip, [r1], #2
ENTRY(__raw_readsw)
teq r2, #0
moveq pc, lr
tst r1, #3
bne .Linsw_align
stmfd sp!, {r4, r5, lr}
subs r2, r2, #8
bmi .Lno_insw_8
.Linsw_8_lp: ldrh r3, [r0]
ldrh r4, [r0]
pack r3, r3, r4
ldrh r4, [r0]
ldrh r5, [r0]
pack r4, r4, r5
ldrh r5, [r0]
ldrh ip, [r0]
pack r5, r5, ip
ldrh ip, [r0]
ldrh lr, [r0]
pack ip, ip, lr
subs r2, r2, #8
stmia r1!, {r3 - r5, ip}
bpl .Linsw_8_lp
.Lno_insw_8: tst r2, #4
beq .Lno_insw_4
ldrh r3, [r0]
ldrh r4, [r0]
pack r3, r3, r4
ldrh r4, [r0]
ldrh ip, [r0]
pack r4, r4, ip
stmia r1!, {r3, r4}
.Lno_insw_4: movs r2, r2, lsl #31
bcc .Lno_insw_2
ldrh r3, [r0]
ldrh ip, [r0]
pack r3, r3, ip
str r3, [r1], #4
.Lno_insw_2: ldrneh r3, [r0]
strneh r3, [r1]
ldmfd sp!, {r4, r5, pc}
#ifdef __ARMEB__
#define _BE_ONLY_(code...) code
#define _LE_ONLY_(code...)
#define push_hbyte0 lsr #8
#define pull_hbyte1 lsl #24
#else
#define _BE_ONLY_(code...)
#define _LE_ONLY_(code...) code
#define push_hbyte0 lsl #24
#define pull_hbyte1 lsr #8
#endif
.Linsw_noalign: stmfd sp!, {r4, lr}
ldrccb ip, [r1, #-1]!
bcc 1f
ldrh ip, [r0]
sub r2, r2, #1
_BE_ONLY_( mov ip, ip, ror #8 )
strb ip, [r1], #1
_LE_ONLY_( mov ip, ip, lsr #8 )
_BE_ONLY_( mov ip, ip, lsr #24 )
1: subs r2, r2, #2
bmi 3f
_BE_ONLY_( mov ip, ip, lsl #24 )
2: ldrh r3, [r0]
ldrh r4, [r0]
subs r2, r2, #2
orr ip, ip, r3, lsl #8
orr ip, ip, r4, push_hbyte0
str ip, [r1], #4
mov ip, r4, pull_hbyte1
bpl 2b
_BE_ONLY_( mov ip, ip, lsr #24 )
3: tst r2, #1
strb ip, [r1], #1
ldrneh ip, [r0]
_BE_ONLY_( movne ip, ip, ror #8 )
strneb ip, [r1], #1
_LE_ONLY_( movne ip, ip, lsr #8 )
_BE_ONLY_( movne ip, ip, lsr #24 )
strneb ip, [r1]
ldmfd sp!, {r4, pc}
ENDPROC(__raw_readsw)

94
arch/arm/lib/io-writesb.S Normal file
View File

@ -0,0 +1,94 @@
/*
* linux/arch/arm/lib/io-writesb.S
*
* Copyright (C) 1995-2000 Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
.macro outword, rd
#ifndef __ARMEB__
strb \rd, [r0]
mov \rd, \rd, lsr #8
strb \rd, [r0]
mov \rd, \rd, lsr #8
strb \rd, [r0]
mov \rd, \rd, lsr #8
strb \rd, [r0]
#else
mov lr, \rd, lsr #24
strb lr, [r0]
mov lr, \rd, lsr #16
strb lr, [r0]
mov lr, \rd, lsr #8
strb lr, [r0]
strb \rd, [r0]
#endif
.endm
.Loutsb_align: rsb ip, ip, #4
cmp ip, r2
movgt ip, r2
cmp ip, #2
ldrb r3, [r1], #1
strb r3, [r0]
ldrgeb r3, [r1], #1
strgeb r3, [r0]
ldrgtb r3, [r1], #1
strgtb r3, [r0]
subs r2, r2, ip
bne .Loutsb_aligned
ENTRY(__raw_writesb)
teq r2, #0 @ do we have to check for the zero len?
moveq pc, lr
ands ip, r1, #3
bne .Loutsb_align
.Loutsb_aligned:
stmfd sp!, {r4, r5, lr}
subs r2, r2, #16
bmi .Loutsb_no_16
.Loutsb_16_lp: ldmia r1!, {r3, r4, r5, ip}
outword r3
outword r4
outword r5
outword ip
subs r2, r2, #16
bpl .Loutsb_16_lp
tst r2, #15
ldmeqfd sp!, {r4, r5, pc}
.Loutsb_no_16: tst r2, #8
beq .Loutsb_no_8
ldmia r1!, {r3, r4}
outword r3
outword r4
.Loutsb_no_8: tst r2, #4
beq .Loutsb_no_4
ldr r3, [r1], #4
outword r3
.Loutsb_no_4: ands r2, r2, #3
ldmeqfd sp!, {r4, r5, pc}
cmp r2, #2
ldrb r3, [r1], #1
strb r3, [r0]
ldrgeb r3, [r1], #1
strgeb r3, [r0]
ldrgtb r3, [r1]
strgtb r3, [r0]
ldmfd sp!, {r4, r5, pc}
ENDPROC(__raw_writesb)

View File

@ -0,0 +1,97 @@
/*
* linux/arch/arm/lib/io-writesw-armv4.S
*
* Copyright (C) 1995-2000 Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
.macro outword, rd
#ifndef __ARMEB__
strh \rd, [r0]
mov \rd, \rd, lsr #16
strh \rd, [r0]
#else
mov lr, \rd, lsr #16
strh lr, [r0]
strh \rd, [r0]
#endif
.endm
.Loutsw_align: movs ip, r1, lsl #31
bne .Loutsw_noalign
ldrh r3, [r1], #2
sub r2, r2, #1
strh r3, [r0]
ENTRY(__raw_writesw)
teq r2, #0
moveq pc, lr
ands r3, r1, #3
bne .Loutsw_align
stmfd sp!, {r4, r5, lr}
subs r2, r2, #8
bmi .Lno_outsw_8
.Loutsw_8_lp: ldmia r1!, {r3, r4, r5, ip}
subs r2, r2, #8
outword r3
outword r4
outword r5
outword ip
bpl .Loutsw_8_lp
.Lno_outsw_8: tst r2, #4
beq .Lno_outsw_4
ldmia r1!, {r3, ip}
outword r3
outword ip
.Lno_outsw_4: movs r2, r2, lsl #31
bcc .Lno_outsw_2
ldr r3, [r1], #4
outword r3
.Lno_outsw_2: ldrneh r3, [r1]
strneh r3, [r0]
ldmfd sp!, {r4, r5, pc}
#ifdef __ARMEB__
#define pull_hbyte0 lsl #8
#define push_hbyte1 lsr #24
#else
#define pull_hbyte0 lsr #24
#define push_hbyte1 lsl #8
#endif
.Loutsw_noalign:
ldr r3, [r1, -r3]!
subcs r2, r2, #1
bcs 2f
subs r2, r2, #2
bmi 3f
1: mov ip, r3, lsr #8
strh ip, [r0]
2: mov ip, r3, pull_hbyte0
ldr r3, [r1, #4]!
subs r2, r2, #2
orr ip, ip, r3, push_hbyte1
strh ip, [r0]
bpl 1b
tst r2, #1
3: movne ip, r3, lsr #8
strneh ip, [r0]
mov pc, lr
ENDPROC(__raw_writesw)

116
include/asm-arm/assembler.h Normal file
View File

@ -0,0 +1,116 @@
/*
* arch/arm/include/asm/assembler.h
*
* Copyright (C) 1996-2000 Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This file contains arm architecture specific defines
* for the different processors.
*
* Do not include any C declarations in this file - it is included by
* assembler source.
*/
#ifndef __ASSEMBLY__
#error "Only include this from assembly code"
#endif
#include <asm/ptrace.h>
/*
* Endian independent macros for shifting bytes within registers.
*/
#ifndef __ARMEB__
#define pull lsr
#define push lsl
#define get_byte_0 lsl #0
#define get_byte_1 lsr #8
#define get_byte_2 lsr #16
#define get_byte_3 lsr #24
#define put_byte_0 lsl #0
#define put_byte_1 lsl #8
#define put_byte_2 lsl #16
#define put_byte_3 lsl #24
#else
#define pull lsl
#define push lsr
#define get_byte_0 lsr #24
#define get_byte_1 lsr #16
#define get_byte_2 lsr #8
#define get_byte_3 lsl #0
#define put_byte_0 lsl #24
#define put_byte_1 lsl #16
#define put_byte_2 lsl #8
#define put_byte_3 lsl #0
#endif
/*
* Data preload for architectures that support it
*/
#if __LINUX_ARM_ARCH__ >= 5
#define PLD(code...) code
#else
#define PLD(code...)
#endif
/*
* This can be used to enable code to cacheline align the destination
* pointer when bulk writing to memory. Experiments on StrongARM and
* XScale didn't show this a worthwhile thing to do when the cache is not
* set to write-allocate (this would need further testing on XScale when WA
* is used).
*
* On Feroceon there is much to gain however, regardless of cache mode.
*/
#ifdef CONFIG_CPU_FEROCEON
#define CALGN(code...) code
#else
#define CALGN(code...)
#endif
/*
* Enable and disable interrupts
*/
#if __LINUX_ARM_ARCH__ >= 6
.macro disable_irq
cpsid i
.endm
.macro enable_irq
cpsie i
.endm
#else
.macro disable_irq
msr cpsr_c, #PSR_I_BIT | SVC_MODE
.endm
.macro enable_irq
msr cpsr_c, #SVC_MODE
.endm
#endif
/*
* Save the current IRQ state and disable IRQs. Note that this macro
* assumes FIQs are enabled, and that the processor is in SVC mode.
*/
.macro save_and_disable_irqs, oldcpsr
mrs \oldcpsr, cpsr
disable_irq
.endm
/*
* Restore interrupt state previously stored in a register. We don't
* guarantee that this will preserve the flags.
*/
.macro restore_irqs, oldcpsr
msr cpsr_c, \oldcpsr
.endm
#define USER(x...) \
9999: x; \
.section __ex_table,"a"; \
.align 3; \
.long 9999b,9001f; \
.previous

View File

@ -39,13 +39,13 @@
#define __arch_putw(v,a) (*(volatile unsigned short *)(a) = (v))
#define __arch_putl(v,a) (*(volatile unsigned int *)(a) = (v))
extern void __raw_writesb(unsigned int addr, const void *data, int bytelen);
extern void __raw_writesw(unsigned int addr, const void *data, int wordlen);
extern void __raw_writesl(unsigned int addr, const void *data, int longlen);
extern void __raw_writesb(void __iomem *addr, const void *data, int bytelen);
extern void __raw_writesw(void __iomem *addr, const void *data, int wordlen);
extern void __raw_writesl(void __iomem *addr, const void *data, int longlen);
extern void __raw_readsb(unsigned int addr, void *data, int bytelen);
extern void __raw_readsw(unsigned int addr, void *data, int wordlen);
extern void __raw_readsl(unsigned int addr, void *data, int longlen);
extern void __raw_readsb(const void __iomem *addr, void *data, int bytelen);
extern void __raw_readsw(const void __iomem *addr, void *data, int wordlen);
extern void __raw_readsl(const void __iomem *addr, void *data, int longlen);
#define __raw_writeb(v,a) __arch_putb(v,a)
#define __raw_writew(v,a) __arch_putw(v,a)

11
include/asm-arm/linkage.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef __ASM_LINKAGE_H
#define __ASM_LINKAGE_H
#define __ALIGN .align 0
#define __ALIGN_STR ".align 0"
#define ENDPROC(name) \
.type name, %function; \
END(name)
#endif

96
include/linux/linkage.h Normal file
View File

@ -0,0 +1,96 @@
#ifndef _LINUX_LINKAGE_H
#define _LINUX_LINKAGE_H
#include <linux/compiler.h>
#include <asm/linkage.h>
#ifdef __cplusplus
#define CPP_ASMLINKAGE extern "C"
#else
#define CPP_ASMLINKAGE
#endif
#ifndef asmlinkage
#define asmlinkage CPP_ASMLINKAGE
#endif
#ifndef asmregparm
# define asmregparm
#endif
#define __page_aligned_data __section(.data.page_aligned) __aligned(PAGE_SIZE)
#define __page_aligned_bss __section(.bss.page_aligned) __aligned(PAGE_SIZE)
/*
* This is used by architectures to keep arguments on the stack
* untouched by the compiler by keeping them live until the end.
* The argument stack may be owned by the assembly-language
* caller, not the callee, and gcc doesn't always understand
* that.
*
* We have the return value, and a maximum of six arguments.
*
* This should always be followed by a "return ret" for the
* protection to work (ie no more work that the compiler might
* end up needing stack temporaries for).
*/
/* Assembly files may be compiled with -traditional .. */
#ifndef __ASSEMBLY__
#ifndef asmlinkage_protect
# define asmlinkage_protect(n, ret, args...) do { } while (0)
#endif
#endif
#ifndef __ALIGN
#define __ALIGN .align 4,0x90
#define __ALIGN_STR ".align 4,0x90"
#endif
#ifdef __ASSEMBLY__
#define ALIGN __ALIGN
#define ALIGN_STR __ALIGN_STR
#ifndef ENTRY
#define ENTRY(name) \
.globl name; \
ALIGN; \
name:
#endif
#ifndef WEAK
#define WEAK(name) \
.weak name; \
name:
#endif
#define KPROBE_ENTRY(name) \
.pushsection .kprobes.text, "ax"; \
ENTRY(name)
#define KPROBE_END(name) \
END(name); \
.popsection
#ifndef END
#define END(name) \
.size name, .-name
#endif
/* If symbol 'name' is treated as a subroutine (gets called, and returns)
* then please use ENDPROC to mark 'name' as STT_FUNC for the benefit of
* static analysis tools such as stack depth analyzer.
*/
#ifndef ENDPROC
#define ENDPROC(name) \
.type name, @function; \
END(name)
#endif
#endif
#define NORET_TYPE /**/
#define ATTRIB_NORET __attribute__((noreturn))
#define NORET_AND noreturn,
#endif