Merge branch master into pae
This commit is contained in:
commit
a5e442a70e
21 changed files with 827 additions and 22 deletions
9
Kconfig
9
Kconfig
|
|
@ -163,6 +163,13 @@ config ARCH_IA32
|
|||
depends on ARCH_I386
|
||||
help
|
||||
Support for PC99 based platform
|
||||
|
||||
config PLAT_ALLWINNERA20
|
||||
bool "ALLWINNERA20 (CUBIETRUCK)"
|
||||
depends on ARCH_ARM
|
||||
depends on ARM_CORTEX_A15
|
||||
help
|
||||
Support for ALLWINNERA20 platform (CUBIETRUCK).
|
||||
endchoice
|
||||
|
||||
source "$KERNEL_PATH/src/plat/pc99/Kconfig"
|
||||
|
|
@ -250,7 +257,7 @@ menu "seL4 System Parameters"
|
|||
configuration.
|
||||
|
||||
config NUM_PRIORITIES
|
||||
int "Numer of priority levels"
|
||||
int "Number of priority levels"
|
||||
default 256
|
||||
help
|
||||
The number of priority levels per domain
|
||||
|
|
|
|||
6
Makefile
6
Makefile
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
ARCH_LIST:=arm ia32
|
||||
CPU_LIST:=arm1136jf-s ixp420 cortex-a8 cortex-a9 cortex-a15
|
||||
PLAT_LIST:=imx31 pc99 ixp420 omap3 am335x exynos4 exynos5 imx6 apq8064 zynq7000
|
||||
PLAT_LIST:=imx31 pc99 ixp420 omap3 am335x exynos4 exynos5 imx6 apq8064 zynq7000 allwinnerA20
|
||||
ARMV_LIST:=armv6 armv7-a
|
||||
|
||||
ifndef SOURCE_ROOT
|
||||
|
|
@ -354,10 +354,12 @@ ASFLAGS += -Wa,-mcpu=${CPU} -Wa,-march=${ARMV}
|
|||
DEFINES += -D$(shell echo ${ARMV}|tr [:lower:] [:upper:]|tr - _)
|
||||
ifeq (${CPU},cortex-a8)
|
||||
DEFINES += -DARM_CORTEX_A8
|
||||
else
|
||||
endif
|
||||
ifeq (${CPU},cortex-a9)
|
||||
DEFINES += -DARM_CORTEX_A9
|
||||
endif
|
||||
ifeq (${CPU},cortex-a15)
|
||||
DEFINES += -DARM_CORTEX_A15
|
||||
endif
|
||||
endif
|
||||
|
||||
|
|
|
|||
11
include/plat/allwinnerA20/plat/Makefile
Executable file
11
include/plat/allwinnerA20/plat/Makefile
Executable file
|
|
@ -0,0 +1,11 @@
|
|||
#
|
||||
# Copyright 2015, DornerWorks, Ltd.
|
||||
#
|
||||
# This software may be distributed and modified according to the terms of
|
||||
# the GNU General Public License version 2. Note that NO WARRANTY is provided.
|
||||
# See "LICENSE_GPLv2.txt" for details.
|
||||
#
|
||||
# @TAG(GD_GPL)
|
||||
#
|
||||
|
||||
include ${SOURCE_ROOT}/include/plat/${PLAT}/plat/machine/Makefile
|
||||
151
include/plat/allwinnerA20/plat/machine.h
Normal file
151
include/plat/allwinnerA20/plat/machine.h
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
* Copyright 2015, DornerWorks, Ltd.
|
||||
*
|
||||
* This software may be distributed and modified according to the terms of
|
||||
* the GNU General Public License version 2. Note that NO WARRANTY is provided.
|
||||
* See "LICENSE_GPLv2.txt" for details.
|
||||
*
|
||||
* @TAG(GD_GPL)
|
||||
*/
|
||||
|
||||
#ifndef __PLAT_MACHINE_H
|
||||
#define __PLAT_MACHINE_H
|
||||
|
||||
#include <arch/machine/gic_pl390.h>
|
||||
|
||||
#define N_INTERRUPTS 122
|
||||
|
||||
enum IRQConstants {
|
||||
SGI_0 = 0,
|
||||
SGI_1 = 1,
|
||||
SGI_2 = 2,
|
||||
SGI_3 = 3,
|
||||
SGI_4 = 4,
|
||||
SGI_5 = 5,
|
||||
SGI_6 = 6,
|
||||
SGI_7 = 7,
|
||||
SGI_8 = 8,
|
||||
SGI_9 = 9,
|
||||
SGI_10 = 10,
|
||||
SGI_11 = 11,
|
||||
SGI_12 = 12,
|
||||
SGI_13 = 13,
|
||||
SGI_14 = 14,
|
||||
SGI_15 = 15,
|
||||
PPI_0 = 16,
|
||||
PPI_1 = 17,
|
||||
PPI_2 = 18,
|
||||
PPI_3 = 19,
|
||||
PPI_4 = 20,
|
||||
PPI_5 = 21,
|
||||
PPI_6 = 22,
|
||||
PPI_7 = 23,
|
||||
PPI_8 = 24,
|
||||
PPI_9 = 25,
|
||||
PPI_10 = 26,
|
||||
PPI_11 = 27,
|
||||
PPI_12 = 28,
|
||||
PPI_13 = 29,
|
||||
PPI_14 = 30,
|
||||
PPI_15 = 31,
|
||||
NMI = 32,
|
||||
UART_0 = 33,
|
||||
UART_1 = 34,
|
||||
UART_2 = 35,
|
||||
UART_3 = 36,
|
||||
IR_0 = 37,
|
||||
IR_1 = 38,
|
||||
TWI_0 = 39,
|
||||
TWI_1 = 40,
|
||||
TWI_2 = 41,
|
||||
SPI_0 = 42,
|
||||
SPI_1 = 43,
|
||||
SPI_2 = 44,
|
||||
OWA = 45,
|
||||
AC97 = 46,
|
||||
TS = 47,
|
||||
IIS0 = 48,
|
||||
UART_4 = 49,
|
||||
UART_5 = 50,
|
||||
UART_6 = 51,
|
||||
UART_7 = 52,
|
||||
KEYPAD = 53,
|
||||
TIMER_0 = 54,
|
||||
TIMER_1 = 55,
|
||||
TIMER_2 = 56,
|
||||
TIMER_3 = 57,
|
||||
CAN = 58,
|
||||
DMA = 59,
|
||||
PIO = 60,
|
||||
TOUCH_PANEL = 61,
|
||||
AUDIO_CODEC = 62,
|
||||
LRADC = 63,
|
||||
MMC_0 = 64,
|
||||
MMC_1 = 65,
|
||||
MMC_2 = 66,
|
||||
MMC_3 = 67,
|
||||
MS = 68,
|
||||
NAND = 69,
|
||||
USB_0 = 70,
|
||||
USB_1 = 71,
|
||||
USB_2 = 72,
|
||||
SCR = 73,
|
||||
CSI_0 = 74,
|
||||
CSI_1 = 75,
|
||||
LCD_0 = 76,
|
||||
LCD_1 = 77,
|
||||
MP = 78,
|
||||
DE_FE0 = 79,
|
||||
DE_FE1 = 80,
|
||||
PMU = 81,
|
||||
SPI3 = 82,
|
||||
RESERVED_IRQ01 = 83,
|
||||
RESERVED_IRQ02 = 84,
|
||||
VE = 85,
|
||||
SS = 86,
|
||||
EMAC = 87,
|
||||
SATA = 88,
|
||||
RESERVED_IRQ03 = 89,
|
||||
HDMI_0 = 90,
|
||||
TVE = 91,
|
||||
ACE = 92,
|
||||
TVD = 93,
|
||||
PS2_0 = 94,
|
||||
PS2_1 = 95,
|
||||
USB_3 = 96,
|
||||
USB_4 = 97,
|
||||
PLE = 98,
|
||||
TIMER_4 = 99,
|
||||
TIMER_5 = 100,
|
||||
GPU_GP = 101,
|
||||
GPU_GPMMU = 102,
|
||||
GPU_PP0 = 103,
|
||||
GPU_PPMMU0 = 104,
|
||||
GPU_PMU = 105,
|
||||
GPU_PP1 = 106,
|
||||
GPU_PPMMU1 = 107,
|
||||
GPU_RSV0 = 108,
|
||||
GPU_RSV1 = 109,
|
||||
GPU_RSV2 = 110,
|
||||
GPU_RSV3 = 111,
|
||||
GPU_RSV4 = 112,
|
||||
HS_TIMER_0 = 113,
|
||||
HS_TIMER_1 = 114,
|
||||
HS_TIMER_2 = 115,
|
||||
HS_TIMER_3 = 116,
|
||||
GMAC = 117,
|
||||
HDMI_1 = 118,
|
||||
IIS1 = 119,
|
||||
TWI_3 = 120,
|
||||
TWI_4 = 121,
|
||||
IIS_2 = 122,
|
||||
maxIRQ = 122
|
||||
} platform_interrupt_t;
|
||||
|
||||
#define KERNEL_TIMER_IRQ TIMER_0
|
||||
|
||||
enum irqNumbers {
|
||||
irqInvalid = 255
|
||||
};
|
||||
|
||||
#endif /* ! __PLAT_MACHINE_H */
|
||||
13
include/plat/allwinnerA20/plat/machine/Makefile
Executable file
13
include/plat/allwinnerA20/plat/machine/Makefile
Executable file
|
|
@ -0,0 +1,13 @@
|
|||
#
|
||||
# Copyright 2015, DornerWorks, Ltd.
|
||||
#
|
||||
# This software may be distributed and modified according to the terms of
|
||||
# the GNU General Public License version 2. Note that NO WARRANTY is provided.
|
||||
# See "LICENSE_GPLv2.txt" for details.
|
||||
#
|
||||
# @TAG(GD_GPL)
|
||||
#
|
||||
|
||||
DIRECTORIES += plat/machine
|
||||
|
||||
BF_SOURCES += plat/machine/hardware.bf
|
||||
17
include/plat/allwinnerA20/plat/machine/debug_helpers.h
Executable file
17
include/plat/allwinnerA20/plat/machine/debug_helpers.h
Executable file
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright 2015, DornerWorks, Ltd.
|
||||
*
|
||||
* This software may be distributed and modified according to the terms of
|
||||
* the GNU General Public License version 2. Note that NO WARRANTY is provided.
|
||||
* See "LICENSE_GPLv2.txt" for details.
|
||||
*
|
||||
* @TAG(GD_GPL)
|
||||
*/
|
||||
|
||||
#ifndef __PLAT_MACHINE_DEBUG_HELPERS_H
|
||||
#define __PLAT_MACHINE_DEBUG_HELPERS_H
|
||||
|
||||
#include <plat/machine/io.h>
|
||||
|
||||
#endif
|
||||
|
||||
47
include/plat/allwinnerA20/plat/machine/devices.h
Normal file
47
include/plat/allwinnerA20/plat/machine/devices.h
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright 2015, DornerWorks, Ltd.
|
||||
*
|
||||
* This software may be distributed and modified according to the terms of
|
||||
* the GNU General Public License version 2. Note that NO WARRANTY is provided.
|
||||
* See "LICENSE_GPLv2.txt" for details.
|
||||
*
|
||||
* @TAG(GD_GPL)
|
||||
*/
|
||||
|
||||
/*
|
||||
definitions for memory addresses of allwinner A20 platform
|
||||
listed in the order of ascending memory address, similar to the datasheet
|
||||
the size must all be powers of 2 and page aligned (4k or 1M).
|
||||
*/
|
||||
|
||||
#ifndef __PLAT_MACHINE_DEVICES_H
|
||||
#define __PLAT_MACHINE_DEVICES_H
|
||||
|
||||
/* These devices are used by the seL4 kernel. */
|
||||
#define UART0_PPTR 0xfff01000
|
||||
#define TIMER0_PPTR 0xfff02000
|
||||
#define GIC_DISTRIBUTOR_PPTR 0xfff03000
|
||||
#define GIC_CONTROLLER_PPTR 0xfff04000
|
||||
|
||||
#define GIC_PL390_CONTROLLER_PPTR GIC_CONTROLLER_PPTR
|
||||
#define GIC_PL390_DISTRIBUTOR_PPTR GIC_DISTRIBUTOR_PPTR
|
||||
|
||||
#define GIC_DISTRIBUTOR_PADDR GIC_PADDR + 0x1000
|
||||
#define GIC_CONTROLLER0_PADDR GIC_PADDR + 0x2000
|
||||
|
||||
|
||||
|
||||
#define UART0_PADDR 0x01C28000
|
||||
|
||||
/* CCU, Interrupt, Timer, OWA */
|
||||
/* Timer = PPTR + 0xC00 */
|
||||
#define TIMER0_PADDR 0x01C20000
|
||||
|
||||
#define GIC_PADDR 0x01C80000
|
||||
|
||||
/* TODO: Add other devices PADDRs */
|
||||
|
||||
#define SPI0_PADDR 0x01C05000
|
||||
#define SPI1_PADDR 0x01C06000
|
||||
|
||||
#endif
|
||||
12
include/plat/allwinnerA20/plat/machine/hardware.bf
Executable file
12
include/plat/allwinnerA20/plat/machine/hardware.bf
Executable file
|
|
@ -0,0 +1,12 @@
|
|||
--
|
||||
-- Copyright 2015, DornerWorks, Ltd.
|
||||
--
|
||||
-- This software may be distributed and modified according to the terms of
|
||||
-- the GNU General Public License version 2. Note that NO WARRANTY is provided.
|
||||
-- See "LICENSE_GPLv2.txt" for details.
|
||||
--
|
||||
-- @TAG(GD_GPL)
|
||||
--
|
||||
|
||||
base 32
|
||||
|
||||
87
include/plat/allwinnerA20/plat/machine/hardware.h
Executable file
87
include/plat/allwinnerA20/plat/machine/hardware.h
Executable file
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Copyright 2015, DornerWorks, Ltd.
|
||||
*
|
||||
* This software may be distributed and modified according to the terms of
|
||||
* the GNU General Public License version 2. Note that NO WARRANTY is provided.
|
||||
* See "LICENSE_GPLv2.txt" for details.
|
||||
*
|
||||
* @TAG(GD_GPL)
|
||||
*/
|
||||
|
||||
#ifndef __PLAT_MACHINE_HARDWARE_H
|
||||
#define __PLAT_MACHINE_HARDWARE_H
|
||||
|
||||
#define physBase 0x48000000
|
||||
#define kernelBase 0xA0000000
|
||||
#define physMappingOffset (kernelBase - physBase)
|
||||
#define BASE_OFFSET physMappingOffset
|
||||
#define PPTR_TOP 0xfff00000
|
||||
#define PADDR_TOP (PPTR_TOP - BASE_OFFSET)
|
||||
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
#include <types.h>
|
||||
#include <arch/object/structures.h>
|
||||
#include <plat/machine.h>
|
||||
#include <plat/machine/hardware_gen.h>
|
||||
|
||||
static inline void* CONST
|
||||
ptrFromPAddr(paddr_t paddr)
|
||||
{
|
||||
return (void*)(paddr + physMappingOffset);
|
||||
}
|
||||
|
||||
static inline paddr_t CONST
|
||||
addrFromPPtr(void* pptr)
|
||||
{
|
||||
return (paddr_t)pptr - physMappingOffset;
|
||||
}
|
||||
|
||||
#define paddr_to_pptr ptrFromPAddr
|
||||
#define pptr_to_paddr addrFromPPtr
|
||||
|
||||
static inline region_t CONST
|
||||
paddr_to_pptr_reg(p_region_t p_reg)
|
||||
{
|
||||
return (region_t) {
|
||||
p_reg.start + physMappingOffset, p_reg.end + physMappingOffset
|
||||
};
|
||||
}
|
||||
|
||||
static inline p_region_t CONST
|
||||
pptr_to_paddr_reg(region_t reg)
|
||||
{
|
||||
return (p_region_t) {
|
||||
reg.start - physMappingOffset, reg.end - physMappingOffset
|
||||
};
|
||||
}
|
||||
|
||||
int get_num_avail_p_regs(void);
|
||||
p_region_t get_avail_p_reg(unsigned int i);
|
||||
int get_num_dev_p_regs(void);
|
||||
p_region_t get_dev_p_reg(unsigned int i);
|
||||
void map_kernel_devices(void);
|
||||
|
||||
bool_t CONST isReservedIRQ(irq_t irq);
|
||||
void handleReservedIRQ(irq_t irq);
|
||||
|
||||
/** MODIFIES: [*] */
|
||||
void resetTimer(void);
|
||||
/** MODIFIES: [*] */
|
||||
void initTimer(void);
|
||||
|
||||
/* L2 cache control */
|
||||
/** MODIFIES: [*] */
|
||||
void initL2Cache(void);
|
||||
|
||||
/** MODIFIES: [*] */
|
||||
static inline void plat_cleanL2Range(paddr_t start, paddr_t end) {}
|
||||
/** MODIFIES: [*] */
|
||||
static inline void plat_invalidateL2Range(paddr_t start, paddr_t end) {}
|
||||
/** MODIFIES: [*] */
|
||||
static inline void plat_cleanInvalidateL2Range(paddr_t start, paddr_t end) {}
|
||||
|
||||
#endif /* !__ASSEMBLER__ */
|
||||
|
||||
#endif
|
||||
26
include/plat/allwinnerA20/plat/machine/io.h
Executable file
26
include/plat/allwinnerA20/plat/machine/io.h
Executable file
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright 2015, DornerWorks, Ltd.
|
||||
*
|
||||
* This software may be distributed and modified according to the terms of
|
||||
* the GNU General Public License version 2. Note that NO WARRANTY is provided.
|
||||
* See "LICENSE_GPLv2.txt" for details.
|
||||
*
|
||||
* @TAG(GD_GPL)
|
||||
*/
|
||||
|
||||
#ifndef __PLAT_IO_H
|
||||
#define __PLAT_IO_H
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#ifdef DEBUG
|
||||
void allwinnerA20_uart_putchar(char c);
|
||||
void putDebugChar(unsigned char c);
|
||||
unsigned char getDebugChar(void);
|
||||
|
||||
#define kernel_putchar(c) allwinnerA20_uart_putchar(c)
|
||||
#else /* !DEBUG */
|
||||
#define kernel_putchar(c) ((void)(0))
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -15,6 +15,8 @@
|
|||
#define INTC_PPTR 0xfff01000
|
||||
#define UART0_PPTR 0xfff02000
|
||||
#define DMTIMER0_PPTR 0xfff03000
|
||||
#define WDT1_PPTR 0xfff04000
|
||||
|
||||
|
||||
/* Other devices on the SoC. */
|
||||
#define INTC_PADDR 0x48200000
|
||||
|
|
@ -26,5 +28,7 @@
|
|||
#define DMTIMER5_PADDR 0x48046000
|
||||
#define DMTIMER6_PADDR 0x48048000
|
||||
#define DMTIMER7_PADDR 0x4804A000
|
||||
#define WDT1_PADDR 0x44e35000
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ typedef seL4_CPtr seL4_ARM_PageDirectory;
|
|||
typedef seL4_CPtr seL4_ARM_ASIDControl;
|
||||
typedef seL4_CPtr seL4_ARM_ASIDPool;
|
||||
|
||||
typedef struct {
|
||||
typedef struct seL4_UserContext_ {
|
||||
/* frame registers */
|
||||
seL4_Word pc, sp, cpsr, r0, r1, r8, r9, r10, r11, r12;
|
||||
/* other integer registers */
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ typedef seL4_CPtr seL4_IA32_IOPageTable;
|
|||
|
||||
/* User context as used by seL4_TCB_ReadRegisters / seL4_TCB_WriteRegisters */
|
||||
|
||||
typedef struct {
|
||||
typedef struct seL4_UserContext_ {
|
||||
/* frameRegisters */
|
||||
seL4_Word eip, esp, eflags, eax, ebx, ecx, edx, esi, edi, ebp;
|
||||
/* gpRegisters */
|
||||
|
|
|
|||
|
|
@ -276,7 +276,7 @@ initL2Cache(void)
|
|||
| CTRL_AUX_ASSOCIATIVITY_16WAY
|
||||
| CTRL_AUS_REPLPOLICY_RROBIN;
|
||||
|
||||
#if defined(EXYNOS4) || defined(IMX6) || defined(PLAT_ZYNQ7000)
|
||||
#if defined(EXYNOS4) || defined(IMX6) || defined(PLAT_ZYNQ7000) || defined(PLAT_ALLWINNERA20)
|
||||
aux |= CTRL_AUX_WAYSIZE_64K;
|
||||
#elif defined(OMAP4)
|
||||
aux |= CTRL_AUX_WAYSIZE_32K;
|
||||
|
|
|
|||
11
src/plat/allwinnerA20/Makefile
Executable file
11
src/plat/allwinnerA20/Makefile
Executable file
|
|
@ -0,0 +1,11 @@
|
|||
#
|
||||
# Copyright 2015, DornerWorks, Ltd.
|
||||
#
|
||||
# This software may be distributed and modified according to the terms of
|
||||
# the GNU General Public License version 2. Note that NO WARRANTY is provided.
|
||||
# See "LICENSE_GPLv2.txt" for details.
|
||||
#
|
||||
# @TAG(GD_GPL)
|
||||
#
|
||||
|
||||
include ${SOURCE_ROOT}/src/plat/allwinnerA20/machine/Makefile
|
||||
84
src/plat/allwinnerA20/linker.lds
Executable file
84
src/plat/allwinnerA20/linker.lds
Executable file
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Copyright 2015, DornerWorks, Ltd.
|
||||
*
|
||||
* This software may be distributed and modified according to the terms of
|
||||
* the GNU General Public License version 2. Note that NO WARRANTY is provided.
|
||||
* See "LICENSE_GPLv2.txt" for details.
|
||||
*
|
||||
* @TAG(GD_GPL)
|
||||
*/
|
||||
|
||||
ENTRY(_start)
|
||||
|
||||
/* WARNING: constants also defined in plat/machine/hardware.h */
|
||||
KERNEL_BASE = 0xA0000000;
|
||||
PHYS_BASE = 0x48000000;
|
||||
KERNEL_OFFSET = KERNEL_BASE - PHYS_BASE;
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = KERNEL_BASE;
|
||||
|
||||
.boot . : AT(ADDR(.boot) - KERNEL_OFFSET)
|
||||
{
|
||||
*(.boot.text)
|
||||
*(.boot.rodata)
|
||||
*(.boot.data)
|
||||
. = ALIGN(64K);
|
||||
}
|
||||
|
||||
ki_boot_end = .;
|
||||
|
||||
.text . : AT(ADDR(.text) - KERNEL_OFFSET)
|
||||
{
|
||||
/* Sit inside a large frame */
|
||||
. = ALIGN(64K);
|
||||
*(.vectors)
|
||||
|
||||
/* Fastpath code */
|
||||
*(.vectors.fastpath_call)
|
||||
*(.vectors.fastpath_reply_wait)
|
||||
*(.vectors.text)
|
||||
|
||||
/* Anything else that should be in the vectors page. */
|
||||
*(.vectors.*)
|
||||
|
||||
/* Hopefully all that fits into 4K! */
|
||||
|
||||
/* Standard kernel */
|
||||
*(.text)
|
||||
}
|
||||
|
||||
.rodata . : AT(ADDR(.rodata) - KERNEL_OFFSET)
|
||||
{
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
}
|
||||
|
||||
.data . : AT(ADDR(.data) - KERNEL_OFFSET)
|
||||
{
|
||||
*(.data)
|
||||
}
|
||||
|
||||
.bss . : AT(ADDR(.bss) - KERNEL_OFFSET)
|
||||
{
|
||||
*(.bss)
|
||||
|
||||
/* 4k breakpoint stack */
|
||||
_breakpoint_stack_bottom = .;
|
||||
. = . + 4K;
|
||||
_breakpoint_stack_top = .;
|
||||
|
||||
/* large data such as the globals frame and global PD */
|
||||
*(.bss.aligned)
|
||||
}
|
||||
|
||||
. = ALIGN(4K);
|
||||
ki_end = .;
|
||||
|
||||
/DISCARD/ :
|
||||
{
|
||||
*(.note.gnu.build-id)
|
||||
*(.comment)
|
||||
}
|
||||
}
|
||||
18
src/plat/allwinnerA20/machine/Makefile
Executable file
18
src/plat/allwinnerA20/machine/Makefile
Executable file
|
|
@ -0,0 +1,18 @@
|
|||
#
|
||||
# Copyright 2015, DornerWorks, Ltd.
|
||||
#
|
||||
# This software may be distributed and modified according to the terms of
|
||||
# the GNU General Public License version 2. Note that NO WARRANTY is provided.
|
||||
# See "LICENSE_GPLv2.txt" for details.
|
||||
#
|
||||
# @TAG(GD_GPL)
|
||||
#
|
||||
|
||||
DIRECTORIES += src/plat/allwinnerA20/machine
|
||||
|
||||
PLAT_C_SOURCES += machine/hardware.c \
|
||||
machine/l2cache.c
|
||||
|
||||
ifdef DEBUG
|
||||
PLAT_C_SOURCES += machine/io.c
|
||||
endif
|
||||
174
src/plat/allwinnerA20/machine/hardware.c
Executable file
174
src/plat/allwinnerA20/machine/hardware.c
Executable file
|
|
@ -0,0 +1,174 @@
|
|||
/*
|
||||
* Copyright 2015, DornerWorks, Ltd.
|
||||
*
|
||||
* This software may be distributed and modified according to the terms of
|
||||
* the GNU General Public License version 2. Note that NO WARRANTY is provided.
|
||||
* See "LICENSE_GPLv2.txt" for details.
|
||||
*
|
||||
* @TAG(GD_GPL)
|
||||
*/
|
||||
|
||||
#include <types.h>
|
||||
#include <machine/io.h>
|
||||
#include <kernel/vspace.h>
|
||||
#include <arch/machine.h>
|
||||
#include <arch/kernel/vspace.h>
|
||||
#include <plat/machine.h>
|
||||
#include <arch/linker.h>
|
||||
#include <plat/machine/devices.h>
|
||||
#include <plat/machine/hardware.h>
|
||||
|
||||
/* Available physical memory regions on platform (RAM minus kernel image). */
|
||||
/* NOTE: Regions are not allowed to be adjacent! */
|
||||
|
||||
const p_region_t BOOT_RODATA avail_p_regs[] = {
|
||||
/* 1408 MB */
|
||||
{ .start = 0x48000000, .end = 0xA0000000 }
|
||||
};
|
||||
|
||||
BOOT_CODE int get_num_avail_p_regs(void)
|
||||
{
|
||||
return sizeof(avail_p_regs) / sizeof(p_region_t);
|
||||
}
|
||||
|
||||
BOOT_CODE p_region_t get_avail_p_reg(unsigned int i)
|
||||
{
|
||||
return avail_p_regs[i];
|
||||
}
|
||||
|
||||
const p_region_t BOOT_RODATA dev_p_regs[] = {
|
||||
/* sorted by increasing memory address */
|
||||
/* region caps must be a power of 2. */
|
||||
|
||||
/* TODO: Add more devices. */
|
||||
{ SPI0_PADDR , SPI0_PADDR + ( 2 << PAGE_BITS) },
|
||||
{ SPI1_PADDR , SPI1_PADDR + ( 2 << PAGE_BITS) },
|
||||
|
||||
};
|
||||
|
||||
BOOT_CODE int get_num_dev_p_regs(void)
|
||||
{
|
||||
return sizeof(dev_p_regs) / sizeof(p_region_t);
|
||||
}
|
||||
|
||||
BOOT_CODE p_region_t get_dev_p_reg(unsigned int i)
|
||||
{
|
||||
return dev_p_regs[i];
|
||||
}
|
||||
|
||||
|
||||
/* Determine if the given IRQ should be reserved by the kernel. */
|
||||
bool_t CONST
|
||||
isReservedIRQ(irq_t irq)
|
||||
{
|
||||
return irq == KERNEL_TIMER_IRQ ||
|
||||
irq == RESERVED_IRQ01 ||
|
||||
irq == RESERVED_IRQ02 ||
|
||||
irq == RESERVED_IRQ03;
|
||||
}
|
||||
|
||||
/* Handle a platform-reserved IRQ. */
|
||||
void
|
||||
handleReservedIRQ(irq_t irq)
|
||||
{
|
||||
printf("Received reserved IRQ: %d\n", (int)irq);
|
||||
}
|
||||
|
||||
BOOT_CODE void
|
||||
map_kernel_devices(void)
|
||||
{
|
||||
/* map kernel device: GP Timer 11 */
|
||||
map_kernel_frame(
|
||||
TIMER0_PADDR,
|
||||
TIMER0_PPTR,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
);
|
||||
|
||||
/* map kernel device: GIC */
|
||||
map_kernel_frame(
|
||||
GIC_CONTROLLER0_PADDR,
|
||||
GIC_CONTROLLER_PPTR,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
);
|
||||
map_kernel_frame(
|
||||
GIC_DISTRIBUTOR_PADDR,
|
||||
GIC_DISTRIBUTOR_PPTR,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
);
|
||||
|
||||
#ifdef DEBUG
|
||||
/* map kernel device: UART */
|
||||
map_kernel_frame(
|
||||
UART0_PADDR,
|
||||
UART0_PPTR,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
#define TIMER_INTERVAL_US (CONFIG_TIMER_TICK_MS * 1000)
|
||||
#define TIMER_MHZ 24ULL
|
||||
#define TIMER_TICKS (TIMER_MHZ * TIMER_INTERVAL_US)
|
||||
|
||||
#define TIMER0_OFFSET 0xC00
|
||||
|
||||
#define TIMER_CTL_EN_FLAG BIT(0)
|
||||
#define TIMER_CTL_RELOAD_FLAG BIT(1)
|
||||
|
||||
#define TMR0_IRQ_EN_FLAG BIT(0)
|
||||
#define TMR0_IRQ_PEND_FLAG BIT(0)
|
||||
|
||||
static volatile struct TIMER_map {
|
||||
uint32_t tmr_irq_en_reg; /* Timer IRQ Enable Register 0x00 */
|
||||
uint32_t tmr_irq_sta_reg; /* Timer Status Register 0x04 */
|
||||
uint32_t tmr_reserved01[2];
|
||||
uint32_t tmr0_ctrl_reg; /* Timer 0 Control Register 0x10 */
|
||||
uint32_t tmr0_intv_value_reg; /* Timer 0 Interval Value Register 0x14 */
|
||||
uint32_t tmr0_cur_value_reg; /* Timer 0 Current Value Register 0x18 */
|
||||
} *timer = (volatile void*)(TIMER0_PPTR + TIMER0_OFFSET);
|
||||
|
||||
/**
|
||||
DONT_TRANSLATE
|
||||
*/
|
||||
void
|
||||
resetTimer(void)
|
||||
{
|
||||
timer->tmr_irq_sta_reg = TMR0_IRQ_PEND_FLAG;
|
||||
}
|
||||
|
||||
/* Configure gptimer11 as kernel preemption timer */
|
||||
/**
|
||||
DONT_TRANSLATE
|
||||
*/
|
||||
BOOT_CODE void
|
||||
initTimer(void)
|
||||
{
|
||||
/* Set the reload value */
|
||||
timer->tmr0_intv_value_reg = TIMER_TICKS;
|
||||
|
||||
/* Enables interrupt */
|
||||
timer->tmr_irq_en_reg = TMR0_IRQ_EN_FLAG;
|
||||
|
||||
/* Set autoreload and start the timer */
|
||||
timer->tmr0_ctrl_reg = TIMER_CTL_EN_FLAG | TIMER_CTL_RELOAD_FLAG;
|
||||
}
|
||||
48
src/plat/allwinnerA20/machine/io.c
Executable file
48
src/plat/allwinnerA20/machine/io.c
Executable file
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright 2015, DornerWorks, Ltd.
|
||||
*
|
||||
* This software may be distributed and modified according to the terms of
|
||||
* the GNU General Public License version 2. Note that NO WARRANTY is provided.
|
||||
* See "LICENSE_GPLv2.txt" for details.
|
||||
*
|
||||
* @TAG(GD_GPL)
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <util.h>
|
||||
#include <machine/io.h>
|
||||
#include <plat/machine/devices.h>
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
#define UTHR 0x00 /* UART Transmit Holding Register */
|
||||
#define ULSR 0x14 /* UART Line Status Register */
|
||||
#define ULSR_THRE 0x20 /* Transmit Holding Register Empty */
|
||||
|
||||
#define UART_REG(x) ((volatile uint32_t *)(UART0_PPTR + (x)))
|
||||
|
||||
void
|
||||
allwinnerA20_uart_putchar(char c)
|
||||
{
|
||||
while ((*UART_REG(ULSR) & ULSR_THRE) == 0);
|
||||
|
||||
*UART_REG(UTHR) = c;
|
||||
|
||||
if (c == '\n') {
|
||||
allwinnerA20_uart_putchar('\r');
|
||||
}
|
||||
}
|
||||
|
||||
void putDebugChar(unsigned char c)
|
||||
{
|
||||
while ((*UART_REG(ULSR) & ULSR_THRE) == 0);
|
||||
|
||||
*UART_REG(UTHR) = c;
|
||||
}
|
||||
|
||||
unsigned char getDebugChar(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
42
src/plat/allwinnerA20/machine/l2cache.c
Executable file
42
src/plat/allwinnerA20/machine/l2cache.c
Executable file
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright 2015, DornerWorks, Ltd.
|
||||
*
|
||||
* This software may be distributed and modified according to the terms of
|
||||
* the GNU General Public License version 2. Note that NO WARRANTY is provided.
|
||||
* See "LICENSE_GPLv2.txt" for details.
|
||||
*
|
||||
* @TAG(GD_GPL)
|
||||
*/
|
||||
|
||||
#include <arch/machine.h>
|
||||
|
||||
static inline word_t
|
||||
readACR(void)
|
||||
{
|
||||
word_t ACR;
|
||||
asm volatile ("mrc p15,0,%0,c1,c0,1" : "=r"(ACR));
|
||||
return ACR;
|
||||
}
|
||||
|
||||
static inline void
|
||||
writeACR(word_t ACR)
|
||||
{
|
||||
asm volatile ("mcr p15,0,%0,c1,c0,1" : : "r"(ACR));
|
||||
}
|
||||
|
||||
void
|
||||
initL2Cache(void)
|
||||
{
|
||||
cleanInvalidateL1Caches();
|
||||
|
||||
/*
|
||||
* Set the L2EN bit in the Auxially Control Register.
|
||||
*
|
||||
* We assume the C bit is already set in the system control register (from
|
||||
* head.S), and that the L2 Cache Auxilliary Control Register is correct
|
||||
* (as per reset).
|
||||
*/
|
||||
writeACR(readACR() | 0x2);
|
||||
|
||||
cleanInvalidateL1Caches();
|
||||
}
|
||||
|
|
@ -51,6 +51,7 @@ const p_region_t BOOT_RODATA dev_p_regs[] = {
|
|||
{ /* .start = */ DMTIMER5_PADDR, /* .end = */ DMTIMER5_PADDR + (1 << PAGE_BITS) },
|
||||
{ /* .start = */ DMTIMER6_PADDR, /* .end = */ DMTIMER6_PADDR + (1 << PAGE_BITS) },
|
||||
{ /* .start = */ DMTIMER7_PADDR, /* .end = */ DMTIMER7_PADDR + (1 << PAGE_BITS) },
|
||||
{ /* .start = */ WDT1_PADDR, /* .end = */ WDT1_PADDR + (1 << PAGE_BITS) },
|
||||
/* Board devices. */
|
||||
/* TODO: This should ultimately be replaced with a more general solution. */
|
||||
};
|
||||
|
|
@ -93,6 +94,18 @@ map_kernel_devices(void)
|
|||
)
|
||||
);
|
||||
|
||||
/* map kernel device: WDT1 */
|
||||
map_kernel_frame(
|
||||
WDT1_PADDR,
|
||||
WDT1_PPTR,
|
||||
VMKernelOnly,
|
||||
vm_attributes_new(
|
||||
false, /* armExecuteNever */
|
||||
false, /* armParityEnabled */
|
||||
false /* armPageCacheable */
|
||||
)
|
||||
);
|
||||
|
||||
#ifdef DEBUG
|
||||
/* map kernel device: UART */
|
||||
map_kernel_frame(
|
||||
|
|
@ -108,6 +121,12 @@ map_kernel_devices(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
#define INTCPS_SYSCONFIG_SOFTRESET BIT(1)
|
||||
#define INTCPS_SYSSTATUS_RESETDONE BIT(0)
|
||||
#define INTCPS_CONTROL_NEWIRQAGR BIT(0)
|
||||
#define INTCPS_SIR_IRQ_SPURIOUSIRQFLAG 0xffffff80
|
||||
|
||||
/*
|
||||
* The struct below is used to discourage the compiler from generating literals
|
||||
* for every single address we might access.
|
||||
|
|
@ -136,11 +155,11 @@ volatile struct INTC_map {
|
|||
uint32_t intcps_isr_clear;
|
||||
uint32_t intcps_pending_irq;
|
||||
uint32_t intcps_pending_fiq;
|
||||
} intcps_n[3];
|
||||
uint32_t padding5[8];
|
||||
uint32_t intcps_ilr[96];
|
||||
} intcps_n[4];
|
||||
uint32_t intcps_ilr[128];
|
||||
} *intc = (volatile void*)INTC_PPTR;
|
||||
|
||||
|
||||
/**
|
||||
DONT_TRANSLATE
|
||||
*/
|
||||
|
|
@ -148,23 +167,30 @@ volatile struct INTC_map {
|
|||
interrupt_t
|
||||
getActiveIRQ(void)
|
||||
{
|
||||
interrupt_t irq = intc->intcps_sir_irq;
|
||||
uint32_t intcps_sir_irq = intc->intcps_sir_irq;
|
||||
interrupt_t irq = (interrupt_t)(intcps_sir_irq & 0x7f);
|
||||
|
||||
/* Ignore spurious interrupts. */
|
||||
if ((irq & ~0b1111111) == 0) {
|
||||
assert(irq <= maxIRQ);
|
||||
if ((intcps_sir_irq & INTCPS_SIR_IRQ_SPURIOUSIRQFLAG) == 0) {
|
||||
assert((irq / 32) < (sizeof intc->intcps_n / sizeof intc->intcps_n[0]));
|
||||
if (intc->intcps_n[irq / 32].intcps_pending_irq & (1 << (irq & 31))) {
|
||||
return irq;
|
||||
} else {
|
||||
/* XXX happening a lot for irq=66! */
|
||||
}
|
||||
} else {
|
||||
/* XXX - should never happen? */
|
||||
printf("spurious irq %d / %x\n", irq, intcps_sir_irq);
|
||||
}
|
||||
|
||||
/* No interrupt. */
|
||||
return 0xff;
|
||||
return irqInvalid;
|
||||
}
|
||||
|
||||
/* Check for pending IRQ */
|
||||
bool_t isIRQPending(void)
|
||||
{
|
||||
return getActiveIRQ() != 0xff;
|
||||
return getActiveIRQ() != irqInvalid;
|
||||
}
|
||||
|
||||
/* Enable or disable irq according to the 'disable' flag. */
|
||||
|
|
@ -174,6 +200,7 @@ bool_t isIRQPending(void)
|
|||
void
|
||||
maskInterrupt(bool_t disable, interrupt_t irq)
|
||||
{
|
||||
assert(irq <= maxIRQ);
|
||||
if (disable) {
|
||||
intc->intcps_n[irq / 32].intcps_mir_set = 1 << (irq & 31);
|
||||
} else {
|
||||
|
|
@ -185,22 +212,19 @@ maskInterrupt(bool_t disable, interrupt_t irq)
|
|||
bool_t
|
||||
isReservedIRQ(interrupt_t irq)
|
||||
{
|
||||
return false;
|
||||
return irq == KERNEL_TIMER_IRQ;
|
||||
}
|
||||
|
||||
/* Handle a platform-reserved IRQ. */
|
||||
void handleReservedIRQ(irq_t irq)
|
||||
{
|
||||
/* We shouldn't be receiving any reserved IRQs anyway. */
|
||||
maskInterrupt(true, irq);
|
||||
|
||||
return;
|
||||
printf("Received reserved IRQ: %d\n", (int)irq);
|
||||
}
|
||||
|
||||
void
|
||||
ackInterrupt(irq_t irq)
|
||||
{
|
||||
intc->intcps_control = 1;
|
||||
intc->intcps_control = INTCPS_CONTROL_NEWIRQAGR;
|
||||
/* Ensure the ack has hit the interrupt controller before potentially
|
||||
* re-enabling interrupts. */
|
||||
dsb();
|
||||
|
|
@ -255,6 +279,27 @@ resetTimer(void)
|
|||
ackInterrupt(DMTIMER0_IRQ);
|
||||
}
|
||||
|
||||
#define WDT_REG(base, off) ((volatile uint32_t *)((base) + (off)))
|
||||
#define WDT_REG_WWPS 0x34
|
||||
#define WDT_REG_WSPR 0x48
|
||||
#define WDT_WWPS_PEND_WSPR BIT(4)
|
||||
|
||||
static BOOT_CODE void
|
||||
disableWatchdog(void)
|
||||
{
|
||||
uint32_t wdt = WDT1_PPTR;
|
||||
|
||||
// am335x ref man, sec 20.4.3.8
|
||||
*WDT_REG(wdt, WDT_REG_WSPR) = 0xaaaa;
|
||||
while ((*WDT_REG(wdt, WDT_REG_WWPS) & WDT_WWPS_PEND_WSPR)) {
|
||||
continue;
|
||||
}
|
||||
*WDT_REG(wdt, WDT_REG_WSPR) = 0x5555;
|
||||
while ((*WDT_REG(wdt, WDT_REG_WWPS) & WDT_WWPS_PEND_WSPR)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Configure dmtimer0 as kernel preemption timer */
|
||||
/**
|
||||
DONT_TRANSLATE
|
||||
|
|
@ -264,11 +309,14 @@ initTimer(void)
|
|||
{
|
||||
int timeout;
|
||||
|
||||
disableWatchdog();
|
||||
|
||||
timer->cfg = TIOCP_CFG_SOFTRESET;
|
||||
|
||||
for (timeout = 10000; (timer->cfg & TIOCP_CFG_SOFTRESET) && timeout > 0; timeout--)
|
||||
;
|
||||
if (!timeout) {
|
||||
printf("init timer failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -293,12 +341,15 @@ initTimer(void)
|
|||
BOOT_CODE void
|
||||
initIRQController(void)
|
||||
{
|
||||
/* Do nothing */
|
||||
intc->intcps_sysconfig = INTCPS_SYSCONFIG_SOFTRESET;
|
||||
while (!(intc->intcps_sysstatus & INTCPS_SYSSTATUS_RESETDONE)) ;
|
||||
}
|
||||
|
||||
void
|
||||
handleSpuriousIRQ(void)
|
||||
{
|
||||
/* Do nothing */
|
||||
/* Reset and re-enable IRQs. */
|
||||
intc->intcps_control = INTCPS_CONTROL_NEWIRQAGR;
|
||||
dsb();
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue