⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mallocx.c

📁 优龙YLP270开发板 光盘自带的BIOS和实验例程源码 强烈推荐
💻 C
字号:
/******************************************************************************
**
**  COPYRIGHT (C) 2001 Intel Corporation
**
**  FILENAME:   mallocx.c
**
**  PURPOSE:    A general purpose implementation of "malloc" and "free".
**
**  $Modtime: 7/17/03 1:01p $
**
******************************************************************************/

/*
*******************************************************************************
*   HEADER FILES
*******************************************************************************
*/

#include <stdio.h>
#include "systypes.h"
#include "dm_errors.h"
#include "cotulla.h"
#define MALLOCX_GLOBALS
#include "mallocx.h"

#define ALIGN 16
#define HEAPSIZE (HEAPEND-HEAPADDR)

// sizeof(MemBlockT) must be <= ALIGN !
typedef struct {
    PUINT8 pAddr;   // The physical address of this block,
                    //    same as the Non-Cached, Non-Buffered address. 
    PUINT8 cbAddr;  // Cached, Buffered virtual address of this block.
    PUINT8 cxAddr;   // Cached, Non-Buffered virtual address of this block.
    UINT32 size;
} MemBlockT;

ErrorT retVal;

/*
*******************************************************************************
*
* FUNCTION:         malloc
*
* DESCRIPTION:      Implements the standard "malloc" function.
*                   Allocates a 16-byte-aligned memory block from the heap.
*
* INPUT PARAMETERS: UINT32 size - Size of requested allocation in bytes.
*                                    -1 = get largest available.
*
* RETURNS:          A pointer to the allocated memory or NULL on error.
*
* GLOBAL EFFECTS:   None.
*
* ASSUMPTIONS:      The heap is identity mapped as non-cached, non-buffered
*                   for DMA usage. It may also be mapped elsewhere for
*                   "normal" usage.
*
* CALLS:            None.
*
* CALLED BY:        Anyone.
*
* PROTOTYPE:        PVOID malloc(UINT32 size)
*
*******************************************************************************
*/
extern int print_malloc;
PVOID malloc(UINT32 size)
{
    MemBlockT *memBlockP, *nextMemBlockP, *largestMemBlockP;

    largestMemBlockP = memBlockP = (MemBlockT *)HEAPADDR;
    if (size != -1) {
        size += ALIGN; // Allow room for the header.
        size = ((size+ALIGN-1)/ALIGN)*ALIGN; // Round up to a multiple of "ALIGN" bytes.
    }

    if (
        (BYTE *)memBlockP > HEAPEND ||
        memBlockP->size > HEAPSIZE ||
        memBlockP->size == 0 ||
        memBlockP->size%ALIGN != 0
    ) {
        retVal = ERRORCODEX(ERR_L_HEAP, 0, 0, ERR_T_UNEXPECTED); // Corrupt chain.
        return NULL;
    }

    while (memBlockP->cbAddr || memBlockP->size < size)
    {
        nextMemBlockP = (MemBlockT *)((BYTE *)memBlockP + memBlockP->size);

        if ((BYTE *)nextMemBlockP == HEAPEND) {
            memBlockP = largestMemBlockP;
            if (size == -1 && !memBlockP->cbAddr) goto out;
            retVal = ERRORCODEX(ERR_L_HEAP, 0, 0, ERR_T_NO_MEM_AVAIL); // No room.
            return NULL;
        }

        if (
            (BYTE *)nextMemBlockP > HEAPEND ||
            nextMemBlockP->size > HEAPSIZE ||
            nextMemBlockP->size == 0 ||
            nextMemBlockP->size%ALIGN != 0
        ) {
            retVal = ERRORCODEX(ERR_L_HEAP, 0, 1, ERR_T_UNEXPECTED); // Corrupt chain.
            return NULL;
        }

// Try to combine two free blocks
        if (!memBlockP->cbAddr && !nextMemBlockP->cbAddr)
            memBlockP->size += nextMemBlockP->size;
        else memBlockP = nextMemBlockP;
        
        if (
            !memBlockP->cbAddr && (
                largestMemBlockP->cbAddr ||
                memBlockP->size > largestMemBlockP->size
            )
        ) largestMemBlockP = memBlockP;
    }

// Found room!

    nextMemBlockP = (MemBlockT *)((BYTE *)memBlockP + size);

// Do we have room to split the block?
    if (memBlockP->size > size) {
        nextMemBlockP->size = memBlockP->size - size;
        memBlockP->size = size;
        nextMemBlockP->cbAddr = NULL;
        nextMemBlockP->cxAddr = NULL;
        nextMemBlockP->pAddr = (BYTE *)nextMemBlockP;
    }

// Continue on to audit the heap integrity.
    while ((BYTE *)nextMemBlockP != HEAPEND) {
        if (
            (BYTE *)nextMemBlockP > HEAPEND ||
            nextMemBlockP->size > HEAPSIZE ||
            nextMemBlockP->size == 0 ||
            nextMemBlockP->size%ALIGN != 0
        ) {
            retVal = ERRORCODEX(ERR_L_HEAP, 0, 2, ERR_T_UNEXPECTED); // Corrupt chain.
            return NULL;
        }
        nextMemBlockP = (MemBlockT *)((BYTE *)nextMemBlockP + nextMemBlockP->size);
    }

out:
    retVal = ERR_NONE;
    
    memBlockP->cbAddr = (((BYTE *)memBlockP) - MEMORYSTART) + MEMORYCACHEDBUFFEREDSTART;
    memBlockP->cxAddr = (((BYTE *)memBlockP) - MEMORYSTART) + MEMORYCACHEDSTART;

// Point past the header.
    return (PVOID)((BYTE *)memBlockP + ALIGN);
}

/*
*******************************************************************************
*
* FUNCTION:         free
*
* DESCRIPTION:      Free a memory block allocated by malloc or mallocx.
*
* INPUT PARAMETERS: A pointer to the memory block.
*
* RETURNS:          An error code.
*
* GLOBAL EFFECTS:   None.
*
* ASSUMPTIONS:      None.
*
* CALLS:            None.
*
* CALLED BY:        Anyone.
*
* PROTOTYPE:        ErrorT free(PVOID pAddr)
*
*******************************************************************************
*/

ErrorT free(PVOID pAddr)
{
    MemBlockT *memBlockP;

    memBlockP = (MemBlockT *)HEAPADDR;
// Get the physical address of this block.
    pAddr = (PVOID)(((MemBlockT *)((BYTE *)pAddr - ALIGN))->pAddr);

    while (pAddr != memBlockP) {
        if (
            (BYTE *)memBlockP > HEAPEND ||
            memBlockP->size > HEAPSIZE ||
            memBlockP->size == 0 ||
            memBlockP->size%ALIGN != 0
        ) return ERRORCODEX(ERR_L_HEAP, 1, 0, ERR_T_UNEXPECTED); // Corrupt chain.
        memBlockP = (MemBlockT *)((BYTE *)memBlockP + memBlockP->size);
        if ((BYTE *)memBlockP == HEAPEND)
            return ERRORCODEX(ERR_L_HEAP, 1, 1, ERR_T_ILLPARAM); // Block not found in chain.
    }

    memBlockP->cbAddr = NULL; // We found it!
    memBlockP->cxAddr = NULL;

// Continue on to audit the heap integrity.
    do {
        if (
            (BYTE *)memBlockP > HEAPEND ||
            memBlockP->size > HEAPSIZE ||
            memBlockP->size == 0 ||
            memBlockP->size%ALIGN != 0
        ) return ERRORCODEX(ERR_L_HEAP, 1, 2, ERR_T_UNEXPECTED); // Corrupt chain.
        memBlockP = (MemBlockT *)((BYTE *)memBlockP + memBlockP->size);
    } while ((BYTE *)memBlockP != HEAPEND);
    return ERR_NONE;
}

/*
*******************************************************************************
*
* FUNCTION:         mallocx
*
* DESCRIPTION:      Legacy function.
*
* INPUT PARAMETERS:
*   size - Size of requested allocation in bytes. -1 = get largest available.
*   virtualAddr - Where to return the vitual address of the allocated block.
*   physicalAddr - Where to return the physical address of the allocated block.
*
* RETURNS:          An error code.
*                   virtualAddr and physicalAddr are filled in with the
*                   corresponding values or NULL if there is an error.
*
* GLOBAL EFFECTS:   None.
*
* ASSUMPTIONS:      None.
*
* CALLS:			None.
*
* CALLED BY:		Anyone.
*
* PROTOTYPE:
*   ErrorT mallocx(UINT32 size, void **virtualAddr, void **physicalAddr);
*
*******************************************************************************
*/

ErrorT mallocx(UINT32 size, void **virtualAddr, void **physicalAddr)
{
    *virtualAddr = *physicalAddr = malloc(size);

    return retVal;
}

/*
*******************************************************************************
*
* FUNCTION:         mallocxSWInit
*
* DESCRIPTION:      Allocate and initialize the heaps.
*
* INPUT PARAMETERS:	None.
*
* RETURNS:          Nothing.
*
* GLOBAL EFFECTS:   None.
*
* ASSUMPTIONS:      None.
*
* CALLS:			None.
*
* CALLED BY:		System.
*
* PROTOTYPE:        void mallocxSWInit(void)
*
*******************************************************************************
*/

void mallocxSWInit(void)
{
    ((MemBlockT *)HEAPADDR)->pAddr = HEAPADDR;
    ((MemBlockT *)HEAPADDR)->cbAddr = NULL;     // Mark free.
    ((MemBlockT *)HEAPADDR)->cxAddr = NULL;
    ((MemBlockT *)HEAPADDR)->size = HEAPSIZE;
}

/*
*******************************************************************************
*
* FUNCTION:         mallocSize
*
* DESCRIPTION:      Return the size of an allocated block.
*
* INPUT PARAMETERS: A pointer to the memory block.
*
* RETURNS:          The size of the allocated block.
*
* GLOBAL EFFECTS:   None.
*
* ASSUMPTIONS:      None.
*
* CALLS:			None.
*
* CALLED BY:		Anyone.
*
* PROTOTYPE:        UINT32 mallocSize(PVOID pAddr);
*
*******************************************************************************
*/

UINT32 mallocSize(PVOID pAddr)
{
    // Look back at the header.
    return ((MemBlockT *)(((PUINT8)pAddr)-ALIGN))->size - ALIGN;
}

/*
*******************************************************************************
*
* FUNCTION:         malloc_cb
*
* DESCRIPTION:      Get the Cached, Buffered address of an allocated block.
*
* INPUT PARAMETERS: A pointer to the memory block.
*
* RETURNS:          The Cached, Buffered address of the allocated block.
*
* GLOBAL EFFECTS:   None.
*
* ASSUMPTIONS:      None.
*
* CALLS:			None.
*
* CALLED BY:		Anyone.
*
* PROTOTYPE:        PVOID malloc_cb(PVOID pAddr);
*
*******************************************************************************
*/

PVOID malloc_cb(PVOID pAddr)
{
    // Look back at the header.
    return ((MemBlockT *)(((PUINT8)pAddr)-ALIGN))->cbAddr + ALIGN;
}

/*
*******************************************************************************
*
* FUNCTION:         malloc_cx
*
* DESCRIPTION:      Get the Cached, Non-Buffered address of an allocated block.
*
* INPUT PARAMETERS: A pointer to the memory block.
*
* RETURNS:          The Cached, Non-Buffered address of the allocated block.
*
* GLOBAL EFFECTS:   None.
*
* ASSUMPTIONS:      None.
*
* CALLS:			None.
*
* CALLED BY:		Anyone.
*
* PROTOTYPE:        PVOID malloc_cx(PVOID pAddr);
*
*******************************************************************************
*/

PVOID malloc_cx(PVOID pAddr)
{
    // Look back at the header.
    return ((MemBlockT *)(((PUINT8)pAddr)-ALIGN))->cxAddr + ALIGN;
}

/*
*******************************************************************************
*
* FUNCTION:         mallocErr
*
* DESCRIPTION:      Get the error code from the last malloc().
*
* INPUT PARAMETERS: None.
*
* RETURNS:          The error code.
*
* GLOBAL EFFECTS:   None.
*
* ASSUMPTIONS:      None.
*
* CALLS:			None.
*
* CALLED BY:		Anyone.
*
* PROTOTYPE:        ErrorT mallocErr(void);
*
*******************************************************************************
*/

ErrorT mallocErr(void)
{
    // Look back at the header.
    return retVal;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -