[vim2] Initial support for Khadas VIM2 boards

This commit is contained in:
Payam
2018-03-13 16:49:18 -07:00
committed by Travis Geiselbrecht
parent 5dea3e1933
commit 6e05388579
10 changed files with 476 additions and 0 deletions

View File

@@ -234,6 +234,36 @@ static int arm_gic_max_cpu(void)
return (GICREG(0, GICD_TYPER) >> 5) & 0x7;
}
static status_t gic_configure_interrupt(unsigned int vector,
enum interrupt_trigger_mode tm,
enum interrupt_polarity pol)
{
//Only configurable for SPI interrupts
if ((vector >= MAX_INT) || (vector < GIC_BASE_SPI)) {
return ERR_INVALID_ARGS;
}
if (pol != IRQ_POLARITY_ACTIVE_HIGH) {
// TODO: polarity should actually be configure through a GPIO controller
return ERR_NOT_SUPPORTED;
}
// type is encoded with two bits, MSB of the two determine type
// 16 irqs encoded per ICFGR register
uint32_t reg_ndx = vector >> 4;
uint32_t bit_shift = ((vector & 0xf) << 1) + 1;
uint32_t reg_val = GICREG(0, GICD_ICFGR(reg_ndx));
if (tm == IRQ_TRIGGER_MODE_EDGE) {
reg_val |= (1 << bit_shift);
}
else {
reg_val &= ~(1 << bit_shift);
}
GICREG(0, GICD_ICFGR(reg_ndx)) = reg_val;
return NO_ERROR;
}
void arm_gic_init(void)
{
int i;
@@ -250,6 +280,12 @@ void arm_gic_init(void)
}
}
// Initialize all the SPIs to edge triggered
for (i = 32; i < MAX_INT; i++) {
gic_configure_interrupt(i, IRQ_TRIGGER_MODE_EDGE, IRQ_POLARITY_ACTIVE_HIGH);
}
GICREG(0, GICD_CTLR) = 1; // enable GIC0
#if WITH_LIB_SM
GICREG(0, GICD_CTLR) = 3; // enable GIC0 ns interrupts

View File

@@ -27,6 +27,20 @@
void arm_gic_init(void);
#define GIC_BASE_SGI 0
#define GIC_BASE_PPI 16
#define GIC_BASE_SPI 32
enum interrupt_trigger_mode {
IRQ_TRIGGER_MODE_EDGE = 0,
IRQ_TRIGGER_MODE_LEVEL = 1,
};
enum interrupt_polarity {
IRQ_POLARITY_ACTIVE_HIGH = 0,
IRQ_POLARITY_ACTIVE_LOW = 1,
};
enum {
/* Ignore cpu_mask and forward interrupt to all CPUs other than the current cpu */
ARM_GIC_SGI_FLAG_TARGET_FILTER_NOT_SENDER = 0x1,

View File

@@ -0,0 +1,32 @@
/*
* Copyright (c) 2018 The Fuchsia Authors
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#pragma once
#include <platform/s912d.h>
#define GICBASE(n) (GIC_BASE)
#define GICD_OFFSET (0x1000)
#define GICC_OFFSET (0x2000)
#define MAX_INT 255

View File

@@ -0,0 +1,35 @@
/*
* Copyright (c) 2018 The Fuchsia Authors
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#pragma once
#define SDRAM_BASE (0x0U)
#define AML_S912D_PERIPH_BASE_PHYS (0xC0000000U)
#define AML_S912D_PERIPH_BASE_SIZE (0x20000000U)
#define AML_S912D_PERIPH_BASE_VIRT (0xFFFFFFFFC0000000ULL)
#define UART0_AO_BASE (AML_S912D_PERIPH_BASE_VIRT + 0x81004c0)
#define GIC_BASE (AML_S912D_PERIPH_BASE_VIRT + 0x4300000)
#define UART0_IRQ 225

View File

@@ -0,0 +1,111 @@
/*
* Copyright (c) 2018 The Fuchsia Authors
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <arch/arm64.h>
#include <trace.h>
#include <assert.h>
#include <err.h>
#include <bits.h>
#include <kernel/spinlock.h>
#include <kernel/thread.h>
#include <kernel/mp.h>
#include <platform/interrupts.h>
#include <lk/init.h>
#include <kernel/vm.h>
#include <kernel/spinlock.h>
#include <dev/timer/arm_generic.h>
#include <platform.h>
#include <dev/interrupt/arm_gic.h>
#include <dev/timer/arm_generic.h>
#include <platform/s912d.h>
#include <dev/uart.h>
typedef struct arm64_iframe_long arm_platform_iframe_t;
/* initial memory mappings. parsed by start.S */
struct mmu_initial_mapping mmu_initial_mappings[] = {
{
.phys = SDRAM_BASE,
.virt = KERNEL_BASE,
.size = MEMSIZE,
.flags = 0,
.name = "memory"
},
/* peripherals */
{
.phys = AML_S912D_PERIPH_BASE_PHYS,
.virt = AML_S912D_PERIPH_BASE_VIRT,
.size = AML_S912D_PERIPH_BASE_SIZE,
.flags = MMU_INITIAL_MAPPING_FLAG_DEVICE,
.name = "peripherals"
},
/* null entry to terminate the list */
{ 0 }
};
static pmm_arena_t arena = {
.name = "sdram",
.base = SDRAM_BASE,
.size = MEMSIZE,
.flags = PMM_ARENA_FLAG_KMAP,
};
#define DEBUG_UART 0
void platform_dputc(char c)
{
if (c == '\n')
uart_putc(DEBUG_UART, '\r');
uart_putc(DEBUG_UART, c);
}
int platform_dgetc(char *c, bool wait)
{
int ret = uart_getc(DEBUG_UART, wait);
if (ret == -1)
return -1;
*c = ret;
return 0;
}
void platform_init(void)
{
uart_init();
}
void platform_early_init(void)
{
uart_init_early();
/* initialize the interrupt controller */
arm_gic_init();
arm_generic_timer_init(30, 0);
pmm_add_arena(&arena);
// TODO: Reserve memory regions if needed
}

View File

@@ -0,0 +1,31 @@
LOCAL_DIR := $(GET_LOCAL_DIR)
MODULE := $(LOCAL_DIR)
MODULE_DEPS += \
lib/cbuf \
lib/fdt \
dev/interrupt/arm_gic \
dev/timer/arm_generic \
MODULE_SRCS += \
$(LOCAL_DIR)/platform.c \
$(LOCAL_DIR)/uart.c \
ARCH := arm64
ARM_CPU := cortex-a53
MEMBASE := 0
MEMSIZE := 0x80000000 # 2GB
KERNEL_LOAD_OFFSET := 0x01080000
LINKER_SCRIPT += \
$(BUILDDIR)/system-onesegment.ld
MODULE := $(LOCAL_DIR)
MODULE_DEPS += \
app/shell \
WITH_CPP_SUPPORT=true
include make/module.mk

View File

@@ -0,0 +1,180 @@
/*
* Copyright (c) 2018 The Fuchsia Authors
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <reg.h>
#include <stdio.h>
#include <trace.h>
#include <lib/cbuf.h>
#include <kernel/thread.h>
#include <platform/interrupts.h>
#include <platform/s912d.h>
#include <dev/uart.h>
#define S912D_UART_WFIFO (0x00)
#define S912D_UART_RFIFO (0x04)
#define S912D_UART_CONTROL (0x08)
#define S912D_UART_STATUS (0x0C)
#define S912D_UART_IRQ_CONTROL (0x10)
#define S912D_UART_REG5 (0x14)
#define S912D_UART_CONTROL_INVRTS (1 << 31)
#define S912D_UART_CONTROL_MASKERR (1 << 30)
#define S912D_UART_CONTROL_INVCTS (1 << 29)
#define S912D_UART_CONTROL_TXINTEN (1 << 28)
#define S912D_UART_CONTROL_RXINTEN (1 << 27)
#define S912D_UART_CONTROL_INVTX (1 << 26)
#define S912D_UART_CONTROL_INVRX (1 << 25)
#define S912D_UART_CONTROL_CLRERR (1 << 24)
#define S912D_UART_CONTROL_RSTRX (1 << 23)
#define S912D_UART_CONTROL_RSTTX (1 << 22)
#define S912D_UART_CONTROL_XMITLEN (1 << 20)
#define S912D_UART_CONTROL_XMITLEN_MASK (0x3 << 20)
#define S912D_UART_CONTROL_PAREN (1 << 19)
#define S912D_UART_CONTROL_PARTYPE (1 << 18)
#define S912D_UART_CONTROL_STOPLEN (1 << 16)
#define S912D_UART_CONTROL_STOPLEN_MASK (0x3 << 16)
#define S912D_UART_CONTROL_TWOWIRE (1 << 15)
#define S912D_UART_CONTROL_RXEN (1 << 13)
#define S912D_UART_CONTROL_TXEN (1 << 12)
#define S912D_UART_CONTROL_BAUD0 (1 << 0)
#define S912D_UART_CONTROL_BAUD0_MASK (0xfff << 0)
#define S912D_UART_STATUS_RXBUSY (1 << 26)
#define S912D_UART_STATUS_TXBUSY (1 << 25)
#define S912D_UART_STATUS_RXOVRFLW (1 << 24)
#define S912D_UART_STATUS_CTSLEVEL (1 << 23)
#define S912D_UART_STATUS_TXEMPTY (1 << 22)
#define S912D_UART_STATUS_TXFULL (1 << 21)
#define S912D_UART_STATUS_RXEMPTY (1 << 20)
#define S912D_UART_STATUS_RXFULL (1 << 19)
#define S912D_UART_STATUS_TXOVRFLW (1 << 18)
#define S912D_UART_STATUS_FRAMEERR (1 << 17)
#define S912D_UART_STATUS_PARERR (1 << 16)
#define S912D_UART_STATUS_TXCOUNT_POS (8)
#define S912D_UART_STATUS_TXCOUNT_MASK (0x7f << S912D_UART_STATUS_TXCOUNT_POS)
#define S912D_UART_STATUS_RXCOUNT_POS (0)
#define S912D_UART_STATUS_RXCOUNT_MASK (0x7f << S912D_UART_STATUS_RXCOUNT_POS)
#define UARTREG(base, reg) (*(volatile uint32_t*)((base) + (reg)))
#define RXBUF_SIZE 16
#define NUM_UART 1
static cbuf_t uart_rx_buf;
static uintptr_t uart_base = 0;
static uint32_t uart_irq = 0;
int uart_putc(int port, char c)
{
while (UARTREG(uart_base, S912D_UART_STATUS) & S912D_UART_STATUS_TXFULL)
;
UARTREG(uart_base, S912D_UART_WFIFO) = c;
return 0;
}
int uart_getc(int port, bool wait)
{
char c;
if (cbuf_read_char(&uart_rx_buf, &c, wait) == 1) {
return c;
}
else {
return -1;
}
}
void uart_irq_handler(void)
{
while ( (UARTREG(uart_base, S912D_UART_STATUS) & S912D_UART_STATUS_RXCOUNT_MASK) > 0 ) {
if (cbuf_space_avail(&uart_rx_buf) == 0) {
break;
}
char c = UARTREG(uart_base, S912D_UART_RFIFO);
cbuf_write_char(&uart_rx_buf, c,false);
}
}
void uart_init_early(void)
{
uart_base = UART0_AO_BASE;
uart_irq = UART0_IRQ;
// reset port
UARTREG(uart_base,S912D_UART_CONTROL) |= S912D_UART_CONTROL_RSTRX |
S912D_UART_CONTROL_RSTTX |
S912D_UART_CONTROL_CLRERR;
UARTREG(uart_base,S912D_UART_CONTROL) &= ~(S912D_UART_CONTROL_RSTRX |
S912D_UART_CONTROL_RSTTX |
S912D_UART_CONTROL_CLRERR);
// enable rx and tx
UARTREG(uart_base,S912D_UART_CONTROL) |= S912D_UART_CONTROL_TXEN |
S912D_UART_CONTROL_RXEN;
UARTREG(uart_base,S912D_UART_CONTROL) |= S912D_UART_CONTROL_INVRTS |
S912D_UART_CONTROL_RXINTEN |
S912D_UART_CONTROL_TWOWIRE;
}
void uart_init(void)
{
uart_base = UART0_AO_BASE;
uart_irq = UART0_IRQ;
// create a circular buufer to hold rx data
cbuf_initialize(&uart_rx_buf, RXBUF_SIZE);
// register uart irq
register_int_handler(uart_irq, &uart_irq_handler, NULL);
// reset port
UARTREG(uart_base,S912D_UART_CONTROL) |= S912D_UART_CONTROL_RSTRX |
S912D_UART_CONTROL_RSTTX |
S912D_UART_CONTROL_CLRERR;
UARTREG(uart_base,S912D_UART_CONTROL) &= ~(S912D_UART_CONTROL_RSTRX |
S912D_UART_CONTROL_RSTTX |
S912D_UART_CONTROL_CLRERR);
// enable rx and tx
UARTREG(uart_base,S912D_UART_CONTROL) |= S912D_UART_CONTROL_TXEN |
S912D_UART_CONTROL_RXEN;
UARTREG(uart_base,S912D_UART_CONTROL) |= S912D_UART_CONTROL_INVRTS |
S912D_UART_CONTROL_RXINTEN |
S912D_UART_CONTROL_TWOWIRE;
// Set to interrupt every 1 rx byte
uint32_t temp2 = UARTREG(uart_base,S912D_UART_IRQ_CONTROL);
temp2 &= 0xffff0000;
temp2 |= (1 << 8) | ( 1 );
UARTREG(uart_base,S912D_UART_IRQ_CONTROL) = temp2;
// TODO: Look into adding baud rate support
// enable interrupts
unmask_interrupt(uart_irq);
}

12
project/vim2-test.mk Normal file
View File

@@ -0,0 +1,12 @@
# main project for vim2
LOCAL_DIR := $(GET_LOCAL_DIR)
TARGET := vim2
MODULES += \
app/shell \
app/stringtests \
app/tests \
lib/cksum \
lib/debugcommands \

16
target/vim2/README Normal file
View File

@@ -0,0 +1,16 @@
Notes on the KHADAS VIM2 Board
-------------------------------
http://docs.khadas.com/
Run LK on VIM2
---------------
Below commands assume the VIM2 board is able to boot into U-Boot.
- Copy lk.bin from build-vim2-test to a USB flash drive
- Connect the USB flash drive to VIM2 USB-A port
- Boot VIM2 and press enter or space to stop autoboot
- Run the following commands from U-Boot prompt:
usb start; fatload usb 0 0x01080000 lk.bin; go 0x01080000

9
target/vim2/rules.mk Normal file
View File

@@ -0,0 +1,9 @@
LOCAL_DIR := $(GET_LOCAL_DIR)
GLOBAL_INCLUDES += \
$(LOCAL_DIR)/include
PLATFORM := amlogic-s912d
#include make/module.mk