1
0
mirror of https://xff.cz/git/u-boot/ synced 2025-10-16 07:21:26 +02:00

nds32: Support AE3XX platform.

Support Andestech AE3xx platform: serial, timer device tree flow.

Signed-off-by: rick <rick@andestech.com>
This commit is contained in:
rick
2017-05-18 14:37:53 +08:00
committed by Andes
parent f5076f8698
commit b841b6e946
33 changed files with 1265 additions and 114 deletions

View File

@@ -11,8 +11,12 @@ choice
config TARGET_ADP_AG101P
bool "Support adp-ag101p"
config TARGET_ADP_AE3XX
bool "Support adp-ae3xx"
endchoice
source "board/AndesTech/adp-ag101p/Kconfig"
source "board/AndesTech/adp-ae3xx/Kconfig"
endmenu

View File

@@ -12,3 +12,4 @@
extra-y = start.o
obj-$(if $(filter ag101,$(SOC)),y) += ag101/
obj-$(if $(filter ae3xx,$(SOC)),y) += ae3xx/

View File

@@ -0,0 +1,18 @@
#
# (C) Copyright 2009
# Marvell Semiconductor <www.marvell.com>
# Written-by: Prafulla Wadaskar <prafulla@marvell.com>
#
# Copyright (C) 2011 Andes Technology Corporation
# Shawn Lin, Andes Technology Corporation <nobuhiro@andestech.com>
# Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com>
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-y := cpu.o timer.o
obj-y += lowlevel_init.o
ifndef CONFIG_SKIP_TRUNOFF_WATCHDOG
obj-y += watchdog.o
endif

View File

@@ -0,0 +1,45 @@
/*
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Marius Groeger <mgroeger@sysgo.de>
*
* (C) Copyright 2002
* Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
*
* Copyright (C) 2011 Andes Technology Corporation
* Shawn Lin, Andes Technology Corporation <nobuhiro@andestech.com>
* Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
/* CPU specific code */
#include <common.h>
#include <command.h>
#include <watchdog.h>
#include <asm/cache.h>
#include <faraday/ftwdt010_wdt.h>
/*
* cleanup_before_linux() is called just before we call linux
* it prepares the processor for linux
*
* we disable interrupt and caches.
*/
int cleanup_before_linux(void)
{
disable_interrupts();
/* turn off I/D-cache */
cache_flush();
icache_disable();
dcache_disable();
return 0;
}
int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
disable_interrupts();
panic("AE3XX wdt not support yet.\n");
}

View File

@@ -0,0 +1,148 @@
/*
* Copyright (C) 2011 Andes Technology Corporation
* Shawn Lin, Andes Technology Corporation <nobuhiro@andestech.com>
* Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
.pic
.text
#include <common.h>
#include <config.h>
#include <asm/macro.h>
#include <generated/asm-offsets.h>
/*
* parameters for the SDRAM controller
*/
#define SDMC_TP1_A (CONFIG_FTSDMC021_BASE + FTSDMC021_TP1)
#define SDMC_TP2_A (CONFIG_FTSDMC021_BASE + FTSDMC021_TP2)
#define SDMC_CR1_A (CONFIG_FTSDMC021_BASE + FTSDMC021_CR1)
#define SDMC_CR2_A (CONFIG_FTSDMC021_BASE + FTSDMC021_CR2)
#define SDMC_B0_BSR_A (CONFIG_FTSDMC021_BASE + FTSDMC021_BANK0_BSR)
#define SDMC_B1_BSR_A (CONFIG_FTSDMC021_BASE + FTSDMC021_BANK1_BSR)
#define SDMC_TP1_D CONFIG_SYS_FTSDMC021_TP1
#define SDMC_TP2_D CONFIG_SYS_FTSDMC021_TP2
#define SDMC_CR1_D CONFIG_SYS_FTSDMC021_CR1
#define SDMC_CR2_D CONFIG_SYS_FTSDMC021_CR2
#define SDMC_B0_BSR_D CONFIG_SYS_FTSDMC021_BANK0_BSR
#define SDMC_B1_BSR_D CONFIG_SYS_FTSDMC021_BANK1_BSR
/*
* for Orca and Emerald
*/
#define BOARD_ID_REG 0x104
#define BOARD_ID_FAMILY_MASK 0xfff000
#define BOARD_ID_FAMILY_V5 0x556000
#define BOARD_ID_FAMILY_K7 0x74b000
/*
* parameters for the static memory controller
*/
#define SMC_BANK0_CR_A (CONFIG_FTSMC020_BASE + FTSMC020_BANK0_CR)
#define SMC_BANK0_TPR_A (CONFIG_FTSMC020_BASE + FTSMC020_BANK0_TPR)
#define SMC_BANK0_CR_D FTSMC020_BANK0_LOWLV_CONFIG
#define SMC_BANK0_TPR_D FTSMC020_BANK0_LOWLV_TIMING
/*
* for Orca and Emerald
*/
#define AHBC_BSR4_A (CONFIG_FTAHBC020S_BASE + FTAHBC020S_SLAVE_BSR_4)
#define AHBC_BSR6_D CONFIG_SYS_FTAHBC020S_SLAVE_BSR_6
/*
* parameters for the pmu controoler
*/
#define PMU_PDLLCR0_A (CONFIG_FTPMU010_BASE + FTPMU010_PDLLCR0)
/*
* numeric 7 segment display
*/
.macro led, num
write32 CONFIG_DEBUG_LED, \num
.endm
/*
* Waiting for SDRAM to set up
*/
.macro wait_sdram
li $r0, CONFIG_FTSDMC021_BASE
1:
lwi $r1, [$r0+FTSDMC021_CR2]
bnez $r1, 1b
.endm
.globl mem_init
mem_init:
move $r11, $lp
li $r0, SMC_BANK0_CR_A
lwi $r1, [$r0+#0x00]
ori $r1, $r1, 0x8f0
xori $r1, $r1, 0x8f0
/* 16-bit mode */
ori $r1, $r1, 0x60
li $r2, 0x00153153
swi $r1, [$r0+#0x00]
swi $r2, [$r0+#0x04]
move $lp, $r11
ret
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
.globl lowlevel_init
lowlevel_init:
move $r10, $lp
jal remap
#if (defined(NDS32_EXT_FPU_DP) || defined(NDS32_EXT_FPU_SP))
jal enable_fpu
#endif
ret $r10
remap:
move $r11, $lp
relo_base:
mfusr $r0, $pc
#ifdef CONFIG_MEM_REMAP
li $r4, 0x00000000
li $r5, 0x80000000
la $r6, _end@GOTOFF
1:
lmw.bim $r12, [$r5], $r19
smw.bim $r12, [$r4], $r19
blt $r5, $r6, 1b
#endif /* #ifdef CONFIG_MEM_REMAP */
move $lp, $r11
2:
ret
/*
* enable_fpu:
* Some of Andes CPU version support FPU coprocessor, if so,
* and toolchain support FPU instruction set, we should enable it.
*/
#if (defined(NDS32_EXT_FPU_DP) || defined(NDS32_EXT_FPU_SP))
enable_fpu:
mfsr $r0, $CPU_VER /* enable FPU if it exists */
srli $r0, $r0, 3
andi $r0, $r0, 1
beqz $r0, 1f /* skip if no COP */
mfsr $r0, $FUCOP_EXIST
srli $r0, $r0, 31
beqz $r0, 1f /* skip if no FPU */
mfsr $r0, $FUCOP_CTL
ori $r0, $r0, 1
mtsr $r0, $FUCOP_CTL
1:
ret
#endif
#endif /* #ifndef CONFIG_SKIP_LOWLEVEL_INIT */

View File

@@ -0,0 +1,16 @@
/*
* (C) Copyright 2009 Faraday Technology
* Po-Yu Chuang <ratbert@faraday-tech.com>
*
* Copyright (C) 2011 Andes Technology Corporation
* Shawn Lin, Andes Technology Corporation <nobuhiro@andestech.com>
* Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef CONFIG_TIMER
#include <common.h>
#include <asm/io.h>
#include <faraday/fttmr010.h>
#error "AE3XX timer only support DM flow"
#endif /* CONFIG_TIMER */

View File

@@ -0,0 +1,17 @@
/*
* Copyright (C) 2011 Andes Technology Corporation
* Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <asm/arch-ag101/ag101.h>
#include <linux/linkage.h>
.text
#ifndef CONFIG_SKIP_TRUNOFF_WATCHDOG
ENTRY(turnoff_watchdog)
#error "AE3XX not support wdt yet"
ENDPROC(turnoff_watchdog)
#endif

View File

@@ -11,10 +11,7 @@
#
obj-y := cpu.o timer.o
ifndef CONFIG_SKIP_LOWLEVEL_INIT
obj-y += lowlevel_init.o
endif
ifndef CONFIG_SKIP_TRUNOFF_WATCHDOG
obj-y += watchdog.o

View File

@@ -31,16 +31,10 @@ int cleanup_before_linux(void)
{
disable_interrupts();
#ifdef CONFIG_MMU
/* turn off I/D-cache */
cache_flush();
icache_disable();
dcache_disable();
/* flush I/D-cache */
invalidate_icac();
invalidate_dcac();
#endif
return 0;
}

View File

@@ -86,25 +86,7 @@
bnez $r1, 1b
.endm
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
.globl lowlevel_init
lowlevel_init:
move $r10, $lp
led 0x0
jal mem_init
led 0x10
jal remap
#if (defined(NDS32_EXT_FPU_DP) || defined(NDS32_EXT_FPU_SP))
led 0x1f
jal enable_fpu
#endif
led 0x20
ret $r10
.globl mem_init
mem_init:
move $r11, $lp
@@ -124,9 +106,7 @@ mem_init:
lwi $r1, [$r0+#0x00]
ori $r1, $r1, 0x8f0
xori $r1, $r1, 0x8f0
/*
* check board
*/
/* check board */
li $r3, CONFIG_FTPMU010_BASE + BOARD_ID_REG
lwi $r3, [$r3]
li $r4, BOARD_ID_FAMILY_MASK
@@ -134,29 +114,21 @@ mem_init:
li $r4, BOARD_ID_FAMILY_K7
xor $r4, $r3, $r4
beqz $r4, use_flash_16bit_boot
/*
* 32-bit mode
*/
/* 32-bit mode */
use_flash_32bit_boot:
ori $r1, $r1, 0x50
li $r2, 0x00151151
j sdram_b0_cr
/*
* 16-bit mode
*/
/* 16-bit mode */
use_flash_16bit_boot:
ori $r1, $r1, 0x60
li $r2, 0x00153153
/*
* SRAM bank0 config
*/
/* SRAM bank0 config */
sdram_b0_cr:
swi $r1, [$r0+#0x00]
swi $r2, [$r0+#0x04]
/*
* config AHB Controller
*/
/* config AHB Controller */
led 0x02
/*
@@ -192,6 +164,21 @@ sdram_b0_cr:
move $lp, $r11
ret
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
.globl lowlevel_init
lowlevel_init:
move $r10, $lp
led 0x10
jal remap
#if (defined(NDS32_EXT_FPU_DP) || defined(NDS32_EXT_FPU_SP))
led 0x1f
jal enable_fpu
#endif
led 0x20
ret $r10
remap:
move $r11, $lp
#ifdef __NDS32_N1213_43U1H__ /* NDS32 V0 ISA - AG101 Only */
@@ -203,9 +190,7 @@ relo_base:
mfusr $r0, $pc
#endif /* __NDS32_N1213_43U1H__ */
/*
* Remapping
*/
/* Remapping */
led 0x1a
write32 SDMC_B0_BSR_A, SDMC_B0_BSR_D ! 0x00001800
write32 SDMC_B1_BSR_A, SDMC_B1_BSR_D ! 0x00001880

View File

@@ -114,11 +114,39 @@ reset_gp:
set_ivb:
li $r0, 0x0
/* turn on BTB */
mtsr $r0, $misc_ctl
/* set IVIC, vector size: 4 bytes, base: 0x0 */
mtsr $r0, $ivb
/*
* MMU_CTL NTC0 Cacheable/Write-Back
*/
li $r0, ~0x3
mfsr $r1, $mr8
and $r1, $r1, $r0
mtsr $r1, $mr8
#if (!defined(CONFIG_SYS_ICACHE_OFF) || !defined(CONFIG_SYS_DCACHE_OFF))
li $r0, 0x4
mfsr $r1, $mr0
or $r1, $r1, $r0
mtsr $r1, $mr0
#endif
#if !defined(CONFIG_SYS_ICACHE_OFF)
li $r0, 0x1
mfsr $r1, $mr8
or $r1, $r1, $r0
mtsr $r1, $mr8
#endif
#if !defined(CONFIG_SYS_DCACHE_OFF)
li $r0, 0x2
mfsr $r1, $mr8
or $r1, $r1, $r0
mtsr $r1, $mr8
#endif
jal mem_init
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
jal lowlevel_init
@@ -133,7 +161,6 @@ update_gp:
ori $gp, $gp, lo12(_GLOBAL_OFFSET_TABLE_-4)
add5.pc $gp
#endif
/*
* do critical initializations first (shall be in short time)
* do self_relocation ASAP.
@@ -169,7 +196,6 @@ call_board_init_f:
bal debug_uart_init
#endif
li $r0, 0x00000000
#ifdef __PIC__
#ifdef __NDS32_N1213_43U1H__
/* __NDS32_N1213_43U1H__ implies NDS32 V0 ISA */
@@ -205,12 +231,10 @@ stack_setup:
la $r1, _end@GOTOFF
move $r2, $r6 /* r2 <- scratch for copy_loop */
copy_loop:
lwi.p $r7, [$r0], #4
swi.p $r7, [$r2], #4
lmw.bim $r11, [$r0], $r18
smw.bim $r11, [$r2], $r18
blt $r0, $r1, copy_loop
/*
* fix relocations related issues
*/
@@ -250,6 +274,8 @@ clbss_l:
* initialization, now running from RAM.
*/
call_board_init_r:
bal invalidate_icache_all
bal flush_dcache_all
la $r0, board_init_r@GOTOFF
move $lp, $r0 /* offset of board_init_r() */
add $lp, $lp, $r9 /* real address of board_init_r() */

View File

@@ -3,6 +3,7 @@
#
dtb-$(CONFIG_TARGET_ADP_AG101P) += ag101p.dtb
dtb-$(CONFIG_TARGET_ADP_AE3XX) += ae3xx.dtb
targets += $(dtb-y)
DTC_FLAGS += -R 4 -p 0x1000

65
arch/nds32/dts/ae3xx.dts Normal file
View File

@@ -0,0 +1,65 @@
/dts-v1/;
/ {
compatible = "nds32 ae3xx";
#address-cells = <1>;
#size-cells = <1>;
interrupt-parent = <&intc>;
aliases {
uart0 = &serial0;
} ;
chosen {
/* bootargs = "console=ttyS0,38400n8 earlyprintk=uart8250-32bit,0xf0300000 debug bootmem_debug memblock=debug loglevel=7"; */
bootargs = "console=ttyS0,38400n8 earlyprintk=uart8250-32bit,0xf0300000 debug loglevel=7";
stdout-path = "uart0:38400n8";
tick-timer = &timer0;
};
memory@0 {
device_type = "memory";
reg = <0x00000000 0x40000000>;
};
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu@0 {
compatible = "andestech,n13";
reg = <0>;
/* FIXME: to fill correct frqeuency */
clock-frequency = <60000000>;
};
};
intc: interrupt-controller {
compatible = "andestech,atnointc010";
#interrupt-cells = <1>;
interrupt-controller;
};
serial0: serial@f0300000 {
compatible = "andestech,uart16550", "ns16550a";
reg = <0xf0300000 0x1000>;
interrupts = <7 4>;
clock-frequency = <14745600>;
reg-shift = <2>;
reg-offset = <32>;
no-loopback-test = <1>;
};
timer0: timer@f0400000 {
compatible = "andestech,atcpit100";
reg = <0xf0400000 0x1000>;
interrupts = <2 4>;
clock-frequency = <30000000>;
};
nor@0,0 {
compatible = "cfi-flash";
reg = <0x88000000 0x1000>;
bank-width = <2>;
device-width = <1>;
};
};

View File

@@ -0,0 +1,54 @@
/*
* Copyright (C) 2016 Andes Technology Corporation
* Nobuhiro Lin, Andes Technology Corporation <nobuhiro@andestech.com>
* Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __AE3XX_H
#define __AE3XX_H
/* Hardware register bases */
/* Static Memory Controller (SRAM) */
#define CONFIG_FTSMC020_BASE 0xe0400000
/* DMA Controller */
#define CONFIG_FTDMAC020_BASE 0xf0c00000
/* AHB-to-APB Bridge */
#define CONFIG_FTAPBBRG020S_01_BASE 0xf0000000
/* Reserved */
#define CONFIG_RESERVED_01_BASE 0xe0500000
/* Reserved */
#define CONFIG_RESERVED_02_BASE 0xf0800000
/* Reserved */
#define CONFIG_RESERVED_03_BASE 0xf0900000
/* Ethernet */
#define CONFIG_FTMAC100_BASE 0xe0100000
/* Reserved */
#define CONFIG_RESERVED_04_BASE 0xf1000000
/* APB Device definitions */
/* UART1 */
#define CONFIG_FTUART010_01_BASE 0xf0200000
/* UART2 */
#define CONFIG_FTUART010_02_BASE 0xf0300000
/* Counter/Timers */
#define CONFIG_FTTMR010_BASE 0xf0400000
/* Watchdog Timer */
#define CONFIG_FTWDT010_BASE 0xf0500000
/* Real Time Clock */
#define CONFIG_FTRTC010_BASE 0xf0600000
/* GPIO */
#define CONFIG_FTGPIO010_BASE 0xf0700000
/* I2C */
#define CONFIG_FTIIC010_BASE 0xf0a00000
/* SD Controller */
#define CONFIG_FTSDC010_BASE 0xf0e00000
/* The following address was not defined in Linux */
/* Synchronous Serial Port Controller (SSP) 01 */
#define CONFIG_FTSSP010_01_BASE 0xf0d00000
#endif /* __AE3XX_H */

View File

@@ -0,0 +1,65 @@
/*
* Copyright (c) 2013, Google Inc.
*
* Copyright (C) 2011
* Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.de>
*
* SPDX-License-Identifier: GPL-2.0+
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef NDS32_BOOTM_H
#define NDS32_BOOTM_H
extern void udc_disconnect(void);
#if defined(CONFIG_SETUP_MEMORY_TAGS) || \
defined(CONFIG_CMDLINE_TAG) || \
defined(CONFIG_INITRD_TAG) || \
defined(CONFIG_SERIAL_TAG) || \
defined(CONFIG_REVISION_TAG)
# define BOOTM_ENABLE_TAGS 1
#else
# define BOOTM_ENABLE_TAGS 0
#endif
#ifdef CONFIG_SETUP_MEMORY_TAGS
# define BOOTM_ENABLE_MEMORY_TAGS 1
#else
# define BOOTM_ENABLE_MEMORY_TAGS 0
#endif
#ifdef CONFIG_CMDLINE_TAG
#define BOOTM_ENABLE_CMDLINE_TAG 1
#else
#define BOOTM_ENABLE_CMDLINE_TAG 0
#endif
#ifdef CONFIG_INITRD_TAG
#define BOOTM_ENABLE_INITRD_TAG 1
#else
#define BOOTM_ENABLE_INITRD_TAG 0
#endif
#ifdef CONFIG_SERIAL_TAG
#define BOOTM_ENABLE_SERIAL_TAG 1
void get_board_serial(struct tag_serialnr *serialnr);
#else
#define BOOTM_ENABLE_SERIAL_TAG 0
static inline void get_board_serial(struct tag_serialnr *serialnr)
{
}
#endif
#ifdef CONFIG_REVISION_TAG
#define BOOTM_ENABLE_REVISION_TAG 1
u32 get_board_rev(void);
#else
#define BOOTM_ENABLE_REVISION_TAG 0
static inline u32 get_board_rev(void)
{
return 0;
}
#endif
#endif

View File

@@ -16,6 +16,7 @@ void icache_disable(void);
int dcache_status(void);
void dcache_enable(void);
void dcache_disable(void);
void cache_flush(void);
#define DEFINE_GET_SYS_REG(reg) \
static inline unsigned long GET_##reg(void) \
@@ -30,10 +31,24 @@ void dcache_disable(void);
enum cache_t {ICACHE, DCACHE};
DEFINE_GET_SYS_REG(ICM_CFG);
DEFINE_GET_SYS_REG(DCM_CFG);
#define ICM_CFG_OFF_ISZ 6 /* I-cache line size */
#define ICM_CFG_MSK_ISZ (0x7UL << ICM_CFG_OFF_ISZ)
#define DCM_CFG_OFF_DSZ 6 /* D-cache line size */
#define DCM_CFG_MSK_DSZ (0x7UL << DCM_CFG_OFF_DSZ)
/* I-cache sets (# of cache lines) per way */
#define ICM_CFG_OFF_ISET 0
/* I-cache ways */
#define ICM_CFG_OFF_IWAY 3
#define ICM_CFG_MSK_ISET (0x7 << ICM_CFG_OFF_ISET)
#define ICM_CFG_MSK_IWAY (0x7 << ICM_CFG_OFF_IWAY)
/* D-cache sets (# of cache lines) per way */
#define DCM_CFG_OFF_DSET 0
/* D-cache ways */
#define DCM_CFG_OFF_DWAY 3
#define DCM_CFG_MSK_DSET (0x7 << DCM_CFG_OFF_DSET)
#define DCM_CFG_MSK_DWAY (0x7 << DCM_CFG_OFF_DWAY)
/* I-cache line size */
#define ICM_CFG_OFF_ISZ 6
#define ICM_CFG_MSK_ISZ (0x7UL << ICM_CFG_OFF_ISZ)
/* D-cache line size */
#define DCM_CFG_OFF_DSZ 6
#define DCM_CFG_MSK_DSZ (0x7UL << DCM_CFG_OFF_DSZ)
/*
* The current upper bound for NDS32 L1 data cache line sizes is 32 bytes.

View File

@@ -13,6 +13,7 @@ extern unsigned int __machine_arch_type;
/* see arch/arm/kernel/arch.c for a description of these */
#define MACH_TYPE_ADPAG101P 1
#define MACH_TYPE_ADPAE3XX 2
#ifdef CONFIG_ARCH_ADPAG101P
# ifdef machine_arch_type

View File

@@ -11,4 +11,5 @@
obj-y += cache.o
obj-$(CONFIG_CMD_BOOTM) += bootm.o
obj-$(CONFIG_CMD_GO) += boot.o
obj-y += interrupts.o

20
arch/nds32/lib/boot.c Normal file
View File

@@ -0,0 +1,20 @@
/*
* Copyright (C) 2011 Andes Technology Corporation
* Rick Chen, Andes Technology Corporation <rick@andestech.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <command.h>
DECLARE_GLOBAL_DATA_PTR;
unsigned long do_go_exec(ulong (*entry)(int, char * const []),
int argc, char * const argv[])
{
cleanup_before_linux();
return entry(argc, argv);
}

View File

@@ -11,6 +11,7 @@
#include <image.h>
#include <u-boot/zlib.h>
#include <asm/byteorder.h>
#include <asm/bootm.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -73,6 +74,15 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
debug("## Transferring control to Linux (at address %08lx) ...\n",
(ulong)theKernel);
if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) {
#ifdef CONFIG_OF_LIBFDT
debug("using: FDT\n");
if (image_setup_linux(images)) {
printf("FDT creation failed! hanging...");
hang();
}
#endif
} else if (BOOTM_ENABLE_TAGS) {
#if defined(CONFIG_SETUP_MEMORY_TAGS) || \
defined(CONFIG_CMDLINE_TAG) || \
defined(CONFIG_INITRD_TAG) || \
@@ -107,16 +117,17 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
udc_disconnect();
}
#endif
}
cleanup_before_linux();
theKernel(0, machid, bd->bi_boot_params);
if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len)
theKernel(0, machid, (unsigned long)images->ft_addr);
else
theKernel(0, machid, bd->bi_boot_params);
/* does not return */
return 1;
}
#if defined(CONFIG_SETUP_MEMORY_TAGS) || \
defined(CONFIG_CMDLINE_TAG) || \
defined(CONFIG_INITRD_TAG) || \
@@ -136,7 +147,6 @@ static void setup_start_tag(bd_t *bd)
params = tag_next(params);
}
#ifdef CONFIG_SETUP_MEMORY_TAGS
static void setup_memory_tags(bd_t *bd)
{
@@ -154,7 +164,6 @@ static void setup_memory_tags(bd_t *bd)
}
#endif /* CONFIG_SETUP_MEMORY_TAGS */
static void setup_commandline_tag(bd_t *bd, char *commandline)
{
char *p;
@@ -182,7 +191,6 @@ static void setup_commandline_tag(bd_t *bd, char *commandline)
params = tag_next(params);
}
#ifdef CONFIG_INITRD_TAG
static void setup_initrd_tag(bd_t *bd, ulong initrd_start, ulong initrd_end)
{
@@ -230,7 +238,6 @@ void setup_revision_tag(struct tag **in_params)
}
#endif /* CONFIG_REVISION_TAG */
static void setup_end_tag(bd_t *bd)
{
params->hdr.tag = ATAG_NONE;

View File

@@ -7,32 +7,56 @@
*/
#include <common.h>
#if (!defined(CONFIG_SYS_ICACHE_OFF) || !defined(CONFIG_SYS_DCACHE_OFF))
static inline unsigned long CACHE_SET(unsigned char cache)
{
if (cache == ICACHE)
return 64 << ((GET_ICM_CFG() & ICM_CFG_MSK_ISET) \
>> ICM_CFG_OFF_ISET);
else
return 64 << ((GET_DCM_CFG() & DCM_CFG_MSK_DSET) \
>> DCM_CFG_OFF_DSET);
}
static inline unsigned long CACHE_WAY(unsigned char cache)
{
if (cache == ICACHE)
return 1 + ((GET_ICM_CFG() & ICM_CFG_MSK_IWAY) \
>> ICM_CFG_OFF_IWAY);
else
return 1 + ((GET_DCM_CFG() & DCM_CFG_MSK_DWAY) \
>> DCM_CFG_OFF_DWAY);
}
static inline unsigned long CACHE_LINE_SIZE(enum cache_t cache)
{
if (cache == ICACHE)
return 8 << (((GET_ICM_CFG() & ICM_CFG_MSK_ISZ) \
>> ICM_CFG_OFF_ISZ) - 1);
>> ICM_CFG_OFF_ISZ) - 1);
else
return 8 << (((GET_DCM_CFG() & DCM_CFG_MSK_DSZ) \
>> DCM_CFG_OFF_DSZ) - 1);
>> DCM_CFG_OFF_DSZ) - 1);
}
#endif
void flush_dcache_range(unsigned long start, unsigned long end)
#ifndef CONFIG_SYS_ICACHE_OFF
void invalidate_icache_all(void)
{
unsigned long line_size;
unsigned long end, line_size;
line_size = CACHE_LINE_SIZE(ICACHE);
end = line_size * CACHE_WAY(ICACHE) * CACHE_SET(ICACHE);
do {
end -= line_size;
__asm__ volatile ("\n\tcctl %0, L1I_IX_INVAL" : : "r" (end));
line_size = CACHE_LINE_SIZE(DCACHE);
end -= line_size;
__asm__ volatile ("\n\tcctl %0, L1I_IX_INVAL" : : "r" (end));
while (end > start) {
asm volatile (
"\n\tcctl %0, L1D_VA_WB"
"\n\tcctl %0, L1D_VA_INVAL"
:
: "r" (start)
);
start += line_size;
}
end -= line_size;
__asm__ volatile ("\n\tcctl %0, L1I_IX_INVAL" : : "r" (end));
end -= line_size;
__asm__ volatile ("\n\tcctl %0, L1I_IX_INVAL" : : "r" (end));
} while (end > 0);
}
void invalidate_icache_range(unsigned long start, unsigned long end)
@@ -50,27 +74,6 @@ void invalidate_icache_range(unsigned long start, unsigned long end)
}
}
void invalidate_dcache_range(unsigned long start, unsigned long end)
{
unsigned long line_size;
line_size = CACHE_LINE_SIZE(DCACHE);
while (end > start) {
asm volatile (
"\n\tcctl %0, L1D_VA_INVAL"
:
: "r"(start)
);
start += line_size;
}
}
void flush_cache(unsigned long addr, unsigned long size)
{
flush_dcache_range(addr, addr + size);
invalidate_icache_range(addr, addr + size);
}
void icache_enable(void)
{
asm volatile (
@@ -107,6 +110,81 @@ int icache_status(void)
return ret;
}
#else
void invalidate_icache_all(void)
{
}
void invalidate_icache_range(unsigned long start, unsigned long end)
{
}
void icache_enable(void)
{
}
void icache_disable(void)
{
}
int icache_status(void)
{
return 0;
}
#endif
#ifndef CONFIG_SYS_DCACHE_OFF
void dcache_wbinval_all(void)
{
unsigned long end, line_size;
line_size = CACHE_LINE_SIZE(DCACHE);
end = line_size * CACHE_WAY(DCACHE) * CACHE_SET(DCACHE);
do {
end -= line_size;
__asm__ volatile ("\n\tcctl %0, L1D_IX_WB" : : "r" (end));
__asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL" : : "r" (end));
end -= line_size;
__asm__ volatile ("\n\tcctl %0, L1D_IX_WB" : : "r" (end));
__asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL" : : "r" (end));
end -= line_size;
__asm__ volatile ("\n\tcctl %0, L1D_IX_WB" : : "r" (end));
__asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL" : : "r" (end));
end -= line_size;
__asm__ volatile ("\n\tcctl %0, L1D_IX_WB" : : "r" (end));
__asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL" : : "r" (end));
} while (end > 0);
}
void flush_dcache_range(unsigned long start, unsigned long end)
{
unsigned long line_size;
line_size = CACHE_LINE_SIZE(DCACHE);
while (end > start) {
asm volatile (
"\n\tcctl %0, L1D_VA_WB"
"\n\tcctl %0, L1D_VA_INVAL" : : "r" (start)
);
start += line_size;
}
}
void invalidate_dcache_range(unsigned long start, unsigned long end)
{
unsigned long line_size;
line_size = CACHE_LINE_SIZE(DCACHE);
while (end > start) {
asm volatile (
"\n\tcctl %0, L1D_VA_INVAL" : : "r"(start)
);
start += line_size;
}
}
void dcache_enable(void)
{
asm volatile (
@@ -131,7 +209,6 @@ void dcache_disable(void)
int dcache_status(void)
{
int ret;
asm volatile (
"mfsr $p0, $mr8\n\t"
"andi %0, $p0, 0x02\n\t"
@@ -139,6 +216,52 @@ int dcache_status(void)
:
: "memory"
);
return ret;
}
#else
void dcache_wbinval_all(void)
{
}
void flush_dcache_range(unsigned long start, unsigned long end)
{
}
void invalidate_dcache_range(unsigned long start, unsigned long end)
{
}
void dcache_enable(void)
{
}
void dcache_disable(void)
{
}
int dcache_status(void)
{
return 0;
}
#endif
void flush_dcache_all(void)
{
dcache_wbinval_all();
}
void cache_flush(void)
{
flush_dcache_all();
invalidate_icache_all();
}
void flush_cache(unsigned long addr, unsigned long size)
{
flush_dcache_range(addr, addr + size);
invalidate_icache_range(addr, addr + size);
}