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#else
33#ifdef __unix__
34#include <machine/endian.h>
35#else
36#define LITTLE_ENDIAN 1234
37#define BIG_ENDIAN 4321
38#define BYTE_ORDER 4321
39//#define BYTE_ORDER 1234
40#endif
41#endif
42
43#include "convert.h"
44
45
46//
47// Defines
48//
49
50
51//
52// Types
53//
54
55
56//
57// Global Constants
58//
59
60
61//
62// Global Variables
63//
64
65
66//
67// Forward declarations
68//
69void reverse2(u8 *bytes);
70void reverse4(u8 *bytes);
71
72
73//
74// Routines
75//
76int
77convert_dpme(DPME *data, int to_cpu_form)
78{
79#if BYTE_ORDER == LITTLE_ENDIAN
80    // Since we will toss the block if the signature doesn't match
81    // we don't need to check the signature down here.
82    reverse2((u8 *)&data->dpme_signature);
83    reverse2((u8 *)&data->dpme_reserved_1);
84    reverse4((u8 *)&data->dpme_map_entries);
85    reverse4((u8 *)&data->dpme_pblock_start);
86    reverse4((u8 *)&data->dpme_pblocks);
87    reverse4((u8 *)&data->dpme_lblock_start);
88    reverse4((u8 *)&data->dpme_lblocks);
89    reverse4((u8 *)&data->dpme_flags);
90    reverse4((u8 *)&data->dpme_boot_block);
91    reverse4((u8 *)&data->dpme_boot_bytes);
92    reverse4((u8 *)&data->dpme_load_addr);
93    reverse4((u8 *)&data->dpme_load_addr_2);
94    reverse4((u8 *)&data->dpme_goto_addr);
95    reverse4((u8 *)&data->dpme_goto_addr_2);
96    reverse4((u8 *)&data->dpme_checksum);
97    convert_bzb((BZB *)data->dpme_bzb, to_cpu_form);
98#endif
99    return 0;
100}
101
102
103#if BYTE_ORDER == LITTLE_ENDIAN
104int
105convert_bzb(BZB *data, int to_cpu_form)
106{
107    // Since the data here varies according to the type of partition we
108    // do not want to convert willy-nilly. We use the flag to determine
109    // whether to check for the signature before or after we flip the bytes.
110    if (to_cpu_form) {
111	reverse4((u8 *)&data->bzb_magic);
112	if (data->bzb_magic != BZBMAGIC) {
113	    reverse4((u8 *)&data->bzb_magic);
114	    if (data->bzb_magic != BZBMAGIC) {
115		return 0;
116	    }
117	}
118    } else {
119	if (data->bzb_magic != BZBMAGIC) {
120	    return 0;
121	}
122	reverse4((u8 *)&data->bzb_magic);
123    }
124    reverse2((u8 *)&data->bzb_inode);
125    reverse4((u8 *)&data->bzb_flags);
126    reverse4((u8 *)&data->bzb_tmade);
127    reverse4((u8 *)&data->bzb_tmount);
128    reverse4((u8 *)&data->bzb_tumount);
129    return 0;
130}
131#endif
132
133
134int
135convert_block0(Block0 *data, int to_cpu_form)
136{
137#if BYTE_ORDER == LITTLE_ENDIAN
138    DDMap *m;
139    u16 count;
140    int i;
141
142    // Since this data is optional we do not want to convert willy-nilly.
143    // We use the flag to determine whether to check for the signature
144    // before or after we flip the bytes and to determine which form of
145    // the count to use.
146    if (to_cpu_form) {
147	reverse2((u8 *)&data->sbSig);
148	if (data->sbSig != BLOCK0_SIGNATURE) {
149	    reverse2((u8 *)&data->sbSig);
150	    if (data->sbSig != BLOCK0_SIGNATURE) {
151		return 0;
152	    }
153	}
154    } else {
155	if (data->sbSig != BLOCK0_SIGNATURE) {
156	    return 0;
157	}
158	reverse2((u8 *)&data->sbSig);
159    }
160    reverse2((u8 *)&data->sbBlkSize);
161    reverse4((u8 *)&data->sbBlkCount);
162    reverse2((u8 *)&data->sbDevType);
163    reverse2((u8 *)&data->sbDevId);
164    reverse4((u8 *)&data->sbData);
165    if (to_cpu_form) {
166	reverse2((u8 *)&data->sbDrvrCount);
167	count = data->sbDrvrCount;
168    } else {
169	count = data->sbDrvrCount;
170	reverse2((u8 *)&data->sbDrvrCount);
171    }
172
173    if (count > 0) {
174	m = (DDMap *) data->sbMap;
175	for (i = 0; i < count; i++) {
176	    reverse4((u8 *)&m[i].ddBlock);
177	    reverse2((u8 *)&m[i].ddSize);
178	    reverse2((u8 *)&m[i].ddType);
179	}
180    }
181#endif
182    return 0;
183}
184
185
186void
187reverse2(u8 *bytes)
188{
189    u8 t;
190
191    t = *bytes;
192    *bytes = bytes[1];
193    bytes[1] = t;
194}
195
196
197void
198reverse4(u8 *bytes)
199{
200    u8 t;
201
202    t = *bytes;
203    *bytes = bytes[3];
204    bytes[3] = t;
205    t = bytes[1];
206    bytes[1] = bytes[2];
207    bytes[2] = t;
208}
209