diff --git a/Documentation/boards/riscv.rst b/Documentation/boards/riscv.rst new file mode 100644 index 0000000..c7fa52a --- /dev/null +++ b/Documentation/boards/riscv.rst @@ -0,0 +1,91 @@ +RISC-V +====== + +Running RISC-V barebox on qemu +------------------------------ + +Obtain RISC-V GCC/Newlib Toolchain, +see https://github.com/riscv/riscv-tools/blob/master/README.md +for details. The ``build.sh`` script from ``riscv-tools`` should +create toolchain. + +Next compile qemu emulator:: + + $ git clone -b 20180409.erizo https://github.com/miet-riscv-workgroup/riscv-qemu + $ cd riscv-qemu + $ cap="no" ./configure \ + --extra-cflags="-Wno-maybe-uninitialized" \ + --audio-drv-list="" \ + --disable-attr \ + --disable-blobs \ + --disable-bluez \ + --disable-brlapi \ + --disable-curl \ + --disable-curses \ + --disable-docs \ + --disable-kvm \ + --disable-spice \ + --disable-sdl \ + --disable-vde \ + --disable-vnc-sasl \ + --disable-werror \ + --enable-trace-backend=simple \ + --disable-stack-protector \ + --target-list=riscv32-softmmu,riscv64-softmmu + $ make + + +Next compile barebox:: + + $ make erizo_generic_defconfig ARCH=riscv + ... + $ make ARCH=riscv CROSS_COMPILE=/riscv32-unknown-elf- + +Run barebox:: + + $ /riscv32-softmmu/qemu-system-riscv32 \ + -nographic -M erizo -bios /barebox.bin \ + -serial stdio -monitor none -trace file=/dev/null + Switch to console [cs0] + + + barebox 2018.12.0-00148-g60e49c4e16 #1 Tue Dec 18 01:12:29 MSK 2018 + + + Board: generic Erizo SoC board + malloc space: 0x80100000 -> 0x801fffff (size 1 MiB) + running /env/bin/init... + /env/bin/init not found + barebox:/ + + +Running RISC-V barebox on DE0-Nano FPGA board +--------------------------------------------- + +See https://github.com/open-design/riscv-soc-cores/ for instructions +on DE0-Nano bitstream generation and loading. + +Connect to board's UART with your favorite serial communication software +(e.g. minicom) and check 'nmon> ' prompt (nmon runs from onchip ROM). + +Next close your communication software and use ./scripts/nmon-loader +to load barebox image into board's DRAM, e.g. + + # ./scripts/nmon-loader barebox.erizo.nmon /dev/ttyUSB0 115200 + +Wait several munutes for 'nmon> ' prompt. + +Next, start barebox from DRAM: + + nmon> g 80000000 + Switch to console [cs0] + + + barebox 2018.12.0-00148-g60e49c4e16 #1 Tue Dec 18 01:12:29 MSK 2018 + + + Board: generic Erizo SoC board + malloc space: 0x80100000 -> 0x801fffff (size 1 MiB) + running /env/bin/init... + /env/bin/init not found + barebox:/ diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig new file mode 100644 index 0000000..c435cc8 --- /dev/null +++ b/arch/riscv/Kconfig @@ -0,0 +1,91 @@ +config RISCV + def_bool y + select GENERIC_FIND_NEXT_BIT + select HAVE_CONFIGURABLE_MEMORY_LAYOUT + select HAVE_CONFIGURABLE_TEXT_BASE + select GPIOLIB + select OFTREE + select COMMON_CLK + select COMMON_CLK_OF_PROVIDER + select CLKDEV_LOOKUP + +config ARCH_TEXT_BASE + hex + default 0x0 + +menu "Machine selection" + +choice + prompt "System type" + default MACH_ERIZO + +config MACH_ERIZO + bool "erizo family" + select HAS_DEBUG_LL + select HAS_NMON + +endchoice + +choice + prompt "Base ISA" + default ARCH_RV32I + +config ARCH_RV32I + bool "RV32I" + select CPU_SUPPORTS_32BIT_KERNEL + select GENERIC_LIB_ASHLDI3 + select GENERIC_LIB_ASHRDI3 + select GENERIC_LIB_LSHRDI3 + +endchoice + +config CPU_SUPPORTS_32BIT_KERNEL + bool + +choice + prompt "barebox code model" + default 32BIT + +config 32BIT + bool "32-bit barebox" + depends on CPU_SUPPORTS_32BIT_KERNEL + help + Select this option to build a 32-bit barebox. + +endchoice + +config BUILTIN_DTB + bool "link a DTB into the barebox image" + depends on OFTREE + +config BUILTIN_DTB_NAME + string "DTB to build into the barebox image" + depends on BUILTIN_DTB + +source arch/riscv/mach-erizo/Kconfig + +endmenu + +menu "RISC-V specific settings" + +config HAS_NMON + bool + +config NMON + bool "nmon" + depends on HAS_NMON + depends on DEBUG_LL + help + Say yes here to add the nmon to pbl. + nmon -- nano-monitor program for the RISC-V processors. + It can operate with NO working RAM, using only + the processor registers. + +config NMON_HELP + bool "nmon help message" + depends on NMON + help + Say yes here to get the nmon commands message on + every nmon start. + +endmenu diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile new file mode 100644 index 0000000..643c0bc --- /dev/null +++ b/arch/riscv/Makefile @@ -0,0 +1,67 @@ +CPPFLAGS += -fno-strict-aliasing + +ifeq ($(CONFIG_ARCH_RV32I),y) + cflags-y += -march=rv32im +endif + +cflags-y += -fno-pic -pipe +cflags-y += -Wall -Wstrict-prototypes \ + -Wno-uninitialized -Wno-format -Wno-main -mcmodel=medany + +LDFLAGS += $(ldflags-y) +LDFLAGS_barebox += -nostdlib + +machine-$(CONFIG_MACH_ERIZO) := erizo + +TEXT_BASE = $(CONFIG_TEXT_BASE) +CPPFLAGS += -DTEXT_BASE=$(CONFIG_TEXT_BASE) + +ifndef CONFIG_MODULES +# Add cleanup flags +CPPFLAGS += -fdata-sections -ffunction-sections +LDFLAGS_barebox += -static --gc-sections +endif + +KBUILD_BINARY := barebox.bin + +machdirs := $(patsubst %,arch/riscv/mach-%/,$(machine-y)) + +ifeq ($(KBUILD_SRC),) +CPPFLAGS += $(patsubst %,-I%include,$(machdirs)) +else +CPPFLAGS += $(patsubst %,-I$(srctree)/%include,$(machdirs)) +endif + +archprepare: maketools + +PHONY += maketools + +ifneq ($(machine-y),) +MACH := arch/riscv/mach-$(machine-y)/ +else +MACH := +endif + +common-y += $(MACH) +common-y += arch/riscv/boot/ +common-y += arch/riscv/lib/ + +common-$(CONFIG_OFTREE) += arch/riscv/dts/ + +CPPFLAGS += $(cflags-y) +CFLAGS += $(cflags-y) + +lds-y := arch/riscv/lib/barebox.lds + +CLEAN_FILES += arch/riscv/lib/barebox.lds + +ifeq ($(CONFIG_MACH_ERIZO),y) +KBUILD_IMAGE := barebox.erizo.nmon +endif + +quiet_cmd_erizo_nmon_image = MKIMAGE $@ + cmd_erizo_nmon_image = $(srctree)/scripts/erizo-nmon-image $< $@ || \ + echo "WARNING: Couldn't create erizo nmon image due to previous errors." + +barebox.erizo.nmon: $(KBUILD_BINARY) FORCE + $(call if_changed,erizo_nmon_image) diff --git a/arch/riscv/boot/Makefile b/arch/riscv/boot/Makefile new file mode 100644 index 0000000..fd62cab --- /dev/null +++ b/arch/riscv/boot/Makefile @@ -0,0 +1,3 @@ +obj-y += start.o +obj-y += main_entry.o +obj-$(CONFIG_OFDEVICE) += dtb.o diff --git a/arch/riscv/boot/dtb.c b/arch/riscv/boot/dtb.c new file mode 100644 index 0000000..5d73413 --- /dev/null +++ b/arch/riscv/boot/dtb.c @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2016, 2018 Antony Pavlov + * + * This file is part of barebox. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include + +extern char __dtb_start[]; + +static int of_riscv_init(void) +{ + struct device_node *root; + + root = of_get_root_node(); + if (root) + return 0; + + root = of_unflatten_dtb(__dtb_start); + if (!IS_ERR(root)) { + pr_debug("using internal DTB\n"); + of_set_root_node(root); + if (IS_ENABLED(CONFIG_OFDEVICE)) + of_probe(); + } + + return 0; +} +core_initcall(of_riscv_init); diff --git a/arch/riscv/boot/main_entry.c b/arch/riscv/boot/main_entry.c new file mode 100644 index 0000000..f9c640c --- /dev/null +++ b/arch/riscv/boot/main_entry.c @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2016 Antony Pavlov + * + * This file is part of barebox. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include + +void main_entry(void); + +/** + * Called plainly from assembler code + * + * @note The C environment isn't initialized yet + */ +void main_entry(void) +{ + /* clear the BSS first */ + memset(__bss_start, 0x00, __bss_stop - __bss_start); + + mem_malloc_init((void *)MALLOC_BASE, + (void *)(MALLOC_BASE + MALLOC_SIZE - 1)); + + start_barebox(); +} diff --git a/arch/riscv/boot/start.S b/arch/riscv/boot/start.S new file mode 100644 index 0000000..d1dbe48 --- /dev/null +++ b/arch/riscv/boot/start.S @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Startup Code for RISC-V CPU + * + * Copyright (C) 2016 Antony Pavlov + * + * based on coreboot/src/arch/riscv/bootblock.S + * and barebox/arch/mips/boot/start.S + * + * This file is part of barebox. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include + +#include "mach/debug_ll.h" + +#include "asm/riscv_nmon.h" + + .text + .section ".text_entry" + .align 2 + +.globl _start +_start: + debug_ll_ns16550_init + + riscv_nmon + + li sp, STACK_BASE + STACK_SIZE + + /* copy barebox to link location */ + + la a0, _start /* a0 <- _start actual address */ + li a1, CONFIG_TEXT_BASE /* a1 <- _start link address */ + + beq a0, a1, main_entry + + la a2, __bss_start + +#define LONGSIZE 4 + +copy_loop: + /* copy from source address [a0] */ + lw t0, LONGSIZE * 0(a0) + lw t1, LONGSIZE * 1(a0) + lw t2, LONGSIZE * 2(a0) + lw t3, LONGSIZE * 3(a0) + /* copy to target address [a1] */ + sw t0, LONGSIZE * 0(a1) + sw t1, LONGSIZE * 1(a1) + sw t2, LONGSIZE * 2(a1) + sw t3, LONGSIZE * 3(a1) + addi a0, a0, LONGSIZE * 4 + addi a1, a1, LONGSIZE * 4 + bgeu a2, a0, copy_loop + + /* Alas! At the moment I can't load main_entry __link__ address + into a0 with la. Use CONFIG_TEXT_BASE instead. This solution + leads to extra cycles for repeat sp initialization. */ + + li a0, CONFIG_TEXT_BASE + jalr a0 diff --git a/arch/riscv/configs/erizo_generic_defconfig b/arch/riscv/configs/erizo_generic_defconfig new file mode 100644 index 0000000..2ea1e46 --- /dev/null +++ b/arch/riscv/configs/erizo_generic_defconfig @@ -0,0 +1,51 @@ +# CONFIG_GLOBALVAR is not set +CONFIG_TEXT_BASE=0x80000000 +CONFIG_MEMORY_LAYOUT_FIXED=y +CONFIG_STACK_BASE=0x800e0000 +CONFIG_STACK_SIZE=0x20000 +CONFIG_MALLOC_BASE=0x80100000 +CONFIG_MALLOC_SIZE=0x100000 +CONFIG_MALLOC_TLSF=y +CONFIG_PANIC_HANG=y +CONFIG_HUSH_FANCY_PROMPT=y +CONFIG_CMDLINE_EDITING=y +CONFIG_AUTO_COMPLETE=y +# CONFIG_ERRNO_MESSAGES is not set +# CONFIG_TIMESTAMP is not set +# CONFIG_BOOTM is not set +# CONFIG_ENV_HANDLING is not set +CONFIG_POLLER=y +CONFIG_DEBUG_LL=y +CONFIG_LONGHELP=y +CONFIG_CMD_IOMEM=y +CONFIG_CMD_IMD=y +CONFIG_CMD_MEMINFO=y +CONFIG_CMD_GO=y +CONFIG_CMD_LOADY=y +CONFIG_CMD_CMP=y +CONFIG_CMD_MD5SUM=y +CONFIG_CMD_SHA1SUM=y +CONFIG_CMD_MSLEEP=y +CONFIG_CMD_SLEEP=y +CONFIG_CMD_MEMTEST=y +CONFIG_CMD_MM=y +CONFIG_CMD_FLASH=y +CONFIG_CMD_GPIO=y +CONFIG_CMD_I2C=y +CONFIG_CMD_SPI=y +CONFIG_CMD_OF_DUMP=y +CONFIG_CMD_TIME=y +CONFIG_CMD_DHRYSTONE=y +CONFIG_OFDEVICE=y +CONFIG_DRIVER_SERIAL_NS16550=y +CONFIG_DRIVER_SPI_GPIO=y +CONFIG_I2C=y +CONFIG_I2C_GPIO=y +CONFIG_MTD=y +# CONFIG_MTD_OOB_DEVICE is not set +CONFIG_MTD_M25P80=y +CONFIG_CLOCKSOURCE_DUMMY_RATE=60000 +CONFIG_EEPROM_AT24=y +CONFIG_GPIO_GENERIC_PLATFORM=y +# CONFIG_PINCTRL is not set +CONFIG_DIGEST_CRC32_GENERIC=y diff --git a/arch/riscv/dts/.gitignore b/arch/riscv/dts/.gitignore new file mode 100644 index 0000000..077903c --- /dev/null +++ b/arch/riscv/dts/.gitignore @@ -0,0 +1 @@ +*dtb* diff --git a/arch/riscv/dts/Makefile b/arch/riscv/dts/Makefile new file mode 100644 index 0000000..903fe8f --- /dev/null +++ b/arch/riscv/dts/Makefile @@ -0,0 +1,13 @@ +BUILTIN_DTB := $(patsubst "%",%,$(CONFIG_BUILTIN_DTB_NAME)) +ifneq ($(BUILTIN_DTB),) +obj-dtb-$(CONFIG_BUILTIN_DTB) += $(BUILTIN_DTB).dtb.o +endif + +obj-dtb-$(CONFIG_BOARD_ERIZO_GENERIC) += erizo-generic.dtb.o + +# just to build a built-in.o. Otherwise compilation fails when no devicetree is +# created. +obj- += dummy.o + +always := $(dtb-y) +clean-files := *.dtb *.dtb.S .*.dtc .*.pre .*.dts diff --git a/arch/riscv/dts/erizo-generic.dts b/arch/riscv/dts/erizo-generic.dts new file mode 100644 index 0000000..d1f8d57 --- /dev/null +++ b/arch/riscv/dts/erizo-generic.dts @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include "erizo.dtsi" +#include + +/ { + model = "generic Erizo SoC board"; + compatible = "miet-riscv-workgroup,erizo-generic-board"; + + memory@0 { + device_type = "memory"; + reg = <0x80000000 0x00800000>; + }; +}; diff --git a/arch/riscv/dts/erizo.dtsi b/arch/riscv/dts/erizo.dtsi new file mode 100644 index 0000000..0753479 --- /dev/null +++ b/arch/riscv/dts/erizo.dtsi @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/dts-v1/; + +/ { + compatible = "miet-riscv-workgroup,erizo"; + + #address-cells = <1>; + #size-cells = <1>; + + clocks { + ref_clk: ref_clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <24000000>; + }; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "cliffordwolf,picorv32"; + clocks = <&ref_clk>; + reg = <0>; + }; + }; + + uart0: uart@90000000 { + compatible = "ns16550a"; + reg = <0x90000000 0x20>; + reg-shift = <2>; + clocks = <&ref_clk>; + }; + + gpio0: gpio@91000000 { + compatible = "wd,mbl-gpio"; + reg-names = "dat", "dirout"; + reg = <0x91000000 0x4>, + <0x91000004 0x4>; + #gpio-cells = <2>; + gpio-controller; + }; +}; diff --git a/arch/riscv/include/asm/barebox.h b/arch/riscv/include/asm/barebox.h new file mode 100644 index 0000000..2997587 --- /dev/null +++ b/arch/riscv/include/asm/barebox.h @@ -0,0 +1 @@ +/* dummy */ diff --git a/arch/riscv/include/asm/bitops.h b/arch/riscv/include/asm/bitops.h new file mode 100644 index 0000000..b4a2f5f --- /dev/null +++ b/arch/riscv/include/asm/bitops.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * This file is part of barebox. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _ASM_BITOPS_H_ +#define _ASM_BITOPS_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define set_bit(x, y) __set_bit(x, y) +#define clear_bit(x, y) __clear_bit(x, y) +#define change_bit(x, y) __change_bit(x, y) +#define test_and_set_bit(x, y) __test_and_set_bit(x, y) +#define test_and_clear_bit(x, y) __test_and_clear_bit(x, y) +#define test_and_change_bit(x, y) __test_and_change_bit(x, y) + +#endif /* _ASM_BITOPS_H_ */ diff --git a/arch/riscv/include/asm/bitsperlong.h b/arch/riscv/include/asm/bitsperlong.h new file mode 100644 index 0000000..4641e7e --- /dev/null +++ b/arch/riscv/include/asm/bitsperlong.h @@ -0,0 +1,10 @@ +#ifndef __ASM_BITSPERLONG_H +#define __ASM_BITSPERLONG_H + +#ifdef __riscv64 +#define BITS_PER_LONG 64 +#else +#define BITS_PER_LONG 32 +#endif + +#endif /* __ASM_BITSPERLONG_H */ diff --git a/arch/riscv/include/asm/byteorder.h b/arch/riscv/include/asm/byteorder.h new file mode 100644 index 0000000..0be8269 --- /dev/null +++ b/arch/riscv/include/asm/byteorder.h @@ -0,0 +1,6 @@ +#ifndef _ASM_RISCV_BYTEORDER_H +#define _ASM_RISCV_BYTEORDER_H + +#include + +#endif /* _ASM_RISCV_BYTEORDER_H */ diff --git a/arch/riscv/include/asm/common.h b/arch/riscv/include/asm/common.h new file mode 100644 index 0000000..bc8a17e --- /dev/null +++ b/arch/riscv/include/asm/common.h @@ -0,0 +1,6 @@ +#ifndef ASM_RISCV_COMMON_H +#define ASM_RISCV_COMMON_H + +/* nothing special yet */ + +#endif /* ASM_RISCV_COMMON_H */ diff --git a/arch/riscv/include/asm/debug_ll_ns16550.h b/arch/riscv/include/asm/debug_ll_ns16550.h new file mode 100644 index 0000000..e891cbd --- /dev/null +++ b/arch/riscv/include/asm/debug_ll_ns16550.h @@ -0,0 +1,182 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2016, 2017 Antony Pavlov + * + * This file is part of barebox. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +/** @file + * This file contains declaration for early output support + */ +#ifndef __INCLUDE_RISCV_ASM_DEBUG_LL_NS16550_H__ +#define __INCLUDE_RISCV_ASM_DEBUG_LL_NS16550_H__ + +#include + +#ifdef CONFIG_DEBUG_LL + +#ifndef DEBUG_LL_UART_ADDR +#error DEBUG_LL_UART_ADDR is undefined! +#endif + +#ifndef DEBUG_LL_UART_SHIFT +#error DEBUG_LL_UART_SHIFT is undefined! +#endif + +#ifndef DEBUG_LL_UART_DIVISOR +#error DEBUG_LL_UART_DIVISOR is undefined! +#endif + +#endif /* CONFIG_DEBUG_LL */ + +#define UART_THR (0x0 << DEBUG_LL_UART_SHIFT) +#define UART_RBR (0x0 << DEBUG_LL_UART_SHIFT) +#define UART_DLL (0x0 << DEBUG_LL_UART_SHIFT) +#define UART_DLM (0x1 << DEBUG_LL_UART_SHIFT) +#define UART_LCR (0x3 << DEBUG_LL_UART_SHIFT) +#define UART_LSR (0x5 << DEBUG_LL_UART_SHIFT) + +#define UART_LCR_W 0x07 /* Set UART to 8,N,2 & DLAB = 0 */ +#define UART_LCR_DLAB 0x87 /* Set UART to 8,N,2 & DLAB = 1 */ + +#define UART_LSR_DR 0x01 /* UART received data present */ +#define UART_LSR_THRE 0x20 /* Xmit holding register empty */ + +#if defined(DEBUG_LL_UART_IOSIZE32) +#define UART_REG_L lw +#define UART_REG_S sw +#elif defined(DEBUG_LL_UART_IOSIZE8) +#define UART_REG_L lbu +#define UART_REG_S sb +#else +#error "Please define DEBUG_LL_UART_IOSIZE{8,32}" +#endif + +#ifndef __ASSEMBLY__ +/* + * C macros + */ + +#include + +static inline void PUTC_LL(char ch) +{ +#ifdef CONFIG_DEBUG_LL + while (!(__raw_readl((u8 *)DEBUG_LL_UART_ADDR + UART_LSR) & UART_LSR_THRE)) + ; + __raw_writel(ch, (u8 *)DEBUG_LL_UART_ADDR + UART_THR); +#endif /* CONFIG_DEBUG_LL */ +} + +static inline void debug_ll_ns16550_init(void) +{ +#ifdef CONFIG_DEBUG_LL + __raw_writel(UART_LCR_DLAB, (u8 *)DEBUG_LL_UART_ADDR + UART_LCR); + __raw_writel(DEBUG_LL_UART_DIVISOR & 0xff, (u8 *)DEBUG_LL_UART_ADDR + UART_DLL); + __raw_writel((DEBUG_LL_UART_DIVISOR >> 8) & 0xff, (u8 *)DEBUG_LL_UART_ADDR + UART_DLM); + __raw_writel(UART_LCR_W, (u8 *)DEBUG_LL_UART_ADDR + UART_LCR); +#endif /* CONFIG_DEBUG_LL */ +} +#else /* __ASSEMBLY__ */ +/* + * Macros for use in assembly language code + */ + +.macro debug_ll_ns16550_init +#ifdef CONFIG_DEBUG_LL + li t0, DEBUG_LL_UART_ADDR + + li t1, UART_LCR_DLAB /* DLAB on */ + UART_REG_S t1, UART_LCR(t0) /* Write it out */ + + li t1, DEBUG_LL_UART_DIVISOR + UART_REG_S t1, UART_DLL(t0) /* write low order byte */ + srl t1, t1, 8 + UART_REG_S t1, UART_DLM(t0) /* write high order byte */ + + li t1, UART_LCR_W /* DLAB off */ + UART_REG_S t1, UART_LCR(t0) /* Write it out */ +#endif /* CONFIG_DEBUG_LL */ +.endm + +/* + * output a character in a0 + */ +.macro debug_ll_outc_a0 +#ifdef CONFIG_DEBUG_LL + + li t0, DEBUG_LL_UART_ADDR + +201: + UART_REG_L t1, UART_LSR(t0) /* get line status */ + andi t1, t1, UART_LSR_THRE /* check for transmitter empty */ + beqz t1, 201b /* try again */ + + UART_REG_S a0, UART_THR(t0) /* write the character */ + +#endif /* CONFIG_DEBUG_LL */ +.endm + +/* + * output a character + */ +.macro debug_ll_outc chr +#ifdef CONFIG_DEBUG_LL + li a0, \chr + debug_ll_outc_a0 +#endif /* CONFIG_DEBUG_LL */ +.endm + +/* + * output CR + NL + */ +.macro debug_ll_ns16550_outnl +#ifdef CONFIG_DEBUG_LL + debug_ll_outc '\r' + debug_ll_outc '\n' +#endif /* CONFIG_DEBUG_LL */ +.endm + +/* + * check character in input buffer + * return value: + * v0 = 0 no character in input buffer + * v0 != 0 character in input buffer + */ +.macro debug_ll_tstc +#ifdef CONFIG_DEBUG_LL + li t0, DEBUG_LL_UART_ADDR + + /* get line status and check for data present */ + UART_REG_L s0, UART_LSR(t0) + andi s0, s0, UART_LSR_DR + +#endif /* CONFIG_DEBUG_LL */ +.endm + +/* + * get character to v0 + */ +.macro debug_ll_getc +#ifdef CONFIG_DEBUG_LL + +204: + debug_ll_tstc + + /* try again */ + beqz s0, 204b + + /* read a character */ + UART_REG_L s0, UART_RBR(t0) + +#endif /* CONFIG_DEBUG_LL */ +.endm +#endif /* __ASSEMBLY__ */ + +#endif /* __INCLUDE_RISCV_ASM_DEBUG_LL_NS16550_H__ */ diff --git a/arch/riscv/include/asm/elf.h b/arch/riscv/include/asm/elf.h new file mode 100644 index 0000000..7134fa0 --- /dev/null +++ b/arch/riscv/include/asm/elf.h @@ -0,0 +1,11 @@ +#ifndef __ASM_RISCV_ELF_H__ +#define __ASM_RISCV_ELF_H__ + +#if __SIZEOF_POINTER__ == 8 +#define ELF_CLASS ELFCLASS64 +#define CONFIG_PHYS_ADDR_T_64BIT +#else +#define ELF_CLASS ELFCLASS32 +#endif + +#endif /* __ASM_RISCV_ELF_H__ */ diff --git a/arch/riscv/include/asm/io.h b/arch/riscv/include/asm/io.h new file mode 100644 index 0000000..3cdea7f --- /dev/null +++ b/arch/riscv/include/asm/io.h @@ -0,0 +1,8 @@ +#ifndef __ASM_RISCV_IO_H +#define __ASM_RISCV_IO_H + +#define IO_SPACE_LIMIT 0 + +#include + +#endif /* __ASM_RISCV_IO_H */ diff --git a/arch/riscv/include/asm/mmu.h b/arch/riscv/include/asm/mmu.h new file mode 100644 index 0000000..95af871 --- /dev/null +++ b/arch/riscv/include/asm/mmu.h @@ -0,0 +1,6 @@ +#ifndef __ASM_MMU_H +#define __ASM_MMU_H + +#define MAP_ARCH_DEFAULT MAP_UNCACHED + +#endif /* __ASM_MMU_H */ diff --git a/arch/riscv/include/asm/posix_types.h b/arch/riscv/include/asm/posix_types.h new file mode 100644 index 0000000..22cae62 --- /dev/null +++ b/arch/riscv/include/asm/posix_types.h @@ -0,0 +1 @@ +#include diff --git a/arch/riscv/include/asm/riscv_nmon.h b/arch/riscv/include/asm/riscv_nmon.h new file mode 100644 index 0000000..caf213c --- /dev/null +++ b/arch/riscv/include/asm/riscv_nmon.h @@ -0,0 +1,234 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * nano-monitor for RISC-V CPU + * + * Copyright (C) 2016, 2017 Antony Pavlov + * + * This file is part of barebox. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __ASM_RISCV_NMON_H +#define __ASM_RISCV_NMON_H + +#define CODE_ESC 0x1b + +.macro nmon_outs msg + + la a1, \msg + + jal _nmon_outs + +.endm + +/* + * output a 32-bit value in hex + */ +.macro debug_ll_outhexw +#ifdef CONFIG_DEBUG_LL + move t6, a0 + li t5, 32 + +202: + addi t5, t5, -4 + srl a0, t6, t5 + + /* output one hex digit */ + andi a0, a0, 15 + li t4, 10 + blt a0, t4, 203f + + addi a0, a0, ('a' - '9' - 1) + +203: + addi a0, a0, '0' + + debug_ll_outc_a0 + + li t4, 1 + bge t5, t4, 202b + +#endif /* CONFIG_DEBUG_LL */ +.endm + +.macro riscv_nmon + +#ifdef CONFIG_NMON + +nmon_main_help: +#ifdef CONFIG_NMON_HELP + nmon_outs msg_nmon_help +#endif /* CONFIG_NMON_HELP */ + +nmon_main: + nmon_outs msg_prompt + + debug_ll_getc + + li a0, 'q' + bne s0, a0, 3f + + jal _nmon_outc_a0 + + j nmon_exit + +3: + li a0, 'd' + beq s0, a0, nmon_cmd_d + + li a0, 'w' + beq s0, a0, nmon_cmd_w + + li a0, 'g' + beq s0, a0, nmon_cmd_g + + j nmon_main_help + +nmon_cmd_d: + jal _nmon_outc_a0 + + li a0, ' ' + jal _nmon_outc_a0 + + jal _nmon_gethexw + + nmon_outs msg_nl + + lw a0, (s0) + debug_ll_outhexw + + j nmon_main + +nmon_cmd_w: + jal _nmon_outc_a0 + + li a0, ' ' + jal _nmon_outc_a0 + + jal _nmon_gethexw + move s2, s0 + + li a0, ' ' + jal _nmon_outc_a0 + jal _nmon_gethexw + + sw s0, 0(s2) + j nmon_main + +nmon_cmd_g: + jal _nmon_outc_a0 + + li a0, ' ' + jal _nmon_outc_a0 + + jal _nmon_gethexw + move s2, s0 + + nmon_outs msg_nl + + jalr s2 + j nmon_main + +_nmon_outc_a0: + debug_ll_outc_a0 + jr ra + +_nmon_outs: + + lb a0, 0(a1) + addi a1, a1, 1 + beqz a0, _nmon_jr_ra_exit + + debug_ll_outc_a0 + + j _nmon_outs + +_nmon_gethexw: + + li t3, 8 + li t2, 0 + +_get_hex_digit: + debug_ll_getc + + li s1, CODE_ESC + beq s0, s1, nmon_main + + li s1, '0' + bge s0, s1, 0f + j _get_hex_digit + +0: + li s1, '9' + ble s0, s1, 9f + + li s1, 'f' + ble s0, s1, 1f + j _get_hex_digit + +1: + li s1, 'a' + bge s0, s1, 8f + + j _get_hex_digit + +8: /* s0 \in {'a', 'b' ... 'f'} */ + sub a3, s0, s1 + addi a3, a3, 0xa + j 0f + +9: /* s0 \in {'0', '1' ... '9'} */ + li a3, '0' + sub a3, s0, a3 + +0: move a0, s0 + debug_ll_outc_a0 + + sll t2, t2, 4 + or t2, t2, a3 + li t0, 1 + sub t3, t3, t0 + + beqz t3, 0f + + j _get_hex_digit + +0: + move s0, t2 + +_nmon_jr_ra_exit: + jr ra + +msg_prompt: + .asciz "\r\nnmon> " + +msg_nl: + .asciz "\r\n" + +msg_bsp: + .asciz "\b \b" + +#ifdef CONFIG_NMON_HELP +msg_nmon_help: + .ascii "\r\n\r\nnmon commands:\r\n" + .ascii " q - quit\r\n" + .ascii " d - read 32-bit word from \r\n" + .ascii " w - write 32-bit word to \r\n" + .ascii " g - jump to \r\n" + .asciz " use key to interrupt current command\r\n" +#endif /* CONFIG_NMON_HELP */ + + .align 2 +nmon_exit: + nmon_outs msg_nl + +#endif /* CONFIG_NMON */ + +.endm + +#endif /* __ASM_RISCV_NMON_H */ diff --git a/arch/riscv/include/asm/sections.h b/arch/riscv/include/asm/sections.h new file mode 100644 index 0000000..2b8c516 --- /dev/null +++ b/arch/riscv/include/asm/sections.h @@ -0,0 +1 @@ +#include diff --git a/arch/riscv/include/asm/string.h b/arch/riscv/include/asm/string.h new file mode 100644 index 0000000..2997587 --- /dev/null +++ b/arch/riscv/include/asm/string.h @@ -0,0 +1 @@ +/* dummy */ diff --git a/arch/riscv/include/asm/swab.h b/arch/riscv/include/asm/swab.h new file mode 100644 index 0000000..60a9012 --- /dev/null +++ b/arch/riscv/include/asm/swab.h @@ -0,0 +1,6 @@ +#ifndef _ASM_SWAB_H +#define _ASM_SWAB_H + +/* nothing. use generic functions */ + +#endif /* _ASM_SWAB_H */ diff --git a/arch/riscv/include/asm/types.h b/arch/riscv/include/asm/types.h new file mode 100644 index 0000000..ba386ab --- /dev/null +++ b/arch/riscv/include/asm/types.h @@ -0,0 +1,60 @@ +#ifndef __ASM_RISCV_TYPES_H +#define __ASM_RISCV_TYPES_H + +#ifdef __riscv64 +/* + * This is used in dlmalloc. On RISCV64 we need it to be 64 bit + */ +#define INTERNAL_SIZE_T unsigned long + +/* + * This is a Kconfig variable in the Kernel, but we want to detect + * this during compile time, so we set it here. + */ +#define CONFIG_PHYS_ADDR_T_64BIT + +#endif + +typedef unsigned short umode_t; + +/* + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space + */ + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +typedef __signed__ long long __s64; +typedef unsigned long long __u64; +#endif + +/* + * These aren't exported outside the kernel to avoid name space clashes + */ +#ifdef __KERNEL__ + +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed int s32; +typedef unsigned int u32; + +typedef signed long long s64; +typedef unsigned long long u64; + +#include + +#endif /* __KERNEL__ */ + +#endif /* __ASM_RISCV_TYPES_H */ diff --git a/arch/riscv/include/asm/unaligned.h b/arch/riscv/include/asm/unaligned.h new file mode 100644 index 0000000..aaebc06 --- /dev/null +++ b/arch/riscv/include/asm/unaligned.h @@ -0,0 +1,19 @@ +#ifndef _ASM_RISCV_UNALIGNED_H +#define _ASM_RISCV_UNALIGNED_H + +/* + * FIXME: this file is copy-n-pasted from sandbox's unaligned.h + */ + +#include +#include + +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define get_unaligned __get_unaligned_le +#define put_unaligned __put_unaligned_le +#else +#define get_unaligned __get_unaligned_be +#define put_unaligned __put_unaligned_be +#endif + +#endif /* _ASM_RISCV_UNALIGNED_H */ diff --git a/arch/riscv/lib/.gitignore b/arch/riscv/lib/.gitignore new file mode 100644 index 0000000..d116578 --- /dev/null +++ b/arch/riscv/lib/.gitignore @@ -0,0 +1 @@ +barebox.lds diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile new file mode 100644 index 0000000..a1df0b7 --- /dev/null +++ b/arch/riscv/lib/Makefile @@ -0,0 +1,3 @@ +extra-y += barebox.lds + +obj-y += riscv_timer.o diff --git a/arch/riscv/lib/asm-offsets.c b/arch/riscv/lib/asm-offsets.c new file mode 100644 index 0000000..22f382b --- /dev/null +++ b/arch/riscv/lib/asm-offsets.c @@ -0,0 +1,12 @@ +/* + * Generate definitions needed by assembly language modules. + * This code generates raw asm output which is post-processed to extract + * and format the required data. + */ + +#include + +int main(void) +{ + return 0; +} diff --git a/arch/riscv/lib/barebox.lds.S b/arch/riscv/lib/barebox.lds.S new file mode 100644 index 0000000..ffb97f4 --- /dev/null +++ b/arch/riscv/lib/barebox.lds.S @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2016 Antony Pavlov + * + * This file is part of barebox. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include + +OUTPUT_ARCH(riscv) +ENTRY(_start) +SECTIONS +{ + . = TEXT_BASE; + + . = ALIGN(8); + .text : + { + _stext = .; + _start = .; + KEEP(*(.text_entry*)) + _text = .; + *(.text*) + } + + . = ALIGN(8); + .rodata : { *(.rodata*) } + + _etext = .; /* End of text and rodata section */ + _sdata = .; + + . = ALIGN(8); + .data : { *(.data*) } + + .barebox_imd : { BAREBOX_IMD } + + . = ALIGN(8); + .got : { *(.got*) } + + . = .; + __barebox_cmd_start = .; + .barebox_cmd : { BAREBOX_CMDS } + __barebox_cmd_end = .; + + __barebox_magicvar_start = .; + .barebox_magicvar : { BAREBOX_MAGICVARS } + __barebox_magicvar_end = .; + + __barebox_initcalls_start = .; + .barebox_initcalls : { INITCALLS } + __barebox_initcalls_end = .; + + __barebox_exitcalls_start = .; + .barebox_exitcalls : { EXITCALLS } + __barebox_exitcalls_end = .; + + __usymtab_start = .; + __usymtab : { BAREBOX_SYMS } + __usymtab_end = .; + + .rela.dyn : { *(.rela*) } + + .oftables : { BAREBOX_CLK_TABLE() } + + .dtb : { BAREBOX_DTB() } + + _edata = .; + . = ALIGN(8); + __bss_start = .; + .bss : { *(.bss*) *(.sbss*) } + __bss_stop = .; + _end = .; +} diff --git a/arch/riscv/lib/riscv_timer.c b/arch/riscv/lib/riscv_timer.c new file mode 100644 index 0000000..919d77d --- /dev/null +++ b/arch/riscv/lib/riscv_timer.c @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2017 Antony Pavlov + * + * This file is part of barebox. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +/** + * @file + * @brief Clocksource based on RISC-V cycle CSR timer + */ + +#include +#include +#include +#include + +static uint64_t rdcycle_read(void) +{ + register unsigned long __v; + + __asm__ __volatile__ ("rdcycle %0" : "=r" (__v)); + + return __v; +} + +static struct clocksource rdcycle_cs = { + .read = rdcycle_read, + .mask = CLOCKSOURCE_MASK(32), +}; + +static int rdcycle_cs_init(void) +{ + unsigned int cycle_frequency; + + /* default rate: 100 MHz */ + cycle_frequency = 100000000; + + if (IS_ENABLED(CONFIG_OFTREE)) { + struct device_node *np; + struct clk *clk; + + np = of_get_cpu_node(0, NULL); + if (np) { + clk = of_clk_get(np, 0); + if (!IS_ERR(clk)) { + cycle_frequency = clk_get_rate(clk); + } + } + } + + clocks_calc_mult_shift(&rdcycle_cs.mult, &rdcycle_cs.shift, + cycle_frequency, NSEC_PER_SEC, 10); + + return init_clock(&rdcycle_cs); +} +postcore_initcall(rdcycle_cs_init); diff --git a/arch/riscv/mach-erizo/Kconfig b/arch/riscv/mach-erizo/Kconfig new file mode 100644 index 0000000..2400b44 --- /dev/null +++ b/arch/riscv/mach-erizo/Kconfig @@ -0,0 +1,11 @@ +if MACH_ERIZO + +choice + prompt "Board type" + +config BOARD_ERIZO_GENERIC + bool "erizo generic board" + +endchoice + +endif diff --git a/arch/riscv/mach-erizo/Makefile b/arch/riscv/mach-erizo/Makefile new file mode 100644 index 0000000..d9c51e7 --- /dev/null +++ b/arch/riscv/mach-erizo/Makefile @@ -0,0 +1,3 @@ +# just to build a built-in.o. Otherwise compilation fails when no o-files is +# created. +obj- += dummy.o diff --git a/arch/riscv/mach-erizo/include/mach/debug_ll.h b/arch/riscv/mach-erizo/include/mach/debug_ll.h new file mode 100644 index 0000000..a20acfc --- /dev/null +++ b/arch/riscv/mach-erizo/include/mach/debug_ll.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2017 Antony Pavlov + * + * This file is part of barebox. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __MACH_ERIZO_DEBUG_LL__ +#define __MACH_ERIZO_DEBUG_LL__ + +/** @file + * This File contains declaration for early output support + */ + +#include + +#define DEBUG_LL_UART_ADDR 0x90000000 +#define DEBUG_LL_UART_SHIFT 2 +#define DEBUG_LL_UART_IOSIZE32 + +#define DEBUG_LL_UART_CLK (24000000 / 16) +#define DEBUG_LL_UART_BPS CONFIG_BAUDRATE +#define DEBUG_LL_UART_DIVISOR (DEBUG_LL_UART_CLK / DEBUG_LL_UART_BPS) + +#include + +#endif /* __MACH_ERIZO_DEBUG_LL__ */ diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index a1fac0e..24cf446 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig @@ -4,7 +4,7 @@ config OFTREE_MEM_GENERIC depends on OFTREE - depends on PPC || ARM || EFI_BOOTUP || OPENRISC || SANDBOX + depends on PPC || ARM || EFI_BOOTUP || OPENRISC || SANDBOX || RISCV def_bool y config DTC diff --git a/scripts/erizo-nmon-image b/scripts/erizo-nmon-image new file mode 100755 index 0000000..b56fd36 --- /dev/null +++ b/scripts/erizo-nmon-image @@ -0,0 +1,10 @@ +#!/bin/sh + +if [ $# != 2 ]; then + echo "Usage:" + echo " erizo-nmon-image " + + exit 1 +fi + +hexdump -v -e '/4 "%08x\n"' $1 | perl -e '$a = 0x80000000; while (<>) { chop; printf("expect \"nmon> \"\n"); printf("send \"w%08x$_\"\n", $a); $a = $a + 4; }' > $2