]>
git.saurik.com Git - apple/xnu.git/blob - osfmk/kdp/kdp_serial.c
2 * Copyright (c) 2008 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
28 #include "kdp_serial.h"
29 #include <libkern/zlib.h>
33 #define SKDP_START_CHAR 0xFA
34 #define SKDP_END_CHAR 0xFB
35 #define SKDP_ESC_CHAR 0xFE
37 static enum {DS_WAITSTART
, DS_READING
, DS_ESCAPED
} dsState
;
38 static unsigned char dsBuffer
[1518];
40 static uint32_t dsCRC
;
41 static bool dsHaveCRC
;
45 kdp_serial_out(unsigned char byte
, void (*outFunc
)(char))
47 //need to escape '\n' because the kernel serial output turns it into a cr/lf
48 if (byte
== SKDP_START_CHAR
|| byte
== SKDP_END_CHAR
|| byte
== SKDP_ESC_CHAR
|| byte
== '\n') {
49 outFunc(SKDP_ESC_CHAR
);
56 kdp_serialize_packet(unsigned char *packet
, unsigned int len
, void (*outFunc
)(char))
62 // insert the CRC between back to back STARTs which is compatible with old clients
63 crc
= (uint32_t) z_crc32(0, packet
, len
);
64 outFunc(SKDP_START_CHAR
);
65 kdp_serial_out((unsigned char)(crc
>> 0), outFunc
);
66 kdp_serial_out((unsigned char)(crc
>> 8), outFunc
);
67 kdp_serial_out((unsigned char)(crc
>> 16), outFunc
);
68 kdp_serial_out((unsigned char)(crc
>> 24), outFunc
);
70 outFunc(SKDP_START_CHAR
);
71 for (index
= 0; index
< len
; index
++) {
73 kdp_serial_out(byte
, outFunc
);
75 outFunc(SKDP_END_CHAR
);
79 kdp_unserialize_packet(unsigned char byte
, unsigned int *len
)
85 if (byte
== SKDP_START_CHAR
) {
86 // printf("got start char\n");
89 *len
= SERIALIZE_READING
;
93 *len
= SERIALIZE_WAIT_START
;
96 if (byte
== SKDP_ESC_CHAR
) {
98 *len
= SERIALIZE_READING
;
101 if (byte
== SKDP_START_CHAR
) {
104 dsCRC
= dsBuffer
[0] | (dsBuffer
[1] << 8) | (dsBuffer
[2] << 16) | (dsBuffer
[3] << 24);
106 //else printf("unexpected start char, resetting\n");
108 *len
= SERIALIZE_READING
;
111 if (byte
== SKDP_END_CHAR
) {
112 dsState
= DS_WAITSTART
;
114 crc
= (uint32_t) z_crc32(0, &dsBuffer
[0], dsPos
);
116 // printf("bad packet crc 0x%x != 0x%x\n", crc, dsCRC);
118 *len
= SERIALIZE_WAIT_START
;
126 dsBuffer
[dsPos
++] = byte
;
129 // printf("unescaping %02x to %02x\n", byte, ~byte);
130 dsBuffer
[dsPos
++] = ~byte
;
131 dsState
= DS_READING
;
132 *len
= SERIALIZE_READING
;
135 if (dsPos
== sizeof(dsBuffer
)) { //too much data...forget this packet
136 dsState
= DS_WAITSTART
;
138 *len
= SERIALIZE_WAIT_START
;