Linux Audio

Check our new training course

Loading...
v4.17
  1/*
  2 * Copyright (C) 2009 Michal Simek <monstr@monstr.eu>
  3 * Copyright (C) 2009 PetaLogix
  4 * Copyright (C) 2007 LynuxWorks, Inc.
  5 *
  6 * This file is subject to the terms and conditions of the GNU General Public
  7 * License.  See the file "COPYING" in the main directory of this archive
  8 * for more details.
  9 */
 10
 11#include <linux/errno.h>
 12#include <linux/linkage.h>
 13#include <asm/page.h>
 14
 15/*
 16 * int __strncpy_user(char *to, char *from, int len);
 17 *
 18 * Returns:
 19 *  -EFAULT  for an exception
 20 *  len      if we hit the buffer limit
 21 *  bytes copied
 22 */
 23
 24	.text
 25.globl __strncpy_user;
 26.type  __strncpy_user, @function
 27.align 4;
 28__strncpy_user:
 29
 30	/*
 31	 * r5 - to
 32	 * r6 - from
 33	 * r7 - len
 34	 * r3 - temp count
 35	 * r4 - temp val
 36	 */
 37	beqid	r7,3f
 38	addik	r3,r7,0		/* temp_count = len */
 391:
 40	lbu	r4,r6,r0
 41	beqid	r4,2f
 42	sb	r4,r5,r0
 43
 44	addik	r5,r5,1
 45	addik	r6,r6,1		/* delay slot */
 46
 47	addik	r3,r3,-1
 48	bnei	r3,1b		/* break on len */
 492:
 50	rsubk	r3,r3,r7	/* temp_count = len - temp_count */
 513:
 52	rtsd	r15,8
 53	nop
 54	.size   __strncpy_user, . - __strncpy_user
 55
 56	.section	.fixup, "ax"
 57	.align	2
 584:
 59	brid	3b
 60	addik	r3,r0, -EFAULT
 61
 62	.section	__ex_table, "a"
 63	.word	1b,4b
 64
 65/*
 66 * int __strnlen_user(char __user *str, int maxlen);
 67 *
 68 * Returns:
 69 *  0 on error
 70 *  maxlen + 1  if no NUL byte found within maxlen bytes
 71 *  size of the string (including NUL byte)
 72 */
 73
 74	.text
 75.globl __strnlen_user;
 76.type  __strnlen_user, @function
 77.align 4;
 78__strnlen_user:
 79	beqid	r6,3f
 80	addik	r3,r6,0
 811:
 82	lbu	r4,r5,r0
 83	beqid	r4,2f		/* break on NUL */
 84	addik	r3,r3,-1	/* delay slot */
 85
 86	bneid	r3,1b
 87	addik	r5,r5,1		/* delay slot */
 88
 89	addik	r3,r3,-1	/* for break on len */
 902:
 91	rsubk	r3,r3,r6
 923:
 93	rtsd	r15,8
 94	nop
 95	.size   __strnlen_user, . - __strnlen_user
 96
 97	.section	.fixup,"ax"
 984:
 99	brid	3b
100	addk	r3,r0,r0
101
102	.section	__ex_table,"a"
103	.word	1b,4b
104
105/* Loop unrolling for __copy_tofrom_user */
106#define COPY(offset)	\
1071:	lwi	r4 , r6, 0x0000 + offset;	\
1082:	lwi	r19, r6, 0x0004 + offset;	\
1093:	lwi	r20, r6, 0x0008 + offset;	\
1104:	lwi	r21, r6, 0x000C + offset;	\
1115:	lwi	r22, r6, 0x0010 + offset;	\
1126:	lwi	r23, r6, 0x0014 + offset;	\
1137:	lwi	r24, r6, 0x0018 + offset;	\
1148:	lwi	r25, r6, 0x001C + offset;	\
1159:	swi	r4 , r5, 0x0000 + offset;	\
11610:	swi	r19, r5, 0x0004 + offset;	\
11711:	swi	r20, r5, 0x0008 + offset;	\
11812:	swi	r21, r5, 0x000C + offset;	\
11913:	swi	r22, r5, 0x0010 + offset;	\
12014:	swi	r23, r5, 0x0014 + offset;	\
12115:	swi	r24, r5, 0x0018 + offset;	\
12216:	swi	r25, r5, 0x001C + offset;	\
123	.section __ex_table,"a";		\
124	.word	1b, 33f;			\
125	.word	2b, 33f;			\
126	.word	3b, 33f;			\
127	.word	4b, 33f;			\
128	.word	5b, 33f;			\
129	.word	6b, 33f;			\
130	.word	7b, 33f;			\
131	.word	8b, 33f;			\
132	.word	9b, 33f;			\
133	.word	10b, 33f;			\
134	.word	11b, 33f;			\
135	.word	12b, 33f;			\
136	.word	13b, 33f;			\
137	.word	14b, 33f;			\
138	.word	15b, 33f;			\
139	.word	16b, 33f;			\
140	.text
141
142#define COPY_80(offset)	\
143	COPY(0x00 + offset);\
144	COPY(0x20 + offset);\
145	COPY(0x40 + offset);\
146	COPY(0x60 + offset);
147
148/*
149 * int __copy_tofrom_user(char *to, char *from, int len)
150 * Return:
151 *   0 on success
152 *   number of not copied bytes on error
153 */
154	.text
155.globl __copy_tofrom_user;
156.type  __copy_tofrom_user, @function
157.align 4;
158__copy_tofrom_user:
159	/*
160	 * r5 - to
161	 * r6 - from
162	 * r7, r3 - count
163	 * r4 - tempval
164	 */
165	beqid	r7, 0f /* zero size is not likely */
166	or	r3, r5, r6 /* find if is any to/from unaligned */
167	or	r3, r3, r7 /* find if count is unaligned */
168	andi	r3, r3, 0x3 /* mask last 3 bits */
169	bneid	r3, bu1 /* if r3 is not zero then byte copying */
170	or	r3, r0, r0
171
172	rsubi	r3, r7, PAGE_SIZE /* detect PAGE_SIZE */
173	beqid	r3, page;
174	or	r3, r0, r0
175
176w1:	lw	r4, r6, r3 /* at least one 4 byte copy */
177w2:	sw	r4, r5, r3
178	addik	r7, r7, -4
179	bneid	r7, w1
180	addik	r3, r3, 4
181	addik	r3, r7, 0
182	rtsd	r15, 8
183	nop
184
185	.section	__ex_table,"a"
186	.word	w1, 0f;
187	.word	w2, 0f;
188	.text
189
190.align 4 /* Alignment is important to keep icache happy */
191page:	/* Create room on stack and save registers for storign values */
192	addik   r1, r1, -40
193	swi	r5, r1, 0
194	swi	r6, r1, 4
195	swi	r7, r1, 8
196	swi	r19, r1, 12
197	swi	r20, r1, 16
198	swi	r21, r1, 20
199	swi	r22, r1, 24
200	swi	r23, r1, 28
201	swi	r24, r1, 32
202	swi	r25, r1, 36
203loop:	/* r4, r19, r20, r21, r22, r23, r24, r25 are used for storing values */
204	/* Loop unrolling to get performance boost */
205	COPY_80(0x000);
206	COPY_80(0x080);
207	COPY_80(0x100);
208	COPY_80(0x180);
209	/* copy loop */
210	addik   r6, r6, 0x200
211	addik   r7, r7, -0x200
212	bneid   r7, loop
213	addik   r5, r5, 0x200
214
215	/* Restore register content */
216	lwi	r5, r1, 0
217	lwi	r6, r1, 4
218	lwi	r7, r1, 8
219	lwi	r19, r1, 12
220	lwi	r20, r1, 16
221	lwi	r21, r1, 20
222	lwi	r22, r1, 24
223	lwi	r23, r1, 28
224	lwi	r24, r1, 32
225	lwi	r25, r1, 36
226	addik   r1, r1, 40
227	/* return back */
228	addik	r3, r0, 0
229	rtsd	r15, 8
230	nop
231
232/* Fault case - return temp count */
23333:
234	addik	r3, r7, 0
235	/* Restore register content */
236	lwi	r5, r1, 0
237	lwi	r6, r1, 4
238	lwi	r7, r1, 8
239	lwi	r19, r1, 12
240	lwi	r20, r1, 16
241	lwi	r21, r1, 20
242	lwi	r22, r1, 24
243	lwi	r23, r1, 28
244	lwi	r24, r1, 32
245	lwi	r25, r1, 36
246	addik   r1, r1, 40
247	/* return back */
248	rtsd	r15, 8
249	nop
250
251.align 4 /* Alignment is important to keep icache happy */
252bu1:	lbu	r4,r6,r3
253bu2:	sb	r4,r5,r3
254	addik	r7,r7,-1
255	bneid	r7,bu1
256	addik	r3,r3,1		/* delay slot */
2570:
258	addik	r3,r7,0
259	rtsd	r15,8
260	nop
261	.size   __copy_tofrom_user, . - __copy_tofrom_user
262
263	.section	__ex_table,"a"
264	.word	bu1, 0b;
265	.word	bu2, 0b;
266	.text
v6.8
  1/*
  2 * Copyright (C) 2009 Michal Simek <monstr@monstr.eu>
  3 * Copyright (C) 2009 PetaLogix
  4 * Copyright (C) 2007 LynuxWorks, Inc.
  5 *
  6 * This file is subject to the terms and conditions of the GNU General Public
  7 * License.  See the file "COPYING" in the main directory of this archive
  8 * for more details.
  9 */
 10
 11#include <linux/errno.h>
 12#include <linux/linkage.h>
 13#include <asm/page.h>
 14
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 15/* Loop unrolling for __copy_tofrom_user */
 16#define COPY(offset)	\
 171:	lwi	r4 , r6, 0x0000 + offset;	\
 182:	lwi	r19, r6, 0x0004 + offset;	\
 193:	lwi	r20, r6, 0x0008 + offset;	\
 204:	lwi	r21, r6, 0x000C + offset;	\
 215:	lwi	r22, r6, 0x0010 + offset;	\
 226:	lwi	r23, r6, 0x0014 + offset;	\
 237:	lwi	r24, r6, 0x0018 + offset;	\
 248:	lwi	r25, r6, 0x001C + offset;	\
 259:	swi	r4 , r5, 0x0000 + offset;	\
 2610:	swi	r19, r5, 0x0004 + offset;	\
 2711:	swi	r20, r5, 0x0008 + offset;	\
 2812:	swi	r21, r5, 0x000C + offset;	\
 2913:	swi	r22, r5, 0x0010 + offset;	\
 3014:	swi	r23, r5, 0x0014 + offset;	\
 3115:	swi	r24, r5, 0x0018 + offset;	\
 3216:	swi	r25, r5, 0x001C + offset;	\
 33	.section __ex_table,"a";		\
 34	.word	1b, 33f;			\
 35	.word	2b, 33f;			\
 36	.word	3b, 33f;			\
 37	.word	4b, 33f;			\
 38	.word	5b, 33f;			\
 39	.word	6b, 33f;			\
 40	.word	7b, 33f;			\
 41	.word	8b, 33f;			\
 42	.word	9b, 33f;			\
 43	.word	10b, 33f;			\
 44	.word	11b, 33f;			\
 45	.word	12b, 33f;			\
 46	.word	13b, 33f;			\
 47	.word	14b, 33f;			\
 48	.word	15b, 33f;			\
 49	.word	16b, 33f;			\
 50	.text
 51
 52#define COPY_80(offset)	\
 53	COPY(0x00 + offset);\
 54	COPY(0x20 + offset);\
 55	COPY(0x40 + offset);\
 56	COPY(0x60 + offset);
 57
 58/*
 59 * int __copy_tofrom_user(char *to, char *from, int len)
 60 * Return:
 61 *   0 on success
 62 *   number of not copied bytes on error
 63 */
 64	.text
 65.globl __copy_tofrom_user;
 66.type  __copy_tofrom_user, @function
 67.align 4;
 68__copy_tofrom_user:
 69	/*
 70	 * r5 - to
 71	 * r6 - from
 72	 * r7, r3 - count
 73	 * r4 - tempval
 74	 */
 75	beqid	r7, 0f /* zero size is not likely */
 76	or	r3, r5, r6 /* find if is any to/from unaligned */
 77	or	r3, r3, r7 /* find if count is unaligned */
 78	andi	r3, r3, 0x3 /* mask last 3 bits */
 79	bneid	r3, bu1 /* if r3 is not zero then byte copying */
 80	or	r3, r0, r0
 81
 82	rsubi	r3, r7, PAGE_SIZE /* detect PAGE_SIZE */
 83	beqid	r3, page;
 84	or	r3, r0, r0
 85
 86w1:	lw	r4, r6, r3 /* at least one 4 byte copy */
 87w2:	sw	r4, r5, r3
 88	addik	r7, r7, -4
 89	bneid	r7, w1
 90	addik	r3, r3, 4
 91	addik	r3, r7, 0
 92	rtsd	r15, 8
 93	nop
 94
 95	.section	__ex_table,"a"
 96	.word	w1, 0f;
 97	.word	w2, 0f;
 98	.text
 99
100.align 4 /* Alignment is important to keep icache happy */
101page:	/* Create room on stack and save registers for storing values */
102	addik   r1, r1, -40
103	swi	r5, r1, 0
104	swi	r6, r1, 4
105	swi	r7, r1, 8
106	swi	r19, r1, 12
107	swi	r20, r1, 16
108	swi	r21, r1, 20
109	swi	r22, r1, 24
110	swi	r23, r1, 28
111	swi	r24, r1, 32
112	swi	r25, r1, 36
113loop:	/* r4, r19, r20, r21, r22, r23, r24, r25 are used for storing values */
114	/* Loop unrolling to get performance boost */
115	COPY_80(0x000);
116	COPY_80(0x080);
117	COPY_80(0x100);
118	COPY_80(0x180);
119	/* copy loop */
120	addik   r6, r6, 0x200
121	addik   r7, r7, -0x200
122	bneid   r7, loop
123	addik   r5, r5, 0x200
124
125	/* Restore register content */
126	lwi	r5, r1, 0
127	lwi	r6, r1, 4
128	lwi	r7, r1, 8
129	lwi	r19, r1, 12
130	lwi	r20, r1, 16
131	lwi	r21, r1, 20
132	lwi	r22, r1, 24
133	lwi	r23, r1, 28
134	lwi	r24, r1, 32
135	lwi	r25, r1, 36
136	addik   r1, r1, 40
137	/* return back */
138	addik	r3, r0, 0
139	rtsd	r15, 8
140	nop
141
142/* Fault case - return temp count */
14333:
144	addik	r3, r7, 0
145	/* Restore register content */
146	lwi	r5, r1, 0
147	lwi	r6, r1, 4
148	lwi	r7, r1, 8
149	lwi	r19, r1, 12
150	lwi	r20, r1, 16
151	lwi	r21, r1, 20
152	lwi	r22, r1, 24
153	lwi	r23, r1, 28
154	lwi	r24, r1, 32
155	lwi	r25, r1, 36
156	addik   r1, r1, 40
157	/* return back */
158	rtsd	r15, 8
159	nop
160
161.align 4 /* Alignment is important to keep icache happy */
162bu1:	lbu	r4,r6,r3
163bu2:	sb	r4,r5,r3
164	addik	r7,r7,-1
165	bneid	r7,bu1
166	addik	r3,r3,1		/* delay slot */
1670:
168	addik	r3,r7,0
169	rtsd	r15,8
170	nop
171	.size   __copy_tofrom_user, . - __copy_tofrom_user
172
173	.section	__ex_table,"a"
174	.word	bu1, 0b;
175	.word	bu2, 0b;
176	.text