Skip to content
Open
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@

# testing
builds/

# Google Drive on OSX
Icon?
47 changes: 34 additions & 13 deletions platforms/m3/prc_v14/software/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
################################################################################

CFLAGS :=
CLDFLAGS :=
ASFLAGS :=

##########################
Expand All @@ -13,14 +14,14 @@ ASFLAGS :=
#CFLAGS += -Wall -Wextra -Werror -mthumb -mcpu=cortex-m0 -ffreestanding
# Don't care about the warnings not compiling. It's annoying.
CFLAGS += -Os -Wall -Wextra -mthumb -mcpu=cortex-m0 -ffreestanding -fdata-sections -ffunction-sections -g
LDFLAGS += -Os -static -S -nostartfiles --gc-sections -e _start #-dead_strip #-why_live read_mbus_register_RADv4
CFLAGS += -flto -ffat-lto-objects
CLDFLAGS = -static -nostdlib -Wl,--gc-sections --entry=_start

# no longer usling linker, as it can't do link-time-optimization, using gcc with CLDFLAGS
#LDFLAGS += -Os -static -S -nostartfiles --gc-sections -e _start #-dead_strip #-why_live read_mbus_register_RADv4
#LDFLAGS += -Os -static -S -nostartfiles -nodefaultlibs -nostdlib --gc-sections -e _start #-dead_strip #-why_live read_mbus_register_RADv4
ASFLAGS += -mthumb --warn -mcpu=cortex-m0

# Experiments in not linking unused sections
#CFLAGS += -fvtable-gc -fdata-sections -ffunction-sections -Wl,-static -Wl,--gc-sections -s
#LDFLAGS += -nostartfiles -nodefaultlibs -nostdlib

# Attempt to divine ARM toolchain
SHELL=/bin/bash
CROSS_COMPILE=$(shell if `hash arm-linux-gnueabi-gcc >& /dev/null`; then echo arm-linux-gnueabi; elif `hash arm-linux-gnu-gcc >& /dev/null`; then echo arm-linux-gnu; elif `hash arm-none-linux-gnueabi-gcc >& /dev/null`; then echo arm-none-linux-gnueabi; elif `hash arm-none-eabi-gcc >& /dev/null`; then echo arm-none-eabi; else echo -n ""; fi)
Expand Down Expand Up @@ -52,6 +53,7 @@ CXX := $(CROSS_COMPILE)-g++
LD := $(CROSS_COMPILE)-ld
OBJDUMP := $(CROSS_COMPILE)-objdump
OBJCOPY := $(CROSS_COMPILE)-objcopy
NM := $(CROSS_COMPILE)-nm

################################################################################
## You should not need to edit this makefile beyond this point
Expand All @@ -63,20 +65,30 @@ OBJCOPY := $(CROSS_COMPILE)-objcopy
ASFLAGS += -Iinclude/
CFLAGS += -Iinclude/

GCCLIB := $(shell arm-none-eabi-gcc -print-libgcc-file-name | tr -d '\r')

LIBS := $(subst .c,.o,$(wildcard libs/*.c))
LIBS += $(subst .s,.o,$(wildcard libs/*.s))
HEADERS := $(wildcard include/*.h)

DIRS := $(patsubst %/,%,$(filter-out libs/,$(filter-out include/,$(wildcard */))))
GDB:= $(subst .c,.o,$(wildcard gdb/*.c))
GDB+= $(subst .s,.o,$(wildcard gdb/*.s))

DIRS := $(patsubst %/,%,\
$(filter-out libs/,\
$(filter-out include/,\
$(filter-out gdb/,\
$(wildcard */)))))
BINS := $(foreach var,$(DIRS),$(var)/$(var).bin)
HEXS := $(foreach var,$(DIRS),$(var)/$(var).hex)
ELFS := $(foreach var,$(DIRS),$(var)/$(var).elf)

.PRECIOUS: $(LIBS) $(BINS) $(ELFS)
.PRECIOUS: $(LIBS) $(BINS) $(ELFS) $(GDB)

.PHONY: all

all: $(HEXS)
# GDB needs to be first if we want to link against it
all: $(GDB) $(HEXS) libs/memmap

$(DIRS):
$(MAKE) $@/$@.hex
Expand All @@ -97,13 +109,21 @@ $(DIRS):
%.bin: %.elf
$(OBJCOPY) -O binary $< $@

# Mind the order here to align -T$^
%.elf: libs/memmap $(LIBS) %.o
$(LD) $(LDFLAGS) -T$^ "$$(echo $$(arm-none-eabi-gcc -print-libgcc-file-name) | tr -d '\r')" -o $@
# Uses GCC (not LD) to do the linking to make use of LTO
# This will link in GDB support if you #include "gdb.h" in any of the source files
%.elf: COBJ=$(patsubst %.c,%.o,$(wildcard $(dir $@)*.c))
%.elf: SOBJ=$(patsubst %.s,%.o,$(wildcard $(dir $@)*.s))
%.elf: $(LIBS) $$(COBJ) $$(SOBJ)
if [ -n "$$(echo $$( $(NM) $^ | grep use_gdb))" ]; then \
$(CC) $(CFLAGS) $(CLDFLAGS) -Tlibs/memmap \
-Wl,--start-group $^ $(GCCLIB) $(GDB) -Wl,--end-group -o $@ ; \
else \
$(CC) $(CFLAGS) $(CLDFLAGS) -Tlibs/memmap \
-Wl,--start-group $^ $(GCCLIB) -Wl,--end-group -o $@ ;\
fi
$(OBJDUMP) -Sd $@ > $*.asm

.PRECIOUS: %.elf

.PRECIOUS: %.elf %.o

##########
## Cleanup
Expand All @@ -113,6 +133,7 @@ clean:
rm -f $(HEXS)
rm -f $(LIBS)
rm -f $(ELFS)
rm -f $(GDB)

clean-%:
rm -f $*/$*.bin $*/$*.hex
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#include "PRCv14_RF.h"
#include "mbus.h"

#include "gdb.h"

// uncomment this for debug mbus message
// #define DEBUG_MBUS_MSG
#define DEBUG_MBUS_MSG_1
Expand Down Expand Up @@ -57,7 +59,7 @@ void handler_ext_int_5(void) __attribute__ ((interrupt ("IRQ")));
void handler_ext_int_6(void) __attribute__ ((interrupt ("IRQ")));
void handler_ext_int_7(void) __attribute__ ((interrupt ("IRQ")));
void handler_ext_int_8(void) __attribute__ ((interrupt ("IRQ")));
void handler_ext_int_9(void) __attribute__ ((interrupt ("IRQ")));
//void handler_ext_int_9(void) __attribute__ ((interrupt ("IRQ")));
void handler_ext_int_10(void) __attribute__ ((interrupt ("IRQ")));
void handler_ext_int_11(void) __attribute__ ((interrupt ("IRQ")));
void handler_ext_int_12(void) __attribute__ ((interrupt ("IRQ")));
Expand All @@ -73,7 +75,7 @@ void handler_ext_int_5(void) { *NVIC_ICPR = (0x1 << 5); mbus_msg_flag = 0x13; }
void handler_ext_int_6(void) { *NVIC_ICPR = (0x1 << 6); mbus_msg_flag = 0x14; } // REG4
void handler_ext_int_7(void) { *NVIC_ICPR = (0x1 << 7); mbus_msg_flag = 0x15; } // REG5
void handler_ext_int_8(void) { *NVIC_ICPR = (0x1 << 8); mbus_msg_flag = 0x16; } // REG6
void handler_ext_int_9(void) { *NVIC_ICPR = (0x1 << 9); mbus_msg_flag = 0x17; } // REG7
//void handler_ext_int_9(void) { *NVIC_ICPR = (0x1 << 9); mbus_msg_flag = 0x17; } // REG7
void handler_ext_int_10(void) { *NVIC_ICPR = (0x1 << 10); } // MEM WR
void handler_ext_int_11(void) { *NVIC_ICPR = (0x1 << 11); } // MBUS_RX
void handler_ext_int_12(void) { *NVIC_ICPR = (0x1 << 12); } // MBUS_TX
Expand Down
233 changes: 233 additions & 0 deletions platforms/m3/prc_v14/software/gdb/_gdb.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
/*
*
* GDB Hooks for GDBoverMBUS support
*
* This works by co-opting the service routine call (svc)
* as well as Interrupt #9 (handler_ext_int_9)
*
*
*
* Andrew Lukefahr
* lukefahr@indiana.edu
*
* Much of this is borrowed from:
* - https://github.com/adamheinrich/os.h/blob/master/src/os_pendsv_handler.s
* - The Definitive Guide to ARM Cortex-M0 and Cortex-M0+ Processors Section 10.7.1
*/

.syntax unified
.cpu cortex-m0
.fpu softvfp

.thumb


/*
*
* use the software trap handler as a soft-Breakpoint
*
*/
.global handler_svcall
.type handler_svcall, %function
handler_svcall:


/*
* Exception frame saved by the NVIC hardware onto stack:
* +------+
* | | <- SP before interrupt (orig. SP)
* | xPSR |
* | PC |
* | LR |
* | R12 |
* | R3 |
* | R2 |
* | R1 |
* | R0 | <- SP after entering interrupt (orig. SP + 32 bytes)
* +------+
*/

/*
* Registers saved by the software (PendSV_Handler):
* +------+
* | R7 |
* | R6 |
* | R5 |
* | R4 |
* | R11 |
* | R10 |
* | R9 |
* | R8 | <- Saved SP (orig. SP + 64 bytes)
* +------+
*/
/* we can push r4-r7 directly, r8-r11 we have to move into a lower
* register first, then store it */
push {r4,r5,r6,r7}
mov r4, r8
mov r5, r9
mov r6, r10
mov r7, r11
push {r4,r5,r6,r7}

/*
* Finally save the (recalculated) origional stack pointer and
* the Special LR is saved by the software (PendSV_Handler):
* +------+
* | SP | this is the origional (pre-svc) sp value
* |ISR_LR| <- Saved SP (orig. SP + 72 bytes)
* +------+
*/
mov r1, sp
subs r1, #68 //back to origional sp before svc
push {r1}
push {lr}

/* Now we can call the C svc_handler
* adapted from 'the_definitive_guide_to_arm_cortex_m0_and_cortex_m0+_processors'
*/

/* make the stack pointer the first argument to the C svc_handler
* but first we need to figure out which stack we're using
* and we can do that by testing the special LR
*/
movs r0, #4
mov r1, LR // SPECIAL LR
tst r0, r1
beq stacking_used_MSP

stacking_used_PSP:
mrs r0, PSP // first parameter - stacking was using PSP
b handler_svcall_2

stacking_used_MSP:
mrs r0, MSP // first parameter - stacking was using MSP

handler_svcall_2:
/* ok, now we can actually call the c svc_handler */
ldr r2, =_gdb_break // branch to C handler
blx r2

/* pop the Special LR */
pop {r1}

/* pop the dummy SP */
pop {r4}

/* pop r8-r11 */
pop {r4,r5,r6,r7}
mov r8, r4
mov r9, r5
mov r10, r6
mov r11, r7

/* pop r4-r7 */
pop {r4,r5,r6,r7}

/* and return from SVC */
bx r1

/*
*
* use the MBUS Reg #7 (IRQ#9) Interrupt as a soft-Halt
*
*/

.global handler_ext_int_9 /* 25 External Interrupt(9) */
.type handler_ext_int_9, %function
handler_ext_int_9:


/*
* Exception frame saved by the NVIC hardware onto stack:
* +------+
* | | <- SP before interrupt (orig. SP)
* | xPSR |
* | PC |
* | LR |
* | R12 |
* | R3 |
* | R2 |
* | R1 |
* | R0 | <- SP after entering interrupt (orig. SP + 32 bytes)
* +------+
*/

/*
* Registers saved by the software (PendSV_Handler):
* +------+
* | R7 |
* | R6 |
* | R5 |
* | R4 |
* | R11 |
* | R10 |
* | R9 |
* | R8 | <- Saved SP (orig. SP + 64 bytes)
* +------+
*/
/* we can push r4-r7 directly, r8-r11 we have to move into a lower
* register first, then store it */
push {r4,r5,r6,r7}
mov r4, r8
mov r5, r9
mov r6, r10
mov r7, r11
push {r4,r5,r6,r7}

/*
* Finally save the (recalculated) origional stack pointer and
* the Special LR is saved by the software (PendSV_Handler):
* +------+
* | SP | this is the origional (pre-svc) sp value
* |ISR_LR| <- Saved SP (orig. SP + 72 bytes)
* +------+
*/
mov r1, sp
subs r1, #68 //back to origional sp before svc
push {r1}
push {lr}

/* Now we can call the C svc_handler
* adapted from 'the_definitive_guide_to_arm_cortex_m0_and_cortex_m0+_processors'
*/

/* make the stack pointer the first argument to the C svc_handler
* but first we need to figure out which stack we're using
* and we can do that by testing the special LR
*/
movs r0, #4
mov r1, LR // SPECIAL LR
tst r0, r1
beq irq9_stacking_used_MSP

irq9_stacking_used_PSP:
mrs r0, PSP // first parameter - stacking was using PSP
b handler_ext_int_9_2

irq9_stacking_used_MSP:
mrs r0, MSP // first parameter - stacking was using MSP

handler_ext_int_9_2:
/* ok, now we can actually call the c svc_handler */
ldr r2, =_gdb_halt // branch to C handler
blx r2

/* pop the Special LR */
pop {r1}

/* pop the dummy SP */
pop {r4}

/* pop r8-r11 */
pop {r4,r5,r6,r7}
mov r8, r4
mov r9, r5
mov r10, r6
mov r11, r7

/* pop r4-r7 */
pop {r4,r5,r6,r7}

/* and return from SVC */
bx r1

Loading