This is an automated email from Gerrit. "Ryan QIAN <jianghao.q...@outlook.com>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/8695
-- gerrit commit fc99ff9dad5375fdd7a45ea326d6e2c350696daf Author: Ryan QIAN <jianghao.q...@hpmicro.com> Date: Tue Jan 7 15:09:18 2025 +0800 contrib/loaders/flash/hpmicro: add hpmicro device xpi support - add xpi flash support for hpmicro devices Change-Id: I3531fdf20a34561c6f3fe6ac0b9af988d483aae7 Signed-off-by: Ryan QIAN <jianghao.q...@hpmicro.com> diff --git a/contrib/loaders/flash/hpmicro/Makefile b/contrib/loaders/flash/hpmicro/Makefile new file mode 100644 index 0000000000..1b3ea9865d --- /dev/null +++ b/contrib/loaders/flash/hpmicro/Makefile @@ -0,0 +1,51 @@ +# Copyright (c) 2023 HPMicro +# SPDX-License-Identifier: BSD-3-Clause +# +BIN2C = ../../../../src/helper/bin2char.sh + + +PROJECT=hpm_xpi_flash +CROSS_COMPILE ?= riscv32-unknown-elf- +CC=$(CROSS_COMPILE)gcc +AS=$(CROSS_COMPILE)gcc +OBJCOPY=$(CROSS_COMPILE)objcopy +OBJDUMP=$(CROSS_COMPILE)objdump +LD=$(CROSS_COMPILE)ld +LDSCRIPT=linker.ld + +OPT=-O3 + +ASFLAGS= +CFLAGS=$(OPT) -fomit-frame-pointer -Wall +LDFLAGS=-nostartfiles -T$(LDSCRIPT) -Wl,-Map=$(PROJECT).map -static -Wl,--gc-sections +OBJS=$(ASRC:.S=.o) $(SRC:.c=.o) + +SRC=openocd_flash_algo.c +ASRC=func_table.S + +all: $(OBJS) $(PROJECT).elf $(PROJECT).bin $(PROJECT).lst $(PROJECT).inc + +%o: %c + @$(CC) -c $(CFLAGS) -I . $< -o $@ + +%o: %S + @$(AS) -c $(ASFLAGS) -I . $< -o $@ + +%elf: $(OBJS) + @$(CC) $(OBJS) $(LDFLAGS) -o $@ + +%lst: %elf + @$(OBJDUMP) -h -S $< > $@ + +%bin: %elf + @$(OBJCOPY) -Obinary $< $@ + +%inc: %bin + $(BIN2C) < $< > $@ + +clean: + @-rm -f *.o *.elf *.lst *.bin *.inc + +.PHONY: all clean + +.INTERMEDIATE: $(patsubst %.S,%.o,$(SRCS)) $(patsubst %.S,%.elf,$(SRCS)) $(patsubst %.S,%.bin,$(SRCS)) diff --git a/contrib/loaders/flash/hpmicro/func_table.S b/contrib/loaders/flash/hpmicro/func_table.S new file mode 100644 index 0000000000..3bca76a498 --- /dev/null +++ b/contrib/loaders/flash/hpmicro/func_table.S @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2021 HPMicro + */ + .section .func_table, "ax" + .global _init +_init: + jal flash_init + ebreak + jal flash_erase + ebreak + jal flash_program + ebreak + jal flash_read + ebreak + jal flash_get_info + ebreak + jal flash_erase_chip + ebreak + jal flash_deinit + ebreak diff --git a/contrib/loaders/flash/hpmicro/hpm_common.h b/contrib/loaders/flash/hpmicro/hpm_common.h new file mode 100644 index 0000000000..110f0b3eb1 --- /dev/null +++ b/contrib/loaders/flash/hpmicro/hpm_common.h @@ -0,0 +1,278 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 2021-2023 HPMicro + */ + +#ifndef _HPM_COMMON_H +#define _HPM_COMMON_H + +#include <assert.h> +#include <stdbool.h> +#include <stdint.h> +#include <string.h> +#include <stdlib.h> + +/** + * + * @brief COMMON driver APIs + * @defgroup common_interface COMMON driver APIs + * @{ + * + */ + +#define __R volatile const /* Define "read-only" permission */ +#define __RW volatile /* Define "read-write" permission */ +#define __W volatile /* Define "write-only" permission */ + +#ifndef __I +#define __I __R +#endif + +#ifndef __IO +#define __IO __RW +#endif + +#ifndef __O +#define __O __W +#endif + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) +#endif + +#ifndef MAX +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#endif +#ifndef MIN +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif + +#define HPM_BITSMASK(val, offset) ((uint32_t)(val) << (offset)) +#define IS_HPM_BITMASK_SET(val, mask) (((uint32_t)(val) & (uint32_t)(mask)) != 0U) +#define IS_HPM_BIT_SET(val, offset) (((uint32_t)(val) & (1UL << (offset))) != 0U) +#define IS_HPM_BITMASK_CLR(val, mask) (((uint32_t)(val) & (uint32_t)(mask)) == 0U) +#define IS_HPM_BIT_CLR(val, offset) (((uint32_t)(val) & (1UL << (offset))) == 0U) + +#define HPM_BREAK_IF(cond) do {if (cond) break; } while (0) +#define HPM_CONTINUE_IF(cond) do {if (cond) continue; } while (0) + +#define HPM_CHECK_RET(x) \ + do { \ + stat = (x); \ + if (status_success != stat) { \ + return stat; \ + } \ + } while (false) + +#define SIZE_1KB (1024UL) +#define SIZE_1MB (1048576UL) + +typedef uint32_t hpm_stat_t; + +/* @brief Enum definition for the Status group + * Rule: + * [Group] 0-999 for the SoC driver and the corresponding components + * 1000 or above for the application status group + * [Code] Valid value: 0-999 + * + */ +#define MAKE_STATUS(group, code) ((uint32_t)(group) * 1000U + (uint32_t)(code)) +/* @brief System status group definitions */ +enum { + status_group_common = 0, + status_group_uart = 1, + status_group_i2c = 2, + status_group_spi = 3, + status_group_usb = 4, + status_group_i2s = 5, + status_group_xpi = 6, + status_group_l1c, + status_group_dma, + status_group_femc, + status_group_sdp, + status_group_xpi_nor, + status_group_otp, + status_group_lcdc, + status_group_mbx, + status_group_rng, + status_group_pdma, + status_group_wdg, + status_group_pmic_sec, + status_group_can, + status_group_sdxc, + status_group_pcfg, + status_group_clk, + status_group_pllctl, + status_group_pllctlv2, + status_group_ffa, + status_group_mcan, + + status_group_middleware_start = 500, + status_group_sdmmc = status_group_middleware_start, + status_group_audio_codec, + status_group_dma_manager, +}; + +/* @brief Common status code definitions */ +enum { + status_success = MAKE_STATUS(status_group_common, 0), + status_fail = MAKE_STATUS(status_group_common, 1), + status_invalid_argument = MAKE_STATUS(status_group_common, 2), + status_timeout = MAKE_STATUS(status_group_common, 3), +}; + +#if defined(__GNUC__) + +/* alway_inline */ +#define ATTR_ALWAYS_INLINE __attribute__((always_inline)) + +/* weak */ +#define ATTR_WEAK __attribute__((weak)) + +/* alignment */ +#define ATTR_ALIGN(alignment) __attribute__((aligned(alignment))) + +/* place var_declare at section_name, e.x. PLACE_AT(".target_section", var); */ +#define ATTR_PLACE_AT(section_name) __attribute__((section(section_name))) + +#define ATTR_PLACE_AT_WITH_ALIGNMENT(section_name, alignment) \ +ATTR_PLACE_AT(section_name) ATTR_ALIGN(alignment) + +#define ATTR_PLACE_AT_NONCACHEABLE ATTR_PLACE_AT(".noncacheable.bss") +#define ATTR_PLACE_AT_NONCACHEABLE_WITH_ALIGNMENT(alignment) \ + ATTR_PLACE_AT_NONCACHEABLE ATTR_ALIGN(alignment) + +#define ATTR_PLACE_AT_NONCACHEABLE_BSS ATTR_PLACE_AT(".noncacheable.bss") +#define ATTR_PLACE_AT_NONCACHEABLE_BSS_WITH_ALIGNMENT(alignment) \ + ATTR_PLACE_AT_NONCACHEABLE_BSS ATTR_ALIGN(alignment) + +/* initialize variable x with y using PLACE_AT_NONCACHEABLE_INIT(x) = {y}; */ +#define ATTR_PLACE_AT_NONCACHEABLE_INIT ATTR_PLACE_AT(".noncacheable.init") +#define ATTR_PLACE_AT_NONCACHEABLE_INIT_WITH_ALIGNMENT(alignment) \ + ATTR_PLACE_AT_NONCACHEABLE_INIT ATTR_ALIGN(alignment) + +#define ATTR_RAMFUNC ATTR_PLACE_AT(".fast") +#define ATTR_RAMFUNC_WITH_ALIGNMENT(alignment) \ + ATTR_RAMFUNC ATTR_ALIGN(alignment) + +#define ATTR_SHARE_MEM ATTR_PLACE_AT(".sh_mem") + +#define NOP() __asm volatile("nop") +#define WFI() __asm volatile("wfi") + +#define HPM_ATTR_MACHINE_INTERRUPT __attribute__ ((section(".isr_vector"), interrupt("machine"), aligned(4))) + +#elif defined(__ICCRISCV__) + + + /* alway_inline */ +#define ATTR_ALWAYS_INLINE __attribute__((always_inline)) + +/* weak */ +#define ATTR_WEAK __weak + +/* alignment */ +#define ATTR_ALIGN(alignment) __attribute__((aligned(alignment))) + +/* place var_declare at section_name, e.x. PLACE_AT(".target_section", var); */ +#define ATTR_PLACE_AT(section_name) __attribute__((section(section_name))) + +#define ATTR_PLACE_AT_WITH_ALIGNMENT(section_name, alignment) \ +ATTR_PLACE_AT(section_name) ATTR_ALIGN(alignment) + +#define ATTR_PLACE_AT_NONCACHEABLE ATTR_PLACE_AT(".noncacheable.bss") +#define ATTR_PLACE_AT_NONCACHEABLE_WITH_ALIGNMENT(alignment) \ + ATTR_PLACE_AT_NONCACHEABLE ATTR_ALIGN(alignment) + +#define ATTR_PLACE_AT_NONCACHEABLE_BSS ATTR_PLACE_AT(".noncacheable.bss") +#define ATTR_PLACE_AT_NONCACHEABLE_BSS_WITH_ALIGNMENT(alignment) \ + ATTR_PLACE_AT_NONCACHEABLE_BSS ATTR_ALIGN(alignment) + +/* initialize variable x with y using PLACE_AT_NONCACHEABLE_INIT(x) = {y}; */ +#define ATTR_PLACE_AT_NONCACHEABLE_INIT ATTR_PLACE_AT(".noncacheable.init") +#define ATTR_PLACE_AT_NONCACHEABLE_INIT_WITH_ALIGNMENT(alignment) \ + ATTR_PLACE_AT_NONCACHEABLE_INIT ATTR_ALIGN(alignment) + +#define ATTR_RAMFUNC ATTR_PLACE_AT(".fast") +#define ATTR_RAMFUNC_WITH_ALIGNMENT(alignment) \ + ATTR_RAMFUNC ATTR_ALIGN(alignment) + +#define ATTR_SHARE_MEM ATTR_PLACE_AT(".sh_mem") + +#define NOP() __asm volatile("nop") +#define WFI() __asm volatile("wfi") + +#define HPM_ATTR_MACHINE_INTERRUPT __machine __interrupt + +#else +#error Unknown toolchain +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @brief Count bits set to 1 + * + * @param value Data to be counted + * + * @return number of bits set to 1 + */ +static inline uint32_t count_set_bits(uint32_t value) +{ + if (value == 0) + return 0; + return 1 + count_set_bits(value & (value - 1)); +} + +/** + * @brief Count bits set to 1 from least significant bit + * + * @param value Data to be counted + * + * @return number of bits set to 1 + * @return 0xFFFFFFFF if no bit was set to 1 + */ +static inline uint32_t get_first_set_bit_from_lsb(uint32_t value) +{ + uint32_t i = 0; + if (!value) + return 0xFFFFFFFFUL; + while (value && !(value & 0x1)) { + value >>= 1; + i++; + } + return i; +} + +/** + * @brief Count bits set to 1 from most significant bit + * + * @param value Data to be counted + * + * @return number of bits set to 1 + * @return 0xFFFFFFFF if no bit was set to 1 + */ +static inline uint32_t get_first_set_bit_from_msb(uint32_t value) +{ + uint32_t i = 31; + if (!value) + return 0xFFFFFFFFUL; + while (value && !(value & 0x80000000)) { + value <<= 1; + value &= ~1; + i--; + } + return i; +} + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ +#endif /* _HPM_COMMON_H */ diff --git a/contrib/loaders/flash/hpmicro/hpm_romapi.h b/contrib/loaders/flash/hpmicro/hpm_romapi.h new file mode 100644 index 0000000000..62dbce1ee7 --- /dev/null +++ b/contrib/loaders/flash/hpmicro/hpm_romapi.h @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 2021-2023 HPMicro + */ + +#ifndef HPM_ROMAPI_H +#define HPM_ROMAPI_H + +/** + * @brief ROM APIs + * @defgroup romapi_interface ROM APIs + * @{ + */ + +#include "hpm_common.h" +#include "hpm_romapi_xpi_def.h" +#include "hpm_romapi_xpi_soc_def.h" +#include "hpm_romapi_xpi_nor_def.h" + + +/*********************************************************************************************************************** + * + * + * Definitions + * + * + **********************************************************************************************************************/ + +/** + * @brief Bootloader API table + */ +typedef struct { + /**< Bootloader API table: version */ + const uint32_t version; + /**< Bootloader API table: copyright string address */ + const char *copyright; + /**< Bootloader API table: run_bootloader API */ + const uint32_t reserved0; + /**< Bootloader API table: otp driver interface address */ + const uint32_t reserved1; + /**< Bootloader API table: xpi driver interface address */ + const xpi_driver_interface_t *xpi_driver_if; + /**< Bootloader API table: xpi nor driver interface address */ + const xpi_nor_driver_interface_t *xpi_nor_driver_if; + /**< Bootloader API table: xpi ram driver interface address */ + const uint32_t reserved2; +} bootloader_api_table_t; + +/**< Bootloader API table Root */ +#define ROM_API_TABLE_ROOT ((const bootloader_api_table_t *)0x2001FF00U) + + + +#endif /* HPM_ROMAPI_H */ diff --git a/contrib/loaders/flash/hpmicro/hpm_romapi_xpi_def.h b/contrib/loaders/flash/hpmicro/hpm_romapi_xpi_def.h new file mode 100644 index 0000000000..7a3d8150fd --- /dev/null +++ b/contrib/loaders/flash/hpmicro/hpm_romapi_xpi_def.h @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2021 HPMicro + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ +#ifndef HPM_ROMAPI_XPI_DEF_H +#define HPM_ROMAPI_XPI_DEF_H + +/** + * @brief XPI ROM APIs + * @defgroup xpi_interface XPI driver APIs + * @{ + */ + +#include "hpm_common.h" + +/** + * @brief XPI_Type definitions for + * @note For compatibility + */ +typedef uint32_t XPI_Type; + +/** + * @brief XPI Read Sample Clock source options + */ +typedef enum { + xpi_rxclksrc_internal_loopback = 0, /**< Internal loopback */ + xpi_rxclksrc_dqs_loopback = 1, /**< Loopback from DQS pad */ + xpi_rxclksrc_external_dqs = 3, /**< Read is driven by External DQS pad */ +} xpi_rxclksrc_type_t; + + +/** + * @brief XPI pad definitions + */ +#define XPI_1PAD (0U) /**< Single pad */ +#define XPI_2PADS (1U) /**< Dual pads */ +#define XPI_4PADS (2U) /**< Quad pads */ +#define XPI_8PADS (3U) /**< Octal pads */ + +/** + * @brief XPI IO pin group options + */ +typedef enum { + xpi_io_1st_group, /**< First/Primary group */ + xpi_io_2nd_group, /**< Second/Secondary group */ +} xpi_io_group_t; + +/** + * @brief XPI Transfer Channel type definitions + */ +typedef enum { + xpi_xfer_channel_a1, /**< The address is based on the device connected to Channel A1 */ + xpi_xfer_channel_a2, /**< The address is based on the device connected to Channel A2 */ + xpi_xfer_channel_b1, /**< The address is based on the device connected to Channel B1 */ + xpi_xfer_channel_b2, /**< The address is based on the device connected to Channel B2 */ + xpi_xfer_channel_auto, /**< The channel is auto determined */ +} xpi_xfer_channel_t; + +/** + * @brief XPI Channel definitions + */ +typedef enum { + xpi_channel_a1, /**< Port: Channel A1 */ + xpi_channel_a2, /**< Port: Channel A2 */ + xpi_channel_b1, /**< Port: Channel B1 */ + xpi_channel_b2, /**< Port: Channel B2 */ +} xpi_channel_t; + +/** + * @brief XPI APB Transfer type + */ +typedef enum { + xpi_apb_xfer_type_cmd, /**< APB Command Type: Command only */ + xpi_apb_xfer_type_config, /**< APB Command Type: Configuration */ + xpi_apb_xfer_type_read, /**< APB Command Type: Read */ + xpi_apb_xfer_type_write, /**< APB Command Type: Write */ +} xpi_apb_xfer_type_t; + +/** + * @brief XPI Xfer Mode + */ +typedef enum { + xpi_xfer_mode_polling, /**< Transfer mode: Polling */ + xpi_xfer_mode_dma, /**< Transfer mode: DMA */ + xpi_xfer_mode_interrupt, /**< Transfer mode: Interrupt */ +} xpi_xfer_mode_t; + +/** + * @brief XPI Xfer context + */ +typedef struct { + uint32_t addr; /**< device address for XPI transfer */ + uint8_t channel; /**< channel for XPI transfer */ + uint8_t cmd_type; /**< command type for XPI transfer */ + uint8_t seq_idx; /**< Sequence index for XPI transfer */ + uint8_t seq_num; /**< Sequence number for XPI transfer */ + uint32_t *buf; /**< Buffer for XPI transfer */ + uint32_t xfer_size; /**< Transfer size in bytes */ +} xpi_xfer_ctx_t; + +/** + * @brief XPI instruction sequence + */ +typedef struct { + uint32_t entry[4]; +} xpi_instr_seq_t; + +/** + * @brief XPI Phase definitions + */ +#define XPI_PHASE_STOP (0x00U) /**< Phase: Stop */ +#define XPI_PHASE_CMD_SDR (0x01U) /**< Phase: Send CMD in SDR mode */ +#define XPI_PHASE_RADDR_SDR (0x02U) /**< Phase: Send Row Address in SDR Mode */ +#define XPI_PHASE_CADDR_SDR (0x03U) /**< Phase: Send Column Address in SDR Mode */ +#define XPI_PHASE_MODE4_SDR (0x06U) /**< Phase: Send Mode 4 in SDR Mode */ +#define XPI_PHASE_MODE8_SDR (0x07U) /**< Phase: Send Mode 8 in SDR Mode */ +#define XPI_PHASE_WRITE_SDR (0x08U) /**< Phase: Write data in SDR Mode */ +#define XPI_PHASE_READ_SDR (0x09U) /**< Phase: Read data in SDR Mode */ +#define XPI_PHASE_DUMMY_SDR (0X0CU) /**< Phase: Send Dummy in SDR Mode */ +#define XPI_PHASE_DUMMY_RWDS_SDR (0x0DU) /**< Phase: Send Dummy RWDS in SDR Mode */ + +#define XPI_PHASE_CMD_DDR (0x21U) /**< Phase: Send CMD in DDR Mode */ +#define XPI_PHASE_RADDR_DDR (0x22U) /**< Phase: Send Raw Address in DDR Mode */ +#define XPI_PHASE_CADDR_DDR (0x23U) /**< Phase: Send Column address in DDR Mode */ +#define XPI_PHASE_MODE4_DDR (0x26U) /**< Phase: Send Mode 4 in DDR Mode */ +#define XPI_PHASE_MODE8_DDR (0x27U) /**< Phase: Send Mode 8 in DDR Mode */ +#define XPI_PHASE_WRITE_DDR (0x28U) /**< Phase: Write data in DDR Mode */ +#define XPI_PHASE_READ_DDR (0x29U) /**< Phase: Read data in SDR Mode */ +#define XPI_PHASE_DUMMY_DDR (0x2CU) /**< Phase: Send DUMMY in DDR Mode */ +#define XPI_PHASE_DUMMY_RWDS_DDR (0x2DU) /**< Phase: Send DUMMY RWDS in DDR Mode */ + +/** + * @brief XPI API command error codes + */ +enum { + status_xpi_apb_jump_on_cs = MAKE_STATUS(status_group_xpi, 1), + status_xpi_apb_unknown_inst = MAKE_STATUS(status_group_xpi, 2), + status_xpi_apb_dummy_sdr_in_ddr_seq = MAKE_STATUS(status_group_xpi, 3), + status_xpi_apb_dummy_ddr_in_sdr_seq = MAKE_STATUS(status_group_xpi, 4), + status_xpi_apb_exceed_addr_range = MAKE_STATUS(status_group_xpi, 5), + status_xpi_apb_seq_timeout = MAKE_STATUS(status_group_xpi, 6), + status_xpi_apb_cross_boundary = MAKE_STATUS(status_group_xpi, 7), +}; + +/** + * @brief Delay line definitions + */ +enum { + xpi_dll_half_cycle = 0xFU, + xpi_dll_quarter_cycle = 0x7U, + xpi_dll_sdr_default_cycle = xpi_dll_half_cycle, + xpi_dll_ddr_default_cycle = xpi_dll_quarter_cycle, +}; + +/** + * @brief XPI configuration structure + */ +typedef struct { + uint8_t rxclk_src; /**< Read sample clock source */ + uint8_t reserved0[7]; /**< Reserved */ + uint8_t tx_watermark_in_dwords; /**< Tx watermark in double words */ + uint8_t rx_watermark_in_dwords; /**< Rx watermark in double words */ + uint8_t enable_differential_clk; /**< Enable differential clock */ + uint8_t reserved1[5]; /**< Reserved */ + uint32_t access_flags; /**< Access flags */ +} xpi_config_t; + +/** + * @brief XPI Device Configuration structure + */ +typedef struct { + uint32_t size_in_kbytes; /**< Device size in kbytes */ + uint32_t serial_root_clk_freq; /**< XPI serial root clock frequency */ + + uint8_t enable_write_mask; /**< Enable write mask, typically for PSRAM/HyperRAM */ + uint8_t data_valid_time; /**< Data valid time, Unit 0.1ns */ + uint8_t reserved0[2]; + + uint8_t cs_hold_time; /**< CS hold time, cycles in terms of FLASH clock */ + uint8_t cs_setup_time; /**< CS setup time, cycles in terms of FLASH clock */ + uint16_t cs_interval; /**< CS interval, cycles in terms of FLASH clock */ + + uint8_t reserved1; + uint8_t column_addr_size; /**< Column address bits */ + uint8_t enable_word_address; /**< Enable word address, for HyperFLASH/HyperRAM */ + uint8_t dly_target; /**< Delay target */ + + uint8_t ahb_write_seq_idx; /**< AHB write sequence index */ + uint8_t ahb_write_seq_num; /**< AHB write sequence number */ + uint8_t ahb_read_seq_idx; /**< AHB read sequence index */ + uint8_t ahb_read_seq_num; /**< AHB read sequence number */ + + uint8_t ahb_write_wait_interval; /**< AHB write wait interval, in terms of FLASH clock */ + uint8_t reserved2[3]; +} xpi_device_config_t; + +/** + * @brief SUB Instruction + * @param [in] phase Phase + * @param [in] pad Pad for Phase + * @param [in] op Operand for Phase + */ +#define SUB_INSTR(phase, pad, op) ((uint32_t)(((uint16_t)(phase) << 10) | ((uint16_t)(pad) << 8) | ((uint16_t)(op)))) +/** + * @brief Generate a single word INSTRUCTION sequence word + * @note Here intentionally use the MACRO because when the arguments are constant value, the compiler + * can generate the const entry word during pre-processing + */ +#define XPI_INSTR_SEQ(phase0, pad0, op0, phase1, pad1, op1) (SUB_INSTR(phase0, pad0, op0) | (SUB_INSTR(phase1, pad1, op1)<<16)) + +typedef struct { + struct { + uint8_t priority; /* Offset: 0x00 */ + uint8_t master_idx; /* Offset: 0x01 */ + uint8_t buf_size_in_dword; /* Offset: 0x02 */ + bool enable_prefetch; /* Offset: 0x03 */ + } entry[8]; +} xpi_ahb_buffer_cfg_t; + +/** + * @brief XPI driver interface + */ +typedef struct { + /**< XPI driver interface: version */ + uint32_t version; + /**< XPI driver interface: get default configuration */ + hpm_stat_t (*get_default_config)(xpi_config_t *xpi_config); + /**< XPI driver interface: get default device configuration */ + hpm_stat_t (*get_default_device_config)(xpi_device_config_t *dev_config); + /**< XPI driver interface: initialize the XPI using xpi_config */ + hpm_stat_t (*init)(XPI_Type *base, xpi_config_t *xpi_config); + /**< XPI driver interface: configure the AHB buffer */ + hpm_stat_t (*config_ahb_buffer)(XPI_Type *base, xpi_ahb_buffer_cfg_t *ahb_buf_cfg); + /**< XPI driver interface: configure the device */ + hpm_stat_t (*config_device)(XPI_Type *base, xpi_device_config_t *dev_cfg, xpi_channel_t channel); + /**< XPI driver interface: update instruction talbe */ + hpm_stat_t (*update_instr_table)(XPI_Type *base, const uint32_t *inst_base, uint32_t seq_idx, uint32_t num); + /**< XPI driver interface: transfer command/data using block interface */ + hpm_stat_t (*transfer_blocking)(XPI_Type *base, xpi_xfer_ctx_t *xfer); + /**< Software reset the XPI controller */ + void (*software_reset)(XPI_Type *base); + /**< XPI driver interface: Check whether IP is idle */ + bool (*is_idle)(XPI_Type *base); + /**< XPI driver interface: update delay line setting */ + void (*update_dllcr)(XPI_Type *base, + uint32_t serial_root_clk_freq, + uint32_t data_valid_time, + xpi_channel_t channel, + uint32_t dly_target); + /**< XPI driver interface: Get absolute address for APB transfer */ + hpm_stat_t + (*get_abs_apb_xfer_addr)(XPI_Type *base, xpi_xfer_channel_t channel, uint32_t in_addr, uint32_t *out_addr); +} xpi_driver_interface_t; + +/** + * @} + */ + +#endif /* HPM_ROMAPI_XPI_DEF_H */ diff --git a/contrib/loaders/flash/hpmicro/hpm_romapi_xpi_nor_def.h b/contrib/loaders/flash/hpmicro/hpm_romapi_xpi_nor_def.h new file mode 100644 index 0000000000..7ef634574b --- /dev/null +++ b/contrib/loaders/flash/hpmicro/hpm_romapi_xpi_nor_def.h @@ -0,0 +1,417 @@ +/* + * Copyright (c) 2021 HPMicro + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ +#ifndef HPM_ROMAPI_XPI_NOR_DEF_H +#define HPM_ROMAPI_XPI_NOR_DEF_H + +/** + * @brief XPI NOR ROM APIs + * @defgroup xpi_nor_interface XPI NOR driver APIs + * @ingroup romapi_interfaces + * @{ + */ + + +#include "hpm_common.h" +#include "hpm_romapi_xpi_def.h" + +#define XPI_NOR_CFG_TAG 0x524f4E58U /**< ASCII: "XNOR" */ + +/** + * @brief XPI NOR properties + */ +enum { + xpi_nor_property_total_size, /**< Total size in bytes */ + xpi_nor_property_page_size, /**< Page size in bytes */ + xpi_nor_property_sector_size, /**<sector size in bytes */ + xpi_nor_property_block_size, /**< block size in bytes */ + xpi_nor_property_max = xpi_nor_property_block_size, +}; + + +/** + * @brief XPI NOR safe frequency option + */ +enum { + xpi_nor_clk_safe_clk_freq = 1, +}; + +/** + * @brief XPI NOR miscellaneous options + */ +enum { + xpi_nor_option_misc_spi_only = 1, /**< SPI only */ + xpi_nor_option_misc_internal_loopback = 2, /**< Internal loopback mode */ + xpi_nor_option_misc_ext_dqs = 3, /**< External DQS pin */ +}; + +/** + * @brief XPI NOR connection option + */ +enum { + xpi_nor_connection_sel_chna_cs0, /**< Channel A, CS0 */ + xpi_nor_connection_sel_chnb_cs0, /**< Channel B, CS0 */ + xpi_nor_connection_sel_chna_cs0_chnb_cs0, /**< Channel A + Channel B, CS0 */ + xpi_nor_connection_sel_chna_cs0_cs1, /**< Channel A, CS0 + CS1 */ + xpi_nor_connection_sel_chnb_cs0_cs1 /**< Channel B, CS0 + CS1 */ +}; + +/** + * @brief QE bit enable sequence option + */ +typedef enum { + xpi_nor_quad_en_auto_or_ignore = 0U, /**< Auto enable or ignore */ + xpi_nor_quad_en_set_bit6_in_status_reg1 = 1U, /**< QE bit is at bit6 in Status register 1 */ + xpi_nor_quad_en_set_bit1_in_status_reg2 = 2U, /**< QE bit is at bit1 in Status register 2 register 2 */ + xpi_nor_quad_en_set_bit7_in_status_reg2 = 3U, /**< QE bit is at bit7 in Status register 2 */ + xpi_nor_quad_en_set_bi1_in_status_reg2_via_0x31_cmd = 4U, /**< QE bit is in status register 2 and configured by CMD 0x31 */ +} xpi_nor_quad_enable_seq_t; + +/** + * @brief XPI working mode + */ +typedef enum { + xpi_working_mode_extend_spi, /**< XPI works in extended SPI mode, including 1-1-1, 1-2-2, 1-4-4, 1-8-8 */ + xpi_working_mode_xpi, /**< XPI works in XPI mode, including, 1-1-1, 2-2-2, 4-4-4, 8-8-8 */ + xpi_working_mode_hyperbus, /**< XPI works in HyperBus mode */ +} xpi_working_mode_t; + + +/** + * @brief XPI NOR configuration command type + */ +typedef enum { + xpi_nor_cfg_cmd_type_no_cfg = 0U, /**< No configuration */ + xpi_nor_cfg_cmd_type_generic = 1U, /**< Generic configuration */ + xpi_nor_cfg_cmd_type_spi2xpi = 2U, /**< SPI to XPI mode */ + xpi_nor_cfg_cmd_type_xpi2spi = 3U, /**< XPI to SPI mode */ +} xpi_nor_cfg_cmd_type_t; + +/** + * @brief XPI NOR probe options + */ +typedef enum { + xpi_nor_probe_sfdp_sdr = 0U, /**< Probe FLASH using SFDP and set FLASH to SDR mode */ + xpi_nor_probe_sfdp_ddr = 1U, /**< Probe FLASH using SDP and set FLASH to DDR mode */ + xpi_nor_quad_read_0xeb = 2U, /**< Set FLASH to default Quad I/O read in SDR mode */ + xpi_nor_dual_read_0xbb = 3U, /**< Set FLASH to default Dual I/O read in SDR mode */ + xpi_nor_hyperbus_1v8 = 4U, /**< Probe FLASH using HyperBus in 1.8V voltage */ + xpi_nor_hyperbus_3v0 = 5U, /**< Probe FLASH using HyperBus in 3.0V voltage */ + xpi_nor_octabus_ddr = 6U, /**< Probe FLASH using Macronix OctaBus and configure FLASH to OPI DDR mode */ + xpi_nor_octabus_sdr = 7U, /**< Probe FLASH using Macronix OctaBus and configure FLASH to OPI SDR mode */ + xpi_nor_xccela_ddr = 8U, /**< Probe FLASH using Xccela Protocol and configure FLASH to OPI DDR mode */ + xpi_nor_xccela_sdr = 9U, /**< Probe FLASH using Xccela Protocol and configure FLASH to SDR mode */ + xpi_nor_ecoxip_ddr = 10U, /**< Probe FLASH using EcoXiP Protocol and configure FLASH to OPI DDR mode */ + xpi_nor_ecoxip_sdr = 11U, /**< Probe FLASH using EcoXiP Protocol and configure FLASH to SDR mode */ +} xpi_nor_probe_t; + +/** + * @brief Standard XPI NOR seuqnce index definitions + */ +typedef enum { + xpi_std_nor_seq_idx_read = 0U, /**< 0 - Read */ + xpi_std_nor_seq_idx_page_program = 1U, /**< 1 - Page Program */ + xpi_std_nor_seq_idx_read_status = 2U, /**< 2 - Read Status */ + xpi_std_nor_seq_idx_read_status_xpi = 3U, /**< 3 - Read Status in xSPI mode */ + xpi_std_nor_seq_idx_write_enable = 4U, /**< 4 - Write Enable */ + xpi_std_nor_seq_idx_write_enable_xpi = 5U, /**< 5 - Write Enable in xSPI mode */ + xpi_std_nor_seq_idx_erase_sector = 6U, /**< 6 - Erase sector */ + xpi_std_nor_seq_idx_erase_block = 7U, /**< 7 - Erase block */ + xpi_std_nor_seq_idx_erase_chip = 8U, /**< 8 - Erase full chip */ + xpi_std_nor_seq_idx_max = 9, /**< 9 */ +} xpi_std_nor_instr_idx_t; + +/** + * @brief XPI NOR option tag + */ +#define XPI_NOR_CFG_OPTION_TAG (0xfcf90U) + +/** + * @brief XPI NOR configuration option + * The ROM SW can detect the FLASH configuration based on the following structure specified by the end-user + */ +typedef struct { + union { + struct { + uint32_t words: 4; /**< Option words, exclude the header itself */ + uint32_t reserved: 8; /**< Reserved for future use */ + uint32_t tag: 20; /**< Must be 0xfcf90 */ + }; + uint32_t U; + } header; + union { + struct { + uint32_t freq_opt: 4; /**< 1 - 30MHz, others, SoC specific setting */ + uint32_t misc: 4; /**< Not used for now */ + uint32_t dummy_cycles: 8; /**< 0 - Auto detected/ use predefined value, others - specified by end-user */ + uint32_t quad_enable_seq: 4; /**< See the xpi_nor_quad_enable_seq_t definitions for more details */ + uint32_t cmd_pads_after_init: 4; /**< See the xpi_data_pad_t definitions for more details */ + uint32_t cmd_pads_after_por: 4; /**< See the xpi_data_pad_t definitions for more details */ + uint32_t probe_type: 4; /**< See the xpi_nor_probe_t definitions for more details */ + }; + uint32_t U; + } option0; + union { + struct { + uint32_t drive_strength: 8; /**< IO drive strength, 0 - pre-defined, Others - specified by end-user */ + uint32_t connection_sel: 4; /**< Device connection selection: 0 - PORTA, 1 - PORTB, 2 - Parallel mode */ + uint32_t pin_group_sel: 4; /**< Pin group selection, 0 - 1st group, 1 - 2nd group, by default, the pin group is 1st group */ + uint32_t io_voltage: 4; /**< SoC pad voltage, 0 - 3.0V, 1-1.8V */ + uint32_t reserved: 12; /**< Reserved for future use */ + }; + uint32_t U; + } option1; + union { + struct { + uint32_t flash_size_option:8; /**< FLASH size option */ + uint32_t flash_sector_size_option:4; /**< FLASH sector size option */ + uint32_t flash_sector_erase_cmd_option:4; /**< Sector Erase command option */ + uint32_t reserved:20; + }; + uint32_t U; + } option2; +} xpi_nor_config_option_t; + +/** + * @brief Sector size options + */ +enum { + serial_nor_sector_size_4kb, /**< Sector size: 4KB */ + serial_nor_sector_size_32kb, /**< Sector size: 32KB */ + serial_nor_sector_size_64kb, /**< Sector size: 64KB */ + serial_nor_sector_size_256kb, /**< Sector size: 256KB */ +}; + +/** + * @brief Sector erase command options + */ +enum { + serial_nor_erase_type_4kb, /**< Sector erase command: 4KB Erase */ + serial_nor_erase_type_32kb, /**< Sector erase command: 32KB Erase */ + serial_nor_erase_type_64kb, /**< Sector erase command: 64KB Erase */ + serial_nor_erase_type_256kb, /**< Sector erase command: 256KB Erase */ +}; + +/** + * @brief FLASH size options + */ +enum { + flash_size_4mb, /**< FLASH size: 4MB */ + flash_size_8mb, /**< FLASH size: 8MB */ + flash_size_16mb, /**< FLASH size: 16MB */ +}; + +/** + * @brief Device Mode configuration structure + */ +typedef struct { + uint8_t cfg_cmd_type; /**< Configuration command type */ + uint8_t param_size; /**< Size for parameter */ +} device_mode_cfg_t; + +/** + * @brief Device mode parameter structure + */ +typedef struct { + uint32_t instr_seq[4]; /**< Command Instruction sequence*/ + uint32_t param; /**< Parameter */ +} device_mode_param_t; + +/** + * @brief XPI NOR device information structure + */ +typedef struct { + uint32_t size_in_kbytes; /**< Device Size in Kilobytes, offset 0x00 */ + uint16_t page_size; /**< Page size, offset 0x04 */ + uint16_t sector_size_kbytes; /**< Sector size in kilobytes, offset 0x06 */ + uint16_t block_size_kbytes; /**< Block size in kilobytes, offset 0x08 */ + uint8_t busy_offset; /**< Busy offset, offset 0x0a */ + uint8_t busy_polarity; /**< Busy polarity, offset 0x0b */ + uint8_t data_pads; /**< Device Size in Kilobytes, offset 0x0c */ + uint8_t en_ddr_mode; /**< Enable DDR mode, offset 0x0d */ + uint8_t clk_freq_for_device_cfg; /**< Clk frequency for device configuration offset 0x0e */ + uint8_t working_mode_por; /**< Working mode after POR reset offset 0x0f */ + uint8_t working_mode; /**< The device working mode, offset 0x10 */ + uint8_t en_diff_clk; /**< Enable Differential clock, offset 0x11 */ + uint8_t data_valid_time; /**< Data valid time, in 0.1ns, offset 0x12 */ + uint8_t en_half_clk_for_non_read_cmd; /**< Enable half clock for non-read command, offset 0x13 */ + uint8_t clk_freq_for_non_read_cmd; /**< Enable safe clock for non-read command, offset 0x14 */ + uint8_t dll_dly_target; /**< XPI DLL Delay Target, offset 0x15 */ + uint8_t io_voltage; /**< IO voltage, offset 0x16 */ + uint8_t reserved0; /**< Reserved for future use, offset 0x17 */ + uint8_t cs_hold_time; /**< CS hold time, 0 - default value, others - user specified value, offset 0x18 */ + uint8_t cs_setup_time; /**< CS setup time, 0 - default value, others - user specified value, offset 0x19 */ + uint8_t cs_interval; /**< CS interval, intervals between to CS active, offset 0x1a */ + uint8_t en_dev_mode_cfg; /**< Enable device mode configuration, offset 0x1b */ + uint32_t flash_state_ctx; /**< Flash state context, offset 0x1c */ + device_mode_cfg_t mode_cfg_list[2]; /**< Mode configuration sequences, offset 0x20 */ + uint32_t mode_cfg_param[2]; /**< Mode configuration parameters, offset 0x24 */ + uint32_t reserved1; /**< Reserved for future use, offset 0x2C */ + struct { + uint32_t entry[4]; + } cfg_instr_seq[2]; /**< Mode Configuration Instruction sequence, offset 0x30 */ +} xpi_device_info_t; + +/** + * @brief XPI NOR configuration structure + */ +typedef struct { + uint32_t tag; /**< Must be "XNOR", offset 0x000 */ + uint32_t reserved0; /**< Reserved for future use, offset 0x004 */ + uint8_t rxclk_src; /**< RXCLKSRC value, offset 0x008 */ + uint8_t clk_freq; /**< Clock frequency, offset 0x009 */ + uint8_t drive_strength; /**< Drive strength, offset 0x0a */ + uint8_t column_addr_size; /**< Column address size, offset 0x0b */ + uint8_t rxclk_src_for_init; /**< RXCLKSRC during FLASH initialization, offset 0x0c */ + uint8_t config_in_progress; /**< Indicate whether device configuration is in progress, offset: 0x0d */ + uint8_t reserved[2]; /**< Reserved for future use, offset 0x00f */ + struct { + uint8_t enable; /**< Port enable flag, 0 - not enabled, 1 - enabled */ + uint8_t group; /**< 0 - 1st IO group, 1 - 2nd IO group */ + uint8_t reserved[2]; + } chn_info[4]; /**< Device connection information */ + xpi_device_info_t device_info; /**< Device info, offset 0x20 */ + xpi_instr_seq_t instr_set[xpi_std_nor_seq_idx_max];/**< Standard instruction sequence table, offset 0x70 */ +} xpi_nor_config_t; + +/** + * @brief FLASH runtime context structure + */ +typedef union { + struct { + uint32_t wait_time: 7; /**< Wait time */ + uint32_t wait_time_unit: 1; /**< 0 - 10us, 1 - 1ms */ + uint32_t reset_gpio: 8; /**<Reset GPIO */ + uint32_t restore_sequence: 4; /**<Restore sequence */ + uint32_t exit_no_cmd_sequence: 4; /**< Exit no-cmd sequence */ + uint32_t current_mode: 4; /**< Current FLASH mode */ + uint32_t por_mode: 4; /**< FLASH mode upon Power-on Reset */ + }; + uint32_t U; +} flash_run_context_t; + +/** + * @brief XPI NOR API error codes + */ +enum { + status_xpi_nor_sfdp_not_found = MAKE_STATUS(status_group_xpi_nor, 0), /**< SFDP table was not found */ + status_xpi_nor_ddr_read_dummy_cycle_probe_failed = MAKE_STATUS(status_group_xpi_nor, 1), /**< Probing Dummy cyles for DDR read failed */ + status_xpi_nor_flash_not_found = MAKE_STATUS(status_group_xpi_nor, 2), /**< FLASH was not detected */ +}; + +/** + * @brief XPI NOR driver interface + */ +typedef struct { + /**< XPI NOR driver interface: API version */ + uint32_t version; + /**< XPI NOR driver interface: Get FLASH configuration */ + hpm_stat_t (*get_config)(XPI_Type *base, xpi_nor_config_t *nor_cfg, xpi_nor_config_option_t *cfg_option); + /**< XPI NOR driver interface: initialize FLASH */ + hpm_stat_t (*init)(XPI_Type *base, xpi_nor_config_t *nor_config); + /**< XPI NOR driver interface: Enable write access to FLASH */ + hpm_stat_t + (*enable_write)(XPI_Type *base, xpi_xfer_channel_t channel, const xpi_nor_config_t *nor_config, uint32_t addr); + /**< XPI NOR driver interface: Get FLASH status register */ + hpm_stat_t (*get_status)(XPI_Type *base, + xpi_xfer_channel_t channel, + const xpi_nor_config_t *nor_config, + uint32_t addr, + uint16_t *out_status); + /**< XPI NOR driver interface: Wait when FLASH is still busy */ + hpm_stat_t + (*wait_busy)(XPI_Type *base, xpi_xfer_channel_t channel, const xpi_nor_config_t *nor_config, uint32_t addr); + /**< XPI NOR driver interface: erase a specified FLASH region */ + hpm_stat_t (*erase)(XPI_Type *base, + xpi_xfer_channel_t channel, + const xpi_nor_config_t *nor_config, + uint32_t start, + uint32_t length); + /**< XPI NOR driver interface: Erase the whole FLASH */ + hpm_stat_t (*erase_chip)(XPI_Type *base, xpi_xfer_channel_t channel, const xpi_nor_config_t *nor_config); + /**< XPI NOR driver interface: Erase specified FLASH sector */ + hpm_stat_t + (*erase_sector)(XPI_Type *base, xpi_xfer_channel_t channel, const xpi_nor_config_t *nor_config, uint32_t addr); + /**< XPI NOR driver interface: Erase specified FLASH block */ + hpm_stat_t + (*erase_block)(XPI_Type *base, xpi_xfer_channel_t channel, const xpi_nor_config_t *nor_config, uint32_t addr); + /**< XPI NOR driver interface: Program data to specified FLASH address */ + hpm_stat_t (*program)(XPI_Type *base, + xpi_xfer_channel_t channel, + const xpi_nor_config_t *nor_config, + const uint32_t *src, + uint32_t dst_addr, + uint32_t length); + /**< XPI NOR driver interface: read data from specified FLASH address */ + hpm_stat_t (*read)(XPI_Type *base, + xpi_xfer_channel_t channel, + const xpi_nor_config_t *nor_config, + uint32_t *dst, + uint32_t start, + uint32_t length); + /**< XPI NOR driver interface: program FLASH page using nonblocking interface */ + hpm_stat_t (*page_program_nonblocking)(XPI_Type *base, + xpi_xfer_channel_t channel, + const xpi_nor_config_t *nor_config, + const uint32_t *src, + uint32_t dst_addr, + uint32_t length); + /**< XPI NOR driver interface: erase FLASH sector using nonblocking interface */ + hpm_stat_t (*erase_sector_nonblocking)(XPI_Type *base, + xpi_xfer_channel_t channel, + const xpi_nor_config_t *nor_config, + uint32_t addr); + /**< XPI NOR driver interface: erase FLASH block using nonblocking interface */ + hpm_stat_t (*erase_block_nonblocking)(XPI_Type *base, + xpi_xfer_channel_t channel, + const xpi_nor_config_t *nor_config, + uint32_t addr); + /**< XPI NOR driver interface: erase the whole FLASh using nonblocking interface */ + hpm_stat_t (*erase_chip_nonblocking)(XPI_Type *base, + xpi_xfer_channel_t channel, + const xpi_nor_config_t *nor_config); + + uint32_t reserved0[3]; + + /**< XPI NOR driver interface: automatically configuration flash based on the cfg_option setting */ + hpm_stat_t (*auto_config)(XPI_Type *base, xpi_nor_config_t *nor_cfg, xpi_nor_config_option_t *cfg_option); + + /**< XPI NOR driver interface: Get FLASH properties */ + hpm_stat_t (*get_property)(XPI_Type *base, xpi_nor_config_t *nor_cfg, uint32_t property_id, uint32_t *value); + + uint32_t reserved1; + + /**< Post Erase Sector Nonblocking operation: For Hybrid mode only */ + hpm_stat_t (*post_erase_sector_nonblocking)(XPI_Type *base, xpi_xfer_channel_t chn, xpi_nor_config_t *nor_cfg, uint32_t addr); + + /**< Post Erase Block Nonblocking operation: For Hybrid mode only */ + hpm_stat_t (*post_erase_block_nonblocking)(XPI_Type *base, xpi_xfer_channel_t chn, xpi_nor_config_t *nor_cfg, uint32_t addr); + + /**< Post Erase Chip Nonblocking operation: For Hybrid mode only */ + hpm_stat_t (*post_erase_chip_nonblocking)(XPI_Type *base, xpi_xfer_channel_t chn, xpi_nor_config_t *nor_cfg); + + /**< Post Page Program Nonblocking operation: For Hybrid mode only */ + hpm_stat_t (*post_page_program_nonblocking)(XPI_Type *base, xpi_xfer_channel_t chn, xpi_nor_config_t *nor_config, + const uint32_t *src, uint32_t dst_addr, uint32_t length); + /**< Turn on the power for Internal FLASH */ + void (*sip_flash_power_on)(XPI_Type *base); + + /**< Turn off the power for Internal FLASH */ + void (*sip_flash_power_off)(XPI_Type *base); + + /**< Enable Hybrid mode */ + void (*enable_hybrid_xpi)(XPI_Type *base); + + /**< Disable Hybrid mode */ + void (*disable_hybrid_xpi)(XPI_Type *base); + +} xpi_nor_driver_interface_t; + +/** + * @} + */ + +#endif /* HPM_ROMAPI_XPI_NOR_DEF_H */ \ No newline at end of file diff --git a/contrib/loaders/flash/hpmicro/hpm_romapi_xpi_soc_def.h b/contrib/loaders/flash/hpmicro/hpm_romapi_xpi_soc_def.h new file mode 100644 index 0000000000..690ab42229 --- /dev/null +++ b/contrib/loaders/flash/hpmicro/hpm_romapi_xpi_soc_def.h @@ -0,0 +1,70 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 2021 HPMicro + */ + +#ifndef HPM_ROMAPI_XPI_SOC_DEF_H +#define HPM_ROMAPI_XPI_SOC_DEF_H + +#include "hpm_common.h" +#include "hpm_romapi_xpi_def.h" + +/*********************************************************************************************************************** + * Definitions + **********************************************************************************************************************/ + +#define XPI_CLK_OUT_FREQ_OPTION_30MHz (1U) +#define XPI_CLK_OUT_FREQ_OPTION_50MHz (2U) +#define XPI_CLK_OUT_FREQ_OPTION_66MHz (3U) +#define XPI_CLK_OUT_FREQ_OPTION_80MHz (4U) +#define XPI_CLK_OUT_FREQ_OPTION_104MHz (5U) +#define XPI_CLK_OUT_FREQ_OPTION_120MHz (6U) +#define XPI_CLK_OUT_FREQ_OPTION_133MHz (7U) +#define XPI_CLK_OUT_FREQ_OPTION_166MHz (8U) +#define XPI_CLK_OUT_FREQ_OPTION_200MHz (9U) + + +typedef struct { + uint8_t data_pads; + xpi_channel_t channel; + xpi_io_group_t io_group; + uint8_t drive_strength; + bool enable_dqs; + bool enable_diff_clk; +} xpi_io_config_t; + +typedef enum { + xpi_freq_type_typical, + xpi_freq_type_mhz, +} clk_freq_type_t; + +typedef enum { + xpi_clk_src_auto, + xpi_clk_src_osc, + xpi_clk_src_pll0clk0, + xpi_clk_src_pll1clk0, + xpi_clk_src_pll1clk1, + xpi_clk_src_pll2clk0, + xpi_clk_src_pll2clk1, + xpi_clk_src_pll3clk0, + xpi_clk_src_pll4clk0, +} xpi_clk_src_t; + + +typedef union { + struct { + uint8_t freq; + bool enable_ddr; + xpi_clk_src_t clk_src; + clk_freq_type_t freq_type; + }; + uint32_t freq_opt; +} xpi_clk_config_t; + +typedef enum { + xpi_clock_bus, + xpi_clock_serial_root, + xpi_clock_serial, +} xpi_clock_t; + +#endif /* HPM_ROMAPI_XPI_SOC_DEF_H */ diff --git a/contrib/loaders/flash/hpmicro/hpm_xpi_flash.elf b/contrib/loaders/flash/hpmicro/hpm_xpi_flash.elf new file mode 100755 index 0000000000..777db69dfa Binary files /dev/null and b/contrib/loaders/flash/hpmicro/hpm_xpi_flash.elf differ diff --git a/contrib/loaders/flash/hpmicro/hpm_xpi_flash.h b/contrib/loaders/flash/hpmicro/hpm_xpi_flash.h new file mode 100644 index 0000000000..55f160b390 --- /dev/null +++ b/contrib/loaders/flash/hpmicro/hpm_xpi_flash.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 2021 hpmicro + */ + +#ifndef HPM_XPI_FLASH_H +#define HPM_XPI_FLASH_H + +#define FLASH_INIT (0) +#define FLASH_ERASE (0x6) +#define FLASH_PROGRAM (0xc) +#define FLASH_READ (0x12) +#define FLASH_GET_INFO (0x18) +#define FLASH_ERASE_CHIP (0x1e) + +uint8_t flash_algo[] = { +#include "hpm_xpi_flash.inc" +}; + +#endif diff --git a/contrib/loaders/flash/hpmicro/hpm_xpi_flash.inc b/contrib/loaders/flash/hpmicro/hpm_xpi_flash.inc new file mode 100644 index 0000000000..75cd228b11 --- /dev/null +++ b/contrib/loaders/flash/hpmicro/hpm_xpi_flash.inc @@ -0,0 +1,72 @@ +/* Autogenerated with ../../../../src/helper/bin2char.sh */ +0xef,0x00,0x20,0x05,0x02,0x90,0xef,0x00,0x00,0x12,0x02,0x90,0xef,0x00,0x80,0x1f, +0x02,0x90,0xef,0x00,0xa0,0x22,0x02,0x90,0xef,0x00,0xe0,0x25,0x02,0x90,0xef,0x00, +0x40,0x27,0x02,0x90,0xef,0x00,0x80,0x28,0x02,0x90,0x9c,0x41,0x05,0x47,0xbd,0x8b, +0x63,0x7b,0xf7,0x00,0x9c,0x45,0x05,0x67,0x13,0x07,0x07,0xf0,0xf9,0x8f,0x13,0x07, +0x00,0x10,0x63,0x83,0xe7,0x00,0x82,0x80,0x23,0x20,0x05,0x06,0x23,0x22,0x05,0x06, +0x82,0x80,0x39,0x71,0x22,0xdc,0x13,0x04,0x00,0x2b,0x83,0x47,0x44,0x00,0x06,0xde, +0x18,0xc0,0xd1,0xef,0x26,0xda,0xba,0x84,0x13,0x07,0x84,0x00,0x4e,0xd6,0x52,0xd4, +0xb2,0x89,0x2e,0x8a,0x13,0x06,0x00,0x10,0x81,0x45,0x3a,0x85,0x4a,0xd8,0x56,0xd2, +0x36,0x89,0xb7,0x0a,0x02,0x20,0x02,0xcc,0x02,0xce,0x0d,0x2e,0x83,0xa6,0x4a,0xf1, +0x93,0x57,0x79,0x00,0x89,0x8b,0xf4,0x46,0xaa,0x85,0x52,0xc6,0x4e,0xc8,0x4a,0xca, +0x23,0x24,0xf4,0x10,0x70,0x00,0x26,0x85,0x93,0x8a,0x0a,0xf0,0x82,0x96,0x29,0xed, +0x03,0xa7,0x4a,0x01,0xb7,0x07,0x01,0x56,0x93,0x87,0xf7,0x2f,0x14,0x43,0x63,0xf5, +0xd7,0x00,0x3c,0x5b,0x08,0x40,0x82,0x97,0xb2,0x47,0x05,0x47,0xbd,0x8b,0x63,0x7b, +0xf7,0x00,0xd2,0x47,0x05,0x67,0x13,0x07,0x07,0xf0,0xf9,0x8f,0x13,0x07,0x00,0x10, +0x63,0x8d,0xe7,0x02,0x83,0x47,0x44,0x00,0x23,0x0e,0x04,0x02,0x81,0xe7,0x85,0x47, +0x23,0x02,0xf4,0x00,0xd2,0x54,0x42,0x59,0xb2,0x59,0x22,0x5a,0x92,0x5a,0xf2,0x50, +0x62,0x54,0x01,0x45,0x21,0x61,0x82,0x80,0xf2,0x50,0x62,0x54,0xd2,0x54,0x42,0x59, +0xb2,0x59,0x22,0x5a,0x92,0x5a,0x21,0x61,0x82,0x80,0x1c,0x40,0x23,0xa0,0x07,0x06, +0x23,0xa2,0x07,0x06,0xc1,0xb7,0xb7,0x07,0x02,0x20,0x83,0xa6,0x47,0xf1,0x01,0x11, +0xb7,0x07,0x01,0x56,0x98,0x42,0x22,0xcc,0x4a,0xc8,0x06,0xce,0x26,0xca,0x4e,0xc6, +0x56,0xc2,0x93,0x87,0xf7,0x2f,0x2e,0x89,0x32,0x84,0x63,0xf4,0xe7,0x00,0x33,0x89, +0xa5,0x00,0x93,0x09,0x00,0x2b,0x83,0xd4,0x09,0x03,0xaa,0x04,0x63,0x69,0x94,0x06, +0xb3,0x7a,0x99,0x02,0x52,0xc4,0x33,0x8a,0x54,0x41,0x63,0x80,0x44,0x03,0x9c,0x4e, +0x83,0xa5,0x89,0x10,0x03,0xa5,0x09,0x00,0x52,0x87,0xca,0x86,0x13,0x86,0x89,0x00, +0x82,0x97,0x05,0xed,0x05,0x8c,0x56,0x94,0x52,0x99,0x63,0xf1,0x84,0x04,0x37,0x0a, +0x02,0x20,0x93,0x0a,0x80,0x2b,0x13,0x0a,0x0a,0xf0,0x21,0xa0,0x26,0x99,0x63,0xf1, +0x84,0x06,0x83,0x27,0x4a,0x01,0x83,0xa5,0x89,0x10,0x03,0xa5,0x09,0x00,0xdc,0x53, +0xca,0x86,0x56,0x86,0x82,0x97,0x05,0x8c,0x75,0xd1,0x22,0x4a,0xf2,0x40,0x62,0x44, +0xd2,0x44,0x42,0x49,0xb2,0x49,0x92,0x4a,0x05,0x61,0x82,0x80,0x22,0x4a,0x01,0x45, +0x75,0xd4,0x93,0x0a,0x80,0x2b,0xb7,0x07,0x02,0x20,0x93,0x87,0x07,0xf0,0xdc,0x4b, +0x22,0x87,0x62,0x44,0x83,0xa5,0x89,0x10,0x03,0xa5,0x09,0x00,0xf2,0x40,0xd2,0x44, +0xb2,0x49,0x9c,0x4f,0xca,0x86,0x56,0x86,0x42,0x49,0x92,0x4a,0x05,0x61,0x82,0x87, +0x22,0x4a,0xd1,0xbf,0xb7,0x07,0x02,0x20,0x83,0xa8,0x47,0xf1,0xb7,0x07,0x01,0x56, +0x13,0x88,0xf7,0x2f,0x03,0xa3,0x08,0x00,0x2e,0x87,0xb6,0x87,0x63,0x74,0x68,0x00, +0x33,0x87,0xa5,0x00,0x13,0x08,0x00,0x2b,0x83,0xa8,0x88,0x02,0x83,0x25,0x88,0x10, +0x03,0x25,0x08,0x00,0xb2,0x86,0x13,0x06,0x88,0x00,0x82,0x88,0xb7,0x07,0x02,0x20, +0x03,0xa3,0x47,0xf1,0xb7,0x07,0x01,0x56,0x13,0x88,0xf7,0x2f,0x03,0x2e,0x03,0x00, +0xae,0x88,0x32,0x87,0xb6,0x87,0x63,0x74,0xc8,0x01,0x33,0x07,0xa6,0x00,0x13,0x08, +0x00,0x2b,0x03,0x23,0xc3,0x02,0x83,0x25,0x88,0x10,0x03,0x25,0x08,0x00,0xc6,0x86, +0x13,0x06,0x88,0x00,0x02,0x83,0x81,0xcd,0x93,0x07,0x00,0x2b,0x98,0x57,0x83,0xd7, +0xe7,0x02,0x01,0x45,0x2a,0x07,0xaa,0x07,0x98,0xc1,0xdc,0xc1,0x82,0x80,0x09,0x45, +0x82,0x80,0xb7,0x07,0x02,0x20,0x93,0x87,0x07,0xf0,0xdc,0x4b,0x13,0x06,0x00,0x2b, +0x83,0x25,0x86,0x10,0x08,0x42,0xdc,0x4f,0x21,0x06,0x82,0x87,0x82,0x80,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3d,0x43,0x2a,0x87, +0x63,0x73,0xc3,0x02,0x93,0x77,0xf7,0x00,0xbd,0xef,0xad,0xe5,0x93,0x76,0x06,0xff, +0x3d,0x8a,0xba,0x96,0x0c,0xc3,0x4c,0xc3,0x0c,0xc7,0x4c,0xc7,0x41,0x07,0xe3,0x6b, +0xd7,0xfe,0x11,0xe2,0x82,0x80,0xb3,0x06,0xc3,0x40,0x8a,0x06,0x97,0x02,0x00,0x00, +0x96,0x96,0x67,0x80,0xa6,0x00,0x23,0x07,0xb7,0x00,0xa3,0x06,0xb7,0x00,0x23,0x06, +0xb7,0x00,0xa3,0x05,0xb7,0x00,0x23,0x05,0xb7,0x00,0xa3,0x04,0xb7,0x00,0x23,0x04, +0xb7,0x00,0xa3,0x03,0xb7,0x00,0x23,0x03,0xb7,0x00,0xa3,0x02,0xb7,0x00,0x23,0x02, +0xb7,0x00,0xa3,0x01,0xb7,0x00,0x23,0x01,0xb7,0x00,0xa3,0x00,0xb7,0x00,0x23,0x00, +0xb7,0x00,0x82,0x80,0x93,0xf5,0xf5,0x0f,0x93,0x96,0x85,0x00,0xd5,0x8d,0x93,0x96, +0x05,0x01,0xd5,0x8d,0x61,0xb7,0x93,0x96,0x27,0x00,0x97,0x02,0x00,0x00,0x96,0x96, +0x86,0x82,0xe7,0x80,0x86,0xfa,0x96,0x80,0xc1,0x17,0x1d,0x8f,0x3e,0x96,0xe3,0x74, +0xc3,0xf8,0xa5,0xb7, diff --git a/contrib/loaders/flash/hpmicro/hpm_xpi_flash.lst b/contrib/loaders/flash/hpmicro/hpm_xpi_flash.lst new file mode 100644 index 0000000000..9e8cb3c506 --- /dev/null +++ b/contrib/loaders/flash/hpmicro/hpm_xpi_flash.lst @@ -0,0 +1,351 @@ + +hpm_xpi_flash.elf: file format elf32-littleriscv + +Sections: +Idx Name Size VMA LMA File off Algn + 0 .text 00000464 00000000 00000000 00001000 2**2 + CONTENTS, ALLOC, LOAD, READONLY, CODE + 1 .riscv.attributes 0000005c 00000000 00000000 00001464 2**0 + CONTENTS, READONLY + 2 .comment 0000001b 00000000 00000000 000014c0 2**0 + CONTENTS, READONLY + +Disassembly of section .text: + +00000000 <_init>: + 0: 052000ef jal 52 <flash_init> + 4: 9002 ebreak + 6: 120000ef jal 126 <flash_erase> + a: 9002 ebreak + c: 1f8000ef jal 204 <flash_program> + 10: 9002 ebreak + 12: 22a000ef jal 23c <flash_read> + 16: 9002 ebreak + 18: 25e000ef jal 276 <flash_get_info> + 1c: 9002 ebreak + 1e: 274000ef jal 292 <flash_erase_chip> + 22: 9002 ebreak + 24: 288000ef jal 2ac <flash_deinit> + 28: 9002 ebreak + +0000002a <refresh_device_size>: + 2a: 419c lw a5,0(a1) + 2c: 4705 li a4,1 + 2e: 8bbd andi a5,a5,15 + 30: 00f77b63 bgeu a4,a5,46 <refresh_device_size+0x1c> + 34: 459c lw a5,8(a1) + 36: 6705 lui a4,0x1 + 38: f0070713 addi a4,a4,-256 # f00 <__bss_end__+0xa9c> + 3c: 8ff9 and a5,a5,a4 + 3e: 10000713 li a4,256 + 42: 00e78363 beq a5,a4,48 <refresh_device_size+0x1e> + 46: 8082 ret + 48: 06052023 sw zero,96(a0) + 4c: 06052223 sw zero,100(a0) + 50: 8082 ret + +00000052 <flash_init>: + 52: 7139 addi sp,sp,-64 + 54: dc22 sw s0,56(sp) + 56: 2b000413 li s0,688 + 5a: 00444783 lbu a5,4(s0) + 5e: de06 sw ra,60(sp) + 60: c018 sw a4,0(s0) + 62: efd1 bnez a5,fe <flash_init+0xac> + 64: da26 sw s1,52(sp) + 66: 84ba mv s1,a4 + 68: 00840713 addi a4,s0,8 + 6c: d64e sw s3,44(sp) + 6e: d452 sw s4,40(sp) + 70: 89b2 mv s3,a2 + 72: 8a2e mv s4,a1 + 74: 10000613 li a2,256 + 78: 4581 li a1,0 + 7a: 853a mv a0,a4 + 7c: d84a sw s2,48(sp) + 7e: d256 sw s5,36(sp) + 80: 8936 mv s2,a3 + 82: 20020ab7 lui s5,0x20020 + 86: cc02 sw zero,24(sp) + 88: ce02 sw zero,28(sp) + 8a: 2e0d jal 3bc <memset> + 8c: f14aa683 lw a3,-236(s5) # 2001ff14 <__bss_end__+0x2001fab0> + 90: 00795793 srli a5,s2,0x7 + 94: 8b89 andi a5,a5,2 + 96: 46f4 lw a3,76(a3) + 98: 85aa mv a1,a0 + 9a: c652 sw s4,12(sp) + 9c: c84e sw s3,16(sp) + 9e: ca4a sw s2,20(sp) + a0: 10f42423 sw a5,264(s0) + a4: 0070 addi a2,sp,12 + a6: 8526 mv a0,s1 + a8: f00a8a93 addi s5,s5,-256 + ac: 9682 jalr a3 + ae: ed29 bnez a0,108 <flash_init+0xb6> + b0: 014aa703 lw a4,20(s5) + b4: 560107b7 lui a5,0x56010 + b8: 2ff78793 addi a5,a5,767 # 560102ff <__bss_end__+0x5600fe9b> + bc: 4314 lw a3,0(a4) + be: 00d7f563 bgeu a5,a3,c8 <flash_init+0x76> + c2: 5b3c lw a5,112(a4) + c4: 4008 lw a0,0(s0) + c6: 9782 jalr a5 + c8: 47b2 lw a5,12(sp) + ca: 4705 li a4,1 + cc: 8bbd andi a5,a5,15 + ce: 00f77b63 bgeu a4,a5,e4 <flash_init+0x92> + d2: 47d2 lw a5,20(sp) + d4: 6705 lui a4,0x1 + d6: f0070713 addi a4,a4,-256 # f00 <__bss_end__+0xa9c> + da: 8ff9 and a5,a5,a4 + dc: 10000713 li a4,256 + e0: 02e78d63 beq a5,a4,11a <flash_init+0xc8> + e4: 00444783 lbu a5,4(s0) + e8: 02040e23 sb zero,60(s0) + ec: e781 bnez a5,f4 <flash_init+0xa2> + ee: 4785 li a5,1 + f0: 00f40223 sb a5,4(s0) + f4: 54d2 lw s1,52(sp) + f6: 5942 lw s2,48(sp) + f8: 59b2 lw s3,44(sp) + fa: 5a22 lw s4,40(sp) + fc: 5a92 lw s5,36(sp) + fe: 50f2 lw ra,60(sp) + 100: 5462 lw s0,56(sp) + 102: 4501 li a0,0 + 104: 6121 addi sp,sp,64 + 106: 8082 ret + 108: 50f2 lw ra,60(sp) + 10a: 5462 lw s0,56(sp) + 10c: 54d2 lw s1,52(sp) + 10e: 5942 lw s2,48(sp) + 110: 59b2 lw s3,44(sp) + 112: 5a22 lw s4,40(sp) + 114: 5a92 lw s5,36(sp) + 116: 6121 addi sp,sp,64 + 118: 8082 ret + 11a: 401c lw a5,0(s0) + 11c: 0607a023 sw zero,96(a5) + 120: 0607a223 sw zero,100(a5) + 124: b7c1 j e4 <flash_init+0x92> + +00000126 <flash_erase>: + 126: 200207b7 lui a5,0x20020 + 12a: f147a683 lw a3,-236(a5) # 2001ff14 <__bss_end__+0x2001fab0> + 12e: 1101 addi sp,sp,-32 + 130: 560107b7 lui a5,0x56010 + 134: 4298 lw a4,0(a3) + 136: cc22 sw s0,24(sp) + 138: c84a sw s2,16(sp) + 13a: ce06 sw ra,28(sp) + 13c: ca26 sw s1,20(sp) + 13e: c64e sw s3,12(sp) + 140: c256 sw s5,4(sp) + 142: 2ff78793 addi a5,a5,767 # 560102ff <__bss_end__+0x5600fe9b> + 146: 892e mv s2,a1 + 148: 8432 mv s0,a2 + 14a: 00e7f463 bgeu a5,a4,152 <flash_erase+0x2c> + 14e: 00a58933 add s2,a1,a0 + 152: 2b000993 li s3,688 + 156: 0309d483 lhu s1,48(s3) + 15a: 04aa slli s1,s1,0xa + 15c: 06946963 bltu s0,s1,1ce <flash_erase+0xa8> + 160: 02997ab3 remu s5,s2,s1 + 164: c452 sw s4,8(sp) + 166: 41548a33 sub s4,s1,s5 + 16a: 03448063 beq s1,s4,18a <flash_erase+0x64> + 16e: 4e9c lw a5,24(a3) + 170: 1089a583 lw a1,264(s3) + 174: 0009a503 lw a0,0(s3) + 178: 8752 mv a4,s4 + 17a: 86ca mv a3,s2 + 17c: 00898613 addi a2,s3,8 + 180: 9782 jalr a5 + 182: ed05 bnez a0,1ba <flash_erase+0x94> + 184: 8c05 sub s0,s0,s1 + 186: 9456 add s0,s0,s5 + 188: 9952 add s2,s2,s4 + 18a: 0484f163 bgeu s1,s0,1cc <flash_erase+0xa6> + 18e: 20020a37 lui s4,0x20020 + 192: 2b800a93 li s5,696 + 196: f00a0a13 addi s4,s4,-256 # 2001ff00 <__bss_end__+0x2001fa9c> + 19a: a021 j 1a2 <flash_erase+0x7c> + 19c: 9926 add s2,s2,s1 + 19e: 0684f163 bgeu s1,s0,200 <flash_erase+0xda> + 1a2: 014a2783 lw a5,20(s4) + 1a6: 1089a583 lw a1,264(s3) + 1aa: 0009a503 lw a0,0(s3) + 1ae: 53dc lw a5,36(a5) + 1b0: 86ca mv a3,s2 + 1b2: 8656 mv a2,s5 + 1b4: 9782 jalr a5 + 1b6: 8c05 sub s0,s0,s1 + 1b8: d175 beqz a0,19c <flash_erase+0x76> + 1ba: 4a22 lw s4,8(sp) + 1bc: 40f2 lw ra,28(sp) + 1be: 4462 lw s0,24(sp) + 1c0: 44d2 lw s1,20(sp) + 1c2: 4942 lw s2,16(sp) + 1c4: 49b2 lw s3,12(sp) + 1c6: 4a92 lw s5,4(sp) + 1c8: 6105 addi sp,sp,32 + 1ca: 8082 ret + 1cc: 4a22 lw s4,8(sp) + 1ce: 4501 li a0,0 + 1d0: d475 beqz s0,1bc <flash_erase+0x96> + 1d2: 2b800a93 li s5,696 + 1d6: 200207b7 lui a5,0x20020 + 1da: f0078793 addi a5,a5,-256 # 2001ff00 <__bss_end__+0x2001fa9c> + 1de: 4bdc lw a5,20(a5) + 1e0: 8722 mv a4,s0 + 1e2: 4462 lw s0,24(sp) + 1e4: 1089a583 lw a1,264(s3) + 1e8: 0009a503 lw a0,0(s3) + 1ec: 40f2 lw ra,28(sp) + 1ee: 44d2 lw s1,20(sp) + 1f0: 49b2 lw s3,12(sp) + 1f2: 4f9c lw a5,24(a5) + 1f4: 86ca mv a3,s2 + 1f6: 8656 mv a2,s5 + 1f8: 4942 lw s2,16(sp) + 1fa: 4a92 lw s5,4(sp) + 1fc: 6105 addi sp,sp,32 + 1fe: 8782 jr a5 + 200: 4a22 lw s4,8(sp) + 202: bfd1 j 1d6 <flash_erase+0xb0> + +00000204 <flash_program>: + 204: 200207b7 lui a5,0x20020 + 208: f147a883 lw a7,-236(a5) # 2001ff14 <__bss_end__+0x2001fab0> + 20c: 560107b7 lui a5,0x56010 + 210: 2ff78813 addi a6,a5,767 # 560102ff <__bss_end__+0x5600fe9b> + 214: 0008a303 lw t1,0(a7) + 218: 872e mv a4,a1 + 21a: 87b6 mv a5,a3 + 21c: 00687463 bgeu a6,t1,224 <flash_program+0x20> + 220: 00a58733 add a4,a1,a0 + 224: 2b000813 li a6,688 + 228: 0288a883 lw a7,40(a7) + 22c: 10882583 lw a1,264(a6) + 230: 00082503 lw a0,0(a6) + 234: 86b2 mv a3,a2 + 236: 00880613 addi a2,a6,8 + 23a: 8882 jr a7 + +0000023c <flash_read>: + 23c: 200207b7 lui a5,0x20020 + 240: f147a303 lw t1,-236(a5) # 2001ff14 <__bss_end__+0x2001fab0> + 244: 560107b7 lui a5,0x56010 + 248: 2ff78813 addi a6,a5,767 # 560102ff <__bss_end__+0x5600fe9b> + 24c: 00032e03 lw t3,0(t1) + 250: 88ae mv a7,a1 + 252: 8732 mv a4,a2 + 254: 87b6 mv a5,a3 + 256: 01c87463 bgeu a6,t3,25e <flash_read+0x22> + 25a: 00a60733 add a4,a2,a0 + 25e: 2b000813 li a6,688 + 262: 02c32303 lw t1,44(t1) + 266: 10882583 lw a1,264(a6) + 26a: 00082503 lw a0,0(a6) + 26e: 86c6 mv a3,a7 + 270: 00880613 addi a2,a6,8 + 274: 8302 jr t1 + +00000276 <flash_get_info>: + 276: cd81 beqz a1,28e <flash_get_info+0x18> + 278: 2b000793 li a5,688 + 27c: 5798 lw a4,40(a5) + 27e: 02e7d783 lhu a5,46(a5) + 282: 4501 li a0,0 + 284: 072a slli a4,a4,0xa + 286: 07aa slli a5,a5,0xa + 288: c198 sw a4,0(a1) + 28a: c1dc sw a5,4(a1) + 28c: 8082 ret + 28e: 4509 li a0,2 + 290: 8082 ret + +00000292 <flash_erase_chip>: + 292: 200207b7 lui a5,0x20020 + 296: f0078793 addi a5,a5,-256 # 2001ff00 <__bss_end__+0x2001fa9c> + 29a: 4bdc lw a5,20(a5) + 29c: 2b000613 li a2,688 + 2a0: 10862583 lw a1,264(a2) + 2a4: 4208 lw a0,0(a2) + 2a6: 4fdc lw a5,28(a5) + 2a8: 0621 addi a2,a2,8 + 2aa: 8782 jr a5 + +000002ac <flash_deinit>: + 2ac: 8082 ret + ... + +000002b0 <xpi_base>: + 2b0: 0000 0000 .... + +000002b4 <xpi_inited>: + 2b4: 0000 0000 .... + +000002b8 <nor_config>: + ... + +000003b8 <channel>: + 3b8: 0000 0000 .... + +000003bc <memset>: + 3bc: 433d li t1,15 + 3be: 872a mv a4,a0 + 3c0: 02c37363 bgeu t1,a2,3e6 <memset+0x2a> + 3c4: 00f77793 andi a5,a4,15 + 3c8: efbd bnez a5,446 <memset+0x8a> + 3ca: e5ad bnez a1,434 <memset+0x78> + 3cc: ff067693 andi a3,a2,-16 + 3d0: 8a3d andi a2,a2,15 + 3d2: 96ba add a3,a3,a4 + 3d4: c30c sw a1,0(a4) + 3d6: c34c sw a1,4(a4) + 3d8: c70c sw a1,8(a4) + 3da: c74c sw a1,12(a4) + 3dc: 0741 addi a4,a4,16 + 3de: fed76be3 bltu a4,a3,3d4 <memset+0x18> + 3e2: e211 bnez a2,3e6 <memset+0x2a> + 3e4: 8082 ret + 3e6: 40c306b3 sub a3,t1,a2 + 3ea: 068a slli a3,a3,0x2 + 3ec: 00000297 auipc t0,0x0 + 3f0: 9696 add a3,a3,t0 + 3f2: 00a68067 jr 10(a3) + 3f6: 00b70723 sb a1,14(a4) + 3fa: 00b706a3 sb a1,13(a4) + 3fe: 00b70623 sb a1,12(a4) + 402: 00b705a3 sb a1,11(a4) + 406: 00b70523 sb a1,10(a4) + 40a: 00b704a3 sb a1,9(a4) + 40e: 00b70423 sb a1,8(a4) + 412: 00b703a3 sb a1,7(a4) + 416: 00b70323 sb a1,6(a4) + 41a: 00b702a3 sb a1,5(a4) + 41e: 00b70223 sb a1,4(a4) + 422: 00b701a3 sb a1,3(a4) + 426: 00b70123 sb a1,2(a4) + 42a: 00b700a3 sb a1,1(a4) + 42e: 00b70023 sb a1,0(a4) + 432: 8082 ret + 434: 0ff5f593 zext.b a1,a1 + 438: 00859693 slli a3,a1,0x8 + 43c: 8dd5 or a1,a1,a3 + 43e: 01059693 slli a3,a1,0x10 + 442: 8dd5 or a1,a1,a3 + 444: b761 j 3cc <memset+0x10> + 446: 00279693 slli a3,a5,0x2 + 44a: 00000297 auipc t0,0x0 + 44e: 9696 add a3,a3,t0 + 450: 8286 mv t0,ra + 452: fa8680e7 jalr -88(a3) + 456: 8096 mv ra,t0 + 458: 17c1 addi a5,a5,-16 + 45a: 8f1d sub a4,a4,a5 + 45c: 963e add a2,a2,a5 + 45e: f8c374e3 bgeu t1,a2,3e6 <memset+0x2a> + 462: b7a5 j 3ca <memset+0xe> diff --git a/contrib/loaders/flash/hpmicro/hpm_xpi_flash.map b/contrib/loaders/flash/hpmicro/hpm_xpi_flash.map new file mode 100644 index 0000000000..d603e7af09 --- /dev/null +++ b/contrib/loaders/flash/hpmicro/hpm_xpi_flash.map @@ -0,0 +1,110 @@ +Archive member included to satisfy reference by file (symbol) + +/Volumes/Data/toolchains/riscv32-unknown-elf-multilib-2024.12.16-macos-intel/bin/../lib/gcc/riscv32-unknown-elf/14.2.0/../../../../riscv32-unknown-elf/lib/libc.a(libc_a-memset.o) + openocd_flash_algo.o (memset) + +Discarded input sections + + .text 0x00000000 0x0 func_table.o + .data 0x00000000 0x0 func_table.o + .bss 0x00000000 0x0 func_table.o + .text 0x00000000 0x0 openocd_flash_algo.o + .data 0x00000000 0x0 openocd_flash_algo.o + .bss 0x00000000 0x0 openocd_flash_algo.o + .data 0x00000000 0x0 /Volumes/Data/toolchains/riscv32-unknown-elf-multilib-2024.12.16-macos-intel/bin/../lib/gcc/riscv32-unknown-elf/14.2.0/../../../../riscv32-unknown-elf/lib/libc.a(libc_a-memset.o) + .bss 0x00000000 0x0 /Volumes/Data/toolchains/riscv32-unknown-elf-multilib-2024.12.16-macos-intel/bin/../lib/gcc/riscv32-unknown-elf/14.2.0/../../../../riscv32-unknown-elf/lib/libc.a(libc_a-memset.o) + +Memory Configuration + +Name Origin Length Attributes +*default* 0x00000000 0xffffffff + +Linker script and memory map + +LOAD func_table.o +LOAD openocd_flash_algo.o +LOAD /Volumes/Data/toolchains/riscv32-unknown-elf-multilib-2024.12.16-macos-intel/bin/../lib/gcc/riscv32-unknown-elf/14.2.0/libgcc.a +START GROUP +LOAD /Volumes/Data/toolchains/riscv32-unknown-elf-multilib-2024.12.16-macos-intel/bin/../lib/gcc/riscv32-unknown-elf/14.2.0/../../../../riscv32-unknown-elf/lib/libc.a +LOAD /Volumes/Data/toolchains/riscv32-unknown-elf-multilib-2024.12.16-macos-intel/bin/../lib/gcc/riscv32-unknown-elf/14.2.0/../../../../riscv32-unknown-elf/lib/libgloss.a +END GROUP +LOAD /Volumes/Data/toolchains/riscv32-unknown-elf-multilib-2024.12.16-macos-intel/bin/../lib/gcc/riscv32-unknown-elf/14.2.0/libgcc.a + +.text 0x00000000 0x464 + *(.func_table) + .func_table 0x00000000 0x2a func_table.o + 0x00000000 _init + *(.flash_algo.text*) + .flash_algo.text + 0x0000002a 0x284 openocd_flash_algo.o + 0x0000002a refresh_device_size + 0x00000052 flash_init + 0x00000126 flash_erase + 0x00000204 flash_program + 0x0000023c flash_read + 0x00000276 flash_get_info + 0x00000292 flash_erase_chip + 0x000002ac flash_deinit + *(.rodata) + *(.rodata*) + *(.flash_algo.data*) + *fill* 0x000002ae 0x2 + .flash_algo.data + 0x000002b0 0x10c openocd_flash_algo.o + 0x000002b0 xpi_base + 0x000002b4 xpi_inited + 0x000002b8 nor_config + 0x000003b8 channel + *(.text) + .text 0x000003bc 0xa8 /Volumes/Data/toolchains/riscv32-unknown-elf-multilib-2024.12.16-macos-intel/bin/../lib/gcc/riscv32-unknown-elf/14.2.0/../../../../riscv32-unknown-elf/lib/libc.a(libc_a-memset.o) + 0x000003bc memset + *(.text*) + 0x00000464 __etext = . + +.discard 0x00000464 0x0 + 0x00000464 __noncacheable_start__ = . + 0x00000464 __noncacheable_bss_start__ = . + 0x00000464 __bss_start__ = . + 0x00000464 __bss_end__ = . + 0x00000464 __noncacheable_bss_end__ = . + 0x00000464 _end = . + 0x00000464 __noncacheable_init_start__ = . + 0x00000464 __data_start__ = . + 0x00000464 __data_end__ = . + 0x00000464 __noncacheable_init_end__ = . + 0x00000464 __noncacheable_end__ = . + 0x00000464 __heap_start__ = . + 0x00000464 __heap_end__ = . + 0x00000464 __ramfunc_start__ = . + 0x00000464 __ramfunc_end__ = . + 0x00000464 __noncacheable_bss_start__ = . + 0x00000464 __noncacheable_bss_end__ = . + 0x00000464 __noncacheable_init_start__ = . + 0x00000464 __noncacheable_init_end__ = . + 0x00000464 __tdata_start__ = . + 0x00000464 __tdata_end__ = . + 0x00000464 __tbss_start__ = . + 0x00000464 __tbss_end__ = . + 0x00000464 __data_load_addr__ = . + 0x00000464 __fast_load_addr__ = . + 0x00000464 __tdata_load_addr__ = . + 0x00000464 __noncacheable_init_load_addr__ = . +OUTPUT(hpm_xpi_flash.elf elf32-littleriscv) + +.riscv.attributes + 0x00000000 0x5c + .riscv.attributes + 0x00000000 0x5a func_table.o + .riscv.attributes + 0x0000005a 0x5c openocd_flash_algo.o + .riscv.attributes + 0x000000b6 0x5a /Volumes/Data/toolchains/riscv32-unknown-elf-multilib-2024.12.16-macos-intel/bin/../lib/gcc/riscv32-unknown-elf/14.2.0/../../../../riscv32-unknown-elf/lib/libc.a(libc_a-memset.o) + +.comment 0x00000000 0x1b + .comment 0x00000000 0x1b openocd_flash_algo.o + 0x1c (size before relaxing) + +.note.GNU-stack + 0x00000000 0x0 + .note.GNU-stack + 0x00000000 0x0 openocd_flash_algo.o diff --git a/contrib/loaders/flash/hpmicro/linker.ld b/contrib/loaders/flash/hpmicro/linker.ld new file mode 100644 index 0000000000..6621f6c3d2 --- /dev/null +++ b/contrib/loaders/flash/hpmicro/linker.ld @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 2021 HPMicro + */ +ENTRY(_init) + +SECTIONS +{ + .text : { + *(.func_table) + KEEP(*(.flash_algo.text*)) + KEEP(*(.rodata)) + KEEP(*(.rodata*)) + KEEP(*(.flash_algo.data*)) + *(.text) + *(.text*) + __etext = .; + } + .discard : { + __noncacheable_start__ = .; + __noncacheable_bss_start__ = .; + __bss_start__ = .; + __bss_end__ = .; + __noncacheable_bss_end__ = .; + _end = .; + __noncacheable_init_start__ = .; + __data_start__ = .; + __data_end__ = .; + __noncacheable_init_end__ = .; + __noncacheable_end__ = .; + __heap_start__ = .; + __heap_end__ = .; + __ramfunc_start__ = .; + __ramfunc_end__ = .; + __noncacheable_bss_start__ = .; + __noncacheable_bss_end__ = .; + __noncacheable_init_start__ = .; + __noncacheable_init_end__ = .; + __tdata_start__ = .; + __tdata_end__ = .; + __tbss_start__ = .; + __tbss_end__ = .; + __data_load_addr__ = .; + __fast_load_addr__ = .; + __tdata_load_addr__ = .; + __noncacheable_init_load_addr__ = .; + } +} diff --git a/contrib/loaders/flash/hpmicro/openocd_flash_algo.c b/contrib/loaders/flash/hpmicro/openocd_flash_algo.c new file mode 100644 index 0000000000..b238a997fc --- /dev/null +++ b/contrib/loaders/flash/hpmicro/openocd_flash_algo.c @@ -0,0 +1,150 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2024 HPMicro + */ + +#include "hpm_romapi.h" + +#define XPI_USE_PORT_B_MASK (0x100) +#define XPI_USE_PORT_A_MASK (0) +#define XPI_USE_PORT_SHIFT (0x8) + +#define ROMAPI_SUPPORTS_HYBRIDXPI() (ROM_API_TABLE_ROOT->xpi_nor_driver_if->version >= 0x56010300) + +typedef struct { + uint32_t total_sz_in_bytes; + uint32_t sector_sz_in_bytes; +} hpm_flash_info_t; + +__attribute__ ((section(".flash_algo.data"))) xpi_nor_config_t nor_config; +__attribute__ ((section(".flash_algo.data"))) bool xpi_inited = false; +__attribute__ ((section(".flash_algo.data"))) uint32_t channel = xpi_channel_a1; +__attribute__ ((section(".flash_algo.data"))) XPI_Type *xpi_base; + + +__attribute__ ((section(".flash_algo.text"))) void refresh_device_size(XPI_Type *base, xpi_nor_config_option_t *option) +{ + volatile uint32_t *dev_size = (volatile uint32_t *)((uint32_t)base + 0x60); + bool enable_channelb = false; + if (option->header.words > 1) + enable_channelb = option->option1.connection_sel == xpi_nor_connection_sel_chnb_cs0; + if (enable_channelb) { + dev_size[0] = 0; + dev_size[1] = 0; + } +} + +__attribute__ ((section(".flash_algo.text"))) uint32_t flash_init(uint32_t flash_base, uint32_t header, + uint32_t opt0, uint32_t opt1, uint32_t xpi_base_addr) +{ + uint32_t i = 0; + xpi_nor_config_option_t cfg_option; + hpm_stat_t stat = status_success; + + xpi_base = (XPI_Type *)xpi_base_addr; + if (xpi_inited) + return stat; + + for (i = 0; i < sizeof(cfg_option); i++) + *((uint8_t *)&cfg_option + i) = 0; + for (i = 0; i < sizeof(nor_config); i++) + *((uint8_t *)&nor_config + i) = 0; + + cfg_option.header.U = header; + cfg_option.option0.U = opt0; + cfg_option.option1.U = opt1; + + if (opt1 & XPI_USE_PORT_B_MASK) + channel = xpi_channel_b1; + else + channel = xpi_channel_a1; + + stat = ROM_API_TABLE_ROOT->xpi_nor_driver_if->auto_config(xpi_base, &nor_config, &cfg_option); + if (stat) + return stat; + + if (ROMAPI_SUPPORTS_HYBRIDXPI()) + ROM_API_TABLE_ROOT->xpi_nor_driver_if->enable_hybrid_xpi(xpi_base); + + refresh_device_size(xpi_base, &cfg_option); + + + nor_config.device_info.clk_freq_for_non_read_cmd = 0; + if (!xpi_inited) + xpi_inited = true; + return stat; +} + +__attribute__ ((section(".flash_algo.text"))) uint32_t flash_erase(uint32_t flash_base, uint32_t address, uint32_t size) +{ + hpm_stat_t stat = status_success; + uint32_t left, start, block_size, align; + + left = size; + start = address; + if (ROMAPI_SUPPORTS_HYBRIDXPI()) + start += flash_base; + block_size = nor_config.device_info.block_size_kbytes * 1024; + if (left >= block_size) { + align = block_size - (start % block_size); + if (align != block_size) { + stat = ROM_API_TABLE_ROOT->xpi_nor_driver_if->erase(xpi_base, channel, &nor_config, start, align); + if (stat != status_success) + return stat; + left -= align; + start += align; + } + while (left > block_size) { + stat = ROM_API_TABLE_ROOT->xpi_nor_driver_if->erase_block(xpi_base, channel, &nor_config, start); + if (stat != status_success) + break; + left -= block_size; + start += block_size; + } + } + if (stat == status_success && left) + stat = ROM_API_TABLE_ROOT->xpi_nor_driver_if->erase(xpi_base, channel, &nor_config, start, left); + return stat; +} + +__attribute__ ((section(".flash_algo.text"))) uint32_t flash_program(uint32_t flash_base, uint32_t address, + uint32_t *buf, uint32_t size) +{ + hpm_stat_t stat; + + if (ROMAPI_SUPPORTS_HYBRIDXPI()) + address += flash_base; + stat = ROM_API_TABLE_ROOT->xpi_nor_driver_if->program(xpi_base, channel, &nor_config, buf, address, size); + return stat; +} + +__attribute__ ((section(".flash_algo.text"))) uint32_t flash_read(uint32_t flash_base, uint32_t *buf, + uint32_t address, uint32_t size) +{ + hpm_stat_t stat; + + if (ROMAPI_SUPPORTS_HYBRIDXPI()) + address += flash_base; + stat = ROM_API_TABLE_ROOT->xpi_nor_driver_if->read(xpi_base, channel, &nor_config, buf, address, size); + return stat; +} + +__attribute__ ((section(".flash_algo.text"))) uint32_t flash_get_info(uint32_t flash_base, hpm_flash_info_t *flash_info) +{ + if (!flash_info) + return status_invalid_argument; + + flash_info->total_sz_in_bytes = nor_config.device_info.size_in_kbytes << 10; + flash_info->sector_sz_in_bytes = nor_config.device_info.sector_size_kbytes << 10; + return status_success; +} + +__attribute__ ((section(".flash_algo.text"))) uint32_t flash_erase_chip(uint32_t flash_base) +{ + return ROM_API_TABLE_ROOT->xpi_nor_driver_if->erase_chip(xpi_base, channel, &nor_config); +} + +__attribute__ ((section(".flash_algo.text"))) void flash_deinit(void) +{ + return; +} --