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

📄 dpram8xx.c

📁 这是单板上DPRAM的驱动程序
💻 C
字号:
/* @(#) pSOSystem PowerPC/V2.2.2: bsps/e360/src/dpram360.c (mpc8xx) 2.7 97/07/31 18:35:55 */
/***********************************************************************/
/*                                                                     */
/*   MODULE: bsps/devices/icontrol/dpram8xx.c                          */
/*   DATE:    97/07/31                                                 */
/*   PURPOSE: MPC8xx dual ported RAM management functions              */
/*                                                                     */
/*---------------------------------------------------------------------*/
/*                                                                     */
/*           Copyright 1991 - 1997, Integrated Systems, Inc.           */
/*                      ALL RIGHTS RESERVED                            */
/*                                                                     */
/*   Permission is hereby granted to licensees of Integrated Systems,  */
/*   Inc. products to use or abstract this computer program for the    */
/*   sole purpose of implementing a product based on Integrated        */
/*   Systems, Inc. products.   No other rights to reproduce, use,      */
/*   or disseminate this computer program, whether in part or in       */
/*   whole, are granted.                                               */
/*                                                                     */
/*   Integrated Systems, Inc. makes no representation or warranties    */
/*   with respect to the performance of this computer program, and     */
/*   specifically disclaims any responsibility for any damages,        */
/*   special or consequential, connected with the use of this program. */
/*                                                                     */
/*---------------------------------------------------------------------*/
/*                                                                     */
/*                                                                     */
/*                                                                     */
/***********************************************************************/

#include "board.h"
#include <icontrol/mpc8xx.h>

#ifdef DEBUG
#undef DEBUG
#endif
#ifndef  ALIGN
#define ALIGN(addr, boundary) (((ULONG)(addr)+(ULONG)(boundary)-1) \
                               & ~((ULONG)(boundary)-1))
#endif

/*---------------------------------------------------------------------*/
/* THESE CONSTANTS ARE RELATED TO THE BIT-MAPPED MEMORY ALLOCATOR.     */
/*---------------------------------------------------------------------*/
#define BYTES_TO_ALLOC  4*1024     /*  Number of DPRAM bytes to manage */
#define CHUNK_SIZE      8          /*  Allocation size (DO NOT CHANGE) */
#define BITS_PER_UNIT   8          /*  Number of bits per bitmap unit  */

/*---------------------------------------------------------------------*/
/* DPRAM Bitmap table: one bit in the bitmap represents CHUNK_SIZE     */
/* bytes, which is the minimum size that can be allocated.             */
/*---------------------------------------------------------------------*/
static UCHAR bitmap[MAX_QUICCS][BYTES_TO_ALLOC / (CHUNK_SIZE * BITS_PER_UNIT)];

extern ULONG dpram_base[];
extern ULONG quicc_num[];

void dpram_init(void);
UCHAR *dpram_alloc(UINT, UINT);
void dpram_dealloc(UINT, UCHAR *, UINT);
static void bit_set(UCHAR *, UINT);
static void bit_clear(UCHAR *, UINT);
static UINT bit_get(UCHAR *, UINT);

/***********************************************************************/
/* BIT-MAPPED memory allocation routines.                              */
/***********************************************************************/
/* dpram_init:                                                         */
/* This routine sets-up the DP_RAM bitmap for all the SCCs supported,  */
/* possibly reserving some areas of the QUICC DP-RAM for other usages  */
/* like Ethernet, SPI, or SMCs.                                        */
/*                                                                     */
/***********************************************************************/
void dpram_init(void)
{
UINT i, n;
/* UCHAR   *map; --deleted by szg , not used */

/*---------------------------------------------------------------------*/
/* On the QUADS board, the master QUICC is fully available:            */
/* all these other functions are performed on the slave QUICC.         */
/* So just completely clear the bitmap.                                */
/*---------------------------------------------------------------------*/
for(n = 0; n < MAX_QUICCS; n++)
    {
        for (i = 0; i < (BYTES_TO_ALLOC / (CHUNK_SIZE * BITS_PER_UNIT)); i++)
            bitmap[n][i] = 0;
    }
#if 0
#if (BD_HAS_SLAVE == 1)
    map  = bitmap[1];
#else /* BD_HAS_SLAVE */
    map  = bitmap[0];
#endif /* BD_HAS_SLAVE */
#endif /* del by szg , not used */
}

/***********************************************************************/
/*  dpram_reserve: Reserve portions of dpram for exclusive usage       */
/***********************************************************************/
UCHAR *
dpram_reserve(ULONG port, ULONG offset, ULONG size)
{
 
UCHAR  *map;
ULONG  BdOffset, BdCount, n;
 
#if (BD_HAS_SLAVE == 1)
    map  = bitmap[1];
#else /* BD_HAS_SLAVE */
    map  = bitmap[0];
#endif /* BD_HAS_SLAVE */
 
BdOffset = ALIGN(offset,CHUNK_SIZE)/CHUNK_SIZE;
BdCount  = ALIGN(size,CHUNK_SIZE)/CHUNK_SIZE;
 
#ifdef  DEBUG
LogPrint("DPRAM8xx.C: In dpram_reserve(), Off 0x%x, Count 0x%x",
          BdOffset, BdCount);
#endif
 
/*---------------------------------------------------------------------*/
/* Mask out those discriptors requested                                */
/*---------------------------------------------------------------------*/
for (n = BdOffset; n < (BdOffset + BdCount); n++)
    bit_set(map, n);
return NULL; /* this is an invalid return value */
}

/***********************************************************************/
/* dpram_alloc:                                                        */
/*              This routine allocates a "chunk" of the dual-port      */
/*               RAM associated with the specified SCC. The port       */
/*              number is used to determine which memory pool is       */
/*              to be allocated from.                                  */
/*                                                                     */
/*      INPUTS:                                                        */
/*              port channel to assign ram to                          */
/*              size amount of ram needed                              */
/*                                                                     */
/*     RETURNS:                                                        */
/*              pointer to Dual ported ram area assigned               */
/*     NOTE(S):                                                        */
/*                                                                     */
/***********************************************************************/
UCHAR   *dpram_alloc0(UINT port, UINT size);
UCHAR   *dpram_alloc(UINT port, UINT size){ return dpram_alloc0(port,size); }
UCHAR   *dpram_alloc0(UINT port, UINT size)
{
UCHAR   *map;
UINT    bits;
UINT    accumulate;
UINT    start;
UINT    i;

#ifdef  DEBUG
LogPrint("DPRA8XX.C: Allocating Dpram, Port %d, Size %d", port, size);
#endif
/*---------------------------------------------------------------------*/
/* Get the correct 68360 chip's bitmap                                 */
/*---------------------------------------------------------------------*/
map  = bitmap[quicc_num[port]];
bits = (size + CHUNK_SIZE - 1) / CHUNK_SIZE;

accumulate = 0;
start = 0;
i = 0;

while (i < (BYTES_TO_ALLOC / CHUNK_SIZE))
    {
    switch(accumulate)
        {
        case 0:
            /*---------------------------------------------------------*/
            /* Search for initial hole. See if chunk is free.          */
            /*---------------------------------------------------------*/
            if (bit_get(map, i) == 0)
                {
                start = i;
                accumulate = 1;
                }
            break;

        default:
            accumulate++;
            /*---------------------------------------------------------*/
            /* See if next chunk is free. If it isn't start over.      */
            /*---------------------------------------------------------*/
            if (bit_get(map, i) != 0)

                /*-----------------------------------------------------*/
                /* Next chunk is not free so start over again and look */
                /* for the next hole start.                            */
                /*-----------------------------------------------------*/
                accumulate = 0;

            break;
        }
    i++;

    /*-----------------------------------------------------------------*/
    /* If we have enough bits, set them and return the allocated       */
    /* pointer.                                                        */
    /*-----------------------------------------------------------------*/
    if (accumulate == bits)
        {
        for (i=start; accumulate--; i++)
            bit_set(map, i);

#ifdef  DEBUG
        LogPrint("DPRA8XX.C: returning from dpram_alloc(), 0x%08x",
                  (UCHAR *)dpram_base[port] + (start * CHUNK_SIZE));
#endif
        return ((UCHAR *)dpram_base[port] + (start * CHUNK_SIZE));
        }
    }
return ((UCHAR *)NULL);
}

/***********************************************************************/
/* dpram_dealloc:                                                      */
/*                This routine is used to deallocate a block of        */
/*                dual-port RAM. The port number is used to determine  */
/*                which pool to deallocate from. It is VERY important  */
/*                that the size parameter match that of the size of    */
/*                the requested block.                                 */
/*                                                                     */
/*      INPUTS:                                                        */
/*              port - channel number                                  */
/*              where - pointer to top of dual-port RAM to dealloc     */
/*              size - size of area to dealloc                         */
/*                                                                     */
/*      NOTE:   The dual-port RAM is controled by a bit map.           */
/*                                                                     */
/***********************************************************************/
void dpram_dealloc0(UINT port, UCHAR *where, UINT size);
void dpram_dealloc(UINT port, UCHAR *where, UINT size){ 
	dpram_dealloc0(port,where,size); 
	}
void dpram_dealloc0(UINT port, UCHAR *where, UINT size)
{
UCHAR   *map;
UINT    bits;
UINT    start;

#ifdef  DEBUG
LogPrint("DPRA8XX.C: De-allocating Dpram, Port %d, Size %d", port, size);
#endif

start = (where - (UCHAR *)dpram_base[port]) / CHUNK_SIZE;
map  = bitmap[quicc_num[port]];
bits = (size + CHUNK_SIZE - 1) / CHUNK_SIZE;
/* bits = (size + CHUNK_SIZE - 1) & ~(CHUNK_SIZE - 1); */
while(bits--)
    bit_clear(map, start++);
}

/***********************************************************************/
/* bit_clear:                                                          */
/*            Clear a bit in the specified bitmap.                     */
/*                                                                     */
/*      INPUTS:                                                        */
/*              map pointer to a bit map                               */
/*              bitnum number of the bit to clear                      */
/*                                                                     */
/***********************************************************************/
/*
 *  Clear a bit in the specified bitmap.
 */
static void bit_clear(UCHAR *map, UINT bitnum)
{
UINT    bit;
UINT    byte;

byte = bitnum /  BITS_PER_UNIT;
bit  = bitnum & (BITS_PER_UNIT - 1);
map[byte] &= ~(1 << bit);
}

/***********************************************************************/
/* bit_set:                                                            */
/*          Set a bit in the specified bit map.                        */
/*                                                                     */
/*      INPUTS:                                                        */
/*              map pointer to bit map                                 */
/*              bitnum bit number to set                               */
/*                                                                     */
/***********************************************************************/
static void bit_set(UCHAR *map, UINT bitnum)
{
UINT    bit;
UINT    byte;

byte = bitnum /  BITS_PER_UNIT;
bit  = bitnum & (BITS_PER_UNIT - 1);
map[byte] |= 1 << bit;
}

/***********************************************************************/
/* bit_get:                                                            */
/*          Retrieve the state of a bit in the specified bitmap.       */
/*                                                                     */
/*      INPUTS:                                                        */
/*          map map pointer to use                                     */
/*          bitnum bit number                                          */
/*                                                                     */
/*     RETURNS:                                                        */
/*          bit value                                                  */
/*                                                                     */
/***********************************************************************/
static UINT bit_get(UCHAR *map, UINT bitnum)
{
UINT    bit;
UINT    byte;

byte = bitnum /  BITS_PER_UNIT;
bit  = bitnum & (BITS_PER_UNIT - 1);

if (map[byte] & (1 << bit))
     return 1;
else return 0;
}

⌨️ 快捷键说明

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