intr.c

来自「SAMSUNG S3C6410 CPU BSP for winmobile6」· C语言 代码 · 共 934 行 · 第 1/2 页

C
934
字号

		// Translate to Physical IRQ
		PhysicalIRQ = g_VirIrq2PhyIrq[VirtualIRQ];

		if (PhysicalIRQ < VIC1_BIT_OFFSET)
		{
			g_pVIC0Reg->VICINTENABLE = (0x1<<PhysicalIRQ);
		}
		else if (PhysicalIRQ < PHYIRQ_MAX_S3C6410)
		{
			g_pVIC1Reg->VICINTENABLE = (0x1<<(PhysicalIRQ-VIC1_BIT_OFFSET));
		}
	}

	OALMSG(OAL_INTR&&OAL_VERBOSE, (L"-OALIntrDoneIrqs\r\n"));
}

//------------------------------------------------------------------------------
//
//  Function:  OEMInterruptHandler
//
ULONG OEMInterruptHandler(ULONG ra)
{
	UINT32 SysIntr = SYSINTR_NOP;
	UINT32 PhysicalIRQ;
	UINT32 VirtualIRQ;
	UINT32 uiPending;
	UINT32 uiMask;
	int nNumber;
#ifdef	VIC_MASK
	UINT32 IntEnVIC0, IntEnVIC1;
#endif

	static DWORD HeartBeatCnt, HeartBeatStat;  //LED4 is used for heart beat

	g_bOalInterruptFlag = TRUE;

	// Get Pending Interrupt Number
	PhysicalIRQ = g_pVIC1Reg->VICADDRESS;	// Ready Dummy from VIC1
	PhysicalIRQ = g_pVIC0Reg->VICADDRESS;

#ifdef	VIC_MASK
	// To Avoid low proirity interrupt lost
	IntEnVIC0 = g_pVIC0Reg->VICINTENABLE;
	IntEnVIC1 = g_pVIC1Reg->VICINTENABLE;
	g_pVIC0Reg->VICINTENCLEAR = 0xffffffff;
	g_pVIC1Reg->VICINTENCLEAR = 0xffffffff;
#endif

	// Translate Physical IRQ to Virtual IRQ (Except Flatten IRQ)
	VirtualIRQ = g_PhyIrq2VirIrq[PhysicalIRQ];

	if (PhysicalIRQ == PHYIRQ_TIMER4)
	{
		//-------------
		// System Timer
		//-------------

		// Heart Beat LED
		if (++HeartBeatCnt > 100)
		{
			HeartBeatCnt = 0;
			HeartBeatStat ^= 1;

			if (HeartBeatStat)
			{
				g_pGPIOReg->GPNDAT &= ~(1<<12);
			}
			else
			{
				g_pGPIOReg->GPNDAT |=  (1<<12);
			}
		}

		if (g_pVIC0Reg->VICRAWINTR & (1<<PHYIRQ_TIMER4))
		{
			// Handling System Timer Interrupt
			SysIntr = OALTimerIntrHandler();
		}
#ifndef	REMOVE_BEFORE_RELEASE
		else
		{
			OALMSG(TRUE, (L"[OAL:ERR] PHYIRQ_TIMER4 Interrupt But There is No Pending !!!!\r\n"));
			OALMSG(TRUE, (L"[OAL:ERR] Maybe OALTimerIntrHandler() in OEMIdle() Make this\r\n"));
		}
#endif

	}
	else if (PhysicalIRQ == PHYIRQ_TIMER2)
	{
		//-------------
		// Profiling Timer
		//-------------

		// Masking Interrupt
#ifdef	VIC_MASK
		IntEnVIC0 &= ~(1<<PHYIRQ_TIMER2);
#else
		g_pVIC0Reg->VICINTENCLEAR = (1<<PHYIRQ_TIMER2);
#endif

		// TODO: Clear Source Pending
		//g_pPwmRegs->TCNTCLRINT2;

		// Handling Profiling Timer Interrupt
		if (g_pProfilerISR)
		{
			SysIntr = g_pProfilerISR(ra);
		}
	}
	else
	{
#ifdef OAL_ILTIMING
		if (g_oalILT.active)
		{
			g_oalILT.isrTime1 = OALTimerCountsSinceSysTick();
			g_oalILT.savedPC = 0;
			g_oalILT.interrupts++;
		}
#endif

		if (PhysicalIRQ == PHYIRQ_EINT0)
		{
			// Do not mask PHYIRQ_EINT0 interrupt for other sub interrupt
			// Mask EINTMASK and EINTPEND which occured this time
			// So each IST of EINT should unmask their EINT for Next Interrupt

			// Check Sub Source and Mask
			uiPending = g_pGPIOReg->EINT0PEND;
			uiMask = g_pGPIOReg->EINT0MASK;

			for (nNumber=0; nNumber<4; nNumber++)	// EINT0~EINT3
			{
				if ((uiPending & (1<<nNumber)) && !(uiMask & (1<<nNumber)))
				{
					g_pGPIOReg->EINT0MASK |= (1<<nNumber);	// Mask Sub Interrupt
					g_pGPIOReg->EINT0PEND |= (1<<nNumber);		// Clear Sub Pending
					VirtualIRQ = (IRQ_EINT0+nNumber);				// Set Virtual IRQ
					break;
				}
			}
		}
		else if (PhysicalIRQ == PHYIRQ_EINT1)
		{
			// Do not mask PHYIRQ_EINT1 interrupt for other sub interrupt
			// Mask EINTMASK and EINTPEND which occured this time
			// So each IST of EINT should unmask their EINT for Next Interrupt

			// Check Sub Source
			uiPending = g_pGPIOReg->EINT0PEND;
			uiMask = g_pGPIOReg->EINT0MASK;

			for (nNumber=4; nNumber<12; nNumber++)	// EINT4~EINT11
			{
				if ((uiPending & (1<<nNumber)) && !(uiMask & (1<<nNumber)))
				{
					g_pGPIOReg->EINT0MASK |= (1<<nNumber);	// Mask Sub Interrupt
					g_pGPIOReg->EINT0PEND |= (1<<nNumber);		// Clear Sub Pending
					VirtualIRQ = (IRQ_EINT4+(nNumber-4));			// Set Virtual IRQ
					break;
				}
			}
		}
		else if (PhysicalIRQ == PHYIRQ_EINT2)
		{
			// Do not mask PHYIRQ_EINT2 interrupt for other sub interrupt
			// Mask EINTMASK and EINTPEND which occured this time
			// So each IST of EINT should unmask their EINT for Next Interrupt

			// Check Sub Source
			uiPending = g_pGPIOReg->EINT0PEND;
			uiMask = g_pGPIOReg->EINT0MASK;

			for (nNumber=12; nNumber<20; nNumber++)	// EINT12~EINT19
			{
				if ((uiPending & (1<<nNumber)) && !(uiMask & (1<<nNumber)))
				{
					g_pGPIOReg->EINT0MASK |= (1<<nNumber);	// Mask Sub Interrupt
					g_pGPIOReg->EINT0PEND |= (1<<nNumber);		// Clear Sub Pending
					VirtualIRQ = (IRQ_EINT12+(nNumber-12));		// Set Virtual IRQ
					break;
				}
			}
		}
		else if (PhysicalIRQ == PHYIRQ_EINT3)
		{
			// Do not mask PHYIRQ_EINT3 interrupt for other sub interrupt
			// Mask EINTMASK and EINTPEND which occured this time
			// So each IST of EINT should unmask their EINT for Next Interrupt

			// Check Sub Source
			uiPending = g_pGPIOReg->EINT0PEND;
			uiMask = g_pGPIOReg->EINT0MASK;

			for (nNumber=20; nNumber<28; nNumber++)	// EINT20~EINT27
			{
				if ((uiPending & (1<<nNumber)) && !(uiMask & (1<<nNumber)))
				{
					g_pGPIOReg->EINT0MASK |= (1<<nNumber);	// Mask Sub Interrupt
					g_pGPIOReg->EINT0PEND |= (1<<nNumber);		// Clear Sub Pending
					VirtualIRQ = (IRQ_EINT20+(nNumber-20));		// Set Virtual IRQ
					break;
				}
			}
		}
		else if (PhysicalIRQ == PHYIRQ_DMA0)
		{
			DWORD dwIntStatus;

#ifdef	VIC_MASK
			IntEnVIC1 &= ~(1<<(PHYIRQ_DMA0-VIC1_BIT_OFFSET));
#else
			g_pVIC1Reg->VICINTENCLEAR = (1<<(PHYIRQ_DMA0-VIC1_BIT_OFFSET));
#endif

			dwIntStatus = g_pDMAC0Reg->DMACIntStatus;

			if (dwIntStatus & 0x01) VirtualIRQ = IRQ_DMA0_CH0;		// channel 0
			else if (dwIntStatus & 0x02) VirtualIRQ = IRQ_DMA0_CH1;	// channel 1
			else if (dwIntStatus & 0x04) VirtualIRQ = IRQ_DMA0_CH2;	// channel 2
			else if (dwIntStatus & 0x08) VirtualIRQ = IRQ_DMA0_CH3;	// channel 3
			else if (dwIntStatus & 0x10) VirtualIRQ = IRQ_DMA0_CH4;	// channel 4
			else if (dwIntStatus & 0x20) VirtualIRQ = IRQ_DMA0_CH5;	// channel 5
			else if (dwIntStatus & 0x40) VirtualIRQ = IRQ_DMA0_CH6;	// channel 6
			else if (dwIntStatus & 0x80) VirtualIRQ = IRQ_DMA0_CH7;	// channel 7
		}
		else if (PhysicalIRQ == PHYIRQ_DMA1)
		{
			DWORD dwIntStatus;

#ifdef	VIC_MASK
			IntEnVIC1 &= ~(1<<(PHYIRQ_DMA1-VIC1_BIT_OFFSET));
#else
			g_pVIC1Reg->VICINTENCLEAR = (1<<(PHYIRQ_DMA1-VIC1_BIT_OFFSET));
#endif

			dwIntStatus = g_pDMAC1Reg->DMACIntStatus;

			if (dwIntStatus & 0x01) VirtualIRQ = IRQ_DMA1_CH0;		// channel 0
			else if (dwIntStatus & 0x02) VirtualIRQ = IRQ_DMA1_CH1;	// channel 1
			else if (dwIntStatus & 0x04) VirtualIRQ = IRQ_DMA1_CH2;	// channel 2
			else if (dwIntStatus & 0x08) VirtualIRQ = IRQ_DMA1_CH3;	// channel 3
			else if (dwIntStatus & 0x10) VirtualIRQ = IRQ_DMA1_CH4;	// channel 4
			else if (dwIntStatus & 0x20) VirtualIRQ = IRQ_DMA1_CH5;	// channel 5
			else if (dwIntStatus & 0x40) VirtualIRQ = IRQ_DMA1_CH6;	// channel 6
			else if (dwIntStatus & 0x80) VirtualIRQ = IRQ_DMA1_CH7;	// channel 7
		}
		else if (PhysicalIRQ < VIC1_BIT_OFFSET)
		{
#ifdef	VIC_MASK
			IntEnVIC0 &= ~(1<<PhysicalIRQ);
#else
			g_pVIC0Reg->VICINTENCLEAR = (1<<PhysicalIRQ);
#endif
		}
		else if (PhysicalIRQ < PHYIRQ_MAX_S3C6410)
		{
#ifdef	VIC_MASK
			IntEnVIC1 &= ~(1<<(PhysicalIRQ-VIC1_BIT_OFFSET));
#else
			g_pVIC1Reg->VICINTENCLEAR = (1<<(PhysicalIRQ-VIC1_BIT_OFFSET));
#endif
		}

#if	0	// Multi IRQ is not supported
		// First find if IRQ is claimed by chain
		SysIntr = NKCallIntChain((BYTE)VirtualIRQ);

		if (SysIntr == SYSINTR_CHAIN || !NKIsSysIntrValid(SysIntr))
		{
			// IRQ wasn't claimed, use static mapping
			SysIntr = OALIntrTranslateIrq(VirtualIRQ);
		}
#else
	        // We don't assume IRQ sharing, use static mapping
		SysIntr = OALIntrTranslateIrq(VirtualIRQ);
#endif
	}

	// Clear Vector Address Register
	g_pVIC0Reg->VICADDRESS = 0x0;
	g_pVIC1Reg->VICADDRESS = 0x0;

#ifdef	VIC_MASK
	// To Avoid low proirity interrupt lost
	g_pVIC0Reg->VICINTENABLE = IntEnVIC0;
	g_pVIC1Reg->VICINTENABLE = IntEnVIC1;
#endif

	return SysIntr;
}

static void PrepareEINTIntr(void)
{
#if	0	// TODO:
	// Mask and clear external interrupts
	OUTREG32(&g_pPortRegs->EINTMASK, 0xFFFFFFFF);
	OUTREG32(&g_pPortRegs->EINTPEND, 0xFFFFFFFF);

	// Mask and clear internal sub interrupts
	OUTREG32(&g_pIntrRegs->SUBSRCPND, 0xFFFFFFFF);
	OUTREG32(&g_pIntrRegs->INTSUBMSK, 0xFFFFFFFF);

	// Mask and clear internal interrupts
	OUTREG32(&g_pIntrRegs->INTMSK, 0xFFFFFFFF);
	OUTREG32(&g_pIntrRegs->SRCPND, 0xFFFFFFFF);
#endif
}

static void PrepareDMACIntr(void)
{
	// Disable Interrupt of All Channel
	// Mask TC and Error Interrupt
	// Clear Interrupt Pending

	g_pDMAC0Reg->DMACC0Control0 &= ~(1<<31);		// TCINT Disable
	g_pDMAC0Reg->DMACC0Configuration &= (3<<14);	// TCINT & ErrINT Mask
	g_pDMAC0Reg->DMACC1Control0 &= ~(1<<31);		// TCINT Disable
	g_pDMAC0Reg->DMACC1Configuration &= (3<<14);	// TCINT & ErrINT Mask
	g_pDMAC0Reg->DMACC2Control0 &= ~(1<<31);		// TCINT Disable
	g_pDMAC0Reg->DMACC2Configuration &= (3<<14);	// TCINT & ErrINT Mask
	g_pDMAC0Reg->DMACC3Control0 &= ~(1<<31);		// TCINT Disable
	g_pDMAC0Reg->DMACC3Configuration &= (3<<14);	// TCINT & ErrINT Mask
	g_pDMAC0Reg->DMACC4Control0 &= ~(1<<31);		// TCINT Disable
	g_pDMAC0Reg->DMACC4Configuration &= (3<<14);	// TCINT & ErrINT Mask
	g_pDMAC0Reg->DMACC5Control0 &= ~(1<<31);		// TCINT Disable
	g_pDMAC0Reg->DMACC5Configuration &= (3<<14);	// TCINT & ErrINT Mask
	g_pDMAC0Reg->DMACC6Control0 &= ~(1<<31);		// TCINT Disable
	g_pDMAC0Reg->DMACC6Configuration &= (3<<14);	// TCINT & ErrINT Mask
	g_pDMAC0Reg->DMACC7Control0 &= ~(1<<31);		// TCINT Disable
	g_pDMAC0Reg->DMACC7Configuration &= (3<<14);	// TCINT & ErrINT Mask

	g_pDMAC0Reg->DMACIntTCClear = 0xff;			// TC Int Pending Clear
	g_pDMAC0Reg->DMACIntErrClear = 0xff;			// Err Int Pending Clear

	g_pDMAC1Reg->DMACC0Control0 &= ~(1<<31);		// TCINT Disable
	g_pDMAC1Reg->DMACC0Configuration &= (3<<14);	// TCINT & ErrINT Mask
	g_pDMAC1Reg->DMACC1Control0 &= ~(1<<31);		// TCINT Disable
	g_pDMAC1Reg->DMACC1Configuration &= (3<<14);	// TCINT & ErrINT Mask
	g_pDMAC1Reg->DMACC2Control0 &= ~(1<<31);		// TCINT Disable
	g_pDMAC1Reg->DMACC2Configuration &= (3<<14);	// TCINT & ErrINT Mask
	g_pDMAC1Reg->DMACC3Control0 &= ~(1<<31);		// TCINT Disable
	g_pDMAC1Reg->DMACC3Configuration &= (3<<14);	// TCINT & ErrINT Mask
	g_pDMAC1Reg->DMACC4Control0 &= ~(1<<31);		// TCINT Disable
	g_pDMAC1Reg->DMACC4Configuration &= (3<<14);	// TCINT & ErrINT Mask
	g_pDMAC1Reg->DMACC5Control0 &= ~(1<<31);		// TCINT Disable
	g_pDMAC1Reg->DMACC5Configuration &= (3<<14);	// TCINT & ErrINT Mask
	g_pDMAC1Reg->DMACC6Control0 &= ~(1<<31);		// TCINT Disable
	g_pDMAC1Reg->DMACC6Configuration &= (3<<14);	// TCINT & ErrINT Mask
	g_pDMAC1Reg->DMACC7Control0 &= ~(1<<31);		// TCINT Disable
	g_pDMAC1Reg->DMACC7Configuration &= (3<<14);	// TCINT & ErrINT Mask

	g_pDMAC1Reg->DMACIntTCClear = 0xff;			// TC Int Pending Clear
	g_pDMAC1Reg->DMACIntErrClear = 0xff;			// Err Int Pending Clear
}

static void InitializeVIC(void)
{
	// Disable All Interrupts
	g_pVIC0Reg->VICINTENCLEAR = 0xFFFFFFFF;
	g_pVIC1Reg->VICINTENCLEAR = 0xFFFFFFFF;
	g_pVIC0Reg->VICSOFTINTCLEAR = 0xFFFFFFFF;
	g_pVIC1Reg->VICSOFTINTCLEAR = 0xFFFFFFFF;

	// Clear Current Active Vector Address
	g_pVIC0Reg->VICADDRESS = 0x0;
	g_pVIC1Reg->VICADDRESS = 0x0;

	// Initialize Vector Address Table
	VICTableInit();

	// Disable Vectored Interrupt Mode on CP15
	System_DisableVIC();

	// Enable IRQ Interrupt on CP15
	System_EnableIRQ();

	// Enable FIQ Interrupt on CP15
	System_EnableFIQ();
}

void VICTableInit(void)
{
	// This Function is reference by OEMPowerOff() in "Off.c"
	// Make Sure that Caller and This function is in Same Address Space

	// Fill Vector Address of VIC0
	// Actually, Filled with Physical IRQ Numbers.
	// Because We do not use vectored interrupt feature

	g_pVIC0Reg->VICVECTADDR0 = PHYIRQ_EINT0;
	g_pVIC0Reg->VICVECTADDR1 = PHYIRQ_EINT1;
	g_pVIC0Reg->VICVECTADDR2 = PHYIRQ_RTC_TIC;
	g_pVIC0Reg->VICVECTADDR3 = PHYIRQ_CAMIF_C;
	g_pVIC0Reg->VICVECTADDR4 = PHYIRQ_CAMIF_P;
#if		(CPU_NAME == S3C6410)
	g_pVIC0Reg->VICVECTADDR5 = PHYIRQ_I2C1;
	g_pVIC0Reg->VICVECTADDR6 = PHYIRQ_I2S_V40;
	g_pVIC0Reg->VICVECTADDR7 = PHYIRQ_GPS;
	g_pVIC0Reg->VICVECTADDR8 = PHYIRQ_3D;
#elif	(CPU_NAME == S3C6400)
	g_pVIC0Reg->VICVECTADDR5 = PHYIRQ_CAMIF_MC;
	g_pVIC0Reg->VICVECTADDR6 = PHYIRQ_CAMIF_MP;
	g_pVIC0Reg->VICVECTADDR7 = PHYIRQ_CAMIF_WE_C;
	g_pVIC0Reg->VICVECTADDR8 = PHYIRQ_CAMIF_WE_P;
#endif
	g_pVIC0Reg->VICVECTADDR9 = PHYIRQ_POST;
	g_pVIC0Reg->VICVECTADDR10 = PHYIRQ_ROTATOR;
	g_pVIC0Reg->VICVECTADDR11 = PHYIRQ_2D;
	g_pVIC0Reg->VICVECTADDR12 = PHYIRQ_TVENC;
	g_pVIC0Reg->VICVECTADDR13 = PHYIRQ_TVSCALER;
	g_pVIC0Reg->VICVECTADDR14 = PHYIRQ_BATF;
	g_pVIC0Reg->VICVECTADDR15 = PHYIRQ_JPEG;
	g_pVIC0Reg->VICVECTADDR16 = PHYIRQ_MFC;
	g_pVIC0Reg->VICVECTADDR17 = PHYIRQ_SDMA0;
	g_pVIC0Reg->VICVECTADDR18 = PHYIRQ_SDMA1;
	g_pVIC0Reg->VICVECTADDR19 = PHYIRQ_ARM_DMAERR;
	g_pVIC0Reg->VICVECTADDR20 = PHYIRQ_ARM_DMA;
	g_pVIC0Reg->VICVECTADDR21 = PHYIRQ_ARM_DMAS;
	g_pVIC0Reg->VICVECTADDR22 = PHYIRQ_KEYPAD;
	g_pVIC0Reg->VICVECTADDR23 = PHYIRQ_TIMER0;
	g_pVIC0Reg->VICVECTADDR24 = PHYIRQ_TIMER1;
	g_pVIC0Reg->VICVECTADDR25 = PHYIRQ_TIMER2;
	g_pVIC0Reg->VICVECTADDR26 = PHYIRQ_WDT;
	g_pVIC0Reg->VICVECTADDR27 = PHYIRQ_TIMER3;
	g_pVIC0Reg->VICVECTADDR28 = PHYIRQ_TIMER4;
	g_pVIC0Reg->VICVECTADDR29 = PHYIRQ_LCD0_FIFO;
	g_pVIC0Reg->VICVECTADDR30 = PHYIRQ_LCD1_FRAME;
	g_pVIC0Reg->VICVECTADDR31 = PHYIRQ_LCD2_SYSIF;

	// Fill Vector Address of VIC1
	g_pVIC1Reg->VICVECTADDR0 = PHYIRQ_EINT2;
	g_pVIC1Reg->VICVECTADDR1 = PHYIRQ_EINT3;
	g_pVIC1Reg->VICVECTADDR2 = PHYIRQ_PCM0;
	g_pVIC1Reg->VICVECTADDR3 = PHYIRQ_PCM1;
	g_pVIC1Reg->VICVECTADDR4 = PHYIRQ_AC97;
	g_pVIC1Reg->VICVECTADDR5 = PHYIRQ_UART0;
	g_pVIC1Reg->VICVECTADDR6 = PHYIRQ_UART1;
	g_pVIC1Reg->VICVECTADDR7 = PHYIRQ_UART2;
	g_pVIC1Reg->VICVECTADDR8 = PHYIRQ_UART3;
	g_pVIC1Reg->VICVECTADDR9 = PHYIRQ_DMA0;
	g_pVIC1Reg->VICVECTADDR10 = PHYIRQ_DMA1;
	g_pVIC1Reg->VICVECTADDR11 = PHYIRQ_ONENAND0;
	g_pVIC1Reg->VICVECTADDR12 = PHYIRQ_ONENAND1;
	g_pVIC1Reg->VICVECTADDR13 = PHYIRQ_NFC;
	g_pVIC1Reg->VICVECTADDR14 = PHYIRQ_CFC;
	g_pVIC1Reg->VICVECTADDR15 = PHYIRQ_UHOST;
	g_pVIC1Reg->VICVECTADDR16 = PHYIRQ_SPI0;
	g_pVIC1Reg->VICVECTADDR17 = PHYIRQ_SPI1;
	g_pVIC1Reg->VICVECTADDR18 = PHYIRQ_I2C;
	g_pVIC1Reg->VICVECTADDR19 = PHYIRQ_HSITX;
	g_pVIC1Reg->VICVECTADDR20 = PHYIRQ_HSIRX;
	g_pVIC1Reg->VICVECTADDR21 = PHYIRQ_RESERVED;
	g_pVIC1Reg->VICVECTADDR22 = PHYIRQ_MSM;
	g_pVIC1Reg->VICVECTADDR23 = PHYIRQ_HOSTIF;
	g_pVIC1Reg->VICVECTADDR24 = PHYIRQ_HSMMC0;
	g_pVIC1Reg->VICVECTADDR25 = PHYIRQ_HSMMC1;
	g_pVIC1Reg->VICVECTADDR26 = PHYIRQ_OTG;
	g_pVIC1Reg->VICVECTADDR27 = PHYIRQ_IRDA;
	g_pVIC1Reg->VICVECTADDR28 = PHYIRQ_RTC_ALARM;
	g_pVIC1Reg->VICVECTADDR29 = PHYIRQ_SEC;
	g_pVIC1Reg->VICVECTADDR30 = PHYIRQ_PENDN;
	g_pVIC1Reg->VICVECTADDR31 = PHYIRQ_ADC;
}

//------------------------------------------------------------------------------

⌨️ 快捷键说明

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