1/*
2 * Copyright (C) 2004-2006 Atmel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8#include <asm/errno.h>
9#include <asm/asm.h>
10
11	/*
12	 * unsigned int csum_partial_copy_generic(const char *src, char *dst, int len
13	 *					  int sum, int *src_err_ptr,
14	 *					  int *dst_err_ptr)
15	 *
16	 * Copy src to dst while checksumming, otherwise like csum_partial.
17	 */
18
19	.macro ld_src size, reg, ptr
209999:	ld.\size \reg, \ptr
21	.section __ex_table, "a"
22	.long	9999b, fixup_ld_src
23	.previous
24	.endm
25
26	.macro st_dst size, ptr, reg
279999:	st.\size \ptr, \reg
28	.section __ex_table, "a"
29	.long	9999b, fixup_st_dst
30	.previous
31	.endm
32
33	.text
34	.global	csum_partial_copy_generic
35	.type	csum_partial_copy_generic,"function"
36	.align	1
37csum_partial_copy_generic:
38	pushm	r4-r7,lr
39
40	/* The inner loop */
411:	sub	r10, 4
42	brlt	5f
432:	ld_src	w, r5, r12++
44	st_dst	w, r11++, r5
45	add	r9, r5
46	acr	r9
47	sub	r10, 4
48	brge	2b
49
50	/* return if we had a whole number of words */
515:	sub	r10, -4
52	brne	7f
53
546:	mov	r12, r9
55	popm	r4-r7,pc
56
57	/* handle additional bytes at the tail */
587:	mov	r5, 0
59	mov	r4, 32
608:	ld_src	ub, r6, r12++
61	st_dst	b, r11++, r6
62	lsl	r5, 8
63	sub	r4, 8
64	bfins	r5, r6, 0, 8
65	sub	r10, 1
66	brne	8b
67
68	lsl	r5, r5, r4
69	add	r9, r5
70	acr	r9
71	rjmp	6b
72
73	/* Exception handler */
74	.section .fixup,"ax"
75	.align	1
76fixup_ld_src:
77	mov	r9, -EFAULT
78	cp.w	r8, 0
79	breq	1f
80	st.w	r8[0], r9
81
821:	/*
83	 * TODO: zero the complete destination - computing the rest
84	 * is too much work
85	 */
86
87	mov	r9, 0
88	rjmp	6b
89
90fixup_st_dst:
91	mov	r9, -EFAULT
92	lddsp	r8, sp[20]
93	cp.w	r8, 0
94	breq	1f
95	st.w	r8[0], r9
961:	mov	r9, 0
97	rjmp	6b
98
99	.previous
100