OK, the good news is we're not crazy. The TypedBufferArg thing is working just fine.

The bad news is that Alpha Linux is kind of crazy. Even though both the user-visible pipe() call and the kernel internal do_pipe() call take a pointer to an array of ints, the low-level user/kernel syscall interface treats pipe as a special case and returns the two fds in $r0 (aka $v0) and $r20 (aka $a4). I guess somebody thought it wasn't worth messing with a buffer pointer just for two ints.

So what the user syscall stub does is take the return values from the kernel from those registers and write them into the array that the program passed in... in the process clobbering the values that your function had written there with the tbuf.copyOut(). It's the two stl instructions in the code below:

(gdb) disas pipe
Dump of assembler code for function pipe:
0x0000000120008950 <pipe+0>:    ldah    gp,9(t12)
0x0000000120008954 <pipe+4>:    lda     gp,18992(gp)
0x0000000120008958 <pipe+8>:    lda     v0,42
0x000000012000895c <pipe+12>:   callsys
0x0000000120008960 <pipe+16>:   bne     a3,0x120008974 <pipe+36>
0x0000000120008964 <pipe+20>:   stl     v0,0(a0)
0x0000000120008968 <pipe+24>:   stl     a4,4(a0)
0x000000012000896c <pipe+28>:   clr     v0
0x0000000120008970 <pipe+32>:   ret
0x0000000120008974 <pipe+36>:   unop
0x0000000120008978 <pipe+40>:   br      0x12000c4a8 <__syscall_error+8>
0x000000012000897c <pipe+44>:   unop
End of assembler dump.

You can see the kernel side of this here:

http://lxr.linux.no/source/arch/alpha/kernel/entry.S#L898

I got it to work as follows:

/// Target pipe() handler.  Even though this is a generic Posix call,
/// the Alpha return convention is funky, so that makes it
/// Alpha-specific.
SyscallReturn
pipeFunc(SyscallDesc *desc, int callnum, Process *process,
         ExecContext *xc)
{
    int fds[2], sim_fds[2];
    int pipe_retval = pipe(fds);

    if (pipe_retval < 0) {
        // error
        return pipe_retval;
    }

    sim_fds[0] = process->open_fd(fds[0]);
    sim_fds[1] = process->open_fd(fds[1]);

    // Alpha Linux convention for pipe() is that fd[0] is returned as
    // the return value of the function, and fd[1] is returned in r20.
    xc->regs.intRegFile[20] = sim_fds[1];
    return sim_fds[0];
}

(I actually tested this in our head, and not in the release tree, so if you have minor problems that could be the reason. I don't think there should be a problem though.)

Steve


Jeff wrote:
Yeah, i'm pretty sure the values are correct, i even created another 
TypedBufferArg right after i do the copyOut and do a copyIn at the same address 
to verify that the values are correct.
It's really strange, because in my test code, i am immediately printing the 
values of the file descriptors returned from this emulated system call, which i 
even verified with the second TypedBufferArg.

the values i see are 0 and -1, and i also set the file pointers in my test code 
to something else before the pipe call, so i know that the values are being 
changed.  but not correctly.



-----Original Message-----
From: Steve Reinhardt <[EMAIL PROTECTED]>
Sent: Feb 22, 2006 10:41 PM
To: Jeff <[EMAIL PROTECTED]>
Cc: m5 <[email protected]>
Subject: Re: [m5sim-users] implementing syscall, memory consistency


It's not obvious to me... looks like it should work. Did you verify that the memory at tbuf.bufPtr has the right values before the copyOut? There may be something subtle in the way operator[] is overloaded on TypedBufferArg.

Jeff wrote:
Hi,

I'm trying to implement the pipe system call in ALPHA_SE mode, by just calling 
pipe natively and writing the file descriptors into the array passed in by 
address.

this is the code snippet showing how i'm doing it.  for some reason, the values 
in memory aren't being updated correctly and the pipe-caller sees the wrong 
values in the file descriptor array.  is there something obvious that i'm 
missing here?

thanks, i really appreciate help with this... i've been stuck on it for the 
past couple days and am getting nowhere.

/// Target pipe() function.
template <class OS>
SyscallReturn
pipeFunc(SyscallDesc *desc, int callnum, Process *process,
         ExecContext *xc)
{
  TypedBufferArg<int> tbuf(xc->getSyscallArg(0), 8);

  int fds[2];
  int pipe_retval = pipe(fds);

  tbuf[0] = process->open_fd(fds[0]);
  tbuf[1] = process->open_fd(fds[1]);

  tbuf.copyOut(xc->mem);

  return pipe_retval;
}




-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems?  Stop!  Download the new AJAX search engine that makes
searching your log files as easy as surfing the  web.  DOWNLOAD SPLUNK!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=103432&bid=230486&dat=121642
_______________________________________________
m5sim-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/m5sim-users


-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
_______________________________________________
m5sim-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/m5sim-users

Reply via email to