📄 tlb.c
字号:
/************************************************************************ * * tlb.c * * Monitor command for displaying and setting TLB. * * tlb -i [-s] (-s only for MIPS32/64 Release 2 CPUs) * * or * * tlb [ <index> <pagesize> * <va> <g> <asid> * <pa0> <c0> <d0> <v0> * <pa1> <c1> <d1> <v1> ] * * ###################################################################### * * mips_start_of_legal_notice * * Copyright (c) 2004 MIPS Technologies, Inc. All rights reserved. * * * Unpublished rights (if any) reserved under the copyright laws of the * United States of America and other countries. * * This code is proprietary to MIPS Technologies, Inc. ("MIPS * Technologies"). Any copying, reproducing, modifying or use of this code * (in whole or in part) that is not expressly permitted in writing by MIPS * Technologies or an authorized third party is strictly prohibited. At a * minimum, this code is protected under unfair competition and copyright * laws. Violations thereof may result in criminal penalties and fines. * * MIPS Technologies reserves the right to change this code to improve * function, design or otherwise. MIPS Technologies does not assume any * liability arising out of the application or use of this code, or of any * error or omission in such code. Any warranties, whether express, * statutory, implied or otherwise, including but not limited to the implied * warranties of merchantability or fitness for a particular purpose, are * excluded. Except as expressly provided in any written license agreement * from MIPS Technologies or an authorized third party, the furnishing of * this code does not give recipient any license to any intellectual * property rights, including any patent rights, that cover this code. * * This code shall not be exported, reexported, transferred, or released, * directly or indirectly, in violation of the law of any country or * international law, regulation, treaty, Executive Order, statute, * amendments or supplements thereto. Should a conflict arise regarding the * export, reexport, transfer, or release of this code, the laws of the * United States of America shall be the governing law. * * This code constitutes one or more of the following: commercial computer * software, commercial computer software documentation or other commercial * items. If the user of this code, 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 code, 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 code 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 code from MIPS Technologies or an authorized * third party. * * * * * mips_end_of_legal_notice * * ************************************************************************//************************************************************************ * 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 (M_EntryHiASID >> S_EntryHiASID)#define TLB_MAX_C (M_EntryLoC >> S_EntryLoC)#define TLB_MAX_D (M_EntryLoD >> S_EntryLoD)#define TLB_MAX_V (M_EntryLoV >> S_EntryLoV)#define TLB_MAX_GLOBAL (M_EntryLoG >> S_EntryLoG)/************************************************************************ * Public variables ************************************************************************//************************************************************************ * Static variables ************************************************************************//* OPTIONS */static t_cmd_option options[] ={ #define OPTION_INIT 0 { "i", "Initialise TLB" },#define OPTION_SMALLPAGE 1 { "s", "Toggle small (1kB) page support" }};#define OPTION_COUNT_REL2 (sizeof(options)/sizeof(t_cmd_option))#define OPTION_COUNT_NOT_REL2 (sizeof(options)/sizeof(t_cmd_option)-1)static UINT32 option_count;static UINT8 tlb_entries;static bool smallpages;static UINT32 pagegrain;/************************************************************************ * Static function prototypes ************************************************************************/static UINT32 get_options( UINT32 argc, char **argv, bool *init, bool *toggle_smallpages, t_tlb_setup *tlb_setup );static boolset_flag( bool *flag, t_shell_option *decode );static boolget_size( UINT32 *pagesize, t_shell_option *decode );static boolsize2mask( UINT32 pagesize, UINT32 *mask );static boolmask2size( UINT32 mask, UINT32 *pagesize );static voiddo_init( bool toggle_smallpages );static voiddo_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, toggle_smallpages; 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) ); } /* Determine whether small pages are currently enabled */ if( sys_smallpage_support ) { rc = SYSCON_read( SYSCON_CPU_CP0_PAGEGRAIN_ID, (void *)&pagegrain, sizeof(UINT32) ); if( rc == OK ) { smallpages = (pagegrain & M_PageGrainESP) ? TRUE : FALSE; } } rc = get_options( argc, argv, &init, &toggle_smallpages, &tlb_setup ); if( rc != OK ) return rc; else { if( init ) { do_init( toggle_smallpages ); } else { do_tlb( &tlb_setup ); } return OK; }}/************************************************************************ * get_options ************************************************************************/static UINT32get_options( UINT32 argc, char **argv, bool *init, bool *toggle_smallpages, t_tlb_setup *tlb_setup ){ t_shell_option decode; UINT32 type; UINT32 arg; UINT32 pagesize; UINT32 error = SHELL_ERROR_SYNTAX; bool ok = TRUE; bool got_value = FALSE; bool got_option = FALSE; UINT32 i; /* Default */ *init = FALSE; *toggle_smallpages = FALSE; if( argc == 1) { tlb_setup->read = TRUE; return OK; } 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( got_value ) { ok = FALSE; } else { got_option = TRUE; /* Find match */ for(i=0; (i<option_count) && (strcmp(decode.option, options[i].option) != 0); i++) ; if( i == option_count ) i = 0xff; /* Make sure we hit default in below switch */ switch(i) { case OPTION_INIT : *init = TRUE; break; case OPTION_SMALLPAGE : *toggle_smallpages = TRUE; break; default : error = SHELL_ERROR_OPTION; shell_error_data = argv[arg]; ok = FALSE; break; } } break; case SHELL_TOKEN_STRING : if( got_option ) { ok = FALSE; } else { got_value = TRUE; 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 : if( got_option ) { ok = FALSE; } else { got_value = TRUE; switch( arg ) { case 1 : /* Index */ if( argc != 14 ) 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 : * * The Virtual address base (VA) must be aligned * to pagesize * 2. * We multiply by two since the VA specified must be * the even page of the even/odd pair that will be * setup. */ if( decode.number & tlb_setup->pagemask ) { error = SHELL_ERROR_ALIGN; ok = FALSE; } else tlb_setup->vpn = decode.number; 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 : * * The Physical address base must be aligned to pagesize. */ if( decode.number & (tlb_setup->pagemask >> 1) ) { error = SHELL_ERROR_ALIGN; ok = FALSE; } else tlb_setup->pfn[0] = decode.number >> (smallpages ? 10 : 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 : * * The Physical address base must be aligned to pagesize. */ if( decode.number & (tlb_setup->pagemask >> 1) ) { error = SHELL_ERROR_ALIGN; ok = FALSE; } else tlb_setup->pfn[1] = decode.number >> (smallpages ? 10 : 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; } } if( *toggle_smallpages && !(*init) ) ok = FALSE; return ok ? OK : error;}/************************************************************************ * set_flag ************************************************************************/static boolset_flag( bool *flag, t_shell_option *decode ){ char ch; if( strlen( decode->string ) != 1 ) return FALSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -