1/*
2 * Copyright (c) 1998-2002 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License").  You may not use this file except in compliance with the
9 * License.  Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22/*
23 * Copyright (c) 1999-2002 Apple Computer, Inc.  All rights reserved.
24 *
25 * HISTORY
26 * 3 June 99 wgulland created.
27 *
28 * Useful stuff called from several different FireWire objects.
29 */
30
31// public
32#import <IOKit/firewire/IOFireWireFamilyCommon.h>
33#import <IOKit/firewire/IOFWUtils.h>
34
35// system
36#import <IOKit/assert.h>
37#import <IOKit/IOLib.h>
38
39////////////////////////////////////////////////////////////////////////////////
40//
41// FWUpdateCRC16
42//
43//   This proc updates a crc with the next quad.
44//
45
46UInt16 FWUpdateCRC16(UInt16 crc16, UInt32 quad)
47{
48	UInt32 host_quad = OSSwapBigToHostInt32( quad );
49    SInt32 shift;
50    UInt32 sum;
51    UInt32 crc = crc16;
52    for (shift = 28; shift >= 0; shift -= 4) {
53        sum = ((crc >> 12) ^ (host_quad >> shift)) & 0x0F;
54        crc = (crc << 4) ^ (sum << 12) ^ (sum << 5) ^ (sum);
55    }
56    return (crc & 0xFFFF);
57}
58////////////////////////////////////////////////////////////////////////////////
59//
60// FWComputeCRC16
61//
62//   This proc computes a CRC 16 check.
63//
64
65UInt16	FWComputeCRC16(const UInt32 *pQuads, UInt32 numQuads)
66{
67    SInt32	shift;
68    UInt32	sum;
69    UInt32	crc16;
70    UInt32	quadNum;
71    UInt32	quad;
72
73    // Compute CRC 16 over all quads.
74    crc16 = 0;
75    for (quadNum = 0; quadNum < numQuads; quadNum++) {
76        quad = OSSwapBigToHostInt32(*pQuads++);
77        for (shift = 28; shift >= 0; shift -= 4) {
78            sum = ((crc16 >> 12) ^ (quad >> shift)) & 0x0F;
79            crc16 = (crc16 << 4) ^ (sum << 12) ^ (sum << 5) ^ (sum);
80        }
81    }
82
83    return (crc16 & 0xFFFF);
84}
85
86UInt32  AddFWCycleTimeToFWCycleTime( UInt32 cycleTime1, UInt32 cycleTime2 )
87{
88    UInt32    secondCount,
89              cycleCount,
90              cycleOffset;
91    UInt32    cycleTime;
92
93    // Add cycle offsets.
94    cycleOffset = (cycleTime1 & 0x0FFF) + (cycleTime2 & 0x0FFF);
95
96    // Add cycle counts.
97    cycleCount = (cycleTime1 & 0x01FFF000) + (cycleTime2 & 0x01FFF000);
98
99    // Add any carry over from cycle offset to cycle count.
100    if (cycleOffset > 3071)
101    {
102        cycleCount += 0x1000;
103        cycleOffset -= 3072;
104    }
105
106    // Add secondCounts.
107    secondCount = (cycleTime1 & 0xFE000000) + (cycleTime2 & 0xFE000000);
108
109    // Add any carry over from cycle count to secondCount.
110    if (cycleCount > (7999 << 12))
111    {
112        secondCount += 0x02000000;
113        cycleCount -= (8000 << 12);
114    }
115
116    // Put everything together into cycle time.
117    cycleTime = secondCount | cycleCount | cycleOffset;
118
119    return (cycleTime);
120}
121
122UInt32 SubtractFWCycleTimeFromFWCycleTime( UInt32 cycleTime1, UInt32 cycleTime2)
123{
124    SInt32 secondCount,
125           cycleCount,
126           cycleOffset;
127    UInt32 cycleTime;
128
129    // Subtract cycle offsets.
130    cycleOffset = (cycleTime1 & 0x0FFF) - (cycleTime2 & 0x0FFF);
131
132    // Subtract cycle counts.
133    cycleCount = (cycleTime1 & 0x01FFF000) - (cycleTime2 & 0x01FFF000);
134
135    // Subtract any borrow over from cycle offset to cycle count.
136
137    if (cycleOffset < 0)
138    {
139        cycleCount -= 0x1000;
140        cycleOffset += 3072;
141    }
142
143    // Subtract secondCounts.
144    secondCount = (cycleTime1 & 0xFE000000) - (cycleTime2 & 0xFE000000);
145
146    // Subtract any borrow over from cycle count to secondCount.
147    if (cycleCount < 0)
148    {
149        secondCount -= 0x02000000;
150        cycleCount += (8000 << 12);
151    }
152
153    // Put everything together into cycle time.
154    cycleTime = secondCount | cycleCount | cycleOffset;
155
156    return (cycleTime);
157}
158
159// findOffsetInRanges:
160// takes a pointer and a list of ranges, and finds the offset of the pointer into
161// the range array
162bool
163findOffsetInRanges ( mach_vm_address_t address, unsigned rangeCount, IOAddressRange ranges[], IOByteCount & outOffset )
164{
165	UInt32			index			= 0 ;
166	IOByteCount		distanceInRange ;
167	bool			found			= false ;
168
169	outOffset = 0 ;
170	while ( ! found && index < rangeCount )
171	{
172		distanceInRange = address - ranges[index].address ;
173		if ( found = ( distanceInRange < ranges[ index ].length ) )
174			outOffset += distanceInRange ;
175		else
176			outOffset += ranges[ index ].length ;
177
178		++index ;
179	}
180
181	return found ;
182}
183
184void
185IOFWGetAbsoluteTime( AbsoluteTime * result )
186{
187	*((uint64_t*)result) = mach_absolute_time();
188}
189