From: Andreas Kölbl <andreas.koe...@st.oth-regensburg.de> Peripheral device drivers: - RTEMS Timercounter API using the ARM Generic Timer. - Benchmark RTEMS with the Nvidia TMRUS Console: - 8250 UART based driver - Devices UART-A and UART-D (Default: UART-D, UART-A is turned off) - Interrupt driven or polled (Default: Polled) --- Instructions to run RTEMS using this BSP in the Jailhouse hypervisor will be provided later.
c/src/lib/libbsp/arm/acinclude.m4 | 2 + c/src/lib/libbsp/arm/jetson-tk1/Makefile.am | 134 ++++++++++ c/src/lib/libbsp/arm/jetson-tk1/README | 21 ++ c/src/lib/libbsp/arm/jetson-tk1/TODO | 3 + c/src/lib/libbsp/arm/jetson-tk1/bsp_specs | 13 + c/src/lib/libbsp/arm/jetson-tk1/clock/car.c | 117 +++++++++ c/src/lib/libbsp/arm/jetson-tk1/clock/clockdrv.c | 138 ++++++++++ c/src/lib/libbsp/arm/jetson-tk1/configure.ac | 39 +++ c/src/lib/libbsp/arm/jetson-tk1/console/console.c | 291 +++++++++++++++++++++ .../libbsp/arm/jetson-tk1/console/debug-console.c | 50 ++++ c/src/lib/libbsp/arm/jetson-tk1/include/bsp.h | 25 ++ c/src/lib/libbsp/arm/jetson-tk1/include/car.h | 30 +++ c/src/lib/libbsp/arm/jetson-tk1/include/console.h | 32 +++ c/src/lib/libbsp/arm/jetson-tk1/include/irq.h | 25 ++ c/src/lib/libbsp/arm/jetson-tk1/include/memory.h | 31 +++ c/src/lib/libbsp/arm/jetson-tk1/include/mmu.h | 42 +++ .../arm/jetson-tk1/make/custom/jetson-tk1.cfg | 16 ++ c/src/lib/libbsp/arm/jetson-tk1/misc/timer.c | 64 +++++ c/src/lib/libbsp/arm/jetson-tk1/startup/bspreset.c | 19 ++ c/src/lib/libbsp/arm/jetson-tk1/startup/bspstart.c | 16 ++ .../libbsp/arm/jetson-tk1/startup/bspstarthooks.c | 59 +++++ .../lib/libbsp/arm/jetson-tk1/startup/linkcmds.in | 39 +++ .../arm/jetson-tk1/startup/mm_config_table.c | 56 ++++ 23 files changed, 1262 insertions(+) create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/Makefile.am create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/README create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/TODO create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/bsp_specs create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/clock/car.c create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/clock/clockdrv.c create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/configure.ac create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/console/console.c create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/console/debug-console.c create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/include/bsp.h create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/include/car.h create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/include/console.h create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/include/irq.h create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/include/memory.h create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/include/mmu.h create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/make/custom/jetson-tk1.cfg create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/misc/timer.c create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/startup/bspreset.c create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/startup/bspstart.c create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/startup/bspstarthooks.c create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/startup/linkcmds.in create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/startup/mm_config_table.c diff --git a/c/src/lib/libbsp/arm/acinclude.m4 b/c/src/lib/libbsp/arm/acinclude.m4 index f5ca105eca..26f743a95e 100644 --- a/c/src/lib/libbsp/arm/acinclude.m4 +++ b/c/src/lib/libbsp/arm/acinclude.m4 @@ -18,6 +18,8 @@ AC_DEFUN([RTEMS_CHECK_BSPDIR], AC_CONFIG_SUBDIRS([gdbarmsim]);; gumstix ) AC_CONFIG_SUBDIRS([gumstix]);; + jetson-tk1 ) + AC_CONFIG_SUBDIRS([jetson-tk1]);; lm3s69xx ) AC_CONFIG_SUBDIRS([lm3s69xx]);; lpc176x ) diff --git a/c/src/lib/libbsp/arm/jetson-tk1/Makefile.am b/c/src/lib/libbsp/arm/jetson-tk1/Makefile.am new file mode 100644 index 0000000000..4316e67957 --- /dev/null +++ b/c/src/lib/libbsp/arm/jetson-tk1/Makefile.am @@ -0,0 +1,134 @@ +ACLOCAL_AMFLAGS = -I ../../../../aclocal + +include $(top_srcdir)/../../../../automake/compile.am + +include_bspdir = $(includedir)/bsp +include_libcpudir = $(includedir)/libcpu + +dist_project_lib_DATA = bsp_specs + +############################################################################### +# Header # +############################################################################### + +include_HEADERS = include/bsp.h +include_HEADERS += ../realview-pbx-a9/include/tm27.h + +nodist_include_HEADERS = ../../shared/include/coverhd.h include/bspopts.h +nodist_include_bsp_HEADERS = ../../shared/include/bootcard.h + +include_libcpu_HEADERS = ../../../libcpu/arm/shared/include/arm-cp15.h + +include_bsp_HEADERS = +include_bsp_HEADERS += ../../../libbsp/shared/include/mm.h +include_bsp_HEADERS += ../../shared/include/irq-generic.h +include_bsp_HEADERS += ../../shared/include/irq-info.h +include_bsp_HEADERS += ../../shared/include/stackalloc.h +include_bsp_HEADERS += ../../shared/include/uart-output-char.h +include_bsp_HEADERS += ../../shared/include/utility.h +include_bsp_HEADERS += ../shared/include/linker-symbols.h +include_bsp_HEADERS += ../shared/include/start.h +include_bsp_HEADERS += ../shared/include/arm-cp15-start.h +include_bsp_HEADERS += ../shared/include/arm-errata.h +include_bsp_HEADERS += ../shared/include/arm-gic.h +include_bsp_HEADERS += ../shared/include/arm-gic-irq.h +include_bsp_HEADERS += ../shared/include/arm-gic-regs.h +include_bsp_HEADERS += ../shared/include/arm-gic-tm27.h +include_bsp_HEADERS += ../shared/include/arm-release-id.h +include_bsp_HEADERS += ../shared/include/arm-cache-l1.h +include_bsp_HEADERS += ../shared/armv467ar-basic-cache/cache_.h + +include_bsp_HEADERS += include/car.h +include_bsp_HEADERS += include/console.h +include_bsp_HEADERS += include/irq.h +include_bsp_HEADERS += include/memory.h +include_bsp_HEADERS += include/mmu.h + +############################################################################### +# Data # +############################################################################### + +noinst_LIBRARIES = libbspstart.a + +libbspstart_a_SOURCES = ../shared/start/start.S + +project_lib_DATA = start.$(OBJEXT) + +project_lib_DATA += startup/linkcmds +project_lib_DATA += ../shared/startup/linkcmds.base + +############################################################################### +# LibBSP # +############################################################################### + +noinst_LIBRARIES += libbsp.a + +libbsp_a_SOURCES = +libbsp_a_CPPFLAGS = +libbsp_a_LIBADD = + +# Shared +libbsp_a_SOURCES += ../../shared/bootcard.c +libbsp_a_SOURCES += ../../shared/bspclean.c +libbsp_a_SOURCES += ../../shared/bspgetworkarea.c +libbsp_a_SOURCES += ../../shared/bsppredriverhook.c +libbsp_a_SOURCES += ../../shared/cpucounterread.c +libbsp_a_SOURCES += ../../shared/cpucounterdiff.c +libbsp_a_SOURCES += ../../shared/gnatinstallhandler.c +libbsp_a_SOURCES += ../../shared/sbrk.c +libbsp_a_SOURCES += ../../shared/src/stackalloc.c +libbsp_a_SOURCES += ../shared/startup/bsp-start-memcpy.S +libbsp_a_SOURCES += ../shared/arm-cp15-set-ttb-entries.c + +# Cache +libbsp_a_SOURCES += ../../../libcpu/shared/src/cache_manager.c +libbsp_a_SOURCES += ../shared/include/arm-cache-l1.h +libbsp_a_SOURCES += ../shared/armv467ar-basic-cache/cache_.h +libbsp_a_CPPFLAGS += -I$(srcdir)/../shared/armv467ar-basic-cache + +# Clock and reset +libbsp_a_SOURCES += clock/clockdrv.c ../../../shared/clockdrv_shell.h +libbsp_a_SOURCES += clock/car.c + +# Console +libbsp_a_SOURCES += ../../shared/console-termios.c +libbsp_a_SOURCES += console/console.c +libbsp_a_SOURCES += console/debug-console.c + +# IRQ +libbsp_a_SOURCES += ../shared/arm-cp15-set-exception-handler.c +libbsp_a_SOURCES += ../shared/arm-gic-irq.c +libbsp_a_SOURCES += ../../shared/src/irq-default-handler.c +libbsp_a_SOURCES += ../../shared/src/irq-generic.c +libbsp_a_SOURCES += ../../shared/src/irq-info.c +libbsp_a_SOURCES += ../../shared/src/irq-legacy.c +libbsp_a_SOURCES += ../../shared/src/irq-server.c +libbsp_a_SOURCES += ../../shared/src/irq-shell.c + +# Restart +libbsp_a_SOURCES += startup/bspreset.c + +# Startup +libbsp_a_SOURCES += startup/bspstart.c +if HAS_SMP +libbsp_a_SOURCES += ../shared/arm-a9mpcore-smp.c +endif + +# Start hooks +libbsp_a_SOURCES += startup/bspstarthooks.c + +# LIBMM +libbsp_a_SOURCES += startup/mm_config_table.c +libbsp_a_SOURCES += ../shared/mminit.c + +# misc +libbsp_a_SOURCES += misc/timer.c + +############################################################################### +# Special Rules # +############################################################################### + +DISTCLEANFILES = include/bspopts.h + +include $(srcdir)/preinstall.am +include $(top_srcdir)/../../../../automake/local.am diff --git a/c/src/lib/libbsp/arm/jetson-tk1/README b/c/src/lib/libbsp/arm/jetson-tk1/README new file mode 100644 index 0000000000..13821c7082 --- /dev/null +++ b/c/src/lib/libbsp/arm/jetson-tk1/README @@ -0,0 +1,21 @@ +BSP for the Jetson TK1 ARM board + +This BSP currently supports the following devices: + - Console using UART-D on DB9 connector and UART-A on the J3A2 Pin header + - Clock using the ARM internal CP15 timer + - Benchmark timer using the Nvidia Generic Timer TimerUS + +Checkout the options described in include/bspopts.h.in in order to configure +the second console or let the consoles operate interrupt driven. + +Currently, following IRQs are used: + If configured NS8250_CONSOLE_USE_INTERRUPTS=1) + - 122 + - 68 + +Also allow the following memory regions: + - UARTA 0x40@0x70006000 + - UARTD 0x40@0x70006300 + - Nvidia Timers 0x1000@0x60005000 + - RAM 64MB@0x90000000 + - PINMUX AUX 0x1000@0x70003000 diff --git a/c/src/lib/libbsp/arm/jetson-tk1/TODO b/c/src/lib/libbsp/arm/jetson-tk1/TODO new file mode 100644 index 0000000000..5813393d82 --- /dev/null +++ b/c/src/lib/libbsp/arm/jetson-tk1/TODO @@ -0,0 +1,3 @@ +- SMP +- Peripheral device drivers +- Doxygen comments diff --git a/c/src/lib/libbsp/arm/jetson-tk1/bsp_specs b/c/src/lib/libbsp/arm/jetson-tk1/bsp_specs new file mode 100644 index 0000000000..32c105fd0f --- /dev/null +++ b/c/src/lib/libbsp/arm/jetson-tk1/bsp_specs @@ -0,0 +1,13 @@ +%rename endfile old_endfile +%rename startfile old_startfile +%rename link old_link + +*startfile: +%{!qrtems: %(old_startfile)} \ +%{!nostdlib: %{qrtems: start.o%s crti.o%s crtbegin.o%s -e _start}} + +*link: +%{!qrtems: %(old_link)} %{qrtems: -dc -dp -N} + +*endfile: +%{!qrtems: %(old_endfiles)} %{qrtems: crtend.o%s crtn.o%s } diff --git a/c/src/lib/libbsp/arm/jetson-tk1/clock/car.c b/c/src/lib/libbsp/arm/jetson-tk1/clock/car.c new file mode 100644 index 0000000000..d9553588eb --- /dev/null +++ b/c/src/lib/libbsp/arm/jetson-tk1/clock/car.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) OTH Regensburg, 2017 + * Author: Andreas Kölbl + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include <stdint.h> +#include <bsp/car.h> +#include <bsp/memory.h> +#include <rtems/score/basedefs.h> + +#define CLK_ENB_L_SET (CAR + 0x320) +#define CLK_ENB_L_CLR (CAR + 0x324) +#define CLK_ENB_U_SET (CAR + 0x330) +#define CLK_ENB_U_CLR (CAR + 0x334) +#define CLK_SOURCE_UARTA (CAR + 0x178) +#define CLK_SOURCE_UARTD (CAR + 0x1c0) + +#define RST_DEV_L_SET (CAR + 0x300) +#define RST_DEV_L_CLR (CAR + 0x304) +#define RST_DEV_U_SET (CAR + 0x310) +#define RST_DEV_U_CLR (CAR + 0x314) + +#define GATE_UARTA (1 << 6) +#define GATE_UARTD (1 << 0) + +typedef struct { + void *enb_set; + void *enb_clear; +} clock_dev; + +typedef struct { + void *enb_set; + void *enb_clear; +} reset_dev; + +typedef const struct { + clock_dev clock; + reset_dev reset; + void *src_reg; + uint32_t gate; +} car_dev; + +static car_dev tegra124_car_dev[] = { + { + .clock = { + .enb_set = CLK_ENB_U_SET, + .enb_clear = CLK_ENB_U_CLR, + }, + .reset = { + .enb_set = RST_DEV_U_SET, + .enb_clear = RST_DEV_U_CLR, + }, + .src_reg = CLK_SOURCE_UARTD, + .gate = GATE_UARTD, + }, + { + .clock = { + .enb_set = CLK_ENB_L_SET, + .enb_clear = CLK_ENB_L_CLR, + }, + .reset = { + .enb_set = RST_DEV_L_SET, + .enb_clear = RST_DEV_L_CLR, + }, + .src_reg = (void *) CLK_SOURCE_UARTA, + .gate = GATE_UARTA, + }, +}; + +int tegra_car_set(uint32_t device_num) +{ + if (device_num > RTEMS_ARRAY_SIZE(tegra124_car_dev)) { + return -1; + } + + mmio_write(tegra124_car_dev[device_num].clock.enb_set, + tegra124_car_dev[device_num].gate); + + return 0; +} + +int tegra_car_gate(uint32_t device_num, uint32_t car_source) +{ + uint32_t source; + + if ((device_num > RTEMS_ARRAY_SIZE(tegra124_car_dev)) || + (car_source > CAR_GATE_MAX)) { + return -1; + } + + source = mmio_read(tegra124_car_dev[device_num].src_reg); + source &= ~(7 << CAR_GATE_OFFSET); + source |= car_source << CAR_GATE_OFFSET; + + mmio_write(tegra124_car_dev[device_num].src_reg, source); + + return 0; +} + +int tegra_car_clear(uint32_t device_num) +{ + if (device_num > RTEMS_ARRAY_SIZE(tegra124_car_dev)) { + return -1; + } + + mmio_write( + tegra124_car_dev[device_num].reset.enb_clear, + mmio_read(tegra124_car_dev[device_num].reset.enb_clear) | + tegra124_car_dev[device_num].gate + ); + + return 0; +} diff --git a/c/src/lib/libbsp/arm/jetson-tk1/clock/clockdrv.c b/c/src/lib/libbsp/arm/jetson-tk1/clock/clockdrv.c new file mode 100644 index 0000000000..52c2e7c9ef --- /dev/null +++ b/c/src/lib/libbsp/arm/jetson-tk1/clock/clockdrv.c @@ -0,0 +1,138 @@ +/* + * Copyright (c) OTH Regensburg, 2017 + * Author: Andreas Kölbl + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include <rtems.h> +#include <rtems/timecounter.h> +#include <rtems/bspIo.h> +#include <bsp.h> +#include <bsp/memory.h> +#include <bsp/irq.h> +#include <bsp/irq-generic.h> + +#define USEC_PER_SEC 1000000L +#define GICD_ICPENDR 0x1280 +#define TIMER_IRQ 27 + +/* This is defined in ../../../shared/clockdrv_shell.h */ +void Clock_isr(rtems_irq_hdl_param arg); +static uint32_t timecounter_ticks_per_clock_tick; +static struct timecounter clock_tc; + +static void gic_timer_start(uint32_t timeout) +{ + /* Write timeout into Virtual Timer TimerValue register */ + arm_write_cp15_32(0, c14, c3, 0, timeout); + /* Run the timer with Virtual Timer Control register */ + arm_write_cp15_32(0, c14, c3, 1, 1); +} + +static uint32_t jetson_clock_get_timecount(struct timecounter *tc) +{ + uint64_t ret = 0; + + /* Read the Physical Count Register */ + arm_read_cp15_64(0, c14, ret); + + /* This should be safe for rtems */ + return (uint32_t) ret; +} + +static void jetson_clock_at_tick(void) +{ + uint32_t CNTV_TVAL = 0; + + arm_read_cp15_32(0, c14, c3, 0, CNTV_TVAL); + + if ( CNTV_TVAL >= timecounter_ticks_per_clock_tick ) { + /* Clear pending interrupt */ + mmio_write(BSP_ARM_GIC_DIST_BASE + GICD_ICPENDR, 1); + /* Reset the Virtual Timer */ + arm_write_cp15_32(0, c14, c3, 1, 0); + gic_timer_start(timecounter_ticks_per_clock_tick); + } +} + +static void jetson_clock_handler_install_isr(rtems_isr_entry clock_isr) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + + if ( clock_isr != NULL ) { + sc = rtems_interrupt_handler_install( + TIMER_IRQ, + "Clock", + RTEMS_INTERRUPT_UNIQUE, + (rtems_interrupt_handler) clock_isr, + NULL + ); + } else { + sc = rtems_interrupt_handler_remove( + TIMER_IRQ, + (rtems_interrupt_handler) Clock_isr, + NULL + ); + } + + if ( sc != RTEMS_SUCCESSFUL ) { + printk("fatal: %p\n", (uint32_t *) clock_isr); + rtems_fatal_error_occurred(0xc10cd1f3); + } +} + +static void jetson_clock_initialize_hardware(void) +{ + uint32_t us_per_tick = rtems_configuration_get_microseconds_per_tick(); + uint32_t frequency; + + /* Get frequency of Generic Timer (CNTFRQ) */ + arm_read_cp15_32(0, c14, c0, 0, frequency); + timecounter_ticks_per_clock_tick = + ((uint64_t) frequency * us_per_tick) / (uint64_t) USEC_PER_SEC; + + gic_timer_start(timecounter_ticks_per_clock_tick); + clock_tc.tc_get_timecount = jetson_clock_get_timecount; + clock_tc.tc_counter_mask = 0xffffffff; + clock_tc.tc_frequency = frequency; + clock_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER; + rtems_timecounter_install(&clock_tc); +} + +static void jetson_clock_cleanup(void) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + + /* Stop the timer */ + arm_write_cp15_32(0, c14, c3, 1, 0); + + sc = rtems_interrupt_handler_remove( + TIMER_IRQ, + (rtems_interrupt_handler) Clock_isr, + NULL + ); + + if ( sc != RTEMS_SUCCESSFUL ) { + rtems_fatal_error_occurred(0xdeadbeef); + } +} + +#define Clock_driver_support_at_tick() jetson_clock_at_tick() + +#define Clock_driver_support_initialize_hardware() \ + jetson_clock_initialize_hardware() + +#define Clock_driver_support_shutdown_hardware() jetson_clock_cleanup() + +#define Clock_driver_support_install_isr(clock_isr, old_isr) \ + do { \ + jetson_clock_handler_install_isr(clock_isr); \ + old_isr = NULL; \ + } while ( 0 ) + +#define CLOCK_DRIVER_USE_ONLY_BOOT_PROCESSOR 1 + +#include "../../../shared/clockdrv_shell.h" diff --git a/c/src/lib/libbsp/arm/jetson-tk1/configure.ac b/c/src/lib/libbsp/arm/jetson-tk1/configure.ac new file mode 100644 index 0000000000..7d4dce3008 --- /dev/null +++ b/c/src/lib/libbsp/arm/jetson-tk1/configure.ac @@ -0,0 +1,39 @@ +AC_PREREQ([2.68]) +AC_INIT([rtems-c-src-lib-libbsp-arm-jetson-tk1],[_RTEMS_VERSION],[https://devel.rtems.org/newticket]) +AC_CONFIG_SRCDIR([bsp_specs]) +RTEMS_TOP(../../../../../..) + +RTEMS_CANONICAL_TARGET_CPU +AM_INIT_AUTOMAKE([no-define nostdinc foreign 1.12.2]) +RTEMS_BSP_CONFIGURE + +RTEMS_PROG_CC_FOR_TARGET +RTEMS_CANONICALIZE_TOOLS +RTEMS_PROG_CCAS + +RTEMS_BSPOPTS_SET([NS8250_CONSOLE_USE_INTERRUPTS],[*],[0]) +RTEMS_BSPOPTS_HELP([NS8250_CONSOLE_USE_INTERRUPTS],[Use interrupt driven mode for console devices]) + +RTEMS_BSPOPTS_SET([MEMORY_SIZE],[*],[0x4000000]) +RTEMS_BSPOPTS_HELP([MEMORY_SIZE],[Set the amount of memory the application can +use]) + +RTEMS_BSPOPTS_SET([TEGRA_BASE],[*],[0x80000000]) +RTEMS_BSPOPTS_HELP([TEGRA_BASE],[Base load address]) + +AC_DEFUN([TEGRA_LINKCMD],[ +AC_ARG_VAR([$1],[$2; default $3])dnl +[$1]=[$]{[$1]:-[$3]} +]) + +TEGRA_LINKCMD([MEMORY_SIZE],[Begin of RAM region],[${MEMORY_SIZE}]) +TEGRA_LINKCMD([TEGRA_BASE],[Base load address],[${TEGRA_BASE}]) + +AM_CONDITIONAL(HAS_SMP,[test "$rtems_cv_HAS_SMP" = "yes"]) + +RTEMS_BSP_CLEANUP_OPTIONS(0, 0) + +AC_CONFIG_FILES([ +Makefile +startup/linkcmds]) +AC_OUTPUT diff --git a/c/src/lib/libbsp/arm/jetson-tk1/console/console.c b/c/src/lib/libbsp/arm/jetson-tk1/console/console.c new file mode 100644 index 0000000000..408972e3fe --- /dev/null +++ b/c/src/lib/libbsp/arm/jetson-tk1/console/console.c @@ -0,0 +1,291 @@ +/* + * Copyright (c) OTH Regensburg, 2017 + * Author: Andreas Kölbl + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include <unistd.h> + +#include <rtems/console.h> +#include <rtems/termiostypes.h> +#include <rtems/bspIo.h> + +#include <bsp.h> +#include <bspopts.h> +#include <bsp/car.h> +#include <bsp/console.h> +#include <bsp/fatal.h> +#include <bsp/irq.h> +#include <bsp/memory.h> + +#define UART_TX 0x0 +#define UART_DLL 0x0 +#define UART_RBR 0x0 +#define UART_DLM 0x4 +#define UART_IER 0x4 +#define UART_IIR 0x8 +#define UART_LCR 0xc +#define UART_LCR_8N1 ((1 << 0) | (1 << 1)) +#define UART_LCR_DLAB (1 << 7) +#define UART_LSR 0x14 +#define UART_LSR_RDR (1 << 0) +#define UART_LSR_THRE (1 << 5) +#define UART_MSR 0x18 + +#define UART_IER_IE_RHR (1 << 0) +#define UART_IER_IE_THR (1 << 1) + +#define BSP_UART_DEFAULT_BAUD_RATE 115200L +#define BSP_UART_SPEED 408000000L + +typedef struct { + rtems_termios_device_context base; + void *regs; + uint32_t car; + bool console; + const char *device_name; +#if NS8250_CONSOLE_USE_INTERRUPTS == 1 + rtems_vector_number irq; + volatile bool transmitting; +#endif +} ns8250_uart_context; + +static ns8250_uart_context ns8250_uart_instances[] = { + { + .regs = UARTD, + .car = CAR_DEV_UARTD, + .device_name = "/dev/ttyS0", +#if NS8250_CONSOLE_USE_INTERRUPTS == 1 + .irq = UARTD_IRQ, + .transmitting = false, +#endif + }, + { + .regs = UARTA, + .car = CAR_DEV_UARTA, + .device_name = "/dev/ttyS1", +#if NS8250_CONSOLE_USE_INTERRUPTS == 1 + .irq = UARTA_IRQ, + .transmitting = false, +#endif + }, +}; + +static void ns8250_uart_write( + rtems_termios_device_context *context, + const char *buf, + size_t len +) +{ + ns8250_uart_context *ctx = (ns8250_uart_context *) context; + +#if NS8250_CONSOLE_USE_INTERRUPTS == 1 + + if ( len ) { + ctx->transmitting = true; + mmio_write(ctx->regs + UART_TX, buf[0]); + mmio_write(ctx->regs + UART_IER, + mmio_read(ctx->regs + UART_IER) | UART_IER_IE_THR); + } else { + mmio_write(ctx->regs + UART_IER, + mmio_read(ctx->regs + UART_IER) & ~UART_IER_IE_THR); + ctx->transmitting = false; + } + +#else + unsigned int i = 0; + + for ( i = 0; i < len; i++ ) { + while ( !(mmio_read(ctx->regs + UART_LSR) & UART_LSR_THRE) ) { + asm volatile("nop"); + } + + if ( buf[i] == '\n' ) { + mmio_write(ctx->regs + UART_TX, '\r'); + } + + mmio_write(ctx->regs + UART_TX, buf[i]); + } + +#endif +} + +#if NS8250_CONSOLE_USE_INTERRUPTS == 1 +static void ns8250_uart_interrupt_handler(void *arg) +{ + char input; + rtems_termios_tty *tty = arg; + ns8250_uart_context *ctx = rtems_termios_get_device_context(tty); + uint32_t lsr = mmio_read(ctx->regs + UART_LSR); + + if ( ctx->transmitting && lsr & UART_LSR_THRE ) { + rtems_termios_dequeue_characters(tty, 1); + } + + if ( lsr & UART_LSR_RDR ) { + input = mmio_read(ctx->regs + UART_RBR); + rtems_termios_enqueue_raw_characters(tty, &input, 1); + } +} +#endif + +static int ns8250_uart_poll_read(rtems_termios_device_context *context) +{ + int result; + ns8250_uart_context *ctx = (ns8250_uart_context *) context; + + /* Block until character appears */ + while ( !(mmio_read(ctx->regs + UART_LSR) & UART_LSR_RDR) ) { + asm volatile("nop"); + } + + /* Save read input to result */ + result = mmio_read(ctx->regs + UART_RBR); + + return result; +} + +static bool ns8250_uart_set_attributes( + rtems_termios_device_context *context, + const struct termios *term +) +{ + ns8250_uart_context *ctx = (ns8250_uart_context *) context; + rtems_termios_baud_t baud; + unsigned int lcr; + uint16_t divider; + + /* We only have baud rate support yet */ + baud = rtems_termios_baud_to_number(term->c_ospeed); + divider = BSP_UART_SPEED / (baud * 16); + lcr = mmio_read(ctx->regs + UART_LCR) | UART_LCR_DLAB; + mmio_write(ctx->regs + UART_LCR, lcr); + + mmio_write(ctx->regs + UART_DLL, divider & 0xff); + mmio_write(ctx->regs + UART_DLM, (divider >> 8) & 0xff); + lcr = UART_LCR_8N1; + mmio_write(ctx->regs + UART_LCR, lcr); + + return true; +} + +static bool ns8250_uart_first_open( + rtems_termios_tty *tty, + rtems_termios_device_context *context, + struct termios *term, + rtems_libio_open_close_args_t *args +) +{ +#if NS8250_CONSOLE_USE_INTERRUPTS == 1 + rtems_status_code status; +#endif + ns8250_uart_context *ctx = (ns8250_uart_context *) context; + + tegra_car_clear(ctx->car); + tegra_car_gate(ctx->car, CAR_SOURCE_UART); + tegra_car_set(ctx->car); + + rtems_termios_set_initial_baud(tty, BSP_UART_DEFAULT_BAUD_RATE); + + if ( !ns8250_uart_set_attributes(context, term) ) { + return false; + } + +#if NS8250_CONSOLE_USE_INTERRUPTS == 1 + /* Read everything pending */ + mmio_read(ctx->regs + UART_RBR); + mmio_read(ctx->regs + UART_IIR); + mmio_read(ctx->regs + UART_LSR); + mmio_read(ctx->regs + UART_MSR); + status = rtems_interrupt_handler_install( + ctx->irq, + ctx->device_name, + RTEMS_INTERRUPT_UNIQUE, + ns8250_uart_interrupt_handler, + tty + ); + if ( status != RTEMS_SUCCESSFUL ) { + return false; + } + + mmio_write(ctx->regs + UART_LCR, UART_LCR_8N1); + mmio_write(ctx->regs + UART_IER, UART_IER_IE_RHR); +#endif + + return true; +} + +static void ns8250_uart_last_close( + rtems_termios_tty *tty, + rtems_termios_device_context *context, + rtems_libio_open_close_args_t *args +) +{ +#if NS8250_CONSOLE_USE_INTERRUPTS == 1 + rtems_status_code status; + ns8250_uart_context *ctx = (ns8250_uart_context *) context; + + tegra_car_clear(ctx->car); + + status = rtems_interrupt_handler_remove( + ctx->irq, + ns8250_uart_interrupt_handler, + tty + ); + + if ( status != RTEMS_SUCCESSFUL ) { + rtems_fatal_error_occurred(status); + } + +#endif +} + +static const rtems_termios_device_handler ns8250_uart_handler = { + .first_open = ns8250_uart_first_open, + .last_close = ns8250_uart_last_close, + .write = ns8250_uart_write, + .set_attributes = ns8250_uart_set_attributes, +#if NS8250_CONSOLE_USE_INTERRUPTS == 1 + .mode = TERMIOS_IRQ_DRIVEN, +#else + .poll_read = ns8250_uart_poll_read, + .mode = TERMIOS_POLLED +#endif +}; + +rtems_status_code console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_status_code status; + + rtems_termios_initialize(); + unsigned int i = 0; + int err = 0; + + for ( i = 0; i < RTEMS_ARRAY_SIZE(ns8250_uart_instances); i++ ) { + status = rtems_termios_device_install( + ns8250_uart_instances[i].device_name, + &ns8250_uart_handler, + NULL, + &ns8250_uart_instances[i].base + ); + + if ( status != RTEMS_SUCCESSFUL ) { + rtems_fatal_error_occurred(status); + } + } + + err = link(ns8250_uart_instances[0].device_name, CONSOLE_DEVICE_NAME); + + if ( err ) { + printk("link: %d", err); + } + + return RTEMS_SUCCESSFUL; +} diff --git a/c/src/lib/libbsp/arm/jetson-tk1/console/debug-console.c b/c/src/lib/libbsp/arm/jetson-tk1/console/debug-console.c new file mode 100644 index 0000000000..44b9b6a0fe --- /dev/null +++ b/c/src/lib/libbsp/arm/jetson-tk1/console/debug-console.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) OTH Regensburg, 2017 + * Author: Andreas Kölbl + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include <bsp.h> +#include <bsp/console.h> +#include <bsp/memory.h> +#include <rtems/bspIo.h> + +#define UART_LSR 0x14 +#define UART_LSR_RDR (1 << 0) + +#define UART_RBR (0 << 0) + +static void ns8250_debug_console_out(char c) +{ + while ( !(mmio_read(UARTD + UART_LSR) & UART_LSR_THRE) ) { + asm volatile ("nop"); + } + + if ( c == '\n' ) { + mmio_write(UARTD + UART_TX, '\r'); + } + + mmio_write( UARTD + UART_TX, c ); +} + +static int ns8250_debug_console_in(void) +{ + int result; + + while ( !(mmio_read( UARTD + UART_LSR ) & UART_LSR_RDR) ) { + asm volatile ( "nop" ); + } + + /* Read from UARTD */ + result = mmio_read(UARTD + UART_RBR); + /* Clear interrupts */ + mmio_write(UARTD + UART_LSR, 0); + + return result; +} + +BSP_output_char_function_type BSP_output_char = ns8250_debug_console_out; +BSP_polling_getchar_function_type BSP_poll_char = ns8250_debug_console_in; diff --git a/c/src/lib/libbsp/arm/jetson-tk1/include/bsp.h b/c/src/lib/libbsp/arm/jetson-tk1/include/bsp.h new file mode 100644 index 0000000000..ea4dcb74e4 --- /dev/null +++ b/c/src/lib/libbsp/arm/jetson-tk1/include/bsp.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) OTH Regensburg, 2017 + * Author: Andreas Kölbl + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef LIBBSP_ARM_JETSONTK1_BSP_H +#define LIBBSP_ARM_JETSONTK1_BSP_H + +#include <bspopts.h> +#include <rtems.h> +#include <bsp/default-initial-extension.h> + +#define BSP_ARM_GIC_DIST_BASE ((void *) 0x50041000) +#define BSP_ARM_GIC_CPUIF_BASE ((void *) 0x50042000) + +#define APB_MISC_BASE ((void*) 0x70000000) +#define PMC_BASE (APB_MISC_BASE + 0xE400) + +#define TIMER_BASE ((void *) 0x60005000) + +#endif /* LIBBSP_ARM_JETSONTK1_BSP_H */ diff --git a/c/src/lib/libbsp/arm/jetson-tk1/include/car.h b/c/src/lib/libbsp/arm/jetson-tk1/include/car.h new file mode 100644 index 0000000000..8b9687386f --- /dev/null +++ b/c/src/lib/libbsp/arm/jetson-tk1/include/car.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) OTH Regensburg, 2017 + * Author: Andreas Kölbl + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef LIBBSP_ARM_JETSONTK1_CAR_H +#define LIBBSP_ARM_JETSONTK1_CAR_H + +#include <bspopts.h> + +#define CAR ((void *) 0x60006000) + +/* UART clock source: PLLC_OUT0 */ +#define CAR_SOURCE_UART 0 + +#define CAR_DEV_UARTD 0 /* U */ +#define CAR_DEV_UARTA 1 /* L */ + +#define CAR_GATE_MAX 31 +#define CAR_GATE_OFFSET 29 + +int tegra_car_set(uint32_t device_num); +int tegra_car_gate(uint32_t device_num, uint32_t car_source); +int tegra_car_clear(uint32_t device_num); + +#endif /* LIBBSP_ARM_JETSONTK1_CAR_H */ diff --git a/c/src/lib/libbsp/arm/jetson-tk1/include/console.h b/c/src/lib/libbsp/arm/jetson-tk1/include/console.h new file mode 100644 index 0000000000..e5191b48e0 --- /dev/null +++ b/c/src/lib/libbsp/arm/jetson-tk1/include/console.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) OTH Regensburg, 2017 + * Author: Andreas Kölbl + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef LIBBSP_ARM_JETSONTK1_CONSOLE_H +#define LIBBSP_ARM_JETSONTK1_CONSOLE_H + +#include <rtems/termiostypes.h> +#include <bsp/memory.h> + +#define UARTA ((void *) 0x70006000) +#define UARTD ((void *) 0x70006300) + +#define UART_TX 0x0 +#define UART_LSR 0x14 +#define UART_LSR_THRE (1 << 5) + +#define UARTA_IRQ (36 + 32) +#define UARTD_IRQ (90 + 32) + +rtems_status_code console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +); + +#endif /* LIBBSP_ARM_JETSONTK1_CONSOLE_H */ diff --git a/c/src/lib/libbsp/arm/jetson-tk1/include/irq.h b/c/src/lib/libbsp/arm/jetson-tk1/include/irq.h new file mode 100644 index 0000000000..200c8c78fa --- /dev/null +++ b/c/src/lib/libbsp/arm/jetson-tk1/include/irq.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) OTH Regensburg, 2017 + * Author: Andreas Kölbl + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef LIBBSP_ARM_JETSONTK1_IRQ_H +#define LIBBSP_ARM_JETSONTK1_IRQ_H + +#ifndef ASM + +#include <rtems.h> +#include <rtems/irq.h> +#include <rtems/irq-extension.h> +#include <bsp/arm-gic-irq.h> +#include <bsp.h> + +#define BSP_INTERRUPT_VECTOR_MIN 0 +#define BSP_INTERRUPT_VECTOR_MAX 160 + +#endif /* ASM */ +#endif /* LIBBSP_ARM_JETSONTK1_IRQ_H */ diff --git a/c/src/lib/libbsp/arm/jetson-tk1/include/memory.h b/c/src/lib/libbsp/arm/jetson-tk1/include/memory.h new file mode 100644 index 0000000000..a65e53e0a4 --- /dev/null +++ b/c/src/lib/libbsp/arm/jetson-tk1/include/memory.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) OTH Regensburg, 2017 + * Author: Andreas Kölbl + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef LIBBSP_ARM_JETSONTK1_MEMORY_H +#define LIBBSP_ARM_JETSONTK1_MEMORY_H + +#define arm_write_cp15_32(op1, crn, crm, op2, val) \ + asm volatile("mcr p15, "#op1 ", %0, "#crn ", "#crm ", "#op2 "\n" \ + : : "r" ((uint32_t) (val))) +#define arm_write_cp15_64(op1, crm, val) \ + asm volatile("mcrr p15, "#op1 ", %Q0, %R0, "#crm "\n" \ + : : "r" ((uint64_t) (val))) + +#define arm_read_cp15_32(op1, crn, crm, op2, val) \ + asm volatile("mrc p15, "#op1 ", %0, "#crn ", "#crm ", "#op2 "\n" \ + : "=r" ((uint32_t) (val))) +#define arm_read_cp15_64(op1, crm, val) \ + asm volatile("mrrc p15, "#op1 ", %Q0, %R0, "#crm "\n" \ + : "=r" ((uint64_t) (val))) + +#define mmio_read(address) (*(volatile uint32_t *) (address)) +#define mmio_write(address, value) \ + (*(volatile uint32_t *) (address) = (value)) + +#endif /* LIBBSP_ARM_JETSONTK1_MEMORY_H */ diff --git a/c/src/lib/libbsp/arm/jetson-tk1/include/mmu.h b/c/src/lib/libbsp/arm/jetson-tk1/include/mmu.h new file mode 100644 index 0000000000..fb8685aa12 --- /dev/null +++ b/c/src/lib/libbsp/arm/jetson-tk1/include/mmu.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) OTH Regensburg, 2017 + * Author: Andreas Kölbl + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef LIBBSP_ARM_JETSONTK1_MMU_H +#define LIBBSP_ARM_JETSONTK1_MMU_H + +#include <bsp/start.h> +#include <bsp/arm-cp15-start.h> +#include <libcpu/arm-cp15.h> + +static __attribute__((always_inline)) void jetson_setup_mmu_and_cache(void) +{ + unsigned int sctlr; + + arm_cp15_start_setup_translation_table( + (uint32_t *) bsp_translation_table_base, + ARM_MMU_DEFAULT_CLIENT_DOMAIN, + arm_cp15_start_mmu_config_table, + arm_cp15_start_mmu_config_table_size + ); + sctlr = arm_cp15_get_control(); + + arm_cp15_instruction_cache_invalidate(); + arm_cp15_branch_predictor_invalidate_all(); + arm_cp15_tlb_invalidate(); + arm_cp15_flush_prefetch_buffer(); + + arm_cp15_set_translation_table_base_control_register(0); + + sctlr |= ARM_CP15_CTRL_I | ARM_CP15_CTRL_C | ARM_CP15_CTRL_M | + ARM_CP15_CTRL_Z | ARM_CP15_CTRL_A | ARM_CP15_CTRL_AFE; + arm_cp15_set_control( sctlr ); + arm_cp15_tlb_invalidate(); +} + +#endif /* LIBBSP_ARM_JETSONTK1_MMU_H */ diff --git a/c/src/lib/libbsp/arm/jetson-tk1/make/custom/jetson-tk1.cfg b/c/src/lib/libbsp/arm/jetson-tk1/make/custom/jetson-tk1.cfg new file mode 100644 index 0000000000..bc7fb9b70a --- /dev/null +++ b/c/src/lib/libbsp/arm/jetson-tk1/make/custom/jetson-tk1.cfg @@ -0,0 +1,16 @@ +include $(RTEMS_ROOT)/make/custom/default.cfg + +RTEMS_CPU = arm +RTEMS_CPU_MODEL = cortex-a15 + +CFLAGS_OPTIMIZE_V ?= -O2 -g +CFLAGS_OPTIMIZE_V += -ffunction-sections -fdata-sections + +CPU_CFLAGS = -march=armv7ve -mtune=cortex-a15 -mfpu=neon-vfpv4 +LDFLAGS = -Wl,--gc-sections + +define bsp-post-link + $(OBJCOPY) -O binary --strip-all \ + $(basename $@)$(EXEEXT) $(basename $@)$(DOWNEXT) + $(SIZE) $(basename $@)$(EXEEXT) +endef diff --git a/c/src/lib/libbsp/arm/jetson-tk1/misc/timer.c b/c/src/lib/libbsp/arm/jetson-tk1/misc/timer.c new file mode 100644 index 0000000000..d7ed8967a5 --- /dev/null +++ b/c/src/lib/libbsp/arm/jetson-tk1/misc/timer.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) OTH Regensburg, 2017 + * Author: Andreas Kölbl + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include <bsp.h> +#include <rtems.h> +#include <rtems/btimer.h> +#include <bsp/memory.h> + +#define TMR1 (0x0) +#define TMR2 (0x8) +#define TIMERUS (0x10) +#define TMR3 (0x50) +#define TMR4 (0x58) +#define TMR5 (0x60) +#define TMR6 (0x68) +#define TMR7 (0x70) +#define TMR8 (0x78) +#define TMR9 (0x80) +#define TMR0 (0x88) + +#define TIMERUS_BASE (TIMER_BASE + TIMERUS) + +#define TIMERUS_CFG 0x4 +#define TIMERUS_CNTR 0x0 +#define TIMERUS_USEC_CFG_12MHZ 0x000b + +static bool benchmark_timer_find_average_overhead = true; + +static uint32_t benchmark_timer_base; + +void benchmark_timer_initialize(void) +{ + /* Set clock speed */ + mmio_write(TIMERUS_BASE + TIMERUS_CFG, TIMERUS_USEC_CFG_12MHZ); + /* Write timeout into Virtual Timer TimerValue register */ + arm_write_cp15_32(0, c14, c3, 0, UINT32_MAX ); + /* Run the timer with Virtual Timer Control register */ + arm_write_cp15_32(0, c14, c3, 1, 1); + benchmark_timer_base = mmio_read(TIMERUS_BASE + TIMERUS_CNTR); +} + +benchmark_timer_t benchmark_timer_read(void) +{ + benchmark_timer_t delta; + + delta = mmio_read(TIMERUS_BASE + TIMERUS_CNTR) - benchmark_timer_base; + + if ( benchmark_timer_find_average_overhead == true) { + return delta; + } else { + return mmio_read(TIMERUS_BASE + TIMERUS_CNTR); + } +} + +void benchmark_timer_disable_subtracting_average_overhead(bool find_flag) +{ + benchmark_timer_find_average_overhead = find_flag; +} diff --git a/c/src/lib/libbsp/arm/jetson-tk1/startup/bspreset.c b/c/src/lib/libbsp/arm/jetson-tk1/startup/bspreset.c new file mode 100644 index 0000000000..d3120cb564 --- /dev/null +++ b/c/src/lib/libbsp/arm/jetson-tk1/startup/bspreset.c @@ -0,0 +1,19 @@ +/* + * Copyright (c) OTH Regensburg, 2017 + * Author: Andreas Kölbl + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include <bsp.h> +#include <bsp/memory.h> +#include <bsp/bootcard.h> + +#define MAIN_RST 4 + +void bsp_reset(void) +{ + mmio_write(PMC_BASE, mmio_read(PMC_BASE) | (1 << MAIN_RST)); +} diff --git a/c/src/lib/libbsp/arm/jetson-tk1/startup/bspstart.c b/c/src/lib/libbsp/arm/jetson-tk1/startup/bspstart.c new file mode 100644 index 0000000000..5deadf7b63 --- /dev/null +++ b/c/src/lib/libbsp/arm/jetson-tk1/startup/bspstart.c @@ -0,0 +1,16 @@ +/* + * Copyright (c) OTH Regensburg, 2017 + * Author: Andreas Kölbl + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include <bsp/irq-generic.h> +#include <bsp/bootcard.h> + +void bsp_start(void) +{ + bsp_interrupt_initialize(); +} diff --git a/c/src/lib/libbsp/arm/jetson-tk1/startup/bspstarthooks.c b/c/src/lib/libbsp/arm/jetson-tk1/startup/bspstarthooks.c new file mode 100644 index 0000000000..01ebcdffa8 --- /dev/null +++ b/c/src/lib/libbsp/arm/jetson-tk1/startup/bspstarthooks.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) OTH Regensburg, 2017 + * Author: Andreas Kölbl + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include <bsp.h> +#include <bsp/mmu.h> +#include <bsp/arm-cache-l1.h> +#include <rtems.h> + +void BSP_START_TEXT_SECTION bsp_start_hook_0(void) +{ +} + +void BSP_START_TEXT_SECTION bsp_start_hook_1(void) +{ + uint32_t sctlr; + + /* + * Do not use bsp_vector_table_begin == 0, since this will get optimized away. + */ + if (bsp_vector_table_end != bsp_vector_table_size) { + arm_cp15_set_vector_base_address(bsp_vector_table_begin); + + sctlr = arm_cp15_get_control(); + sctlr &= ~ARM_CP15_CTRL_V; + arm_cp15_set_control(sctlr); + } + + /* + * Current U-boot loader seems to start kernel image + * with I and D caches on and MMU enabled. + * If RTEMS application image finds that cache is on + * during startup then disable caches. + */ + if ( sctlr & (ARM_CP15_CTRL_I | ARM_CP15_CTRL_C | ARM_CP15_CTRL_M | + ARM_CP15_CTRL_A | ARM_CP15_CTRL_Z) ) { + if ( sctlr & (ARM_CP15_CTRL_C | ARM_CP15_CTRL_M) ) { + /* + * If the data cache is on then ensure that it is clean + * before switching off to be extra carefull. + */ + arm_cp15_data_cache_clean_all_levels(); + } + rtems_cache_invalidate_entire_data(); + arm_cp15_flush_prefetch_buffer(); + sctlr &= ~(ARM_CP15_CTRL_I | ARM_CP15_CTRL_C | ARM_CP15_CTRL_M | + ARM_CP15_CTRL_Z | ARM_CP15_CTRL_A); + arm_cp15_set_control(sctlr); + + } + bsp_start_copy_sections(); + jetson_setup_mmu_and_cache(); + bsp_start_clear_bss(); +} diff --git a/c/src/lib/libbsp/arm/jetson-tk1/startup/linkcmds.in b/c/src/lib/libbsp/arm/jetson-tk1/startup/linkcmds.in new file mode 100644 index 0000000000..f37a62faed --- /dev/null +++ b/c/src/lib/libbsp/arm/jetson-tk1/startup/linkcmds.in @@ -0,0 +1,39 @@ +bsp_mmu_size = 16k; + +MEMORY { + RAM (AIW) : ORIGIN = @TEGRA_BASE@, LENGTH = @MEMORY_SIZE@ - bsp_mmu_size + RAM_MMU (AIW) : ORIGIN = @TEGRA_BASE@ + @MEMORY_SIZE@ - bsp_mmu_size, LENGTH = bsp_mmu_size +} + +bsp_processor_count = DEFINED (bsp_processor_count) ? bsp_processor_count : 1; + +REGION_ALIAS ("REGION_START", RAM); +REGION_ALIAS ("REGION_VECTOR", RAM); +REGION_ALIAS ("REGION_TEXT", RAM); +REGION_ALIAS ("REGION_TEXT_LOAD", RAM); +REGION_ALIAS ("REGION_RODATA", RAM); +REGION_ALIAS ("REGION_RODATA_LOAD", RAM); +REGION_ALIAS ("REGION_DATA", RAM); +REGION_ALIAS ("REGION_DATA_LOAD", RAM); +REGION_ALIAS ("REGION_FAST_TEXT", RAM); +REGION_ALIAS ("REGION_FAST_TEXT_LOAD", RAM); +REGION_ALIAS ("REGION_FAST_DATA", RAM); +REGION_ALIAS ("REGION_FAST_DATA_LOAD", RAM); +REGION_ALIAS ("REGION_BSS", RAM); +REGION_ALIAS ("REGION_WORK", RAM); +REGION_ALIAS ("REGION_STACK", RAM); +REGION_ALIAS ("REGION_NOCACHE", RAM); +REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM); + +bsp_stack_irq_size = DEFINED (bsp_stack_irq_size) ? bsp_stack_irq_size : 4096; +bsp_stack_abt_size = DEFINED (bsp_stack_abt_size) ? bsp_stack_abt_size : 1024; + +bsp_vector_table_in_start_section = 1; +bsp_section_robarrier_align = DEFINED (bsp_section_robarrier_align) ? bsp_section_robarrier_align : 1M; + +bsp_translation_table_base = ORIGIN (RAM_MMU); +bsp_translation_table_end = ORIGIN (RAM_MMU) + LENGTH (RAM_MMU); + +INCLUDE linkcmds.armv4 + +HeapSize = DEFINED(HeapSize) ? HeapSize : 1024*1024; diff --git a/c/src/lib/libbsp/arm/jetson-tk1/startup/mm_config_table.c b/c/src/lib/libbsp/arm/jetson-tk1/startup/mm_config_table.c new file mode 100644 index 0000000000..a8c3f41ccf --- /dev/null +++ b/c/src/lib/libbsp/arm/jetson-tk1/startup/mm_config_table.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) OTH Regensburg, 2017 + * Author: Andreas Kölbl + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include <bsp.h> +#include <bspopts.h> +#include <bsp/car.h> +#include <bsp/console.h> +#include <bsp/arm-cp15-start.h> + +/* + * Pagetable initialization data + * + * Keep all read-only sections before read-write ones. + * This ensures that write is allowed if one page/region + * is partially filled by read-only section content + * and rest is used for writeable section + */ + +BSP_START_DATA_SECTION const arm_cp15_start_section_config +arm_cp15_start_mmu_config_table[] = { + ARMV7_CP15_START_DEFAULT_SECTIONS, + { + .begin = (uint32_t) CAR, + .end = (uint32_t) (CAR + 0x1000), + .flags = ARMV7_MMU_DEVICE + }, { + .begin = (uint32_t) TIMER_BASE, + .end = (uint32_t) (TIMER_BASE + 0x1000), + .flags = ARMV7_MMU_DEVICE + }, { + .begin = (uint32_t) APB_MISC_BASE, + .end = (uint32_t) (APB_MISC_BASE + 0x1000), + .flags = ARMV7_MMU_DEVICE + }, { + .begin = (uint32_t) UARTA, + .end = (uint32_t) UARTA + 0x1000, + .flags = ARMV7_MMU_DEVICE + }, { + .begin = (uint32_t) BSP_ARM_GIC_DIST_BASE, + .end = (uint32_t) (BSP_ARM_GIC_DIST_BASE + 0x1000), + .flags = ARMV7_MMU_DEVICE + }, { + .begin = (uint32_t) BSP_ARM_GIC_CPUIF_BASE, + .end = (uint32_t) (BSP_ARM_GIC_CPUIF_BASE + 0x1000), + .flags = ARMV7_MMU_DEVICE + } +}; + +const size_t arm_cp15_start_mmu_config_table_size = + RTEMS_ARRAY_SIZE(arm_cp15_start_mmu_config_table); -- 2.13.3 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel