mirror of
https://gitee.com/Vancouver2017/luban-lite-t3e-pro.git
synced 2025-12-14 18:38:55 +00:00
v1.1.1
This commit is contained in:
@@ -1,3 +1,11 @@
|
||||
/*
|
||||
* Copyright (c) 2023-2024, ArtInChip Technology Co., Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Authors: Wu Dehuang <dehuang.wu@artinchip.com>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -383,7 +391,8 @@ static int console_run_cmd_internal(struct tiny_console *cons,
|
||||
for (c = root; c; c = c->next) {
|
||||
int rc = CONSOLE_OK;
|
||||
|
||||
if (strncasecmp(c->cmdname, args[starg_arg], strlen(args[starg_arg])))
|
||||
if (strncasecmp(c->cmdname, args[starg_arg], strlen(c->cmdname)) ||
|
||||
strlen(c->cmdname) != strlen(args[starg_arg]))
|
||||
continue;
|
||||
|
||||
/* name is matched */
|
||||
|
||||
207
bsp/artinchip/drv_bare/qspi/spi.c
Normal file
207
bsp/artinchip/drv_bare/qspi/spi.c
Normal file
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
* Copyright (c) 2024, ArtInChip Technology Co., Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Authors: jiji.chen <jiji.chen@artinchip.com>
|
||||
*/
|
||||
|
||||
#include <rtconfig.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <sfud.h>
|
||||
#include <aic_common.h>
|
||||
#include <aic_core.h>
|
||||
#include <aic_soc.h>
|
||||
#include <aic_log.h>
|
||||
#include <aic_hal.h>
|
||||
#include <hal_qspi.h>
|
||||
#include <spinor_port.h>
|
||||
#include <hal_dma.h>
|
||||
#include <aic_dma_id.h>
|
||||
#include <aic_clk_id.h>
|
||||
|
||||
static struct aic_qspi_bus qspi_bus_arr[] = {
|
||||
#if defined(AIC_USING_QSPI0) && defined(AIC_QSPI0_DEVICE_SPINOR)
|
||||
{
|
||||
.name = "qspi0",
|
||||
.idx = 0,
|
||||
.clk_id = CLK_QSPI0,
|
||||
.clk_in_hz = AIC_DEV_QSPI0_MAX_SRC_FREQ_HZ,
|
||||
.bus_hz = AIC_QSPI0_DEVICE_SPINOR_FREQ,
|
||||
.dma_port_id = DMA_ID_SPI0,
|
||||
.irq_num = QSPI0_IRQn,
|
||||
.dl_width = AIC_QSPI0_BUS_WIDTH,
|
||||
#if defined(AIC_QSPI_MULTIPLE_CS_NUM)
|
||||
.cs_num = AIC_QSPI0_CS_NUM,
|
||||
#endif
|
||||
.rxd_dylmode = AIC_DEV_QSPI0_DELAY_MODE,
|
||||
#if defined(AIC_QSPI_DRV_V20)
|
||||
.txd_dylmode = AIC_DEV_QSPI0_TXD_DELAY_MODE,
|
||||
.txc_dylmode = AIC_DEV_QSPI0_TX_CLK_DELAY_MODE,
|
||||
#endif
|
||||
},
|
||||
#endif
|
||||
#if defined(AIC_USING_QSPI1) && defined(AIC_QSPI1_DEVICE_SPINOR)
|
||||
{
|
||||
.name = "qspi1",
|
||||
.idx = 1,
|
||||
.clk_id = CLK_QSPI1,
|
||||
.clk_in_hz = AIC_DEV_QSPI1_MAX_SRC_FREQ_HZ,
|
||||
.bus_hz = AIC_QSPI1_DEVICE_SPINOR_FREQ,
|
||||
.dma_port_id = DMA_ID_SPI1,
|
||||
.irq_num = QSPI1_IRQn,
|
||||
.dl_width = AIC_QSPI1_BUS_WIDTH,
|
||||
#if defined(AIC_QSPI_MULTIPLE_CS_NUM)
|
||||
.cs_num = AIC_QSPI1_CS_NUM,
|
||||
#endif
|
||||
.rxd_dylmode = AIC_DEV_QSPI1_DELAY_MODE,
|
||||
#if defined(AIC_QSPI_DRV_V20)
|
||||
.txd_dylmode = AIC_DEV_QSPI1_TXD_DELAY_MODE,
|
||||
.txc_dylmode = AIC_DEV_QSPI1_TX_CLK_DELAY_MODE,
|
||||
#endif
|
||||
},
|
||||
#endif
|
||||
#if defined(AIC_USING_QSPI2) && defined(AIC_QSPI2_DEVICE_SPINOR)
|
||||
{
|
||||
.name = "qspi2",
|
||||
.idx = 2,
|
||||
.clk_id = CLK_QSPI2,
|
||||
.clk_in_hz = AIC_DEV_QSPI2_MAX_SRC_FREQ_HZ,
|
||||
.bus_hz = AIC_QSPI2_DEVICE_SPINOR_FREQ,
|
||||
.dma_port_id = DMA_ID_SPI2,
|
||||
.irq_num = QSPI2_IRQn,
|
||||
.dl_width = AIC_QSPI2_BUS_WIDTH,
|
||||
#if defined(AIC_QSPI_MULTIPLE_CS_NUM)
|
||||
.cs_num = AIC_QSPI2_CS_NUM,
|
||||
#endif
|
||||
.rxd_dylmode = AIC_DEV_QSPI2_DELAY_MODE,
|
||||
#if defined(AIC_QSPI_DRV_V20)
|
||||
.txd_dylmode = AIC_DEV_QSPI2_TXD_DELAY_MODE,
|
||||
.txc_dylmode = AIC_DEV_QSPI2_TX_CLK_DELAY_MODE,
|
||||
#endif
|
||||
},
|
||||
#endif
|
||||
#if defined(AIC_USING_QSPI3)
|
||||
{
|
||||
.name = "qspi3",
|
||||
.idx = 3,
|
||||
.clk_id = CLK_QSPI3,
|
||||
.clk_in_hz = AIC_DEV_QSPI3_MAX_SRC_FREQ_HZ,
|
||||
.bus_hz = AIC_QSPI3_DEVICE_SPINOR_FREQ,
|
||||
.dma_port_id = DMA_ID_SPI3,
|
||||
.irq_num = QSPI3_IRQn,
|
||||
.dl_width = AIC_QSPI3_BUS_WIDTH,
|
||||
#if defined(AIC_QSPI_MULTIPLE_CS_NUM)
|
||||
.cs_num = AIC_QSPI3_CS_NUM,
|
||||
#endif
|
||||
.rxd_dylmode = AIC_DEV_QSPI3_DELAY_MODE,
|
||||
#if defined(AIC_QSPI_DRV_V20)
|
||||
.txd_dylmode = AIC_DEV_QSPI3_TXD_DELAY_MODE,
|
||||
.txc_dylmode = AIC_DEV_QSPI3_TX_CLK_DELAY_MODE,
|
||||
#endif
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
int spi_write_read(struct aic_qspi_bus *qspi,
|
||||
const uint8_t *write_buf, size_t write_size,
|
||||
uint8_t *read_buf, size_t read_size)
|
||||
{
|
||||
struct qspi_transfer t;
|
||||
int ret = 0;
|
||||
u32 cs_num = 0;
|
||||
|
||||
hal_qspi_master_set_bus_width(&qspi->handle, HAL_QSPI_BUS_WIDTH_SINGLE);
|
||||
#if defined(AIC_QSPI_MULTIPLE_CS_NUM)
|
||||
cs_num = qspi->cs_num;
|
||||
#endif
|
||||
hal_qspi_master_set_cs(&qspi->handle, cs_num, true);
|
||||
if (write_size) {
|
||||
t.rx_data = NULL;
|
||||
t.tx_data = (uint8_t *)write_buf;
|
||||
t.data_len = write_size;
|
||||
ret = hal_qspi_master_transfer_sync(&qspi->handle, &t);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
}
|
||||
if (read_size) {
|
||||
t.rx_data = read_buf;
|
||||
t.tx_data = NULL;
|
||||
t.data_len = read_size;
|
||||
ret = hal_qspi_master_transfer_sync(&qspi->handle, &t);
|
||||
}
|
||||
out:
|
||||
#if defined(AIC_QSPI_MULTIPLE_CS_NUM)
|
||||
cs_num = qspi->cs_num;
|
||||
#endif
|
||||
hal_qspi_master_set_cs(&qspi->handle, cs_num, false);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct aic_qspi_bus *get_qspi_by_index(u32 idx)
|
||||
{
|
||||
struct aic_qspi_bus *qspi;
|
||||
u32 i;
|
||||
|
||||
qspi = NULL;
|
||||
for (i = 0; i < ARRAY_SIZE(qspi_bus_arr); i++) {
|
||||
if (qspi_bus_arr[i].idx == idx) {
|
||||
qspi = &qspi_bus_arr[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return qspi;
|
||||
}
|
||||
|
||||
struct aic_qspi_bus *qspi_probe(u32 spi_bus)
|
||||
{
|
||||
|
||||
struct aic_qspi_bus *qspi;
|
||||
int ret;
|
||||
struct qspi_master_config cfg = {0};
|
||||
|
||||
qspi = get_qspi_by_index(spi_bus);
|
||||
if (!qspi) {
|
||||
pr_err("spi bus is invalid: %d\n", spi_bus);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (qspi->probe_flag)
|
||||
return qspi;
|
||||
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
cfg.idx = qspi->idx;
|
||||
cfg.clk_in_hz = qspi->clk_in_hz;
|
||||
cfg.clk_id = qspi->clk_id;
|
||||
cfg.cpol = HAL_QSPI_CPOL_ACTIVE_HIGH;
|
||||
cfg.cpha = HAL_QSPI_CPHA_FIRST_EDGE;
|
||||
cfg.cs_polarity = HAL_QSPI_CS_POL_VALID_LOW;
|
||||
cfg.rx_dlymode = qspi->rxd_dylmode;
|
||||
cfg.tx_dlymode = aic_convert_tx_dlymode(qspi->txc_dylmode, qspi->txd_dylmode);
|
||||
|
||||
ret = hal_qspi_master_init(&qspi->handle, &cfg);
|
||||
if (ret) {
|
||||
pr_err("hal_qspi_master_init failed. ret %d\n", ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef AIC_DMA_DRV
|
||||
struct qspi_master_dma_config dmacfg;
|
||||
memset(&dmacfg, 0, sizeof(dmacfg));
|
||||
dmacfg.port_id = qspi->dma_port_id;
|
||||
|
||||
ret = hal_qspi_master_dma_config(&qspi->handle, &dmacfg);
|
||||
if (ret) {
|
||||
pr_err("qspi dma config failed.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
qspi->probe_flag = true;
|
||||
return qspi;
|
||||
}
|
||||
@@ -1,44 +1,237 @@
|
||||
/*
|
||||
* Copyright (C) 2023-2024 ArtInChip Technology Co.,Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Author: Dehuang Wu <dehuang.wu@artinchip.com>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <heap.h>
|
||||
#include <aic_core.h>
|
||||
#include "umm_malloc.h"
|
||||
|
||||
int heap_init(void *ptr, size_t size)
|
||||
/* mem check */
|
||||
|
||||
#if defined(AIC_BOOTLOADER) && defined(AIC_BOOTLOADER_MEM_AUTO)
|
||||
#if AIC_PSRAM_SIZE
|
||||
#if (AIC_BOOTLOADER_TEXT_BASE < CPU_PSRAM_BASE)
|
||||
#error AIC_BOOTLOADER_TEXT_BASE less than CPU_PSRAM_BASE
|
||||
#endif
|
||||
#if (AIC_BOOTLOADER_TEXT_BASE > (CPU_PSRAM_BASE + AIC_PSRAM_SIZE))
|
||||
#error AIC_BOOTLOADER_TEXT_BASE more than (CPU_PSRAM_BASE + AIC_PSRAM_SIZE)
|
||||
#endif
|
||||
#elif AIC_DRAM_TOTAL_SIZE
|
||||
#if (AIC_BOOTLOADER_TEXT_BASE < CPU_DRAM_BASE)
|
||||
#error AIC_BOOTLOADER_TEXT_BASE less than CPU_DRAM_BASE
|
||||
#endif
|
||||
#if (AIC_BOOTLOADER_TEXT_BASE > (CPU_DRAM_BASE + AIC_DRAM_TOTAL_SIZE))
|
||||
#error AIC_BOOTLOADER_TEXT_BASE more than (CPU_DRAM_BASE + AIC_DRAM_TOTAL_SIZE)
|
||||
#endif
|
||||
#elif AIC_SRAM_SIZE
|
||||
#if (AIC_BOOTLOADER_TEXT_BASE < CPU_SRAM_BASE)
|
||||
#error AIC_BOOTLOADER_TEXT_BASE less than CPU_SRAM_BASE
|
||||
#endif
|
||||
#if (AIC_BOOTLOADER_TEXT_BASE > (CPU_SRAM_BASE + AIC_SRAM_SIZE))
|
||||
#error AIC_BOOTLOADER_TEXT_BASE more than (CPU_SRAM_BASE + AIC_SRAM_SIZE)
|
||||
#endif
|
||||
#elif AIC_SRAM_TOTAL_SIZE
|
||||
#if (AIC_BOOTLOADER_TEXT_BASE < CPU_SRAM_BASE)
|
||||
#error AIC_BOOTLOADER_TEXT_BASE less than CPU_SRAM_BASE
|
||||
#endif
|
||||
#if (AIC_BOOTLOADER_TEXT_BASE > (CPU_SRAM_BASE + AIC_SRAM_TOTAL_SIZE))
|
||||
#error AIC_BOOTLOADER_TEXT_BASE more than (CPU_SRAM_BASE + AIC_SRAM_TOTAL_SIZE)
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
char * name;
|
||||
aic_mem_region_t type;
|
||||
size_t start;
|
||||
size_t end;
|
||||
} heap_def_t;
|
||||
|
||||
static struct umm_heap_config heap[MAX_MEM_REGION];
|
||||
|
||||
static heap_def_t heap_def[MAX_MEM_REGION] = {
|
||||
{
|
||||
.name = "sys",
|
||||
.type = MEM_DEFAULT,
|
||||
.start = (size_t)(&__heap_start),
|
||||
.end = (size_t)(&__heap_end),
|
||||
},
|
||||
|
||||
#if defined(AIC_BOOTLOADER) && defined(AIC_BOOTLOADER_MEM_AUTO)
|
||||
{
|
||||
.name = "reserved",
|
||||
.type = MEM_RESERVED,
|
||||
#if AIC_PSRAM_SIZE
|
||||
.start = (size_t)(CPU_PSRAM_BASE),
|
||||
.end = (size_t)(AIC_BOOTLOADER_TEXT_BASE - 0x100),
|
||||
#elif AIC_DRAM_TOTAL_SIZE
|
||||
.start = (size_t)(CPU_DRAM_BASE),
|
||||
.end = (size_t)(AIC_BOOTLOADER_TEXT_BASE - 0x100),
|
||||
|
||||
#elif AIC_SRAM_SIZE || AIC_SRAM_TOTAL_SIZE
|
||||
.start = (size_t)(CPU_SRAM_BASE),
|
||||
.end = (size_t)(AIC_BOOTLOADER_TEXT_BASE - 0x100),
|
||||
#endif
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
int heap_init(void)
|
||||
{
|
||||
umm_init_heap(ptr, size);
|
||||
int i = 0;
|
||||
size_t start, end;
|
||||
|
||||
for (i = 0; i < MAX_MEM_REGION; i++) {
|
||||
start = heap_def[i].start;
|
||||
end = heap_def[i].end;
|
||||
if (start >= end) {
|
||||
pr_err("%s: region %d addr err. start = 0x%x, end = 0x%x\n", __func__, i, (u32)start, (u32)end);
|
||||
return -1;
|
||||
}
|
||||
|
||||
umm_init_heap(&heap[i], (void *)start, (end - start));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef TLSF_MEM_HEAP
|
||||
void *aic_tlsf_malloc(uint32_t mem_type, uint32_t nbytes)
|
||||
void *aic_tlsf_malloc(u32 mem_type, u32 nbytes)
|
||||
{
|
||||
return umm_malloc(nbytes);
|
||||
void *ptr;
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < sizeof(heap_def) / sizeof(heap_def_t); i++) {
|
||||
if (heap_def[i].type == mem_type)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= MAX_MEM_REGION) {
|
||||
pr_debug("%s: not found mem type %d, use mem type 0.\n", __func__, mem_type);
|
||||
ptr = umm_malloc(&heap[0], nbytes);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
ptr = umm_malloc(&heap[i], nbytes);
|
||||
|
||||
pr_debug("%s: ptr = 0x%x, nbytes = 0x%x.\n", __func__, (u32)(uintptr_t)ptr, nbytes);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void aic_tlsf_free(uint32_t mem_type, void *ptr)
|
||||
void aic_tlsf_free(u32 mem_type, void *ptr)
|
||||
{
|
||||
umm_free(ptr);
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < sizeof(heap_def) / sizeof(heap_def_t); i++) {
|
||||
if (heap_def[i].type == mem_type)
|
||||
break;
|
||||
}
|
||||
|
||||
pr_debug("%s: ptr = 0x%x.\n", __func__, (u32)(uintptr_t)ptr);
|
||||
|
||||
if (i >= MAX_MEM_REGION) {
|
||||
pr_debug("%s: not found mem type %d, use mem type 0.\n", __func__, mem_type);
|
||||
umm_free(&heap[0], ptr);
|
||||
return;
|
||||
}
|
||||
|
||||
umm_free(&heap[i], ptr);
|
||||
}
|
||||
|
||||
void *aic_tlsf_malloc_align(uint32_t mem_type, uint32_t size, uint32_t align)
|
||||
void *aic_tlsf_malloc_align(u32 mem_type, u32 nbytes, u32 align)
|
||||
{
|
||||
return umm_malloc_align(size, align);
|
||||
void *ptr;
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < sizeof(heap_def) / sizeof(heap_def_t); i++) {
|
||||
if (heap_def[i].type == mem_type)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= MAX_MEM_REGION) {
|
||||
pr_debug("%s: not found mem type %d, use mem type 0.\n", __func__, mem_type);
|
||||
ptr = umm_malloc_align(&heap[0], nbytes, align);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
ptr = umm_malloc_align(&heap[i], nbytes, align);
|
||||
|
||||
pr_debug("%s: ptr = 0x%x, nbytes = 0x%x.\n", __func__, (u32)(uintptr_t)ptr, nbytes);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void aic_tlsf_free_align(uint32_t mem_type, void *ptr)
|
||||
void aic_tlsf_free_align(u32 mem_type, void *ptr)
|
||||
{
|
||||
umm_free_align(ptr);
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < sizeof(heap_def) / sizeof(heap_def_t); i++) {
|
||||
if (heap_def[i].type == mem_type)
|
||||
break;
|
||||
}
|
||||
|
||||
pr_debug("%s: ptr = 0x%x.\n", __func__, (u32)(uintptr_t)ptr);
|
||||
|
||||
if (i >= MAX_MEM_REGION) {
|
||||
pr_debug("%s: not found mem type %d, use mem type 0.\n", __func__, mem_type);
|
||||
umm_free_align(&heap[0], ptr);
|
||||
return;
|
||||
}
|
||||
|
||||
umm_free_align(&heap[i], ptr);
|
||||
}
|
||||
|
||||
void *aic_tlsf_realloc(uint32_t mem_type, void *ptr, uint32_t nbytes)
|
||||
void *aic_tlsf_realloc(u32 mem_type, void *ptr, u32 nbytes)
|
||||
{
|
||||
return umm_realloc(ptr, nbytes);
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < sizeof(heap_def) / sizeof(heap_def_t); i++) {
|
||||
if (heap_def[i].type == mem_type)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= MAX_MEM_REGION) {
|
||||
pr_debug("%s: not found mem type %d, use mem type 0.\n", __func__, mem_type);
|
||||
ptr = umm_realloc(&heap[0], ptr, nbytes);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
ptr = umm_realloc(&heap[i], ptr, nbytes);
|
||||
|
||||
pr_debug("%s: ptr = 0x%x, nbytes = 0x%x.\n", __func__, (u32)(uintptr_t)ptr, nbytes);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *aic_tlsf_calloc(uint32_t mem_type, uint32_t count, uint32_t size)
|
||||
void *aic_tlsf_calloc(u32 mem_type, u32 count, u32 nbytes)
|
||||
{
|
||||
return umm_calloc(count, size);
|
||||
void *ptr;
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < sizeof(heap_def) / sizeof(heap_def_t); i++) {
|
||||
if (heap_def[i].type == mem_type)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= MAX_MEM_REGION) {
|
||||
pr_debug("%s: not found mem type %d, use mem type 0.\n", __func__, mem_type);
|
||||
ptr = umm_calloc(&heap[0], count, nbytes);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
ptr = umm_calloc(&heap[i], count, nbytes);
|
||||
|
||||
pr_debug("%s: ptr = 0x%x, nbytes = 0x%x.\n", __func__, (u32)(uintptr_t)ptr, nbytes);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -19,13 +19,14 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <umm_malloc.h>
|
||||
#include <aic_core.h>
|
||||
#include <aic_tlsf.h>
|
||||
|
||||
void *_malloc_r(struct _reent *ptr, size_t size)
|
||||
{
|
||||
void* result;
|
||||
|
||||
result = (void*)umm_malloc(size);
|
||||
result = (void*)aic_tlsf_malloc(MEM_DEFAULT, size);
|
||||
if (result == NULL)
|
||||
{
|
||||
ptr->_errno = ENOMEM;
|
||||
@@ -38,7 +39,7 @@ void *_realloc_r(struct _reent *ptr, void *old, size_t newlen)
|
||||
{
|
||||
void* result;
|
||||
|
||||
result = (void*)umm_realloc(old, newlen);
|
||||
result = (void*)aic_tlsf_realloc(MEM_DEFAULT, old, newlen);
|
||||
if (result == NULL)
|
||||
{
|
||||
ptr->_errno = ENOMEM;
|
||||
@@ -51,7 +52,7 @@ void *_calloc_r(struct _reent *ptr, size_t size, size_t len)
|
||||
{
|
||||
void* result;
|
||||
|
||||
result = (void*)umm_calloc(size, len);
|
||||
result = (void*)aic_tlsf_calloc(MEM_DEFAULT, size, len);
|
||||
if (result == NULL)
|
||||
{
|
||||
ptr->_errno = ENOMEM;
|
||||
@@ -62,7 +63,7 @@ void *_calloc_r(struct _reent *ptr, size_t size, size_t len)
|
||||
|
||||
void _free_r(struct _reent *ptr, void *addr)
|
||||
{
|
||||
umm_free(addr);
|
||||
aic_tlsf_free(MEM_DEFAULT, addr);
|
||||
}
|
||||
|
||||
int *__errno(void)
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
* R.Hempel 2020-02-01 - Macro functions are uppercased - See Issue 34
|
||||
* R.Hempel 2020-06-20 - Support alternate body size - See Issue 42
|
||||
* R.Hempel 2021-05-02 - Support explicit memory umm_init_heap() - See Issue 53
|
||||
* K.Whitlock 2023-07-06 - Add support for multiple heaps
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
@@ -81,18 +82,9 @@ UMM_H_ATTPACKPRE typedef struct umm_block_t {
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
struct umm_heap_config {
|
||||
umm_block *pheap;
|
||||
size_t heap_size;
|
||||
uint16_t numblocks;
|
||||
};
|
||||
|
||||
struct umm_heap_config umm_heap_current;
|
||||
// struct umm_heap_config umm_heaps[UMM_NUM_HEAPS];
|
||||
|
||||
#define UMM_HEAP (umm_heap_current.pheap)
|
||||
#define UMM_HEAPSIZE (umm_heap_current.heap_size)
|
||||
#define UMM_NUMBLOCKS (umm_heap_current.numblocks)
|
||||
#define UMM_HEAP ((umm_block *)heap->pheap)
|
||||
#define UMM_HEAPSIZE (heap->heap_size)
|
||||
#define UMM_NUMBLOCKS (heap->numblocks)
|
||||
|
||||
#define UMM_BLOCKSIZE (sizeof(umm_block))
|
||||
#define UMM_BLOCK_LAST (UMM_NUMBLOCKS - 1)
|
||||
@@ -200,7 +192,8 @@ static uint16_t umm_blocks(size_t size) {
|
||||
*
|
||||
* Note that free pointers are NOT modified by this function.
|
||||
*/
|
||||
static void umm_split_block(uint16_t c,
|
||||
static void umm_split_block(umm_heap *heap,
|
||||
uint16_t c,
|
||||
uint16_t blocks,
|
||||
uint16_t new_freemask) {
|
||||
|
||||
@@ -213,7 +206,7 @@ static void umm_split_block(uint16_t c,
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
static void umm_disconnect_from_free_list(uint16_t c) {
|
||||
static void umm_disconnect_from_free_list(umm_heap *heap, uint16_t c) {
|
||||
/* Disconnect this block from the FREE list */
|
||||
|
||||
UMM_NFREE(UMM_PFREE(c)) = UMM_NFREE(c);
|
||||
@@ -230,7 +223,7 @@ static void umm_disconnect_from_free_list(uint16_t c) {
|
||||
* next block is free.
|
||||
*/
|
||||
|
||||
static void umm_assimilate_up(uint16_t c) {
|
||||
static void umm_assimilate_up(umm_heap *heap, uint16_t c) {
|
||||
|
||||
if (UMM_NBLOCK(UMM_NBLOCK(c)) & UMM_FREELIST_MASK) {
|
||||
|
||||
@@ -245,7 +238,7 @@ static void umm_assimilate_up(uint16_t c) {
|
||||
|
||||
/* Disconnect the next block from the FREE list */
|
||||
|
||||
umm_disconnect_from_free_list(UMM_NBLOCK(c));
|
||||
umm_disconnect_from_free_list(heap, UMM_NBLOCK(c));
|
||||
|
||||
/* Assimilate the next block with this one */
|
||||
|
||||
@@ -260,7 +253,7 @@ static void umm_assimilate_up(uint16_t c) {
|
||||
* up before assimilating down.
|
||||
*/
|
||||
|
||||
static uint16_t umm_assimilate_down(uint16_t c, uint16_t freemask) {
|
||||
static uint16_t umm_assimilate_down(umm_heap *heap, uint16_t c, uint16_t freemask) {
|
||||
|
||||
// We are going to assimilate down to the previous block because
|
||||
// it was free, so remove it from the fragmentation metric
|
||||
@@ -285,10 +278,10 @@ static uint16_t umm_assimilate_down(uint16_t c, uint16_t freemask) {
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
void umm_init_heap(void *ptr, size_t size)
|
||||
void umm_init_heap(umm_heap *heap, void *ptr, size_t size)
|
||||
{
|
||||
/* init heap pointer and size, and memset it to 0 */
|
||||
UMM_HEAP = (umm_block *)ptr;
|
||||
heap->pheap = ptr;
|
||||
UMM_HEAPSIZE = size;
|
||||
UMM_NUMBLOCKS = (UMM_HEAPSIZE / UMM_BLOCKSIZE);
|
||||
memset(UMM_HEAP, 0x00, UMM_HEAPSIZE);
|
||||
@@ -337,10 +330,10 @@ void umm_init_heap(void *ptr, size_t size)
|
||||
|
||||
}
|
||||
|
||||
void umm_init(void) {
|
||||
void umm_init(umm_heap *heap) {
|
||||
/* Initialize the heap from linker supplied values */
|
||||
|
||||
umm_init_heap(UMM_MALLOC_CFG_HEAP_ADDR, UMM_MALLOC_CFG_HEAP_SIZE);
|
||||
umm_init_heap(heap, UMM_MALLOC_CFG_HEAP_ADDR, UMM_MALLOC_CFG_HEAP_SIZE);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
@@ -348,7 +341,7 @@ void umm_init(void) {
|
||||
* UMM_CRITICAL_ENTRY(id) and UMM_CRITICAL_EXIT(id).
|
||||
*/
|
||||
|
||||
static void umm_free_core(void *ptr) {
|
||||
static void umm_free_core(umm_heap *heap, void *ptr) {
|
||||
|
||||
uint16_t c;
|
||||
|
||||
@@ -369,7 +362,7 @@ static void umm_free_core(void *ptr) {
|
||||
|
||||
/* Now let's assimilate this block with the next one if possible. */
|
||||
|
||||
umm_assimilate_up(c);
|
||||
umm_assimilate_up(heap, c);
|
||||
|
||||
/* Then assimilate with the previous block if possible */
|
||||
|
||||
@@ -377,7 +370,7 @@ static void umm_free_core(void *ptr) {
|
||||
|
||||
DBGLOG_DEBUG("Assimilate down to previous block, which is FREE\n");
|
||||
|
||||
c = umm_assimilate_down(c, UMM_FREELIST_MASK);
|
||||
c = umm_assimilate_down(heap, c, UMM_FREELIST_MASK);
|
||||
} else {
|
||||
/*
|
||||
* The previous block is not a free block, so add this one to the head
|
||||
@@ -398,7 +391,7 @@ static void umm_free_core(void *ptr) {
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
void umm_free(void *ptr) {
|
||||
void umm_free(umm_heap *heap, void *ptr) {
|
||||
UMM_CRITICAL_DECL(id_free);
|
||||
|
||||
UMM_CHECK_INITIALIZED();
|
||||
@@ -411,11 +404,20 @@ void umm_free(void *ptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* If we're being asked to free an out of range pointer - do nothing */
|
||||
/* TODO: remove the check for NULL pointer later */
|
||||
|
||||
if ((ptr < heap->pheap) || ((size_t)ptr >= (size_t)heap->pheap + heap->heap_size)) {
|
||||
DBGLOG_DEBUG("free an out of range pointer -> do nothing\n");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Free the memory withing a protected critical section */
|
||||
|
||||
UMM_CRITICAL_ENTRY(id_free);
|
||||
|
||||
umm_free_core(ptr);
|
||||
umm_free_core(heap, ptr);
|
||||
|
||||
UMM_CRITICAL_EXIT(id_free);
|
||||
}
|
||||
@@ -425,7 +427,7 @@ void umm_free(void *ptr) {
|
||||
* UMM_CRITICAL_ENTRY(id) and UMM_CRITICAL_EXIT(id).
|
||||
*/
|
||||
|
||||
static void *umm_malloc_core(size_t size) {
|
||||
static void *umm_malloc_core(umm_heap *heap, size_t size) {
|
||||
uint16_t blocks;
|
||||
uint16_t blockSize = 0;
|
||||
|
||||
@@ -493,7 +495,7 @@ static void *umm_malloc_core(size_t size) {
|
||||
|
||||
/* Disconnect this block from the FREE list */
|
||||
|
||||
umm_disconnect_from_free_list(cf);
|
||||
umm_disconnect_from_free_list(heap, cf);
|
||||
} else {
|
||||
|
||||
/* It's not an exact fit and we need to split off a block. */
|
||||
@@ -503,7 +505,7 @@ static void *umm_malloc_core(size_t size) {
|
||||
* split current free block `cf` into two blocks. The first one will be
|
||||
* returned to user, so it's not free, and the second one will be free.
|
||||
*/
|
||||
umm_split_block(cf, blocks, UMM_FREELIST_MASK /*new block is free*/);
|
||||
umm_split_block(heap, cf, blocks, UMM_FREELIST_MASK /*new block is free*/);
|
||||
|
||||
UMM_FRAGMENTATION_METRIC_ADD(UMM_NBLOCK(cf));
|
||||
|
||||
@@ -536,7 +538,7 @@ static void *umm_malloc_core(size_t size) {
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
void *umm_malloc(size_t size) {
|
||||
void *umm_malloc(umm_heap *heap, size_t size) {
|
||||
UMM_CRITICAL_DECL(id_malloc);
|
||||
|
||||
void *ptr = NULL;
|
||||
@@ -560,7 +562,7 @@ void *umm_malloc(size_t size) {
|
||||
|
||||
UMM_CRITICAL_ENTRY(id_malloc);
|
||||
|
||||
ptr = umm_malloc_core(size);
|
||||
ptr = umm_malloc_core(heap, size);
|
||||
|
||||
UMM_CRITICAL_EXIT(id_malloc);
|
||||
|
||||
@@ -569,7 +571,7 @@ void *umm_malloc(size_t size) {
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
void *umm_realloc(void *ptr, size_t size) {
|
||||
void *umm_realloc(umm_heap *heap, void *ptr, size_t size) {
|
||||
UMM_CRITICAL_DECL(id_realloc);
|
||||
|
||||
uint16_t blocks;
|
||||
@@ -594,7 +596,7 @@ void *umm_realloc(void *ptr, size_t size) {
|
||||
if (((void *)NULL == ptr)) {
|
||||
DBGLOG_DEBUG("realloc the NULL pointer - call malloc()\n");
|
||||
|
||||
return umm_malloc(size);
|
||||
return umm_malloc(heap, size);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -606,7 +608,7 @@ void *umm_realloc(void *ptr, size_t size) {
|
||||
if (0 == size) {
|
||||
DBGLOG_DEBUG("realloc to 0 size, just free the block\n");
|
||||
|
||||
umm_free(ptr);
|
||||
umm_free(heap, ptr);
|
||||
|
||||
return (void *)NULL;
|
||||
}
|
||||
@@ -698,20 +700,20 @@ void *umm_realloc(void *ptr, size_t size) {
|
||||
// Case 2 - block + next block fits EXACTLY
|
||||
} else if ((blockSize + nextBlockSize) == blocks) {
|
||||
DBGLOG_DEBUG("exact realloc using next block - %i\n", blocks);
|
||||
umm_assimilate_up(c);
|
||||
umm_assimilate_up(heap, c);
|
||||
blockSize += nextBlockSize;
|
||||
|
||||
// Case 3 - prev block NOT free and block + next block fits
|
||||
} else if ((0 == prevBlockSize) && (blockSize + nextBlockSize) >= blocks) {
|
||||
DBGLOG_DEBUG("realloc using next block - %i\n", blocks);
|
||||
umm_assimilate_up(c);
|
||||
umm_assimilate_up(heap, c);
|
||||
blockSize += nextBlockSize;
|
||||
|
||||
// Case 4 - prev block + block fits
|
||||
} else if ((prevBlockSize + blockSize) >= blocks) {
|
||||
DBGLOG_DEBUG("realloc using prev block - %i\n", blocks);
|
||||
umm_disconnect_from_free_list(UMM_PBLOCK(c));
|
||||
c = umm_assimilate_down(c, 0);
|
||||
umm_disconnect_from_free_list(heap, UMM_PBLOCK(c));
|
||||
c = umm_assimilate_down(heap, c, 0);
|
||||
memmove((void *)&UMM_DATA(c), ptr, curSize);
|
||||
ptr = (void *)&UMM_DATA(c);
|
||||
blockSize += prevBlockSize;
|
||||
@@ -719,9 +721,9 @@ void *umm_realloc(void *ptr, size_t size) {
|
||||
// Case 5 - prev block + block + next block fits
|
||||
} else if ((prevBlockSize + blockSize + nextBlockSize) >= blocks) {
|
||||
DBGLOG_DEBUG("realloc using prev and next block - %i\n", blocks);
|
||||
umm_assimilate_up(c);
|
||||
umm_disconnect_from_free_list(UMM_PBLOCK(c));
|
||||
c = umm_assimilate_down(c, 0);
|
||||
umm_assimilate_up(heap, c);
|
||||
umm_disconnect_from_free_list(heap, UMM_PBLOCK(c));
|
||||
c = umm_assimilate_down(heap, c, 0);
|
||||
memmove((void *)&UMM_DATA(c), ptr, curSize);
|
||||
ptr = (void *)&UMM_DATA(c);
|
||||
blockSize += (prevBlockSize + nextBlockSize);
|
||||
@@ -730,10 +732,10 @@ void *umm_realloc(void *ptr, size_t size) {
|
||||
} else {
|
||||
DBGLOG_DEBUG("realloc a completely new block %i\n", blocks);
|
||||
void *oldptr = ptr;
|
||||
if ((ptr = umm_malloc_core(size))) {
|
||||
if ((ptr = umm_malloc_core(heap, size))) {
|
||||
DBGLOG_DEBUG("realloc %i to a bigger block %i, copy, and free the old\n", blockSize, blocks);
|
||||
memcpy(ptr, oldptr, curSize);
|
||||
umm_free_core(oldptr);
|
||||
umm_free_core(heap, oldptr);
|
||||
} else {
|
||||
DBGLOG_DEBUG("realloc %i to a bigger block %i failed - return NULL and leave the old block!\n", blockSize, blocks);
|
||||
/* This space intentionally left blnk */
|
||||
@@ -747,8 +749,8 @@ void *umm_realloc(void *ptr, size_t size) {
|
||||
|
||||
if (blockSize > blocks) {
|
||||
DBGLOG_DEBUG("split and free %i blocks from %i\n", blocks, blockSize);
|
||||
umm_split_block(c, blocks, 0);
|
||||
umm_free_core((void *)&UMM_DATA(c + blocks));
|
||||
umm_split_block(heap, c, blocks, 0);
|
||||
umm_free_core(heap, (void *)&UMM_DATA(c + blocks));
|
||||
}
|
||||
|
||||
/* Release the critical section... */
|
||||
@@ -759,10 +761,10 @@ void *umm_realloc(void *ptr, size_t size) {
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
void *umm_calloc(size_t num, size_t item_size) {
|
||||
void *umm_calloc(umm_heap *heap, size_t num, size_t item_size) {
|
||||
void *ret;
|
||||
|
||||
ret = umm_malloc((size_t)(item_size * num));
|
||||
ret = umm_malloc(heap, (size_t)(item_size * num));
|
||||
|
||||
if (ret) {
|
||||
memset(ret, 0x00, (size_t)(item_size * num));
|
||||
@@ -771,7 +773,7 @@ void *umm_calloc(size_t num, size_t item_size) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *umm_malloc_align(size_t size, size_t align)
|
||||
void *umm_malloc_align(umm_heap *heap, size_t size, size_t align)
|
||||
{
|
||||
void *ptr;
|
||||
void *align_ptr;
|
||||
@@ -788,7 +790,7 @@ void *umm_malloc_align(size_t size, size_t align)
|
||||
/* get total aligned size */
|
||||
align_size = ((size + uintptr_size) & ~uintptr_size) + align;
|
||||
/* allocate memory block from heap */
|
||||
ptr = umm_malloc(align_size);
|
||||
ptr = umm_malloc(heap, align_size);
|
||||
if (ptr != NULL) {
|
||||
/* the allocated memory block is aligned */
|
||||
if (((unsigned long)ptr & (align - 1)) == 0) {
|
||||
@@ -807,7 +809,7 @@ void *umm_malloc_align(size_t size, size_t align)
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void umm_free_align(void *ptr)
|
||||
void umm_free_align(umm_heap *heap, void *ptr)
|
||||
{
|
||||
void *real_ptr;
|
||||
|
||||
@@ -815,6 +817,6 @@ void umm_free_align(void *ptr)
|
||||
if (ptr == NULL)
|
||||
return;
|
||||
real_ptr = (void *)*(unsigned long *)((unsigned long)ptr - sizeof(void *));
|
||||
umm_free(real_ptr);
|
||||
umm_free(heap, real_ptr);
|
||||
}
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
@@ -16,15 +16,21 @@ extern "C" {
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
extern void umm_init_heap(void *ptr, size_t size);
|
||||
extern void umm_init(void);
|
||||
typedef struct umm_heap_config {
|
||||
void *pheap;
|
||||
size_t heap_size;
|
||||
uint16_t numblocks;
|
||||
} umm_heap;
|
||||
|
||||
extern void *umm_malloc(size_t size);
|
||||
extern void *umm_calloc(size_t num, size_t size);
|
||||
extern void *umm_realloc(void *ptr, size_t size);
|
||||
extern void umm_free(void *ptr);
|
||||
extern void *umm_malloc_align(size_t size, size_t align);
|
||||
extern void umm_free_align(void *ptr);
|
||||
extern void umm_init_heap(umm_heap *heap, void *ptr, size_t size);
|
||||
extern void umm_init(umm_heap *heap);
|
||||
|
||||
extern void *umm_malloc(umm_heap *heap, size_t size);
|
||||
extern void *umm_calloc(umm_heap *heap, size_t num, size_t size);
|
||||
extern void *umm_realloc(umm_heap *heap, void *ptr, size_t size);
|
||||
extern void umm_free(umm_heap *heap, void *ptr);
|
||||
extern void *umm_malloc_align(umm_heap *heap, size_t size, size_t align);
|
||||
extern void umm_free_align(umm_heap *heap, void *ptr);
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user