diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2022-03-27 20:57:01 +0200 |
---|---|---|
committer | David Bauer <mail@david-bauer.net> | 2022-10-14 23:13:02 +0200 |
commit | a296055b82fbb20457273492069ce9d62009e2a1 (patch) | |
tree | 83db19e52b93c16e832ba33f9f11f20514d6a159 /target/linux/mpc85xx/image/spi-loader/include | |
parent | 63e5ba8e69f03a584b707520db0a0821eda3024f (diff) | |
download | upstream-a296055b82fbb20457273492069ce9d62009e2a1.tar.gz upstream-a296055b82fbb20457273492069ce9d62009e2a1.tar.bz2 upstream-a296055b82fbb20457273492069ce9d62009e2a1.zip |
mpc85xx: add SPI kernel loader for TP-Link TL-WDR4900 v1
Similar to the lzma-loader on our MIPS targets, the spi-loader acts as
a second-stage loader that will then load and start the actual kernel.
As the TL-WDR4900 uses SPI-NOR and the P1010 family does not have support
for memory mapping of this type of flash, this loader needs to contain a
basic driver for the FSL ESPI controller.
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
Diffstat (limited to 'target/linux/mpc85xx/image/spi-loader/include')
10 files changed, 426 insertions, 0 deletions
diff --git a/target/linux/mpc85xx/image/spi-loader/include/image.h b/target/linux/mpc85xx/image/spi-loader/include/image.h new file mode 100644 index 0000000000..0377c2959e --- /dev/null +++ b/target/linux/mpc85xx/image/spi-loader/include/image.h @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Derived from U-Boot include/image.h: + * + * (C) Copyright 2008 Semihalf + * + * (C) Copyright 2000-2005 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + ******************************************************************** + * NOTE: This header file defines an interface to U-Boot. Including + * this (unmodified) header file in another file is considered normal + * use of U-Boot, and does *not* fall under the heading of "derived + * work". + ******************************************************************** + */ + +#pragma once + +#include <types.h> + +/* + * Compression Types + * + * The following are exposed to uImage header. + * New IDs *MUST* be appended at the end of the list and *NEVER* + * inserted for backward compatibility. + */ +enum { + IH_COMP_NONE = 0, /* No Compression Used */ + IH_COMP_GZIP, /* gzip Compression Used */ + IH_COMP_BZIP2, /* bzip2 Compression Used */ + IH_COMP_LZMA, /* lzma Compression Used */ + IH_COMP_LZO, /* lzo Compression Used */ + IH_COMP_LZ4, /* lz4 Compression Used */ + IH_COMP_ZSTD, /* zstd Compression Used */ + + IH_COMP_COUNT, +}; + +#define IH_MAGIC 0x27051956 /* Image Magic Number */ +#define IH_MAGIC_OKLI 0x4f4b4c49 /* 'OKLI' Magic Number */ +#define IH_NMLEN 32 /* Image Name Length */ + +/* + * Legacy format image header, + * all data in network byte order (aka natural aka bigendian). + */ +typedef struct image_header { + uint32_t ih_magic; /* Image Header Magic Number */ + uint32_t ih_hcrc; /* Image Header CRC Checksum */ + uint32_t ih_time; /* Image Creation Timestamp */ + uint32_t ih_size; /* Image Data Size */ + uint32_t ih_load; /* Data Load Address */ + uint32_t ih_ep; /* Entry Point Address */ + uint32_t ih_dcrc; /* Image Data CRC Checksum */ + uint8_t ih_os; /* Operating System */ + uint8_t ih_arch; /* CPU architecture */ + uint8_t ih_type; /* Image Type */ + uint8_t ih_comp; /* Compression Type */ + uint8_t ih_name[IH_NMLEN]; /* Image Name */ +} image_header_t; diff --git a/target/linux/mpc85xx/image/spi-loader/include/init.h b/target/linux/mpc85xx/image/spi-loader/include/init.h new file mode 100644 index 0000000000..f3a15f5d43 --- /dev/null +++ b/target/linux/mpc85xx/image/spi-loader/include/init.h @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * Copyright (c) 2022 Matthias Schiffer <mschiffer@universe-factory.net> + */ + +#pragma once + +void start(void); diff --git a/target/linux/mpc85xx/image/spi-loader/include/io.h b/target/linux/mpc85xx/image/spi-loader/include/io.h new file mode 100644 index 0000000000..d6eed5eee0 --- /dev/null +++ b/target/linux/mpc85xx/image/spi-loader/include/io.h @@ -0,0 +1,101 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#pragma once + +#include <stdint.h> + +/* + * Low-level I/O routines. + * + * Copied from <file:arch/powerpc/include/asm/io.h> (which has no copyright) + */ +static inline uint8_t in_8(const volatile uint8_t *addr) +{ + int ret; + + __asm__ __volatile__("lbz%U1%X1 %0,%1; twi 0,%0,0; isync" + : "=r" (ret) : "m" (*addr)); + return ret; +} + +static inline void out_8(volatile uint8_t *addr, uint8_t val) +{ + __asm__ __volatile__("stb%U0%X0 %1,%0; sync" + : "=m" (*addr) : "r" (val)); +} + +static inline uint16_t in_le16(const volatile uint16_t *addr) +{ + uint32_t ret; + + __asm__ __volatile__("lhbrx %0,0,%1; twi 0,%0,0; isync" + : "=r" (ret) : "r" (addr), "m" (*addr)); + + return ret; +} + +static inline uint16_t in_be16(const volatile uint16_t *addr) +{ + uint32_t ret; + + __asm__ __volatile__("lhz%U1%X1 %0,%1; twi 0,%0,0; isync" + : "=r" (ret) : "m" (*addr)); + return ret; +} + +static inline void out_le16(volatile uint16_t *addr, uint16_t val) +{ + __asm__ __volatile__("sthbrx %1,0,%2; sync" : "=m" (*addr) + : "r" (val), "r" (addr)); +} + +static inline void out_be16(volatile uint16_t *addr, uint16_t val) +{ + __asm__ __volatile__("sth%U0%X0 %1,%0; sync" + : "=m" (*addr) : "r" (val)); +} + +static inline uint32_t in_le32(const volatile uint32_t *addr) +{ + uint32_t ret; + + __asm__ __volatile__("lwbrx %0,0,%1; twi 0,%0,0; isync" + : "=r" (ret) : "r" (addr), "m" (*addr)); + return ret; +} + +static inline uint32_t in_be32(const volatile uint32_t *addr) +{ + uint32_t ret; + + __asm__ __volatile__("lwz%U1%X1 %0,%1; twi 0,%0,0; isync" + : "=r" (ret) : "m" (*addr)); + return ret; +} + +static inline void out_le32(volatile uint32_t *addr, uint32_t val) +{ + __asm__ __volatile__("stwbrx %1,0,%2; sync" : "=m" (*addr) + : "r" (val), "r" (addr)); +} + +static inline void out_be32(volatile uint32_t *addr, uint32_t val) +{ + __asm__ __volatile__("stw%U0%X0 %1,%0; sync" + : "=m" (*addr) : "r" (val)); +} + +static inline void sync(void) +{ + asm volatile("sync" : : : "memory"); +} + +static inline void eieio(void) +{ + asm volatile("eieio" : : : "memory"); +} + +static inline void barrier(void) +{ + asm volatile("" : : : "memory"); +} diff --git a/target/linux/mpc85xx/image/spi-loader/include/ppc_asm.h b/target/linux/mpc85xx/image/spi-loader/include/ppc_asm.h new file mode 100644 index 0000000000..5dae34eb70 --- /dev/null +++ b/target/linux/mpc85xx/image/spi-loader/include/ppc_asm.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#pragma once +/* + * + * Definitions used by various bits of low-level assembly code on PowerPC. + * + * Copyright (C) 1995-1999 Gary Thomas, Paul Mackerras, Cort Dougan. + */ + +/* Condition Register Bit Fields */ + +#define cr0 0 +#define cr1 1 +#define cr2 2 +#define cr3 3 +#define cr4 4 +#define cr5 5 +#define cr6 6 +#define cr7 7 + +/* General Purpose Registers (GPRs) */ + +#define r0 0 +#define r1 1 +#define r2 2 +#define r3 3 +#define r4 4 +#define r5 5 +#define r6 6 +#define r7 7 +#define r8 8 +#define r9 9 +#define r10 10 +#define r11 11 +#define r12 12 +#define r13 13 +#define r14 14 +#define r15 15 +#define r16 16 +#define r17 17 +#define r18 18 +#define r19 19 +#define r20 20 +#define r21 21 +#define r22 22 +#define r23 23 +#define r24 24 +#define r25 25 +#define r26 26 +#define r27 27 +#define r28 28 +#define r29 29 +#define r30 30 +#define r31 31 diff --git a/target/linux/mpc85xx/image/spi-loader/include/serial.h b/target/linux/mpc85xx/image/spi-loader/include/serial.h new file mode 100644 index 0000000000..1d80ede335 --- /dev/null +++ b/target/linux/mpc85xx/image/spi-loader/include/serial.h @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: BSD-2-Clause + +#pragma once + +int serial_console_getchar(void); +int serial_console_tstc(void); +void serial_console_putchar(char c); +void serial_console_init(void); + diff --git a/target/linux/mpc85xx/image/spi-loader/include/spi-nor.h b/target/linux/mpc85xx/image/spi-loader/include/spi-nor.h new file mode 100644 index 0000000000..efbf386601 --- /dev/null +++ b/target/linux/mpc85xx/image/spi-loader/include/spi-nor.h @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * Copyright (c) 2022 Matthias Schiffer <mschiffer@universe-factory.net> + */ + +#pragma once + +#include <types.h> + +int spi_nor_read_id(void); +int spi_nor_read_data(void *dest, size_t pos, size_t len); diff --git a/target/linux/mpc85xx/image/spi-loader/include/spi.h b/target/linux/mpc85xx/image/spi-loader/include/spi.h new file mode 100644 index 0000000000..98e799ccaf --- /dev/null +++ b/target/linux/mpc85xx/image/spi-loader/include/spi.h @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Common SPI Interface: Controller-specific definitions + * + * Copyright (c) 2022 Matthias Schiffer <mschiffer@universe-factory.net> + * + * Based on U-boot's spi.h: + * + * (C) Copyright 2001 + * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com. + */ + +#pragma once + +#include <types.h> + +/* SPI mode flags */ +#define SPI_CPHA BIT(0) /* clock phase (1 = SPI_CLOCK_PHASE_SECOND) */ +#define SPI_CPOL BIT(1) /* clock polarity (1 = SPI_POLARITY_HIGH) */ +#define SPI_MODE_0 (0|0) /* (original MicroWire) */ +#define SPI_MODE_1 (0|SPI_CPHA) +#define SPI_MODE_2 (SPI_CPOL|0) +#define SPI_MODE_3 (SPI_CPOL|SPI_CPHA) + +struct spi_transfer { + const void *tx_buf; + void *rx_buf; + size_t len; +}; + +static inline size_t spi_message_len(const struct spi_transfer *msg, int n) { + size_t total = 0; + for (int i = 0; i < n; i++) { + total += msg[i].len; + } + return total; +} + +int spi_init(unsigned int cs, unsigned int max_hz, unsigned int mode); +int spi_claim_bus(void); +void spi_release_bus(void); +int spi_xfer(const struct spi_transfer *msg, int n); +size_t spi_max_xfer(void); diff --git a/target/linux/mpc85xx/image/spi-loader/include/stdio.h b/target/linux/mpc85xx/image/spi-loader/include/stdio.h new file mode 100644 index 0000000000..60494300b2 --- /dev/null +++ b/target/linux/mpc85xx/image/spi-loader/include/stdio.h @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * Copyright (c) 2022 Matthias Schiffer <mschiffer@universe-factory.net> + */ + +#pragma once + +#include <serial.h> +#include <types.h> + +static inline int getchar(void) +{ + return serial_console_getchar(); +} + +static inline int tstc(void) +{ + return serial_console_tstc(); +} + +static inline int putchar(char c) +{ + if (c == '\n') + serial_console_putchar('\r'); + serial_console_putchar(c); + return 0; +} + +int puts(const char *s); + +/* Utility functions */ +void put_u4(uint8_t v); +void put_u8(uint8_t v); +void put_u16(uint16_t v); +void put_u32(uint32_t v); +void put_ptr(const void *p); +void put_array(const void *p, size_t l); + +#define put_with_label(label, put, value) do { \ + puts(label); \ + put(value); \ + puts("\n"); \ + } while (0) diff --git a/target/linux/mpc85xx/image/spi-loader/include/string.h b/target/linux/mpc85xx/image/spi-loader/include/string.h new file mode 100644 index 0000000000..f9e6fed38d --- /dev/null +++ b/target/linux/mpc85xx/image/spi-loader/include/string.h @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#pragma once + +#include <stddef.h> + +extern char *strcpy(char *dest, const char *src); +extern char *strncpy(char *dest, const char *src, size_t n); +extern char *strcat(char *dest, const char *src); +extern char *strchr(const char *s, int c); +extern char *strrchr(const char *s, int c); +extern int strcmp(const char *s1, const char *s2); +extern int strncmp(const char *s1, const char *s2, size_t n); +extern size_t strlen(const char *s); +extern size_t strnlen(const char *s, size_t count); + +extern void *memset(void *s, int c, size_t n); +extern void *memmove(void *dest, const void *src, unsigned long n); +extern void *memcpy(void *dest, const void *src, unsigned long n); +extern void *memchr(const void *s, int c, size_t n); +extern int memcmp(const void *s1, const void *s2, size_t n); + +extern void flush_cache(void *, unsigned long); diff --git a/target/linux/mpc85xx/image/spi-loader/include/types.h b/target/linux/mpc85xx/image/spi-loader/include/types.h new file mode 100644 index 0000000000..b80f9e625c --- /dev/null +++ b/target/linux/mpc85xx/image/spi-loader/include/types.h @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Code originates from Linux kernel arch/powerpc/boot + * (types.h, swab.h, of.h) + */ + +#pragma once + +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +#define BIT(nr) (1UL << (nr)) + +#define min(x,y) ({ \ + typeof(x) _x = (x); \ + typeof(y) _y = (y); \ + (void) (&_x == &_y); \ + _x < _y ? _x : _y; }) + +#define max(x,y) ({ \ + typeof(x) _x = (x); \ + typeof(y) _y = (y); \ + (void) (&_x == &_y); \ + _x > _y ? _x : _y; }) + +#define min_t(type, a, b) min(((type) a), ((type) b)) +#define max_t(type, a, b) max(((type) a), ((type) b)) + +static inline uint16_t swab16(uint16_t x) +{ + return ((x & (uint16_t)0x00ffU) << 8) | + ((x & (uint16_t)0xff00U) >> 8); +} + +static inline uint32_t swab32(uint32_t x) +{ + return ((x & (uint32_t)0x000000ffUL) << 24) | + ((x & (uint32_t)0x0000ff00UL) << 8) | + ((x & (uint32_t)0x00ff0000UL) >> 8) | + ((x & (uint32_t)0xff000000UL) >> 24); +} + +static inline uint64_t swab64(uint64_t x) +{ + return (uint64_t)((x & (uint64_t)0x00000000000000ffULL) << 56) | + (uint64_t)((x & (uint64_t)0x000000000000ff00ULL) << 40) | + (uint64_t)((x & (uint64_t)0x0000000000ff0000ULL) << 24) | + (uint64_t)((x & (uint64_t)0x00000000ff000000ULL) << 8) | + (uint64_t)((x & (uint64_t)0x000000ff00000000ULL) >> 8) | + (uint64_t)((x & (uint64_t)0x0000ff0000000000ULL) >> 24) | + (uint64_t)((x & (uint64_t)0x00ff000000000000ULL) >> 40) | + (uint64_t)((x & (uint64_t)0xff00000000000000ULL) >> 56); +} + +#ifdef __LITTLE_ENDIAN__ +#define cpu_to_be16(x) swab16(x) +#define be16_to_cpu(x) swab16(x) +#define cpu_to_be32(x) swab32(x) +#define be32_to_cpu(x) swab32(x) +#define cpu_to_be64(x) swab64(x) +#define be64_to_cpu(x) swab64(x) +#else +#define cpu_to_be16(x) (x) +#define be16_to_cpu(x) (x) +#define cpu_to_be32(x) (x) +#define be32_to_cpu(x) (x) +#define cpu_to_be64(x) (x) +#define be64_to_cpu(x) (x) +#endif |