当前位置:网站首页>Explanation of core interrupt of Godson processor

Explanation of core interrupt of Godson processor

2022-06-12 17:57:00 _ kerneler

/*
* Statement :
*
* Article transferred from : Big 、 cat
*
* link :https://blog.csdn.net/tongxin1101124/article/details/104993993
*
* Reprint usage : Only for backup and learning
*/

Explanation of core interrupt of Godson processor

Explanation of core interrupt of Godson processor

Godson processor is used here ls2k1000 As an example to explain

1、 Interrupt related coprocessor

①  Reason register (Cause)
 Insert picture description here
IP7-0 Indicate the interruption of waiting . This bit will remain unchanged until the interrupt is removed .IP0~IP1 It is the soft middle position ,IP2-IP6 Each represents a set of interrupt sources ,IP7 Represents an internal timer .
ExcCode It's a 5 Bit code , Tell me what kind of exception occurred , If an exception occurs and ExcCode by 0 It indicates an interrupt exception .
Cause The register of ExcCode Domain

ExcCode Mnemonic symbol describe
0INT interrupt
1MODTLB Modify exceptions
2TLBLTLB exception ( Read or fetch instructions )
3TLBSTLB exception ( Storage )
4~7… … …… … …
8SYS System call exception
9~31… … …… … …

②  Status register (SR)
 Insert picture description here
BEV Startup exception vector , When BEV==1 when ,CPU use ROM Abnormal entrance of space .
IM7-0 Interrupt mask :8 Bit fields , Determine which group of interrupts can trigger an exception when there is a request . for example IM2 Set up 1,cpu The group of interrupt sources corresponding to this bit can be received .
IE Enable global interrupt , Only this position 1 when ,CPU Interrupt exceptions can be accepted . if ERL and EXL Set up 1, Even if this position 1 It also disables all interrupts .
EXL When an exception occurs CPU I'll set 1 This bit , The purpose is to force CPU Enter kernel mode and disable interrupts , These are all done automatically by hardware , This bit is clear 0 Instructions are needed eret.

2、 The hardware works

When an exception occurs cpu Work done by hardware initiatively :
①  Set up EPC( Exception return address register ),
②  Set up SR(EXL) Bit forcing CPU Enter kernel mode and disable interrupts
③  Set up Cause register , Enable the software to see the cause of the exception
④ CPU Take the instruction from the exception entry point to execute

cpu It will jump to the exception handling entry to fetch instructions , The exception handling entry under the kernel is set to 0x80000180, And according to the regulations, this code cannot exceed 128 Bytes , For the above details, please refer to *《MIPS Architecture perspective 》

3、 Software works

When the kernel starts, it will call trap_init function

===>start_kernel (init/main.c)
	===>trap_init (arch/mips/kernel/traps.c)
		===>set_handler
			set_except_vector

     
      
  • 1
  • 2
  • 3
  • 4

trap_init Function to fill the exception handler into the exception entry point , This function is located in arch/mips/kernel/traps.c in , There are the following statements in this function :

set_handler(0x180, &except_vec3_generic, 0x80);

     
      
  • 1

The function of a statement is to put a function excpet_vec3_generic Copy to exception entry point :0x80000180, This function is the exception handler , Function in arch/mips/kernel/genex.S in , This function is very short and will not exceed 128 Bytes .

NESTED(except_vec3_generic, 0, sp)                                                                                                           
     .set    push
     .set    noat
 	 ... ... ... ...
     mfc0    k1, CP0_CAUSE			      /* Read reason register */
     andi    k1, k1, 0x7c				  /* Take out the exception code */
 	 ... ... ... ...
     PTR_L   k0, exception_handlers(k1)  /* According to the exception code, put the address of the corresponding exception function into  K0  In the register */                        
     jr  k0							     /* Handle different exceptions according to the exception code */
     .set    pop
END(except_vec3_generic)

     
      
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

exception_handlers It's defined in arch/mips/kernel/traps.c, Let's list the definitions :

unsigned long exception_handlers[32];

     
      
  • 1

exception_handlers Yes. 32 Array of elements , And the reason register ExcCode It's also 32,exception_handlers[32] Each array element corresponds to an exception , such as exception_handlers[0] Corresponds to an interrupt or exception_handlers[8] To use the system call . When an exception occurs exception_handlers[32] Array , So this array must be initialized before an exception occurs , The initialization of the array is in the function trap_init Function , List and initialize exception_handlers[32] Array related code :

set_except_vector(0, handle_int);		 /*handle_int Interrupt handling function */
set_except_vector(1, handle_tlbm);
set_except_vector(2, handle_tlbl);
set_except_vector(3, handle_tlbs);

set_except_vector(4, handle_adel);
set_except_vector(5, handle_ades);

set_except_vector(6, handle_ibe);
set_except_vector(7, handle_dbe);

set_except_vector(8, handle_sys);
set_except_vector(9, handle_bp);
... ... ... ...

When an interruption occurs, it will be based on ExcCode choice handle_int Function execution , The function is defined in arch/mips/kernel/genex.S,handle_int Function and make corresponding comments :

NESTED(handle_int, PT_SIZE, sp)
 ... ... ... ...
     SAVE_ALL			/* The function is defined in  include/asm/stackframe.h*/ 
/* Due to the random type of interruption , And you need to return from the interrupt , So when an interrupt occurs , The site environment must be preserved , This function mainly includes various registers and so on */                                                                      
     CLI                                                                                          
     TRACE_IRQS_OFF                                                                               
                                                                                                  
     LONG_L  s0, TI_REGS($28)                                                                     
     LONG_S  sp, TI_REGS($28)                                                                     
     PTR_LA  ra, ret_from_irq	/* The function is defined in  arch/mips/kernel/entry.S*/     
/* Save the function address to  ra  in , When the slave function plat_irq_dispatch  Will execute after returning from  ret_from_irq  In the implementation of ,ra A register stores the return instructions of a subroutine */                                                        
     PTR_LA  v0, plat_irq_dispatch                                                                
     jr  v0                                                                                                                                                                         
     END(handle_int)

 
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

function plat_irq_dispatch It's defined in arch/mips/loongson2/irq.c in , Function according to the reason register (IP7-0) Execute interrupt handler .

asmlinkage void plat_irq_dispatch(void)                                                       
{
                                                                                                 
     unsigned int cp0_cause;                                                                                                                  
     unsigned int cp0_status;                                                                  
     unsigned int cp0_cause_saved;                                                             
     cp0_cause_saved = read_c0_cause() & ST0_IM ;                                              
     cp0_status = read_c0_status();                                                            
     cp0_cause = cp0_cause_saved & cp0_status;                                                 
                                                                                                                                                                                              
     if (cp0_cause & STATUSF_IP7)                                                              
         ip7_dispatch();                                                                       
                                                                                               
 #ifdef CONFIG_SMP 
     else if (cp0_cause & STATUSF_IP6)                                                         
         ip6_dispatch();                                                                       
                                                                                               
 #endif 
     else if (cp0_cause & STATUSF_IP5)                                                         
         ip5_dispatch();                                                                       
     else                                                                                      
         ip4_dispatch();                                                                       
                                                                                               
 }

After the interrupt is generated, the kernel looks for the interrupt handling function flow defined in the driver :

==>handle_int  (arch/mips/kernel/genex.S)
	==>plat_irq_dispatch (arch/mips/loongson2/irq.c)
		==>ip*_dispatch (arch/mips/loongson2/irq.c)
			==> do_IRQ (arch/mips/kernel/irq.c)
				==>generic_handle_irq (kernel/irq/irqdesc.c)
					==>generic_handle_irq_desc (include/linux/irqdesc.h)
						==> desc->handle_irq

 
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

desc->handle_irq origin

==>start_kernel (init/main.c)
	==>init_IRQ (arch/mips/kernel/irq.c)
		==>arch_init_irq	(arch/mips/loongson2/irq.c)
			==>setup_irq_default (arch/mips/loongson2/irq.c)
				==> irq_set_chip_and_handler (include/linux/irq.h)
					==>irq_set_chip_and_handler_name (kernel/irq/chip.c)
						==> irq_set_chip
						 	__irq_set_handler

 
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

__irq_set_handler It's defined in desc->handle_irq = handle, and handle To pass parameters , the truth is that handle_level_irq function .

==>handle_level_irq (kernel/irq/chip.c)
	==>handle_irq_event (kernel/irq/handle.c)
		==>handle_irq_event_percpu 
			==>__handle_irq_event_percpu
				==> action->handler  Call the registered interrupt handler 

 
  
  • 1
  • 2
  • 3
  • 4
  • 5

The above roughly describes when an interrupt exception occurs , How exactly the kernel is found request_irq Function registered interrupt handling function .

4、 Peripheral interrupt

①  Interrupt registration
stay 3.10 The functions used in the kernel to apply for interrupts are request_irq, The function prototype is include/linux/interrupt.h In the definition of :

static inline int __must_check
request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
         const char *name, void *dev)
 {
    
     return request_threaded_irq(irq, handler, NULL, flags, name, dev);
 } 

 
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

irq: Is the hardware interrupt number to apply for
handler: Is an interrupt handling function registered with the system , Is a callback function , When the interruption occurs , The system calls this function ,dev_id Parameters will be passed to it .
irqflags: Is the property of interrupt handling ,include/linux/interrupt.h Define the attributes of all interrupt handling in .
devname: Set interrupt name , Usually the name of the device driver , stay cat /proc/interrupts You can see this name in .
dev_id: It's used to interrupt sharing , It is generally set as the equipment structure of this equipment or NULL.
request_irq The function returns 0 It means success , return -INVAL Indicates that the interrupt number is invalid or the handler pointer is NULL, return -EBUSY Indicates that the interrupt has been occupied and cannot be shared .

request_threaded_irq The function prototype is kernel/irq/manage.c In the definition of , The interrupt handling function registered in this function handler Assigned to action->handler.

Godson 2K1000 The chip supports at most 64 Broken source , Manage in a unified way , The interrupt number of each peripheral can be set at arch/mips/include/asm/mach-loongson2/irq.h lookup .

②  Interrupt release
The logoff function is defined in kernel/irq/manage.c In the definition of :

void free_irq(unsigned int irq, void *dev_id)

 
  
  • 1

Return value : When the function runs normally, it returns 0 , Otherwise, a negative value corresponding to the error is returned .

原网站

版权声明
本文为[_ kerneler]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/163/202206121707443904.html