# Copyright (c) 1996-2003 MIPS Technologies, Inc.  All rights reserved.
# 
# Unpublished rights (if any) reserved under the copyright laws of the
# United States of America and other countries.
# 
# This code is proprietary to MIPS Technologies, Inc. ("MIPS
# Technologies").  Any copying, reproducing, modifying or use of this
# code (in whole or in part) that is not expressly permitted in writing
# by MIPS Technologies or an authorized third party is strictly
# prohibited.  At a minimum, this code is protected under unfair
# competition and copyright laws.  Violations thereof may result in
# criminal penalties and fines.
# 
# MIPS Technologies reserves the right to change this code to improve
# function, design or otherwise.  MIPS Technologies does not assume any
# liability arising out of the application or use of this code, or of
# any error or omission in such code.  Any warranties, whether express,
# statutory, implied or otherwise, including but not limited to the
# implied warranties of merchantability or fitness for a particular
# purpose, are excluded.  Except as expressly provided in any written
# license agreement from MIPS Technologies or an authorized third party,
# the furnishing of this code does not give recipient any license to any
# intellectual property rights, including any patent rights, that cover
# this code.
# 
# This code shall not be exported or transferred for the purpose of
# reexporting in violation of any U.S. or non-U.S. regulation, treaty,
# Executive Order, law, statute, amendment or supplement thereto.
# 
# This code constitutes one or more of the following: commercial
# computer software, commercial computer software documentation or other
# commercial items.  If the user of this code, or any related
# documentation of any kind, including related technical data or
# manuals, is an agency, department, or other entity of the United
# States government ("Government"), the use, duplication, reproduction,
# release, modification, disclosure, or transfer of this code, or any
# related documentation of any kind, is restricted in accordance with
# Federal Acquisition Regulation 12.212 for civilian agencies and
# Defense Federal Acquisition Regulation Supplement 227.7202 for
# military agencies.  The use of this code by the Government is further
# restricted in accordance with the terms of the license agreement(s)
# and/or applicable contract terms and conditions covering this code
# from MIPS Technologies or an authorized third party.


#
# examples/make.mk
#
# Shared make include file for SDE-MIPS example programs


ifndef DEPTH
DEPTH		=..
endif

# Location of SDE source code kit
ifndef KITDIR
KITDIR		=$(DEPTH)/../kit
endif

# System/eval board: 
ifndef SBD
SBD=NOSBD
MONITOR=$(SBD)
endif

# defaults, which may be overriden by sbd.mk
CPU	=r3k
TLB	=r3k
FPU	=no
PCI	=no
ENDIAN	=-EB
ROM_U	=bfc00000
ROM_C	=9fc00000
ROM_SZ	=400000
RAM_U	=a0000280
RAM_C	=80000280
DLBASE_C =80004000
DLBASE_U =a0004000

SBDDIR	=$(KITDIR)/$(SBD)
include $(SBDDIR)/sbd.mk
include $(KITDIR)/bare/monitor.mk
include $(KITDIR)/$(MONITOR)/monitor.mk
include $(KITDIR)/archs.mk


#EXTRA_LIBS = $(shell echo $(LDFLAGS) | egrep -o "\-Wl,\-l*" |awk '{print $2}')
EXTRA_LIBS = $(shell echo $(LDFLAGS) | grep -o "\-Wl,-l[^ ]*")

ifndef SBDDIRS
SBDDIRS	=$(SBDDIR)
endif

# Allow application-specific override of ISA and CPU type

ifdef APPISA
ISA	=$(APPISA)
endif

# 
# For rommable programs link code and read-only data to ROM,
# and writeable data to RAM (just above the exception vectors).
#
# For interactive debugging link everything into RAM.
# The "kit/romlow" code will then copy both the code and data 
# to RAM, so breakpoints can be set.
#

ifndef ASSIGNROMTEXT
 ifeq ($(UNCACHED),yes)
   ROM_BASE = $(ROM_U)
   RAM_BASE = $(RAM_U)
 else
   ROM_BASE = $(ROM_C)
   RAM_BASE = $(RAM_C)
 endif
 ifneq (,$(strip $(filter imm% copy romcopy ram,$(RDEBUG) $(LAYOUT))))
   # code and data in RAM
   ROMLDFLAGS	=-Ttext $(RAM_BASE)
 else
   # code in ROM, data in RAM
   ROMLDFLAGS	=-Ttext $(ROM_BASE) -Tdata $(RAM_BASE)
 endif
endif

# 
# For downloadable programs link all code and data to RAM.
#
ifndef ASSIGNRAMTEXT
 ifeq ($(UNCACHED),yes)
   RAMLDFLAGS	=-Ttext $(DLBASE_U)
 else
   RAMLDFLAGS	=-Ttext $(DLBASE_C)
 endif
endif

# Lowest safe address for downloadable, but standalone programs
ifndef SABASE_C
 SABASE_U	=$(DLBASE_U)
 SABASE_C	=$(DLBASE_C)
endif

ifndef ASSIGNRAMTEXT
 ifeq ($(UNCACHED),yes)
   SALDFLAGS	=-Ttext $(SABASE_U)
 else
   SALDFLAGS	=-Ttext $(SABASE_C)
 endif
endif

#
# Set RDBG for use by crt0.S
#
ifdef RDEBUG
  CRT0FLAGS	+=$(foreach rdbg,$(RDEBUG),'-Ardbg($(rdbg))')
  ifneq (,$(findstring imm,$(RDEBUG)))
    CRT0FLAGS	+=-DRDBG=2
  else
    CRT0FLAGS	+=-DRDBG=1 
  endif
endif

# Work out the flags which tell the compiler what type of
# floating-point code to generate, and tell the run-time 
# startup code how to initialise the hardware and/or emulator.
#
# Permissible values for FLOAT are:
#   no		doesn't do any f.p arithmetic (default)
#   yes		uses f.p, but won't underflow or get denormalised results
#   ieee	full support for IEEE denormalised numbers and u/flow
#   trap	(for testing only) force use of CP1 trap emulation

ifndef FLOAT
  FLOAT	=no
endif

ifeq ($(FLOAT),no)
 # No floating-point used in code
 FP		=-mno-float
 FPFLAGS	='-Afloat(no)'
else
 # Floating-point used, select what type
 ifeq ($(FPU),no)
  # No hardware fpu: use compiler emulation
  FP		=-msoft-float
  FPFLAGS	='-Afloat(soft)'
 else
  ifeq ($(FPU),single)
   # R4640/50 single-precision fpu only
   FP		=-msingle-float
   FPFLAGS	='-Afloat($(FLOAT))'
  else
   ifeq ($(FPU),yes)
     # Definite hardware floating-point
     FP		=-mhard-float
     FPFLAGS	='-Afloat($(FLOAT))'
   else
     # Possible hardware floating-point - check at run-time
     FP		=-mhard-float
     FPFLAGS	='-Afloat(switch)'
   endif
  endif
 endif
 LIBM		=-lm
endif

#
# Default PROM programmer download format is 32-bit S-records
#
ifndef ROMDLFMT
  ROMDLFMT	=s3
endif

ifndef ALL
 ifdef DLFMT
  ALL	=ram
  ifndef SBDNOSER
    ALL += sa
  endif
  ifdef SBDLOW
    ALL +=rom
  endif
 else
  ALL	=rom
 endif
endif

ifndef DLFMT
  DLFMT		=s3
endif

#
# Default to a fairly high optimisation level, but with post-mortem
# debug info
#
ifndef ASFLAGS
 ASFLAGS	=-O -g
endif

ifndef CFLAGS
 CFLAGS		=-O2 -g1
endif

ifndef CXXFLAGS
 CXXFLAGS	=-O2 -g1
endif

#
# Finally the standard make rules
#
CPUFLAGS	=$(FP) $(CPU_APP)
INCDIRS		+=$(patsubst %,-I$(SBDDIR)/%,$(subst :, ,$(SBDDIRS)))
INCDIRS		+=$(STDINCDIR)
CPPFLAGS	+=$(SBDFLAGS) $(SBDOPTIONS) $(FPFLAGS) $(CPUVARIANT) \
		  $(ARCHFLAGS) $(INCDIRS)
kitfeatures	=xcptstackinfo

ifneq ($(PCI),no)
  CPPFLAGS	+='-Apci($(PCI))'
  kitfeatures	+=pci pcilookup
endif

override ASFLAGS  +=$(CPUFLAGS)
override CFLAGS   +=$(CPUFLAGS)
override CXXFLAGS +=$(CPUFLAGS)
override LDFLAGS  +=$(CPUFLAGS) 

unexport ASFLAGS
unexport CFLAGS
unexport CXXFLAGS
unexport LDFLAGS

#
# Select the correct startup file
#
ifneq (,$(filter -p -pg,$(CFLAGS) $(CXXFLAGS)))
 # Profiling startup
 CRT0		=$(OUTPUT_PATH)/mcrt0.o
else
 # Normal startup
 CRT0		=$(OUTPUT_PATH)/crt0.o
endif
CRTN		=$(SBDDIR)/crtn.o

#
# Build the intersection of requested and supported features for
# this application and board kit, and pass to crt0.
# 
allfeatures	:=$(SBDFEATURES) $(MONFEATURES) $(kitfeatures)
wantfeatures	:=$(patsubst all,$(allfeatures),$(filter-out -%,$(FEATURES)))
exclfeatures	:=$(patsubst -%,%,$(filter -%,$(FEATURES)))
selectfeatures	:=$(filter $(wantfeatures),$(allfeatures))
crt0features	:=$(filter-out $(exclfeatures),$(selectfeatures))
ifneq (,$(strip $(crt0features)))
  comma		:=,
  loadfeatures	:=$(patsubst %,_%_load$(comma),$(crt0features))
  CRT0FLAGS	+=-DFEATURES="$(loadfeatures)0"
endif

# Select the correct arguments for sde-conv when making a ROM
ifeq ($(ROM_U)/$(ROM_SZ),bfc00000/400000)
  ROMFLG=-p
else
  ROMFLG=-a $(ROM_U)/$(ROM_SZ)
endif

SBDROM =$(SBDDIR)/romstart.o $(SBDDIR)/librom.a

SBDRAM =$(SBDDIR)/ramstart.o $(SBDDIR)/libram.a

SBDSA =$(SBDDIR)/ramstart.o $(SBDDIR)/librom.a

SBDLIBS=$(CRTN)

ifneq (,$(filter network,$(FEATURES)))
# Add network library
INCDIRS   +=-idirafter $(DEPTH)/../net/sys
SBDLIBS   +=$(SBDDIR)/libnet.a
LOADLIBES +=-lnet
endif

ifneq (,$(filter network pthread,$(FEATURES)))
# Add Pthread library
SBDLIBS   +=$(SBDDIR)/libth.a
LOADLIBES +=-lth
endif

all: prelink $(ALL) $(SBDCONFIG) clean

ram: $(PROG)ram.$(DLFMT)

rom: $(PROG)rom.$(ROMDLFMT)$(ROMDLSPLIT)

sa: $(PROG)sa.$(DLFMT)

r3k: prelink_r3k getelf clean

getelf: 
	$(CC) $(ASFLAGS) "r3k/r3k_crt0.S" -c -o $(OUTPUT_PATH)/r3k_crt0.o
	$(CC) $(CFLAGS) "r3k/stubs.c" -c -o $(OUTPUT_PATH)/stubs.o
	$(CC) $(CFLAGS) "r3k/memio.c" -c -o $(OUTPUT_PATH)/memio.o
	$(CC) $(LDFLAGS) $(RAMLDFLAGS) $(OUTPUT_PATH)/stubs.o $(OUTPUT_PATH)/memio.o $(OUTPUT_PATH)/r3k_crt0.o $(OBJS) $(LOADLIBES) $(LDLIBS) -lc $(LIBM) -lgcc -lc -le -lc -lgcc $(LIBM) -o $(OUTPUT_PATH)/$(PROG).elf

$(PROG)ram.$(DLFMT): $(PROG)ram
	sde-conv -vf $(DLFMT) $(DLSYMS) -o $@ $(PROG)ram
	@cp $@ $(OUTPUT_PATH)/$(PROG).$(DLFMT)

$(PROG)sa.$(DLFMT): $(PROG)sa
	sde-conv -vf $(DLFMT) $(DLSYMS) -o $@ $(PROG)sa
	@cp $@ $(OUTPUT_PATH)/$(PROG)_sa.$(DLFMT)

$(PROG)rom.$(ROMDLFMT): $(PROG)rom
	sde-conv -vf $(ROMDLFMT) $(ROMFLG) -o $(PROG)rom.$(ROMDLFMT) $(PROG)rom
	@cp $@ $(OUTPUT_PATH)/$(PROG).$(ROMDLFMT)

$(PROG)rom.$(ROMDLFMT).byte: $(PROG)rom
	sde-conv -vb0 -f$(ROMDLFMT) $(ROMFLG) -o $(PROG)rom.$(ROMDLFMT).b0 $(PROG)rom
	sde-conv -vb1 -f$(ROMDLFMT) $(ROMFLG) -o $(PROG)rom.$(ROMDLFMT).b1 $(PROG)rom
	sde-conv -vb2 -f$(ROMDLFMT) $(ROMFLG) -o $(PROG)rom.$(ROMDLFMT).b2 $(PROG)rom
	sde-conv -vb3 -f$(ROMDLFMT) $(ROMFLG) -o $(PROG)rom.$(ROMDLFMT).b3 $(PROG)rom
	@touch $@
	@cp $@ $(OUTPUT_PATH)/$(PROG).$(ROMDLFMT).byte

$(PROG)rom.$(ROMDLFMT).half: $(PROG)rom
	sde-conv -vb01 -f$(ROMDLFMT) $(ROMFLG) -o $(PROG)rom.$(ROMDLFMT).h0 $(PROG)rom
	sde-conv -vb23 -f$(ROMDLFMT) $(ROMFLG) -o $(PROG)rom.$(ROMDLFMT).h3 $(PROG)rom
	@touch $@
	@cp $@ $(OUTPUT_PATH)/$(PROG).$(ROMDLFMT).half

$(PROG)rom.$(ROMDLFMT).hswap: $(PROG)rom
	sde-conv -vb10 -f$(ROMDLFMT) $(ROMFLG) -o $(PROG)rom.$(ROMDLFMT).h0 $(PROG)rom
	sde-conv -vb32 -f$(ROMDLFMT) $(ROMFLG) -o $(PROG)rom.$(ROMDLFMT).h3 $(PROG)rom
	@touch $@
	@cp $@ $(OUTPUT_PATH)/$(PROG).$(ROMDLFMT).hswap

$(PROG)rom.$(ROMDLFMT).wswap: $(PROG)rom
	sde-conv -vb3210 -f$(ROMDLFMT) $(ROMFLG) -o $@ $(PROG)rom
	@cp $@ $(OUTPUT_PATH)/$(PROG).$(ROMDLFMT).wswap

$(PROG)rom.$(ROMDLFMT).dswap: $(PROG)rom
	sde-conv -v -w64 -b76543210 -f$(ROMDLFMT) $(ROMFLG) -o $@ $(PROG)rom
	@cp $@ $(OUTPUT_PATH)/$(PROG).$(ROMDLFMT).dswap

$(PROG)rom: $(CRT0) $(OBJS) $(LDLIBS) $(SBDROM) $(SBDLIBS) $(SBDDIR)/romstart.o
	@cp $(OUTPUT_PATH)/../ldscript_ram.ld .
	$(CC) $(LDFLAGS) $(ROMLDFLAGS) -L$(SBDDIR) $(STDLIBDIR) $(SBDDIR)/romstart.o $(CRT0) $(OBJS) $(LOADLIBES) $(LDLIBS) $(EXTRA_LIBS) -lc $(LIBM) -lrom -lgcc -lc -le -lrom -lc -lgcc $(CRTN) -o $@
	@cp $@ $(OUTPUT_PATH)/$(PROG).elf

$(PROG)ram: $(CRT0) $(OBJS) $(LDLIBS) $(SBDRAM) $(SBDLIBS) $(SBDDIR)/ramstart.o
	@cp $(OUTPUT_PATH)/../ldscript_ram.ld .
	$(CC) $(LDFLAGS) $(RAMLDFLAGS) -L$(SBDDIR) $(STDLIBDIR) $(SBDDIR)/ramstart.o $(CRT0) $(OBJS) $(LOADLIBES)  $(LDLIBS)  $(EXTRA_LIBS) -lc $(LIBM) -lram -lgcc -lc -le -lram -lc -lgcc $(CRTN) -o $@
	@cp $@ $(OUTPUT_PATH)/$(PROG).elf 

$(PROG)sa: $(CRT0) $(OBJS) $(LDLIBS) $(SBDSA) $(SBDLIBS) $(SBDDIR)/ramstart.o
	$(LINK.o) $(SALDFLAGS) -L$(SBDDIR) $(STDLIBDIR) $(SBDDIR)/ramstart.o $(CRT0) $(OBJS) $(LOADLIBES) $(LDLIBS) $(EXTRA_LIBS)  -lc $(LIBM) -lrom -lgcc -lc -le -lrom -lc -lgcc $(CRTN) -o $@
	@cp $@ $(OUTPUT_PATH)/$(PROG)_sa.elf

# Override default build rules for files which need particular #defines
$(OUTPUT_PATH)/crt0.o: $(KITDIR)/share/crt0.sx
	$(COMPILE.S) $(RDBGFLAGS) $(CRT0FLAGS) $(TIMING) $< -o $@
	#echo $(DLBASE_U)

$(OUTPUT_PATH)/mcrt0.o: $(KITDIR)/share/crt0.sx
	$(COMPILE.S) $(RDBGFLAGS) $(CRT0FLAGS) $(TIMING) -DMCRT0 $< -o $@

ifdef SBDCONFIG
$(SBDCONFIG):
	@if [ ! -e ./$(SBDCONFIG) ]; then \
	  echo cp $(SBDDIR)/$(SBDCONFIG) . ; \
	  cp $(SBDDIR)/$(SBDCONFIG) . ; \
	fi
endif

# These next two targets make sure that everything gets rebuilt if 
# the SBD variable, it's associated sbd.mk file, or this program's
# own Makefile are changed.

ifndef MAKEFILE
# MAKEFILE=Makefile
  MAKEFILE=$(OUTPUT_PATH)/../$(PROG).mak
endif

$(OBJS) $(CRT0): $(MAKEFILE) $(SBD).sbd $(SBDDIR)/sbd.mk $(DEPTH)/make.mk

$(SBD).sbd:
	@echo "++ Rebuilding with new SBD $(SBD)"
	@rm -f $(PROG)rom $(PROG)ram $(PROG)sa
	@rm -f $(PROG)rom.* $(PROG)ram.* $(PROG)sa.*
	@rm -f *.sbd
	@touch $(SBD).sbd

$(SBDROM) $(SBDRAM) $(CRTN): kit

.PHONY: prelink
prelink:
	@cp $(OUTPUT_PATH)/../*.ld .
	
.PHONY: prelink_r3k
prelink_r3k:
	@cp r3k/*.ld .
	
.PHONY: kit
kit:
	@$(MAKE) -C $(SBDDIR) SBD=$(SBD) kit LDFLAGS=""

$(SBDDIR)/libth.a: 
	@$(MAKE) -C $(SBDDIR) SBD=$(SBD) rtpx

$(SBDDIR)/libnet.a: 
	@$(MAKE) -C $(SBDDIR) SBD=$(SBD) net

.PHONY: clean
clean:
	rm -f *.o *.sbd *.ld
	rm -f $(PROG)rom $(PROG)ram $(PROG)sa 
	rm -f $(PROG)rom.* $(PROG)ram.* $(PROG)sa.* r3k.elf

.PHONY: clobber
clobber: clean
	rm -f core *.core *[~#] ,*

.PHONY: depend
depend: $(SRCS)
	@rm -f depend.mk
	$(CC) $(CFLAGS) $(CPPFLAGS) -MM $? >depend.mk

-include depend.mk

# include default rules
include $(KITDIR)/rules.mk
