Shop OBEX P1 Docs P2 Docs Learn Events
COGNEWx/COGRUNx and further discussion on how starting a cog works — Parallax Forums

COGNEWx/COGRUNx and further discussion on how starting a cog works

Cluso99Cluso99 Posts: 18,069
edited 2014-02-24 18:56 in Propeller 2
This needs it's own thread (so we can find it later - tired of trying to sift thru' the huge P2 haystacks looking for those needles)

Background
COGNEW/COGNEWX/COGRUN/COGRUNX now replace COGINIT/COGNEW.

X means the cog starts in HUBEXEC mode (the start address is in hub), else the cog starts in cog mode.
COGRUNx means the cog is not reset, just restarted.
COGNEWx means the cog is reset, then restarted.
Loading code from hub to cog before the cog starts is optional, as is the length. Clearing the cog ram is also an optional extra.

Here is some sample code I posted to start a cog (reposted here for reference).
It starts the cog in hubexec mode and executes a stub to load the cog ram $000-$1EF from hub using wides (fastest) and then the cog executes the loaded program from cog $000.
http://forums.parallax.com/showthread.php/125543-Propeller-II-update-BLOG?p=1245635&viewfull=1#post1245635
Cluso99 wrote: »
Here is something like the code that I think I would like to run to load a cog from hub using wides - ie fastest. I have left a couple of bits to fill in that I don't quite understand yet. Something like this could perhaps be placed in the Hub ROM.
DAT
        org     $0              ' boot code for Cog 0 ...
start
' Cog code that will load and start a cog
                                ' <cogload>  is hub addr of hubexec routine to load the cog
                                ' <codeaddr> is hub addr of cog code to load ($0-1E0)
                                ' <paraddr>  is hub addr of parameters
                                ' <cog>      is cog# to start
                                ' <len>      is length to load (bytes)             
        COGNEWX ????

DAT
        orgh    $1000           ' needs to be on a wide boundary for caching
' Load a Cog $000-1EF from Hub on a wide boundary...        
cogload SETPTRA <codeaddr>
        SETINDA #0
        REPS    #62*8,#1        ' 496 longs
        RDWIDEA #62             ' 62 wides
        MOV     INDA++,$1F1     ' repeat loading 62*8 longs
' set PTRA = PAR = hub addr of parameters & PTRB = <hubaddr> of cog code in hub
' Begin cog execution at $000
        JMPD    #0              ' J to cog $0 after executing following 2 instructions...
        SETPTRA <paraddr>       ' set hub PAR  addr
        SETPTRB <codeaddr>      ' set hub CODE addr
' Cog execution will now begin at cog $0

DAT
' Cog Program to be loaded into cog $0 and executed as a COGNEW...
        orgh    $2000           ' needs to be on a wide boundary
entry   jmp     #entry          ' loop here indefinately
                         
Chip replied "Looks good. PTRB could be used, since it otherwise contains the program's start address. INDA could be initialized in hardware to $000 on cog start."

Comments

  • Cluso99Cluso99 Posts: 18,069
    edited 2014-02-24 16:13
    <reserved for a summary>
  • Cluso99Cluso99 Posts: 18,069
    edited 2014-02-24 16:58
    What I have wondered is how precisely we can use some standard hub routines to load the cog fast, and whether they could then be part of the hub ROM.
    In fact, it seems to me that we might even be able to simplify the COGNEW/COGRUN instructions and save instruction space.

    In the P1 we only ever load 496 longs ($000-$1EF) because $1F0-1FF are special registers. In P2 we actually have $1F0 & 1F1 available as register/instruction space.

    So, in P2, why don't we make the normal/standard cog start (ie a user program that runs in cog ram) a ROM routine in hub that:
    • only loads 496 longs ($000-$1EF)
    • clears $1F0, $1F1
    • clears $1F2 (INDA), $1F3 (INDB)
    • PTRA is set to the hub address of any parameters (PAR)
    • PTRB is set to the hub address of the cog code loaded
    • caveat: the hub load address must be on a wide boundary (8 long)
    The cog performing the cognew would setup a 32bit D register value with the parameters required, and then execute a special coginit instruction (can now be a simpler instruction from the "1111111" instruction group).

    This could be implemented by either of these 2 sets of code...
        AUGD    #<pars> << 9
        COGINIT #<pars> & $1FF,#0-8  'where 8 = next available cog
    [I]---or---[/I]
        COGINIT D,#0-8
    [I]where
    D or <pars> = <hub address of code to load> + <hub address of optional parameters>[/I]
    
    In both the above examples, the new COGINIT would cause the new cog to start execution in hubexec mode at a predefined hub address in ROM (where something similar to my previous post would execute - reposted here with some fixes - and following the loading a JMP to cog $000 would occur to begin the user's program.
    DAT
            org     $0              ' boot code for Cog 0 ...
    start
    ' Cog code that will load and start a cog
                                    ' <cogload>  is hub addr of hubexec routine to load the cog
                                    ' <codeaddr> is hub addr of cog code to load ($0-1E0)
                                    ' <paraddr>  is hub addr of parameters
                                    ' <cog>      is cog# to start
                                    ' <len>      is length to load (bytes)             
            ...
            COGINIT cogpars,#8      ' start any cog in hubexec at hub ROM <cogload>
            ...
    
    cogpars long  <codeaddr> << 16 | <paraddr> & $FFFF
              
    DAT
            orgh    <romaddr>       ' Hub ROM coginit code - needs to be on a wide boundary for caching
    ' Load a Cog $000-1EF from Hub on a wide boundary...        
    ' HOW DO WE GET THE PASSED "D" PARAMETER TO EXTRACT CODEADDR & PARADDR ???
    
    cogload SETPTRA <paraddr>       ' set hub PAR  addr
            SETPTRB <codeaddr>      ' set hub CODE addr
            SETINDA #0              ' clear INDA
            SETINDB #0              ' clear INDB (ptr to cog ram)
            MOV     $1F0,#0         ' clear $1F0
            MOV     $1F1,#0         ' clear $1F1
            REPS    #62*8,#1        ' 496 longs
            RDWIDEB #62             ' 62 wides
            MOV     INDB++,$1F1     ' repeat loading 62*8 longs
    
    ' set PTRA = PAR = hub addr of parameters & PTRB = <hubaddr> of cog code in hub
    ' Begin cog execution at $000
            JMPD    #0              ' J to cog $0 after executing following 2 instructions...
            SETPTRB <codeaddr>      ' set hub CODE addr
            SETINDB #0              ' clear INDB
    ' Cog execution will now begin at cog $0
    
    DAT
    ' Cog Program to be loaded into cog $0 and executed as a COGNEW...
    
            orgh    $2000           ' needs to be on a wide boundary
    codeaddr jmp    #codeaddr       ' loop here indefinitely
    
            orgh    $2861           ' any address for PARameters
    paraddr long    0               ' parameters...
            long    0
    
  • Cluso99Cluso99 Posts: 18,069
    edited 2014-02-24 17:29
    Now, all we need to do our own loading, is a simple COGRUN/COGNEW plus our own routine to optionally reset, optionally load with variable length, optional clear, and a JMP to start the cog.

    Could we simplify the current loading method, and free up the current COGNEWx and COGRUNx instructions ?

    So what instruction support would this require...
    • a COGRUNx/COGNEWx instruction(s) that...
      • COGXXXX <hubstart>,#<resetbit>,#0-8
        • <hubstart> is the address in hub where the cog will start hubexec from (the loading program)
        • #<resetbit> is a bit to reset the cog (currently the difference between cogrun and cognew)
        • #0-8 is the cog# 0-7 to start, and 8 = start the next free cog
        • returns C if the cog is started successfully
        • returns the cog# in D if the #8 was used
    • a hub long(s) where the parameters will be stored temporarily for the <hubaddr>, <length>, <paraddr>, <clearbit>, etc.
    Note, the COGXXXX <hubstart>,#<resetbit>,#0-8 can also be used to immediately start a cog in hubexec mode without loading/clearing.
  • Cluso99Cluso99 Posts: 18,069
    edited 2014-02-24 17:35
    Chip,
    With the above two simpler instructions (which can be moved to the "1111111" instruction range, thereby freeing up some instruction space)...
    Would this work ???
    Would this mean that your cog ROM would no longer be required?
    What code does your cog ROM do?
  • SapiehaSapieha Posts: 2,964
    edited 2014-02-24 17:44
    Hi Cluso

    As we can now run both from HUB and COG.

    In my opinion that Instructions NEED be renamed to simple to--->

    START (C,H) addres, index (L W).

    (C,H) HUB
    COG
    (L W) LONGS --- WIDES
  • Cluso99Cluso99 Posts: 18,069
    edited 2014-02-24 18:56
    Sapieha wrote: »
    Hi Cluso

    As we can now run both from HUB and COG.

    In my opinion that Instructions NEED be renamed to simple to--->

    START (C,H) addres, index (L W).

    (C,H) HUB
    COG
    (L W) LONGS --- WIDES
    In fact, provided we don't want to start a cog in hubexec mode from <$200 long (<$800 bytes) we can just use the addresses <$200 as cog.
    Naming can come once it settles down.
Sign In or Register to comment.