OSDN Git Service

* linux-low.c (linux_create_inferior): Call setpgid. Return
[pf3gnuchains/pf3gnuchains3x.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 */