COGNEWx/COGRUNx and further discussion on how starting a cog works
Cluso99
Posts: 18,069
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
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
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."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
Comments
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... 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.
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.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?
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
Naming can come once it settles down.