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

📄 sys.c

📁 MIPS YAMON, a famous monitor inc. source, make file and PDF manuals.
💻 C
📖 第 1 页 / 共 2 页
字号:
    last = addr + (count - size);     if( last < addr )        return SHELL_ERROR_OVERFLOW;    SYSCON_read( SYSCON_CPU_TLB_AVAIL_ID,	         (void *)&sys_mmu_tlb,	         sizeof( bool ) );    if(      KUSEG( addr ) == addr ) range_start = R_KUSEG;    else if( KSEG0( addr ) == addr ) range_start = R_KSEG0;    else if( KSEG1( addr ) == addr ) range_start = R_KSEG1;    else if( KSSEG( addr ) == addr ) range_start = R_KSSEG;    else			     range_start = R_KSEG3;    switch( range_start )    {      case R_KUSEG :      case R_KSSEG :      case R_KSEG3 :        if( !sys_mmu_tlb )	{	    /* Assume Fixed Mapping MMU */	    /* Determine ERL setting */	    SYSCON_read( SYSCON_CPU_CP0_STATUS_ID,			 (void *)&erl,			 sizeof(UINT32) );	    erl &= M_StatusERL;            if( last < KSEG0BASE )	    {                /* Range contained within KUSEG */		if( !erl )		{		    addr += 0x40000000;		    last += 0x40000000;		}   	        return sys_validate_ram_range( addr, last );	    }	    else if( addr >= KSSEGBASE )	    {	        /* Range contained within KSSEG,KSEG3 */   	        return sys_validate_ram_range( addr, last );	    }	    else	    {                /* Range overflows KUSEG */	        rc = sys_validate_ram_range( 		         erl ? addr : addr + 0x40000000, 			 erl ? KSEG0BASE- size : KSEG0BASE - size + 0x40000000 );	      	        return ( rc != OK ) ?	            rc :	            /* Continue in KSEG0 */		    sys_validate_range( KSEG0BASE,				        count - (KSEG0BASE - addr),				        size,				        write );	    }	}	else	{	    /* MMU = TLB */	    switch( sys_tlb_lookup( addr, &phys, &pagesize ) )            {	      case SYS_TLB_WP :		if( write )		{                    sprintf( msg, "Address = 0x%08x", addr );	            shell_error_data = msg;		    return SHELL_ERROR_TLB_WP;		}		/* Fallthrough !! */   	      case SYS_TLB_OK :		rc = sys_validate_ram_range( phys, 					     phys + pagesize - size );		if( rc != OK )		   return rc;		addr += pagesize;		return ( addr > last ) ?		    OK :		    sys_validate_range( addr,					count - pagesize,					size,					write );		break;	      case SYS_TLB_NOTFOUND :	      case SYS_TLB_NOTVALID :	      default : /* Should not happen */                sprintf( msg, "Address = 0x%08x", addr );                shell_error_data = msg;	        return SHELL_ERROR_TLB;            }	}	break;      case R_KSEG0 :        if( KSEG0( last ) == last )	{            /* Range contained within KSEG0 */   	    return sys_validate_ram_range( PHYS(addr), PHYS(last) );        }	else	{            /* Range overflows KSEG0 */	    rc = sys_validate_ram_range( PHYS(addr), PHYS(KSEG1BASE-size) );	    return ( rc != OK ) ?	        rc :	        /* Continue in KSEG1 */		sys_validate_range( KSEG1BASE,				    count - (KSEG1BASE - addr),				    size,				    write );	}	break;      case R_KSEG1 :        if( KSEG1( last ) == last )	{            /* Range contained within KSEG1 */   	    return sys_validate_ram_range( PHYS(addr), PHYS(last) );        }	else	{            /* Range overflows KSEG1 */	    rc = sys_validate_ram_range( PHYS(addr), PHYS(KSSEGBASE-size) );	    return ( rc != OK ) ?	        rc :	        /* Continue in KSSEG */		sys_validate_range( KSSEGBASE,				    count - (KSSEGBASE - addr),				    size,				    write );	}	break;    }    return OK; /* Should never reach this point */}/************************************************************************ * *                          sys_kseg0 *  Description : *  ------------- * *  Determine KSEG0 address corresponding to input address. *  *  In case input address is TLB mapped, a lookup is performed in the *  TLB to determine the physical address. Then, the corresponding *  KSEG0 address is calculated. * *  In case input address is in KSEG1 range, it is converted to KSEG0. * *  In case of fixed mapping TLB, a KUSEG address is mapped to a *  corresponding KSEG0 address based on the ERL setting. * *  Return values : *  --------------- * *  TRUE if conversion was successfull, otherwise FALSE * ************************************************************************/boolsys_kseg0(    UINT32 addr,		/* Address to be converted		*/    UINT32 *kseg0addr )		/* OUT : Converted address		*/{    UINT32 phys, pagesize;    bool   sys_mmu_tlb;    UINT32 erl;    SYSCON_read( SYSCON_CPU_TLB_AVAIL_ID,                 (void *)&sys_mmu_tlb,	         sizeof( bool ) );    if( sys_mmu_tlb )    {        /* MMU = TLB */        if( (KSEG0( addr ) == addr) || (KSEG1( addr ) == addr) )        {            *kseg0addr = KSEG0(addr);	    return TRUE;        }	else	{	    if( sys_tlb_lookup( addr, &phys, &pagesize ) == SYS_TLB_OK )	    {	        *kseg0addr = KSEG0( phys );		return TRUE;	    }	    else	        return FALSE;	}    }    else    {	/* Assume Fixed Mapping MMU */        if(      KUSEG( addr ) == addr )        {	    /* Determine ERL setting */	    SYSCON_read( SYSCON_CPU_CP0_STATUS_ID,			 (void *)&erl,			 sizeof(UINT32) );	    if( (erl & M_StatusERL) == 0 )	        return FALSE; /* Can't be mapped to KSEG0 */	    if( (addr & KSEG_MSK) != addr )	        return FALSE; /* Can't be mapped to KSEG0 */		    *kseg0addr = KSEG0(addr);	    	    return TRUE;        }        else if( KSEG0( addr ) == addr )        {            *kseg0addr = addr;	    return TRUE;        }        else if( KSEG1( addr ) == addr )        {            *kseg0addr = KSEG0(addr);	    return TRUE;        }        else        {            /* KSSEG/KSEG3, can't be mapped to KSEG0 */	    return FALSE;        }    }}/************************************************************************ * *                          sys_legal_align *  Description : *  ------------- * *  Determine if alignment of address is legal * *  Return values : *  --------------- * *  TRUE -> Legal alignment, FALSE -> Illegal alignment * ************************************************************************/boolsys_legal_align(    UINT32 address,    UINT32 align ){    return (address == (address & ~(align - 1))) ? TRUE : FALSE;}/************************************************************************ *  Implementation : static functions ************************************************************************//************************************************************************ *                          determine_dev ************************************************************************/static booldetermine_dev(     UINT32 port,     UINT32 *major,     UINT32 *minor ){    UINT32 id_major, id_minor;    if( port == PORT_TTY0 )    {	id_major = SYSCON_COM_TTY0_MAJOR;	id_minor = SYSCON_COM_TTY0_MINOR;    }    else if( port == PORT_TTY1 )    {		id_major = SYSCON_COM_TTY1_MAJOR;	id_minor = SYSCON_COM_TTY1_MINOR;    }    else	return FALSE;    SYSCON_read( id_major,	         (void *)(major),		 sizeof(UINT32) );    SYSCON_read( id_minor,	         (void *)(minor),	         sizeof(UINT32) );		         return TRUE;}/************************************************************************ * *                          sys_validate_ram_range *  Description : *  ------------- * *  Perform range check relating to RAM use. * *  The range defined by parameters 'start' and 'last' is checked with *  relation to RAM use. * *  The memory map allocates a range for RAM. In case the RAM *  module does not occupy this entire range, there will be an *  "empty" RAM range. We detect whether the specified range *  hits this empty RAM range. If so, we return an error code.  *  Otherwise, OK is returned. * *  In case of a hit in the unused range, shell_err_data is set to a  *  text string stating the illegal address. This may be used by  *  error handling. * *  Return values : *  --------------- * *  OK :		    No error *  SHELL_ERROR_RAM_RANGE : Error detected * ************************************************************************/static UINT32sys_validate_ram_range(    UINT32 start,		/* Start address (physical)		*/    UINT32 last )		/* Last address (physical)		*/{    static void    *ram_base;    static UINT32  ram_actual_size, ram_size;    static UINT32  ram_range_unused_start;    static UINT32  ram_range_unused_last;    static bool    first = TRUE;        if( first )    {        /* Self-initialisation */        first = FALSE;        SYSCON_read( SYSCON_BOARD_SYSTEMRAM_ACTUAL_SIZE_ID,		     (void *)&ram_actual_size,		     sizeof(UINT32) );        SYSCON_read( SYSCON_BOARD_SYSTEMRAM_BASE_ID,		     (void *)&ram_base,		     sizeof(void *) );        SYSCON_read( SYSCON_BOARD_SYSTEMRAM_SIZE_ID,		     (void *)&ram_size,		     sizeof(UINT32) );        ram_range_unused_start = (UINT32)ram_base + ram_actual_size;        ram_range_unused_last  = (UINT32)ram_base + ram_size - 1;    }    if( ram_actual_size == ram_size )        return OK;  /* No unused RAM space */    if( start <= ram_range_unused_last )    {        if( start >= ram_range_unused_start )	{            sprintf( msg, "Address = 0x%08x", start );	    shell_error_data = msg;	    return SHELL_ERROR_RAM_RANGE;	}        if( last >= ram_range_unused_start )	{            sprintf( msg, "Address = 0x%08x", ram_range_unused_start );	    shell_error_data = msg;	    return SHELL_ERROR_RAM_RANGE;	}    }    return OK;}/************************************************************************ * *                          sys_func_noram *  Description : *  ------------- * *  Access function while executing from flash. *  All RAM access will be disabled while accessing function. * *  Return values : *  --------------- * *  UINT32 returned by requested function * ************************************************************************/UINT32sys_func_noram(    t_sys_func_noram func,    UINT32	     parm1,     UINT32	     parm2,     UINT32	     parm3 ){    UINT32 old_ie;    UINT32 rc;        /* Disable interrupts */    old_ie = sys_disable_int();    /* Stop DMA */    sys_dma_enable( FALSE );        /* Call function */    rc = (*func)(parm1, parm2, parm3);    /* Restart DMA */    sys_dma_enable( TRUE );    /* Restore interrupt enable setting */    if(old_ie)        sys_enable_int();    return rc;}

⌨️ 快捷键说明

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