]> git.saurik.com Git - apple/boot.git/blob - i386/libsaio/ufs_byteorder.c
boot-111.tar.gz
[apple/boot.git] / i386 / libsaio / ufs_byteorder.c
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25 /*
26 * Copyright 1993 NeXT, Inc.
27 * All rights reserved.
28 */
29
30 #include <sys/types.h>
31 #include <sys/param.h>
32 #include <sys/vnode.h>
33 #include <ufs/ufs/dir.h>
34 #include <libkern/OSByteOrder.h>
35 #include "ufs_byteorder.h"
36 #include "libsaio.h"
37
38 #define swapBigLongToHost(thing) ((thing) = OSSwapBigToHostInt32(thing))
39 #define swapBigShortToHost(thing) ((thing) = OSSwapBigToHostInt16(thing))
40 #define byte_swap_longlong(thing) ((thing) = OSSwapBigToHostInt64(thing))
41 #define byte_swap_int(thing) ((thing) = OSSwapBigToHostInt32(thing))
42 #define byte_swap_short(thing) ((thing) = OSSwapBigToHostInt16(thing))
43
44 void
45 byte_swap_longlongs(unsigned long long *array, int count)
46 {
47 register unsigned long long i;
48
49 for (i = 0; i < (unsigned long long)count; i++)
50 byte_swap_longlong(array[i]);
51 }
52
53 void
54 byte_swap_ints(int *array, int count)
55 {
56 register int i;
57
58 for (i = 0; i < count; i++)
59 byte_swap_int(array[i]);
60 }
61
62 void
63 byte_swap_shorts(short *array, int count)
64 {
65 register int i;
66
67 for (i = 0; i < count; i++)
68 byte_swap_short(array[i]);
69 }
70
71 void
72 swapBigIntsToHost(int *array, int count)
73 {
74 register int i;
75
76 for (i = 0; i < count; i++)
77 swapBigLongToHost(array[i]);
78 }
79
80
81 void
82 swapBigShortToHosts(short *array, int count)
83 {
84 register int i;
85
86 for (i = 0; i < count; i++)
87 swapBigShortToHost(array[i]);
88 }
89
90 void
91 byte_swap_superblock(struct fs *sb)
92 {
93 u_int16_t * usptr;
94 unsigned long size;
95
96 byte_swap_ints(((int32_t *)&sb->fs_firstfield), 52);
97 byte_swap_int(sb->fs_cgrotor);
98 byte_swap_int(sb->fs_cpc);
99 byte_swap_shorts((int16_t *)sb->fs_opostbl, 16 * 8);
100 byte_swap_ints((int32_t *)sb->fs_sparecon, 50);
101 byte_swap_ints((int32_t *)&sb->fs_contigsumsize, 3);
102 byte_swap_longlongs((u_int64_t *)&sb->fs_maxfilesize,3);
103 byte_swap_ints((int32_t *)&sb->fs_state, 6);
104
105 /* Got these magic numbers from mkfs.c in newfs */
106 if (sb->fs_nrpos != 8 || sb->fs_cpc > 16) {
107 usptr = (u_int16_t *)((u_int8_t *)(sb) + (sb)->fs_postbloff);
108 size = sb->fs_cpc * sb->fs_nrpos;
109 byte_swap_shorts(usptr,size); /* fs_postbloff */
110 }
111 }
112
113 static inline void
114 byte_swap_disklabel_common(disk_label_t *dl)
115 {
116 swapBigLongToHost(dl->dl_version); /* ditto */
117 swapBigLongToHost(dl->dl_label_blkno);
118 swapBigLongToHost(dl->dl_size);
119 swapBigLongToHost(dl->dl_flags);
120 swapBigLongToHost(dl->dl_tag);
121 // swapBigShortToHost(dl->dl_checksum);
122 // if (dl->dl_version >= DL_V3)
123 // swapBigShortToHost(dl->dl_un.DL_v3_checksum);
124 // else
125 // swapBigIntsToHost(dl->dl_un.DL_bad, NBAD);
126 }
127
128 void
129 byte_swap_disklabel_in(disk_label_t *dl)
130 {
131 byte_swap_disklabel_common(dl);
132 byte_swap_disktab_in(&dl->dl_dt);
133 }
134
135 static inline void
136 byte_swap_disktab_common(struct disktab *dt)
137 {
138 register unsigned int i;
139
140 swapBigLongToHost(dt->d_secsize);
141 swapBigLongToHost(dt->d_ntracks);
142 swapBigLongToHost(dt->d_nsectors);
143 swapBigLongToHost(dt->d_ncylinders);
144 // swapBigLongToHost(dt->d_rpm);
145 swapBigShortToHost(dt->d_front);
146 swapBigShortToHost(dt->d_back);
147 // swapBigShortToHost(dt->d_ngroups);
148 // swapBigShortToHost(dt->d_ag_size);
149 // swapBigShortToHost(dt->d_ag_alts);
150 // swapBigShortToHost(dt->d_ag_off);
151 // swapBigIntsToHost(dt->d_boot0_blkno, NBOOTS);
152
153 for (i=0; i < NPART; i++)
154 byte_swap_partition(&dt->d_partitions[i]);
155 }
156
157 /*
158 * This is particularly grody. The beginning of the partition array is two
159 * bytes low on the 68 wrt natural alignment rules. Furthermore, each
160 * element of the partition table is two bytes smaller on 68k due to padding
161 * at the end of the struct.
162 */
163 void
164 byte_swap_disktab_in(struct disktab *dt)
165 {
166 struct partition * pp;
167 int i;
168
169 /*
170 * Shift each struct partition up in memory by 2 + 2 * offset bytes.
171 * Do it backwards so we don't overwrite anything.
172 */
173 for (i=NPART - 1; i >=0; i--) {
174 struct partition temp;
175 pp = &dt->d_partitions[i];
176 /* beware: compiler doesn't do overlapping struct assignment */
177 temp = *(struct partition *)(((char *) pp) - 2 * (i + 1));
178 *pp = temp;
179 }
180
181 byte_swap_disktab_common(dt);
182 }
183
184 void
185 byte_swap_partition(struct partition *part)
186 {
187 swapBigLongToHost(part->p_base);
188 swapBigLongToHost(part->p_size);
189 swapBigShortToHost(part->p_bsize);
190 swapBigShortToHost(part->p_fsize);
191 swapBigShortToHost(part->p_cpg);
192 swapBigShortToHost(part->p_density);
193 }
194
195 /* This value should correspond to the value set in the ffs_mounts */
196
197 #define RESYMLNKLEN 60
198
199 void
200 byte_swap_dinode_in(struct dinode *di)
201 {
202 int i;
203
204 di->di_mode = NXSwapShort(di->di_mode);
205 di->di_nlink = NXSwapShort(di->di_nlink);
206 #ifdef LFS
207 di->di_u.inumber = NXSwapLong(di->di_u.inumber);
208 #else
209 di->di_u.oldids[0] = NXSwapShort(di->di_u.oldids[0]);
210 di->di_u.oldids[1] = NXSwapShort(di->di_u.oldids[1]);
211 #endif
212 di->di_size = NXSwapLongLong(di->di_size);
213 di->di_atime = NXSwapLong(di->di_atime);
214 di->di_atimensec = NXSwapLong(di->di_atimensec);
215 di->di_mtime = NXSwapLong(di->di_mtime);
216 di->di_mtimensec = NXSwapLong(di->di_mtimensec);
217 di->di_ctime = NXSwapLong(di->di_ctime);
218 di->di_ctimensec = NXSwapLong(di->di_ctimensec);
219 if (((di->di_mode & IFMT) != IFLNK ) || (di->di_size > RESYMLNKLEN)) {
220 for (i=0; i < NDADDR; i++) /* direct blocks */
221 di->di_db[i] = NXSwapLong(di->di_db[i]);
222 for (i=0; i < NIADDR; i++) /* indirect blocks */
223 di->di_ib[i] = NXSwapLong(di->di_ib[i]);
224 }
225 di->di_flags = NXSwapLong(di->di_flags);
226 di->di_blocks = NXSwapLong(di->di_blocks);
227 di->di_gen = NXSwapLong(di->di_gen);
228 di->di_uid = NXSwapLong(di->di_uid);
229 di->di_gid = NXSwapLong(di->di_gid);
230 di->di_spare[0] = NXSwapLong(di->di_spare[0]);
231 di->di_spare[1] = NXSwapLong(di->di_spare[1]);
232 }
233
234 void
235 byte_swap_dir_block_in(char *addr, int count)
236 {
237 register struct direct * ep = (struct direct *) addr;
238 register int entryoffsetinblk = 0;
239
240 while (entryoffsetinblk < count) {
241 ep = (struct direct *) (entryoffsetinblk + addr);
242 swapBigLongToHost(ep->d_ino);
243 swapBigShortToHost(ep->d_reclen);
244 entryoffsetinblk += ep->d_reclen;
245 if (ep->d_reclen < 12) /* handle garbage in dirs */
246 break;
247 }
248 }