* Semihosting output on ARM7TDMI
@ 2001-08-14 4:51 Joel Brenner
2001-08-14 7:56 ` Grant Edwards
0 siblings, 1 reply; 8+ messages in thread
From: Joel Brenner @ 2001-08-14 4:51 UTC (permalink / raw)
To: gdb
Hi I'm using JEENI debug module wich supports semihosting (libc) on a
ARM7TDMI target. I'make use of function printf() from newlib wich seems
to work.
I've tried to execute "printf("abc\n\n");" and I've logged the ADP
communication:
....
R=0001000d H->T CI_HADP: ADP_Execute 00000000
rx: [T=0 L=24] 01 d1 d1 01 0d 00 01 80 00 00 00 00 ff ff ff ff ff ff ff
ff 00 00 00 00
R=8001000d H<-T CI_HADP: ADP_Execute 00000000
rx: [T=0 L=36] 05 d2 d1 01 69 00 00 80 00 00 00 00 ff ff ff ff ff ff ff
ff 00 00 00 00 04 00 00 00 04 00 00 00 61 62 63 0a
R=80000069 H<-T CI_CLIB: CL_Write 00000000 00000004 00000004 0a636261
tx: [T=0 L=28] 05 d2 d2 01 69 00 00 00 00 00 00 00 ff ff ff ff ff ff ff
ff 01 00 00 00 04 00 00 00
R=00000069 H->T CI_CLIB: CL_Write 00000001 00000004
rx: [T=0 L=33] 05 d3 d2 01 69 00 00 80 00 00 00 00 ff ff ff ff ff ff ff
ff 00 00 00 00 01 00 00 00 01 00 00 00 0a
R=80000069 H<-T CI_CLIB: CL_Write 00000000 00000001 00000001 0000000a
tx: [T=0 L=28] 05 d3 d3 01 69 00 00 00 00 00 00 00 ff ff ff ff ff ff ff
ff 01 00 00 00 01 00 00 00
R=00000069 H->T CI_CLIB: CL_Write 00000001 00000001
rx: [T=0 L=28] 02 d4 d3 01 01 00 02 80 00 00 00 00 ff ff ff ff ff ff ff
ff 20 00 02 00 00 00 00 00
R=80020001 H<-T CI_TADP: ADP_Stopped 00020020 00000000
...
but no message are printed to gdb console. Are the above messages
correct?
Whath is the command to enable semihosting? Where GDB puts the receved
strings ?
tanks Brenner Joel
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Semihosting output on ARM7TDMI
2001-08-14 4:51 Semihosting output on ARM7TDMI Joel Brenner
@ 2001-08-14 7:56 ` Grant Edwards
2001-08-14 8:33 ` Andrew Cagney
0 siblings, 1 reply; 8+ messages in thread
From: Grant Edwards @ 2001-08-14 7:56 UTC (permalink / raw)
To: Joel Brenner; +Cc: gdb
On Tue, Aug 14, 2001 at 02:49:01PM +0200, Joel Brenner wrote:
> Hi I'm using JEENI debug module wich supports semihosting (libc) on a
> ARM7TDMI target. I'make use of function printf() from newlib wich seems
> to work.
> I've tried to execute "printf("abc\n\n");" and I've logged the ADP
> communication:
> ....
> R=0001000d H->T CI_HADP: ADP_Execute 00000000
> rx: [T=0 L=24] 01 d1 d1 01 0d 00 01 80 00 00 00 00 ff ff ff ff ff ff ff
> ff 00 00 00 00
> R=8001000d H<-T CI_HADP: ADP_Execute 00000000
> rx: [T=0 L=36] 05 d2 d1 01 69 00 00 80 00 00 00 00 ff ff ff ff ff ff ff
> ff 00 00 00 00 04 00 00 00 04 00 00 00 61 62 63 0a
> R=80000069 H<-T CI_CLIB: CL_Write 00000000 00000004 00000004 0a636261
> tx: [T=0 L=28] 05 d2 d2 01 69 00 00 00 00 00 00 00 ff ff ff ff ff ff ff
> ff 01 00 00 00 04 00 00 00
> R=00000069 H->T CI_CLIB: CL_Write 00000001 00000004
> rx: [T=0 L=33] 05 d3 d2 01 69 00 00 80 00 00 00 00 ff ff ff ff ff ff ff
> ff 00 00 00 00 01 00 00 00 01 00 00 00 0a
> R=80000069 H<-T CI_CLIB: CL_Write 00000000 00000001 00000001 0000000a
> tx: [T=0 L=28] 05 d3 d3 01 69 00 00 00 00 00 00 00 ff ff ff ff ff ff ff
> ff 01 00 00 00 01 00 00 00
> R=00000069 H->T CI_CLIB: CL_Write 00000001 00000001
> rx: [T=0 L=28] 02 d4 d3 01 01 00 02 80 00 00 00 00 ff ff ff ff ff ff ff
> ff 20 00 02 00 00 00 00 00
> R=80020001 H<-T CI_TADP: ADP_Stopped 00020020 00000000
How handy!
> but no message are printed to gdb console. Are the above
> messages correct? Whath is the command to enable semihosting?
> Where GDB puts the receved strings ?
IIRC, The RDI interface code writes semihosting output data to
whatever filedescriptor is requested. I think your request are
for fd 0. The CL_Write data is fd,len,len,data. I've no clue
why the length is there twice.
There is an internal file table that translates from "RDI" fd
number to Unix FILE pointers. The table is initialized to be
empty, and then filled in when the semi-hosting client opens
files.
It looks like it needs to be changed so that it is
pre-initialized so that stdin, stdout, and stderr are
"pre-opened". I think you'll need to change the code in
rdi-share/hsys.c HostSysInit() so that fds 0,1,2, are
initialized to map to FILE pointers stdin, stdout, stderr.
If you enable debugging info in hsys.c (by adding "#define
DEBUG" at the top of the file) you might be able to get a
better idea about what's going on.
--
Grant Edwards
grante@visi.com
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Semihosting output on ARM7TDMI
2001-08-14 7:56 ` Grant Edwards
@ 2001-08-14 8:33 ` Andrew Cagney
2001-08-14 8:46 ` Grant Edwards
0 siblings, 1 reply; 8+ messages in thread
From: Andrew Cagney @ 2001-08-14 8:33 UTC (permalink / raw)
To: Grant Edwards; +Cc: Joel Brenner, gdb
> It looks like it needs to be changed so that it is
> pre-initialized so that stdin, stdout, and stderr are
> "pre-opened". I think you'll need to change the code in
> rdi-share/hsys.c HostSysInit() so that fds 0,1,2, are
> initialized to map to FILE pointers stdin, stdout, stderr.
Almost. The theory is right.
For output the ``struct ui_file'' objects gdb_std*, normally target
output is sent to gdb_stdtarg (one day I'll remember to rename it to
gdb_targout).
For input, things get messy, if you look at remote.c and fixme's from me
there are hopefully enough hints on how it can be done, in theory. It
is made complicated by the fact that there is an event look wanting a
look-in.
Andrew
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Semihosting output on ARM7TDMI
2001-08-14 8:33 ` Andrew Cagney
@ 2001-08-14 8:46 ` Grant Edwards
2001-08-14 9:11 ` Andrew Cagney
0 siblings, 1 reply; 8+ messages in thread
From: Grant Edwards @ 2001-08-14 8:46 UTC (permalink / raw)
To: Andrew Cagney; +Cc: Joel Brenner, gdb
On Tue, Aug 14, 2001 at 11:33:02AM -0400, Andrew Cagney wrote:
> > It looks like it needs to be changed so that it is
> > pre-initialized so that stdin, stdout, and stderr are
> > "pre-opened". I think you'll need to change the code in
> > rdi-share/hsys.c HostSysInit() so that fds 0,1,2, are
> > initialized to map to FILE pointers stdin, stdout, stderr.
>
> Almost. The theory is right.
>
> For output the ``struct ui_file'' objects gdb_std*, normally target
> output is sent to gdb_stdtarg (one day I'll remember to rename it to
> gdb_targout).
Er, wha?
The routines in rdi-remote/hsys.c have no idea that gdb is "up
there" somewhere.
The RDI file table is in a structure defined like so:
typedef struct {
FILE *FileTable[HSYS_FOPEN_MAX] ;
char FileFlags[HSYS_FOPEN_MAX] ;
char *TempNames[UNIQUETEMPS];
} OSblock;
The initialization (rdi-remote/hsys.c) looks like this
77 /* Set up the state block, filetable and register the C lib callback fn */
78 int HostSysInit(const struct Dbg_HostosInterface *hostif, char **cmdline,
79 hsys_state **stateptr)
80 {
81 ChannelCallback HandleMessageFPtr = (ChannelCallback) HandleSysMessage;
82 int i;
83 *stateptr = (hsys_state *)malloc(sizeof(hsys_state));
84
85 if (*stateptr == NULL) return RDIError_OutOfStore;
86
87 (*stateptr)->hostif=hostif;
88 (*stateptr)->last_errno=0;
89 (*stateptr)->OSptr=(OSblock *)malloc(sizeof(OSblock));
90 if ((*stateptr)->OSptr == NULL) return RDIError_OutOfStore;
91 for (i=0; i<UNIQUETEMPS; i++) (*stateptr)->OSptr->TempNames[i]=NULL;
92 for (i=0; i<HSYS_FOPEN_MAX; i++) {
93 (*stateptr)->OSptr->FileTable[i]=NULL;
94 (*stateptr)->OSptr->FileFlags[i]=0;
95 }
96 (*stateptr)->CommandLine=cmdline;
97
98 return Adp_ChannelRegisterRead(CI_CLIB, (ChannelCallback)HandleMessageFPtr,
99 *stateptr);
100 }
I think that it might work if the lines below were added
somewhere after the second for() loop:
(*stateptr)->OSptr->FileTable[0] = stdin;
(*stateptr)->OSptr->FileTable[1] = stdout;
(*stateptr)->OSptr->FileTable[2] = stderr;
I don't think that FileFlags[n] needs to be initialized to
anything other than zero, but I'm not sure about that.
It would be possible to make these routines "gdb aware" but
they aren't at the moment -- semi-hosting requests are handled
below the gdb<->RDI interface.
> For input, things get messy, if you look at remote.c and fixme's from me
> there are hopefully enough hints on how it can be done, in theory. It
> is made complicated by the fact that there is an event look wanting a
> look-in.
I think you're looking at the wrong target. ;)
--
Grant Edwards
grante@visi.com
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Semihosting output on ARM7TDMI
2001-08-14 8:46 ` Grant Edwards
@ 2001-08-14 9:11 ` Andrew Cagney
2001-08-14 9:24 ` Grant Edwards
0 siblings, 1 reply; 8+ messages in thread
From: Andrew Cagney @ 2001-08-14 9:11 UTC (permalink / raw)
To: Grant Edwards; +Cc: Joel Brenner, gdb
> On Tue, Aug 14, 2001 at 11:33:02AM -0400, Andrew Cagney wrote:
>
>> > It looks like it needs to be changed so that it is
>> > pre-initialized so that stdin, stdout, and stderr are
>> > "pre-opened". I think you'll need to change the code in
>> > rdi-share/hsys.c HostSysInit() so that fds 0,1,2, are
>> > initialized to map to FILE pointers stdin, stdout, stderr.
>
>>
>> Almost. The theory is right.
>>
>> For output the ``struct ui_file'' objects gdb_std*, normally target
>> output is sent to gdb_stdtarg (one day I'll remember to rename it to
>> gdb_targout).
>
>
> Er, wha?
>
> The routines in rdi-remote/hsys.c have no idea that gdb is "up
> there" somewhere.
>
> The RDI file table is in a structure defined like so:
>
> typedef struct {
> FILE *FileTable[HSYS_FOPEN_MAX] ;
> char FileFlags[HSYS_FOPEN_MAX] ;
> char *TempNames[UNIQUETEMPS];
> } OSblock;
If you don't route the output from the target through gdb_stdtarg then
people, using GUI's, will complain that their output disappears or turns
up in the wrong place. gdb_stdtarg captures all output and then passes
it through to things like the console.
How you manage to get the output routed to gdb_stdtarg, er, isn't my
problem :-)
> It would be possible to make these routines "gdb aware" but
> they aren't at the moment -- semi-hosting requests are handled
> below the gdb<->RDI interface.
It isn't so much GDB aware not assume that the world is a UNIX tty.
>> For input, things get messy, if you look at remote.c and fixme's from me
>> there are hopefully enough hints on how it can be done, in theory. It
>> is made complicated by the fact that there is an event look wanting a
>> look-in.
>
>
> I think you're looking at the wrong target. [;)]
The theory is the same. remote.c contains a working example of
correctly wired output. It also contains a nasty hack, from
Cygnus/Cisco, to both co-ordinate target output and GDB input.
How much of that you need for tty UNIX I don't know. I do know that and
a lot more are needed to get GDB handling this correctly in a GUI
environment.
Andrew
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Semihosting output on ARM7TDMI
2001-08-14 9:11 ` Andrew Cagney
@ 2001-08-14 9:24 ` Grant Edwards
2001-08-14 9:31 ` Keith Seitz
0 siblings, 1 reply; 8+ messages in thread
From: Grant Edwards @ 2001-08-14 9:24 UTC (permalink / raw)
To: Andrew Cagney; +Cc: Joel Brenner, gdb
On Tue, Aug 14, 2001 at 12:11:17PM -0400, Andrew Cagney wrote:
> > The routines in rdi-remote/hsys.c have no idea that gdb is "up
> > there" somewhere.
> >
> > The RDI file table is in a structure defined like so:
> >
> > typedef struct {
> > FILE *FileTable[HSYS_FOPEN_MAX] ;
> > char FileFlags[HSYS_FOPEN_MAX] ;
> > char *TempNames[UNIQUETEMPS];
> > } OSblock;
>
> If you don't route the output from the target through
> gdb_stdtarg then people, using GUI's, will complain that their
> output disappears or turns up in the wrong place. gdb_stdtarg
> captures all output and then passes it through to things like
> the console.
I understand.
But, the RDI stuff isn't aware of gdb, and it would take some
work to make it aware. It would be "a good thing" but somebody
would have to want it bad enough to actuallly do it.
> How you manage to get the output routed to gdb_stdtarg, er,
> isn't my problem :-)
Nor mine, since I don't use semi-hosting. ;)
> > It would be possible to make these routines "gdb aware" but
> > they aren't at the moment -- semi-hosting requests are handled
> > below the gdb<->RDI interface.
>
> It isn't so much GDB aware not assume that the world is a UNIX
> tty.
Right now, the RDI host-end stuff assumes the world is a Unix
filesystem and that you have to open any files before you
access them. The client-end stuff appears to assume that fd 0
is pre-opened. My three-line hack will (maybe) make accesses to
fd 0, 1, 2 translate into accesses to stdin, stdout, and
stderr.
Whether the user wants to access stdin/stdout/stderr verses the
the gdb console is another question.
> The theory is the same. remote.c contains a working example of
> correctly wired output. It also contains a nasty hack, from
> Cygnus/Cisco, to both co-ordinate target output and GDB input.
>
> How much of that you need for tty UNIX I don't know. I do know
> that and a lot more are needed to get GDB handling this
> correctly in a GUI environment.
It would be nice if the RDI code were made gdb-aware, but I'm
aware of no plans to do it.
--
Grant Edwards
grante@visi.com
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Semihosting output on ARM7TDMI
2001-08-14 9:24 ` Grant Edwards
@ 2001-08-14 9:31 ` Keith Seitz
2001-08-14 11:43 ` Grant Edwards
0 siblings, 1 reply; 8+ messages in thread
From: Keith Seitz @ 2001-08-14 9:31 UTC (permalink / raw)
To: Grant Edwards; +Cc: Andrew Cagney, gdb
On Tue, 14 Aug 2001, Grant Edwards wrote:
> But, the RDI stuff isn't aware of gdb, and it would take some
> work to make it aware. It would be "a good thing" but somebody
> would have to want it bad enough to actuallly do it.
Isn't there already some machinery in place to do target I/O? You can
certainly do printf and the like on an arm board using rdi and gdb.
What do the the members writec, readc, write, gets in struct
Dbg_HostosInterface mean? Specifically:
/* Open a connection to a remote debugger. NAME is the filename used
for communication. */
static void
arm_rdi_open (char *name, int from_tty)
{
/* snip */
rslt = Adp_OpenDevice (devName, openArgs, rdi_heartbeat);
if (rslt != adp_ok)
error ("Could not open device \"%s\"", name);
gdb_config.bytesex = 2 | (TARGET_BYTE_ORDER == BIG_ENDIAN ? 1 : 0);
gdb_config.fpe = 1;
gdb_config.rditype = 2;
gdb_config.heartbeat_on = 1;
gdb_config.flags = 2;
gdb_hostif.dbgprint = myprint;
gdb_hostif.dbgpause = mypause;
gdb_hostif.dbgarg = NULL;
gdb_hostif.writec = mywritec;
gdb_hostif.readc = myreadc;
gdb_hostif.write = mywrite;
gdb_hostif.gets = mygets;
gdb_hostif.hostosarg = NULL;
gdb_hostif.reset = voiddummy;
rslt = angel_RDI_open (10, &gdb_config, &gdb_hostif, NULL);
/* snip */
Doesn't any of this deal with "semi-hosting"?
Keith
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Semihosting output on ARM7TDMI
2001-08-14 9:31 ` Keith Seitz
@ 2001-08-14 11:43 ` Grant Edwards
0 siblings, 0 replies; 8+ messages in thread
From: Grant Edwards @ 2001-08-14 11:43 UTC (permalink / raw)
To: Keith Seitz; +Cc: Andrew Cagney, gdb
On Tue, Aug 14, 2001 at 09:31:26AM -0700, Keith Seitz wrote:
> On Tue, 14 Aug 2001, Grant Edwards wrote:
>
> > But, the RDI stuff isn't aware of gdb, and it would take some
> > work to make it aware. It would be "a good thing" but somebody
> > would have to want it bad enough to actuallly do it.
>
> Isn't there already some machinery in place to do target I/O? You can
> certainly do printf and the like on an arm board using rdi and gdb.
I wasn't aware that that stuff worked. What I've seen in the
past is that the semi-hosting routines generates the "CL_Write"
messages, and the handler for that flushes the data.
> What do the the members writec, readc, write, gets in struct
> Dbg_HostosInterface mean? Specifically:
It appears that they're the routines that are supposed to get
called for semi-hosting console I/O.
> gdb_hostif.dbgprint = myprint;
> gdb_hostif.dbgpause = mypause;
> gdb_hostif.dbgarg = NULL;
> gdb_hostif.writec = mywritec;
> gdb_hostif.readc = myreadc;
> gdb_hostif.write = mywrite;
> gdb_hostif.gets = mygets;
> gdb_hostif.hostosarg = NULL;
> gdb_hostif.reset = voiddummy;
>>
> Doesn't any of this deal with "semi-hosting"?
It's supposed to, but I don't think it all works. From what
I've seen, the semi-hosting client stuff generates writes to fd
0, and since that fd has never been opened, the data is
discarded in hsys.c by HandleSysMessage:
490 case CL_Write:
491 {
492 /* Write(word handle, word nbtotal, word nbytes, bytes data)
493 * return(word nbytes)
494 * WriteX(word nbytes, bytes data)
495 * return(word nbytes)
496 */
497 unsigned char *rwdata = NULL, *rwhead = NULL;
498 unsigned char *write_source = NULL;
499 char flags;
500 FILE *fhreal;
501 unsigned int ack_reason = CL_Write; /* first ack is for CL_Write */
502
503 err = -1; /* err == 0 is fwrite() error indication */
504 unpack_message(buffp, "%w%w%w", &fh, &nbtotal, &nbytes);
505 DebugPrintF(("CL_Write: fh %d nbtotal %u nbytes %u\n",
506 fh, nbtotal, nbytes));
507
** 508 fhreal = hsysGetRealFileHandle(stateptr, fh, &flags);
509 nbtogo = nbtotal;
510
511 /* deal with the file handle */
** 512 if (fhreal == NULL)
** 513 err = 0;
514 else {
515 if (flags & READOP)
516 fseek(fhreal,0,SEEK_CUR);
517 stateptr->OSptr->FileFlags[fh] = (flags & BINARY) | WRITEOP;
line 508 returns a NULL, since no file has been opened, and the
data is flushed.
[It looks like CL_WriteC and CL_ReadC do what they should:
calling hostif->writec and hostif->readc, but I've never seen
anybody post ADP traces that showed those being used.]
Aha! I just noticed something that I missed before...
It also looks like somebody _did_ create a special case when an
fd maps to stdout or stderr by calling hostif->write() instead
of calling fwrite() on the file handle directly. The RDI stuff
is more aware than I thought. It isn't aware specifically of
gdb, but the remote-rdi.c adapts the RDI API well enough that I
think semi-hosting can be made to work right.
535 do {
536 /* at least once!! */
537
538 if (nbtogo == 0 && err != 0) {
539 /* Do the actual write! */
** 540 if (fhreal == stdout || fhreal == stderr) {
** 541 stateptr->hostif->write(stateptr->hostif->hostosarg,
542 (char *)write_source, nbtotal);
543 }
544 else
** 545 err = fwrite(write_source, 1, nbtotal, fhreal);
546 stateptr->last_errno = errno;
547 DebugCheckErr("fwrite", TRUE, (err == 0), stateptr->last_errno);
548 }
549
I think that if you initialize fd #0 to be stdout, then the
hostif->write() routine will get called, and that in turn calls
fputc_unfiltered(c,gdb_stdout). I don't know why the
semi-hosting client routines are writing to fd 0 (which I would
assume to be stdin) rather than 1 (stdout) or 2 (stderr).
So one could try changing my three-line kludge to initialize
the first fd to stdout instead of stdin.
The handling for CL_Read is different and doesn't check for
stdin, stdout, stderr. Instead, if the fd maps to a file handle
that's a tty, then hostif->gets() is called which then does an
fgets() on stdin. Otherwise fread() is called on the file
handle.
--
Grant Edwards
grante@visi.com
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2001-08-14 11:43 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-08-14 4:51 Semihosting output on ARM7TDMI Joel Brenner
2001-08-14 7:56 ` Grant Edwards
2001-08-14 8:33 ` Andrew Cagney
2001-08-14 8:46 ` Grant Edwards
2001-08-14 9:11 ` Andrew Cagney
2001-08-14 9:24 ` Grant Edwards
2001-08-14 9:31 ` Keith Seitz
2001-08-14 11:43 ` Grant Edwards
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox