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

📄 syslib.c

📁 vxworks MPC8541 BSP
💻 C
📖 第 1 页 / 共 4 页
字号:
/* sysLib.c - Motorola ads85xx board system-dependent library *//* Copyright 1984-2004 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01r,17sep04,dtr  Enable address streaming.01q,30jul04,dtr  Fixing sysMsDelay, added saveExcMsg.01p,22jul04,dtr  Disable ICACHE after boot up for initialisation.01o,31mar04,dtr  Some minor mods. Install parity handler.                  Branch prediction support.01n,20nov03,dtr  Setting HID1 ABE bit by default .01m,03nov03,dtr  Minor fixes..01l,27oct03,dtr  Use GNU_TOOL instead of __GCC__.01k,21oct03,dtr  Remove EUMBAR read/write.01j,17oct03,dtr  Modifying Pvr lkup.01i,29sep03,dtr  Set default aux clock setting if included.01h,09sep03,dtr  Clear L2 control register prior to Enable.01g,20aug03,dtr  Adding in TSEC configlette file.                  Adding new FCC2 End driver support.                 Test for bootrom then initialise static TLB entries.                 Adding dynamic config of L1 cache.01f,04aug03,dtr  Adding in support for LBC SDRAM.01e,29jul03,dtr  Removing CCSBAR magic number,support for MMU 'off' and                 support for SNOOP when MMU 'off'.01d,24jul03,mil  Added storing of flash params.01c,19jun03,mil  Changed ROM TLB entry to writable, added SCC and FCC.01b,07jan03,dtr  Adding TLB static table entries.01a,13oct02,dtr  More complete file for further development.*//*DESCRIPTIONThis library provides board-specific routines for ADS85XX.SEE ALSO:.pG "Configuration"*//* includes */#include "vxWorks.h"#include "vme.h"#include "memLib.h"#include "cacheLib.h"#include "sysLib.h"#include "config.h"#include "string.h"#include "intLib.h"#include "logLib.h"#include "stdio.h"#include "taskLib.h"#include "vxLib.h"#include "tyLib.h"#include "arch/ppc/mmuE500Lib.h"#include "arch/ppc/vxPpcLib.h"#include "private/vmLibP.h"#include "miiLib.h"#include "m85xxGlobUtil.h"#include "bspDefs.h"#ifdef INCLUDE_SCC_SERIAL#include "m8260Scc.h"#include "drv/sio/m8260CpmMux.h"#endif#ifdef INCLUDE_PCI#include "drv/pci/pciConfigLib.h"#include "drv/pci/pciIntLib.h" 	#include "mot85xxPci.h"#endif /* INCLUDE_PCI */#ifdef INCLUDE_CPM#include "m8560CpmIntrCtl.h"#include "drv/sio/m8260Cp.h"#include "drv/parallel/m8260IOPort.h"#endif/* globals */TLB_ENTRY_DESC sysStaticTlbDesc [] =    {    /* effAddr,  Unused,  realAddr, ts | size | attributes | permissions */    /* TLB #0.  Flash      * needed be first entry here      */	{ FLASH0_MAP_ADRS, 0x0, FLASH0_MAP_ADRS, _MMU_TLB_TS_0 | _MMU_TLB_SZ_16M | 	  _MMU_TLB_IPROT | _MMU_TLB_PERM_W | _MMU_TLB_PERM_X | _MMU_TLB_ATTR_I |	  _MMU_TLB_ATTR_G	},    /* LOCAL MEMORY needed be second entry here  */	{ LOCAL_MEM_LOCAL_ADRS, 0x0, LOCAL_MEM_LOCAL_ADRS, _MMU_TLB_TS_0 | _MMU_TLB_SZ_256M | 	  _MMU_TLB_PERM_W | _MMU_TLB_PERM_X | _MMU_TLB_ATTR_M | _MMU_TLB_IPROT	},	{ CCSBAR, 0x0, CCSBAR, _MMU_TLB_TS_0 | _MMU_TLB_SZ_16M | 	  _MMU_TLB_ATTR_I | _MMU_TLB_ATTR_G | _MMU_TLB_PERM_W | _MMU_TLB_ATTR_M	},	{ LBC_MEM_LOCAL_ADRS, 0x0, LBC_MEM_LOCAL_ADRS, _MMU_TLB_TS_0 | _MMU_TLB_SZ_256M | 	  _MMU_TLB_PERM_W | _MMU_TLB_PERM_X | _MMU_TLB_ATTR_I | _MMU_TLB_ATTR_G	},#if defined(INCLUDE_LBC_SDRAM) && defined(INCLUDE_LOCAL_MEM2)	{ LOCAL_MEM_LOCAL_ADRS2, 0x0, LOCAL_MEM_LOCAL_ADRS2, _MMU_TLB_TS_0 | _MMU_TLB_SZ_64M | 	  _MMU_TLB_PERM_W | _MMU_TLB_PERM_X | _MMU_TLB_ATTR_M | _MMU_TLB_IPROT	},#endif /* INCLUDE_LBC_SDRAM && INCLUDE_LOCAL_MEM2 */#ifdef INCLUDE_L2_SRAM	{ L2SRAM_ADDR, 0x0, L2SRAM_ADDR, _MMU_TLB_TS_0 | _MMU_TLB_SZ_256K | 	  _MMU_TLB_PERM_W | _MMU_TLB_PERM_X | _MMU_TLB_ATTR_I | _MMU_TLB_ATTR_G	},#endif /* INCLUDE_L2_SRAM */#ifdef INCLUDE_PCI	{ PCI_MEM_ADRS, 0x0, PCI_MEM_ADRS, _MMU_TLB_TS_0 | _MMU_TLB_SZ_64M | 	  _MMU_TLB_ATTR_I | _MMU_TLB_ATTR_G | _MMU_TLB_PERM_W	},	{ PCI_MEMIO_ADRS, 0x0, PCI_MEMIO_ADRS, _MMU_TLB_TS_0 | _MMU_TLB_SZ_64M | 	  _MMU_TLB_ATTR_I | _MMU_TLB_ATTR_G | _MMU_TLB_PERM_W	},	{ PCI_IO_ADRS, 0x0, PCI_IO_ADRS, _MMU_TLB_TS_0 | _MMU_TLB_SZ_64M | 	  _MMU_TLB_ATTR_I | _MMU_TLB_ATTR_G | _MMU_TLB_PERM_W	},#ifdef INCLUDE_SECONDARY_PCI	{ PCI_MEM_ADRS2, 0x0, PCI_MEM_ADRS2, _MMU_TLB_TS_0 | _MMU_TLB_SZ_64M | 	  _MMU_TLB_ATTR_I | _MMU_TLB_ATTR_G | _MMU_TLB_PERM_W	},	{ PCI_MEMIO_ADRS2, 0x0, PCI_MEMIO_ADRS2, _MMU_TLB_TS_0 | _MMU_TLB_SZ_64M | 	  _MMU_TLB_ATTR_I | _MMU_TLB_ATTR_G | _MMU_TLB_PERM_W	},	{ PCI_IO_ADRS2, 0x0, PCI_IO_ADRS2, _MMU_TLB_TS_0 | _MMU_TLB_SZ_64M | 	  _MMU_TLB_ATTR_I | _MMU_TLB_ATTR_G | _MMU_TLB_PERM_W	}#endif /* INCLUDE_SECONDARY_PCI */#endif  /* INCLUDE_PCI */    };int sysStaticTlbDescNumEnt = NELEMENTS (sysStaticTlbDesc);/* * sysPhysMemDesc[] is used to initialize the Page Table Entry (PTE) array * used by the MMU to translate addresses with single page (4k) granularity. * PTE memory space should not, in general, overlap BAT memory space but * may be allowed if only Data or Instruction access is mapped via BAT. * * Address translations for local RAM, memory mapped PCI bus, the Board Control and * Status registers, the MPC8260 Internal Memory Map, and local FLASH RAM are set here. * * PTEs are held, strangely enough, in a Page Table.  Page Table sizes are * integer powers of two based on amount of memory to be mapped and a * minimum size of 64 kbytes.  The MINIMUM recommended Page Table sizes * for 32-bit PowerPCs are: * * Total mapped memory		Page Table size * -------------------		--------------- *        8 Meg			     64 K *       16 Meg			    128 K *       32 Meg			    256 K *       64 Meg			    512 K *      128 Meg			      1 Meg * 	.				. * 	.				. * 	.				. * * [Ref: chapter 7, PowerPC Microprocessor Family: The Programming Environments] * */PHYS_MEM_DESC sysPhysMemDesc [] =    {    {    /* Vector Table and Interrupt Stack */    /* Must be sysPhysMemDesc [0] to allow adjustment in sysHwInit() */    (void *) LOCAL_MEM_LOCAL_ADRS,    (void *) LOCAL_MEM_LOCAL_ADRS,    RAM_LOW_ADRS,    VM_STATE_MASK_VALID | VM_STATE_MASK_WRITABLE | VM_STATE_MASK_CACHEABLE,    VM_STATE_VALID      | VM_STATE_WRITABLE      | VM_STATE_CACHEABLE_NOT    },    {    /* Must be sysPhysMemDesc [1] to allow adjustment in sysHwInit() */    (void *) RAM_LOW_ADRS,    (void *) RAM_LOW_ADRS,    LOCAL_MEM_LOCAL_ADRS + LOCAL_MEM_SIZE - RAM_LOW_ADRS,    VM_STATE_MASK_VALID | VM_STATE_MASK_WRITABLE | VM_STATE_MASK_CACHEABLE | VM_STATE_MASK_MEM_COHERENCY,    VM_STATE_VALID      | VM_STATE_WRITABLE      | VM_STATE_CACHEABLE | VM_STATE_MEM_COHERENCY    },#if defined(INCLUDE_LBC_SDRAM) && defined(INCLUDE_LOCAL_MEM2)    {    /* Must be sysPhysMemDesc [2] to allow adjustment in sysHwInit() */    (void *) LOCAL_MEM_LOCAL_ADRS2,    (void *) LOCAL_MEM_LOCAL_ADRS2,    LOCAL_MEM_SIZE2,    VM_STATE_MASK_VALID | VM_STATE_MASK_WRITABLE | VM_STATE_MASK_CACHEABLE | VM_STATE_MASK_MEM_COHERENCY,    VM_STATE_VALID      | VM_STATE_WRITABLE      | VM_STATE_CACHEABLE | VM_STATE_MEM_COHERENCY    },#endif /* INCLUDE_LBC_SDRAM && INCLUDE_LOCAL_MEM2 */    {    (void *) CCSBAR,    (void *) CCSBAR,    1024 * 1024,    VM_STATE_MASK_VALID | VM_STATE_MASK_WRITABLE | VM_STATE_MASK_CACHEABLE | \    VM_STATE_MASK_GUARDED | VM_STATE_MASK_MEM_COHERENCY,    VM_STATE_VALID      | VM_STATE_WRITABLE      | VM_STATE_CACHEABLE_NOT | \    VM_STATE_GUARDED      | VM_STATE_MEM_COHERENCY    },    {    (void *) LBC_MEM_LOCAL_ADRS,    (void *) LBC_MEM_LOCAL_ADRS,    LBC_MEM_SIZE,    VM_STATE_MASK_VALID | VM_STATE_MASK_WRITABLE | VM_STATE_MASK_CACHEABLE | \    VM_STATE_MASK_GUARDED | VM_STATE_MASK_MEM_COHERENCY,    VM_STATE_VALID      | VM_STATE_WRITABLE      | VM_STATE_CACHEABLE_NOT | \    VM_STATE_GUARDED      | VM_STATE_MEM_COHERENCY    },#ifdef INCLUDE_L2_SRAM    {    (void *) L2SRAM_ADDR,    (void *) L2SRAM_ADDR,    256 * 1024,    VM_STATE_MASK_VALID | VM_STATE_MASK_WRITABLE | VM_STATE_MASK_CACHEABLE,    VM_STATE_VALID      | VM_STATE_WRITABLE      | VM_STATE_CACHEABLE_NOT    },#endif#ifdef INCLUDE_PCI    {    (void *) PCI_MEM_ADRS,    (void *) PCI_MEM_ADRS,    PCI_MEM_SIZE,    VM_STATE_MASK_VALID | VM_STATE_MASK_WRITABLE | VM_STATE_MASK_CACHEABLE | \    VM_STATE_MASK_GUARDED | VM_STATE_MASK_MEM_COHERENCY,    VM_STATE_VALID      | VM_STATE_WRITABLE      | VM_STATE_CACHEABLE_NOT | \    VM_STATE_GUARDED      | VM_STATE_MEM_COHERENCY    },    {    (void *) PCI_MEMIO_ADRS,    (void *) PCI_MEMIO_ADRS,    PCI_MEMIO_SIZE,    VM_STATE_MASK_VALID | VM_STATE_MASK_WRITABLE | VM_STATE_MASK_CACHEABLE | \    VM_STATE_MASK_GUARDED | VM_STATE_MASK_MEM_COHERENCY,    VM_STATE_VALID      | VM_STATE_WRITABLE      | VM_STATE_CACHEABLE_NOT | \    VM_STATE_GUARDED      | VM_STATE_MEM_COHERENCY    },    {    (void *) PCI_IO_ADRS,    (void *) PCI_IO_ADRS,    PCI_IO_SIZE,    VM_STATE_MASK_VALID | VM_STATE_MASK_WRITABLE | VM_STATE_MASK_CACHEABLE | \    VM_STATE_MASK_GUARDED | VM_STATE_MASK_MEM_COHERENCY,    VM_STATE_VALID      | VM_STATE_WRITABLE      | VM_STATE_CACHEABLE_NOT | \    VM_STATE_GUARDED      | VM_STATE_MEM_COHERENCY    },#ifdef INCLUDE_SECONDARY_PCI    {    (void *) PCI_MEM_ADRS2,    (void *) PCI_MEM_ADRS2,    PCI_MEM_SIZE,    VM_STATE_MASK_VALID | VM_STATE_MASK_WRITABLE | VM_STATE_MASK_CACHEABLE | \    VM_STATE_MASK_GUARDED | VM_STATE_MASK_MEM_COHERENCY,    VM_STATE_VALID      | VM_STATE_WRITABLE      | VM_STATE_CACHEABLE_NOT | \    VM_STATE_GUARDED      | VM_STATE_MEM_COHERENCY    },    {    (void *) PCI_MEMIO_ADRS2,    (void *) PCI_MEMIO_ADRS2,    PCI_MEMIO_SIZE,    VM_STATE_MASK_VALID | VM_STATE_MASK_WRITABLE | VM_STATE_MASK_CACHEABLE | \    VM_STATE_MASK_GUARDED | VM_STATE_MASK_MEM_COHERENCY,    VM_STATE_VALID      | VM_STATE_WRITABLE      | VM_STATE_CACHEABLE_NOT | \    VM_STATE_GUARDED      | VM_STATE_MEM_COHERENCY    },    {    (void *) PCI_IO_ADRS2,    (void *) PCI_IO_ADRS2,    PCI_IO_SIZE,    VM_STATE_MASK_VALID | VM_STATE_MASK_WRITABLE | VM_STATE_MASK_CACHEABLE | \    VM_STATE_MASK_GUARDED | VM_STATE_MASK_MEM_COHERENCY,    VM_STATE_VALID      | VM_STATE_WRITABLE      | VM_STATE_CACHEABLE_NOT | \    VM_STATE_GUARDED      | VM_STATE_MEM_COHERENCY    },#endif /* INCLUDE_SECONDARY_PCI */#endif /* INCLUDE_PCI */    {    (void *) FLASH0_MEM_ADRS,    (void *) FLASH0_MEM_ADRS,    FLASH0_MEM_SIZE,    VM_STATE_MASK_VALID | VM_STATE_MASK_WRITABLE | VM_STATE_MASK_CACHEABLE | \    VM_STATE_MASK_GUARDED | VM_STATE_MASK_MEM_COHERENCY,    VM_STATE_VALID      | VM_STATE_WRITABLE      | VM_STATE_CACHEABLE_NOT | \    VM_STATE_GUARDED      | VM_STATE_MEM_COHERENCY    }    };int sysPhysMemDescNumEnt = NELEMENTS (sysPhysMemDesc);/* CLock Ratio Tables */#define MAX_VALUE_PLAT_RATIO 32UINT32 platRatioTable[MAX_VALUE_PLAT_RATIO][2] =     {    { 0, 0 },	{ 0, 0 },	{ 2, 0 },	{ 3, 0 },	{ 4, 0 },	{ 5, 0 },	{ 6, 0 },	{ 7, 0 }, 	{ 8, 0 },	{ 9, 0 },	{ 10, 0 },	{ 0, 0 },	{ 12, 0 },	{ 0, 0 },	{ 0, 0 },	{ 0, 0 },	{ 16, 0 },	{ 0, 0 }     };#define MAX_VALUE_E500_RATIO 8UINT32 e500RatioTable[MAX_VALUE_PLAT_RATIO][2] =     {    { 0, 0 },	{ 0, 0 },	{ 0, 0 },	{ 0, 0 },	{ 2, 0 },	{ 5, 1 },	{ 3, 0 },	{ 7, 1 }     };int   sysBus      = BUS;                /* system bus type (VME_BUS, etc) */int   sysCpu      = CPU;                /* system CPU type (PPC8260) */char *sysBootLine = BOOT_LINE_ADRS;	/* address of boot line */char *sysExcMsg   = EXC_MSG_ADRS;	/* catastrophic message area */int   sysProcNum;			/* processor number of this CPU */int   sysFlags;				/* boot flags */char  sysBootHost [BOOT_FIELD_LEN];	/* name of host from which we booted */char  sysBootFile [BOOT_FIELD_LEN];	/* name of file from which we booted */BOOL  sysVmeEnable = FALSE;		/* by default no VME */UINT32  coreFreq;IMPORT void     mmuE500TlbDynamicInvalidate(void);IMPORT void     mmuE500TlbStaticInvalidate(void);IMPORT void     mmuE500TlbStaticInit (int numDescs, 								      TLB_ENTRY_DESC *pTlbDesc, 								      BOOL cacheAllow);IMPORT BOOL     mmuPpcIEnabled;IMPORT BOOL     mmuPpcDEnabled;  /* forward declarations */void   sysUsDelay (UINT32);#ifdef INCLUDE_PCISTATUS sysPciSpecialCycle (int busNo, UINT32 message);STATUS sysPciConfigRead   (int busNo, int deviceNo, int funcNo,			   int offset, int width, void * pData);STATUS sysPciConfigWrite  (int busNo, int deviceNo, int funcNo,			   int offset, int width, ULONG data);void   sysPciConfigEnable (int);#endif /* INCLUDE_PCI */UINT32 sysClkFreqGet(void);UINT32 ppcE500ICACHE_LINE_NUM = (128 * 12);UINT32 ppcE500DCACHE_LINE_NUM = (128 * 12); UINT32 ppcE500CACHE_ALIGN_SIZE = 32;UINT32 baudRateGenClk;#ifdef INCLUDE_PCIULONG sysPciConfAddr = PCI_CFG_ADR_REG;   /* PCI Configuration Address */ULONG sysPciConfData = PCI_CFG_DATA_REG;  /* PCI Configuration Data */#include "pci/pciIntLib.c"           /* PCI int support */#include "pci/pciConfigLib.c"        /* pci configuration library *//* use show routine */#ifdef INCLUDE_SHOW_ROUTINES#include "pci/pciConfigShow.c"       /* pci configuration show routines */#endif/* use pci auto config */#include "pci/pciAutoConfigLib.c"    /* automatic PCI configuration */#include "sysBusPci.c"               /* pciAutoConfig BSP support file */#include "mot85xxPci.c"#ifdef INCLUDE_FEI_END#include "sysFei82557End.c"#endif  /* INCLUDE_FEI_END */#ifdef INCLUDE_BCM56504#include "sysBcmPciInit.c"#endif /* INCLUDE_BCM56504 */#endif /* INCLUDE_PCI */#include "sysL2Cache.c"#ifdef INCLUDE_CPMUINT32 vxImmrGet(void);#include "m82xxDpramLib.c"#endif#include "m85xxTimer.c"#include "sysEpic.c"#ifdef INCLUDE_CPM#include "m8560CpmIntrCtl.c"#endif#ifdef INCLUDE_DUART#include "sysDuart.c"#endif#ifdef INCLUDE_SCC_SERIAL#include "m8260Sio.c"#include "sysScc.c"#endif/* 060701 lyf add */SIO_CHAN *dbgSerChan;void dbgSerInit (void);void dbgSerOutstr (char *str);/* end lyf add */#ifdef  INCLUDE_MOT_TSEC_ENDunsigned char sysTsecEnetAddr [2][6] = {{0x00, 0xd0, 0xd0, 0x82, 0x50, 0x01},										{0x00, 0xd0, 0xd0, 0x82, 0x50, 0x02}};#endif  /* INCLUDE_MOT_TSEC_END */#ifdef  INCLUDE_MOT_FCC_END/* set the following array to a unique Ethernet hardware address *//* last 5 nibbles are board specific, initialized in sysHwInit */unsigned char sysFccEnetAddr [2][6] = {{0x00, 0xd0, 0xd0, 0x82, 0x50, 0x03},									   {0x00, 0xd0, 0xd0, 0x82, 0x50, 0x04}};unsigned char sysEnetMacAddr [6] = {0x00, 0xd0, 0xd0, 0x82, 0x50, 0x00};									   unsigned char sysMBEnetMacAddr[6] = {0x00, 0xd0, 0xd0, 0x82, 0x50, 0x00};/*STATUS sysFccEnetAddrGet (int unit, UCHAR * address);*/#endif  /* INCLUDE_MOT_FCC_END */unsigned char sysoutbandmacAddr[6] = {0x00, 0xd0, 0xd0, 0x82, 0x50, 0x01};unsigned char sysinbandmacAddr[6] = {0x00, 0xd0, 0xd0, 0x82, 0x50, 0x02};UINT32 inFullVxWorksImage=FALSE;#define EXT_VEC_IRQ0            56#define EXT_NUM_IRQ0            EXT_VEC_IRQ0#define EXT_MAX_IRQS            200/*STATUS  sysIntEnablePIC		(int intNum);*/	/* Enable i8259 or EPIC */STATUS  sysCascadeIntEnable      (int intNum);STATUS  sysCascadeIntDisable     (int intNum);/* defines */#define ZERO    0#define SYS_MODEL_8540    "Motorola MPC8540 ADS"#define SYS_MODEL_8560    "Motorola MPC8560 ADS"#define SYS_MODEL_8541    "Freescale CDS MPC8541"#define SYS_MODEL_8555    "Freescale CDS MPC8555"#define SYS_MODEL_E500    "Motorola E500 : Unknown system version" #define SYS_MODEL_UNKNOWN "Motorola Unknown processor"#define DELTA(a,b)                 (abs((int)a - (int)b))#define HID0_MCP 0x80000000#define HID1_ABE 0x00001000#define HID1_ASTME 0x00002000#ifdef  INCLUDE_MOT_FCC_END#include "sysMotFcc2End.c"#endif /* INCLUDE_MOT_FCC_END */#ifdef INCLUDE_BRANCH_PREDICTIONIMPORT void disableBranchPrediction(void);#endif#define _EXC_OFF_END 0x1500/*lint -e937*/void jumpIParity();/*lint +e937*/IMPORT void sysIvor1Set(UINT32);#ifdef INCLUDE_L2_SRAMLOCAL void sysL2SramEnable(BOOL both);#endif /* INCLUDE_L2_SRAM */#ifdef INCLUDE_SPE#include "speLib.h"IMPORT int       (* _func_speProbeRtn) () ;#endif /* INCLUDE_SPE */#ifdef INCLUDE_CACHE_SUPPORTLOCAL void sysL1CacheQuery(void);#endifUINT32 sysTimerClkFreq = OSCILLATOR_FREQ;UINT32 instrParityCount=0;IMPORT  void    sysL1Csr1Set(UINT32);IMPORT  UINT    sysTimeBaseLGet(void);IMPORT  STATUS  sysBdcsInit (void);IMPORT  UINT8   b_getMachineType (void);#if     defined (INCLUDE_SPE)/********************************************************************************* sysSpeProbe - Check if the CPU has SPE unit.** This routine returns OK it the CPU has an SPE unit in it.* Presently it assumes available.* RETURNS: OK * */int  sysSpeProbe (void)    {    ULONG regVal;    int speUnitPresent = OK;    /* The CPU type is indicated in the Processor Version Register (PVR) */     regVal = 0;

⌨️ 快捷键说明

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