Mips TLB Miss implementation in Linux__linux

Source: Internet
Author: User
Tags reserved

TLB Miss is the core process of memory management in MIPS. In the previous article on MIPS, TLB miss related principles, this article focuses on the Linux kernel code implementation. TLB Refill Initialization

In the kernel boot process, the TLB refill exception is initialized and the corresponding processing interface is set. The main processes are as follows (take r3k as an example):

Start_secondary
  per_cpu_trap_init
    tlb_init
      build_tlb_refill_handler
        Build_r3000_tlb_refill_ Handler

The operation of the specific settings handler is performed at Build_r3000_tlb_refill_handler, and the code is as follows:

  * * The R3000 TLB handler is simple.
 * * * Standard TLB Refill code, relatively simple, with only one page table, with the MIPS manual in the Basic Agreement.
	*/static void Build_r3000_tlb_refill_handler (void) {/* page directory */Long PGDC = (long) pgd_current;
  U32 *p;
	/* Initialize TLB Processing interface * * memset (tlb_handler, 0, sizeof (Tlb_handler));
  p = Tlb_handler;
	/* Read the virtual address that generated the exception * * UASM_I_MFC0 (&p, K0, c0_badvaddr); Uasm_i_lui (&p, K1, Uasm_rel_hi (PGDC));
	/* CP0 Delay * * UASM_I_LW (&p, K1, Uasm_rel_lo (PGDC), K1); UASM_I_SRL (&p, K0, K0, 22);
	/* Load Delay * * UASM_I_SLL (&p, K0, K0, 2);
  Uasm_i_addu (&p, K1, K1, K0);
	/* Read the information from the context Register/* UASM_I_MFC0 (&p, K0, C0_context); UASM_I_LW (&p, K1, 0, K1); /* CP0 Delay * * Uasm_i_andi (&p, K0, K0, 0XFFC);
	/* Load Delay * * UASM_I_ADDU (&p, K1, K1, K0);
	UASM_I_LW (&p, K0, 0, K1); Uasm_i_nop (&P); /* Read EPC registers, which save the exception return address * * UASM_I_MFC0 (&p, K1, C0_EPC); /* CP0 Delay */* TLBWR instruction, write TLB/UASM_I_TLBWR (&p) According to ENTRYLO0 Register contents (from page table, via context Register index);
	/* cp0 delay/* Jump to the exception return address, exit abnormal * * * UASM_I_JR (&p, K1); Uasm_i_rfe (&P); /* Branch delay/* key point: Copy the Tlb_handler (that is, the TLB refill exception handler function) to Ebase * (MIPS is the abnormal allocated physical address space (size is 0x80), with EB
   ASE registers point to, in simple cases, * Physical Address 0x0), when the TLB refill exception occurs, the hardware automatically jumps to the ebase corresponding address execution.
  * * memcpy (void *) Ebase, Tlb_handler, 0x80);
 ...
}

It can be seen that the TLB refill exception processing function code, is the kernel dynamic settings, rather than the assembly of static code, due to the MIPS hardware model more, so the operation more flexible.

Also, note that the TLB refill exception handling function entry is located at the fixed physical address: 0x0. General Exception Initialization

During kernel boot, the corresponding exception handling interface for general exception is initialized, the main process is as follows:

Start_kernel
  Trap_init

Trap_init complete the exception-related initialization operation, the main code is as follows:

void __init trap_init (void) {//General exception processing interface extern char except_vec3_generic;
	 ... * * Copy the generic exception handlers to their final destination.
	 * This is overriden later as suitable for a particular * configuration. * * * To copy the general exception processing function (instruction) to the 0x180 (physical address), 0x180 is r4000 above * MIPS CPU in the general exception default entry address, the physical address space size of 0x
   80, dedicated * reserved for general exception processing.

	* * Set_handler (0x180, &except_vec3_generic, 0x80);
   * * Setup Default vectors//x* for exception 0-31 to set the defaults processing interface, general exception corresponding number is 3,tlb refill exception * corresponding to the number 1.

  * for (i = 0; I <= i++) set_except_vector (i, handle_reserved);
   ... * * General exception is the total entry point for all common priority exceptions, where different processing * interfaces are invoked according to the exception code, and here is the corresponding processing interface for setting different exceptions. * Note: The 2nd anomaly code corresponds to the **page fault** exception, that is, the TLB load exception, the processing interface is HANDLE_TLBL/set_except_vector (0, Using_rollback_handler ()? rollback
	_handle_int:handle_int);
	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 system call Processing interface * * Set_except_vector (8, Handle_sys);
   * * According to the different CPU type, set the corresponding general exception processing interface address, corresponding R4, address is * 0x180, other (older) is 0x80. */if (CPU_HAS_VCE)/* Special exception:r4[04]00 uses also the Divec space.
	* * Set_handler (0x180, &except_vec3_r4000, 0x100);
	else if (Cpu_has_4kex) Set_handler (0x180, &except_vec3_generic, 0x80);
  else Set_handler (0x080, &except_vec3_generic, 0x80);
 ...
}
General Exception Processing

The general exception is processed in the Except_vec3_generic function to assemble the implementation, where the main work is to read the exception type code Exccode and then invoke the corresponding processing interface. The main code is as follows (Genex. S file):

 * * General exception vectors for all other CPUs.
 *
 * is careful when changing this, it has to is at most 128 bytes * to fit into spaces reserved for the
 exception h Andler.
 * * * * assembly code, eventually copied to the physical address of the 0x180, note that this physical address space is limited in size, the largest 128
 * bytes (0x80), so processing can not be too complex.
 */
NESTED (except_vec3_generic, 0, SP)
	. Set	push
	. Set	noat
#if r5432_cp0_interrupt_war
	MFC0	K0, Cp0_index
#endif
	mfc0	K1, cp0_cause  //Read the exception type code from the Cp0_cause register
	Exccode	K1, K1, 0x7c
#ifdef config_64bit
	dsll K1,	K1, 1
#endif
  /
   * * According to type code, strip Exception_ The corresponding interface in the handlers, the processing interface in Exception_handlers
   is set at Trap_init initialization.
   */
	ptr_l	K0, Exception_handlers (K1)
	Jr	K0
	. Set	pop end
	(except_vec3_generic)
TLB Load Exception handling initialization

In the previous general exception initialization process, only the general exception processing portal and different exception code corresponding to the processing interface, but and set up the specific exception handling function, that is, the exception occurred after the specific execution of the code, the initialization is in another process:

Start_secondary
  per_cpu_trap_init
    tlb_init
      build_tlb_refill_handler
        build_r3000_tlb_load_ Handler

Implementation in the Build_r3000_tlb_load_handler function, the key code is as follows:

static void Build_r3000_tlb_load_handler (void)
{
	u32 *p = handle_tlbl;
	const int handle_tlbl_size = HANDLE_TLBL_END-HANDLE_TLBL;
  ...
  /* Initialize *
	/memset (HANDLE_TLBL, 0, handle_tlbl_size * sizeof (handle_tlbl[0));
  ...
   * * Write assembly code, equivalent to J Tlb_do_page_fault_0, that is, jump directly to the TLB_DO_PAGE_FAULT_0 place
   * execution, that is, call the TLB_DO_PAGE_FAULT_0 function * *
	Uasm_i_j (&p, (unsigned long) Tlb_do_page_fault_0 & 0X0FFFFFFF);
	Uasm_i_nop (&p);
  ...
}
TLB Load Exception handling (Page Fault)

As the previous code analysis, the TLB load exception processing interface, in fact, is to call the TLB_DO_PAGE_FAULT_0 function, and then look at this function implementation (assembly code, in Tlbex-fault. S file):

/* Tlb_do_page_fault_0 and tlb_do_page_fault_1 together, through macro control/
macro Tlb_do_page_fault, write
NESTED (tlb_do_page _fault_\write, pt_size, SP)/
* Save context/
save_all
* Read the virtual address of the send exception/
MFC0	A2, Cp0_badvaddr
Kmode
Move	A0, SP
reg_s	A2, pt_bvaddr (SP)
Li	A1, \write
ptr_la	ra, ret_from_ Exception/
* Key point: Call the Do_page_fault function *	/J Do_page_fault End
(tlb_do_page_fault_\write)
. Endm

The code is very simple, in addition to saving context, such as operations, is called the Do_page_fault function, this is our very familiar page fault standard interface, which will allocate memory, and add page table entries, establish virtual address and physical address mapping relationship. Here is not said, previously written analysis of the document.


Original address: http://happyseeker.github.io/kernel/2016/12/28/mips-TLB-miss-implemented-in-linux.html

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.