[arm64][odroidc2] OdroidC2 support

Change-Id: If817e84390a3f72bca35473db949cb92cfdec6c8
Esse commit está contido em:
Eric Holland
2017-06-30 12:06:50 -07:00
commit 995a8f28bd
12 arquivos alterados com 581 adições e 0 exclusões
+18
Ver Arquivo
@@ -0,0 +1,18 @@
# Copyright 2017 The Fuchsia Authors
# 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
LOCAL_DIR := $(GET_LOCAL_DIR)
MODULE := $(LOCAL_DIR)
MODULE_SRCS += \
$(LOCAL_DIR)/uart.c
MODULE_DEPS += \
kernel/dev/pdev \
kernel/dev/pdev/uart \
kernel/lib/mdi \
include make/module.mk
+232
Ver Arquivo
@@ -0,0 +1,232 @@
// Copyright 2017 The Fuchsia Authors
//
// 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 <reg.h>
#include <stdio.h>
#include <trace.h>
#include <string.h>
#include <lib/cbuf.h>
#include <kernel/thread.h>
#include <dev/interrupt.h>
#include <dev/uart.h>
#include <mdi/mdi.h>
#include <mdi/mdi-defs.h>
#include <pdev/driver.h>
#include <pdev/uart.h>
#define S905_UART_WFIFO (0x0)
#define S905_UART_RFIFO (0x4)
#define S905_UART_CONTROL (0x8)
#define S905_UART_STATUS (0xc)
#define S905_UART_IRQ_CONTROL (0x10)
#define S905_UART_REG5 (0x14)
#define S905_UART_CONTROL_INVRTS (1 << 31)
#define S905_UART_CONTROL_MASKERR (1 << 30)
#define S905_UART_CONTROL_INVCTS (1 << 29)
#define S905_UART_CONTROL_TXINTEN (1 << 28)
#define S905_UART_CONTROL_RXINTEN (1 << 27)
#define S905_UART_CONTROL_INVTX (1 << 26)
#define S905_UART_CONTROL_INVRX (1 << 25)
#define S905_UART_CONTROL_CLRERR (1 << 24)
#define S905_UART_CONTROL_RSTRX (1 << 23)
#define S905_UART_CONTROL_RSTTX (1 << 22)
#define S905_UART_CONTROL_XMITLEN (1 << 20)
#define S905_UART_CONTROL_XMITLEN_MASK (0x3 << 20)
#define S905_UART_CONTROL_PAREN (1 << 19)
#define S905_UART_CONTROL_PARTYPE (1 << 18)
#define S905_UART_CONTROL_STOPLEN (1 << 16)
#define S905_UART_CONTROL_STOPLEN_MASK (0x3 << 16)
#define S905_UART_CONTROL_TWOWIRE (1 << 15)
#define S905_UART_CONTROL_RXEN (1 << 13)
#define S905_UART_CONTROL_TXEN (1 << 12)
#define S905_UART_CONTROL_BAUD0 (1 << 0)
#define S905_UART_CONTROL_BAUD0_MASK (0xfff << 0)
#define S905_UART_STATUS_RXBUSY (1 << 26)
#define S905_UART_STATUS_TXBUSY (1 << 25)
#define S905_UART_STATUS_RXOVRFLW (1 << 24)
#define S905_UART_STATUS_CTSLEVEL (1 << 23)
#define S905_UART_STATUS_TXEMPTY (1 << 22)
#define S905_UART_STATUS_TXFULL (1 << 21)
#define S905_UART_STATUS_RXEMPTY (1 << 20)
#define S905_UART_STATUS_RXFULL (1 << 19)
#define S905_UART_STATUS_TXOVRFLW (1 << 18)
#define S905_UART_STATUS_FRAMEERR (1 << 17)
#define S905_UART_STATUS_PARERR (1 << 16)
#define S905_UART_STATUS_TXCOUNT_POS (8)
#define S905_UART_STATUS_TXCOUNT_MASK (0x7f << S905_UART_STATUS_TXCOUNT_POS)
#define S905_UART_STATUS_RXCOUNT_POS (0)
#define S905_UART_STATUS_RXCOUNT_MASK (0x7f << S905_UART_STATUS_RXCOUNT_POS)
#define UARTREG(base, reg) (*(volatile uint32_t*)((base) + (reg)))
#define RXBUF_SIZE 128
#define NUM_UART 5
#define S905_UART0_OFFSET (0x011084c0)
#define S905_UART1_OFFSET (0x011084dc)
#define S905_UART2_OFFSET (0x01108700)
#define S905_UART0_AO_OFFSET (0x081004c0)
#define S905_UART1_AO_OFFSET (0x081004e0)
static cbuf_t uart_rx_buf;
static bool initialized = false;
static uintptr_t s905_uart_base = 0;
static uint32_t s905_uart_irq = 0;
static enum handler_return uart_irq(void *arg)
{
uintptr_t base = (uintptr_t)arg;
/* read interrupt status and mask */
while ( (UARTREG(base, S905_UART_STATUS) & S905_UART_STATUS_RXCOUNT_MASK) > 0 ) {
if (cbuf_space_avail(&uart_rx_buf) == 0) {
break;
}
char c = UARTREG(base, S905_UART_RFIFO);
cbuf_write_char(&uart_rx_buf, c, false);
}
return true;
}
static void s905_uart_init(mdi_node_ref_t* node, uint level)
{
assert(s905_uart_base);
assert(s905_uart_irq);
// create circular buffer to hold received data
cbuf_initialize(&uart_rx_buf, RXBUF_SIZE);
//reset the port
UARTREG(s905_uart_base,S905_UART_CONTROL) |= S905_UART_CONTROL_RSTRX |
S905_UART_CONTROL_RSTTX |
S905_UART_CONTROL_CLRERR;
UARTREG(s905_uart_base,S905_UART_CONTROL) &= ~(S905_UART_CONTROL_RSTRX |
S905_UART_CONTROL_RSTTX |
S905_UART_CONTROL_CLRERR);
// enable rx and tx
UARTREG(s905_uart_base,S905_UART_CONTROL) |= S905_UART_CONTROL_TXEN |
S905_UART_CONTROL_RXEN;
UARTREG(s905_uart_base,S905_UART_CONTROL) |= S905_UART_CONTROL_INVRTS |
S905_UART_CONTROL_RXINTEN |
S905_UART_CONTROL_TWOWIRE;
// Set to interrupt every 1 rx byte
uint32_t temp2 = UARTREG(s905_uart_base,S905_UART_IRQ_CONTROL);
temp2 &= 0xffff0000;
temp2 |= (1 << 8) | ( 1 );
UARTREG(s905_uart_base,S905_UART_IRQ_CONTROL) = temp2;
register_int_handler(s905_uart_irq, &uart_irq, (void *)s905_uart_base);
initialized = true;
// enable interrupt
unmask_interrupt(s905_uart_irq);
}
/* panic-time getc/putc */
static int s905_uart_pputc(char c)
{
if (!s905_uart_base)
return 0;
/* spin while fifo is full */
while (UARTREG(s905_uart_base, S905_UART_STATUS) & S905_UART_STATUS_TXFULL)
;
UARTREG(s905_uart_base, S905_UART_WFIFO) = c;
return 1;
}
static int s905_uart_pgetc(void)
{
if (!s905_uart_base)
return 0;
if ((UARTREG(s905_uart_base, S905_UART_STATUS) & S905_UART_STATUS_RXEMPTY) == 0) {
return UARTREG(s905_uart_base, S905_UART_RFIFO);
} else {
return -1;
}
}
static int s905_uart_putc(char c)
{
if (!s905_uart_base)
return 0;
/* spin while fifo is full */
while (UARTREG(s905_uart_base, S905_UART_STATUS) & S905_UART_STATUS_TXFULL)
;
UARTREG(s905_uart_base, S905_UART_WFIFO) = c;
return 1;
}
static int s905_uart_getc(bool wait)
{
if (!s905_uart_base)
return -1;
if (initialized) {
// do cbuf stuff here
char c;
if (cbuf_read_char(&uart_rx_buf, &c, false) == 1)
return c;
return -1;
} else {
//Interupts not online yet, use the panic calls for now.
return s905_uart_pgetc();
}
}
static const struct pdev_uart_ops s905_uart_ops = {
.putc = s905_uart_putc,
.getc = s905_uart_getc,
.pputc = s905_uart_pputc,
.pgetc = s905_uart_pgetc,
};
static void s905_uart_init_early(mdi_node_ref_t* node, uint level)
{
s905_uart_base = 0;
s905_uart_irq = 0;
mdi_node_ref_t child;
mdi_each_child(node, &child) {
switch (mdi_id(&child)) {
case MDI_BASE_VIRT:
if(mdi_node_uint64(&child, &s905_uart_base) != MX_OK)
return;
break;
case MDI_IRQ:
if(mdi_node_uint32(&child, &s905_uart_irq) != MX_OK)
return;
break;
}
}
if ((s905_uart_base == 0) || (s905_uart_irq == 0))
return;
pdev_register_uart(&s905_uart_ops);
}
LK_PDEV_INIT(s905_uart_init_early, MDI_S905_UART, s905_uart_init_early, LK_INIT_LEVEL_PLATFORM_EARLY);
LK_PDEV_INIT(s905_uart_init, MDI_S905_UART, s905_uart_init, LK_INIT_LEVEL_PLATFORM);
+5
Ver Arquivo
@@ -530,6 +530,11 @@ void platform_early_init(void)
} else {
// on qemu we read arena size from the device tree
read_device_tree(&ramdisk_base, &ramdisk_size, &arena_size);
// Some legacy bootloaders do not properly set linux,initrd-end
// Pull the ramdisk size directly from the bootdata container
// now that we have the base to ensure that the size is valid.
ramdisk_from_bootdata_container(ramdisk_base, &ramdisk_base,
&ramdisk_size);
}
if (!ramdisk_base || !ramdisk_size) {
+1
Ver Arquivo
@@ -34,6 +34,7 @@ MODULE_DEPS += \
kernel/dev/interrupt/bcm28xx \
kernel/dev/psci \
kernel/dev/qemu \
kernel/dev/uart/amlogic_s905 \
kernel/dev/uart/bcm28xx \
kernel/dev/uart/pl011 \
+14
Ver Arquivo
@@ -0,0 +1,14 @@
# Copyright 2017 The Fuchsia Authors
# 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
# main project for qemu-aarch64
MODULES +=
ENABLE_BUILD_LISTFILES:=true
include kernel/project/virtual/user.mk
include kernel/project/virtual/test.mk
include kernel/project/target/odroidc2-a53.mk
+8
Ver Arquivo
@@ -0,0 +1,8 @@
# Copyright 2017 The Fuchsia Authors
# 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
ARCH := arm64
TARGET := odroidc2
ARM_CPU := cortex-a53
+33
Ver Arquivo
@@ -0,0 +1,33 @@
ODROIDC2-UBOOT-CONFIG
setenv bootcmd ''
setenv dtb_load 0x10200000
setenv kern_load 0x10280000
setenv ramdisk_start 0x18000000
# We don't have a great way to calculate the ramdisk_end
# on the odroidc2 since the default u-boot build did not
# enable the setexpr command. In order to avoid requiring
# users to build/update the u-boot from the prebuilt available
# from hardkernel we will just declare a really large ramdisk.
# the arm generic platform will get the base address from the
# fdt, but will then pull the size from the ramdisk itself, so
# this will work around bootloader limitations without breaking
# compatibility on other targets.
setenv ramdisk_end 0x70000000
movi read dtb 0 ${dtb_load}
fdt addr ${dtb_load}
fdt resize
fatload mmc 0 ${ramdisk_start} bootdata.bin
fdt chosen ${ramdisk_start} ${ramdisk_end}
fatload mmc 0 ${kern_load} magenta.bin
fdt print
booti ${kern_load} - ${dtb_load}
+31
Ver Arquivo
@@ -0,0 +1,31 @@
include "system/public/magenta/mdi/magenta.mdi"
cpu-map = {
clusters = {
{
cpu-count = 4
}
}
}
kernel = {
s905-uart = {
irq = 225
base-phys = 0xc81004c0
base-virt = 0xffffffffc81004c0
}
arm-gic-v2 = {
base-virt = 0xffffffffc4300000
base-phys = 0xc4300000
gicc-offset = 0x002000
gicd-offset = 0x001000
ipi-base = 5
}
arm-psci = {
use-smc = true
}
arm-timer = {
irq-phys = 30
}
}
+49
Ver Arquivo
@@ -0,0 +1,49 @@
# Copyright 2017 The Fuchsia Authors
#
# 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
LOCAL_DIR := $(GET_LOCAL_DIR)
PLATFORM := generic-arm
MEMBASE := 0x00000000
MEMSIZE ?= 0x80000000 # 2GB
KERNEL_LOAD_OFFSET := 0x10280000
PERIPH_BASE_PHYS := 0xc0000000U
PERIPH_SIZE := 0x10200000UL
PERIPH_BASE_VIRT := 0xffffffffc0000000ULL
MEMORY_APERTURE_SIZE := 0xc0000000UL
# TODO(hollande) this will reserve a large-ish chunk of memory
# to protect two discontiguous regions...
# 0x00000000 - 0x01000000 bl0-bl2 code
# 0x10000000 - 0x10200000 bl3 code
# We will need a mechanism, likely mdi, for reserving chunks
# of memory early in boot on a per target basis.
BOOTLOADER_RESERVE_START := 0
BOOTLOADER_RESERVE_SIZE := 0x10200000
KERNEL_DEFINES += \
MEMBASE=$(MEMBASE) \
MEMSIZE=$(MEMSIZE) \
PERIPH_BASE_PHYS=$(PERIPH_BASE_PHYS) \
PERIPH_BASE_VIRT=$(PERIPH_BASE_VIRT) \
PERIPH_SIZE=$(PERIPH_SIZE) \
MEMORY_APERTURE_SIZE=$(MEMORY_APERTURE_SIZE) \
BOOTLOADER_RESERVE_START=$(BOOTLOADER_RESERVE_START) \
BOOTLOADER_RESERVE_SIZE=$(BOOTLOADER_RESERVE_SIZE) \
PLATFORM_SUPPORTS_PANIC_SHELL=1 \
include make/fastboot.mk
# build MDI
MDI_SRCS := \
$(LOCAL_DIR)/odroidc2.mdi \
MDI_DEPS := \
kernel/include/mdi/kernel-defs.mdi \
include make/mdi.mk
+174
Ver Arquivo
@@ -0,0 +1,174 @@
#!/usr/bin/env bash
# Copyright 2017 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
set -eu
get_confirmation() {
echo -n "Press 'y' to confirm: "
read CONFIRM
if [[ "$CONFIRM" != "y" ]]; then
echo "[format_sdcard] Aborted due to invalid confirmation"
exit 1
fi
}
if [[ $OSTYPE != "linux-gnu" ]]; then
echo "[format_sdcard] Script is currently Linux-exclusive"
exit 1
fi
SCRIPT_DIR=$( cd $( dirname "${BASH_SOURCE[0]}" ) && pwd)
MAGENTA_DIR="$SCRIPT_DIR/.."
echo $MAGENTA_DIR
# Ensure Magenta has been built prior to formatting USB
pushd "$MAGENTA_DIR" > /dev/null
./scripts/make-parallel magenta-odroidc2-arm64
popd > /dev/null
lsblk
echo "Enter the name of a block device to format: "
echo " This will probably be of the form 'sd[letter]', like 'sdc'"
echo -n "> "
read DEVICE
# Ensure that device exists
echo -n "[format_sdcard] Checking that device exists: $DEVICE ..."
DEVICE_PATH="/dev/$DEVICE"
if [[ ! -e "$DEVICE_PATH" ]]; then
echo " FAILED"
echo "[format_sdcard] ERROR: This device does not exist: $DEVICE_PATH"
exit 1
fi
echo " SUCCESS"
# Ensure that the device is a real block device
echo -n "[format_sdcard] Checking that device is a known block device..."
if [[ ! -e "/sys/block/$DEVICE" ]]; then
echo " FAILED"
echo "[format_sdcard] ERROR: /sys/block/$DEVICE does not exist."
echo " Does $DEVICE refer to a partition?"
exit 1
fi
echo " SUCCESS"
# Try to check that the device is a USB stick
echo -n "[format_sdcard] Checking if device is USB: $DEVICE ..."
READLINK_USB=$(readlink -f "/sys/class/block/$DEVICE/device" | { grep -i "usb" || true; })
if [[ -z "$READLINK_USB" ]]; then
echo " FAILED"
echo "[format_sdcard] ERROR: Cannot confirm that device is a USB stick"
echo "[format_sdcard] ERROR: Please insert USB stick and retry"
exit 1
fi
echo " SUCCESS"
# Ensure the device is not mounted
echo -n "[format_sdcard] Checking that device is not mounted: $DEVICE ..."
if [[ -n $(df -Hl | grep "$DEVICE") ]]; then
echo " FAILED"
echo "[format_sdcard] ERROR: Your device appears to be mounted: "
echo "..."
df -Hl | grep "$DEVICE"
echo "..."
echo "[format_sdcard] ERROR: Please unmount your device and retry"
exit 1
fi
echo " SUCCESS"
# Confirm that the user knows what they are doing
sudo -v -p "[sudo] Enter password to confirm information about device: "
sudo sfdisk -l "$DEVICE_PATH"
echo "[format_sdcard] ABOUT TO COMPLETELY WIPE / FORMAT: $DEVICE_PATH"
get_confirmation
echo "[format_sdcard] ARE YOU 100% SURE? This will hurt if you get it wrong."
get_confirmation
# Create three new partitions on the device, 1GB for root and divide the
# remaining space into 2 pieces for data and bootfs
# Determine how many bytes we have available on this disk.
BLK_DEV_SIZE=`sudo blockdev --getsize64 $DEVICE_PATH`
BLK_DEV_SIZE_MB=$((BLK_DEV_SIZE/1048576))
if [ "$BLK_DEV_SIZE_MB" -lt 3000 ]; then
echo " FAILED"
echo "[format_sdcard] ERROR: SD Card must be at least 4GB"
exit 1
fi
sudo dd if=/dev/zero of="$DEVICE_PATH" bs=512 count=1
DATA_PTN_START=4259840
DATA_PTN_END=4521983
DATA_PTN_SIZE=$((DATA_PTN_END-DATA_PTN_START+1))
DATA_PTN_SIZE_B=$(((DATA_PTN_END - DATA_PTN_START + 1)*512))
echo "Using Data Partition Size = ${DATA_PTN_SIZE_B} bytes"
sudo sfdisk -uS "$DEVICE_PATH" << EOF
${DATA_PTN_START} ${DATA_PTN_SIZE} 0x0b -
EOF
DATA_PTN_PATH="${DEVICE_PATH}1"
sudo mkfs.fat ${DEVICE_PATH}1
# Function to attempt unmounting a mount point up to three times, sleeping
# a couple of seconds between attempts.
function umount_retry() {
set +e
TRIES=0
while (! sudo umount $1); do
((TRIES++))
if [[ ${TRIES} > 2 ]]; then
echo "[format_sdcard] Unable to umount $0"
exit 1
fi
sleep 2
done
set -e
}
# Copy the necessary files to the root partition
MOUNT_PATH=`mktemp -d`
sudo mount "$DATA_PTN_PATH" "$MOUNT_PATH"
trap "umount_retry \"${MOUNT_PATH}\" && rm -rf \"${MOUNT_PATH}\" && echo \"Unmounted succesfully\"" INT TERM EXIT
# Copy the kernel to the boot partition.
sudo cp "$MAGENTA_DIR/build-magenta-odroidc2-arm64/magenta.bin" \
"${MOUNT_PATH}/"
# Copy the ramdisk
sudo cp "$MAGENTA_DIR/build-magenta-odroidc2-arm64/bootdata.bin" \
"${MOUNT_PATH}/"
sudo cp "$MAGENTA_DIR/kernel/target/odroidc2/boot.ini" \
"${MOUNT_PATH}/"
# Make sure all writes are committed to disk.
pushd "$MOUNT_PATH" > /dev/null
sync
popd > /dev/null
curl -L http://dn.odroid.com/S905/BootLoader/ODROID-C2/c2_boot_release.tar.gz >/tmp/sd.tgz
tar -C /tmp -xzf /tmp/sd.tgz
cd /tmp/sd_fuse
sudo sh sd_fusing.sh $DEVICE_PATH
rm -rf /tmp/sd_fuse
rm -f /tmp/sd.tgz
echo " SUCCESS"
+13
Ver Arquivo
@@ -0,0 +1,13 @@
#!/usr/bin/env bash
# Copyright 2016 The Fuchsia Authors
#
# 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
export PROJECT=magenta-odroidc2-arm64
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
$DIR/make-parallel -C $DIR/.. $PROJECT "$@"
+3
Ver Arquivo
@@ -74,3 +74,6 @@ uint64 kernel.arm-gic-v2.gicc-offset MDI_ARM_GIC_V2_GICC_OFFSET
uint32 kernel.arm-gic-v2.ipi-base MDI_ARM_GIC_V2_IPI_BASE 1073
uint64 kernel.arm-gic-v2.msi-frame-phys MDI_ARM_GIC_V2_MSI_FRAME_PHYS 1074
uint64 kernel.arm-gic-v2.msi-frame-virt MDI_ARM_GIC_V2_MSI_FRAME_VIRT 1075
// AmLogic S905
list kernel.s905-uart MDI_S905_UART 1080