|
@@ -25,7 +25,33 @@
|
|
|
DEFINE_PER_CPU(struct Xgt_desc_struct, cpu_gdt_descr);
|
|
|
EXPORT_PER_CPU_SYMBOL(cpu_gdt_descr);
|
|
|
|
|
|
-DEFINE_PER_CPU(struct desc_struct, cpu_gdt[GDT_ENTRIES]);
|
|
|
+DEFINE_PER_CPU(struct desc_struct, cpu_gdt[GDT_ENTRIES]) = {
|
|
|
+ [GDT_ENTRY_KERNEL_CS] = { 0x0000ffff, 0x00cf9a00 },
|
|
|
+ [GDT_ENTRY_KERNEL_DS] = { 0x0000ffff, 0x00cf9200 },
|
|
|
+ [GDT_ENTRY_DEFAULT_USER_CS] = { 0x0000ffff, 0x00cffa00 },
|
|
|
+ [GDT_ENTRY_DEFAULT_USER_DS] = { 0x0000ffff, 0x00cff200 },
|
|
|
+ /*
|
|
|
+ * Segments used for calling PnP BIOS have byte granularity.
|
|
|
+ * They code segments and data segments have fixed 64k limits,
|
|
|
+ * the transfer segment sizes are set at run time.
|
|
|
+ */
|
|
|
+ [GDT_ENTRY_PNPBIOS_CS32] = { 0x0000ffff, 0x00409a00 },/* 32-bit code */
|
|
|
+ [GDT_ENTRY_PNPBIOS_CS16] = { 0x0000ffff, 0x00009a00 },/* 16-bit code */
|
|
|
+ [GDT_ENTRY_PNPBIOS_DS] = { 0x0000ffff, 0x00009200 }, /* 16-bit data */
|
|
|
+ [GDT_ENTRY_PNPBIOS_TS1] = { 0x00000000, 0x00009200 },/* 16-bit data */
|
|
|
+ [GDT_ENTRY_PNPBIOS_TS2] = { 0x00000000, 0x00009200 },/* 16-bit data */
|
|
|
+ /*
|
|
|
+ * The APM segments have byte granularity and their bases
|
|
|
+ * are set at run time. All have 64k limits.
|
|
|
+ */
|
|
|
+ [GDT_ENTRY_APMBIOS_BASE] = { 0x0000ffff, 0x00409a00 },/* 32-bit code */
|
|
|
+ /* 16-bit code */
|
|
|
+ [GDT_ENTRY_APMBIOS_BASE+1] = { 0x0000ffff, 0x00009a00 },
|
|
|
+ [GDT_ENTRY_APMBIOS_BASE+2] = { 0x0000ffff, 0x00409200 }, /* data */
|
|
|
+
|
|
|
+ [GDT_ENTRY_ESPFIX_SS] = { 0x00000000, 0x00c09200 },
|
|
|
+ [GDT_ENTRY_PDA] = { 0x00000000, 0x00c09200 }, /* set in setup_pda */
|
|
|
+};
|
|
|
|
|
|
DEFINE_PER_CPU(struct i386_pda, _cpu_pda);
|
|
|
EXPORT_PER_CPU_SYMBOL(_cpu_pda);
|
|
@@ -618,46 +644,6 @@ struct i386_pda boot_pda = {
|
|
|
.pcurrent = &init_task,
|
|
|
};
|
|
|
|
|
|
-static inline void set_kernel_fs(void)
|
|
|
-{
|
|
|
- /* Set %fs for this CPU's PDA. Memory clobber is to create a
|
|
|
- barrier with respect to any PDA operations, so the compiler
|
|
|
- doesn't move any before here. */
|
|
|
- asm volatile ("mov %0, %%fs" : : "r" (__KERNEL_PDA) : "memory");
|
|
|
-}
|
|
|
-
|
|
|
-/* Initialize the CPU's GDT and PDA. This is either the boot CPU doing itself
|
|
|
- (still using cpu_gdt_table), or a CPU doing it for a secondary which
|
|
|
- will soon come up. */
|
|
|
-__cpuinit void init_gdt(int cpu, struct task_struct *idle)
|
|
|
-{
|
|
|
- struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu);
|
|
|
- struct desc_struct *gdt = per_cpu(cpu_gdt, cpu);
|
|
|
- struct i386_pda *pda = &per_cpu(_cpu_pda, cpu);
|
|
|
-
|
|
|
- memcpy(gdt, cpu_gdt_table, GDT_SIZE);
|
|
|
- cpu_gdt_descr->address = (unsigned long)gdt;
|
|
|
- cpu_gdt_descr->size = GDT_SIZE - 1;
|
|
|
-
|
|
|
- pack_descriptor((u32 *)&gdt[GDT_ENTRY_PDA].a,
|
|
|
- (u32 *)&gdt[GDT_ENTRY_PDA].b,
|
|
|
- (unsigned long)pda, sizeof(*pda) - 1,
|
|
|
- 0x80 | DESCTYPE_S | 0x2, 0); /* present read-write data segment */
|
|
|
-
|
|
|
- memset(pda, 0, sizeof(*pda));
|
|
|
- pda->_pda = pda;
|
|
|
- pda->cpu_number = cpu;
|
|
|
- pda->pcurrent = idle;
|
|
|
-}
|
|
|
-
|
|
|
-void __cpuinit cpu_set_gdt(int cpu)
|
|
|
-{
|
|
|
- struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu);
|
|
|
-
|
|
|
- load_gdt(cpu_gdt_descr);
|
|
|
- set_kernel_fs();
|
|
|
-}
|
|
|
-
|
|
|
/* Common CPU init for both boot and secondary CPUs */
|
|
|
static void __cpuinit _cpu_init(int cpu, struct task_struct *curr)
|
|
|
{
|
|
@@ -740,10 +726,6 @@ void __cpuinit cpu_init(void)
|
|
|
int cpu = smp_processor_id();
|
|
|
struct task_struct *curr = current;
|
|
|
|
|
|
- /* Set up the real GDT and PDA, so we can transition from the
|
|
|
- boot_gdt_table & boot_pda. */
|
|
|
- init_gdt(cpu, curr);
|
|
|
- cpu_set_gdt(cpu);
|
|
|
_cpu_init(cpu, curr);
|
|
|
}
|
|
|
|