; --------------------------------------------------------------------------------
; @Title: Debugging Actors of ChorusOS PRM in TRACE32
; @Description: 
;   
;   This batchfile shows, how to debug actors and load their
;   symbols in a ChorusOS protected memory model environment.
;   
;   It is not intended as a ready-to-run script file, but
;   as a file to extract the necessary information.
;   Compare it to the ChorusOS load script chorus.cmm.
;   
;   
; @Keywords: chorus, prm, v40x
; @Author: DIE
; @Copyright: (C) 1989-2014 Lauterbach GmbH, licensed for use with TRACE32(R) only
; --------------------------------------------------------------------------------
; $Id: load_actor.cmm 7020 2014-04-28 10:10:12Z kjmal $

;   Created by Rudi Dienstbeck / Lauterbach GmbH at 22.06.2001

; There are basically three different actor layouts, which
; have to be handled differently:
; - user actors
; - linked-in supervisor actors
; - dynamically loaded supervisor actors


; Prerequisites
; --------------------------------------------------------------------------------

; see chorus.cmm for a complete setup sequence

; TRACE32 attaches an MMU space id to each user actor.
; The next command only works, if no symbols are loaded (y.res).

 SYStem.Option mmu ON       ; enable MMU space ids

; The ChorusOS attribute "space_barrier" defines, where user
; actors are loaded. The area below this address is supervisor
; area and may be accessed by any actor MMU space. This area
; must be defined as "common".

 TRANSlation.COMMON 0--5fffffff    ; space_barrier: 0x60000000
 
; After the system came up, scan the current MMU for kernel
; address translation. After reboot, a save place to do this
; is the first call of the kernel function actorRun.

 TRANSlation.SCANALL

; And switch on TRACE32 MMU address translation

 TRANSlation.ON


; User Actors
; --------------------------------------------------------------------------------

; User actors are always linked to the same virtual address
; (usually space_barrier), at which they are executed.
; After loading them into ChorusOS, you can simply load the
; symbols to the right MMU space id.

 LOCAL &space                            ; TRACE32 script variable
 &space=task.actor.space("myActor_u")    ; get MMU space id
 ; now load the symbols into the right space id
 Data.LOAD.Elf myActor_u &space:0 /NoCODE /NoClear


; Linked-in Supervisor Actors
; --------------------------------------------------------------------------------

; Supervisor actors, that are linked into the kernel image,
; are already linked to the right supervisor virtual address.
; All supervisor actors are in MMU space id 0, the need not
; to be loaded into a specific MMU space.

 Data.LOAD.Elf myLinkedInActor_s /NoCODE /NoClear


; Loaded Supervisor Actors
; --------------------------------------------------------------------------------

; Dynamically loaded supervisor actors are usually linked 
; to zero and relocated at load time. First after this relocation
; you can load the symbols into TRACE32. The symbols then must
; be relocated to the actual address of the actor.
; Check in the TASK.LA "myActor_s" window the region addresses:
; "EX" should be the first (below: 1) for the text segment;
; "WR" should be the second (below: 2) for the data segment.
; All supervisor actors are in MMU space id 0, the need not
; to be loaded into a specific MMU space.

 LOCAL &text &data &bss &rodata             ; TRACE32 script variables
 &text=task.actor.start("myActor_s",1)      ; text region ("EX")
 &data=task.actor.start("myActor_s",2)      ; data region ("RW")
 &bss=task.actor.start("myActor_s",3)       ; bss region ("RW")
 &rodata=task.actor.start("myActor_s",4)    ; read-only region, if applicable ("RO")
 ; now load the symbols with relocation
 Data.LOAD.Elf myActor_s /NoCODE /NoClear /RELOC .text at &text /RELOC .data at &data /RELOC .bss at &bss /RELOC .rodata at &rodata
 ; if no bss is available, you may use this command:
 Data.LOAD.Elf myActor_s /NoCODE /NoClear /RELOC .text at &text /RELOC .data at &data /RELOC .bss AFTER .data


; Breaking into Actors
; --------------------------------------------------------------------------------

; There are three possibilities to break into an actor:
; - halting in the actor thread
; - attaching to an loaded actor
; - set breakpoint at main() befor actor start

; 1. Halting in the Actor Thread

; This method requires, that the actor is in the current
; running state, i.e. in a running endless loop.
; Just break and scan the actual MMU table

 Break.direct
 TRANSlation.SCANALL
 ; load actor symbols, see above
 
; 2. Attaching to an loaded actor

; If the actor is loaded and already started, you have to
; find an address, which is executed next in the actor.
; This is a little bit tricky.
; Halt the system. Set a breakpoint into the actor and
; continue execution. The application will stop on
; the breakpoint

 Break.direct
 TRANSlation.SCANALL        ; scan MMU space of all actors
 ; load actor symbols, see above
 Break.Set \myActor\myFunction
 Go.direct
 WAIT !run()
 TRANSlation.SCANALL        ; scan again, to get dynamical regions (e.g. stack)
 
; 3. Set Breakpoint Before Start

; If you like to debug your actor right from the beginning,
; then you must load the symbols and set a breakpoint
; after ChorusOS loaded the actor but BEFORE ChorusOS 
; starts the actor. Set a breakpoint at actorRun. Load the
; actor; the system will hit the breakpoint. Ensure, that
; the actor is loaded into ChorusOS (TASK.LA). Set a
; breakpoint at main() and continue. The application will
; halt right on main() of your actor.

 Break.direct
 TASK.LA                    ; to check actor loading
 Break.Set actorRun         ; actor is about to be started
 Go.direct
 ; load actor into ChorusOS, system will halt at actorRun
 WAIT !run()
 Break.Delete actorRun
 TRANSlation.SCANALL                ; scan MMU space, including loaded actor
 ; load actor symbols, see above
 Break.Set \myActor\main    ; set breakpoint on main routine
 Go.direct
 WAIT !run()
 TRANSlation.SCANALL        ; scan again, to get dynamical regions (e.g. stack)
 
