📄 pxa_memory.c
字号:
/******************************************************************************
**
** COPYRIGHT (C) 2000, 2001 Intel Corporation.
**
** This software as well as the software described in it is furnished under
** license and may only be used or copied in accordance with the terms of the
** license. The information in this file is furnished for informational use
** only, is subject to change without notice, and should not be construed as
** a commitment by Intel Corporation. Intel Corporation assumes no
** responsibility or liability for any errors or inaccuracies that may appear
** in this document or any software that may be provided in association with
** this document.
** Except as permitted by such license, no part of this document may be
** reproduced, stored in a retrieval system, or transmitted in any form or by
** any means without the express written consent of Intel Corporation.
**
** FILENAME: memory.c
**
** PURPOSE: This file contains the memory tests used for the Power-On
** Self Test (POST).
**
** LAST MODIFIED: $Modtime: 2/13/04 2:32p $
******************************************************************************/
/*
*******************************************************************************
* HEADER FILES
*******************************************************************************
*/
#include <stdio.h>
#include <string.h>
#include "systypes.h"
#include "dm_errors.h"
#include "cotulla.h"
#include "platform.h"
#include "memory.h"
#include "XsDmaApi.h"
#include "serialCommon.h"
#include "DM_Debug.h"
#include "mallocx.h"
#include "ROS.h"
/*
********************************************************************************
* LOCAL DEFINITIONS
*******************************************************************************
*/
static INT testFailed;
/*
*******************************************************************************
*
* FUNCTION:
* GetParameters
*
* DESCRIPTION:
* This routine parses the input string to determine the memory test
* configuration.
*
* INPUT PARAMETERS:
* PCHAR arg - Pointer to the input string.
* PUINT pa - Pointer to the physical address to test.
* PUINT length - Pointer to the length of the address to test.
*
* RETURNS:
* UINT - status of operation.
*
* GLOBAL EFFECTS:
* None.
*
* ASSUMPTIONS:
* None.
*
* CALLS:
* SSCANF, PhysicalToVirtual, DM_ErrPrintf, LOGERROR, DM_DbgPrintf
*
* CALLED BY:
* Memory test routines.
*
* PROTOTYPE:
* static
* UINT GetParameters(PCHAR arg, PUINT pa, PUINT length);
*
*******************************************************************************
*/
static
UINT GetParameters(PCHAR arg, PUINT vtAddrP, PUINT phAddrP, PUINT length)
{
UINT loggedError = 0;
CHAR type[80];
// Clear the return parameters.
*vtAddrP = 0;
DM_CwDbgPrintf(DM_CW_MEM," Parameter: %s", arg);
strcpy(type, arg);
PostDisplayProgress(ERR_L_MEMORY, ERR_TS_MEMORY, 1);
// Now check for SRAM valid parameters
if (!strcmp("SRAM", type))
{
PostDisplayProgress(ERR_L_MEMORY, ERR_TS_MEMORY, 2);
// Run full range with MMU enabled.
*vtAddrP = *phAddrP = SRAM_TEST_OFFSET;
PostDisplayProgress(ERR_L_MEMORY, ERR_TS_MEMORY, 3);
// Test the whole memory.
PostDisplayProgress(ERR_L_MEMORY, ERR_TS_MEMORY, 4);
*length = SRAM_TEST_LENGTH;
}
// Now check for Cached SDRAM valid parameters
else if (!strcmp("SDRAM_CACHEDBUFFERED", type))
{
PostDisplayProgress(ERR_L_MEMORY, ERR_TS_MEMORY, 5);
// Run full range with MMU enabled.
*phAddrP = (UINT32)malloc(-1);
*vtAddrP = (UINT32)malloc_cb((PVOID)*phAddrP);
// Test the whole memory.
*length = mallocSize((PVOID)*phAddrP);
free((PVOID)*phAddrP); // This is bad, Shouldn't "free" this early!
*phAddrP = *vtAddrP;
PostDisplayProgress(ERR_L_MEMORY, ERR_TS_MEMORY, 6);
DM_CwDbgPrintf(DM_CW_MEM," Length of test: %08x", *length);
}
// Now check for Cached SDRAM valid parameters
else if (!strcmp("SDRAM_CACHED", type))
{
PostDisplayProgress(ERR_L_MEMORY, ERR_TS_MEMORY, 5);
// Run full range with MMU enabled.
*phAddrP = (UINT32)malloc(-1);
*vtAddrP = (UINT32)malloc_cx((PVOID)*phAddrP);
// Test the whole memory.
*length = mallocSize((PVOID)*phAddrP);
free((PVOID)*phAddrP); // This is bad, Shouldn't "free" this early!
*phAddrP = *vtAddrP;
PostDisplayProgress(ERR_L_MEMORY, ERR_TS_MEMORY, 6);
DM_CwDbgPrintf(DM_CW_MEM," Length of test: %08x", *length);
}
// Now check for Non-Cached SDRAM valid parameters
else if (!strcmp("SDRAM", type))
{
PostDisplayProgress(ERR_L_MEMORY, ERR_TS_MEMORY, 7);
// Run full range with MMU enabled.
*vtAddrP = *phAddrP = (UINT32)malloc(0x200000);//-1); //hzh, test 2M only
// Test the whole memory.
*length = mallocSize((PVOID)*phAddrP);
free((PVOID)*phAddrP); // This is bad, Shouldn't "free" this early!
PostDisplayProgress(ERR_L_MEMORY, ERR_TS_MEMORY, 8);
DM_CwDbgPrintf(DM_CW_MEM," Length of test: %08x", *length);
}
else
{
LOGERROR(loggedError, ERR_L_MEMORY, ERR_TS_MEMORY, ERR_T_ILLPARAM, 0, 0, 0);
XllpUtilityOutputError(loggedError);
return (loggedError);
}
DM_CwDbgPrintf(DM_CW_MEM," Address of memory tested: %08x", *vtAddrP);
DM_CwDbgPrintf(DM_CW_MEM," Length of test: %08x", *length);
return (0);
}
static
VOID DisplayMemTestProgess(PCHAR arg, PCHAR testName, UINT phAddr, UINT length)
{
CHAR type[80];
if (!strcmp("SDRAM_CACHED", arg))
strcpy(type, "Cached/Non-Buffered SDRAM,");
else if (!strcmp("SDRAM_CACHEDBUFFERED", arg))
strcpy(type, "Cached/Buffered SDRAM,");
else if (!strcmp("SDRAM", arg))
strcpy(type, "Non-Cached/Non-Buffered SDRAM,");
else if (!strcmp("SRAM", arg))
strcpy(type, "SRAM,");
printf (" Testing %s %s %08x to %08x\r\n", type, testName, phAddr, (phAddr + length));
}
/*
*******************************************************************************
*
* FUNCTION:
* MemoryAddressLines
*
* DESCRIPTION:
* This routine tests each of the address lines associated with the memory
* region under test.
*
* INPUT PARAMETERS:
* PVOID ctxP - Pointer to the memory context structure (NULL).
* PCHAR arg - Pointer to the input string.
*
* RETURNS:
* None.
*
* GLOBAL EFFECTS:
* Tests each address line within the memory region.
*
* ASSUMPTIONS:
* The memory region has been mapped to actual RAM.
*
* CALLS:
* PlatformLeds, DM_StartTest, DM_DbgPrintf, GetParameters,
* DM_ErrPrintf, LOGERROR, DM_FinishTest.
*
* CALLED BY:
* Menu system or User script.
*
* PROTOTYPE:
* VOID MemoryAddressLines(PVOID ctxP, PCHAR arg);
*
*******************************************************************************
*/
VOID MemoryAddressLines(PVOID ctxP, PCHAR arg)
{
register PVUINT p, e;
UINT memVtAddr;
UINT memPhAddr;
UINT address;
UINT length;
UINT loggedError = 0;
UINT j;
CHAR testName[64];
sprintf (testName, "Address lines");
PostDisplayProgress(ERR_L_MEMORY, ERR_TS_MEMADDR, 1);
// Get the parameters needed to test memory.
if (GetParameters(arg, &memVtAddr, &memPhAddr, &length))
{
testFailed = TRUE;
return;
}
DisplayMemTestProgess(arg, testName, memPhAddr, length);
PostDisplayProgress(ERR_L_MEMORY, ERR_TS_MEMADDR, 2);
e = (PVUINT)(memVtAddr+length);
// Clear all memory.
for (p = (PVUINT)memVtAddr; p < e; p++)
{
// Zero memory.
*p = 0;
if (!((UINT32)p&0xfffff)) ROS_Release();
}
PostDisplayProgress(ERR_L_MEMORY, ERR_TS_MEMADDR, 3);
// Start at 0.
j = 0;
p = (PVUINT)memVtAddr;
// Write to every address line.
while (p < e)
{
// Store the data pattern.
*p = (UINT)p;
// Adjust shift count.
j++;
// Make sure address is on a LONG WORD boundary.
if (j < 2)
{
// Force address to be on a LONG WORD boundary.
j = 2;
}
// Generate the address pattern.
address = 1 << j;
// Calculate the target address.
p = (PVUINT)(memVtAddr + address);
}
PostDisplayProgress(ERR_L_MEMORY, ERR_TS_MEMADDR, 4);
// Start at 0.
j = 0;
p = (PVUINT)memVtAddr;
// Verify the data written.
while (p < e)
{
// Check the data.
if (*p != (UINT)p)
{
// Failure!
break;
}
// Adjust shift count.
j++;
// Make sure address is on a LONG WORD boundary.
if (j < 2)
{
// Force address to be on a LONG WORD boundary.
j = 2;
}
// Generate the address pattern.
address = 1 << j;
// Calculate the target address.
p = (PVUINT)(memVtAddr + address);
}
if ((UINT)p < (memVtAddr + length -1))
{
DM_CwDbgPrintf(DM_CW_MEM, " Failed at %08x, wrote: %08x, read: %08x",
(UINT)p, (UINT)p, (UINT)*p);
LOGERROR(loggedError, ERR_L_SDRAM, ERR_TS_MEMADDR,
ERR_T_WRONG_VALUE, (UINT)p, (UINT)p, *p);
XllpUtilityOutputError(loggedError);
testFailed = TRUE;
return;
}
PostDisplayProgress(ERR_L_MEMORY, ERR_TS_MEMADDR, 5);
testFailed = FALSE;
printf(" Success!\r\n");
}
/*
*******************************************************************************
*
* FUNCTION:
* MemoryWalking1
*
* DESCRIPTION:
* This routine sets each bit of each location within the memory region
* under test.
*
* INPUT PARAMETERS:
* PVOID ctxP - Pointer to the memory context structure (NULL).
* PCHAR arg - Pointer to the input string.
*
* RETURNS:
* None.
*
* GLOBAL EFFECTS:
* Tests each bit within the memory region.
*
* ASSUMPTIONS:
* The memory region has been mapped to actual RAM.
*
* CALLS:
* PlatformLeds, DM_StartTest, DM_DbgPrintf, GetParameters,
* DM_ErrPrintf, LOGERROR, DM_FinishTest.
*
* CALLED BY:
* Menu system or User script.
*
* PROTOTYPE:
* VOID MemoryWalking1(PVOID ctxP, PCHAR arg);
*
*******************************************************************************
*/
VOID MemoryWalking1(PVOID ctxP, PCHAR arg)
{
register PVUINT p, e;
register UINT mask;
UINT memVtAddr;
UINT memPhAddr;
UINT length;
UINT loggedError = 0;
UINT j;
CHAR testName[64];
sprintf (testName, "1's pattern");
PostDisplayProgress(ERR_L_MEMORY, ERR_TS_SDRAM_WO, 1);
// Get the parameters needed to test memory.
if (GetParameters(arg, &memVtAddr, &memPhAddr, &length))
{
testFailed = TRUE;
return;
}
PostDisplayProgress(ERR_L_MEMORY, ERR_TS_SDRAM_WO, 2);
DisplayMemTestProgess(arg, testName, memPhAddr, length);
e = (PVUINT)(memVtAddr+length);
// Walk a 1 thru the memory
for (j = 0; j < 32; j++)
{
// Shifting bit position.
mask = 1 << j;
PlatformLeds(mask);
// Write the pattern thru the memory range.
for (p = (PVUINT)memVtAddr; p < e; p++)
{
// Write the data.
*p = mask;
// Shifting bit position.
if ((mask <<= 1) == 0) mask = 1;
if (!((UINT32)p&0xfffff)) ROS_Release();
}
// Shifting bit position.
mask = 1 << j;
// Verify the pattern thru the memory range.
for (p = (PVUINT)memVtAddr; p < e; p++)
{
// Check the data written.
if (*p != mask) break;
// Shifting bit position.
if ((mask <<= 1) == 0) mask = 1;
if (!((UINT32)p&0x3ffff)) ROS_Release();
}
if (p < e) {
DM_CwDbgPrintf(DM_CW_MEM, " Failed at %08x, wrote: %08x, read: %08x",
p, mask, *p);
LOGERROR(loggedError, ERR_L_SDRAM, ERR_TS_SDRAM_WO,
ERR_T_WRONG_VALUE, (UINT32)p, mask, *p);
XllpUtilityOutputError(loggedError);
testFailed = TRUE;
return;
}
}
PostDisplayProgress(ERR_L_MEMORY, ERR_TS_SDRAM_WO, 3);
testFailed = FALSE;
printf (" Success!\r\n");
}
/*
*******************************************************************************
*
* FUNCTION:
* MemoryWalking0
*
* DESCRIPTION:
* This routine clears each bit of each location within the memory region
* under test.
*
* INPUT PARAMETERS:
* PVOID ctxP - Pointer to the memory context structure (NULL).
* PCHAR arg - Pointer to the input string.
*
* RETURNS:
* None.
*
* GLOBAL EFFECTS:
* Tests each bit within the memory region.
*
* ASSUMPTIONS:
* The memory region has been mapped to actual RAM.
*
* CALLS:
* PlatformLeds, DM_StartTest, DM_DbgPrintf, GetParameters,
* DM_ErrPrintf, LOGERROR, DM_FinishTest.
*
* CALLED BY:
* Menu system or User script.
*
* PROTOTYPE:
* VOID MemoryWalking0(PVOID ctxP, PCHAR arg);
*
*******************************************************************************
*/
VOID MemoryWalking0(PVOID ctxP, PCHAR arg)
{
register PVUINT p, e;
register UINT mask;
UINT memVtAddr;
UINT memPhAddr;
UINT length;
UINT loggedError = 0;
UINT j;
CHAR testName[64];
sprintf (testName, "0's pattern");
PostDisplayProgress(ERR_L_MEMORY, ERR_TS_SDRAM_WZ, 1);
// Get the parameters needed to test memory.
if (GetParameters(arg, &memVtAddr, &memPhAddr, &length))
{
testFailed = TRUE;
return;
}
PostDisplayProgress(ERR_L_MEMORY, ERR_TS_SDRAM_WZ, 2);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -