[target][banana pi f3] quick n dirty port to the bananapi f3 board
A decent 8 core riscv64 board with dual ethernet and 2 or 4GB ram. Fairly easy to bring up on, though not a lot of docs at the moment.
This commit is contained in:
3
.github/workflows/github-ci.yml
vendored
3
.github/workflows/github-ci.yml
vendored
@@ -43,6 +43,7 @@ jobs:
|
|||||||
- pico-test
|
- pico-test
|
||||||
- sifive-e-test
|
- sifive-e-test
|
||||||
- visionfive2-test
|
- visionfive2-test
|
||||||
|
- bananapi-f3-test
|
||||||
- rosco-m68k-test
|
- rosco-m68k-test
|
||||||
exclude:
|
exclude:
|
||||||
# no real point building ubsan on the old compiler
|
# no real point building ubsan on the old compiler
|
||||||
@@ -63,6 +64,8 @@ jobs:
|
|||||||
toolchain-ver: 7.5.0
|
toolchain-ver: 7.5.0
|
||||||
- project: visionfive2-test
|
- project: visionfive2-test
|
||||||
toolchain-ver: 7.5.0
|
toolchain-ver: 7.5.0
|
||||||
|
- project: bananapi-f3-test
|
||||||
|
toolchain-ver: 7.5.0
|
||||||
|
|
||||||
env:
|
env:
|
||||||
PROJECT: ${{ matrix.project }}
|
PROJECT: ${{ matrix.project }}
|
||||||
|
|||||||
39
platform/spacemit-k1/include/platform/spacemit-k1.h
Normal file
39
platform/spacemit-k1/include/platform/spacemit-k1.h
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 Travis Geiselbrecht
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a MIT-style
|
||||||
|
* license that can be found in the LICENSE file or at
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// Taken from device tree from booted Linux system
|
||||||
|
|
||||||
|
// memory and irq layout of Spacemit-K1
|
||||||
|
#define MEMORY_BASE_PHYS (0)
|
||||||
|
// up to 16 GB of ram
|
||||||
|
#define MEMORY_APERTURE_SIZE (16ULL * 1024 * 1024 * 1024)
|
||||||
|
|
||||||
|
// map all of 0-2GB into kernel space in one shot
|
||||||
|
#define PERIPHERAL_BASE_PHYS (0x80000000UL)
|
||||||
|
#define PERIPHERAL_BASE_SIZE (0x80000000UL) // 2GB
|
||||||
|
|
||||||
|
// use the giant mapping at the bottom of the kernel as our peripheral space
|
||||||
|
#define PERIPHERAL_BASE_VIRT (KERNEL_ASPACE_BASE + PERIPHERAL_BASE_PHYS)
|
||||||
|
|
||||||
|
// interrupts
|
||||||
|
#define IRQ_VIRTIO_BASE 1
|
||||||
|
#define IRQ_UART0 0x2a
|
||||||
|
#define NUM_IRQS 0x9f
|
||||||
|
|
||||||
|
// addresses of some peripherals
|
||||||
|
#define CLINT_BASE 0xe4000000
|
||||||
|
#define CLINT_BASE_VIRT (PERIPHERAL_BASE_VIRT + CLINT_BASE - PERIPHERAL_BASE_PHYS)
|
||||||
|
#define PLIC_BASE 0xe0000000
|
||||||
|
#define PLIC_BASE_VIRT (PERIPHERAL_BASE_VIRT + PLIC_BASE - PERIPHERAL_BASE_PHYS)
|
||||||
|
#define UART0_BASE 0xd4017000
|
||||||
|
#define UART0_BASE_VIRT (PERIPHERAL_BASE_VIRT + UART0_BASE - PERIPHERAL_BASE_PHYS)
|
||||||
|
#define DRAM_BASE 0
|
||||||
|
#define DRAM_BASE_VIRT (PERIPHERAL_BASE_VIRT + DRAM_BASE - PERIPHERAL_BASE_PHYS)
|
||||||
|
#define DRAM_BASE2 0x10000000UL
|
||||||
|
#define DRAM_BASE2_VIRT (PERIPHERAL_BASE_VIRT + DRAM_BASE2 - PERIPHERAL_BASE_PHYS)
|
||||||
113
platform/spacemit-k1/platform.c
Normal file
113
platform/spacemit-k1/platform.c
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018 Travis Geiselbrecht
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a MIT-style
|
||||||
|
* license that can be found in the LICENSE file or at
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
#include "config.h"
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <lk/err.h>
|
||||||
|
#include <lk/main.h>
|
||||||
|
#include <lk/reg.h>
|
||||||
|
#include <lk/trace.h>
|
||||||
|
#include <kernel/thread.h>
|
||||||
|
#include <platform.h>
|
||||||
|
#include <platform/interrupts.h>
|
||||||
|
#include <platform/debug.h>
|
||||||
|
#include <platform/timer.h>
|
||||||
|
#include <platform/spacemit-k1.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <lib/fdtwalk.h>
|
||||||
|
#include <dev/interrupt/riscv_plic.h>
|
||||||
|
#if WITH_LIB_MINIP
|
||||||
|
#include <lib/minip.h>
|
||||||
|
#endif
|
||||||
|
#include <kernel/vm.h>
|
||||||
|
#if WITH_LIB_CONSOLE
|
||||||
|
#include <lib/console.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "platform_p.h"
|
||||||
|
|
||||||
|
#define LOCAL_TRACE 0
|
||||||
|
|
||||||
|
static const void *fdt;
|
||||||
|
|
||||||
|
void platform_early_init(void) {
|
||||||
|
TRACE;
|
||||||
|
plic_early_init(PLIC_BASE_VIRT, NUM_IRQS, false);
|
||||||
|
|
||||||
|
LTRACEF("starting FDT scan\n");
|
||||||
|
|
||||||
|
/* look for a flattened device tree in the second arg passed to us */
|
||||||
|
fdt = (void *)lk_boot_args[1];
|
||||||
|
fdt = (const void *)((uintptr_t)fdt + KERNEL_ASPACE_BASE);
|
||||||
|
|
||||||
|
if (LOCAL_TRACE) {
|
||||||
|
LTRACEF("dumping FDT at %p\n", fdt);
|
||||||
|
fdt_walk_dump(fdt);
|
||||||
|
}
|
||||||
|
|
||||||
|
// detect physical memory layout from the device tree
|
||||||
|
fdtwalk_setup_memory(fdt, lk_boot_args[1], MEMORY_BASE_PHYS, MEMSIZE);
|
||||||
|
|
||||||
|
// detect secondary cores to start
|
||||||
|
fdtwalk_setup_cpus_riscv(fdt);
|
||||||
|
|
||||||
|
LTRACEF("done scanning FDT\n");
|
||||||
|
|
||||||
|
// disable the watchdog
|
||||||
|
mmio_write32((volatile uint32_t *)paddr_to_kvaddr(0xd40800b0), 0xbaba);
|
||||||
|
mmio_write32((volatile uint32_t *)paddr_to_kvaddr(0xd40800b4), 0xeb10);
|
||||||
|
mmio_write32((volatile uint32_t *)paddr_to_kvaddr(0xd40800b8), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void platform_init(void) {
|
||||||
|
plic_init();
|
||||||
|
uart_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void platform_halt(platform_halt_action suggested_action,
|
||||||
|
platform_halt_reason reason) {
|
||||||
|
switch (suggested_action) {
|
||||||
|
case HALT_ACTION_SHUTDOWN:
|
||||||
|
dprintf(ALWAYS, "Shutting down... (reason = %d)\n", reason);
|
||||||
|
// try to use SBI as a cleaner way to stop
|
||||||
|
sbi_system_reset(SBI_RESET_TYPE_SHUTDOWN, SBI_RESET_REASON_NONE);
|
||||||
|
break;
|
||||||
|
case HALT_ACTION_REBOOT:
|
||||||
|
dprintf(ALWAYS, "Rebooting... (reason = %d)\n", reason);
|
||||||
|
sbi_system_reset(SBI_RESET_TYPE_WARM_REBOOT, SBI_RESET_REASON_NONE);
|
||||||
|
break;
|
||||||
|
case HALT_ACTION_HALT:
|
||||||
|
#if ENABLE_PANIC_SHELL
|
||||||
|
if (reason == HALT_REASON_SW_PANIC) {
|
||||||
|
dprintf(ALWAYS, "CRASH: starting debug shell... (reason = %d)\n", reason);
|
||||||
|
arch_disable_ints();
|
||||||
|
panic_shell_start();
|
||||||
|
}
|
||||||
|
#endif // ENABLE_PANIC_SHELL
|
||||||
|
dprintf(ALWAYS, "HALT: spinning forever... (reason = %d)\n", reason);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
arch_disable_ints();
|
||||||
|
for (;;)
|
||||||
|
arch_idle();
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t platform_pci_int_to_vector(unsigned int pci_int, unsigned int *vector) {
|
||||||
|
// at the moment there's no translation between PCI IRQs and native irqs
|
||||||
|
*vector = pci_int;
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t platform_allocate_interrupts(size_t count, uint align_log2, bool msi, unsigned int *vector) {
|
||||||
|
return ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t platform_compute_msi_values(unsigned int vector, unsigned int cpu, bool edge,
|
||||||
|
uint64_t *msi_address_out, uint16_t *msi_data_out) {
|
||||||
|
return ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
14
platform/spacemit-k1/platform_p.h
Normal file
14
platform/spacemit-k1/platform_p.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018 Travis Geiselbrecht
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a MIT-style
|
||||||
|
* license that can be found in the LICENSE file or at
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
void uart_init(void);
|
||||||
|
|
||||||
|
|
||||||
36
platform/spacemit-k1/rules.mk
Normal file
36
platform/spacemit-k1/rules.mk
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
LOCAL_DIR := $(GET_LOCAL_DIR)
|
||||||
|
|
||||||
|
MODULE := $(LOCAL_DIR)
|
||||||
|
|
||||||
|
ARCH := riscv
|
||||||
|
SUBARCH := 64
|
||||||
|
RISCV_MODE := supervisor
|
||||||
|
WITH_SMP ?= true
|
||||||
|
SMP_MAX_CPUS ?= 8
|
||||||
|
LK_HEAP_IMPLEMENTATION ?= dlmalloc
|
||||||
|
RISCV_FPU := true
|
||||||
|
RISCV_MMU := sv39
|
||||||
|
RISCV_EXTENSION_LIST ?= zba zbb zbc zbs
|
||||||
|
|
||||||
|
MODULE_DEPS += lib/cbuf
|
||||||
|
MODULE_DEPS += lib/fdt
|
||||||
|
MODULE_DEPS += lib/fdtwalk
|
||||||
|
MODULE_DEPS += dev/interrupt/riscv_plic
|
||||||
|
|
||||||
|
MODULE_SRCS += $(LOCAL_DIR)/platform.c
|
||||||
|
MODULE_SRCS += $(LOCAL_DIR)/uart.c
|
||||||
|
|
||||||
|
MEMBASE ?= 0
|
||||||
|
MEMSIZE ?= 0x80000000 # default to 2GB
|
||||||
|
ifeq ($(RISCV_MODE),supervisor)
|
||||||
|
# offset the kernel to account for OpenSBI using the bottom
|
||||||
|
KERNEL_LOAD_OFFSET ?= 0x10200000 # kernel load offset
|
||||||
|
endif
|
||||||
|
|
||||||
|
# we can revert to a poll based uart spin routine
|
||||||
|
GLOBAL_DEFINES += PLATFORM_SUPPORTS_PANIC_SHELL=1
|
||||||
|
|
||||||
|
# do not need to implement any cache ops
|
||||||
|
GLOBAL_DEFINES += RISCV_NO_CACHE_OPS=1
|
||||||
|
|
||||||
|
include make/module.mk
|
||||||
92
platform/spacemit-k1/uart.c
Normal file
92
platform/spacemit-k1/uart.c
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018 Travis Geiselbrecht
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a MIT-style
|
||||||
|
* license that can be found in the LICENSE file or at
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
#include <lk/reg.h>
|
||||||
|
#include <lk/trace.h>
|
||||||
|
#include <lib/cbuf.h>
|
||||||
|
#include <kernel/thread.h>
|
||||||
|
#include <platform.h>
|
||||||
|
#include <platform/interrupts.h>
|
||||||
|
#include <platform/debug.h>
|
||||||
|
#include <platform/spacemit-k1.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include "platform_p.h"
|
||||||
|
|
||||||
|
// simple 16550 driver for the emulated serial port on jh7110
|
||||||
|
// uart registers are 4 byte separated
|
||||||
|
|
||||||
|
static volatile uint8_t *const uart_base = (uint8_t *)UART0_BASE_VIRT;
|
||||||
|
|
||||||
|
#define RXBUF_SIZE 128
|
||||||
|
static char uart_rx_buf_data[RXBUF_SIZE];
|
||||||
|
static cbuf_t uart_rx_buf;
|
||||||
|
|
||||||
|
static inline uint8_t uart_read_8(size_t offset) {
|
||||||
|
return uart_base[offset * 4];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void uart_write_8(size_t offset, uint8_t val) {
|
||||||
|
uart_base[offset * 4] = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum handler_return uart_irq_handler(void *arg) {
|
||||||
|
unsigned char c;
|
||||||
|
bool resched = false;
|
||||||
|
|
||||||
|
while (uart_read_8(5) & (1<<0)) {
|
||||||
|
c = uart_read_8(0);
|
||||||
|
cbuf_write_char(&uart_rx_buf, c, false);
|
||||||
|
resched = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return resched ? INT_RESCHEDULE : INT_NO_RESCHEDULE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void uart_init(void) {
|
||||||
|
/* finish uart init to get rx going */
|
||||||
|
cbuf_initialize_etc(&uart_rx_buf, RXBUF_SIZE, uart_rx_buf_data);
|
||||||
|
|
||||||
|
register_int_handler(IRQ_UART0, uart_irq_handler, NULL);
|
||||||
|
|
||||||
|
uart_write_8(1, (1<<6) | 0x1); // enable receive data available interrupt
|
||||||
|
uart_write_8(4, (1<<3)); // set OUT2, enabling IRQs to reach the cpu
|
||||||
|
|
||||||
|
unmask_interrupt(IRQ_UART0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void uart_putc(char c) {
|
||||||
|
while ((uart_read_8(5) & (1<<6)) == 0)
|
||||||
|
;
|
||||||
|
uart_write_8(0, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int uart_getc(char *c, bool wait) {
|
||||||
|
return cbuf_read_char(&uart_rx_buf, c, wait);
|
||||||
|
}
|
||||||
|
|
||||||
|
void platform_dputc(char c) {
|
||||||
|
if (c == '\n')
|
||||||
|
platform_dputc('\r');
|
||||||
|
uart_putc(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
int platform_dgetc(char *c, bool wait) {
|
||||||
|
int ret = uart_getc(c, wait);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* panic-time getc/putc */
|
||||||
|
int platform_pgetc(char *c, bool wait) {
|
||||||
|
if (uart_read_8(5) & (1<<0)) {
|
||||||
|
*c = uart_read_8(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
7
project/bananapi-f3-test.mk
Normal file
7
project/bananapi-f3-test.mk
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# main project for banana pi f3 test project
|
||||||
|
MODULES += \
|
||||||
|
app/shell
|
||||||
|
|
||||||
|
include project/virtual/test.mk
|
||||||
|
include project/target/bananapi-f3.mk
|
||||||
|
|
||||||
2
project/target/bananapi-f3.mk
Normal file
2
project/target/bananapi-f3.mk
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
TARGET := bananapi-f3
|
||||||
|
|
||||||
34
scripts/do-bananapi-f3
Executable file
34
scripts/do-bananapi-f3
Executable file
@@ -0,0 +1,34 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Quick script to build and copy the kernel to the tftp server.
|
||||||
|
# Modify the TFTPHOST variable to match your setup.
|
||||||
|
# Alternatively change the scp to a cp to copy the kernel to the SD card.
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
export PROJECT=bananapi-f3-test
|
||||||
|
BUILDDIR="build-${PROJECT}"
|
||||||
|
|
||||||
|
RAMDISK="${BUILDDIR}/ramdisk.img"
|
||||||
|
OUTPUT="${BUILDDIR}/lk.img"
|
||||||
|
|
||||||
|
TFTPHOST=192.168.0.4
|
||||||
|
|
||||||
|
set -x
|
||||||
|
|
||||||
|
./scripts/make-parallel
|
||||||
|
|
||||||
|
# create a small ramdisk to satisfy the mkimage tool
|
||||||
|
truncate -s 4 ${BUILDDIR}/ramdisk.img
|
||||||
|
|
||||||
|
# build a uboot uimage containing the lk binary, the ramdisk and the device tree
|
||||||
|
mkimage -A riscv -O linux -T multi -C none -a 0x10200000 -e 0x10200000 -n LK -d ${BUILDDIR}/lk.bin:${RAMDISK}:target/bananapi-f3/bananapi-f3.dtb ${OUTPUT}
|
||||||
|
|
||||||
|
# copy to a local tftp server, replace with cp if a using a local directory
|
||||||
|
scp ${BUILDDIR}/lk.img ${TFTPHOST}:/tftpboot
|
||||||
|
|
||||||
|
set +x
|
||||||
|
|
||||||
|
echo boot with
|
||||||
|
echo dhcp\; tftpboot ${TFTPHOST}:lk.img\; bootm
|
||||||
|
exit 1
|
||||||
5
target/bananapi-f3/README.md
Normal file
5
target/bananapi-f3/README.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# Banana Pi F3
|
||||||
|
|
||||||
|
A port to the Banana Pi F3 board.
|
||||||
|
|
||||||
|
See links at https://wiki.banana-pi.org/Banana_Pi_BPI-F3 and https://docs.banana-pi.org/en/BPI-F3/BananaPi_BPI-F3
|
||||||
BIN
target/bananapi-f3/bananapi-f3.dtb
Normal file
BIN
target/bananapi-f3/bananapi-f3.dtb
Normal file
Binary file not shown.
3982
target/bananapi-f3/bananapi-f3.dts
Normal file
3982
target/bananapi-f3/bananapi-f3.dts
Normal file
File diff suppressed because it is too large
Load Diff
10
target/bananapi-f3/rules.mk
Normal file
10
target/bananapi-f3/rules.mk
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
LOCAL_DIR := $(GET_LOCAL_DIR)
|
||||||
|
|
||||||
|
MODULE := $(LOCAL_DIR)
|
||||||
|
|
||||||
|
PLATFORM := spacemit-k1
|
||||||
|
|
||||||
|
MEMSIZE ?= 0x80000000 # 2GB smallest configuration
|
||||||
|
|
||||||
|
# set time base
|
||||||
|
GLOBAL_DEFINES += ARCH_RISCV_MTIME_RATE=24000000
|
||||||
Reference in New Issue
Block a user