#Generation of a boot-over-spacewire application.
#The target application is encapsulated in a mkprom
#image, which in turn is linked to a RAM area above
#the target application.
#The mkprom image is encapsulated in a RMAP master
#application called 'spwboot'
#
#Requires the following steps:
# 0. Edit spwboot.tcl to reference correct grspwN on master and target
# 1. Edit target application, debug link options, memory etc in this Makefile
# 2. Connect debug link to target
# 3. make target (or copy from examples)
# 4. Connect debug link to master
# 5. make master (or copy from examples)
# 6. make spwboot
#

###### edit configuration here:

#compilation of the (target) bdinit functions. Also used for boot application (master) 'spwboot'
CC=sparc-elf-gcc
CCOPT=-msoft-float -O2 -g -mtune=ut699

#how to connect to the boards
GRMONOPT_MASTER=-digilent
GRMONOPT_TARGET=-ftdi -edac
#application binary to be uploaded by spw and started on target
SPWBOOT_TARGET_APP=hello

#mkprom arguments: Most MCTRL options are irrelevant since 
#configuration registers are set up via RMAP.
#-ramsize defines the stack pointer
MKPROM_GEN_ARGS=-leon3 -freq 48 -ramsize 8192 -baud 38400
RAM_START=0x40000000
RAM_END=0x40800000

#Set which grspw links are used. On GR740 target, don't care or use e.g. spwrtr0::psts_1
GRSPW_MASTER=grspw2
GRSPW_TARGET=grspw0

#set to 1 if target is GR740, 0 otherwise
TARGET_GR740=0
#which SpW port receives RMAP packet. Needed for return path in spwboot.c
GR740_SPWPORT=1

###### end edit configuration
#file name of MKPROM image to create
SPWBOOT_TARGET_PROM=spw_bootprom

#link boot PROM after target app, aligned to a 4kbyte boundary
SPWBOOT_PROM_ENTRY=$(shell ./obj2array  $(SPWBOOT_TARGET_APP) -t4)

#EDAC clean (wash) areas around PROM image.
EDCLEAN1_START=$(RAM_START)
EDCLEAN1_SIZE=$(shell ./obj2array $(SPWBOOT_TARGET_APP) -t4b $(EDCLEAN1_START))
EDCLEAN2_START=$(shell ./obj2array $(SPWBOOT_TARGET_PROM) -t8)
EDCLEAN2_SIZE=$(shell ./obj2array $(SPWBOOT_TARGET_PROM) -t8a $(RAM_END))

#bdinit1() initializes the first word after the PROM image,
#in case the PROM image size is not 8byte aligned
#(-edac-clean uses double stores)
BDINIT_WASHWORD=$(shell ./obj2array $(SPWBOOT_TARGET_PROM) -t)

#Use target app entry point as a valid address in RAM.
#Avoids mctrl reconfiguration during execution
MCTRL_DUMMY=$(shell ./obj2array  $(SPWBOOT_TARGET_APP) -e)

SPWBOOT_ENTRY=$(shell ./obj2array  $(SPWBOOT_TARGET_PROM) -e)

include spwboot.mk

all:
	@echo 0. Edit spwboot.tcl to reference correct grspwN on master and target
	@echo 1. Edit target application, debug link options, memory etc in this Makefile
	@echo 2. Connect debug link to target
	@echo 3. make target
	@echo 4. Connect debug link to master
	@echo 5. make master
	@echo 6. make spwboot
	@echo ---
	@echo If no master is available, spwboot_master.h can be copied from the examples folder.
	@echo If the target is GR740, make target-GR740 copies the target relevant files from the GR740 example. No connection to the target is required.

#GR740: application entry point at 0x0
ifeq ($(TARGET_GR740),1)
        SPARCLEON0_ld=-sparcleon0
        SPARCLEON0=-Wl,-msparcleon0
else
        SPARCLEON0_ld=
        SPARCLEON0=
endif

MKPROM_ALL_ARGS=$(MKPROM_GEN_ARGS) $(SPARCLEON0_ld) -nopnp -bdinit $(MKPROM_ARGS) $(SPWBOOT_TARGET_APP) -o $(SPWBOOT_TARGET_PROM)

hello-app:
	$(CC) -msoft-float -O2 $(SPARCLEON0) hello.c -o hello

#We need the second mkprom run to get the right PROM image size for EDAC initialization
prom0: obj2array hello-app
	$(CC) $(CCOPT) -DSPWBOOT_WASHWORD=$(BDINIT_WASHWORD) -DGR740=$(TARGET_GR740) -c bdinit.c -o bdinit.o
	mkprom2 $(MKPROM_ALL_ARGS) -rstaddr $(SPWBOOT_PROM_ENTRY) -memc $(MCTRL_DUMMY) -edac -edac-clean $(EDCLEAN1_START) $(EDCLEAN1_SIZE) $(EDCLEAN2_START) $(EDCLEAN2_SIZE)

$(SPWBOOT_TARGET_PROM): prom0 obj2array
	$(CC) $(CCOPT) -DSPWBOOT_WASHWORD=$(BDINIT_WASHWORD) -DGR740=$(TARGET_GR740) -c bdinit.c -o bdinit.o
	mkprom2 $(MKPROM_ALL_ARGS) -rstaddr $(SPWBOOT_PROM_ENTRY) -memc $(MCTRL_DUMMY) -edac -edac-clean $(EDCLEAN1_START) $(EDCLEAN1_SIZE) $(EDCLEAN2_START) $(EDCLEAN2_SIZE)

spwboot: spwboot_rmap_img.h
	$(CC) $(CCOPT) -DREMOTE_ENTRYPOINT=$(SPWBOOT_ENTRY) -DGR740=$(TARGET_GR740) -DGR740_SPWPORT=$(GR740_SPWPORT) -o spwboot spwboot.c spwapi.c

spwboot_rmap_img.h: obj2array $(SPWBOOT_TARGET_PROM)
	./obj2array $(SPWBOOT_TARGET_PROM) > spwboot_rmap_img.h

obj2array: obj2array.c
	gcc -g -O2 obj2array.c -o obj2array -lbfd

master: obj2array
	GRSPW=$(GRSPW_MASTER) grmon $(GRMONOPT_MASTER) -c master_gen.tcl

target: obj2array
	GRSPW=$(GRSPW_TARGET) IS_GR740=$(TARGET_GR740) grmon $(GRMONOPT_TARGET) -c target_gen.tcl

target-GR740:
	cp examples/GR740-target/GR740_SDCFG1.h examples/GR740-target/spwboot.mk examples/GR740-target/spwboot_target.h .

clean:
	rm -f spwboot spwboot_rmap.h spwboot_master.h spwboot_target.h obj2array spw_bootprom spwboot_rmap_img.h bdinit.o xdump.s hello GR740_SDCFG1.h
