Skip to content

Commit

Permalink
[target][banana pi f3] quick n dirty port to the bananapi f3 board
Browse files Browse the repository at this point in the history
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.

TODO:
-pet or stop the hw watchdog (resets after 60 seconds)
-add script to run mkimage and wehatnot to the target dir
  • Loading branch information
travisg committed Jun 17, 2024
1 parent e3a5f9c commit f7438e5
Show file tree
Hide file tree
Showing 10 changed files with 4,314 additions and 0 deletions.
39 changes: 39 additions & 0 deletions platform/spacemit-k1/include/platform/spacemit-k1.h
Original file line number Diff line number Diff line change
@@ -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)
130 changes: 130 additions & 0 deletions platform/spacemit-k1/platform.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/*
* 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/bus/pci.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;
static volatile uint32_t *power_reset_reg;

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");

/* save a copy of the pointer to the poweroff/reset register */
/* TODO: read it from the FDT */
power_reset_reg = paddr_to_kvaddr(0x100000);
}

void platform_init(void) {
plic_init();
uart_init();

// TODO: fix this, seems to read all zeros from the ecam
#if 0
/* configure and start pci from device tree */
status_t err = fdtwalk_setup_pci(fdt);
if (err >= NO_ERROR) {
// start the bus manager
pci_bus_mgr_init();

// assign resources to all devices in case they need it
pci_bus_mgr_assign_resources();
}
#endif

}

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);
*power_reset_reg = 0x5555;
break;
case HALT_ACTION_REBOOT:
dprintf(ALWAYS, "Rebooting... (reason = %d)\n", reason);
sbi_system_reset(SBI_RESET_TYPE_WARM_REBOOT, SBI_RESET_REASON_NONE);
*power_reset_reg = 0x7777;
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 changes: 14 additions & 0 deletions platform/spacemit-k1/platform_p.h
Original file line number Diff line number Diff line change
@@ -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);


38 changes: 38 additions & 0 deletions platform/spacemit-k1/rules.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
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

MODULE_DEPS += lib/cbuf
MODULE_DEPS += lib/fdt
MODULE_DEPS += lib/fdtwalk
MODULE_DEPS += dev/interrupt/riscv_plic
MODULE_DEPS += dev/bus/pci
MODULE_DEPS += dev/bus/pci/drivers

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 changes: 92 additions & 0 deletions platform/spacemit-k1/uart.c
Original file line number Diff line number Diff line change
@@ -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 changes: 7 additions & 0 deletions project/bananapi-f3-test.mk
Original file line number Diff line number Diff line change
@@ -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 changes: 2 additions & 0 deletions project/target/bananapi-f3.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
TARGET := bananapi-f3

Binary file added target/bananapi-f3/bananapi-f3.dtb
Binary file not shown.
Loading

0 comments on commit f7438e5

Please sign in to comment.