]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/rdi-share/tx.c
* config/sh/tm-sh.h (BELIEVE_PCC_PROMOTION): Define, so that
[thirdparty/binutils-gdb.git] / gdb / rdi-share / tx.c
1 /*
2 * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
3 *
4 * This software may be freely used, copied, modified, and distributed
5 * provided that the above copyright notice is preserved in all copies of the
6 * software.
7 */
8
9 /*-*-C-*-
10 *
11 * $Revision$
12 * $Date$
13 *
14 * Project: ANGEL
15 *
16 * Title: Character based packet transmission engine
17 */
18
19 #include <stdarg.h> /* ANSI varargs support */
20 #include "angel.h" /* Angel system definitions */
21 #include "endian.h" /* Endian independant memory access macros */
22 #include "crc.h" /* crc generation definitions and headers */
23 #include "rxtx.h"
24 #include "channels.h"
25 #include "buffers.h"
26 #include "logging.h"
27
28 /* definitions to describe the engines state */
29 #define N_STX 0x0 /* first 2 bits for N_ */
30 #define N_BODY 0x1
31 #define N_ETX 0x2
32 #define N_IDLE 0x3
33 #define N_MASK 0x3 /* mask for the Encapsulator state */
34
35 #define E_PLAIN (0x0 << 2) /* 3rd bit for E_ */
36 #define E_ESC (0x1 << 2) /* 3rd bit for E_ */
37 #define E_MASK (0x1 << 2) /* mask for the Escaper state */
38
39 #define F_HEAD (0x0 << 3) /* 4th and 5th bits for F_ */
40 #define F_DATA (0x1 << 3)
41 #define F_CRC (0x1 << 4)
42 #define F_MASK (0x3 << 3) /* mask for the Escaper state */
43
44 static unsigned char escape(unsigned char ch_in, struct te_state *txstate);
45
46 void Angel_TxEngineInit(const struct re_config *txconfig,
47 const struct data_packet *packet,
48 struct te_state *txstate){
49 IGNORE(packet);
50 txstate->tx_state = N_STX | E_PLAIN | F_HEAD;
51 txstate->field_c = 0;
52 txstate->encoded = 0;
53 txstate->config = txconfig;
54 txstate->crc = 0;
55 }
56
57 te_status Angel_TxEngine(const struct data_packet *packet,
58 struct te_state *txstate,
59 unsigned char *tx_ch){
60 /* TODO: gaurd on long/bad packets */
61 /*
62 * encapsulate the packet, framing has been moved from a seperate
63 * function into the encapsulation routine as it needed too much
64 * inherited state for it to be sensibly located elsewhere
65 */
66 switch ((txstate->tx_state) & N_MASK){
67 case N_STX:
68 #ifdef DO_TRACE
69 __rt_trace("txe-stx ");
70 #endif
71 txstate->tx_state = (txstate->tx_state & ~N_MASK) | N_BODY;
72 *tx_ch = txstate->config->stx;
73 txstate->field_c = 3; /* set up for the header */
74 txstate->crc = startCRC32; /* set up basic crc */
75 return TS_IN_PKT;
76 case N_BODY:{
77 switch (txstate->tx_state & F_MASK) {
78 case F_HEAD:
79 #ifdef DO_TRACE
80 __rt_trace("txe-head ");
81 #endif
82 if (txstate->field_c == 3) {
83 /* send type */
84 *tx_ch = escape(packet->type, txstate);
85 return TS_IN_PKT;
86 }
87 else {
88 *tx_ch = escape((packet->len >> (txstate->field_c - 1) * 8) & 0xff,
89 txstate);
90 if (txstate->field_c == 0) {
91 /* move on to the next state */
92 txstate->tx_state = (txstate->tx_state & ~F_MASK) | F_DATA;
93 txstate->field_c = packet->len;
94 }
95 return TS_IN_PKT;
96 }
97 case F_DATA:
98 #ifdef DO_TRACE
99 __rt_trace("txe-data ");
100 #endif
101 *tx_ch = escape(packet->data[packet->len - txstate->field_c], txstate);
102 if (txstate->field_c == 0) {
103 /* move on to the next state */
104 txstate->tx_state = (txstate->tx_state & ~F_MASK) | F_CRC;
105 txstate->field_c = 4;
106 }
107 return TS_IN_PKT;
108 case F_CRC:
109 #ifdef DO_TRACE
110 __rt_trace("txe-crc ");
111 #endif
112 *tx_ch = escape((txstate->crc >> ((txstate->field_c - 1) * 8)) & 0xff,
113 txstate);
114
115 if (txstate->field_c == 0) {
116 #ifdef DO_TRACE
117 __rt_trace("txe crc = 0x%x\n", txstate->crc);
118 #endif
119 /* move on to the next state */
120 txstate->tx_state = (txstate->tx_state & ~N_MASK) | N_ETX;
121 }
122 return TS_IN_PKT;
123 }
124 }
125 case N_ETX:
126 #ifdef DO_TRACE
127 __rt_trace("txe-etx\n");
128 #endif
129 txstate->tx_state = (txstate->tx_state & ~N_MASK) | N_IDLE;
130 *tx_ch = txstate->config->etx;
131 return TS_DONE_PKT;
132 default:
133 #ifdef DEBUG
134 __rt_info("tx default\n");
135 #endif
136 txstate->tx_state = (txstate->tx_state & ~N_MASK) | N_IDLE;
137 return TS_IDLE;
138 }
139 /* stop a silly -Wall warning */
140 return (te_status)-1;
141 }
142
143 /*
144 * crc generation occurs in the escape function because it is the only
145 * place where we know that we're putting a real char into the buffer
146 * rather than an escaped one.
147 * We must be careful here not to update the crc when we're sending it
148 */
149 static unsigned char escape(unsigned char ch_in, struct te_state *txstate) {
150 if (((txstate->tx_state) & E_MASK) == E_ESC) {
151 /* char has been escaped so send the real char */
152 #ifdef DO_TRACE
153 __rt_trace("txe-echar ");
154 #endif
155 txstate->tx_state = (txstate->tx_state & ~E_MASK) | E_PLAIN;
156 txstate->field_c--;
157 if ((txstate->tx_state & F_MASK) != F_CRC)
158 txstate->crc = crc32( &ch_in, 1, txstate->crc);
159 return ch_in | serial_ESCAPE;
160 }
161 if ((ch_in < 32) && ((txstate->config->esc_set & (1 << ch_in)) != 0)) {
162 /* char needs escaping */
163 #ifdef DO_TRACE
164 __rt_trace("txe-esc ");
165 #endif
166 txstate->tx_state = (txstate->tx_state & ~E_MASK) | E_ESC;
167 return txstate->config->esc;
168 }
169 /* must be a char that can be sent plain */
170 txstate->field_c--;
171 if ((txstate->tx_state & F_MASK) != F_CRC)
172 txstate->crc = crc32(&ch_in, 1, txstate->crc);
173 return ch_in;
174 }
175
176 /* EOF tx.c */