Home | History | Annotate | Download | only in asm-x86
      1 #ifndef _ASM_SEGMENT_H
      2 #define _ASM_SEGMENT_H
      3 
      4 /*
      5  * The layout of the per-CPU GDT under Linux:
      6  *
      7  *   0 - null
      8  *   1 - reserved
      9  *   2 - reserved
     10  *   3 - reserved
     11  *
     12  *   4 - unused			<==== new cacheline
     13  *   5 - unused
     14  *
     15  *  ------- start of TLS (Thread-Local Storage) segments:
     16  *
     17  *   6 - TLS segment #1			[ glibc's TLS segment ]
     18  *   7 - TLS segment #2			[ Wine's %fs Win32 segment ]
     19  *   8 - TLS segment #3
     20  *   9 - reserved
     21  *  10 - reserved
     22  *  11 - reserved
     23  *
     24  *  ------- start of kernel segments:
     25  *
     26  *  12 - kernel code segment		<==== new cacheline
     27  *  13 - kernel data segment
     28  *  14 - default user CS
     29  *  15 - default user DS
     30  *  16 - TSS
     31  *  17 - LDT
     32  *  18 - PNPBIOS support (16->32 gate)
     33  *  19 - PNPBIOS support
     34  *  20 - PNPBIOS support
     35  *  21 - PNPBIOS support
     36  *  22 - PNPBIOS support
     37  *  23 - APM BIOS support
     38  *  24 - APM BIOS support
     39  *  25 - APM BIOS support
     40  *
     41  *  26 - ESPFIX small SS
     42  *  27 - per-cpu			[ offset to per-cpu data area ]
     43  *  28 - unused
     44  *  29 - unused
     45  *  30 - unused
     46  *  31 - TSS for double fault handler
     47  */
     48 #define GDT_ENTRY_TLS_ENTRIES	3
     49 #define GDT_ENTRY_TLS_MIN	6
     50 #define GDT_ENTRY_TLS_MAX 	(GDT_ENTRY_TLS_MIN + GDT_ENTRY_TLS_ENTRIES - 1)
     51 
     52 #define TLS_SIZE (GDT_ENTRY_TLS_ENTRIES * 8)
     53 
     54 #define GDT_ENTRY_DEFAULT_USER_CS	14
     55 #define __USER_CS (GDT_ENTRY_DEFAULT_USER_CS * 8 + 3)
     56 
     57 #define GDT_ENTRY_DEFAULT_USER_DS	15
     58 #define __USER_DS (GDT_ENTRY_DEFAULT_USER_DS * 8 + 3)
     59 
     60 #define GDT_ENTRY_KERNEL_BASE	12
     61 
     62 #define GDT_ENTRY_KERNEL_CS		(GDT_ENTRY_KERNEL_BASE + 0)
     63 #define __KERNEL_CS (GDT_ENTRY_KERNEL_CS * 8)
     64 
     65 #define GDT_ENTRY_KERNEL_DS		(GDT_ENTRY_KERNEL_BASE + 1)
     66 #define __KERNEL_DS (GDT_ENTRY_KERNEL_DS * 8)
     67 
     68 #define GDT_ENTRY_TSS			(GDT_ENTRY_KERNEL_BASE + 4)
     69 #define GDT_ENTRY_LDT			(GDT_ENTRY_KERNEL_BASE + 5)
     70 
     71 #define GDT_ENTRY_PNPBIOS_BASE		(GDT_ENTRY_KERNEL_BASE + 6)
     72 #define GDT_ENTRY_APMBIOS_BASE		(GDT_ENTRY_KERNEL_BASE + 11)
     73 
     74 #define GDT_ENTRY_ESPFIX_SS		(GDT_ENTRY_KERNEL_BASE + 14)
     75 #define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS * 8)
     76 
     77 #define GDT_ENTRY_PERCPU			(GDT_ENTRY_KERNEL_BASE + 15)
     78 #ifdef CONFIG_SMP
     79 #define __KERNEL_PERCPU (GDT_ENTRY_PERCPU * 8)
     80 #else
     81 #define __KERNEL_PERCPU 0
     82 #endif
     83 
     84 #define GDT_ENTRY_DOUBLEFAULT_TSS	31
     85 
     86 /*
     87  * The GDT has 32 entries
     88  */
     89 #define GDT_ENTRIES 32
     90 #define GDT_SIZE (GDT_ENTRIES * 8)
     91 
     92 /* Simple and small GDT entries for booting only */
     93 
     94 #define GDT_ENTRY_BOOT_CS		2
     95 #define __BOOT_CS	(GDT_ENTRY_BOOT_CS * 8)
     96 
     97 #define GDT_ENTRY_BOOT_DS		(GDT_ENTRY_BOOT_CS + 1)
     98 #define __BOOT_DS	(GDT_ENTRY_BOOT_DS * 8)
     99 
    100 /* The PnP BIOS entries in the GDT */
    101 #define GDT_ENTRY_PNPBIOS_CS32		(GDT_ENTRY_PNPBIOS_BASE + 0)
    102 #define GDT_ENTRY_PNPBIOS_CS16		(GDT_ENTRY_PNPBIOS_BASE + 1)
    103 #define GDT_ENTRY_PNPBIOS_DS		(GDT_ENTRY_PNPBIOS_BASE + 2)
    104 #define GDT_ENTRY_PNPBIOS_TS1		(GDT_ENTRY_PNPBIOS_BASE + 3)
    105 #define GDT_ENTRY_PNPBIOS_TS2		(GDT_ENTRY_PNPBIOS_BASE + 4)
    106 
    107 /* The PnP BIOS selectors */
    108 #define PNP_CS32   (GDT_ENTRY_PNPBIOS_CS32 * 8)	/* segment for calling fn */
    109 #define PNP_CS16   (GDT_ENTRY_PNPBIOS_CS16 * 8)	/* code segment for BIOS */
    110 #define PNP_DS     (GDT_ENTRY_PNPBIOS_DS * 8)	/* data segment for BIOS */
    111 #define PNP_TS1    (GDT_ENTRY_PNPBIOS_TS1 * 8)	/* transfer data segment */
    112 #define PNP_TS2    (GDT_ENTRY_PNPBIOS_TS2 * 8)	/* another data segment */
    113 
    114 /*
    115  * The interrupt descriptor table has room for 256 idt's,
    116  * the global descriptor table is dependent on the number
    117  * of tasks we can have..
    118  */
    119 #define IDT_ENTRIES 256
    120 
    121 /* Bottom two bits of selector give the ring privilege level */
    122 #define SEGMENT_RPL_MASK	0x3
    123 /* Bit 2 is table indicator (LDT/GDT) */
    124 #define SEGMENT_TI_MASK		0x4
    125 
    126 /* User mode is privilege level 3 */
    127 #define USER_RPL		0x3
    128 /* LDT segment has TI set, GDT has it cleared */
    129 #define SEGMENT_LDT		0x4
    130 #define SEGMENT_GDT		0x0
    131 
    132 #ifndef CONFIG_PARAVIRT
    133 #define get_kernel_rpl()  0
    134 #endif
    135 /*
    136  * Matching rules for certain types of segments.
    137  */
    138 
    139 /* Matches only __KERNEL_CS, ignoring PnP / USER / APM segments */
    140 #define SEGMENT_IS_KERNEL_CODE(x) (((x) & 0xfc) == GDT_ENTRY_KERNEL_CS * 8)
    141 
    142 /* Matches __KERNEL_CS and __USER_CS (they must be 2 entries apart) */
    143 #define SEGMENT_IS_FLAT_CODE(x)  (((x) & 0xec) == GDT_ENTRY_KERNEL_CS * 8)
    144 
    145 /* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */
    146 #define SEGMENT_IS_PNP_CODE(x)   (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8)
    147 
    148 #endif
    149