This commit is contained in:
刘可亮
2024-10-30 16:50:31 +08:00
parent 0ef85b55da
commit 661e71562d
458 changed files with 46555 additions and 12133 deletions

View File

@@ -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 */

View 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;
}

View File

@@ -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

View File

@@ -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)

View File

@@ -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);
}
/* ------------------------------------------------------------------------ */

View File

@@ -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);
/* ------------------------------------------------------------------------ */