soc/xilinx/zynq7000: Initial Xilinx Zynq 7000 SoC bringup

The Zynq 7000 family of SoCs integrates up to two Cortex-A9 processor
cores with FPGA fabric using Xilinx's 7-series architecture. This commit
adds the bare minimum support code to compile a rom successfully when
the SoC is selected by a board. This code was loosely based on the TI
AM335x code, especially the memlayout.ld file.

In its current state valid Zynq boot images cannot be produced. CBFS
media is not yet supported so only the bootblock is able to run. The
easiest way to run this code is to manually load the bootblock ELF into
memory over JTAG using OpenOCD.

Change-Id: I45aa4e3a11074fa447d4008ac3c96d44f891831c
Signed-off-by: Nicholas Chin <nic.c3.14@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/84343
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: coreboot org <coreboot.org@gmail.com>
This commit is contained in:
Nicholas Chin 2022-05-01 17:54:54 -06:00 committed by Matt DeVillier
commit 1212b774b2
8 changed files with 135 additions and 0 deletions

4
src/soc/xilinx/Kconfig Normal file
View file

@ -0,0 +1,4 @@
## SPDX-License-Identifier: GPL-2.0-only
# Load all chipsets
source "src/soc/xilinx/*/Kconfig"

View file

@ -0,0 +1,17 @@
## SPDX-License-Identifier: GPL-2.0-only
#
config SOC_XILINX_ZYNQ7000
bool
default n
select ARCH_BOOTBLOCK_ARMV7
select ARCH_VERSTAGE_ARMV7
select ARCH_ROMSTAGE_ARMV7
select ARCH_RAMSTAGE_ARMV7
if SOC_XILINX_ZYNQ7000
config MEMLAYOUT_LD_FILE
string
default "src/soc/xilinx/zynq7000/memlayout.ld"
endif

View file

@ -0,0 +1,15 @@
# SPDX-License-Identifier: GPL-2.0-only
ifeq ($(CONFIG_SOC_XILINX_ZYNQ7000),y)
bootblock-y += timer.c
romstage-y += timer.c
ramstage-y += timer.c
romstage-y += cbmem.c
ramstage-y += soc.c
bootblock-y += reset.c
romstage-y += reset.c
ramstage-y += reset.c
endif

View file

@ -0,0 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <cbmem.h>
#include <commonlib/bsd/helpers.h>
uintptr_t cbmem_top_chipset(void)
{
return CONFIG_DRAM_SIZE_MB * MiB;
}

View file

@ -0,0 +1,24 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <memlayout.h>
#include <arch/header.ld>
SECTIONS
{
SRAM_START(0x00000000)
BOOTBLOCK(0x00000000, 20K)
FMAP_CACHE(0x00000000+20K, 2K)
CBFS_MCACHE(0x00000000+20K+2K, 8K)
TTB(0x00008000, 16K)
ROMSTAGE(0x00008000+16K, 40K)
PRERAM_CBFS_CACHE(0x00008000+16K+40K, 20K)
STACK(0x0001b000, 4K)
SRAM_END(0x30000)
DRAM_START(0x100000)
RAMSTAGE(0x100000, 2M)
POSTRAM_CBFS_CACHE(0x300000, 32M)
}

View file

@ -0,0 +1,13 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <device/mmio.h>
#include <reset.h>
#define SLCR_UNLOCK ((void *)0xF8000008u)
#define SLCR_UNLOCK_KEY 0xDF0D
#define PSS_RST_CTRL ((void *)0xF8000200u)
void do_board_reset(void)
{
write16(SLCR_UNLOCK, SLCR_UNLOCK_KEY);
write32(PSS_RST_CTRL, 1);
}

View file

@ -0,0 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <bootmem.h>
#include <device/device.h>
#include <symbols.h>
static void soc_enable(struct device *dev)
{
ram_range(dev, 0, 0, CONFIG_DRAM_SIZE_MB * (uint64_t)MiB);
}
struct chip_operations soc_xilinx_zynq7000_ops = {
.name = "Xilinx Zynq 7000",
.enable_dev = soc_enable,
};

View file

@ -0,0 +1,38 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <timer.h>
#include <delay.h>
#include <device/mmio.h>
#include <stdint.h>
#define G_TIMER_COUNTER_0 ((void *)0xF8F00200u)
#define G_TIMER_COUNTER_1 ((void *)0xF8F00204u)
#define G_TIMER_CTRL ((void *)0xF8F00208u)
#define CLK_PER_USEC 108
static inline uint64_t timer_raw_value(void)
{
uint32_t upper, lower;
do {
upper = read32(G_TIMER_COUNTER_1);
lower = read32(G_TIMER_COUNTER_0);
} while (upper != read32(G_TIMER_COUNTER_1));
return (((uint64_t)upper) << 32) | lower;
}
void init_timer(void)
{
/* Disable timer */
write32(G_TIMER_CTRL, read32(G_TIMER_CTRL) & ~0x1);
write32(G_TIMER_COUNTER_0, 0);
write32(G_TIMER_COUNTER_1, 0);
/* Enable timer */
write32(G_TIMER_CTRL, read32(G_TIMER_CTRL) | 0x1);
}
void timer_monotonic_get(struct mono_time *mt)
{
mono_time_set_usecs(mt, timer_raw_value() / CLK_PER_USEC);
}