Shop OBEX P1 Docs P2 Docs Learn Events
Documentation clarification request — Parallax Forums

Documentation clarification request

pedwardpedward Posts: 1,642
edited 2012-05-04 07:00 in Propeller 1
I was reading the docs on the supported memory models (https://sites.google.com/site/propellergcc/propgcc-compiler/memory-models) and it isn't entirely clear what the restrictions of each memory model are.

Specifically, I know from regular Prop programming that COG mode is straight PASM, but some clarifications I would like to know:

Specifically, which PASM instructions are restricted in LMM mode?

How about a table of "what you use in COG mode" => "what you would use in LMM mode".

Furthermore, is PASM off limit in XMM mode?

If it's not off limits, what restrictions are there beyond LMM?

How about a table like the one above, illustrating how you would implement each restricted instruction.

As you move into XMM, what are some good rules to follow when writing PASM to play nice with XMM?

Pthreads will only run on COG N and not N*M in XMM mode, so what is the suggested alternative to get code running on additional cogs?

Does each COG have to run the XMM kernel to make that work?

Is it implied in XMM mode that only COG mode code can be run on other COGs?

I saw a smattering somewhere which suggested what C routines should be used in place of the traditional cognew to launch code so it plays nice with the C runtime, but it doesn't seem easy to find.

I see cognew/init are implemented, but to what end are they useful?

I assume only COG code is of any use with cognew/coginit?

What is the approved or suggested API for managing multiple COGs in the C runtime, aside from pthreads?

The C API reference mentions 2 STDIO drivers, but doesn't mention the DOS driver, what other drivers/support is available but not explicitly enumerated?

I don't see the propeller loader config file options documented thoroughly. Specifically, the extended options like sd card pins and the XMM drivers.

If I design a memory board for XMM use, I want to know what the CFG file settings should be to talk to the chips.

The SSF driver is said to use only 10 pins, what pins are used? Are the CS pins and CLK pins shared and the prop just mirrors the nibbles when writing commands?

Is QPI mode supported for the Winbond chips?

I just wanted to pose a few relevant questions that should help to clear up the documentation.

Comments

  • jazzedjazzed Posts: 11,803
    edited 2012-05-01 11:47
    Hi Perry.

    Our documentation is lacking in some respects. :depressed:

    Daniel and I are working on a site that is targeted for better documentation. All of your questions here are very helpful in focusing on new user concerns. Thanks.

    I'll answer these in separate posts and try to follow up with doc pointers when possible.

    --Steve
  • jazzedjazzed Posts: 11,803
    edited 2012-05-01 11:54
    pedward wrote: »
    Specifically, I know from regular Prop programming that COG mode is straight PASM, but some clarifications I would like to know: Specifically, which PASM instructions are restricted in LMM mode?

    I'm not exactly sure what this means.

    If you're talking about in-line ASM instructions, restrictions include "any jump instruction". Jump instructions are replaced by LMM/XMM macros. There are other limits that I'm not entirely sure of regarding immediate type instructions - maybe Bill or Eric can explain these in more detail. Using the ASM syntax you will not be able to use self modifying code in any way. There is a generic ASM syntax description in the GCC.pdf.
  • jazzedjazzed Posts: 11,803
    edited 2012-05-01 11:58
    This post is a place-holder for my current answers - which could be all we need, but I want to give the answers separate posts since the there is so much information to cover. I'll remove it after I've given the Q&A separate posts.

    --Steve


    For now here are quick and simple answers to your questions which are in bold italic:

    I was reading the docs on the supported memory models (https://sites.google.com/site/propel.../memory-models) and it isn't entirely clear what the restrictions of each memory model are.

    This will take another post.

    Specifically, I know from regular Prop programming that COG mode is straight PASM, but some clarifications I would like to know:

    Specifically, which PASM instructions are restricted in LMM mode?

    I'm not exactly sure what this means.

    If you're talking about in-line ASM instructions, restrictions include "any jump instruction". Jump instructions are replaced by LMM/XMM macros. There are other limits that I'm not entirely sure of regarding immediate type instructions - maybe Bill or Eric can explain these in more detail. Using the ASM syntax you will not be able to use self modifying code in any way. There is a generic ASM syntax description in the GCC.pdf.

    How about a table of "what you use in COG mode" => "what you would use in LMM mode".


    Indeed. Rick (@mindrobots) posted a beginning table of these things. It would be good to expand on that and provide more "what to use" mode info. I'll explore this in another post.

    Furthermore, is PASM off limit in XMM mode?

    It depends on what you're asking. COG PASM is like any other PASM. COG C can also be used to make PASM COG programs.
    ASM should not be much different between LMM and XMM modes - like I mentioned above, self-modifying code is not advised.
    Again I'm hoping one of the other GCC team members will contribute on this.

    If it's not off limits, what restrictions are there beyond LMM?

    TBD

    How about a table like the one above, illustrating how you would implement each restricted instruction.

    TBD
    As you move into XMM, what are some good rules to follow when writing PASM to play nice with XMM?

    PASM should always use a HUB RAM mailbox for startup parameters and communications, should accept a lock-id if it expects to share hardware pins like cache driver interface or other hardware, should never write to HUB RAM unless it's part of the presumed API contract, should always indicate when it is ready to accept commands after startup, and should NEVER rely on Spin code to poke parameters.

    Pthreads will only run on COG N and not N*M in XMM mode, so what is the suggested alternative to get code running on additional cogs?

    Actually, you can have as many Pthreads as you like, but they will only run on one COG (a subtly different but clearer statement).

    In these cases, you should COG C or PASM programs in separate COGs.

    Does each COG have to run the XMM kernel to make that work?

    Assuming you mean in the case where XMM would allow M*N Pthreads on N COGs, yes.

    Is it implied in XMM mode that only COG mode code can be run on other COGs?

    Yes.

    I saw a smattering somewhere which suggested what C routines should be used in place of the traditional cognew to launch code so it plays nice with the C runtime, but it doesn't seem easy to find.

    You can share any non-static global variable with threads started by pthreads or some variation of _start_cog_thread.
    There are some examples of this in the toggle demos.

    I see cognew/init are implemented, but to what end are they useful?

    They are used to launch PASM code. Launching C code requires some variation of _start_cog_thread.

    I assume only COG code is of any use with cognew/coginit?


    Today that's true. There is a volunteer project that may use cognew to start SPIN programs - this is not clear yet.

    What is the approved or suggested API for managing multiple COGs in the C runtime, aside from pthreads?

    Currently this is _start_cog_thread which is found in propeller-gcc's propeller-elf/include/sys/thread.h
    My plan is to make some candy coated syntax wrappers for this since it's kind of difficult as is.

    The C API reference mentions 2 STDIO drivers, but doesn't mention the DOS driver, what other drivers/support is available but not explicitly enumerated?

    A built-in file-system stdio driver is available (DOS driver?). The driver symbol is _FileDriver and can be referenced as FILE *stream.
    The best example of this is in Dave Hein's c3files demo. Here's a snippet:
    extern _Driver _SimpleSerialDriver;
    extern _Driver _FileDriver;
    
    
    /* This is a list of all drivers we can use in the
     * program. The default _InitIO function opens stdin,
     * stdout, and stderr based on the first driver in
     * the list (the serial driver, for us)
     */
    _Driver *_driverlist[] = {
      &_SimpleSerialDriver,
      &_FileDriver,
      NULL
    };
    
    
    char *FindChar(char *ptr, int val);
    
    
    FILE *stdinfile;
    FILE *stdoutfile;
    

    I don't see the propeller loader config file options documented thoroughly. Specifically, the extended options like sd card pins and the XMM drivers.

    Yes, I've had a hard time with this too. I'm hoping David will be able to add more information on the fields.

    If I design a memory board for XMM use, I want to know what the CFG file settings should be to talk to the chips.

    This is a very good question for cache interface. Essentially, you specify a cachedriver.dat which is typically a spin file PASM driver.
    There are 2 parameters available: cache-param1 and cache-param2 ... both parameters are typically coded in hex and allow passing 64 bits to the driver (8 total 8 bit parameters or however you want to use them). The documentation of the parameters is up to the cache driver creator.

    The SSF driver is said to use only 10 pins, what pins are used? Are the CS pins and CLK pins shared and the prop just mirrors the nibbles when writing commands?

    Currently they are P0..7 + CLK P26 + CS* P27. It would be easy to change this for another driver.
    Not sure what you mean by mirroring the nibbles. Clarify?


    Is QPI mode supported for the Winbond chips?

    Yes. It is also supported for SST26FVxx parts using David's new driver.
    Also, SPI works on Winbond chips but not SST chips.

    I just wanted to pose a few relevant questions that should help to clear up the documentation.

    Thanks. This is very helpful.
    --Steve
  • pedwardpedward Posts: 1,642
    edited 2012-05-01 12:42
    jazzed wrote: »
    I'm not exactly sure what this means.

    If you're talking about in-line ASM instructions, restrictions include "any jump instruction". Jump instructions are replaced by LMM/XMM macros. There are other limits that I'm not entirely sure of regarding immediate type instructions - maybe Bill or Eric can explain these in more detail. Using the ASM syntax you will not be able to use self modifying code in any way. There is a generic ASM syntax description in the GCC.pdf.

    I was hoping for a list like:

    Restricted instructions:

    JMP
    JMPRET
    DJNZ
    CALL
    RET

    Additionally, local references sound like they are broken, so any references to local tags ":loop" or COG variables "h1007" are unsupported too?

    Basically only ALU instructions are supported in LMM or XMM, and setup is required to manage variables?

    It seems to me that the simplest way to convey this is to create an X by Y table of all 64 instructions with a pink background of the restricted instructions and to specifically discuss what language structure is unsupported and what *is* supported.
  • jazzedjazzed Posts: 11,803
    edited 2012-05-01 13:24
    pedward wrote: »
    I was hoping for a list like:

    Restricted instructions:

    JMP
    JMPRET
    DJNZ
    CALL
    RET

    No problem. That's pretty much the list.
    pedward wrote: »
    Additionally, local references sound like they are broken, so any references to local tags ":loop" or COG variables "h1007" are unsupported too?

    Not broken, it's just that using :loop or h1007 doesn't make any sense for in-line LMM ASM("...") syntax.
    In LMM GAS as emitted by C programs you can use labels and variables with GAS macro syntax.
    COG GAS has different requirements though and PASM is recommended over GAS.
    pedward wrote: »

    It seems to me that the simplest way to convey this is to create an X by Y table of all 64 instructions with a pink background of the restricted instructions and to specifically discuss what language structure is unsupported and what *is* supported.

    Yes, that's a great idea.
  • ersmithersmith Posts: 6,097
    edited 2012-05-01 18:03
    pedward wrote: »
    I was hoping for a list like:

    Restricted instructions:

    JMP
    JMPRET
    DJNZ
    CALL
    RET

    You left out TJNZ and TJZ. Other than that the list is pretty complete for LMM mode. Note that it is actually legal to use any of these if you can guarantee that the destination is in COG memory and not HUB memory, for example if the function is declared as a _NATIVE one or is part of the built in LMM kernel. So in one sense all instructions are supported in LMM mode. But the instructions above are useful only in a very restricted sense (for COG addresses). For jumps to LMM addresses, which are by far the most common case in LMM mode, you have to use some special code, such as:
    // jmp #NNNN -- jump to a specific address in hub memory
      jmp #__LMM_JMP
      long NNNN
    
    // jmp rN -- indirect jump to a register; the register rN must be in COG memory, but it must point into hub memory!!!
      mov pc, rN
    
    // jmp #NNNN -- jump to a specific address which is +- 511 bytes from here
    // this is a macro that GAS expands to "add pc, #(NNNN - .)"
       brs  NNNN
    
    // call #NNNN -- call a subroutine directly (NNNN is the address in hub memory)
      jmp  #__LMM_CALL
      long NNNN
    
    // call a subroutine indirectly (rN is a register which must be in COG memory)
       mov __TMP0, rN
       jmp  #__LMM_CALL_INDIRECT
    
    // ret to an address in HUB memory
       mov pc, lr
    
    // for JMPRET, DJNZ, TJZ, TJNZ you'll have to use the basics above combined with ALU operations
    // for example, TJZ r0, #NNNN becomes:
    //    cmp r0, #0
    //  if_e brs NNNN
    
    
    It's generally simplest in LMM mode to just let the compiler handle the jumps, calls, and returns, and put inline assembly for PASM inside the function body.

    In XMM mode there is the additional restriction that RDLONG, RDWORD, etc. and WRLONG, WRWORD, etc. only work for variables that are explicitly placed in HUB memory. For variables in external memory you should use the GAS "xmmio" macro (which will expand into an appropriate call into the LMM kernel). For example
    // read a long word in external memory (XMM mode only); similar to "RDLONG r0, r1"
       xmmio rdlong, r0, r1
    // write a byte to external memory (XMM mode only)
       xmmio wrbyte, r0, r2
    
    Additionally, local references sound like they are broken, so any references to local tags ":loop" or COG variables "h1007" are unsupported too?
    PASM instructions can only operate on things in COG memory, so in LMM and XMM mode you have to be very careful with register references. There are some standard registers r0-r14 which you can use, provided you don't conflict with the C compiler's use of them (the compiler expects r8-r14 to be preserved across function calls). You can also explicitly declare variables to reside in COG memory with the _COGMEM directive from <propeller.h>, but use this very sparingly -- most of the COG memory is taken up by the kernel.

    Also note that because you can't directly reference HUB memory, things like immediate constants > 511 must be handled with LMM subroutines. For example, to load 0x8000 into register r0 you would do the following in COG mode
       mov r0, h8000
    ...
    h8000 long 0x8000
    
    but in LMM mode you would instead do:
    // set r0 to 0x8000
       jmp #__LMM_MVI_r0
       long 0x8000
    
  • jrjr.jrjr. Posts: 45
    edited 2012-05-03 20:47
    Jazzed,

    This is the closest area to DOC that I've seen while looking, so here is a
    simple request, please include an 'about' box inside the simple terminal that calls out all it does
    (and doesn't) do.
    I was expecting some ANSI terminal sequences to work but found very few.
    Bypassed the problem with Putty, of course.
    Maybe that might be an interesting default for the terminal output, a selectable launcher
    for the terminal of choice as an IDE option.

    Btw, Thanks to all for the great work on this, it was running in 4 minutes.....beautiful.

    jack
  • jazzedjazzed Posts: 11,803
    edited 2012-05-03 22:10
    Yes, the terminal is a dumb terminal.

    I'll look into adding the Qt help context button or maybe options to the window.
    The terminal will probably never* support ANSI sequences.

    Meanwhile, I'll also add the recognized characters to the user guide.
    The only supported "sequences" are CLEAR 0, BKSP '\b', TAB '\t', LF '\n', and CR '\r'.

    Thanks,
    --Steve

    *Never say never :)
    jrjr. wrote: »
    Jazzed,

    This is the closest area to DOC that I've seen while looking, so here is a
    simple request, please include an 'about' box inside the simple terminal that calls out all it does
    (and doesn't) do.
    I was expecting some ANSI terminal sequences to work but found very few.
    Bypassed the problem with Putty, of course.
    Maybe that might be an interesting default for the terminal output, a selectable launcher
    for the terminal of choice as an IDE option.

    Btw, Thanks to all for the great work on this, it was running in 4 minutes.....beautiful.

    jack
  • jrjr.jrjr. Posts: 45
    edited 2012-05-04 06:35
    Steve,

    Thanks for the quick response.

    It may be early to ask, but where should requests as to the IDE functionality go ?

    I guess for now, it could go here....

    ********
    What element calls the dumbterm, (probably the loader) and is it exposed enough to be re-vectored to Putty ?

    If not an option, please consider adding it to the .cfg for the board that is selected, i.e.:

    as for a new selection:

    -t=putty.exe (params)

    or
    as the default:

    -t=dumbterm.exe (params)

    ******

    Thanks,

    jack
  • jazzedjazzed Posts: 11,803
    edited 2012-05-04 07:00
    Hi Jack.

    The issue tracker is here:
    http://code.google.com/p/propside/issues/list

    I'll look into hooking up a different terminal at some point.
    It's a bigger job than I have time for at the moment.

    If/when I add that, it will be a global rather than a board type property.
    I know it's a pain to use an external terminal right now - I've tried it too.

    The loader is a separate program from the IDE.

    Thanks,
    --Steve

    jrjr. wrote: »
    Steve,

    Thanks for the quick response.

    It may be early to ask, but where should requests as to the IDE functionality go ?

    I guess for now, it could go here....

    ********
    What element calls the dumbterm, (probably the loader) and is it exposed enough to be re-vectored to Putty ?

    If not an option, please consider adding it to the .cfg for the board that is selected, i.e.:

    as for a new selection:

    -t=putty.exe (params)

    or
    as the default:

    -t=dumbterm.exe (params)

    ******

    Thanks,

    jack
Sign In or Register to comment.