From 102b0d2daa97dae68d3eed54d8fe37a9cc38a892 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 28 Apr 2024 11:13:47 +0200 Subject: Adding upstream version 2.8.0+dfsg. Signed-off-by: Daniel Baumann --- drivers/amlogic/console/aarch64/meson_console.S | 262 ++++++++++++++++++++++++ drivers/amlogic/crypto/sha_dma.c | 183 +++++++++++++++++ 2 files changed, 445 insertions(+) create mode 100644 drivers/amlogic/console/aarch64/meson_console.S create mode 100644 drivers/amlogic/crypto/sha_dma.c (limited to 'drivers/amlogic') diff --git a/drivers/amlogic/console/aarch64/meson_console.S b/drivers/amlogic/console/aarch64/meson_console.S new file mode 100644 index 0000000..6d0a2d6 --- /dev/null +++ b/drivers/amlogic/console/aarch64/meson_console.S @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + + .globl console_meson_register + .globl console_meson_init + .globl console_meson_putc + .globl console_meson_getc + .globl console_meson_flush + .globl console_meson_core_putc + .globl console_meson_core_getc + .globl console_meson_core_flush + + /* ----------------------------------------------- + * Hardware definitions + * ----------------------------------------------- + */ +#define MESON_WFIFO_OFFSET 0x0 +#define MESON_RFIFO_OFFSET 0x4 +#define MESON_CONTROL_OFFSET 0x8 +#define MESON_STATUS_OFFSET 0xC +#define MESON_MISC_OFFSET 0x10 +#define MESON_REG5_OFFSET 0x14 + +#define MESON_CONTROL_CLR_ERROR_BIT 24 +#define MESON_CONTROL_RX_RESET_BIT 23 +#define MESON_CONTROL_TX_RESET_BIT 22 +#define MESON_CONTROL_RX_ENABLE_BIT 13 +#define MESON_CONTROL_TX_ENABLE_BIT 12 + +#define MESON_STATUS_RX_EMPTY_BIT 20 +#define MESON_STATUS_TX_FULL_BIT 21 +#define MESON_STATUS_TX_EMPTY_BIT 22 + +#define MESON_REG5_USE_XTAL_CLK_BIT 24 +#define MESON_REG5_USE_NEW_RATE_BIT 23 +#define MESON_REG5_NEW_BAUD_RATE_MASK 0x7FFFFF + + /* ----------------------------------------------- + * int console_meson_register(uintptr_t base, + * uint32_t clk, uint32_t baud, + * console_t *console); + * Function to initialize and register a new MESON + * console. Storage passed in for the console struct + * *must* be persistent (i.e. not from the stack). + * In: x0 - UART register base address + * w1 - UART clock in Hz + * w2 - Baud rate + * x3 - pointer to empty console_t struct + * Out: return 1 on success, 0 on error + * Clobber list : x0, x1, x2, x6, x7, x14 + * ----------------------------------------------- + */ +func console_meson_register + mov x7, x30 + mov x6, x3 + cbz x6, register_fail + str x0, [x6, #CONSOLE_T_BASE] + + bl console_meson_init + cbz x0, register_fail + + mov x0, x6 + mov x30, x7 + finish_console_register meson putc=1, getc=1, flush=1 + +register_fail: + ret x7 +endfunc console_meson_register + + /* ----------------------------------------------- + * int console_meson_init(uintptr_t base_addr, + * unsigned int uart_clk, unsigned int baud_rate) + * Function to initialize the console without a + * C Runtime to print debug information. This + * function will be accessed by console_init and + * crash reporting. + * In: x0 - console base address + * w1 - Uart clock in Hz + * w2 - Baud rate + * Out: return 1 on success else 0 on error + * Clobber list : x0-x3 + * ----------------------------------------------- + */ +func console_meson_init + cmp w0, #0 + beq init_fail + mov_imm w3, 24000000 /* TODO: This only works with a 24 MHz clock. */ + cmp w1, w3 + bne init_fail + cmp w2, #0 + beq init_fail + /* Set baud rate: value = ((clock / 3) / baudrate) - 1 */ + mov w3, #3 + udiv w3, w1, w3 + udiv w3, w3, w2 + sub w3, w3, #1 + orr w3, w3, #((1 << MESON_REG5_USE_XTAL_CLK_BIT) | \ + (1 << MESON_REG5_USE_NEW_RATE_BIT)) + str w3, [x0, #MESON_REG5_OFFSET] + /* Reset UART and clear error flag */ + ldr w3, [x0, #MESON_CONTROL_OFFSET] + orr w3, w3, #((1 << MESON_CONTROL_CLR_ERROR_BIT) | \ + (1 << MESON_CONTROL_RX_RESET_BIT) | \ + (1 << MESON_CONTROL_TX_RESET_BIT)) + str w3, [x0, #MESON_CONTROL_OFFSET] + bic w3, w3, #((1 << MESON_CONTROL_CLR_ERROR_BIT) | \ + (1 << MESON_CONTROL_RX_RESET_BIT) | \ + (1 << MESON_CONTROL_TX_RESET_BIT)) + str w3, [x0, #MESON_CONTROL_OFFSET] + /* Enable transfer and receive FIFO */ + orr w3, w3, #((1 << MESON_CONTROL_RX_ENABLE_BIT) | \ + (1 << MESON_CONTROL_TX_ENABLE_BIT)) + str w3, [x0, #MESON_CONTROL_OFFSET] + /* Success */ + mov w0, #1 + ret +init_fail: + mov w0, wzr + ret +endfunc console_meson_init + + /* -------------------------------------------------------- + * int console_meson_putc(int c, console_t *console) + * Function to output a character over the console. It + * returns the character printed on success or -1 on error. + * In : w0 - character to be printed + * x1 - pointer to console_t structure + * Out : return -1 on error else return character. + * Clobber list : x2 + * -------------------------------------------------------- + */ +func console_meson_putc +#if ENABLE_ASSERTIONS + cmp x1, #0 + ASM_ASSERT(ne) +#endif /* ENABLE_ASSERTIONS */ + ldr x1, [x1, #CONSOLE_T_BASE] + b console_meson_core_putc +endfunc console_meson_putc + + /* -------------------------------------------------------- + * int console_meson_core_putc(int c, uintptr_t base_addr) + * Function to output a character over the console. It + * returns the character printed on success or -1 on error. + * In : w0 - character to be printed + * x1 - console base address + * Out : return -1 on error else return character. + * Clobber list : x2 + * -------------------------------------------------------- + */ +func console_meson_core_putc +#if ENABLE_ASSERTIONS + cmp x1, #0 + ASM_ASSERT(ne) +#endif + /* Prepend '\r' to '\n' */ + cmp w0, #0xA + b.ne 2f + /* Wait until the transmit FIFO isn't full */ +1: ldr w2, [x1, #MESON_STATUS_OFFSET] + tbnz w2, #MESON_STATUS_TX_FULL_BIT, 1b + /* Write '\r' if needed */ + mov w2, #0xD + str w2, [x1, #MESON_WFIFO_OFFSET] + /* Wait until the transmit FIFO isn't full */ +2: ldr w2, [x1, #MESON_STATUS_OFFSET] + tbnz w2, #MESON_STATUS_TX_FULL_BIT, 2b + /* Write input character */ + str w0, [x1, #MESON_WFIFO_OFFSET] + ret +endfunc console_meson_core_putc + + /* --------------------------------------------- + * int console_meson_getc(console_t *console) + * Function to get a character from the console. + * It returns the character grabbed on success + * or -1 if no character is available. + * In : x0 - pointer to console_t structure + * Out: w0 - character if available, else -1 + * Clobber list : x0, x1 + * --------------------------------------------- + */ +func console_meson_getc +#if ENABLE_ASSERTIONS + cmp x0, #0 + ASM_ASSERT(ne) +#endif /* ENABLE_ASSERTIONS */ + ldr x0, [x0, #CONSOLE_T_BASE] + b console_meson_core_getc +endfunc console_meson_getc + + /* --------------------------------------------- + * int console_meson_core_getc(uintptr_t base_addr) + * Function to get a character from the console. + * It returns the character grabbed on success + * or -1 if no character is available. + * In : x0 - console base address + * Out: w0 - character if available, else -1 + * Clobber list : x0, x1 + * --------------------------------------------- + */ +func console_meson_core_getc +#if ENABLE_ASSERTIONS + cmp x0, #0 + ASM_ASSERT(ne) +#endif + /* Is the receive FIFO empty? */ + ldr w1, [x0, #MESON_STATUS_OFFSET] + tbnz w1, #MESON_STATUS_RX_EMPTY_BIT, 1f + /* Read one character from the RX FIFO */ + ldr w0, [x0, #MESON_RFIFO_OFFSET] + ret +1: + mov w0, #ERROR_NO_PENDING_CHAR + ret +endfunc console_meson_core_getc + + /* --------------------------------------------- + * void console_meson_flush(console_t *console) + * Function to force a write of all buffered + * data that hasn't been output. + * In : x0 - pointer to console_t structure + * Out : void. + * Clobber list : x0, x1 + * --------------------------------------------- + */ +func console_meson_flush +#if ENABLE_ASSERTIONS + cmp x0, #0 + ASM_ASSERT(ne) +#endif /* ENABLE_ASSERTIONS */ + ldr x0, [x0, #CONSOLE_T_BASE] + b console_meson_core_flush +endfunc console_meson_flush + + /* --------------------------------------------- + * void console_meson_core_flush(uintptr_t base_addr) + * Function to force a write of all buffered + * data that hasn't been output. + * In : x0 - console base address + * Out : void. + * Clobber list : x0, x1 + * --------------------------------------------- + */ +func console_meson_core_flush +#if ENABLE_ASSERTIONS + cmp x0, #0 + ASM_ASSERT(ne) +#endif + /* Wait until the transmit FIFO is empty */ +1: ldr w1, [x0, #MESON_STATUS_OFFSET] + tbz w1, #MESON_STATUS_TX_EMPTY_BIT, 1b + ret +endfunc console_meson_core_flush diff --git a/drivers/amlogic/crypto/sha_dma.c b/drivers/amlogic/crypto/sha_dma.c new file mode 100644 index 0000000..5c16d49 --- /dev/null +++ b/drivers/amlogic/crypto/sha_dma.c @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2019, Remi Pommarel + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include + +#include "aml_private.h" + +#define ASD_MODE_SHA224 0x7 +#define ASD_MODE_SHA256 0x6 + +/* SHA DMA descriptor */ +struct asd_desc { + uint32_t cfg; + uint32_t src; + uint32_t dst; +}; +#define ASD_DESC_GET(x, msk, off) (((x) >> (off)) & (msk)) +#define ASD_DESC_SET(x, v, msk, off) \ + ((x) = ((x) & ~((msk) << (off))) | (((v) & (msk)) << (off))) + +#define ASD_DESC_LEN_OFF 0 +#define ASD_DESC_LEN_MASK 0x1ffff +#define ASD_DESC_LEN(d) \ + (ASD_DESC_GET((d)->cfg, ASD_DESC_LEN_MASK, ASD_DESC_LEN_OFF)) +#define ASD_DESC_LEN_SET(d, v) \ + (ASD_DESC_SET((d)->cfg, v, ASD_DESC_LEN_MASK, ASD_DESC_LEN_OFF)) + +#define ASD_DESC_IRQ_OFF 17 +#define ASD_DESC_IRQ_MASK 0x1 +#define ASD_DESC_IRQ(d) \ + (ASD_DESC_GET((d)->cfg, ASD_DESC_IRQ_MASK, ASD_DESC_IRQ_OFF)) +#define ASD_DESC_IRQ_SET(d, v) \ + (ASD_DESC_SET((d)->cfg, v, ASD_DESC_IRQ_MASK, ASD_DESC_IRQ_OFF)) + +#define ASD_DESC_EOD_OFF 18 +#define ASD_DESC_EOD_MASK 0x1 +#define ASD_DESC_EOD(d) \ + (ASD_DESC_GET((d)->cfg, ASD_DESC_EOD_MASK, ASD_DESC_EOD_OFF)) +#define ASD_DESC_EOD_SET(d, v) \ + (ASD_DESC_SET((d)->cfg, v, ASD_DESC_EOD_MASK, ASD_DESC_EOD_OFF)) + +#define ASD_DESC_LOOP_OFF 19 +#define ASD_DESC_LOOP_MASK 0x1 +#define ASD_DESC_LOOP(d) \ + (ASD_DESC_GET((d)->cfg, ASD_DESC_LOOP_MASK, ASD_DESC_LOOP_OFF)) +#define ASD_DESC_LOOP_SET(d, v) \ + (ASD_DESC_SET((d)->cfg, v, ASD_DESC_LOOP_MASK, ASD_DESC_LOOP_OFF)) + +#define ASD_DESC_MODE_OFF 20 +#define ASD_DESC_MODE_MASK 0xf +#define ASD_DESC_MODE(d) \ + (ASD_DESC_GET((d)->cfg, ASD_DESC_MODE_MASK, ASD_DESC_MODE_OFF)) +#define ASD_DESC_MODE_SET(d, v) \ + (ASD_DESC_SET((d)->cfg, v, ASD_DESC_MODE_MASK, ASD_DESC_MODE_OFF)) + +#define ASD_DESC_BEGIN_OFF 24 +#define ASD_DESC_BEGIN_MASK 0x1 +#define ASD_DESC_BEGIN(d) \ + (ASD_DESC_GET((d)->cfg, ASD_DESC_BEGIN_MASK, ASD_DESC_BEGIN_OFF)) +#define ASD_DESC_BEGIN_SET(d, v) \ + (ASD_DESC_SET((d)->cfg, v, ASD_DESC_BEGIN_MASK, ASD_DESC_BEGIN_OFF)) + +#define ASD_DESC_END_OFF 25 +#define ASD_DESC_END_MASK 0x1 +#define ASD_DESC_END(d) \ + (ASD_DESC_GET((d)->cfg, ASD_DESC_END_MASK, ASD_DESC_END_OFF)) +#define ASD_DESC_END_SET(d, v) \ + (ASD_DESC_SET((d)->cfg, v, ASD_DESC_END_MASK, ASD_DESC_END_OFF)) + +#define ASD_DESC_OP_OFF 26 +#define ASD_DESC_OP_MASK 0x2 +#define ASD_DESC_OP(d) \ + (ASD_DESC_GET((d)->cfg, ASD_DESC_OP_MASK, ASD_DESC_OP_OFF)) +#define ASD_DESC_OP_SET(d, v) \ + (ASD_DESC_SET((d)->cfg, v, ASD_DESC_OP_MASK, ASD_DESC_OP_OFF)) + +#define ASD_DESC_ENCONLY_OFF 28 +#define ASD_DESC_ENCONLY_MASK 0x1 +#define ASD_DESC_ENCONLY(d) \ + (ASD_DESC_GET((d)->cfg, ASD_DESC_ENCONLY_MASK, ASD_DESC_ENCONLY_OFF)) +#define ASD_DESC_ENCONLY_SET(d, v) \ + (ASD_DESC_SET((d)->cfg, v, ASD_DESC_ENCONLY_MASK, ASD_DESC_ENCONLY_OFF)) + +#define ASD_DESC_BLOCK_OFF 29 +#define ASD_DESC_BLOCK_MASK 0x1 +#define ASD_DESC_BLOCK(d) \ + (ASD_DESC_GET((d)->cfg, ASD_DESC_BLOCK_MASK, ASD_DESC_BLOCK_OFF)) +#define ASD_DESC_BLOCK_SET(d, v) \ + (ASD_DESC_SET((d)->cfg, v, ASD_DESC_BLOCK_MASK, ASD_DESC_BLOCK_OFF)) + +#define ASD_DESC_ERR_OFF 30 +#define ASD_DESC_ERR_MASK 0x1 +#define ASD_DESC_ERR(d) \ + (ASD_DESC_GET((d)->cfg, ASD_DESC_ERR_MASK, ASD_DESC_ERR_OFF)) +#define ASD_DESC_ERR_SET(d, v) \ + (ASD_DESC_SET((d)->cfg, v, ASD_DESC_ERR_MASK, ASD_DESC_ERR_OFF)) + +#define ASD_DESC_OWNER_OFF 31u +#define ASD_DESC_OWNER_MASK 0x1u +#define ASD_DESC_OWNER(d) \ + (ASD_DESC_GET((d)->cfg, ASD_DESC_OWNER_MASK, ASD_DESC_OWNER_OFF)) +#define ASD_DESC_OWNER_SET(d, v) \ + (ASD_DESC_SET((d)->cfg, v, ASD_DESC_OWNER_MASK, ASD_DESC_OWNER_OFF)) + +static void asd_compute_sha(struct asd_ctx *ctx, void *data, size_t len, + int finalize) +{ + /* Make it cache line size aligned ? */ + struct asd_desc desc = { + .src = (uint32_t)(uintptr_t)data, + .dst = (uint32_t)(uintptr_t)ctx->digest, + }; + + /* Check data address is 32bit compatible */ + assert((uintptr_t)data == (uintptr_t)desc.src); + assert((uintptr_t)ctx->digest == (uintptr_t)desc.dst); + assert((uintptr_t)&desc == (uintptr_t)&desc); + + ASD_DESC_LEN_SET(&desc, len); + ASD_DESC_OWNER_SET(&desc, 1u); + ASD_DESC_ENCONLY_SET(&desc, 1); + ASD_DESC_EOD_SET(&desc, 1); + if (ctx->started == 0) { + ASD_DESC_BEGIN_SET(&desc, 1); + ctx->started = 1; + } + if (finalize) { + ASD_DESC_END_SET(&desc, 1); + ctx->started = 0; + } + if (ctx->mode == ASM_SHA224) + ASD_DESC_MODE_SET(&desc, ASD_MODE_SHA224); + else + ASD_DESC_MODE_SET(&desc, ASD_MODE_SHA256); + + flush_dcache_range((uintptr_t)&desc, sizeof(desc)); + flush_dcache_range((uintptr_t)data, len); + + mmio_write_32(AML_SHA_DMA_STATUS, 0xf); + mmio_write_32(AML_SHA_DMA_DESC, ((uintptr_t)&desc) | 2); + while (mmio_read_32(AML_SHA_DMA_STATUS) == 0) + continue; + flush_dcache_range((uintptr_t)ctx->digest, SHA256_HASHSZ); +} + +void asd_sha_update(struct asd_ctx *ctx, void *data, size_t len) +{ + size_t nr; + + if (ctx->blocksz) { + nr = MIN(len, SHA256_BLOCKSZ - ctx->blocksz); + memcpy(ctx->block + ctx->blocksz, data, nr); + ctx->blocksz += nr; + len -= nr; + data += nr; + } + + if (ctx->blocksz == SHA256_BLOCKSZ) { + asd_compute_sha(ctx, ctx->block, SHA256_BLOCKSZ, 0); + ctx->blocksz = 0; + } + + asd_compute_sha(ctx, data, len & ~(SHA256_BLOCKSZ - 1), 0); + data += len & ~(SHA256_BLOCKSZ - 1); + + if (len & (SHA256_BLOCKSZ - 1)) { + nr = len & (SHA256_BLOCKSZ - 1); + memcpy(ctx->block + ctx->blocksz, data, nr); + ctx->blocksz += nr; + } +} + +void asd_sha_finalize(struct asd_ctx *ctx) +{ + asd_compute_sha(ctx, ctx->block, ctx->blocksz, 1); +} -- cgit v1.2.3