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

📄 tlb.c

📁 MIPS下的boottloader yamon 的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:

/************************************************************************
 *
 *  tlb.c
 *
 *  Monitor command for displaying and setting TLB.
 *
 *  tlb -i | [ <index> <pagesize> 
 *	       <va> <g> <asid>
 *	       <pa0> <c0> <d0> <v0>
 *	       <pa1> <c1> <d1> <v1> ]
 *
 *
 * ######################################################################
 *
 * Copyright (c) 1999-2000 MIPS Technologies, Inc. All rights reserved. 
 * 
 * Unpublished rights reserved under the Copyright Laws of the United States of 
 * America. 
 * 
 * This document contains information that is proprietary to MIPS Technologies, 
 * Inc. ("MIPS Technologies"). Any copying, modifying or use of this information 
 * (in whole or in part) which is not expressly permitted in writing by MIPS 
 * Technologies or a contractually-authorized third party is strictly 
 * prohibited. At a minimum, this information is protected under unfair 
 * competition laws and the expression of the information contained herein is 
 * protected under federal copyright laws. Violations thereof may result in 
 * criminal penalties and fines. 
 * MIPS Technologies or any contractually-authorized third party reserves the 
 * right to change the information contained in this document to improve 
 * function, design or otherwise. MIPS Technologies does not assume any 
 * liability arising out of the application or use of this information. Any 
 * license under patent rights or any other intellectual property rights owned 
 * by MIPS Technologies or third parties shall be conveyed by MIPS Technologies 
 * or any contractually-authorized third party in a separate license agreement 
 * between the parties. 
 * The information contained in this document constitutes one or more of the 
 * following: commercial computer software, commercial computer software 
 * documentation or other commercial items. If the user of this information, or 
 * any related documentation of any kind, including related technical data or 
 * manuals, is an agency, department, or other entity of the United States 
 * government ("Government"), the use, duplication, reproduction, release, 
 * modification, disclosure, or transfer of this information, or any related 
 * documentation of any kind, is restricted in accordance with Federal 
 * Acquisition Regulation 12.212 for civilian agencies and Defense Federal 
 * Acquisition Regulation Supplement 227.7202 for military agencies. The use of 
 * this information by the Government is further restricted in accordance with 
 * the terms of the license agreement(s) and/or applicable contract terms and 
 * conditions covering this information from MIPS Technologies or any 
 * contractually-authorized third party. 
 *
 ************************************************************************/


/************************************************************************
 *  Include files
 ************************************************************************/

#include <sysdefs.h>
#include <sys_api.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <shell_api.h>
#include <syscon_api.h>
#include <mips.h>
#include "shell.h"

/************************************************************************
 *  Definitions
 ************************************************************************/

typedef struct
{
    bool   read;
    UINT8  index;
    UINT32 pagemask;
    UINT32 vpn;
    UINT32 asid;
    bool   global;
    UINT32 pfn[2];
    UINT8  cache[2];
    bool   dirty[2];
    bool   valid[2];
}
t_tlb_setup;

#define TLB_MAX_ASID		(C0_ENTRYHI_ASID_MSK >> C0_ENTRYHI_ASID_SHF)
#define TLB_MAX_C		(C0_ENTRYLO0_C_MSK   >> C0_ENTRYLO0_C_SHF)
#define TLB_MAX_D		(C0_ENTRYLO0_D_MSK   >> C0_ENTRYLO0_D_SHF)
#define TLB_MAX_V		(C0_ENTRYLO0_V_MSK   >> C0_ENTRYLO0_V_SHF)
#define TLB_MAX_GLOBAL		(C0_ENTRYLO0_G_MSK   >> C0_ENTRYLO0_G_SHF)


/************************************************************************
 *  Public variables
 ************************************************************************/

/************************************************************************
 *  Static variables
 ************************************************************************/

/* OPTIONS */
static t_cmd_option options[] =
{ 
#define OPTION_INIT	0
  { "i",  "Initialise TLB" }
};
#define OPTION_COUNT	(sizeof(options)/sizeof(t_cmd_option))

static UINT8 tlb_entries;

/************************************************************************
 *  Static function prototypes
 ************************************************************************/

static UINT32 
get_options(
    UINT32      argc,
    char        **argv,
    bool	*init,
    t_tlb_setup *tlb_setup );

static bool
set_flag(
    bool	   *flag,
    t_shell_option *decode );

static bool
get_size(
    UINT32	   *pagesize, 
    t_shell_option *decode );

static bool
size2mask(
    UINT32 pagesize,
    UINT32 *mask );

static bool
mask2size(
    UINT32 mask,
    UINT32 *pagesize );

static void
do_init( void );

static void
do_tlb( 
    t_tlb_setup *tlb_setup );

/************************************************************************
 *  Implementation : Static functions
 ************************************************************************/

/************************************************************************
 *                          tlb
 ************************************************************************/
static MON_FUNC(tlb)
{
    UINT32      rc;
    bool	tlb_avail;
    t_tlb_setup tlb_setup;
    bool	init;

    SYSCON_read( SYSCON_CPU_TLB_AVAIL_ID,
		 (void *)&tlb_avail,
		 sizeof(bool) );

    if( !tlb_avail )
    {
        printf( "No TLB\n" );
	return OK;
    }
    else
    {
        SYSCON_read( SYSCON_CPU_TLB_COUNT_ID,
		     (void *)&tlb_entries,
		     sizeof(UINT8) );
    }

    rc = get_options( argc, argv, &init, &tlb_setup );

    if( rc != OK )
        return rc;
    else
    {
        if( init )
	{
	    do_init();
        }
	else
	{
	    do_tlb( &tlb_setup );
	}
	return OK;
    }
}


/************************************************************************
 *                          get_options
 ************************************************************************/
static UINT32
get_options(
    UINT32      argc,
    char        **argv,
    bool	*init,
    t_tlb_setup *tlb_setup )
{
    t_shell_option decode;
    UINT32	   type;
    UINT32	   arg;
    UINT32	   pagesize;
    UINT32	   error = SHELL_ERROR_SYNTAX;
    bool	   ok    = TRUE;

    /* Default */
    *init = FALSE;

    /* TBD : Add alignment check for PA and VA */

    if( argc == 1)
    {
        tlb_setup->read = TRUE;
	return OK;
    }

    if( (argc != 2) && (argc != 14) )
    {
        return error;
    }
    else
        tlb_setup->read = FALSE;

    for( arg = 1; 
	          ok && 
	          (arg < argc) && 
                  shell_decode_token( argv[arg], &type, &decode );
         arg++ )
    {
	switch( type )
	{
	  case SHELL_TOKEN_OPTION :
	    if( (arg != 1) || (argc != 2) )
	        ok = FALSE;
	    else if( strcmp( decode.option, options[0].option ) == 0 )
	    {
	        *init = TRUE;
	    }
	    else
	    {
	        error	         = SHELL_ERROR_OPTION;
	        shell_error_data = argv[arg];
	        ok		 = FALSE;
	    }
	    break;

	  case SHELL_TOKEN_STRING :

	    switch( arg )
	    {
	      case 2 : 
	        /* Pagesize */
		ok = get_size( &pagesize, &decode );

		if( ok && !size2mask( pagesize, &tlb_setup->pagemask ) )
		{
		    error = SHELL_ERROR_TLB_PAGESIZE;
		    ok    = FALSE;
		}
		break;
	      case 4 :
	        /* Global */
		ok = set_flag( &tlb_setup->global, &decode );
		if( !ok )
		    error = SHELL_ERROR_TLB_GLOBAL;
		break;
	      case 8 :
	        /* D0 */
		ok = set_flag( &tlb_setup->dirty[0], &decode );
		if( !ok )
		    error = SHELL_ERROR_TLB_D;
		break;
	      case 9 :
	        /* V0 */
		ok = set_flag( &tlb_setup->valid[0], &decode );
		if( !ok )
		    error = SHELL_ERROR_TLB_V;
		break;
	      case 12 :
	        /* D1 */
		ok = set_flag( &tlb_setup->dirty[1], &decode );
		if( !ok )
		    error = SHELL_ERROR_TLB_D;
		break;
	      case 13 :
	        /* V1 */
		ok = set_flag( &tlb_setup->valid[1], &decode );
		if( !ok )
		    error = SHELL_ERROR_TLB_V;
		break;
	      default :
	        ok = FALSE;
		break;
	    }

	    break;

	  case SHELL_TOKEN_NUMBER :

	    switch( arg )
	    {
	      case 1 : 
	        /* Index */
		if( argc == 2 )
		    ok = FALSE;
		else if( decode.number >= tlb_entries )
		{
		    error = SHELL_ERROR_TLB_INDEX;
		    ok    = FALSE;
		}
		else
	            tlb_setup->index = decode.number;
		break;
	      case 2 : 
	        /* Pagesize */
		pagesize = decode.number;
		
		if( !size2mask( pagesize, &tlb_setup->pagemask ) )
		{
		    error = SHELL_ERROR_TLB_PAGESIZE;
		    ok    = FALSE;
		}
		break;
	      case 3 : 
	        /* VA */
                tlb_setup->vpn = decode.number & C0_ENTRYHI_VPN2_MSK;
		break;
	      case 5 :
	        /* ASID */
		if( decode.number > TLB_MAX_ASID )
		{
		    error = SHELL_ERROR_TLB_ASID;
		    ok    = FALSE;
		}
		else
		    tlb_setup->asid = decode.number;
		break;
	      case 6 :
	        /* PFN0 */
	        tlb_setup->pfn[0] = decode.number >> 12;
		break;
	      case 7 :
	        /* C0 */
		if( decode.number > TLB_MAX_C )
		{
		    error = SHELL_ERROR_TLB_C;
		    ok    = FALSE;
		}
		else
		    tlb_setup->cache[0] = decode.number;
		break;
	      case 10 :
	        /* PFN1 */
	        tlb_setup->pfn[1] = decode.number >> 12;
		break;
	      case 11 :
	        /* C1 */
		if( decode.number > TLB_MAX_C )
		{
		    error = SHELL_ERROR_TLB_C;
		    ok    = FALSE;
		}
		else
		    tlb_setup->cache[1] = decode.number;
		break;
	      default :
	        ok = FALSE;
		break;
            }

	    break;

	  default :
	    ok = FALSE;
	    break;
        }
    }

    return ok ? OK : error;
}


/************************************************************************
 *                          set_flag
 ************************************************************************/
static bool
set_flag(
    bool	   *flag,
    t_shell_option *decode )
{
    char ch;

    if( strlen( decode->string ) != 1 )
        return FALSE;

    ch = tolower( *decode->string );

    if( ch == 'y' )
    {
        *flag = TRUE;
	return TRUE;
    }

⌨️ 快捷键说明

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