aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Nazaryev <sergey@nazaryev.ru>2018-10-07 03:49:58 +0000
committerLera Pastova <lelik95@gmail.com>2018-10-11 10:16:13 +0300
commite75b1fc5a564b5f029fe9b765cbf72373c76128f (patch)
tree6b0ba06dafdd5760458889d1058629cb7ab00e1e
downloadzybo-z7-baremetal-e75b1fc5a564b5f029fe9b765cbf72373c76128f.zip
zybo-z7-baremetal-e75b1fc5a564b5f029fe9b765cbf72373c76128f.tar.gz
zybo-z7-baremetal-e75b1fc5a564b5f029fe9b765cbf72373c76128f.tar.bz2
Initial commit
-rw-r--r--.gitignore4
-rw-r--r--README.md64
-rw-r--r--bsp/Makefile.inc53
-rw-r--r--bsp/Zynq.ld86
-rw-r--r--bsp/boot.S254
-rw-r--r--bsp/ps7_init_gpl.c297
-rw-r--r--bsp/ps7_init_gpl.h47
-rw-r--r--bsp/ps7_spl_init.c141
-rw-r--r--examples/blink/Makefile6
-rw-r--r--examples/blink/blink.c29
-rw-r--r--examples/uart/Makefile6
-rw-r--r--examples/uart/uart.c114
12 files changed, 1101 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e341069
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+*.o
+tags
+*.elf
+*.log
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..a039e0c
--- /dev/null
+++ b/README.md
@@ -0,0 +1,64 @@
+# Digilent Zybo Z7-10 (bare metal)
+
+This repository is aimed to simplify the interaction with Digilent
+Zybo Z7-10 by using standard Linux open source utilities (such as
+gcc, gdb, openocd) instead of proprietary Xilinx SDK. It is something
+like [libopencm3][3] but for Xilinx Zynq 7010.
+
+## Quick Start
+
+ 1. Check if you have these apps installed:
+
+ - `openocd`
+ - `arm-none-eabi-gdb`
+ - `arm-none-eabi-gcc`
+ - `arm-none-eabi-newlib`
+
+ 2. Check whether the jumper JP5 set in JTAG mode on board;
+
+ 3. Connect your Zybo Z7 via USB (PROG/UART) to PC and turn the
+ switch "ON/OFF" on;
+
+ 4. Open terminal and check for `/dev/ttyUSB0` and `/dev/ttyUSB1`:
+
+```bash
+$ ls -al /dev/ttyUSB*
+crw-rw---- 1 root uucp 188, 0 Oct 10 15:50 /dev/ttyUSB0
+crw-rw---- 1 root uucp 188, 1 Oct 10 15:50 /dev/ttyUSB1
+```
+
+ 5. Add your user to the group that owns ttyUSB1 (usually `dialout` or
+ `uucp`) for getting access to UART without root permissions:
+
+```bash
+sudo usermod -aG uucp "${LOGNAME}"
+newgrp uucp
+```
+
+ 6. Create file /etc/udev/rules.d/49-digilent.rules (change the
+ group from p.5) for getting access to JTAG without root
+ permissions:
+
+```
+SUBSYSTEMS=="usb", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6010", GROUP="uucp", MODE:="0660"
+```
+
+ 7. Turn off and on board;
+
+ 8. Now you can run blink example for testing purpose:
+
+```bash
+cd examples/blink
+make
+make openocd &
+make run
+```
+
+## Credits
+
+ - `bsp/boot.S` & `bsp/Zynq.ld` from [bigbrett/zybo-baremetal][1]
+ - `bsp/ps7_init_gpl.{c,h}` & `bsp/ps7_spl_init.c` from [Das U-boot][2]
+
+[1]: https://github.com/bigbrett/zybo-baremetal
+[2]: http://git.denx.de/?p=u-boot.git;a=summary
+[3]: https://github.com/libopencm3/libopencm3
diff --git a/bsp/Makefile.inc b/bsp/Makefile.inc
new file mode 100644
index 0000000..a39362e
--- /dev/null
+++ b/bsp/Makefile.inc
@@ -0,0 +1,53 @@
+CROSS_COMPILE ?= arm-none-eabi-
+
+AS = $(CROSS_COMPILE)as
+CC = $(CROSS_COMPILE)gcc
+LD = $(CROSS_COMPILE)ld
+SZ = $(CROSS_COMPILE)size
+GDB = $(CROSS_COMPILE)gdb
+OOCD = openocd
+
+CFLAGS = -I$(BSPDIR) -mcpu=cortex-a9 -O0 -g3 -Wall -Werror -Wpedantic
+LDFLAGS = -nostdlib -T$(BSPDIR)/Zynq.ld
+ASFLAGS = -g -mcpu=cortex-a9
+
+BSP = $(BSPDIR)/boot.S \
+ $(BSPDIR)/ps7_init_gpl.c \
+ $(BSPDIR)/ps7_spl_init.c
+
+OBJECTS = $(patsubst %.S,%.o,$(patsubst %.c,%.o,$(SOURCES) $(BSP)))
+
+all: $(TARGET)
+
+$(TARGET): $(OBJECTS)
+ $(LD) $(LDFLAGS) -o $@ $^
+ @$(SZ) $(TARGET)
+
+%.o: %.S
+ $(AS) $(ASFLAGS) -c -o $@ $<
+
+%.o: %.c
+ $(CC) $(CFLAGS) -c -o $@ $<
+
+clean:
+ rm -f $(TARGET) $(OBJECTS)
+
+openocd:
+ $(OOCD) -f interface/ftdi/digilent-hs1.cfg \
+ -f target/zynq_7000.cfg
+
+debug: $(TARGET)
+ $(GDB) -iex "target remote localhost:3333" \
+ -iex "monitor halt" \
+ -ex "load" \
+ -ex "continue" "$(TARGET)"
+
+run: $(TARGET)
+ $(GDB) -iex "target remote localhost:3333" \
+ -iex "monitor halt" \
+ -ex "load" \
+ -ex "continue" \
+ -ex "set confirm no" \
+ -ex "quit" "$(TARGET)"
+
+.PHONY: clean debug openocd
diff --git a/bsp/Zynq.ld b/bsp/Zynq.ld
new file mode 100644
index 0000000..e94fafc
--- /dev/null
+++ b/bsp/Zynq.ld
@@ -0,0 +1,86 @@
+OUTPUT_FORMAT ("elf32-littlearm")
+
+MEMORY
+{
+ SRAM_0 : ORIGIN = 0x00000000, LENGTH = 0x00030000 /* 192k */
+ SRAM_1 : ORIGIN = 0xFFFF0000, LENGTH = 0x00010000 /* 64k */
+ DDR_PS : ORIGIN = 0x00100000, LENGTH = 0x1FF00000 /* 512M */
+}
+
+EXTERN(__stack_size)
+ASSERT(__stack_size, "Must provide a non-zero stack size");
+/* TODO: Also make sure stack size is 32-bit aligned */
+
+__heap_end = __stext + LENGTH(SRAM_0);
+__heap_start = __end;
+
+SECTIONS
+{
+ .text :
+ {
+ __stext = .;
+ *(.vectortable) /* Vector table */
+ *(.text .text.*) /* Standard Code */
+ *(.rodata .rodata.*) /* Constants, strings, ... */
+ *(.glue_7) /* Glue ARM to thumb code */
+ *(.glue_7t) /* Glue thumb to ARM code */
+ __etext = .;
+ } >SRAM_0
+
+ .data :
+ {
+ . = ALIGN(4);
+ __sdata = .;
+ *(.data .data.*)
+ __edata = .;
+
+ } >SRAM_0
+
+ .bss (NOLOAD) :
+ {
+ . = ALIGN(4);
+ __sbss = .; /* Used for zeroing bss on startup */
+ *(.bss .bss.*)
+ __ebss = .;
+ } >SRAM_0
+
+ . = ALIGN(4);
+ __end = .;
+
+ /* Place all stacks in SRAM_1 - need to avoid filling addresses */
+ /* 0xfffffe00 to 0xfffffff0 - proc1 is halted running code in this range */
+ /* TODO: assert stacks do not step on proc1's code out of reset */
+ .stack (NOLOAD) :
+ {
+ . += __stack_size;
+ __proc0_irq_stack = .;
+ . += __stack_size;
+ __proc0_fiq_stack = .;
+ . += __stack_size;
+ __proc0_svc_stack = .;
+ . += __stack_size;
+ __proc0_abt_stack = .;
+ . += __stack_size;
+ __proc0_und_stack = .;
+ . += __stack_size;
+ __proc0_sys_stack = .;
+ . += __stack_size;
+ __proc1_irq_stack = .;
+ . += __stack_size;
+ __proc1_fiq_stack = .;
+ . += __stack_size;
+ __proc1_svc_stack = .;
+ . += __stack_size;
+ __proc1_abt_stack = .;
+ . += __stack_size;
+ __proc1_und_stack = .;
+ . += __stack_size;
+ __proc1_sys_stack = .;
+ . += __stack_size;
+ } >SRAM_1 =0xFEEDBEEF
+
+ .data.ddr :
+ {
+ *(.data_in_ddr)
+ } >DDR_PS
+}
diff --git a/bsp/boot.S b/bsp/boot.S
new file mode 100644
index 0000000..f948aaf
--- /dev/null
+++ b/bsp/boot.S
@@ -0,0 +1,254 @@
+/*
+ * Init.s
+ *
+ * Initial system initialization code (1st-stage boot-loader)
+ */
+
+ .syntax unified /* Use the unified instruction syntax */
+ .arm /* Assemble ARM instruction set, not thumb */
+
+/*
+ *
+ * References:
+ * [1] Zynq-7000 Extensible Processing Platform - Technical Reference Manual UG585 (v1.0)
+ * May 8, 2012 http://www.xilinx.com
+ * Section 6.x "Boot and Configuration"
+ *
+ * [2] Zynq-7000 EPP Software Developers Guide - UG821 (v2.0) April 24, 2012
+ * http://www.xilinx.com
+ * Section 3.x "Boot and Configuration"
+ *
+ * [3] ZedBoard Hardware User Guide v1.1. August 1st, 2012.
+ * Retrieved from Digilent website
+ * Page 29.
+ *
+ * [4] Cortex-A Series Programmer's Guide, Version 2.0.
+ * http:/www.arm.com
+ *
+ * The Zynq processor boot includes two mandatory stages: stage 0 and stage 1.
+ * Stage 0 is the on-chip, immutable boot ROM. This code is called on reset/
+ * warm restart.
+ *
+ * The first-stage bootloader (FSBL) starts after boot. It is either run from
+ * on-chip memory starting at address 0x00000000 (populated by 0-th stage bootloader)
+ * or it executes in place (XIP) from unencrypted memory-maped flash depending on the
+ * BootROM header description. First-stage bootloader is responsible for initialization
+ * of the PS (ARM core) using the PS data provided by XPS, programming the PL (FPGA) using
+ * a bit-stream, loading second-stage bootloader or bare-metal application code into memory
+ * and starting execution of the second-stage bootloader or bare-metal application.
+ * NOTE: the default FSBL disables the MMU before starting the 2nd stage code.
+ *
+ * The files ps7_init.c and ps7_init.h are used to initialize CLK, DDR and MIO. The same
+ * initialization can be performed by ps7_init.tcl. When debugging with XMD, the ps7_init.tcl
+ * code is run by XMD, bypassing the need for a first-stage bootloader.
+ *
+ * For now, all development is done using XPS, with ps7_init.tcl utilized to perform the
+ * 1st stage bootloader behavior. When the program is moved to QSPI Flash or SD, refer
+ * to [2] section 3.4 and 3.5 for details about how to generate boot images.
+ *
+ * When the JTAG boot source is selected, the CPU halts imediately after it disables
+ * access to all security-related items and enables the JTAG port. It is the user's
+ * responsibility to manage downloading the boot image into OC RAM or DDR memory via
+ * JTAG before waking up the CPU and continuing the boot process (See [1] pp 129).
+ *
+ * 5 mode pins (Boot_Mode[4:0] - mapped to physical pins MIO[6:2]) determing the boot source.
+ * On the ZedBoard these are JP7-JP11 on the upper-right corner.
+ *
+ * MIO[2] (Boot_Mode[3]) determines JTAG configuration. Open (default) cascades both
+ * the processor and FPGA resources - so they are both available from the same JTAG
+ * interface.
+ *
+ * NOTE: the BootRom has two methods for communicating status information in the event
+ * of a startup failure. The primary metho is through the REBOOT_STATUS register. Non-secure
+ * boot failures result in the BootROM disabling access to the AES engine, clearing the PL
+ * and enabling JTAG. After JTAG is enabled, the REBOOT_STATUS register can be read to find the
+ * source of boot failure. See Table 6-9 in [1].
+ *
+ * MIO[5:3] (Boot_Mode[2:0]) determine boot device. Three useful configurations are:
+ * MIO[5] MIO[4] MIO[3]
+ * 0 0 0 = Boot from JTAG-provided image
+ * 1 0 0 = Boot from Q-SPI
+ * 1 1 0 = Boot from SD Card
+ *
+ * MIO[6] (Boot-Mode[4]) enables or disables the PLLs during 0-stage bootloader.
+ * The default is 0 (open), or enabled.
+ *
+ * After BootROM, the PS is in the following state:
+ * - MMU, Icache, Dcache, L2 cache are all disabled
+ * - Both processors are in the supervisor state
+ * - ROM code is masked and inaccessible
+ * - 192 kB of OCM is accessible starting at address 0x0
+ * - 64 kB of OCM is accessible starting at address 0xFFFF0000
+ * - CPU0 branches into the stage1 image if no failure occurs
+ * - CPU1 is in a WFE state while executing code at address 0xFFFFFE00 to 0xFFFFFFF0
+ *
+ * CPU0 is in charge of starting any addtional code on CPU1. The BootROM keeps CPU1
+ * in a reset-type state (WFE). When CPU1 receives a system event it reads the contents
+ * of address 0xFFFFFFF0 and jumps to that address. Only ARM-32 ISA code is supported
+ * at the jump target placed in 0xFFFFFFF0. The destination address must be 32-bit
+ * aligned and must be a valid ARM-32 instruction.
+ */
+ .equ PROC1_RESET_VECTOR_TABLE, 0xFFFFFFF0
+/*
+ * See sectoin 6.3.7 of [1] for more information on PS (CPU0,1) state after BootROM exit
+ *
+ * The ARM Cortex-A series processors have 7 standard modes (an 8th mode
+ * is utilized by the TrustZone security architecure and in systems with
+ * virtualization extensions a 9th mode is utilized by the hypervisor)
+ * associated with the standard modes.
+ *
+ * MODE_USER and MODE_SYSTEM are the normal operating modes. The former
+ * is for unprivileged user code and the latter for privileged execution.
+ * They share a common stack and register set (thus 7 modes, 6 stacks).
+ *
+ * MODE_SVC (Supervisor) is used to handle software-generated exceptions,
+ * such as system requests generated by user code.
+ *
+ * MODE_ABORT and MODE_UNDEFINED support fault and undefined instruction
+ * states.
+ *
+ * Two interrupt request signals, IRQ and FIQ, are used to interrupt the
+ * processor. The procesor has two modes, MODE_IRQ and MODE_FIQ, for
+ * handling these interupts. The FIQ ("Fast Interrupt Request") has
+ * additional hardware support and placement optimizations to increase
+ * its responsiveness.
+ *
+ * Mode is determined by the value in the MODE field of the CPSR register.
+ * These can be set using the "CPS" instruction, ie "CPS CPSR_MODE_USER":
+ */
+ /* TODO THESE ARE MACROS DEFINING THE HARDWARE MODE OF THE PROCESSOR */
+ .equ CPSR_MODE_USER, 0x10
+ .equ CPSR_MODE_FIQ, 0x11
+ .equ CPSR_MODE_IRQ, 0x12
+ .equ CPSR_MODE_SVC, 0x13
+ .equ CPSR_MODE_ABORT, 0x17
+ .equ CPSR_MODE_UNDEFINED, 0x8B
+ .equ CPSR_MODE_SYSTEM, 0x1F
+
+/*
+ * Stack placement is handled in the linker script - see Zynq.ld. The
+ * stack size for each is defined by __stack_size, below. Stacks are
+ * placed in the high 64k block of OCM. There are 14 stacks and
+ * we can't step on the last ~256 bytes of this block (as it is used
+ * by proc1 on start-up - see below) so limited to ~4k stack size.
+ */
+ .equ __stack_size, 0x1000 /* See linker script */
+ .global __stack_size
+
+/*
+ * The IRQ and FIQ exceptions are enabled/disabled by flags in the CPSR.
+ * They are enabled/disabled using the CPSIE/CPSID instructions followed by
+ * an argument describing which interupt to alter, 'i' for IRQ and 'f' for FIQ:
+ *
+ * cpsie i - enables IRQ interrupts
+ * cpsid d - disables IRQ interupts // TODO should this be cpsid i?
+ * cpsie f - enables FIQ interrupts
+ * cpsid f - disables FIQ interrupts
+ *
+ * These can also be set by writing directly to the CPSR register - which is done
+ * below during initialization to set up stacks and interrupt masks for the
+ * multiple processor modes
+ */
+ .equ CPSR_IRQ, 0x80 /* disable IRQ interrupts */
+ .equ CPSR_FIQ, 0x40 /* disable FIQ interrupts */
+
+/*
+ * The linker script (Zynq.ld) places text in the "bootimage" section at the
+ * start of the image. The interrupt jump table (vector) lives at address 0x00000000 and
+ * contains branch instructions to appropriate handlers. Single-instruction
+ * branches cannot jump further than 2^24 bits, so common practice is to
+ * branch to a locally placed handler, or branch to a locally placed
+ * verneer that allows a longer jump to a handler. Note that in general
+ * the FIQ is the last entry, allowing the FIQ handler to begin execution
+ * at the jump table address (rather than jumping to the handler) as no
+ * addtional jump table entries exist after it. In BEAR we take the
+ * performance hit and jump to a handler.
+ *
+ * Exception Modes and handling are described in [4] Section 10. Note there
+ * are different recommended return instructions for each mode; these are
+ * captured in the comments in the jump table below.
+ *
+ * Unimplemented handlers halt by looping in the jump table below.
+ *
+ * _init (reset handler), svc_Handler (supervisor call) and fiq_handler (interrupts)
+ * are assumed to live in the OCM, well within the 2^24 max jump distance restriction
+ * on the "b <target>" instruction.
+ *
+ * FIQ_handler and SVC_handler are defined in interrupts.S
+ */
+ .section .vectortable
+
+ /* Exception Processor Mode Event Return Sequence */
+ b reset_handler /* MODE_SVC System Reset n/a */
+ b undef_handler /* MODE_UNDEFINED Undefined Instruction MOVS PC, LR (if emulating) */
+ b SVC_handler /* MODE_SVC SVC instruction MOVS PC, LR */
+ b prefetch_abort_handler /* MODE_ABORT Invalid inst. address SUBS PC, LR, #4 */
+ b data_abort_handler /* MODE_ABORT R/W to invalid address SUBS PC, LR, #8 (to retry) */
+ b hypervisor_handler /* MODE_HYP Hypervisor entry ERET */
+ b IRQ_handler /* MODE_IRQ IRQ Input Asserted SUBS PC, LR, #4 */
+ b FIQ_handler /* MODE_FIQ FIQ Input Asserted SUBS PC, LR, #4 */
+
+ .text
+
+reset_handler:
+proc0_init:
+main:
+ /* For xilinx debugger - IDE debugger init searches for this function */
+ /* Switch between the various modes and initialize stack pointers */
+ /* When finished with this block, we'll be in the supervisor (privledged user) mode */
+ /* set all the stack pointers */
+ /* NOTE: ONLY NEED TO SET STACK POINTERS FOR THE MODE IM RUNNING IN (SVC and IRQ)
+ Jason reccomends only using the last 2 lines of code
+ NOTE: this also disables interrupts in each of these modes as the default setting */
+ msr CPSR, #(CPSR_IRQ | CPSR_FIQ | CPSR_MODE_IRQ) /* switch to MODE_IRQ */
+ ldr sp, =__proc0_irq_stack /* load IRQ mode stack pointer */
+ msr CPSR, #(CPSR_IRQ | CPSR_FIQ | CPSR_MODE_FIQ) /* switch to MODE_FIQ */
+ ldr sp, =__proc0_fiq_stack /* load FIQ mode stack pointer */
+ msr CPSR, #(CPSR_IRQ | CPSR_FIQ | CPSR_MODE_ABORT) /* switch to MODE_ABT */
+ ldr sp, =__proc0_abt_stack /* load ABT mode stack pointer */
+ msr CPSR, #(CPSR_IRQ | CPSR_FIQ | CPSR_MODE_UNDEFINED) /* switch to MODE_UND */
+ ldr sp, =__proc0_und_stack /* load UND mode stack pointer */
+ msr CPSR, #(CPSR_IRQ | CPSR_FIQ | CPSR_MODE_SYSTEM) /* switch to MODE_SYS */
+ ldr sp, =__proc0_sys_stack /* load SYS mode stack pointer */
+ msr CPSR, #(CPSR_IRQ | CPSR_FIQ | CPSR_MODE_SVC) /* switch to MODE_SVC */
+ ldr sp, =__proc0_svc_stack /* load SVC mode stack pointer */
+ /* We are now in SVC mode */
+
+
+ /* Clear the .bss section (zero inits) */
+ ldr r1, =__sbss // where in memory is start of bss (get from linker script)
+ ldr r2, =__ebss // where in memory is end of bss (get from linker script)
+ mov r3, #0
+clearbss:
+ cmp r1, r2
+ stmialt r1!,{r3}
+ blt clearbss
+
+ bl ps7_init
+ /* Finally, transfer control to the user program */
+ b init
+
+undef_handler:
+ b undef_handler
+
+SVC_handler:
+ b SVC_handler
+
+prefetch_abort_handler:
+ b prefetch_abort_handler
+
+data_abort_handler:
+ b data_abort_handler
+
+hypervisor_handler:
+ b hypervisor_handler
+
+IRQ_handler:
+ /* IRQ only used for scheduling */
+ b IRQ_handler
+
+FIQ_handler:
+ b FIQ_handler
+
+
+.end
diff --git a/bsp/ps7_init_gpl.c b/bsp/ps7_init_gpl.c
new file mode 100644
index 0000000..d97640e
--- /dev/null
+++ b/bsp/ps7_init_gpl.c
@@ -0,0 +1,297 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (c) Copyright 2010-2014 Xilinx, Inc. All rights reserved.
+ *
+ * Procedure to generate this file (using Vivado Webpack 2018.2):
+ * + Install board files from digilent/vivado-boards repository
+ * (commit 6a45981 from 2018-06-05)
+ * + Start Vivado and create a new RTL project with the Zybo-z7-20 board
+ * + Create a block design
+ * - Add "ZYNQ7 Processing System" IP
+ * - Run "Block Automation" (Check "Apply Board Preset")
+ * - Connect ports FCLK_CLK0 and M_AXI_GP0_ACLK
+ * - Save diagram changes
+ * - Go to sources view, select the block diagram,
+ * and select "Generate Output Products"
+ * + Copy the generated "ps7_init_gpl.c" file
+ * + Perform manual editions based on existing Zynq boards
+ * and the checkpatch.pl script
+ *
+ */
+
+#include "ps7_init_gpl.h"
+
+static unsigned long ps7_pll_init_data_3_0[] = {
+ EMIT_WRITE(0xF8000008, 0x0000DF0DU),
+ EMIT_MASKWRITE(0xF8000110, 0x003FFFF0U, 0x000FA220U),
+ EMIT_MASKWRITE(0xF8000100, 0x0007F000U, 0x00028000U),
+ EMIT_MASKWRITE(0xF8000100, 0x00000010U, 0x00000010U),
+ EMIT_MASKWRITE(0xF8000100, 0x00000001U, 0x00000001U),
+ EMIT_MASKWRITE(0xF8000100, 0x00000001U, 0x00000000U),
+ EMIT_MASKPOLL(0xF800010C, 0x00000001U),
+ EMIT_MASKWRITE(0xF8000100, 0x00000010U, 0x00000000U),
+ EMIT_MASKWRITE(0xF8000120, 0x1F003F30U, 0x1F000200U),
+ EMIT_MASKWRITE(0xF8000114, 0x003FFFF0U, 0x0012C220U),
+ EMIT_MASKWRITE(0xF8000104, 0x0007F000U, 0x00020000U),
+ EMIT_MASKWRITE(0xF8000104, 0x00000010U, 0x00000010U),
+ EMIT_MASKWRITE(0xF8000104, 0x00000001U, 0x00000001U),
+ EMIT_MASKWRITE(0xF8000104, 0x00000001U, 0x00000000U),
+ EMIT_MASKPOLL(0xF800010C, 0x00000002U),
+ EMIT_MASKWRITE(0xF8000104, 0x00000010U, 0x00000000U),
+ EMIT_MASKWRITE(0xF8000124, 0xFFF00003U, 0x0C200003U),
+ EMIT_MASKWRITE(0xF8000118, 0x003FFFF0U, 0x001452C0U),
+ EMIT_MASKWRITE(0xF8000108, 0x0007F000U, 0x0001E000U),
+ EMIT_MASKWRITE(0xF8000108, 0x00000010U, 0x00000010U),
+ EMIT_MASKWRITE(0xF8000108, 0x00000001U, 0x00000001U),
+ EMIT_MASKWRITE(0xF8000108, 0x00000001U, 0x00000000U),
+ EMIT_MASKPOLL(0xF800010C, 0x00000004U),
+ EMIT_MASKWRITE(0xF8000108, 0x00000010U, 0x00000000U),
+ EMIT_WRITE(0xF8000004, 0x0000767BU),
+ EMIT_EXIT(),
+};
+
+static unsigned long ps7_clock_init_data_3_0[] = {
+ EMIT_WRITE(0xF8000008, 0x0000DF0DU),
+ EMIT_MASKWRITE(0xF8000128, 0x03F03F01U, 0x00700F01U),
+ EMIT_MASKWRITE(0xF8000138, 0x00000011U, 0x00000001U),
+ EMIT_MASKWRITE(0xF8000140, 0x03F03F71U, 0x00100801U),
+ EMIT_MASKWRITE(0xF800014C, 0x00003F31U, 0x00000501U),
+ EMIT_MASKWRITE(0xF8000150, 0x00003F33U, 0x00001401U),
+ EMIT_MASKWRITE(0xF8000154, 0x00003F33U, 0x00000A02U),
+ EMIT_MASKWRITE(0xF8000168, 0x00003F31U, 0x00000501U),
+ EMIT_MASKWRITE(0xF8000170, 0x03F03F30U, 0x00400500U),
+ EMIT_MASKWRITE(0xF80001C4, 0x00000001U, 0x00000001U),
+ EMIT_MASKWRITE(0xF800012C, 0x01FFCCCDU, 0x01EC044DU),
+ EMIT_WRITE(0xF8000004, 0x0000767BU),
+ EMIT_EXIT(),
+};
+
+static unsigned long ps7_ddr_init_data_3_0[] = {
+ EMIT_MASKWRITE(0xF8006000, 0x0001FFFFU, 0x00000080U),
+ EMIT_MASKWRITE(0xF8006004, 0x0007FFFFU, 0x00001081U),
+ EMIT_MASKWRITE(0xF8006008, 0x03FFFFFFU, 0x03C0780FU),
+ EMIT_MASKWRITE(0xF800600C, 0x03FFFFFFU, 0x02001001U),
+ EMIT_MASKWRITE(0xF8006010, 0x03FFFFFFU, 0x00014001U),
+ EMIT_MASKWRITE(0xF8006014, 0x001FFFFFU, 0x0004281AU),
+ EMIT_MASKWRITE(0xF8006018, 0xF7FFFFFFU, 0x44E458D2U),
+ EMIT_MASKWRITE(0xF800601C, 0xFFFFFFFFU, 0x720238E5U),
+ EMIT_MASKWRITE(0xF8006020, 0x7FDFFFFCU, 0x270872D0U),
+ EMIT_MASKWRITE(0xF8006024, 0x0FFFFFC3U, 0x00000000U),
+ EMIT_MASKWRITE(0xF8006028, 0x00003FFFU, 0x00002007U),
+ EMIT_MASKWRITE(0xF800602C, 0xFFFFFFFFU, 0x00000008U),
+ EMIT_MASKWRITE(0xF8006030, 0xFFFFFFFFU, 0x00040930U),
+ EMIT_MASKWRITE(0xF8006034, 0x13FF3FFFU, 0x000116D4U),
+ EMIT_MASKWRITE(0xF8006038, 0x00000003U, 0x00000000U),
+ EMIT_MASKWRITE(0xF800603C, 0x000FFFFFU, 0x00000777U),
+ EMIT_MASKWRITE(0xF8006040, 0xFFFFFFFFU, 0xFFF00000U),
+ EMIT_MASKWRITE(0xF8006044, 0x0FFFFFFFU, 0x0F666666U),
+ EMIT_MASKWRITE(0xF8006048, 0x0003F03FU, 0x0003C008U),
+ EMIT_MASKWRITE(0xF8006050, 0xFF0F8FFFU, 0x77010800U),
+ EMIT_MASKWRITE(0xF8006058, 0x00010000U, 0x00000000U),
+ EMIT_MASKWRITE(0xF800605C, 0x0000FFFFU, 0x00005003U),
+ EMIT_MASKWRITE(0xF8006060, 0x000017FFU, 0x0000003EU),
+ EMIT_MASKWRITE(0xF8006064, 0x00021FE0U, 0x00020000U),
+ EMIT_MASKWRITE(0xF8006068, 0x03FFFFFFU, 0x00284141U),
+ EMIT_MASKWRITE(0xF800606C, 0x0000FFFFU, 0x00001610U),
+ EMIT_MASKWRITE(0xF8006078, 0x03FFFFFFU, 0x00466111U),
+ EMIT_MASKWRITE(0xF800607C, 0x000FFFFFU, 0x00032222U),
+ EMIT_MASKWRITE(0xF80060A4, 0xFFFFFFFFU, 0x10200802U),
+ EMIT_MASKWRITE(0xF80060A8, 0x0FFFFFFFU, 0x0690CB73U),
+ EMIT_MASKWRITE(0xF80060AC, 0x000001FFU, 0x000001FEU),
+ EMIT_MASKWRITE(0xF80060B0, 0x1FFFFFFFU, 0x1CFFFFFFU),
+ EMIT_MASKWRITE(0xF80060B4, 0x00000200U, 0x00000200U),
+ EMIT_MASKWRITE(0xF80060B8, 0x01FFFFFFU, 0x00200066U),
+ EMIT_MASKWRITE(0xF80060C4, 0x00000003U, 0x00000000U),
+ EMIT_MASKWRITE(0xF80060C8, 0x000000FFU, 0x00000000U),
+ EMIT_MASKWRITE(0xF80060DC, 0x00000001U, 0x00000000U),
+ EMIT_MASKWRITE(0xF80060F0, 0x0000FFFFU, 0x00000000U),
+ EMIT_MASKWRITE(0xF80060F4, 0x0000000FU, 0x00000008U),
+ EMIT_MASKWRITE(0xF8006114, 0x000000FFU, 0x00000000U),
+ EMIT_MASKWRITE(0xF8006118, 0x7FFFFFCFU, 0x40000001U),
+ EMIT_MASKWRITE(0xF800611C, 0x7FFFFFCFU, 0x40000001U),
+ EMIT_MASKWRITE(0xF8006120, 0x7FFFFFCFU, 0x40000001U),
+ EMIT_MASKWRITE(0xF8006124, 0x7FFFFFCFU, 0x40000001U),
+ EMIT_MASKWRITE(0xF800612C, 0x000FFFFFU, 0x00027000U),
+ EMIT_MASKWRITE(0xF8006130, 0x000FFFFFU, 0x00027000U),
+ EMIT_MASKWRITE(0xF8006134, 0x000FFFFFU, 0x00026C00U),
+ EMIT_MASKWRITE(0xF8006138, 0x000FFFFFU, 0x00028800U),
+ EMIT_MASKWRITE(0xF8006140, 0x000FFFFFU, 0x00000035U),
+ EMIT_MASKWRITE(0xF8006144, 0x000FFFFFU, 0x00000035U),
+ EMIT_MASKWRITE(0xF8006148, 0x000FFFFFU, 0x00000035U),
+ EMIT_MASKWRITE(0xF800614C, 0x000FFFFFU, 0x00000035U),
+ EMIT_MASKWRITE(0xF8006154, 0x000FFFFFU, 0x0000007AU),
+ EMIT_MASKWRITE(0xF8006158, 0x000FFFFFU, 0x0000007AU),
+ EMIT_MASKWRITE(0xF800615C, 0x000FFFFFU, 0x0000007CU),
+ EMIT_MASKWRITE(0xF8006160, 0x000FFFFFU, 0x00000073U),
+ EMIT_MASKWRITE(0xF8006168, 0x001FFFFFU, 0x000000F1U),
+ EMIT_MASKWRITE(0xF800616C, 0x001FFFFFU, 0x000000F1U),
+ EMIT_MASKWRITE(0xF8006170, 0x001FFFFFU, 0x000000F0U),
+ EMIT_MASKWRITE(0xF8006174, 0x001FFFFFU, 0x000000F7U),
+ EMIT_MASKWRITE(0xF800617C, 0x000FFFFFU, 0x000000BAU),
+ EMIT_MASKWRITE(0xF8006180, 0x000FFFFFU, 0x000000BAU),
+ EMIT_MASKWRITE(0xF8006184, 0x000FFFFFU, 0x000000BCU),
+ EMIT_MASKWRITE(0xF8006188, 0x000FFFFFU, 0x000000B3U),
+ EMIT_MASKWRITE(0xF8006190, 0x6FFFFEFEU, 0x00040080U),
+ EMIT_MASKWRITE(0xF8006194, 0x000FFFFFU, 0x0001FC82U),
+ EMIT_MASKWRITE(0xF8006204, 0xFFFFFFFFU, 0x00000000U),
+ EMIT_MASKWRITE(0xF8006208, 0x000703FFU, 0x000003FFU),
+ EMIT_MASKWRITE(0xF800620C, 0x000703FFU, 0x000003FFU),
+ EMIT_MASKWRITE(0xF8006210, 0x000703FFU, 0x000003FFU),
+ EMIT_MASKWRITE(0xF8006214, 0x000703FFU, 0x000003FFU),
+ EMIT_MASKWRITE(0xF8006218, 0x000F03FFU, 0x000003FFU),
+ EMIT_MASKWRITE(0xF800621C, 0x000F03FFU, 0x000003FFU),
+ EMIT_MASKWRITE(0xF8006220, 0x000F03FFU, 0x000003FFU),
+ EMIT_MASKWRITE(0xF8006224, 0x000F03FFU, 0x000003FFU),
+ EMIT_MASKWRITE(0xF80062A8, 0x00000FF5U, 0x00000000U),
+ EMIT_MASKWRITE(0xF80062AC, 0xFFFFFFFFU, 0x00000000U),
+ EMIT_MASKWRITE(0xF80062B0, 0x003FFFFFU, 0x00005125U),
+ EMIT_MASKWRITE(0xF80062B4, 0x0003FFFFU, 0x000012A8U),
+ EMIT_MASKPOLL(0xF8000B74, 0x00002000U),
+ EMIT_MASKWRITE(0xF8006000, 0x0001FFFFU, 0x00000081U),
+ EMIT_MASKPOLL(0xF8006054, 0x00000007U),
+ EMIT_EXIT(),
+};
+
+static unsigned long ps7_mio_init_data_3_0[] = {
+ EMIT_WRITE(0xF8000008, 0x0000DF0DU),
+ EMIT_MASKWRITE(0xF8000B40, 0x00000FFFU, 0x00000600U),
+ EMIT_MASKWRITE(0xF8000B44, 0x00000FFFU, 0x00000600U),
+ EMIT_MASKWRITE(0xF8000B48, 0x00000FFFU, 0x00000672U),
+ EMIT_MASKWRITE(0xF8000B4C, 0x00000FFFU, 0x00000672U),
+ EMIT_MASKWRITE(0xF8000B50, 0x00000FFFU, 0x00000674U),
+ EMIT_MASKWRITE(0xF8000B54, 0x00000FFFU, 0x00000674U),
+ EMIT_MASKWRITE(0xF8000B58, 0x00000FFFU, 0x00000600U),
+ EMIT_MASKWRITE(0xF8000B5C, 0xFFFFFFFFU, 0x0018C068U),
+ EMIT_MASKWRITE(0xF8000B60, 0xFFFFFFFFU, 0x00F98068U),
+ EMIT_MASKWRITE(0xF8000B64, 0xFFFFFFFFU, 0x00F98068U),
+ EMIT_MASKWRITE(0xF8000B68, 0xFFFFFFFFU, 0x00F98068U),
+ EMIT_MASKWRITE(0xF8000B6C, 0x00007FFFU, 0x00000260U),
+ EMIT_MASKWRITE(0xF8000B70, 0x00000001U, 0x00000001U),
+ EMIT_MASKWRITE(0xF8000B70, 0x00000021U, 0x00000020U),
+ EMIT_MASKWRITE(0xF8000B70, 0x07FEFFFFU, 0x00000823U),
+ EMIT_MASKWRITE(0xF8000700, 0x00003FFFU, 0x00001600U),
+ EMIT_MASKWRITE(0xF8000704, 0x00003FFFU, 0x00001602U),
+ EMIT_MASKWRITE(0xF8000708, 0x00003FFFU, 0x00000602U),
+ EMIT_MASKWRITE(0xF800070C, 0x00003FFFU, 0x00000602U),
+ EMIT_MASKWRITE(0xF8000710, 0x00003FFFU, 0x00000602U),
+ EMIT_MASKWRITE(0xF8000714, 0x00003FFFU, 0x00000602U),
+ EMIT_MASKWRITE(0xF8000718, 0x00003FFFU, 0x00000602U),
+ EMIT_MASKWRITE(0xF800071C, 0x00003FFFU, 0x00000600U),
+ EMIT_MASKWRITE(0xF8000720, 0x00003FFFU, 0x00000602U),
+ EMIT_MASKWRITE(0xF8000724, 0x00003FFFU, 0x00001600U),
+ EMIT_MASKWRITE(0xF8000728, 0x00003FFFU, 0x00001600U),
+ EMIT_MASKWRITE(0xF800072C, 0x00003FFFU, 0x00001600U),
+ EMIT_MASKWRITE(0xF8000730, 0x00003FFFU, 0x00001600U),
+ EMIT_MASKWRITE(0xF8000734, 0x00003FFFU, 0x00001600U),
+ EMIT_MASKWRITE(0xF8000738, 0x00003FFFU, 0x00001600U),
+ EMIT_MASKWRITE(0xF800073C, 0x00003FFFU, 0x00001600U),
+ EMIT_MASKWRITE(0xF8000740, 0x00003FFFU, 0x00001302U),
+ EMIT_MASKWRITE(0xF8000744, 0x00003FFFU, 0x00001302U),
+ EMIT_MASKWRITE(0xF8000748, 0x00003FFFU, 0x00001302U),
+ EMIT_MASKWRITE(0xF800074C, 0x00003FFFU, 0x00001302U),
+ EMIT_MASKWRITE(0xF8000750, 0x00003FFFU, 0x00001302U),
+ EMIT_MASKWRITE(0xF8000754, 0x00003FFFU, 0x00001302U),
+ EMIT_MASKWRITE(0xF8000758, 0x00003FFFU, 0x00001303U),
+ EMIT_MASKWRITE(0xF800075C, 0x00003FFFU, 0x00001303U),
+ EMIT_MASKWRITE(0xF8000760, 0x00003FFFU, 0x00001303U),
+ EMIT_MASKWRITE(0xF8000764, 0x00003FFFU, 0x00001303U),
+ EMIT_MASKWRITE(0xF8000768, 0x00003FFFU, 0x00001303U),
+ EMIT_MASKWRITE(0xF800076C, 0x00003FFFU, 0x00001303U),
+ EMIT_MASKWRITE(0xF8000770, 0x00003FFFU, 0x00001304U),
+ EMIT_MASKWRITE(0xF8000774, 0x00003FFFU, 0x00001305U),
+ EMIT_MASKWRITE(0xF8000778, 0x00003FFFU, 0x00001304U),
+ EMIT_MASKWRITE(0xF800077C, 0x00003FFFU, 0x00001305U),
+ EMIT_MASKWRITE(0xF8000780, 0x00003FFFU, 0x00001304U),
+ EMIT_MASKWRITE(0xF8000784, 0x00003FFFU, 0x00001304U),
+ EMIT_MASKWRITE(0xF8000788, 0x00003FFFU, 0x00001304U),
+ EMIT_MASKWRITE(0xF800078C, 0x00003FFFU, 0x00001304U),
+ EMIT_MASKWRITE(0xF8000790, 0x00003FFFU, 0x00001305U),
+ EMIT_MASKWRITE(0xF8000794, 0x00003FFFU, 0x00001304U),
+ EMIT_MASKWRITE(0xF8000798, 0x00003FFFU, 0x00001304U),
+ EMIT_MASKWRITE(0xF800079C, 0x00003FFFU, 0x00001304U),
+ EMIT_MASKWRITE(0xF80007A0, 0x00003FFFU, 0x00001280U),
+ EMIT_MASKWRITE(0xF80007A4, 0x00003FFFU, 0x00001280U),
+ EMIT_MASKWRITE(0xF80007A8, 0x00003FFFU, 0x00001280U),
+ EMIT_MASKWRITE(0xF80007AC, 0x00003FFFU, 0x00001280U),
+ EMIT_MASKWRITE(0xF80007B0, 0x00003FFFU, 0x00001280U),
+ EMIT_MASKWRITE(0xF80007B4, 0x00003FFFU, 0x00001280U),
+ EMIT_MASKWRITE(0xF80007B8, 0x00003FFFU, 0x00001200U),
+ EMIT_MASKWRITE(0xF80007BC, 0x00003F01U, 0x00001201U),
+ EMIT_MASKWRITE(0xF80007C0, 0x00003FFFU, 0x000012E0U),
+ EMIT_MASKWRITE(0xF80007C4, 0x00003FFFU, 0x000012E1U),
+ EMIT_MASKWRITE(0xF80007C8, 0x00003FFFU, 0x00001200U),
+ EMIT_MASKWRITE(0xF80007CC, 0x00003FFFU, 0x00001200U),
+ EMIT_MASKWRITE(0xF80007D0, 0x00003FFFU, 0x00001280U),
+ EMIT_MASKWRITE(0xF80007D4, 0x00003FFFU, 0x00001280U),
+ EMIT_MASKWRITE(0xF8000830, 0x003F003FU, 0x002F0037U),
+ EMIT_WRITE(0xF8000004, 0x0000767BU),
+ EMIT_EXIT(),
+};
+
+static unsigned long ps7_peripherals_init_data_3_0[] = {
+ EMIT_WRITE(0xF8000008, 0x0000DF0DU),
+ EMIT_MASKWRITE(0xF8000B48, 0x00000180U, 0x00000180U),
+ EMIT_MASKWRITE(0xF8000B4C, 0x00000180U, 0x00000180U),
+ EMIT_MASKWRITE(0xF8000B50, 0x00000180U, 0x00000180U),
+ EMIT_MASKWRITE(0xF8000B54, 0x00000180U, 0x00000180U),
+ EMIT_WRITE(0xF8000004, 0x0000767BU),
+ EMIT_MASKWRITE(0xE0001034, 0x000000FFU, 0x00000006U),
+ EMIT_MASKWRITE(0xE0001018, 0x0000FFFFU, 0x0000007CU),
+ EMIT_MASKWRITE(0xE0001000, 0x000001FFU, 0x00000017U),
+ EMIT_MASKWRITE(0xE0001004, 0x000003FFU, 0x00000020U),
+ EMIT_MASKWRITE(0xE000D000, 0x00080000U, 0x00080000U),
+ EMIT_MASKWRITE(0xF8007000, 0x20000000U, 0x00000000U),
+ EMIT_MASKWRITE(0xE000A244, 0x003FFFFFU, 0x00004000U),
+ EMIT_MASKWRITE(0xE000A008, 0xFFFFFFFFU, 0xBFFF4000U),
+ EMIT_MASKWRITE(0xE000A248, 0x003FFFFFU, 0x00004000U),
+ EMIT_MASKWRITE(0xE000A008, 0xFFFFFFFFU, 0xBFFF0000U),
+ EMIT_MASKDELAY(0xF8F00200, 1),
+ EMIT_MASKWRITE(0xE000A008, 0xFFFFFFFFU, 0xBFFF4000U),
+ EMIT_EXIT(),
+};
+
+static unsigned long ps7_post_config_3_0[] = {
+ EMIT_WRITE(0xF8000008, 0x0000DF0DU),
+ EMIT_MASKWRITE(0xF8000900, 0x0000000FU, 0x0000000FU),
+ EMIT_MASKWRITE(0xF8000240, 0xFFFFFFFFU, 0x00000000U),
+ EMIT_WRITE(0xF8000004, 0x0000767BU),
+ EMIT_EXIT(),
+};
+
+int ps7_post_config(void)
+{
+ int ret = -1;
+
+ ret = ps7_config(ps7_post_config_3_0);
+ if (ret != PS7_INIT_SUCCESS)
+ return ret;
+
+ return PS7_INIT_SUCCESS;
+}
+
+int ps7_init(void)
+{
+ int ret;
+
+ ret = ps7_config(ps7_mio_init_data_3_0);
+ if (ret != PS7_INIT_SUCCESS)
+ return ret;
+
+ ret = ps7_config(ps7_pll_init_data_3_0);
+ if (ret != PS7_INIT_SUCCESS)
+ return ret;
+
+ ret = ps7_config(ps7_clock_init_data_3_0);
+ if (ret != PS7_INIT_SUCCESS)
+ return ret;
+
+ ret = ps7_config(ps7_ddr_init_data_3_0);
+ if (ret != PS7_INIT_SUCCESS)
+ return ret;
+
+ ret = ps7_config(ps7_peripherals_init_data_3_0);
+ if (ret != PS7_INIT_SUCCESS)
+ return ret;
+
+ return PS7_INIT_SUCCESS;
+}
diff --git a/bsp/ps7_init_gpl.h b/bsp/ps7_init_gpl.h
new file mode 100644
index 0000000..bd46a9b
--- /dev/null
+++ b/bsp/ps7_init_gpl.h
@@ -0,0 +1,47 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (c) Copyright 2010-2014 Xilinx, Inc. All rights reserved.
+ * (c) Copyright 2016 Topic Embedded Products.
+ */
+
+#ifndef _ASM_ARCH_PS7_INIT_GPL_H
+#define _ASM_ARCH_PS7_INIT_GPL_H
+
+/* Opcode exit is 0 all the time */
+#define OPCODE_EXIT 0U
+#define OPCODE_MASKWRITE 0U
+#define OPCODE_MASKPOLL 1U
+#define OPCODE_MASKDELAY 2U
+#define OPCODE_WRITE 3U
+#define OPCODE_ADDRESS_MASK (~3U)
+
+/* Sentinel */
+#define EMIT_EXIT() OPCODE_EXIT
+/* Opcode is in lower 2 bits of address, address is always 4-byte aligned */
+#define EMIT_MASKWRITE(addr, mask, val) OPCODE_MASKWRITE | addr, mask, val
+#define EMIT_MASKPOLL(addr, mask) OPCODE_MASKPOLL | addr, mask
+#define EMIT_MASKDELAY(addr, mask) OPCODE_MASKDELAY | addr, mask
+#define EMIT_WRITE(addr, val) OPCODE_WRITE | addr, val
+
+/* Returns codes of ps7_init* */
+#define PS7_INIT_SUCCESS (0)
+#define PS7_INIT_CORRUPT (1)
+#define PS7_INIT_TIMEOUT (2)
+#define PS7_POLL_FAILED_DDR_INIT (3)
+#define PS7_POLL_FAILED_DMA (4)
+#define PS7_POLL_FAILED_PLL (5)
+
+#define PCW_SILICON_VERSION_1 0
+#define PCW_SILICON_VERSION_2 1
+#define PCW_SILICON_VERSION_3 2
+
+/* Called by spl.c */
+int ps7_init(void);
+int ps7_post_config(void);
+
+/* Defined in ps7_init_common.c */
+int ps7_config(unsigned long *ps7_config_init);
+
+unsigned long ps7GetSiliconVersion(void);
+
+#endif /* _ASM_ARCH_PS7_INIT_GPL_H */
diff --git a/bsp/ps7_spl_init.c b/bsp/ps7_spl_init.c
new file mode 100644
index 0000000..5914042
--- /dev/null
+++ b/bsp/ps7_spl_init.c
@@ -0,0 +1,141 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (c) Copyright 2010-2017 Xilinx, Inc. All rights reserved.
+ * (c) Copyright 2016 Topic Embedded Products.
+ */
+
+#include "ps7_init_gpl.h"
+
+/* For delay calculation using global registers*/
+#define SCU_GLOBAL_TIMER_COUNT_L32 0xF8F00200
+#define SCU_GLOBAL_TIMER_COUNT_U32 0xF8F00204
+#define SCU_GLOBAL_TIMER_CONTROL 0xF8F00208
+#define SCU_GLOBAL_TIMER_AUTO_INC 0xF8F00218
+#define APU_FREQ 666666666
+
+#define PS7_MASK_POLL_TIME 100000000
+
+#define __arch_getb(a) (*(volatile unsigned char *)(a))
+#define __arch_getw(a) (*(volatile unsigned short *)(a))
+#define __arch_getl(a) (*(volatile unsigned int *)(a))
+#define __arch_getq(a) (*(volatile unsigned long long *)(a))
+
+#define __arch_putb(v,a) (*(volatile unsigned char *)(a) = (v))
+#define __arch_putw(v,a) (*(volatile unsigned short *)(a) = (v))
+#define __arch_putl(v,a) (*(volatile unsigned int *)(a) = (v))
+#define __arch_putq(v,a) (*(volatile unsigned long long *)(a) = (v))
+
+#define __raw_writeb(v,a) __arch_putb(v,a)
+#define __raw_writew(v,a) __arch_putw(v,a)
+#define __raw_writel(v,a) __arch_putl(v,a)
+#define __raw_writeq(v,a) __arch_putq(v,a)
+
+#define __raw_readb(a) __arch_getb(a)
+#define __raw_readw(a) __arch_getw(a)
+#define __raw_readl(a) __arch_getl(a)
+#define __raw_readq(a) __arch_getq(a)
+
+/* IO accessors. No memory barriers desired. */
+static inline void iowrite(unsigned long val, unsigned long addr)
+{
+ __raw_writel(val, addr);
+}
+
+static inline unsigned long ioread(unsigned long addr)
+{
+ return __raw_readl(addr);
+}
+
+/* start timer */
+static void perf_start_clock(void)
+{
+ iowrite((1 << 0) | /* Timer Enable */
+ (1 << 3) | /* Auto-increment */
+ (0 << 8), /* Pre-scale */
+ SCU_GLOBAL_TIMER_CONTROL);
+}
+
+/* Compute mask for given delay in miliseconds*/
+static unsigned long get_number_of_cycles_for_delay(unsigned long delay)
+{
+ return (APU_FREQ / (2 * 1000)) * delay;
+}
+
+/* stop timer */
+static void perf_disable_clock(void)
+{
+ iowrite(0, SCU_GLOBAL_TIMER_CONTROL);
+}
+
+/* stop timer and reset timer count regs */
+static void perf_reset_clock(void)
+{
+ perf_disable_clock();
+ iowrite(0, SCU_GLOBAL_TIMER_COUNT_L32);
+ iowrite(0, SCU_GLOBAL_TIMER_COUNT_U32);
+}
+
+static void perf_reset_and_start_timer(void)
+{
+ perf_reset_clock();
+ perf_start_clock();
+}
+
+int ps7_config(unsigned long *ps7_config_init)
+{
+ unsigned long *ptr = ps7_config_init;
+ unsigned long opcode;
+ unsigned long addr;
+ unsigned long val;
+ unsigned long mask;
+ unsigned int numargs;
+ int i;
+ unsigned long delay;
+
+ for (;;) {
+ opcode = ptr[0];
+ if (opcode == OPCODE_EXIT)
+ return PS7_INIT_SUCCESS;
+ addr = (opcode & OPCODE_ADDRESS_MASK);
+
+ switch (opcode & ~OPCODE_ADDRESS_MASK) {
+ case OPCODE_MASKWRITE:
+ numargs = 3;
+ mask = ptr[1];
+ val = ptr[2];
+ iowrite((ioread(addr) & ~mask) | (val & mask), addr);
+ break;
+
+ case OPCODE_WRITE:
+ numargs = 2;
+ val = ptr[1];
+ iowrite(val, addr);
+ break;
+
+ case OPCODE_MASKPOLL:
+ numargs = 2;
+ mask = ptr[1];
+ i = 0;
+ while (!(ioread(addr) & mask)) {
+ if (i == PS7_MASK_POLL_TIME)
+ return PS7_INIT_TIMEOUT;
+ i++;
+ }
+ break;
+
+ case OPCODE_MASKDELAY:
+ numargs = 2;
+ mask = ptr[1];
+ delay = get_number_of_cycles_for_delay(mask);
+ perf_reset_and_start_timer();
+ while (ioread(addr) < delay)
+ ;
+ break;
+
+ default:
+ return PS7_INIT_CORRUPT;
+ }
+
+ ptr += numargs;
+ }
+}
diff --git a/examples/blink/Makefile b/examples/blink/Makefile
new file mode 100644
index 0000000..c786ea2
--- /dev/null
+++ b/examples/blink/Makefile
@@ -0,0 +1,6 @@
+BSPDIR = ../../bsp
+
+TARGET = blink.elf
+SOURCES = blink.c
+
+include $(BSPDIR)/Makefile.inc
diff --git a/examples/blink/blink.c b/examples/blink/blink.c
new file mode 100644
index 0000000..759a858
--- /dev/null
+++ b/examples/blink/blink.c
@@ -0,0 +1,29 @@
+#include <stdint.h>
+
+#define MIO_PIN07_CTRL *((uint32_t *)0xF800071C)
+#define MIO_PIN07_CTRL_GPIO0 0x00003200
+
+#define GPIO_DIRM0 *((uint32_t *)0xE000A204)
+#define GPIO_OEN0 *((uint32_t *)0xE000A208)
+#define GPIO_DATA0 *((uint32_t *)0xE000A040)
+
+#define GPIO0_PIN7 0x80
+
+void delay(uint32_t delay) {
+ for(volatile uint32_t i = 0; i < delay; i++);
+}
+
+void init(void)
+{
+ MIO_PIN07_CTRL = MIO_PIN07_CTRL_GPIO0;
+
+ GPIO_DIRM0 |= GPIO0_PIN7;
+ GPIO_OEN0 |= GPIO0_PIN7;
+
+ while(1) {
+ GPIO_DATA0 &= ~GPIO0_PIN7;
+ delay(1000000);
+ GPIO_DATA0 |= GPIO0_PIN7;
+ delay(1000000);
+ }
+}
diff --git a/examples/uart/Makefile b/examples/uart/Makefile
new file mode 100644
index 0000000..6ebdd6e
--- /dev/null
+++ b/examples/uart/Makefile
@@ -0,0 +1,6 @@
+BSPDIR = ../../bsp
+
+TARGET = uart.elf
+SOURCES = uart.c
+
+include $(BSPDIR)/Makefile.inc
diff --git a/examples/uart/uart.c b/examples/uart/uart.c
new file mode 100644
index 0000000..8fcd8df
--- /dev/null
+++ b/examples/uart/uart.c
@@ -0,0 +1,114 @@
+#include <stdint.h>
+
+#define MIO_PIN07_CTRL *((uint32_t *)0xF800071C)
+#define MIO_PIN07_CTRL_GPIO0 0x00003200
+#define GPIO_DIRM0 *((uint32_t *)0xE000A204)
+#define GPIO_OEN0 *((uint32_t *)0xE000A208)
+#define GPIO_DATA0 *((uint32_t *)0xE000A040)
+#define GPIO0_PIN7 0x80
+
+#define XUARTPS_CR_TXRST 0x00000002U /**< TX logic reset */
+#define XUARTPS_CR_RXRST 0x00000001U /**< RX logic reset */
+
+#define XUARTPS_CR_OFFSET 0x0000U /**< Control Register [8:0] */
+#define XUARTPS_MR_OFFSET 0x0004U /**< Mode Register [9:0] */
+#define XUARTPS_BAUDGEN_OFFSET 0x0018U /**< Baud Rate Generator [15:0] */
+#define XUARTPS_BAUDDIV_OFFSET 0x0034U /**< Baud Rate Divider [7:0] */
+#define XUARTPS_FIFO_OFFSET 0x0030U /**< FIFO [7:0] */
+#define XUARTPS_SR_OFFSET 0x002CU /**< Channel Status [14:0] */
+#define XPS_UART1_BASEADDR 0xE0001000U
+
+#define XUARTPS_MR_CHMODE_NORM 0x00000000U /**< Normal mode */
+#define XUARTPS_MR_STOPMODE_1_BIT 0x00000000U /**< 1 stop bit */
+#define XUARTPS_MR_PARITY_NONE 0x00000020U /**< No parity mode */
+#define XUARTPS_MR_CHARLEN_8_BIT 0x00000000U /**< 8 bits data */
+#define XUARTPS_MR_CLKSEL 0x00000001U /**< Input clock selection */
+
+#define XUARTPS_SR_TNFUL 0x00004000U /**< TX FIFO Nearly Full Status */
+#define XUARTPS_SR_TACTIVE 0x00000800U /**< TX active */
+#define XUARTPS_SR_RXEMPTY 0x00000002U /**< RX FIFO empty */
+
+#define XUARTPS_CR_TX_DIS 0x00000020U /**< TX disabled. */
+#define XUARTPS_CR_TX_EN 0x00000010U /**< TX enabled */
+#define XUARTPS_CR_RX_DIS 0x00000008U /**< RX disabled. */
+#define XUARTPS_CR_RX_EN 0x00000004U /**< RX enabled */
+
+#define POuint32_tER_TO_REGISTER(REG) ( *((volatile uint32_t*)(REG))) //u32 (xil_types.h) data type is declared as uuint32_t32_t (stduint32_t.h)
+
+#define UART_BASE XPS_UART1_BASEADDR // Base Address
+#define UART_CTRL POuint32_tER_TO_REGISTER(UART_BASE + XUARTPS_CR_OFFSET) // Control Register
+#define UART_MODE POuint32_tER_TO_REGISTER(UART_BASE + XUARTPS_MR_OFFSET) // Mode Register
+
+#define UART_BAUD_GEN POuint32_tER_TO_REGISTER(UART_BASE + XUARTPS_BAUDGEN_OFFSET) // Baud Rate Generator "CD"
+#define UART_BAUD_DIV POuint32_tER_TO_REGISTER(UART_BASE + XUARTPS_BAUDDIV_OFFSET) // Baud Rate Divider "BDIV"
+#define UART_FIFO POuint32_tER_TO_REGISTER(UART_BASE + XUARTPS_FIFO_OFFSET) // FIFO
+#define UART_STATUS POuint32_tER_TO_REGISTER(UART_BASE + XUARTPS_SR_OFFSET) // Channel Status
+
+#define BUFFER_SIZE 20
+
+static char str[] = "\tHello World\r";
+
+// Send one character through UART interface
+void uart_send(char c) {
+ while (UART_STATUS & XUARTPS_SR_TNFUL);
+ UART_FIFO = c;
+ while (UART_STATUS & XUARTPS_SR_TACTIVE);
+}
+
+// Send string (character array) through UART interface
+void uart_send_string(char str[BUFFER_SIZE]) {
+ char *ptr = str;
+
+ while (*ptr != '\0') {
+ uart_send(*ptr);
+ ptr++;
+ }
+ }
+
+// Check if UART receive FIFO is not empty and return the new data
+char uart_receive() {
+ if ((UART_STATUS & XUARTPS_SR_RXEMPTY) == XUARTPS_SR_RXEMPTY) return 0;
+ return UART_FIFO;
+}
+
+void init(void) {
+ uint32_t r = 0; // Temporary value variable
+
+ r = UART_CTRL;
+ r &= ~(XUARTPS_CR_TX_EN | XUARTPS_CR_RX_EN); // Clear Tx & Rx Enable
+ r |= XUARTPS_CR_RX_DIS | XUARTPS_CR_TX_DIS; // Tx & Rx Disable
+ UART_CTRL = r;
+
+ UART_MODE = 0;
+ UART_MODE &= ~XUARTPS_MR_CLKSEL; // Clear "Input clock selection" - 0: clock source is uart_ref_clk
+ UART_MODE |= XUARTPS_MR_CHARLEN_8_BIT; // Set "8 bits data"
+ UART_MODE |= XUARTPS_MR_PARITY_NONE; // Set "No parity mode"
+ UART_MODE |= XUARTPS_MR_STOPMODE_1_BIT; // Set "1 stop bit"
+ UART_MODE |= XUARTPS_MR_CHMODE_NORM; // Set "Normal mode"
+
+ // baud_rate = sel_clk / (CD * (BDIV + 1) (ref: UG585 - TRM - Ch. 19 UART)
+ UART_BAUD_DIV = 6; // ("BDIV")
+ UART_BAUD_GEN = 124; // ("CD")
+ // Baud Rate = 100Mhz / (124 * (6 + 1)) = 115200 bps
+
+ UART_CTRL |= (XUARTPS_CR_TXRST | XUARTPS_CR_RXRST); // TX & RX logic reset
+
+ r = UART_CTRL;
+ r |= XUARTPS_CR_RX_EN | XUARTPS_CR_TX_EN; // Set TX & RX enabled
+ r &= ~(XUARTPS_CR_RX_DIS | XUARTPS_CR_TX_DIS); // Clear TX & RX disabled
+ UART_CTRL = r;
+
+ while(1) {
+ // Count to big number before exiting for loop - delay loop
+ for(uint32_t i = 1; i < (1 << 20); i++){
+ uart_receive(); // polling UART receive buffer
+ }
+
+ static char c = '0';
+ uart_send(c++); // Send and increment character variable c
+ // If incremented over 'Z', initialize to '0' (ref: see ASCII character table)
+ if (c > 'Z') c = '0';
+ uart_send_string(str); // Send character array variable str
+
+ }
+}