1//
2// convert.c - Little-endian conversion
3//
4// Written by Eryk Vershen
5//
6// See comments in convert.h
7//
8
9/*
10 * Copyright 1996,1997,1998 by Apple Computer, Inc.
11 *              All Rights Reserved
12 *
13 * Permission to use, copy, modify, and distribute this software and
14 * its documentation for any purpose and without fee is hereby granted,
15 * provided that the above copyright notice appears in all copies and
16 * that both the copyright notice and this permission notice appear in
17 * supporting documentation.
18 *
19 * APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
20 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 * FOR A PARTICULAR PURPOSE.
22 *
23 * IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
24 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
25 * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
26 * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
27 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
28 */
29
30#ifdef __linux__
31#include <endian.h>
32#elif __NetBSD__
33#include <machine/endian.h>
34#else
35#define LITTLE_ENDIAN 1234
36#define BIG_ENDIAN 4321
37#define BYTE_ORDER 4321
38//#define BYTE_ORDER 1234
39#endif
40
41#include "convert.h"
42
43
44//
45// Defines
46//
47
48
49//
50// Types
51//
52
53
54//
55// Global Constants
56//
57
58
59//
60// Global Variables
61//
62
63
64//
65// Forward declarations
66//
67void reverse2(u8 *bytes);
68void reverse4(u8 *bytes);
69
70
71//
72// Routines
73//
74int
75convert_dpme(DPME *data, int to_cpu_form)
76{
77#if BYTE_ORDER == LITTLE_ENDIAN
78    // Since we will toss the block if the signature doesn't match
79    // we don't need to check the signature down here.
80    reverse2((u8 *)&data->dpme_signature);
81    reverse2((u8 *)&data->dpme_reserved_1);
82    reverse4((u8 *)&data->dpme_map_entries);
83    reverse4((u8 *)&data->dpme_pblock_start);
84    reverse4((u8 *)&data->dpme_pblocks);
85    reverse4((u8 *)&data->dpme_lblock_start);
86    reverse4((u8 *)&data->dpme_lblocks);
87    reverse4((u8 *)&data->dpme_flags);
88    reverse4((u8 *)&data->dpme_boot_block);
89    reverse4((u8 *)&data->dpme_boot_bytes);
90    reverse4((u8 *)&data->dpme_load_addr);
91    reverse4((u8 *)&data->dpme_load_addr_2);
92    reverse4((u8 *)&data->dpme_goto_addr);
93    reverse4((u8 *)&data->dpme_goto_addr_2);
94    reverse4((u8 *)&data->dpme_checksum);
95    convert_bzb((BZB *)data->dpme_bzb, to_cpu_form);
96#endif
97    return 0;
98}
99
100
101#if BYTE_ORDER == LITTLE_ENDIAN
102int
103convert_bzb(BZB *data, int to_cpu_form)
104{
105    // Since the data here varies according to the type of partition we
106    // do not want to convert willy-nilly. We use the flag to determine
107    // whether to check for the signature before or after we flip the bytes.
108    if (to_cpu_form) {
109	reverse4((u8 *)&data->bzb_magic);
110	if (data->bzb_magic != BZBMAGIC) {
111	    reverse4((u8 *)&data->bzb_magic);
112	    if (data->bzb_magic != BZBMAGIC) {
113		return 0;
114	    }
115	}
116    } else {
117	if (data->bzb_magic != BZBMAGIC) {
118	    return 0;
119	}
120	reverse4((u8 *)&data->bzb_magic);
121    }
122    reverse2((u8 *)&data->bzb_inode);
123    reverse4((u8 *)&data->bzb_flags);
124    reverse4((u8 *)&data->bzb_tmade);
125    reverse4((u8 *)&data->bzb_tmount);
126    reverse4((u8 *)&data->bzb_tumount);
127    return 0;
128}
129#endif
130
131
132int
133convert_block0(Block0 *data, int to_cpu_form)
134{
135#if BYTE_ORDER == LITTLE_ENDIAN
136    DDMap *m;
137    u16 count;
138    int i;
139
140    // Since this data is optional we do not want to convert willy-nilly.
141    // We use the flag to determine whether to check for the signature
142    // before or after we flip the bytes and to determine which form of
143    // the count to use.
144    if (to_cpu_form) {
145	reverse2((u8 *)&data->sbSig);
146	if (data->sbSig != BLOCK0_SIGNATURE) {
147	    reverse2((u8 *)&data->sbSig);
148	    if (data->sbSig != BLOCK0_SIGNATURE) {
149		return 0;
150	    }
151	}
152    } else {
153	if (data->sbSig != BLOCK0_SIGNATURE) {
154	    return 0;
155	}
156	reverse2((u8 *)&data->sbSig);
157    }
158    reverse2((u8 *)&data->sbBlkSize);
159    reverse4((u8 *)&data->sbBlkCount);
160    reverse2((u8 *)&data->sbDevType);
161    reverse2((u8 *)&data->sbDevId);
162    reverse4((u8 *)&data->sbData);
163    if (to_cpu_form) {
164	reverse2((u8 *)&data->sbDrvrCount);
165	count = data->sbDrvrCount;
166    } else {
167	count = data->sbDrvrCount;
168	reverse2((u8 *)&data->sbDrvrCount);
169    }
170
171    if (count > 0) {
172	m = (DDMap *) data->sbMap;
173	for (i = 0; i < count; i++) {
174	    reverse4((u8 *)&m[i].ddBlock);
175	    reverse2((u8 *)&m[i].ddSize);
176	    reverse2((u8 *)&m[i].ddType);
177	}
178    }
179#endif
180    return 0;
181}
182
183
184void
185reverse2(u8 *bytes)
186{
187    u8 t;
188
189    t = *bytes;
190    *bytes = bytes[1];
191    bytes[1] = t;
192}
193
194
195void
196reverse4(u8 *bytes)
197{
198    u8 t;
199
200    t = *bytes;
201    *bytes = bytes[3];
202    bytes[3] = t;
203    t = bytes[1];
204    bytes[1] = bytes[2];
205    bytes[2] = t;
206}
207