Commit 422cb08a authored by Bhupesh Sharma's avatar Bhupesh Sharma Committed by York Sun

armv8/fsl-lsch3: Add Freescale Debug Server driver

The Debug Server driver is responsible for loading the Debug
server FW on the Service Processor (Cortex-A5 core) on LS2085A like
SoCs and then polling for the successful initialization of the same.
TOP MEM HIDE is adjusted to ensure the space required by Debug Server
FW is accounted for. MC uses the DDR area which is calculated as:

MC DDR region start = Top of DDR - area reserved by Debug Server FW
Signed-off-by: 's avatarBhupesh Sharma <bhupesh.sharma@freescale.com>
Reviewed-by: 's avatarYork Sun <yorksun@freescale.com>
parent 1fb5ff9a
......@@ -10,6 +10,7 @@
#include <asm/armv8/mmu.h>
#include <asm/io.h>
#include <asm/arch-fsl-lsch3/immap_lsch3.h>
#include <fsl_debug_server.h>
#include <fsl-mc/fsl_mc.h>
#include "cpu.h"
#include "mp.h"
......@@ -384,7 +385,6 @@ int cpu_eth_init(bd_t *bis)
return error;
}
int arch_early_init_r(void)
{
int rv;
......
......@@ -30,6 +30,15 @@
#define CONFIG_SYS_FSL_PMU_CLTBENR (CONFIG_SYS_FSL_PMU_ADDR + \
0x18A0)
/* SP (Cortex-A5) related */
#define CONFIG_SYS_FSL_SP_ADDR (CONFIG_SYS_IMMR + 0x00F00000)
#define CONFIG_SYS_FSL_SP_VSG_GIC_ADDR (CONFIG_SYS_FSL_SP_ADDR)
#define CONFIG_SYS_FSL_SP_VSG_GIC_VIGR1 (CONFIG_SYS_FSL_SP_ADDR)
#define CONFIG_SYS_FSL_SP_VSG_GIC_VIGR2 \
(CONFIG_SYS_FSL_SP_ADDR + 0x0008)
#define CONFIG_SYS_FSL_SP_LOOPBACK_DUART \
(CONFIG_SYS_FSL_SP_ADDR + 0x1000)
#define CONFIG_SYS_FSL_DCSR_DDR_ADDR 0x70012c000ULL
#define CONFIG_SYS_FSL_DCSR_DDR2_ADDR 0x70012d000ULL
#define CONFIG_SYS_FSL_DCSR_DDR3_ADDR 0x700132000ULL
......@@ -88,7 +97,6 @@
#define CONFIG_MAX_MEM_MAPPED CONFIG_SYS_LS2_DDR_BLOCK1_SIZE
#define CONFIG_SYS_FSL_DDR_VER FSL_DDR_VER_5_0
/* IFC */
#define CONFIG_SYS_FSL_IFC_LE
......
......@@ -12,6 +12,7 @@
#include <asm/io.h>
#include <fdt_support.h>
#include <libfdt.h>
#include <fsl_debug_server.h>
#include <fsl-mc/fsl_mc.h>
#include <environment.h>
......@@ -79,6 +80,34 @@ void reset_cpu(ulong addr)
{
}
#if defined(CONFIG_ARCH_MISC_INIT)
int arch_misc_init(void)
{
#ifdef CONFIG_FSL_DEBUG_SERVER
debug_server_init();
#endif
return 0;
}
#endif
unsigned long get_dram_size_to_hide(void)
{
unsigned long dram_to_hide = 0;
/* Carve the Debug Server private DRAM block from the end of DRAM */
#ifdef CONFIG_FSL_DEBUG_SERVER
dram_to_hide += debug_server_get_dram_block_size();
#endif
/* Carve the MC private DRAM block from the end of DRAM */
#ifdef CONFIG_FSL_MC_ENET
dram_to_hide += mc_get_dram_block_size();
#endif
return dram_to_hide;
}
int board_eth_init(bd_t *bis)
{
int error = 0;
......
......@@ -13,6 +13,7 @@ obj-$(CONFIG_CROS_EC_LPC) += cros_ec_lpc.o
obj-$(CONFIG_CROS_EC_I2C) += cros_ec_i2c.o
obj-$(CONFIG_CROS_EC_SANDBOX) += cros_ec_sandbox.o
obj-$(CONFIG_CROS_EC_SPI) += cros_ec_spi.o
obj-$(CONFIG_FSL_DEBUG_SERVER) += fsl_debug_server.o
obj-$(CONFIG_FSL_IIM) += fsl_iim.o
obj-$(CONFIG_GPIO_LED) += gpio_led.o
obj-$(CONFIG_I2C_EEPROM) += i2c_eeprom.o
......
/*
* Copyright (C) 2014 Freescale Semiconductor
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <errno.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/arch-fsl-lsch3/immap_lsch3.h>
#include <fsl_debug_server.h>
DECLARE_GLOBAL_DATA_PTR;
static int debug_server_ver_info_maj, debug_server_ver_info_min;
/**
* Copying Debug Server firmware to DDR
*/
static int debug_server_copy_image(const char *title, u64 image_addr,
u32 image_size, u64 debug_server_ram_addr)
{
debug("%s copied to address %p\n", title,
(void *)debug_server_ram_addr);
memcpy((void *)debug_server_ram_addr, (void *)image_addr, image_size);
return 0;
}
/**
* Debug Server FIT image parser checks if the image is in FIT
* format, verifies integrity of the image and calculates
* raw image address and size values.
*
* Returns 0 if success and -1 if any of the above mentioned
* task fail.
**/
int debug_server_parse_firmware_fit_image(const void **raw_image_addr,
size_t *raw_image_size)
{
int format;
void *fit_hdr;
int node_offset;
const void *data;
size_t size;
const char *uname = "firmware";
char *desc;
char *debug_server_ver_info;
char *debug_server_ver_info_major, *debug_server_ver_info_minor;
/* Check if the image is in NOR flash */
#ifdef CONFIG_SYS_DEBUG_SERVER_FW_IN_NOR
fit_hdr = (void *)CONFIG_SYS_DEBUG_SERVER_FW_ADDR;
#else
#error "CONFIG_SYS_DEBUG_SERVER_FW_IN_NOR not defined"
#endif
/* Check if Image is in FIT format */
format = genimg_get_format(fit_hdr);
if (format != IMAGE_FORMAT_FIT) {
printf("Error! Not a FIT image\n");
goto out_error;
}
if (!fit_check_format(fit_hdr)) {
printf("Error! Bad FIT image format\n");
goto out_error;
}
node_offset = fit_image_get_node(fit_hdr, uname);
if (node_offset < 0) {
printf("Error! Can not find %s subimage\n", uname);
goto out_error;
}
/* Verify Debug Server firmware image */
if (!fit_image_verify(fit_hdr, node_offset)) {
printf("Error! Bad Debug Server firmware hash");
goto out_error;
}
if (fit_get_desc(fit_hdr, node_offset, &desc) < 0) {
printf("Error! Failed to get Debug Server fw description");
goto out_error;
}
debug_server_ver_info = strstr(desc, "Version");
debug_server_ver_info_major = strtok(debug_server_ver_info, ".");
debug_server_ver_info_minor = strtok(NULL, ".");
debug_server_ver_info_maj =
simple_strtoul(debug_server_ver_info_major, NULL, 10);
debug_server_ver_info_min =
simple_strtoul(debug_server_ver_info_minor, NULL, 10);
/* Debug server version checking */
if ((debug_server_ver_info_maj < DEBUG_SERVER_VER_MAJOR) ||
(debug_server_ver_info_min < DEBUG_SERVER_VER_MINOR)) {
printf("Debug server FW mismatches the min version required\n");
printf("Expected:%d.%d, Got %d.%d\n",
DEBUG_SERVER_VER_MAJOR, DEBUG_SERVER_VER_MINOR,
debug_server_ver_info_maj,
debug_server_ver_info_min);
goto out_error;
}
/* Get address and size of raw image */
fit_image_get_data(fit_hdr, node_offset, &data, &size);
*raw_image_addr = data;
*raw_image_size = size;
return 0;
out_error:
return -1;
}
/**
* Return the actual size of the Debug Server private DRAM block.
*
* NOTE: For now this function always returns the minimum required size,
* However, in the future, the actual size may be obtained from an environment
* variable.
*/
unsigned long debug_server_get_dram_block_size(void)
{
return CONFIG_SYS_DEBUG_SERVER_DRAM_BLOCK_MIN_SIZE;
}
int debug_server_init(void)
{
struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
int error, timeout = CONFIG_SYS_DEBUG_SERVER_TIMEOUT;
int debug_server_boot_status;
u64 debug_server_ram_addr, debug_server_ram_size;
const void *raw_image_addr;
size_t raw_image_size = 0;
debug("debug_server_init called\n");
/*
* The Debug Server private DRAM block was already carved at the end of
* DRAM by board_init_f() using CONFIG_SYS_MEM_TOP_HIDE:
*/
debug_server_ram_size = debug_server_get_dram_block_size();
if (gd->bd->bi_dram[1].start)
debug_server_ram_addr =
gd->bd->bi_dram[1].start + gd->bd->bi_dram[1].size;
else
debug_server_ram_addr =
gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size;
error = debug_server_parse_firmware_fit_image(&raw_image_addr,
&raw_image_size);
if (error != 0)
goto out;
debug("debug server (ram addr = 0x%llx, ram size = 0x%llx)\n",
debug_server_ram_addr, debug_server_ram_size);
/*
* Load the Debug Server FW at the beginning of the Debug Server
* private DRAM block:
*/
debug_server_copy_image("Debug Server Firmware",
(u64)raw_image_addr, raw_image_size,
debug_server_ram_addr);
/* flush dcache */
flush_dcache_range((unsigned long)debug_server_ram_addr,
(unsigned long)debug_server_ram_addr +
(unsigned long)debug_server_ram_size);
/*
* Tell SP that the Debug Server FW is about to be launched. Before that
* populate the following:
* 1. Write the size allocated to SP Memory region into Bits {31:16} of
* SCRATCHRW5.
* 2. Write the start address of the SP memory regions into
* SCRATCHRW5 (Bits {15:0}, contain most significant bits, Bits
* {47:32} of the SP Memory Region physical start address
* (SoC address)) and SCRATCHRW6 (Bits {31:0}).
* 3. To know the Debug Server FW boot status, set bit 0 of SCRATCHRW11
* to 1. The Debug Server sets this to 0 to indicate a
* successul boot.
* 4. Wakeup SP by writing 0x1F to VSG GIC reg VIGR2.
*/
/* 512 MB */
out_le32(&gur->scratchrw[5 - 1],
(u32)((u64)debug_server_ram_addr >> 32) | (0x000D << 16));
out_le32(&gur->scratchrw[6 - 1],
((u32)debug_server_ram_addr) & 0xFFFFFFFF);
out_le32(&gur->scratchrw[11 - 1], DEBUG_SERVER_INIT_STATUS);
/* Allow the changes to reflect in GUR block */
mb();
/*
* Program VGIC to raise an interrupt to SP
*/
out_le32(CONFIG_SYS_FSL_SP_VSG_GIC_VIGR2, 0x1F);
/* Allow the changes to reflect in VIGR2 */
mb();
dmb();
debug("Polling for Debug server to launch ...\n");
while (1) {
debug_server_boot_status = in_le32(&gur->scratchrw[11 - 1]);
if (!(debug_server_boot_status & DEBUG_SERVER_INIT_STATUS_MASK))
break;
udelay(1); /* throttle polling */
if (timeout-- <= 0)
break;
}
if (timeout <= 0) {
printf("Debug Server FW timed out (boot status: 0x%x)\n",
debug_server_boot_status);
error = -ETIMEDOUT;
goto out;
}
if (debug_server_boot_status & DEBUG_SERVER_INIT_STATUS_MASK) {
printf("Debug server FW error'ed out (boot status: 0x%x)\n",
debug_server_boot_status);
error = -ENODEV;
goto out;
}
printf("Debug server booted\n");
printf("Detected firmware %d.%d, (boot status: 0x0%x)\n",
debug_server_ver_info_maj, debug_server_ver_info_min,
debug_server_boot_status);
out:
if (error != 0)
debug_server_boot_status = -error;
else
debug_server_boot_status = 0;
return debug_server_boot_status;
}
......@@ -9,6 +9,7 @@
#include <fsl-mc/fsl_mc.h>
#include <fsl-mc/fsl_mc_sys.h>
#include <fsl-mc/fsl_dpmng.h>
#include <fsl_debug_server.h>
DECLARE_GLOBAL_DATA_PTR;
static int mc_boot_status;
......@@ -112,6 +113,9 @@ int mc_init(bd_t *bis)
gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size;
}
#ifdef CONFIG_FSL_DEBUG_SERVER
mc_ram_addr -= debug_server_get_dram_block_size();
#endif
/*
* Management Complex cores should be held at reset out of POR.
* U-boot should be the first software to touch MC. To be safe,
......
......@@ -19,6 +19,9 @@
#define CONFIG_ARM_ERRATA_828024
#define CONFIG_ARM_ERRATA_826974
/* We need architecture specific misc initializations */
#define CONFIG_ARCH_MISC_INIT
/* Link Definitions */
#define CONFIG_SYS_TEXT_BASE 0x30001000
......@@ -205,6 +208,14 @@
#define CONFIG_SYS_CS0_FTIM2 CONFIG_SYS_NOR_FTIM2
#define CONFIG_SYS_CS0_FTIM3 CONFIG_SYS_NOR_FTIM3
/* Debug Server firmware */
#define CONFIG_FSL_DEBUG_SERVER
#define CONFIG_SYS_DEBUG_SERVER_DRAM_BLOCK_MIN_SIZE (512UL * 1024 * 1024)
#define CONFIG_SYS_DEBUG_SERVER_FW_IN_NOR
#define CONFIG_SYS_DEBUG_SERVER_FW_ADDR 0x580C00000ULL
/* 2 sec timeout */
#define CONFIG_SYS_DEBUG_SERVER_TIMEOUT (2 * 1000 * 1000)
/* MC firmware */
#define CONFIG_FSL_MC_ENET
#define CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE (512UL * 1024 * 1024)
......@@ -216,9 +227,9 @@
#define CONFIG_SYS_LS_MC_DPL_MAX_LENGTH (256 * 1024)
#define CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET 0xe00000
/* Carve the MC private DRAM block from the end of DRAM */
#ifdef CONFIG_FSL_MC_ENET
#define CONFIG_SYS_MEM_TOP_HIDE mc_get_dram_block_size()
/* Carve out a DDR region which will not be used by u-boot/Linux */
#if defined(CONFIG_FSL_MC_ENET) || defined(CONFIG_FSL_DEBUG_SERVER)
#define CONFIG_SYS_MEM_TOP_HIDE get_dram_size_to_hide()
#endif
/* Command line configuration */
......@@ -250,7 +261,6 @@
#define CONFIG_SYS_CLK_FREQ 100000000
#define CONFIG_DDR_CLK_FREQ 133333333
#define CONFIG_NR_DRAM_BANKS 3
#define CONFIG_HWCONFIG
......@@ -297,7 +307,7 @@
#define CONFIG_SYS_MAXARGS 64 /* max command args */
#ifndef __ASSEMBLY__
unsigned long mc_get_dram_block_size(void);
unsigned long get_dram_size_to_hide(void);
#endif
#endif /* __LS2_COMMON_H */
......@@ -56,4 +56,5 @@ struct mc_ccsr_registers {
int mc_init(bd_t *bis);
int get_mc_boot_status(void);
unsigned long mc_get_dram_block_size(void);
#endif
/*
* Copyright (C) 2014 Freescale Semiconductor
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __FSL_DBG_SERVER_H__
#define __FSL_DBG_SERVER_H__
#include <asm/io.h>
#include <common.h>
/*
* Define Debug Server firmware version information
*/
/* Major version number: incremented on API compatibility changes */
#define DEBUG_SERVER_VER_MAJOR 0
/* Minor version number: incremented on API additions (backward
* compatible); reset when major version is incremented.
*/
#define DEBUG_SERVER_VER_MINOR 1
#define DEBUG_SERVER_INIT_STATUS (1 << 0)
#define DEBUG_SERVER_INIT_STATUS_MASK (0x00000001)
int debug_server_init(void);
unsigned long debug_server_get_dram_block_size(void);
#endif /* __FSL_DBG_SERVER_H__ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment