1/*
2 * Coyright (c) 2005-2006 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29#include <sys/cdefs.h>
30#include <sys/types.h>
31#include <sys/munge.h>
32#include <stdint.h>
33
34static inline __attribute__((always_inline)) void
35munge_32_to_64_unsigned(volatile uint64_t *dest, volatile uint32_t *src, int count);
36
37/*
38 * Refer to comments in bsd/sys/munge.h
39 */
40void
41munge_w(const void *arg0 __unused, void *args)
42{
43	munge_32_to_64_unsigned(args, args, 1);
44}
45
46void
47munge_ww(const void *arg0 __unused, void *args)
48{
49	munge_32_to_64_unsigned(args, args, 2);
50}
51
52void
53munge_www(const void *arg0 __unused, void *args)
54{
55	munge_32_to_64_unsigned(args, args, 3);
56}
57
58void
59munge_wwww(const void *arg0 __unused, void *args)
60{
61	munge_32_to_64_unsigned(args, args, 4);
62}
63
64void
65munge_wwwww(const void *arg0 __unused, void *args)
66{
67	munge_32_to_64_unsigned(args, args, 5);
68}
69
70void
71munge_wwwwww(const void *arg0 __unused, void *args)
72{
73	munge_32_to_64_unsigned(args, args, 6);
74}
75
76void
77munge_wwwwwww(const void *arg0 __unused, void *args)
78{
79	munge_32_to_64_unsigned(args, args, 7);
80}
81
82void
83munge_wwwwwwww(const void *arg0 __unused, void *args)
84{
85	munge_32_to_64_unsigned(args, args, 8);
86}
87
88void
89munge_wl(const void *arg0 __unused, void *args)
90{
91	volatile uint64_t *out_args = (volatile uint64_t*)args;
92	volatile uint32_t *in_args = (volatile uint32_t*)args;
93
94	out_args[1] = *(uint64_t*)&in_args[1];
95	out_args[0] = in_args[0];
96}
97
98void
99munge_wwl(const void *arg0 __unused, void *args)
100{
101	volatile uint64_t *out_args = (volatile uint64_t*)args;
102	volatile uint32_t *in_args = (volatile uint32_t*)args;
103
104	out_args[2] = *(uint64_t*)&in_args[2];
105	out_args[1] = in_args[1];
106	out_args[0] = in_args[0];
107}
108
109void
110munge_wwlw(const void *arg0 __unused, void *args)
111{
112	volatile uint64_t *out_args = (volatile uint64_t*)args;
113	volatile uint32_t *in_args = (volatile uint32_t*)args;
114
115	out_args[3] = in_args[4];
116	out_args[2] = *(uint64_t*)&in_args[2];
117	out_args[1] = in_args[1];
118	out_args[0] = in_args[0];
119}
120void
121munge_wwlll(const void *arg0 __unused, void *args)
122{
123	volatile uint64_t *out_args = (volatile uint64_t*)args;
124	volatile uint32_t *in_args = (volatile uint32_t*)args;
125
126	out_args[4] = *(uint64_t*)&in_args[6];
127	out_args[3] = *(uint64_t*)&in_args[4];
128	out_args[2] = *(uint64_t*)&in_args[2];
129	out_args[1] = in_args[1];
130	out_args[0] = in_args[0];
131}
132
133void
134munge_wwllww(const void *arg0 __unused, void *args)
135{
136	volatile uint64_t *out_args = (volatile uint64_t*)args;
137	volatile uint32_t *in_args = (volatile uint32_t*)args;
138
139	out_args[5] = in_args[7];
140	out_args[4] = in_args[6];
141	out_args[3] = *(uint64_t*)&in_args[4];
142	out_args[2] = *(uint64_t*)&in_args[2];
143	out_args[1] = in_args[1];
144	out_args[0] = in_args[0];
145}
146
147void
148munge_wlw(const void *arg0 __unused, void *args)
149{
150	volatile uint64_t *out_args = (volatile uint64_t*)args;
151	volatile uint32_t *in_args = (volatile uint32_t*)args;
152
153	out_args[2] = in_args[3];
154	out_args[1] = *(uint64_t*)&in_args[1];
155	out_args[0] = in_args[0];
156}
157
158void
159munge_wlwwwll(const void *arg0 __unused, void *args)
160{
161	volatile uint64_t *out_args = (volatile uint64_t*)args;
162	volatile uint32_t *in_args = (volatile uint32_t*)args;
163
164	out_args[6] = *(uint64_t*)&in_args[8];
165	out_args[5] = *(uint64_t*)&in_args[6];
166	out_args[4] = in_args[5];
167	out_args[3] = in_args[4];
168	out_args[2] = in_args[3];
169	out_args[1] = *(uint64_t*)&in_args[1];
170	out_args[0] = in_args[0];
171}
172
173void
174munge_wlwwwllw(const void *arg0 __unused, void *args)
175{
176	volatile uint64_t *out_args = (volatile uint64_t*)args;
177	volatile uint32_t *in_args = (volatile uint32_t*)args;
178
179	out_args[7] = in_args[10];
180	munge_wlwwwll(args, args);
181}
182
183void
184munge_wlwwlwlw(const void *arg0 __unused, void *args)
185{
186	volatile uint64_t *out_args = (volatile uint64_t*)args;
187	volatile uint32_t *in_args = (volatile uint32_t*)args;
188
189	out_args[7] = in_args[10];
190	out_args[6] = *(uint64_t*)&in_args[8];
191	out_args[5] = in_args[7];
192	out_args[4] = *(uint64_t*)&in_args[5];
193	out_args[3] = in_args[4];
194	out_args[2] = in_args[3];
195	out_args[1] = *(uint64_t*)&in_args[1];
196	out_args[0] = in_args[0];
197}
198
199void
200munge_wll(const void *arg0 __unused, void *args)
201{
202	volatile uint64_t *out_args = (volatile uint64_t*)args;
203	volatile uint32_t *in_args = (volatile uint32_t*)args;
204
205	out_args[2] = *(uint64_t*)&in_args[3];
206	out_args[1] = *(uint64_t*)&in_args[1];
207	out_args[0] = in_args[0];
208}
209
210void
211munge_wlll(const void *arg0 __unused, void *args)
212{
213	volatile uint64_t *out_args = (volatile uint64_t*)args;
214	volatile uint32_t *in_args = (volatile uint32_t*)args;
215
216	out_args[3] = *(uint64_t*)&in_args[5];
217	out_args[2] = *(uint64_t*)&in_args[3];
218	out_args[1] = *(uint64_t*)&in_args[1];
219	out_args[0] = in_args[0];
220}
221
222void
223munge_wllww(const void *arg0 __unused, void *args)
224{
225	volatile uint64_t *out_args = (volatile uint64_t*)args;
226	volatile uint32_t *in_args = (volatile uint32_t*)args;
227
228	out_args[4] = in_args[6];
229	out_args[3] = in_args[5];
230	out_args[2] = *(uint64_t*)&in_args[3];
231	out_args[1] = *(uint64_t*)&in_args[1];
232	out_args[0] = in_args[0];
233}
234
235void
236munge_wllwwll(const void *arg0 __unused, void *args)
237{
238	volatile uint64_t *out_args = (volatile uint64_t*)args;
239	volatile uint32_t *in_args = (volatile uint32_t*)args;
240
241	out_args[6] = *(uint64_t*)&in_args[9];
242	out_args[5] = *(uint64_t*)&in_args[7];
243	out_args[4] = in_args[6];
244	out_args[3] = in_args[5];
245	out_args[2] = *(uint64_t*)&in_args[3];
246	out_args[1] = *(uint64_t*)&in_args[1];
247	out_args[0] = in_args[0];
248}
249
250void
251munge_wwwlw(const void *arg0 __unused, void *args)
252{
253	volatile uint64_t *out_args = (volatile uint64_t*)args;
254	volatile uint32_t *in_args = (volatile uint32_t*)args;
255
256	out_args[4] = in_args[5];
257	out_args[3] = *(uint64_t*)&in_args[3];
258	out_args[2] = in_args[2];
259	out_args[1] = in_args[1];
260	out_args[0] = in_args[0];
261}
262
263void
264munge_wwwlww(const void *arg0 __unused, void *args)
265{
266	volatile uint64_t *out_args = (volatile uint64_t*)args;
267	volatile uint32_t *in_args = (volatile uint32_t*)args;
268
269	out_args[5] = in_args[6];
270	out_args[4] = in_args[5];
271	out_args[3] = *(uint64_t*)&in_args[3];
272	out_args[2] = in_args[2];
273	out_args[1] = in_args[1];
274	out_args[0] = in_args[0];
275}
276
277void
278munge_wwwl(const void *arg0 __unused, void *args)
279{
280	volatile uint64_t *out_args = (volatile uint64_t*)args;
281	volatile uint32_t *in_args = (volatile uint32_t*)args;
282
283	out_args[3] = *(uint64_t*)&in_args[3];
284	out_args[2] = in_args[2];
285	out_args[1] = in_args[1];
286	out_args[0] = in_args[0];
287}
288
289void
290munge_wwwwlw(const void *arg0 __unused, void *args)
291{
292	volatile uint64_t *out_args = (volatile uint64_t*)args;
293	volatile uint32_t *in_args = (volatile uint32_t*)args;
294
295	out_args[5] = in_args[6];
296	out_args[4] = *(uint64_t*)&in_args[4];
297	out_args[3] = in_args[3];
298	out_args[2] = in_args[2];
299	out_args[1] = in_args[1];
300	out_args[0] = in_args[0];
301}
302
303void
304munge_wwwwl(const void *arg0 __unused, void *args)
305{
306	volatile uint64_t *out_args = (volatile uint64_t*)args;
307	volatile uint32_t *in_args = (volatile uint32_t*)args;
308
309	out_args[4] = *(uint64_t*)&in_args[4];
310	out_args[3] = in_args[3];
311	out_args[2] = in_args[2];
312	out_args[1] = in_args[1];
313	out_args[0] = in_args[0];
314}
315
316void
317munge_wwwwwl(const void *arg0 __unused, void *args)
318{
319	volatile uint64_t *out_args = (volatile uint64_t*)args;
320	volatile uint32_t *in_args = (volatile uint32_t*)args;
321
322	out_args[5] = *(uint64_t*)&in_args[5];
323	out_args[4] = in_args[4];
324	out_args[3] = in_args[3];
325	out_args[2] = in_args[2];
326	out_args[1] = in_args[1];
327	out_args[0] = in_args[0];
328}
329
330void
331munge_wwwwwlww(const void *arg0 __unused, void *args)
332{
333	volatile uint64_t *out_args = (volatile uint64_t*)args;
334	volatile uint32_t *in_args = (volatile uint32_t*)args;
335
336	out_args[7] = in_args[8];
337	out_args[6] = in_args[7];
338	out_args[5] = *(uint64_t*)&in_args[5];
339	out_args[4] = in_args[4];
340	out_args[3] = in_args[3];
341	out_args[2] = in_args[2];
342	out_args[1] = in_args[1];
343	out_args[0] = in_args[0];
344}
345
346void
347munge_wwwwwllw(const void *arg0 __unused, void *args)
348{
349	volatile uint64_t *out_args = (volatile uint64_t*)args;
350	volatile uint32_t *in_args = (volatile uint32_t*)args;
351
352	out_args[7] = in_args[9];
353	out_args[6] = *(uint64_t*)&in_args[7];
354	out_args[5] = *(uint64_t*)&in_args[5];
355	out_args[4] = in_args[4];
356	out_args[3] = in_args[3];
357	out_args[2] = in_args[2];
358	out_args[1] = in_args[1];
359	out_args[0] = in_args[0];
360}
361
362void
363munge_wwwwwlll(const void *arg0 __unused, void *args)
364{
365	volatile uint64_t *out_args = (volatile uint64_t*)args;
366	volatile uint32_t *in_args = (volatile uint32_t*)args;
367
368	out_args[7] = *(uint64_t*)&in_args[9];
369	out_args[6] = *(uint64_t*)&in_args[7];
370	out_args[5] = *(uint64_t*)&in_args[5];
371	out_args[4] = in_args[4];
372	out_args[3] = in_args[3];
373	out_args[2] = in_args[2];
374	out_args[1] = in_args[1];
375	out_args[0] = in_args[0];
376}
377
378void
379munge_wwwwwwl(const void *arg0 __unused, void *args)
380{
381	volatile uint64_t *out_args = (volatile uint64_t*)args;
382	volatile uint32_t *in_args = (volatile uint32_t*)args;
383
384	out_args[6] = *(uint64_t*)&in_args[6];
385	out_args[5] = in_args[5];
386	out_args[4] = in_args[4];
387	out_args[3] = in_args[3];
388	out_args[2] = in_args[2];
389	out_args[1] = in_args[1];
390	out_args[0] = in_args[0];
391}
392
393void
394munge_wwwwwwlw(const void *arg0 __unused, void *args)
395{
396	volatile uint64_t *out_args = (volatile uint64_t*)args;
397	volatile uint32_t *in_args = (volatile uint32_t*)args;
398
399	out_args[7] = in_args[8];
400	out_args[6] = *(uint64_t*)&in_args[6];
401	out_args[5] = in_args[5];
402	out_args[4] = in_args[4];
403	out_args[3] = in_args[3];
404	out_args[2] = in_args[2];
405	out_args[1] = in_args[1];
406	out_args[0] = in_args[0];
407}
408
409void
410munge_wwwwwwll(const void *arg0 __unused, void *args)
411{
412	volatile uint64_t *out_args = (volatile uint64_t*)args;
413	volatile uint32_t *in_args = (volatile uint32_t*)args;
414
415	out_args[7] = *(uint64_t*)&in_args[8];
416	out_args[6] = *(uint64_t*)&in_args[6];
417	out_args[5] = in_args[5];
418	out_args[4] = in_args[4];
419	out_args[3] = in_args[3];
420	out_args[2] = in_args[2];
421	out_args[1] = in_args[1];
422	out_args[0] = in_args[0];
423}
424
425void
426munge_wsw(const void *arg0 __unused, void *args)
427{
428	volatile uint64_t *out_args = (volatile uint64_t*)args;
429	volatile uint32_t *in_args = (volatile uint32_t*)args;
430
431	out_args[2] = in_args[2];
432	out_args[1] = (int64_t)(int)in_args[1]; /* Sign-extend */
433	out_args[0] = in_args[0];
434}
435
436void
437munge_wws(const void *arg0 __unused, void *args)
438{
439	volatile uint64_t *out_args = (volatile uint64_t*)args;
440	volatile uint32_t *in_args = (volatile uint32_t*)args;
441
442	out_args[2] = (int64_t)(int)in_args[2]; /* Sign-extend */
443	out_args[1] = in_args[1];
444	out_args[0] = in_args[0];
445}
446
447void
448munge_wwwsw(const void *arg0 __unused, void *args)
449{
450	volatile uint64_t *out_args = (volatile uint64_t*)args;
451	volatile uint32_t *in_args = (volatile uint32_t*)args;
452
453	out_args[4] = in_args[4];
454	out_args[3] = (int64_t)(int)in_args[3]; /* Sign-extend */
455	out_args[2] = in_args[2];
456	out_args[1] = in_args[1];
457	out_args[0] = in_args[0];
458}
459
460void
461munge_llllll(const void *arg0 __unused, void *args __unused)
462{
463	/* Nothing to do, already all 64-bit */
464}
465
466void
467munge_ll(const void *arg0 __unused, void *args __unused)
468{
469	/* Nothing to do, already all 64-bit */
470}
471
472void
473munge_l(const void *arg0 __unused, void *args __unused)
474{
475	/* Nothing to do, already all 64-bit */
476}
477
478void
479munge_lw(const void *arg0 __unused, void *args)
480{
481	volatile uint64_t *out_args = (volatile uint64_t*)args;
482	volatile uint32_t *in_args = (volatile uint32_t*)args;
483
484	out_args[1] = in_args[2];
485	out_args[0] = *(uint64_t*)&in_args[0];
486}
487
488void
489munge_lwww(const void *arg0 __unused, void *args)
490{
491	volatile uint64_t *out_args = (volatile uint64_t*)args;
492	volatile uint32_t *in_args = (volatile uint32_t*)args;
493
494	out_args[3] = in_args[4];
495	out_args[2] = in_args[3];
496	out_args[1] = in_args[2];
497	out_args[0] = *(uint64_t*)&in_args[0];
498}
499
500void
501munge_wwlwww(const void *arg0 __unused, void *args)
502{
503	volatile uint64_t *out_args = (volatile uint64_t*)args;
504	volatile uint32_t *in_args = (volatile uint32_t*)args;
505
506	out_args[5] = in_args[6];
507	out_args[4] = in_args[5];
508	out_args[3] = in_args[4];
509	out_args[2] = *(uint64_t*)&in_args[2];
510	out_args[1] = in_args[1];
511	out_args[0] = in_args[0];
512}
513
514/*
515 * Munge array of 32-bit values into an array of 64-bit values,
516 * without sign extension.  Note, src and dest can be the same
517 * (copies from end of array)
518 */
519static inline __attribute__((always_inline)) void
520munge_32_to_64_unsigned(volatile uint64_t *dest, volatile uint32_t *src, int count)
521{
522	int i;
523
524	for (i = count - 1; i >= 0; i--) {
525		dest[i] = src[i];
526	}
527}
528
529