Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions core/dev/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,13 @@ tests-mcu:
--tee ./build/tests-mcu.log ./build/tests-mcu.frt
awk -f $(AMFORTH)/tests/results-mcu.awk ./build/tests-mcu.log

## Run tests-mcu.frt through amforth-shell on hardware
tests-sock:
# export EDITOR in your .env file to make the #edit shell directive work.
$(SKIP) -x assembler-with-cpp -I $(AMFORTH) $(AMFORTH)/tests/tests-mcu.frt > ./build/tests-mcu.frt
$(AMFORTH)/tools/socket-shell.py -I $(AMFORTH) --no-error-on-output ./build/tests-mcu.frt
#awk -f $(AMFORTH)/tests/results-mcu.awk ./build/tests-mcu.log

## Detailed dump of ELF sections for debugging linker issues
sections: sec-type sec-addr sec-sum

Expand Down
2 changes: 1 addition & 1 deletion core/words/see.s
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ SEEDOTDODOTXT_0001: /* then */
.word XT_DP_RAM
.word XT_DP
.word XT_MAX
.word XT_LESS
.word XT_ULESS
.word XT_DOCONDBRANCH,SEEDOTDODOTXT_0002 /* if */
.word XT_SEEDOTIP
.word XT_FETCH
Expand Down
86 changes: 86 additions & 0 deletions rv/mcu/fe310/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# SPDX-License-Identifier: GPL-3.0-only

-include .env

AMFORTH ?= $(shell git rev-parse --show-toplevel)

QEMU_RV32 ?= qemu-system-riscv32

# Default target to build
TARGET ?= REDFIVE
TARGETS = REDFIVE HIFIVE1

CHIPSET=$(TARGET)
MCU_LD := ./$(TARGET).ld
LIB_WCH := ./lib_$(TARGET)
LIB_USER := ./lib_$(TARGET)_user

ASFLAGS += -march=rv32imac_zicsr_zifencei -mabi=ilp32

# Included after various configuration bits are defined (importantly MCU_LD and TARGET)
include $(AMFORTH)/rv/dev/Makefile

.PRECIOUS: amforth.s

#? --- QEM ---

# This is quite different from the -kernel option, which will for the RV 'virt' jump to
# 0x8000_0000 no matter what ENTRY() has in the linker file. The cpu-num=0 sets the PC
# to the value indicated by ENTRY(), which is much more suitable our needs. The commented
# out line gives a hint as to how to set the PC to an absolute address at boot time.

QEMU := $(QEMU_RV32) -M virt -bios none -device loader,file=build/amforth.elf,cpu-num=0
# -device loader,addr=0x20010000,cpu-num=0

## Start AmForth under QEMU with operator uart connected to stdio
stdio:
$(QEMU) -display none -serial stdio

## Start AmForth under QEMU with operator uart connected to a pty
pty:
$(QEMU) -nographic -serial pty

# Add -S if you want QEMU to not start the quest.
## Like pty but allows GDB to attach to it (-s).
debug:
$(QEMU) -nographic -serial pty -s

## Connect GDB to amforth running on QEMU (must be running with -s, see debug)
gdb:
$(GDBPY) build/amforth.elf --quiet \
-ex 'target remote :1234' \
-ex "source tui-full.gdb"

## Serve AmForth on :4444 (make nc|socshell for client) - logs to /tmp/serial.log
socket:
$(QEMU) -display none \
-chardev socket,id=sock0,host=127.0.0.1,port=4444,server=on,wait=on,logfile=/tmp/serial.log \
-serial chardev:sock0

## Serve AmForth on :4444 with debug on :1234 - logs to /tmp/serial.log
socbug:
$(QEMU) -display none \
-chardev socket,id=sock0,host=127.0.0.1,port=4444,server=on,wait=on,logfile=/tmp/serial.log \
-serial chardev:sock0 -s

## rlwrap nc client connecting to :4444
nc:
rlwrap nc localhost 4444

## socket-shell as client connecting to :4444
socshell:
$(AMFORTH)/tools/socket-shell.py --no-error-on-output -i --ignore-error

read-elf:
$(TC_DIR)/bin/$(CROSS)readelf -h build/amforth.elf

ifeq ($(strip $(TARGET)),REDFIVE)
QEMU:=$(QEMU_RV32) -M sifive_e,revb=true -bios none -kernel build/amforth.elf
## Upload hex file to the device
upload:
cp build/amforth.hex /Volumes/HiFive
else
QEMU:=$(QEMU_RV32) -M sifive_e -bios none -kernel build/amforth.elf
upload:
echo "no upload for $(TARGET) available"
endif
32 changes: 32 additions & 0 deletions rv/mcu/fe310/amforth.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# This is a template to start from.
# Copy it into your mcu/ directory and modify as needed.

.text

.include "mcu/qemu/config.inc" # most configuration options are in this file
.include "build-config.inc"

.print "INFO: using FE310 startup"
.include "fe310.startup" # startup and master_int handler for both C and Forth

.section amforth, "ax"

.option push # save option set
.option norvc # don't use compressed
.option norelax # don't relax

.include "config.inc"
.include "build-config.inc"
.include "rv/macros.inc"
.include "user.inc"

STARTDICT

.include "dict_prims.inc"
.include "dict_secs.inc"
.include "dict_env.inc"
.include "dict_mcu.inc"

ENDDICT

.option pop # restore option set
18 changes: 18 additions & 0 deletions rv/mcu/fe310/config.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

.include "core/config.inc"

.equ datastack_size, 32 * cellsize
.equ returnstack_size, 32 * cellsize

/* TODO: this is made up, needs correcting */
.equ flash_page, 1*1024
.equ flash_cell, 1
.equ flash_erased, 0xFFFFFFFF /* a word in erased flash */

.equ rampool_size, 1024*1

.equ WANT_DEBUGGER , YES
.equ WANT_IGNORECASE , YES
.equ WANT_SEE , YES
.equ WANT_TRANSPILER , NO

21 changes: 21 additions & 0 deletions rv/mcu/fe310/dict_mcu.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

.include "words/gpio.s"
.include "words/usart.s"

.if TARGET==HIFIVE1
.include "words/leds.s"
.else
.include "words/redvled.s"
.endif

.include "words/mtime.s"

.include "words/applturnkey.s"

.include "words/type0.s"

.include "words/pll.s"
.include "words/qspidiv.s"
.include "words/csr.s"


64 changes: 64 additions & 0 deletions rv/mcu/fe310/eval.f
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
variable strlen
variable str
variable str-buf $20 allot

: source-string str @ strlen @ dup . ;
: refill-false ( -- false ) false ;

: (evaluate)
break
['] source defer@ >r
['] refill defer@ >r
>in @ >r
0 >in !
strlen !
str !
['] source-string is source
['] interpret catch
r> >in !
r> is refill
r> is source
throw
;

\ : (evaluate) \ i*x addr len -- j*y
\ break
\ ['] source defer@ >r \ 1. Save current source implementation
\ >in @ >r \ 2. Save current input offset
\ 0 >in ! \ 3. Reset offset to start of buffer
\ strlen ! \ 4. Store string length
\ str ! \ 5. Store string address
\ ['] source-string is source \ 6. Redirect source to our buffer
\ ['] interpret catch \ 7. Execute interpreter (with error trapping)
\ r> >in ! \ 8. Restore original input offset
\ r> is source \ 9. Restore original source
\ throw \ 10. Re-throw any caught errors
\ ;

: evaluate
state @ if
postpone (evaluate)
else
(evaluate)
then
; immediate


: ww ( addr len -- )
dup strlen ! \ a n
str-buf swap move \
str-buf str !
\ (evaluate)
;

: (evaluate-test)
strlen !
str !
['] source-string is source
source
." len=" .
." addr=" hex.
['] source is source
;

\ s" 1 1 +" (evaluate-test)
16 changes: 16 additions & 0 deletions rv/mcu/fe310/fe310.startup
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

.option norvc # no opportunistic use of compressed ...
.option norelax # instructions or other such optimisations

#la gp, __global_pointer$

.global PFA_COLD
.global _start

.section .init
_start:
la gp, __global_pointer$
la sp, _eusrstack

j PFA_COLD

20 changes: 20 additions & 0 deletions rv/mcu/fe310/hifive1.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
OUTPUT_ARCH( "riscv" )

ENTRY( _start )

/* Not enough memory to support pvalues practically */
PVFLASH_PAGE = 0;
PVFLASH_CELL = 0;
PVFLASH_ERASED = flash_erased;

/* !! Memory regions are defined early and their parameters MUST NOT be computed from object file symbols !! */
MEMORY
{
/* FLASH(RX) : ORIGIN = 0x20400000, LENGTH = 32K */
FLASH(RX) : ORIGIN = 0x20400000, LENGTH = 64K
RAM(WAIXL) : ORIGIN = 0x80000000, LENGTH = 16K
/* MUST define the PVFLASH region otherwise it will default to occupying the entire memory space */
PVFLASH(RW) : ORIGIN = 0 , LENGTH = 0
}

INCLUDE amforth32.ld
9 changes: 9 additions & 0 deletions rv/mcu/fe310/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# AmForth for SiFive Hifive1

AmForth is published under the GNU Public License v3 (GPL).

Arduino-compatible development board featuring the SiFive Freedom E310 (FE310) SoC [32-bit RV32IMAC core].

# References

* https://www.sifive.com/boards/hifive1
20 changes: 20 additions & 0 deletions rv/mcu/fe310/redfive.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
OUTPUT_ARCH( "riscv" )

ENTRY( _start )

/* Not enough memory to support pvalues practically */
PVFLASH_PAGE = 0;
PVFLASH_CELL = 0;
PVFLASH_ERASED = flash_erased;

/* !! Memory regions are defined early and their parameters MUST NOT be computed from object file symbols !! */
MEMORY
{
/* FLASH(RX) : ORIGIN = 0x20400000, LENGTH = 32K */
FLASH(RX) : ORIGIN = 0x20010000, LENGTH = 64K
RAM(WAIXL) : ORIGIN = 0x80000000, LENGTH = 16K
/* MUST define the PVFLASH region otherwise it will default to occupying the entire memory space */
PVFLASH(RW) : ORIGIN = 0 , LENGTH = 0
}

INCLUDE amforth32.ld
19 changes: 19 additions & 0 deletions rv/mcu/fe310/words/applturnkey.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
COLON "hifive-turnkey", APPLTURNKEY

.word XT_LED_INIT
.word XT_DECIMAL

/* setup for 256MHz via PLL with 115200 */

.word XT_PLL
.word XT_QSPIDIV
.word XT_INIT_USART

.word XT_DOT_VER, XT_SPACE
.word XT_ENV_BOARD,XT_TYPE, XT_CR
.word XT_ENV_DOT_BUILD

.word XT_EXIT
END APPLTURNKEY


8 changes: 8 additions & 0 deletions rv/mcu/fe310/words/build-info.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

COLON "build-info", BUILD_INFO
STRING "%d"
.word XT_EXIT

COLON "rev-info", REV_INFO
STRING "%r"
.word XT_EXIT
26 changes: 26 additions & 0 deletions rv/mcu/fe310/words/clock.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@

.equ PRCI_BASE, 0x10008000

.equ PRCI_HFROSCCFG , PRCI_BASE + 0x00
.equ PRCI_HFXOSCCFG , PRCI_BASE + 0x04
.equ PRCI_PLLCFG , PRCI_BASE + 0x08
.equ PRCI_PLLDIV , PRCI_BASE + 0x0C
.equ PRCI_PROCMONCFG , PRCI_BASE + 0xF0

CODEWORD "clock", CLOCK

# set up the clock system and make it run

1:li t0, PRCI_HFXOSCCFG # 0x10008004
lw t1, 0(t0)
li t2, 0xC0000000
bne t1, t2, 1b

# Select crystal as main clock source

li t0, PRCI_PLLCFG
li t1, 0x00070df1 # 0x00060df1 | (1<<16) | (1<<17) | (1<<18) # Reset value | PLLSEL | PLLREFSEL | PLLBYPASS
sw t1, 0(t0)

NEXT
END CLOCK
Loading
Loading