?? dpram8xx.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 + -