/*
 *  Copyright (c) 1996-2007 Digi International Inc., All Rights Reserved
 *
 *  This software contains proprietary and confidential information of Digi
 *  International Inc.  By accepting transfer of this copy, Recipient agrees
 *  to retain this software in confidence, to prevent disclosure to others,
 *  and to make no use of this software other than that for which it was
 *  delivered.  This is an unpublished copyrighted work of Digi International
 *  Inc.  Except as permitted by federal law, 17 USC 117, copying is strictly
 *  prohibited.
 *
 *  Restricted Rights Legend
 *
 *  Use, duplication, or disclosure by the Government is subject to
 *  restrictions set forth in sub-paragraph (c)(1)(ii) of The Rights in
 *  Technical Data and Computer Software clause at DFARS 252.227-7031 or
 *  subparagraphs (c)(1) and (2) of the Commercial Computer Software -
 *  Restricted Rights at 48 CFR 52.227-19, as applicable.
 *
 *  Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
 *
 * Description.
 * =======================================================================
 *  This file contains the code that sets up the NET+ARM chip selects.
 *  THE CODE IN THIS FILE MUST BE CUSTOMIZED TO SUPPORT YOUR APPLICATION
 *  HARDWARE.  The default implementation supports the NET+OS development
 *  boards.  These boards have flash attached to CS1, RAM attached to CS4,
 *  possibly more RAM attached to CS5, CS6 and CS7. The other chip selects CS0, 
 *  CS1 and CS2 have static memory (flash) or other peripherals attached, the 
 *  table in bsp.c defines the register settings for these chip selects.
 *
 * This uses definitions in the following files to configure the chip selects, 
 * carefully review these files before modifying this file.
 *      1. bsp.h: Defines for MMCR register (the SDRAM refresh rate).
 *      2. bsp.c: Tables which define SRAM (flash) chip select register settings.
 *      3. customize.ldr: (GNU) or customize.lx (Green Hills), linker directive
 *        files.
 *
 */

 /*
 * Edit History
 *
 * Date       Initials                Change description
 * 08/18/05   JZW                     Change autodoc for customizeSetupCS1 to more
 *                                    accurately reflect how it works
 */

/*
 * Do not attempt to trace registers before the C library is
 * setup.  The global variables used by the trace library will
 * be in an undefined state until after the C library has
 * initilized the data segement.
 */
#ifdef NA_REG_TRACE_ENABLED
    #ifdef _REG_DEF_H
        #error Trace code compiled into init code.
    #endif
    #undef NA_REG_TRACE_ENABLED
#endif

#include <Npttypes.h>
#include <reg_def.h>
#include <mc_reg.h>
#include <ncc_init.h>
#include <gen_def.h>
#include <errhndlr.h>
#include <sysClockApi.h>  
#include <cs.h>
#include <bsp_refs.h>
#include <bsp_sys.h>
#include "init_settings.h"
#include "ncc_init.h"

unsigned long heap_adjustment = 0;
/*ad*
 * The NET+OS BSP contains a set of functions that usually
 * need to be customized to support specific hardware.  The 
 * default implementations support the NET+OS development
 * boards.  You must modify them to support your application's
 * hardware.
 *
 * The customization hooks are located in the following files.
 * <list type="unordered">
 *      <item>cs.c contains the code that sets up the NET+ARM chip selects to
 *            support the memory parts on your board.  The default implementation
 *            sets up CS0 to support 2 Megs of flash, and CS1 and CS2 to support
 *            RAM. </item>
 *      <item>gpio.c contains the code that sets up the GPIO ports.  These need
 *            to be configured to support serial port functions, DMA handshake
 *            signals, LEDs, interrupt requests, or other I/O signals.</item>
 *      <item>dialog.c contains the code that displays the development board's
 *            configuration dialog.  Usually you should disable the dialog in most
 *            shipping applications.</item>
 *      <item>boardParams.c and aceParams.c contain functions that read and write
 *            to NVRAM.  You must update these functions to support your application's
 *            usage of NVRAM.</item>
 * </list>
 *
 *
 * @category BSP:BSP_CustomizationHooks
 * @since 6.0
 * @overview BSP Customization Hooks
 * @external
*ad*/


/*ad*
 * Value of the refresh rate in nano-seconds, you will
 * have to modify this to be the refresh rate specified for
 * your SDRAM, the value used for the development boards 
 * is 7.812 micro-seconds.  This is used in the file
 * cs.c to program the SDRAM memory controller registers.
 *
 * @since 6.1
 * @external
 * @category BSP:BSP_CustomizationHooks 
*ad*/
#define BSP_MPMC_REFRESH_RATE 7812 /* nano-seconds */

/*ad*
 * This function sets up the memory management control register (MMCR).
 * The MMCR controls the SDRAM refresh timing.
 *
 * This version of this function sets up the MMCR for the NET+OS
 * development board. The refresh rate is derived from the define
 * MPMC_REFRESH_RATE, you need to adjust this value to equal the
 * refresh rate of the SDRAM part you are using.  This is a default
 * refresh rate which already been setup, but you may want to optimize
 * this value.
 *
 * @note THIS CODE MUST BE CUSTOMIZED FOR YOUR BOARD.  The implementation
 * below is for NET+OS development boards only.  If you followed the 
 * NET+OS design guidelines in your H/W design, then you should be 
 * able to use this function as is for your H/W.
 *
 * This function will be called by ncc_init() before RAM has been
 * configured.  The stack will be located on internal RAM in the
 * NET+ARM.  You can only use stack variables.  Do not use global
 * or static variables.
 *
 *
 * @external
 * @category BSP:BSP_CustomizationHooks
 * @since 6.1
*ad*/
void customizeSetupMMCR(void)
{
    narm_write_reg(NA_MPMC_DYNAMIC_REFRESH, NA_MPMC_DYNAMIC_REFRESH_ADDR, 
                   refresh, MPMCDynamicRefresh);
}     

/*ad*
 * This function must setup CS0 (Static Memory).  CS0 will have its power up
 * value when this function is called, the table in the file bsp.c
 * is used to set the registers in the Memory Controller. CS0 has an optional
 * SRAM device connected to it.
 *
 * @note THIS CODE MUST BE CUSTOMIZED FOR YOUR BOARD.  The implementation
 * below is for NET+OS development boards only.
 *
 * This function will be called by ncc_init() before the C library has been
 * loaded.  You can only use stack variables.  Do not use global
 * or static variables.
 *
 * @external
 * @category BSP:BSP_CustomizationHooks
 * @since 6.0
*ad*/
void customizeSetupCS0(void) 
{

    if (NAStaticMemoryTable[CS_0_INDEX].enabled)
    {
        /* Configure the values for the PrimeCell MultiPort Memory Controller */
        narm_write_reg(NA_MPMC_STATIC_CONFIG0, NA_MPMC_STATIC_CONFIG0_ADDR, 
                       config, NAStaticMemoryTable[CS_0_INDEX].StaticConfig);

        narm_write_reg(NA_MPMC_STATIC_WAIT_WEN0, NA_MPMC_STATIC_WAIT_WEN0_ADDR, 
                       wen, NAStaticMemoryTable[CS_0_INDEX].StaticWaitWen);

        narm_write_reg(NA_MPMC_STATIC_WAIT_OEN0, NA_MPMC_STATIC_WAIT_OEN0_ADDR, 
                       oen, NAStaticMemoryTable[CS_0_INDEX].StaticWaitOen);

        narm_write_reg(NA_MPMC_STATIC_WAIT_RD0, NA_MPMC_STATIC_WAIT_RD0_ADDR, 
                       rd, NAStaticMemoryTable[CS_0_INDEX].StaticWaitRd);

        narm_write_reg(NA_MPMC_STATIC_WAIT_PAGE0, NA_MPMC_STATIC_WAIT_PAGE0_ADDR, 
                       page, NAStaticMemoryTable[CS_0_INDEX].StaticWaitPage);

        narm_write_reg(NA_MPMC_STATIC_WAIT_WR0, NA_MPMC_STATIC_WAIT_WR0_ADDR, 
                       wr, NAStaticMemoryTable[CS_0_INDEX].StaticWaitWr);

        narm_write_reg(NA_MPMC_STATIC_WAIT_TURN0, NA_MPMC_STATIC_WAIT_TURN0_ADDR, 
                       turn, NAStaticMemoryTable[CS_0_INDEX].StaticWaitTurn);

        /* Set the mask and base address for the chip select in the SCM. */
        narm_write_reg(NA_SCM_CS0_BASE, NA_SCM_CS0_BASE_ADDR,
                       addr, NAStaticMemoryTable[CS_0_INDEX].StaticBaseAddess);

        narm_write_reg(NA_SCM_CS0_MASK, NA_SCM_CS0_MASK_ADDR,
                       mask, NAStaticMemoryTable[CS_0_INDEX].StaticMask);
    }
}

/*ad*
 *  This function setups CS1 (flash ROM).  CS1 contains the flash
 *  code which the processor initially starts executing on bootstrap, 
 *  CS1 is preconfigured through the use of strapping pins. CS1 must always
 *  be connected to flash.  We get the size and starting address of flash
 *  from the linker directive file which is created from customize.ldr.
 *  This last sentence can not be emphasized enough. Due to the need for the
 *  linker to know the starting address and size of flash, this information 
 *  is accessed from the linker directive file. It is NOT accessed from the
 *  static memory table. If due to your application's requirements you need
 *  to change the starting address or the size of flash, please change them
 *  in file customize.ldr. Additionally, we have changed the function 
 *  customizeSetupCS1 accordingly. We have added an assert to look for changes
 *  made to these fields in the static memory table. Making changes to the
 *  starting memory address of flash in the static memory table will cause
 *  an abort.  
 *
 * @external
 * @category BSP:BSP_CustomizationHooks
 * @since 6.1
 *
 * @note This function will be called by ncc_init() before the C library has been
 * loaded.  You can only use stack variables.  Do not use global
 * or static variables.
*ad*/
void customizeSetupCS1(void) 
{
    int           memory_width;
    unsigned long flash_size, flash_start;

    /* if we are running from flash, we should use the flashSize in the linker file */
    if (nccRomImageBuild() == 1)
    {
        flash_size = (unsigned long)&_NABspFlashSize; /* flashSize specified from ld */
    }
    else
    {
        flash_size = (unsigned long)NABspFlashSize; /* software specifies the flash size */
        NA_ASSERT(flash_size != 0);
        if (flash_size == 0)                        /* if flash is disabled */
        {                                           /* use value from linker script */
            flash_size = (unsigned long)&_NABspFlashSize; 
        }
    }
    flash_start = (unsigned int)&_NABspFlashStart;

    /* The base address for flash is acquired from the linker directive file not from
	 * the static memory table. This assert checks to see whether the user has tried to
	 * update the chip select base address information via the static memory table. If
	 * the customer has, this assert will cause an abort. The base address for chip select
	 * 1 (one) shall remain as 0x0. To update the base address for chip select 1, update
	 * customize.ldr. The linker directive files are derived form customize.ldr.
	 */
    NA_ASSERT(NAStaticMemoryTable[CS_1_INDEX].StaticBaseAddess == 0x0);

    /* Configure the values for the PrimeCell MultiPort Memory Controller */
    narm_write_reg(NA_MPMC_STATIC_CONFIG1, NA_MPMC_STATIC_CONFIG1_ADDR, 
                   config, NAStaticMemoryTable[CS_1_INDEX].StaticConfig);

    narm_write_reg(NA_MPMC_STATIC_WAIT_WEN1, NA_MPMC_STATIC_WAIT_WEN1_ADDR, 
                   wen, NAStaticMemoryTable[CS_1_INDEX].StaticWaitWen);

    narm_write_reg(NA_MPMC_STATIC_WAIT_OEN1, NA_MPMC_STATIC_WAIT_OEN1_ADDR, 
                   oen, NAStaticMemoryTable[CS_1_INDEX].StaticWaitOen);

    narm_write_reg(NA_MPMC_STATIC_WAIT_RD1, NA_MPMC_STATIC_WAIT_RD1_ADDR, 
                   rd, NAStaticMemoryTable[CS_1_INDEX].StaticWaitRd);

    narm_write_reg(NA_MPMC_STATIC_WAIT_PAGE1, NA_MPMC_STATIC_WAIT_PAGE1_ADDR, 
                   page, NAStaticMemoryTable[CS_1_INDEX].StaticWaitPage);

    narm_write_reg(NA_MPMC_STATIC_WAIT_WR1, NA_MPMC_STATIC_WAIT_WR1_ADDR, 
                   wr, NAStaticMemoryTable[CS_1_INDEX].StaticWaitWr);

    narm_write_reg(NA_MPMC_STATIC_WAIT_TURN1, NA_MPMC_STATIC_WAIT_TURN1_ADDR, 
                   turn, NAStaticMemoryTable[CS_1_INDEX].StaticWaitTurn);

    /* Set base address of ROM, this is defined as FLASH_START in customize.ldr/lx */
    narm_write_reg(NA_SCM_CS1_BASE, NA_SCM_CS1_BASE_ADDR, addr, flash_start);


    /* Extract the memory width from the table */
    memory_width = NAStaticMemoryTable[CS_1_INDEX].StaticConfig & ~0xFFFFFFFC;

    /*
     * Set the mask for the chip select.  The mask determines the size of the
     * part.  Note that we set up the mask so that the part appears
     * in four places in the NET+ARM's address space.  This is done for
     * caching.
     */

    if (memory_width == STATIC_MEM_32_BIT)
    {
        narm_write_reg(NA_SCM_CS1_MASK, NA_SCM_CS1_MASK_ADDR,
                       mask, (customizeCreateMask(flash_size) | 1));
    }
    else if (memory_width == STATIC_MEM_16_BIT)
    {
        narm_write_reg(NA_SCM_CS1_MASK, NA_SCM_CS1_MASK_ADDR,
                        mask, (customizeCreateMask(flash_size) | 1));
    }
    else
    {
        /* Invalid static memory width! Read page 3-31 of the PL172 spec */
        return;
    }

}

/*ad*
 * This function must setup CS2 (Static).  The table in the file bsp.c
 * is used to set the registers in the Memory Controller. 
 *
 * @external
 * @category BSP:BSP_CustomizationHooks
 * @since 6.1
 *
 * @note THIS CODE MUST BE CUSTOMIZED FOR YOUR BOARD.  The implementation
 * below is for NET+OS development boards only.
 *
 * This function will be called by ncc_init() before the C library has been
 * loaded.  You can only use stack variables.  Do not use global
 * or static variables.
*ad*/
void customizeSetupCS2(void) 
{
    if (NAStaticMemoryTable[CS_2_INDEX].enabled)
    {
        /* Configure the values for the PrimeCell MultiPort Memory Controller */
        *NA_MPMCStaticExtendedWait_ADDRESS = 0x4; /* support Compact Flash memory mode */

        narm_write_reg(NA_MPMC_STATIC_CONFIG2, NA_MPMC_STATIC_CONFIG2_ADDR, 
                       config, NAStaticMemoryTable[CS_2_INDEX].StaticConfig);

        /* The following CS2 registers are the reset or power on values */
        narm_write_reg(NA_MPMC_STATIC_WAIT_WEN2, NA_MPMC_STATIC_WAIT_WEN2_ADDR, 
                       wen, NAStaticMemoryTable[CS_2_INDEX].StaticWaitWen);

        narm_write_reg(NA_MPMC_STATIC_WAIT_OEN2, NA_MPMC_STATIC_WAIT_OEN2_ADDR, 
                       oen, NAStaticMemoryTable[CS_2_INDEX].StaticWaitOen);

        narm_write_reg(NA_MPMC_STATIC_WAIT_RD2, NA_MPMC_STATIC_WAIT_RD2_ADDR, 
                       rd, NAStaticMemoryTable[CS_2_INDEX].StaticWaitRd);

        narm_write_reg(NA_MPMC_STATIC_WAIT_PAGE2, NA_MPMC_STATIC_WAIT_PAGE2_ADDR, 
                       page, NAStaticMemoryTable[CS_2_INDEX].StaticWaitPage);

        narm_write_reg(NA_MPMC_STATIC_WAIT_WR2, NA_MPMC_STATIC_WAIT_WR2_ADDR, 
                       wr, NAStaticMemoryTable[CS_2_INDEX].StaticWaitWr);

        narm_write_reg(NA_MPMC_STATIC_WAIT_TURN2, NA_MPMC_STATIC_WAIT_TURN2_ADDR, 
                       turn, NAStaticMemoryTable[CS_2_INDEX].StaticWaitTurn);

        /* Set the mask and base address for the chip select in the SCM. */
        narm_write_reg(NA_SCM_CS2_MASK, NA_SCM_CS2_MASK_ADDR,
                       mask, 0x0);

        narm_write_reg(NA_SCM_CS2_BASE, NA_SCM_CS2_BASE_ADDR,
                       addr, NAStaticMemoryTable[CS_2_INDEX].StaticBaseAddess);

        narm_write_reg(NA_SCM_CS2_MASK, NA_SCM_CS2_MASK_ADDR,
                       mask, NAStaticMemoryTable[CS_2_INDEX].StaticMask);
    }
}

/*ad*
 * This function must setup CS3 (Static).  CS3 will have its power up
 * value when this function is called, the table is bsp.c
 * is used to set the registers in the Memory Controller for this chip
 * select.
 *
 * @external
 * @category BSP:BSP_CustomizationHooks
 * @since 6.1
 *
 * @note  THIS CODE MUST BE CUSTOMIZED FOR YOUR BOARD.  The implementation
 * below is for NET+OS development boards only.
 *
 * This function will be called by ncc_init() before the C library has been
 * loaded.  You can only use stack variables.  Do not use global
 * or static variables.
 *
*ad*/
void customizeSetupCS3(void) 
{
    if (NAStaticMemoryTable[CS_3_INDEX].enabled)
    {
        /* Configure the values for the PrimeCell MultiPort Memory Controller */
        narm_write_reg(NA_MPMC_STATIC_CONFIG3, NA_MPMC_STATIC_CONFIG3_ADDR, 
                       config, NAStaticMemoryTable[CS_3_INDEX].StaticConfig);

        narm_write_reg(NA_MPMC_STATIC_WAIT_WEN3, NA_MPMC_STATIC_WAIT_WEN3_ADDR, 
                       wen, NAStaticMemoryTable[CS_3_INDEX].StaticWaitWen);

        narm_write_reg(NA_MPMC_STATIC_WAIT_OEN3, NA_MPMC_STATIC_WAIT_OEN3_ADDR, 
                       oen, NAStaticMemoryTable[CS_3_INDEX].StaticWaitOen);

        narm_write_reg(NA_MPMC_STATIC_WAIT_RD3, NA_MPMC_STATIC_WAIT_RD3_ADDR, 
                       rd, NAStaticMemoryTable[CS_3_INDEX].StaticWaitRd);

        narm_write_reg(NA_MPMC_STATIC_WAIT_PAGE3, NA_MPMC_STATIC_WAIT_PAGE3_ADDR, 
                       page, NAStaticMemoryTable[CS_3_INDEX].StaticWaitPage);

        narm_write_reg(NA_MPMC_STATIC_WAIT_WR3, NA_MPMC_STATIC_WAIT_WR3_ADDR, 
                       wr, NAStaticMemoryTable[CS_3_INDEX].StaticWaitWr);

        narm_write_reg(NA_MPMC_STATIC_WAIT_TURN3, NA_MPMC_STATIC_WAIT_TURN3_ADDR, 
                       turn, NAStaticMemoryTable[CS_3_INDEX].StaticWaitTurn);

        /* Set the mask and base address for the chip select in the SCM. */
        narm_write_reg(NA_SCM_CS3_BASE, NA_SCM_CS3_BASE_ADDR,
                       addr, NAStaticMemoryTable[CS_3_INDEX].StaticBaseAddess);

        narm_write_reg(NA_SCM_CS3_MASK, NA_SCM_CS3_MASK_ADDR,
                       mask, NAStaticMemoryTable[CS_3_INDEX].StaticMask);
    }
}


/*ad*
 * This function is called to customize cs4 (SDRAM), cs4 is initially setup in
 * in INIT.arm with the parameters from init_settings.h. So by default we don't need to
 * do anything here other than get the size from the configuration register MPMCDynamicConfig. 
 * The minimum size of the RAM on cs4 must be specified in the
 * file customize.ldr. The actual size of RAM is autosensed in INIT.arm 
 *
 * @external
 * @category BSP:BSP_CustomizationHooks:ARM9
 * @since 6.1
 * 
 * @note This function will be called by nccInit() before the C library has been
 * loaded.  You can only use stack variables.  Do not use global
 * or static variables before main(). After reach main(), this function is also called to setup the 
 * cache and is called by _sbrk() to setup heap extension.
 *
 * NET+OS supports a maximum of 256 Megabytes of RAM.  If more than 
 * that is used, then the cache driver will have to be adjusted.
 *
 * @param ramSize Pointer to in loaded with the amount of RAM on this chip select.  
 *
*ad*/
void customizeSetupCS4(unsigned int * ramSize) 
{
	
    unsigned int ram_size;
    unsigned long data_bus_width = (((*NA_MPMCDynamicConfig0_ADDRESS) >> 14) & 0x1)? 32: 16;
    unsigned long sdram_width = ((*NA_MPMCDynamicConfig0_ADDRESS) >> 7 ) & 0x3;
    unsigned long mem_size = ((*NA_MPMCDynamicConfig0_ADDRESS) >> 9) & 0x7;
    
  /* 
   * CS4 (RAM) settings are setup in INIT.arm. The parameters for cs4 are defined in 
   * init_settings.h, and the sized of the RAM is auto sensed in INIT.arm.
   */
   
#define CS_2MEG  CS_1_MEG*2 
#define CS_8MEG  CS_1_MEG*8
#define CS_16MEG  CS_1_MEG*16
#define CS_32MEG  CS_1_MEG*32
#define CS_64MEG  CS_1_MEG*64
  
    switch (sdram_width)
    {
    	case MEM_TYPE_x8:
    		sdram_width = 8;
    		break;
    	case MEM_TYPE_x16:
    		sdram_width = 16;
    		break;
    	case MEM_TYPE_x32:
    		sdram_width = 32;
    		break;
    	default:
    	        sdram_width = 16;
    	        break;
    	}
    	
    switch (mem_size)
    {
    	case MEM_SIZE_16Mb:
    	   	ram_size = CS_2MEG *(data_bus_width/sdram_width);
    	   	break;
    	   	
    	case MEM_SIZE_64Mb:
    	   	ram_size = CS_8MEG *(data_bus_width/sdram_width);
    	   	break;
    	   	
    	case MEM_SIZE_128Mb:
    	   	ram_size = CS_16MEG *(data_bus_width/sdram_width);
    	   	break;
    	   	
    	case MEM_SIZE_256Mb:
    	   	ram_size = CS_32MEG *(data_bus_width/sdram_width);
    	   	break;
    	   	
    	case MEM_SIZE_512Mb:
    	   	ram_size = CS_64MEG *(data_bus_width/sdram_width);
    	   	break;
    	   
    	default:
    	   	ram_size = (unsigned int)&_NABspRamSize;
    	   	break;
    	}
    	
    	/* adjust the heap size here */
    	if (ram_size > (unsigned int)&_NABspRamSize)
    	{
    		heap_adjustment = ram_size - (unsigned int)&_NABspRamSize ;
    	}
    	else
    	{
    		heap_adjustment = 0;
    	}
    	   	
   *ramSize = ram_size;

}

/*ad*
 * This function must setup CS5 (RAM), this routine must fill in the size
 * of the amount of RAM detected on this chip select.  This is then used
 * to create the memory map so that the address space is continous.
 *
 * @note This function will be called by ncc_init() before the C library has been
 * loaded.  You can only use stack variables.  Do not use global
 * or static variables.
 *
 * @external
 * @category BSP:BSP_CustomizationHooks
 * @since 6.1
 *
 * @param ramSize   pointer to in loaded with amount of RAM found on CS1.  
 *
*ad*/
void customizeSetupCS5(unsigned int * ramSize) 
{

    if (nccCheckIfRamExists(CS_5_DEFAULT_ADDR) == NCC_RAM_DETECTED)
    {
        /* See how big the RAM is */
        *ramSize = nccDetermineRamSize(CS_5_DEFAULT_ADDR, NA_CS5_MAX_SIZE, 
                                       (unsigned int)NA_SCM_CS5_BASE_ADDR, 
                                       (unsigned int)NA_SCM_CS5_MASK_ADDR); 

    }
    else
    {
        *ramSize = 0;
    }
}


/*ad*
 * This function must setup CS6 (RAM), this routine must fill in the size
 * of the amount of RAM detected on this chip select.  This is then used
 * to create the memory map so that the address space is continous.
 *
 * @note This function will be called by ncc_init() before the C library has been
 * loaded.  You can only use stack variables.  Do not use global
 * or static variables.
 *
 * @external
 * @category BSP:BSP_CustomizationHooks
 * @since 6.1
 *
 * @param ramSize   pointer to in loaded with amount of RAM found on CS1.  
*ad*/
void customizeSetupCS6(unsigned int * ramSize) 
{
    if (nccCheckIfRamExists(CS_6_DEFAULT_ADDR) == NCC_RAM_DETECTED)
    {
        /* See how big the RAM is */
        *ramSize = nccDetermineRamSize(CS_6_DEFAULT_ADDR, NA_CS6_MAX_SIZE, 
                                       (unsigned int)NA_SCM_CS6_BASE_ADDR, 
                                       (unsigned int)NA_SCM_CS6_MASK_ADDR); 
    }
    else
    {
        *ramSize = 0;
    }
}

/*ad*
 * This function must setup CS7 (RAM), this routine must fill in the size
 * of the amount of RAM detected on this chip select.  This is then used
 * to create the memory map so that the address space is continous.
 *
 * @note This function will be called by ncc_init() before the C library has been
 * loaded.  You can only use stack variables.  Do not use global
 * or static variables.
 *
 * @external
 * @category BSP:BSP_CustomizationHooks
 * @since 6.1
 *
 * @param ramSize   pointer to in loaded with amount of RAM found on CS1.  
*ad*/
void customizeSetupCS7(unsigned int * ramSize) 
{
    if (nccCheckIfRamExists(CS_7_DEFAULT_ADDR) == NCC_RAM_DETECTED)
    {
        /* See how big the RAM is */
        *ramSize = nccDetermineRamSize(CS_7_DEFAULT_ADDR, NA_CS7_MAX_SIZE, 
                                       (unsigned int)NA_SCM_CS7_BASE_ADDR, 
                                       (unsigned int)NA_SCM_CS7_MASK_ADDR); 
    }
    else
    {
        *ramSize = 0;
    }
}

/*ad*
 * This function creates an appropriate mask that can be written into 
 * the chip select mask register.  If the mask is used, it will setup
 * the chip select to support the amount of RAM indicated by the
 * parameter size.
 *
 * @external
 * @category BSP:BSP_CustomizationHooks
 * @since 6.1
 *
 * @note This function will be called by ncc_init() before the C library has been
 * loaded.  You can only use stack variables.  Do not use global
 * or static variables.
 *
 * @param size The number of bytes of RAM connected to the CS
 *
 * @return  Value for mask field of CSOR register
*ad*/
WORD32 customizeCreateMask(WORD32 size)
{
    unsigned int mask;

    mask = ~size + 1;               /* compute raw mask*/

    return mask;
}

/*ad*
 * This routine returns the total number of bytes of memory
 * the chip select is configured to support.  It does this
 * by examining the address mask in the CS option register.
 * This routine was written to support the NET+OS development
 * board and NET+OS.  NET+OS normally sets up the address 
 * masks so that a part's memory appears in the address space
 * four times.  This is done to support caching.  This function
 * takes this into account when it calculates the amount of
 * memory connected to the CS.
 *
 * @external
 * @category BSP:BSP_CustomizationHooks
 * @since 6.1
 *
 * @note THIS CODE MUST BE CUSTOMIZED FOR YOUR BOARD.  The implementation
 * below is for NET+OS development boards only.  You will need to
 * modify this function if you are using a nonstandard cache setup.
 *
 * This function will be called by ncc_init() before the C library has been
 * loaded.  You can only use stack variables.  Do not use global
 * or static variables.
 *
 * @param csBaseAddr        Address of the address register for this CS
 * @param csMaskRegAddr     Address of the option register for this CS
 *
 * @return The number of bytes of memory the CS is configured for
*ad*/
WORD32 customizeGetCSSize(WORD32 * csBaseAddr, WORD32 * csMaskRegAddr)
{
/*
 * THIS CODE MUST BE CUSTOMIZED FOR YOUR BOARD.  This implementation
 * is for NET+OS development boards only.
 */
    unsigned int mask, size = 0;

    NA_UNUSED_PARAM(csBaseAddr);

    mask = _narm_read_reg(csMaskRegAddr, NA_SCM_CS_MASK) & 0xFFFFF000;
    size = (~mask) + 1;                 /* determine the size of the part */

#ifdef DEBUG_NETOS
    mprintf("customizeGetCSSize: csMaskRegAddr [%X]\n", csMaskRegAddr);
    mprintf("customizeGetCSSize: mask [%X]\n", mask);
    mprintf("customizeGetCSSize: size [%X]\n", size);
#endif


    return size;
}

/*ad*
 *  This routine returns the total number of bytes of RAM on the board.
 *  This function is called if the BSP initialization code detects that
 *  the chip selects have already been configured due to a software restart.  
 *  Instead of reconfiguring them and possibly destroying variables in RAM, 
 *  the init code will call this function to determine how much RAM is on the
 *  board.
 *
 * @note This version is written to support NET+OS development boards.  These
 * boards have RAM on CS1, and possibly CS2.  We determine the amount
 * of RAM by examining the mask value in the option registers for these
 * chip selects.
 *
 * THIS CODE MUST BE CUSTOMIZED FOR YOUR BOARD.  The implementation
 * below is for NET+OS development boards only.
 *
 * This function will be called by ncc_init() before the C library has been
 * loaded.  You can only use stack variables.  Do not use global
 * or static variables.
 *
 * @external
 * @category BSP:BSP_CustomizationHooks
 * @since 6.1
 *
 *
 * @return The amount of available RAM in bytes
 *
*ad*/
WORD32 customizeGetRamSize(void)
{
/*
 * THIS CODE MUST BE CUSTOMIZED FOR YOUR BOARD.  This implementation
 * is for NET+OS development boards only.
 */
    unsigned int size;


    /*
     * RAM should be attached to CS4, CS5, CS6 and CS7, only CS4 is used on this platform.
     */
     size = 0;
     customizeSetupCS4(&size); 
    /*size  = customizeGetCSSize((WORD32 *)CS_4_DEFAULT_ADDR, 
                              (WORD32 *)NA_SCM_CS4_MASK_ADDR);

    size += customizeGetCSSize((WORD32 *)CS_5_DEFAULT_ADDR, 
                              (WORD32 *)NA_SCM_CS5_MASK_ADDR);

    size += customizeGetCSSize((WORD32 *)CS_6_DEFAULT_ADDR, 
                              (WORD32 *)NA_SCM_CS6_MASK_ADDR);

    size += customizeGetCSSize((WORD32 *)CS_7_DEFAULT_ADDR, 
                              (WORD32 *)NA_SCM_CS7_MASK_ADDR); */

        	
    return size;
}

/*ad*
 *  This function is called to update any CS1 after RAM and FLASH has initialized.
 *  This is usually called to update the actual size of the FLASH after flash driver
 *  is initialized.
 *
*ad*/
void customizeUpdateCS(void) 
{

    /* no need to update cs for flash if running from rom */    
    customizeSetupCS1() ;
    
#ifdef NETOS_DEBUG    
    mprintf("main: flash %X = %x\n", (unsigned) NA_SCM_CS1_MASK_ADDR, (unsigned) *NA_SCM_CS1_MASK_ADDR);
    mprintf("main: ram %X = %x\n", (unsigned) NA_SCM_CS4_MASK_ADDR, (unsigned) *NA_SCM_CS4_MASK_ADDR);
#endif
    
    return;

}

