1 /*
2  * Copyright (C) 2009, Mukesh Rathor, Oracle Corp.  All rights reserved.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public
6  * License v2 as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public
14  * License along with this program; If not, see <http://www.gnu.org/licenses/>.
15  */
16 
17 #include <stdio.h>
18 #include <stdint.h>
19 #include <stdarg.h>
20 
21 #include "gx.h"
22 
23 
24 void
gxprt(const char * fmt,...)25 gxprt(const char *fmt, ...)
26 {
27     char buf[2048];
28     va_list args;
29 
30     va_start(args, fmt);
31     (void)vsnprintf(buf, sizeof(buf), fmt, args);
32     va_end(args);
33     fprintf(stderr, "%s", buf);
34     fflush(stderr);
35 }
36 
37 int
gx_fromhex(int a)38 gx_fromhex(int a)
39 {
40     if (a >= '0' && a <= '9')
41         return a - '0';
42     else if (a >= 'a' && a <= 'f')
43         return a - 'a' + 10;
44     else
45         gxprt("Reply contains invalid hex digit");
46     return 0;
47 }
48 
49 int
gx_tohex(int nib)50 gx_tohex(int nib)
51 {
52     if (nib < 10)
53         return '0' + nib;
54     else
55         return 'a' + nib - 10;
56 }
57 
58 
59 void
gx_convert_int_to_ascii(char * from,char * to,int n)60 gx_convert_int_to_ascii(char *from, char *to, int n)
61 {
62     int nib;
63     int ch;
64     while (n--) {
65         ch = *from++;
66         nib = ((ch & 0xf0) >> 4) & 0x0f;
67         *to++ = gx_tohex(nib);
68         nib = ch & 0x0f;
69         *to++ = gx_tohex(nib);
70     }
71     *to = 0;
72 }
73 
74 /* input: "70676433206431" output: "pgd3 d1" n == 7 */
75 void
gx_convert_ascii_to_int(char * from,char * to,int n)76 gx_convert_ascii_to_int(char *from, char *to, int n)
77 {
78     int nib1, nib2;
79     while (n--) {
80         nib1 = gx_fromhex(*from++);
81         nib2 = gx_fromhex(*from++);
82         *to++ = (((nib1 & 0x0f) << 4) & 0xf0) | (nib2 & 0x0f);
83     }
84     *to = 0;
85 }
86 
87 void
gx_decode_zZ_packet(char * from,uint64_t * mem_addr_ptr)88 gx_decode_zZ_packet(char *from, uint64_t *mem_addr_ptr)
89 {
90     int i = 0;
91     char ch;
92     *mem_addr_ptr = 0;
93 
94     while ((ch=from[i++]) != ',') {
95         *mem_addr_ptr = *mem_addr_ptr << 4;
96         *mem_addr_ptr |= gx_fromhex(ch) & 0x0f;
97     }
98 }
99 
100 /* Eg: mc0267d3a,1\0 : from points to char after 'm' */
101 void
gx_decode_m_packet(char * from,uint64_t * mem_addr_ptr,int * len_ptr)102 gx_decode_m_packet(char *from, uint64_t *mem_addr_ptr, int *len_ptr)
103 {
104     int i = 0, j = 0;
105     char ch;
106     *mem_addr_ptr = *len_ptr = 0;
107 
108     while ((ch=from[i++]) != ',') {
109         *mem_addr_ptr = *mem_addr_ptr << 4;
110         *mem_addr_ptr |= gx_fromhex(ch) & 0x0f;
111     }
112     for (j = 0; j < 4; j++) {
113         if ((ch=from[i++]) == 0)
114             break;
115         *len_ptr = *len_ptr << 4;
116         *len_ptr |= gx_fromhex(ch) & 0x0f;
117     }
118 }
119 
120 /*
121  * Decode M pkt as in: Mc0267d3a,1:cc\0 where c0267d3a is the guest addr
122  * from points to char after 'M'
123  * Returns: address of byte after ":", ie, addr of cc in buf
124  */
125 char *
gx_decode_M_packet(char * from,uint64_t * mem_addr_ptr,int * len_ptr)126 gx_decode_M_packet(char *from, uint64_t *mem_addr_ptr, int *len_ptr)
127 {
128     int i = 0;
129     char ch;
130 
131     *mem_addr_ptr = *len_ptr = 0;
132 
133     while ((ch=from[i++]) != ',') {
134         *mem_addr_ptr = *mem_addr_ptr << 4;
135         *mem_addr_ptr |= gx_fromhex(ch) & 0x0f;
136     }
137     while ((ch = from[i++]) != ':') {
138         *len_ptr = *len_ptr << 4;
139         *len_ptr |= gx_fromhex(ch) & 0x0f;
140     }
141     return(&from[i]);
142 }
143 
144