1*e93f7393Sniklas /* MIPS-dependent portions of the RPC protocol
2*e93f7393Sniklas    used with a VxWorks target
3*e93f7393Sniklas 
4*e93f7393Sniklas Contributed by Wind River Systems.
5*e93f7393Sniklas 
6*e93f7393Sniklas This file is part of GDB.
7*e93f7393Sniklas 
8*e93f7393Sniklas This program is free software; you can redistribute it and/or modify
9*e93f7393Sniklas it under the terms of the GNU General Public License as published by
10*e93f7393Sniklas the Free Software Foundation; either version 2 of the License, or
11*e93f7393Sniklas (at your option) any later version.
12*e93f7393Sniklas 
13*e93f7393Sniklas This program is distributed in the hope that it will be useful,
14*e93f7393Sniklas but WITHOUT ANY WARRANTY; without even the implied warranty of
15*e93f7393Sniklas MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16*e93f7393Sniklas GNU General Public License for more details.
17*e93f7393Sniklas 
18*e93f7393Sniklas You should have received a copy of the GNU General Public License
19*e93f7393Sniklas along with this program; if not, write to the Free Software
20*e93f7393Sniklas Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
21*e93f7393Sniklas 
22*e93f7393Sniklas #include <stdio.h>
23*e93f7393Sniklas #include "defs.h"
24*e93f7393Sniklas 
25*e93f7393Sniklas #include "vx-share/regPacket.h"
26*e93f7393Sniklas #include "frame.h"
27*e93f7393Sniklas #include "inferior.h"
28*e93f7393Sniklas #include "wait.h"
29*e93f7393Sniklas #include "target.h"
30*e93f7393Sniklas #include "gdbcore.h"
31*e93f7393Sniklas #include "command.h"
32*e93f7393Sniklas #include "symtab.h"
33*e93f7393Sniklas #include "symfile.h"		/* for struct complaint */
34*e93f7393Sniklas 
35*e93f7393Sniklas #include "gdb_string.h"
36*e93f7393Sniklas #include <errno.h>
37*e93f7393Sniklas #include <signal.h>
38*e93f7393Sniklas #include <fcntl.h>
39*e93f7393Sniklas #include <sys/types.h>
40*e93f7393Sniklas #include <sys/time.h>
41*e93f7393Sniklas #include <sys/socket.h>
42*e93f7393Sniklas #include <rpc/rpc.h>
43*e93f7393Sniklas #include <sys/time.h>		/* UTek's <rpc/rpc.h> doesn't #incl this */
44*e93f7393Sniklas #include <netdb.h>
45*e93f7393Sniklas #include "vx-share/ptrace.h"
46*e93f7393Sniklas #include "vx-share/xdr_ptrace.h"
47*e93f7393Sniklas #include "vx-share/xdr_ld.h"
48*e93f7393Sniklas #include "vx-share/xdr_rdb.h"
49*e93f7393Sniklas #include "vx-share/dbgRpcLib.h"
50*e93f7393Sniklas 
51*e93f7393Sniklas /* get rid of value.h if possible */
52*e93f7393Sniklas #include <value.h>
53*e93f7393Sniklas #include <symtab.h>
54*e93f7393Sniklas 
55*e93f7393Sniklas /* Flag set if target has fpu */
56*e93f7393Sniklas 
57*e93f7393Sniklas extern int target_has_fp;
58*e93f7393Sniklas 
59*e93f7393Sniklas /* Generic register read/write routines in remote-vx.c.  */
60*e93f7393Sniklas 
61*e93f7393Sniklas extern void net_read_registers ();
62*e93f7393Sniklas extern void net_write_registers ();
63*e93f7393Sniklas 
64*e93f7393Sniklas /* Read a register or registers from the VxWorks target.
65*e93f7393Sniklas    REGNO is the register to read, or -1 for all; currently,
66*e93f7393Sniklas    it is ignored.  FIXME look at regno to improve efficiency.  */
67*e93f7393Sniklas 
68*e93f7393Sniklas void
69*e93f7393Sniklas vx_read_register (regno)
70*e93f7393Sniklas      int regno;
71*e93f7393Sniklas {
72*e93f7393Sniklas   char mips_greg_packet[MIPS_GREG_PLEN];
73*e93f7393Sniklas   char mips_fpreg_packet[MIPS_FPREG_PLEN];
74*e93f7393Sniklas 
75*e93f7393Sniklas   /* Get general-purpose registers.  */
76*e93f7393Sniklas 
77*e93f7393Sniklas   net_read_registers (mips_greg_packet, MIPS_GREG_PLEN, PTRACE_GETREGS);
78*e93f7393Sniklas 
79*e93f7393Sniklas   /* this code copies the registers obtained by RPC
80*e93f7393Sniklas      stored in a structure(s) like this :
81*e93f7393Sniklas 
82*e93f7393Sniklas     	Register(s)		Offset(s)
83*e93f7393Sniklas    	gp 0-31			0x00
84*e93f7393Sniklas    	hi			0x80
85*e93f7393Sniklas    	lo			0x84
86*e93f7393Sniklas    	sr			0x88
87*e93f7393Sniklas    	pc			0x8c
88*e93f7393Sniklas 
89*e93f7393Sniklas      into a stucture like this:
90*e93f7393Sniklas 
91*e93f7393Sniklas    	0x00	GP 0-31
92*e93f7393Sniklas    	0x80   	SR
93*e93f7393Sniklas    	0x84	LO
94*e93f7393Sniklas    	0x88	HI
95*e93f7393Sniklas    	0x8C	BAD    		--- Not available currently
96*e93f7393Sniklas    	0x90	CAUSE    	--- Not available currently
97*e93f7393Sniklas    	0x94	PC
98*e93f7393Sniklas    	0x98	FP 0-31
99*e93f7393Sniklas    	0x118	FCSR
100*e93f7393Sniklas    	0x11C	FIR    		--- Not available currently
101*e93f7393Sniklas    	0x120	FP	    	--- Not available currently
102*e93f7393Sniklas 
103*e93f7393Sniklas      structure is 0x124 (292) bytes in length */
104*e93f7393Sniklas 
105*e93f7393Sniklas   /* Copy the general registers.  */
106*e93f7393Sniklas 
107*e93f7393Sniklas   bcopy (&mips_greg_packet[MIPS_R_GP0], &registers[0], 32 * MIPS_GREG_SIZE);
108*e93f7393Sniklas 
109*e93f7393Sniklas   /* Copy SR, LO, HI, and PC.  */
110*e93f7393Sniklas 
111*e93f7393Sniklas   bcopy (&mips_greg_packet[MIPS_R_SR],
112*e93f7393Sniklas          &registers[REGISTER_BYTE (PS_REGNUM)], MIPS_GREG_SIZE);
113*e93f7393Sniklas   bcopy (&mips_greg_packet[MIPS_R_LO],
114*e93f7393Sniklas          &registers[REGISTER_BYTE (LO_REGNUM)], MIPS_GREG_SIZE);
115*e93f7393Sniklas   bcopy (&mips_greg_packet[MIPS_R_HI],
116*e93f7393Sniklas          &registers[REGISTER_BYTE (HI_REGNUM)], MIPS_GREG_SIZE);
117*e93f7393Sniklas   bcopy (&mips_greg_packet[MIPS_R_PC],
118*e93f7393Sniklas          &registers[REGISTER_BYTE (PC_REGNUM)], MIPS_GREG_SIZE);
119*e93f7393Sniklas 
120*e93f7393Sniklas   /* If the target has floating point registers, fetch them.
121*e93f7393Sniklas      Otherwise, zero the floating point register values in
122*e93f7393Sniklas      registers[] for good measure, even though we might not
123*e93f7393Sniklas      need to.  */
124*e93f7393Sniklas 
125*e93f7393Sniklas   if (target_has_fp)
126*e93f7393Sniklas     {
127*e93f7393Sniklas       net_read_registers (mips_fpreg_packet, MIPS_FPREG_PLEN,
128*e93f7393Sniklas 			  PTRACE_GETFPREGS);
129*e93f7393Sniklas 
130*e93f7393Sniklas       /* Copy the floating point registers.  */
131*e93f7393Sniklas 
132*e93f7393Sniklas       bcopy (&mips_fpreg_packet[MIPS_R_FP0],
133*e93f7393Sniklas 	     &registers[REGISTER_BYTE (FP0_REGNUM)],
134*e93f7393Sniklas 	     REGISTER_RAW_SIZE (FP0_REGNUM) * 32);
135*e93f7393Sniklas 
136*e93f7393Sniklas       /* Copy the floating point control/status register (fpcsr).  */
137*e93f7393Sniklas 
138*e93f7393Sniklas       bcopy (&mips_fpreg_packet[MIPS_R_FPCSR],
139*e93f7393Sniklas 	     &registers[REGISTER_BYTE (FCRCS_REGNUM)],
140*e93f7393Sniklas 	     REGISTER_RAW_SIZE (FCRCS_REGNUM));
141*e93f7393Sniklas     }
142*e93f7393Sniklas   else
143*e93f7393Sniklas     {
144*e93f7393Sniklas       bzero ((char *) &registers[REGISTER_BYTE (FP0_REGNUM)],
145*e93f7393Sniklas 	     REGISTER_RAW_SIZE (FP0_REGNUM) * 32);
146*e93f7393Sniklas       bzero ((char *) &registers[REGISTER_BYTE (FCRCS_REGNUM)],
147*e93f7393Sniklas 	     REGISTER_RAW_SIZE (FCRCS_REGNUM));
148*e93f7393Sniklas     }
149*e93f7393Sniklas 
150*e93f7393Sniklas   /* Mark the register cache valid.  */
151*e93f7393Sniklas 
152*e93f7393Sniklas   registers_fetched ();
153*e93f7393Sniklas }
154*e93f7393Sniklas 
155*e93f7393Sniklas /* Store a register or registers into the VxWorks target.
156*e93f7393Sniklas    REGNO is the register to store, or -1 for all; currently,
157*e93f7393Sniklas    it is ignored.  FIXME look at regno to improve efficiency.  */
158*e93f7393Sniklas 
159*e93f7393Sniklas vx_write_register (regno)
160*e93f7393Sniklas      int regno;
161*e93f7393Sniklas {
162*e93f7393Sniklas   char mips_greg_packet[MIPS_GREG_PLEN];
163*e93f7393Sniklas   char mips_fpreg_packet[MIPS_FPREG_PLEN];
164*e93f7393Sniklas 
165*e93f7393Sniklas   /* Store general registers.  */
166*e93f7393Sniklas 
167*e93f7393Sniklas   bcopy (&registers[0], &mips_greg_packet[MIPS_R_GP0], 32 * MIPS_GREG_SIZE);
168*e93f7393Sniklas 
169*e93f7393Sniklas   /* Copy SR, LO, HI, and PC.  */
170*e93f7393Sniklas 
171*e93f7393Sniklas   bcopy (&registers[REGISTER_BYTE (PS_REGNUM)],
172*e93f7393Sniklas          &mips_greg_packet[MIPS_R_SR], MIPS_GREG_SIZE);
173*e93f7393Sniklas   bcopy (&registers[REGISTER_BYTE (LO_REGNUM)],
174*e93f7393Sniklas          &mips_greg_packet[MIPS_R_LO], MIPS_GREG_SIZE);
175*e93f7393Sniklas   bcopy (&registers[REGISTER_BYTE (HI_REGNUM)],
176*e93f7393Sniklas          &mips_greg_packet[MIPS_R_HI], MIPS_GREG_SIZE);
177*e93f7393Sniklas   bcopy (&registers[REGISTER_BYTE (PC_REGNUM)],
178*e93f7393Sniklas          &mips_greg_packet[MIPS_R_PC], MIPS_GREG_SIZE);
179*e93f7393Sniklas 
180*e93f7393Sniklas   net_write_registers (mips_greg_packet, MIPS_GREG_PLEN, PTRACE_SETREGS);
181*e93f7393Sniklas 
182*e93f7393Sniklas   /* Store floating point registers if the target has them.  */
183*e93f7393Sniklas 
184*e93f7393Sniklas   if (target_has_fp)
185*e93f7393Sniklas     {
186*e93f7393Sniklas       /* Copy the floating point data registers.  */
187*e93f7393Sniklas 
188*e93f7393Sniklas       bcopy (&registers[REGISTER_BYTE (FP0_REGNUM)],
189*e93f7393Sniklas 	     &mips_fpreg_packet[MIPS_R_FP0],
190*e93f7393Sniklas 	     REGISTER_RAW_SIZE (FP0_REGNUM) * 32);
191*e93f7393Sniklas 
192*e93f7393Sniklas       /* Copy the floating point control/status register (fpcsr).  */
193*e93f7393Sniklas 
194*e93f7393Sniklas       bcopy (&registers[REGISTER_BYTE (FCRCS_REGNUM)],
195*e93f7393Sniklas 	     &mips_fpreg_packet[MIPS_R_FPCSR],
196*e93f7393Sniklas 	     REGISTER_RAW_SIZE (FCRCS_REGNUM));
197*e93f7393Sniklas 
198*e93f7393Sniklas       net_write_registers (mips_fpreg_packet, MIPS_FPREG_PLEN,
199*e93f7393Sniklas 			   PTRACE_SETFPREGS);
200*e93f7393Sniklas     }
201*e93f7393Sniklas }
202