Comparar commits

...

1 Commits

Autor SHA1 Mensagem Data
Travis Geiselbrecht f69935b599 WIP first stab at getting system running on an odroid-c2
Change-Id: I2c314b15515bff74cdf0bbebf80b9f24ef2a7a8a
2017-02-15 17:08:25 -08:00
13 arquivos alterados com 583 adições e 4 exclusões
+2 -2
Ver Arquivo
@@ -227,11 +227,11 @@ void arch_enter_uspace(uintptr_t pc, uintptr_t sp, uintptr_t arg1, uintptr_t arg
/* set up a default spsr to get into 64bit user space:
* zeroed NZCV
* no SS, no IL, no D
* no SS, no IL, no D, no A
* all interrupts enabled
* mode 0: EL0t
*/
uint32_t spsr = 0;
uint32_t spsr = (1<<9) | (1<<8);
arch_disable_ints();
+1
Ver Arquivo
@@ -334,6 +334,7 @@ void arm64_invalid_exception(struct arm64_iframe_long *iframe, unsigned int whic
void arm64_invalid_exception(struct arm64_iframe_long *iframe, unsigned int which)
{
printf("invalid exception, which 0x%x\n", which);
printf("ESR 0x%lx\n", ARM64_READ_SYSREG(esr_el1));
dump_iframe(iframe);
platform_halt(HALT_ACTION_HALT, HALT_REASON_SW_PANIC);
+55
Ver Arquivo
@@ -0,0 +1,55 @@
// Copyright 2016 The Fuchsia Authors
// Copyright (c) 2008-2014 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 <stdarg.h>
#include <reg.h>
#include <stdio.h>
#include <kernel/thread.h>
#include <dev/uart.h>
#include <platform/debug.h>
#include <platform/s905.h>
#include <reg.h>
// XXX have target set this
#define DEBUG_UART 3
void platform_dputs(const char* str, size_t len)
{
while (len-- > 0) {
char c = *str++;
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_pputc(char c)
{
if (c == '\n')
uart_pputc(DEBUG_UART, '\r');
uart_pputc(DEBUG_UART, c);
}
int platform_pgetc(char *c, bool wait)
{
int ret = uart_pgetc(DEBUG_UART);
if (ret < 0)
return ret;
*c = ret;
return 0;
}
@@ -0,0 +1,15 @@
// Copyright 2016 The Fuchsia Authors
// Copyright (c) 2014-2015 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 <platform/s905.h>
#define GICBASE(n) (CPUPRIV_BASE_VIRT)
#define GICC_OFFSET (0x02000)
#define GICD_OFFSET (0x01000)
@@ -0,0 +1,54 @@
// 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
#pragma once
/* up to 3 GB of ram */
#define MEMORY_BASE_PHYS (0x00000000)
#define MEMORY_APERTURE_SIZE (3ULL * 1024 * 1024 * 1024)
/* map all of 0-1GB into kernel space in one shot */
#define PERIPHERAL_BASE_PHYS (0xc0000000UL) // start of peripherals
#define PERIPHERAL_BASE_SIZE (0x10200000UL) // end of peripherals
#define PERIPHERAL_BASE_VIRT (0xffffffffc0000000ULL) // -1GB
/* individual peripherals in this mapping */
#define CPUPRIV_BASE_PHYS (PERIPHERAL_BASE_PHYS + 0x04300000)
#define CPUPRIV_BASE_VIRT (PERIPHERAL_BASE_VIRT + 0x04300000)
#define CPUPRIV_SIZE (0x00008000)
#define UART0_BASE (PERIPHERAL_BASE_VIRT + 0x011084c0)
#define UART1_BASE (PERIPHERAL_BASE_VIRT + 0x011084dc)
#define UART2_BASE (PERIPHERAL_BASE_VIRT + 0x01108700)
#define UART0_AO_BASE (PERIPHERAL_BASE_VIRT + 0x081004c0)
#define UART1_AO_BASE (PERIPHERAL_BASE_VIRT + 0x081004e0)
#define RTC_BASE (PERIPHERAL_BASE_VIRT + 0x09010000)
#define RTC_SIZE (0x00001000)
#define FW_CFG_BASE (PERIPHERAL_BASE_VIRT + 0x09020000)
#define FW_CFG_SIZE (0x00001000)
#define NUM_VIRTIO_TRANSPORTS 32
#define VIRTIO_BASE (PERIPHERAL_BASE_VIRT + 0x0a000000)
#define VIRTIO_SIZE (NUM_VIRTIO_TRANSPORTS * 0x200)
#define PCIE_MMIO_BASE_PHYS ((paddr_t)(PERIPHERAL_BASE_PHYS + 0x10000000))
#define PCIE_MMIO_SIZE (0x2eff0000)
#define PCIE_PIO_BASE_PHYS ((paddr_t)(PERIPHERAL_BASE_PHYS + 0x3eff0000))
#define PCIE_PIO_SIZE (0x00010000)
#define PCIE_ECAM_BASE_PHYS ((paddr_t)(PERIPHERAL_BASE_PHYS + 0x3f000000))
#define PCIE_ECAM_SIZE (0x01000000)
#define GICV2M_FRAME_PHYS (PERIPHERAL_BASE_PHYS + 0x08020000)
/* interrupts */
#define ARM_GENERIC_TIMER_VIRTUAL_INT 27
#define ARM_GENERIC_TIMER_PHYSICAL_INT 30
#define UART0_INT (32 + 1)
#define PCIE_INT_BASE (32 + 3)
#define PCIE_INT_COUNT (4)
#define VIRTIO0_INT (32 + 16)
#define MAX_INT 288
+164
Ver Arquivo
@@ -0,0 +1,164 @@
// Copyright 2016 The Fuchsia Authors
// Copyright (c) 2012-2015 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 <arch.h>
#include <err.h>
#include <debug.h>
#include <trace.h>
#include <dev/display.h>
#include <dev/hw_rng.h>
#include <dev/interrupt/arm_gic.h>
#include <dev/timer/arm_generic.h>
#include <dev/uart.h>
#include <lk/init.h>
#include <lib/console.h>
#include <kernel/cmdline.h>
#include <kernel/vm.h>
#include <kernel/spinlock.h>
#include <kernel/thread.h>
#include <platform.h>
#include <platform/gic.h>
#include <dev/psci.h>
#include <dev/interrupt.h>
#include <platform/s905.h>
#include <libfdt.h>
#include "platform_p.h"
/* initial memory mappings. parsed by start.S */
struct mmu_initial_mapping mmu_initial_mappings[] = {
/* all of memory */
{
.phys = MEMORY_BASE_PHYS,
.virt = KERNEL_BASE,
.size = MEMORY_APERTURE_SIZE,
.flags = 0,
.name = "memory"
},
/* 1GB of peripherals */
{
.phys = PERIPHERAL_BASE_PHYS,
.virt = PERIPHERAL_BASE_VIRT,
.size = PERIPHERAL_BASE_SIZE,
.flags = MMU_INITIAL_MAPPING_FLAG_DEVICE,
.name = "peripherals"
},
/* null entry to terminate the list */
{}
};
static pmm_arena_info_t arena = {
.name = "ram",
.base = MEMORY_BASE_PHYS + 0x01000000,
.size = MEMSIZE - 0x01000000,
.flags = PMM_ARENA_FLAG_KMAP,
};
static uint32_t bootloader_ramdisk_base;
static uint32_t bootloader_ramdisk_size;
static void* ramdisk_base;
static size_t ramdisk_size;
static void platform_preserve_ramdisk(void) {
if (bootloader_ramdisk_size == 0) {
return;
}
if (bootloader_ramdisk_base == 0) {
return;
}
struct list_node list = LIST_INITIAL_VALUE(list);
size_t pages = (bootloader_ramdisk_size + PAGE_SIZE - 1) / PAGE_SIZE;
size_t actual = pmm_alloc_range(bootloader_ramdisk_base, pages, &list);
if (actual != pages) {
panic("unable to reserve ramdisk memory range\n");
}
// mark all of the pages we allocated as WIRED
vm_page_t *p;
list_for_every_entry(&list, p, vm_page_t, free.node) {
p->state = VM_PAGE_STATE_WIRED;
}
ramdisk_base = paddr_to_kvaddr(bootloader_ramdisk_base);
ramdisk_size = pages * PAGE_SIZE;
}
void* platform_get_ramdisk(size_t *size) {
if (ramdisk_base) {
*size = ramdisk_size;
return ramdisk_base;
} else {
*size = 0;
return NULL;
}
}
void platform_early_init(void)
{
/* initialize the interrupt controller */
arm_gic_init();
arm_generic_timer_init(ARM_GENERIC_TIMER_PHYSICAL_INT, 0);
uart_init_early();
/* add the main memory arena */
pmm_add_arena(&arena);
/* reserve the first 64k of ram, which should be holding the fdt */
//pmm_alloc_range(MEMBASE, 0x100000 / PAGE_SIZE, NULL);
//platform_preserve_ramdisk();
/* boot the secondary cpus using the Power State Coordintion Interface */
for (uint i = 1; i < SMP_MAX_CPUS; i++) {
psci_cpu_on(0, i, MEMBASE + KERNEL_LOAD_OFFSET);
}
}
void platform_init(void)
{
uart_init();
}
void platform_halt(platform_halt_action suggested_action, platform_halt_reason reason)
{
if (suggested_action == HALT_ACTION_REBOOT) {
psci_system_reset();
} else if (suggested_action == HALT_ACTION_SHUTDOWN) {
psci_system_off();
} else {
#if WITH_PANIC_BACKTRACE
thread_print_backtrace(get_current_thread(), __GET_FRAME(0));
#endif
#if ENABLE_PANIC_SHELL
dprintf(ALWAYS, "HALT: starting debug shell... (reason = %u)\n", reason);
arch_disable_ints();
panic_shell_start();
#else
dprintf(ALWAYS, "HALT: spinning forever... (reason = %u)\n", reason);
arch_disable_ints();
for (;;);
#endif
}
// catch all fallthrough cases
arch_disable_ints();
for (;;);
}
/* stub out the hardware rng entropy generator, which doesn't eixst on this platform */
size_t hw_rng_get_entropy(void* buf, size_t len, bool block) {
return 0;
}
/* no built in framebuffer */
status_t display_get_info(struct display_info *info) {
return ERR_NOT_FOUND;
}
+14
Ver Arquivo
@@ -0,0 +1,14 @@
// Copyright 2016 The Fuchsia Authors
// Copyright (c) 2012 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
#ifndef __PLATFORM_P_H
#define __PLATFORM_P_H
void platform_init_timer(void);
#endif
+47
Ver Arquivo
@@ -0,0 +1,47 @@
# Copyright 2016 The Fuchsia Authors
# Copyright (c) 2008-2015 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
LOCAL_DIR := $(GET_LOCAL_DIR)
MODULE := $(LOCAL_DIR)
ARCH := arm64
ARM_CPU ?= cortex-a53
WITH_SMP ?= 1
# qemu virt can support up to 8 cores in cluster 0
SMP_MAX_CPUS := 4
SMP_CPU_ID_BITS := 2
LK_HEAP_IMPLEMENTATION ?= cmpctmalloc
MODULE_SRCS += \
$(LOCAL_DIR)/debug.c \
$(LOCAL_DIR)/platform.c \
$(LOCAL_DIR)/uart.c
MEMBASE := 0x00000000
MEMSIZE ?= 0x80000000 # 2GB
KERNEL_LOAD_OFFSET := 0x11000000 # whatever grub wanted
MODULE_DEPS += \
lib/cbuf \
lib/fdt \
dev/pcie \
dev/timer/arm_generic \
dev/interrupt/arm_gic \
dev/psci \
KERNEL_DEFINES += \
MEMBASE=$(MEMBASE) \
MEMSIZE=$(MEMSIZE) \
PLATFORM_SUPPORTS_PANIC_SHELL=1
LINKER_SCRIPT += \
$(BUILDDIR)/system-onesegment.ld
include make/module.mk
+195
Ver Arquivo
@@ -0,0 +1,195 @@
// Copyright 2016 The Fuchsia Authors
// Copyright (c) 2014-2015 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 <reg.h>
#include <stdio.h>
#include <trace.h>
#include <lib/cbuf.h>
#include <kernel/thread.h>
#include <dev/interrupt.h>
#include <dev/uart.h>
#include <platform/debug.h>
#include <platform/s905.h>
/* PL011 implementation */
#if 0
#define UART_DR (0x00)
#define UART_RSR (0x04)
#define UART_TFR (0x18)
#define UART_ILPR (0x20)
#define UART_IBRD (0x24)
#define UART_FBRD (0x28)
#define UART_LCRH (0x2c)
#define UART_CR (0x30)
#define UART_IFLS (0x34)
#define UART_IMSC (0x38)
#define UART_TRIS (0x3c)
#define UART_TMIS (0x40)
#define UART_ICR (0x44)
#define UART_DMACR (0x48)
#endif
#define UART_WFIFO (0x0)
#define UART_RFIFO (0x4)
#define UART_CONTROL (0x8)
#define UART_STATUS (0xc)
#define UART_IRQ_CONTROL (0x10)
#define UART_REG5 (0x14)
#define UARTREG(base, reg) (*REG32((base) + (reg)))
#define RXBUF_SIZE 128
#define NUM_UART 5
//static cbuf_t uart_rx_buf[NUM_UART];
static inline uintptr_t uart_to_ptr(unsigned int n)
{
switch (n) {
default:
case 0: return UART0_BASE;
case 1: return UART1_BASE;
case 2: return UART2_BASE;
case 3: return UART0_AO_BASE;
case 4: return UART1_AO_BASE;
}
}
#if 0
static enum handler_return uart_irq(void *arg)
{
bool resched = false;
uint port = (uintptr_t)arg;
uintptr_t base = uart_to_ptr(port);
/* read interrupt status and mask */
uint32_t isr = UARTREG(base, UART_TMIS);
if (isr & (1<<4)) { // rxmis
cbuf_t *rxbuf = &uart_rx_buf[port];
/* while fifo is not empty, read chars out of it */
while ((UARTREG(base, UART_TFR) & (1<<4)) == 0) {
/* if we're out of rx buffer, mask the irq instead of handling it */
if (cbuf_space_avail(rxbuf) == 0) {
UARTREG(base, UART_IMSC) &= ~(1<<4); // !rxim
break;
}
char c = UARTREG(base, UART_DR);
cbuf_write_char(rxbuf, c, false);
resched = true;
}
}
return resched ? INT_RESCHEDULE : INT_NO_RESCHEDULE;
}
#endif
void uart_init(void)
{
#if 0
for (size_t i = 0; i < NUM_UART; i++) {
uintptr_t base = uart_to_ptr(i);
// create circular buffer to hold received data
cbuf_initialize(&uart_rx_buf[i], RXBUF_SIZE);
// assumes interrupts are contiguous
register_int_handler(UART0_INT + i, &uart_irq, (void *)i);
// clear all irqs
UARTREG(base, UART_ICR) = 0x3ff;
// set fifo trigger level
UARTREG(base, UART_IFLS) = 0; // 1/8 rxfifo, 1/8 txfifo
// enable rx interrupt
UARTREG(base, UART_IMSC) = (1<<4); // rxim
// enable receive
UARTREG(base, UART_CR) |= (1<<9); // rxen
// enable interrupt
unmask_interrupt(UART0_INT + i);
}
#endif
}
void uart_init_early(void)
{
#if 0
for (size_t i = 0; i < NUM_UART; i++) {
UARTREG(uart_to_ptr(i), UART_CR) = (1<<8)|(1<<0); // tx_enable, uarten
}
#endif
}
int uart_putc(int port, char c)
{
uintptr_t base = uart_to_ptr(port);
/* spin while fifo is full */
while (UARTREG(base, UART_STATUS) & (1<<21))
;
UARTREG(base, UART_WFIFO) = c;
return 1;
}
int uart_getc(int port, bool wait)
{
#if 0
cbuf_t *rxbuf = &uart_rx_buf[port];
char c;
if (cbuf_read_char(rxbuf, &c, wait) == 1) {
UARTREG(uart_to_ptr(port), UART_IMSC) = (1<<4); // rxim
return c;
}
#endif
return uart_pgetc(port);
}
/* panic-time getc/putc */
int uart_pputc(int port, char c)
{
uintptr_t base = uart_to_ptr(port);
/* spin while fifo is full */
while (UARTREG(base, UART_STATUS) & (1<<21))
;
UARTREG(base, UART_WFIFO) = c;
return 1;
}
int uart_pgetc(int port)
{
uintptr_t base = uart_to_ptr(port);
if ((UARTREG(base, UART_STATUS) & (1<<20)) == 0) {
return UARTREG(base, UART_RFIFO);
} else {
return -1;
}
}
void uart_flush_tx(int port)
{
}
void uart_flush_rx(int port)
{
}
void uart_init_port(int port, uint baud)
{
}
@@ -10,6 +10,6 @@
#include <platform/qemu-virt.h>
#define GICBASE(n) (CPUPRIV_BASE_VIRT)
#define GICD_OFFSET (0x00000)
#define GICC_OFFSET (0x10000)
#define GICC_OFFSET (0x01000)
#define GICD_OFFSET (0x02000)
+17
Ver Arquivo
@@ -0,0 +1,17 @@
# Copyright 2016 The Fuchsia Authors
# Copyright (c) 2008-2015 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
# main project for qemu-aarch64
MODULES +=
ENABLE_BUILD_LISTFILES:=true
EMBED_USER_BOOTFS:=true
include project/virtual/user.mk
include project/virtual/test.mk
include project/target/odroidc2.mk
+8
Ver Arquivo
@@ -0,0 +1,8 @@
# Copyright 2016 The Fuchsia Authors
# Copyright (c) 2008-2015 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
TARGET := odroidc2
+9
Ver Arquivo
@@ -0,0 +1,9 @@
# 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 := amlogic_s905