[haiku-commits] BRANCH xyzzy-github.x86_64 - in src/system: boot/platform/bios_ia32 kernel/arch/x86 kernel/arch/x86/32

  • From: xyzzy-github.x86_64 <community@xxxxxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 11 Jul 2012 19:49:14 +0200 (CEST)

added 1 changeset to branch 'refs/remotes/xyzzy-github/x86_64'
old head: 659bacac269ec0992603008ef436ee20505bd67f
new head: 76a1175dbe1a314563ca18c0b7fb82695a9730cd

----------------------------------------------------------------------------

76a1175: Support for SMP on x86_64.
  
  No major changes to the kernel: just compiled in arch_smp.cpp and fixed the
  IDT load in arch_cpu_init_percpu to use the correct limit for x86_64 (uses
  sizeof(interrupt_descriptor)). In the boot loader, changed smp_boot_other_cpus
  to construct a temporary GDT and get the page directory address from CR3, as
  what's in kernel_args will be 64-bit stuff and will not work to switch the
  CPUs into 32-bit mode in the trampoline code. Refactored 64-bit kernel entry
  code to not use the stack after disabling paging, as the secondary CPUs are
  given a 32-bit virtual stack address by the SMP trampoline code which will
  no longer work.

                                      [ Alex Smith <alex@xxxxxxxxxxxxxxxx> ]

----------------------------------------------------------------------------

Commit:      76a1175dbe1a314563ca18c0b7fb82695a9730cd

Author:      Alex Smith <alex@xxxxxxxxxxxxxxxx>
Date:        Wed Jul 11 17:29:15 2012 UTC

----------------------------------------------------------------------------

13 files changed, 177 insertions(+), 172 deletions(-)
headers/private/kernel/arch/x86/32/descriptors.h  |    4 +
src/system/boot/platform/bios_ia32/interrupts.cpp |    5 -
src/system/boot/platform/bios_ia32/long.cpp       |   65 +++++++---
src/system/boot/platform/bios_ia32/long.h         |    4 -
src/system/boot/platform/bios_ia32/long_asm.S     |   53 ++++----
src/system/boot/platform/bios_ia32/smp.cpp        |  108 +++++------------
src/system/boot/platform/bios_ia32/smp.h          |    4 +-
src/system/boot/platform/bios_ia32/start.cpp      |   51 +++++++-
src/system/kernel/arch/x86/32/int.cpp             |   11 +-
src/system/kernel/arch/x86/64/stubs.cpp           |   28 -----
src/system/kernel/arch/x86/Jamfile                |    2 +-
src/system/kernel/arch/x86/arch_cpu.cpp           |    5 +-
src/system/kernel/arch/x86/arch_smp.cpp           |    9 +-

----------------------------------------------------------------------------

diff --git a/headers/private/kernel/arch/x86/32/descriptors.h 
b/headers/private/kernel/arch/x86/32/descriptors.h
index c578acf..81fd842 100644
--- a/headers/private/kernel/arch/x86/32/descriptors.h
+++ b/headers/private/kernel/arch/x86/32/descriptors.h
@@ -50,6 +50,10 @@ typedef struct segment_descriptor {
        uint32 base_31_24 : 8;                  //              24 - 31
 } segment_descriptor;
 
+typedef struct interrupt_descriptor {
+       uint32 a, b;
+} interrupt_descriptor;
+
 struct tss {
        uint16 prev_task;
        uint16 unused0;
diff --git a/src/system/boot/platform/bios_ia32/interrupts.cpp 
b/src/system/boot/platform/bios_ia32/interrupts.cpp
index c5efc58..2d5d0fa 100644
--- a/src/system/boot/platform/bios_ia32/interrupts.cpp
+++ b/src/system/boot/platform/bios_ia32/interrupts.cpp
@@ -83,11 +83,6 @@ struct interrupt_frame {
        uint32 eflags;
 };
 
-struct interrupt_descriptor {
-       uint32 a;
-       uint32 b;
-};
-
 
 static interrupt_descriptor sDebugIDT[DEBUG_IDT_SLOT_COUNT];
 
diff --git a/src/system/boot/platform/bios_ia32/long.cpp 
b/src/system/boot/platform/bios_ia32/long.cpp
index 28137d4..3e50305 100644
--- a/src/system/boot/platform/bios_ia32/long.cpp
+++ b/src/system/boot/platform/bios_ia32/long.cpp
@@ -23,6 +23,7 @@
 #include <kernel.h>
 
 #include "debug.h"
+#include "smp.h"
 #include "mmu.h"
 
 
@@ -31,6 +32,13 @@ static const uint64 kLargePageMappingFlags = 0x183;
 static const uint64 kPageMappingFlags = 0x103;
        // Global, R/W, Present
 
+extern "C" void long_enter_kernel(int currentCPU, uint64 stackTop);
+
+extern uint32 gLongPhysicalGDT;
+extern uint64 gLongVirtualGDT;
+extern uint32 gLongPhysicalPML4;
+extern uint64 gLongKernelEntry;
+
 
 /*! Convert a 32-bit address to a 64-bit address. */
 static inline uint64
@@ -71,6 +79,10 @@ long_gdt_init()
                DPL_USER);
        set_segment_descriptor(&gdt[USER_DATA_SEG / 8], DT_DATA_WRITEABLE,
                DPL_USER);
+
+       // Used by long_enter_kernel().
+       gLongPhysicalGDT = gKernelArgs.arch_args.phys_gdt;
+       gLongVirtualGDT = gKernelArgs.arch_args.vir_gdt;
 }
 
 
@@ -222,6 +234,8 @@ long_mmu_init()
                        gKernelArgs.virtual_allocated_range[i].start,
                        gKernelArgs.virtual_allocated_range[i].size);
        }
+
+       gLongPhysicalPML4 = gKernelArgs.arch_args.phys_pgdir;
 }
 
 
@@ -275,12 +289,6 @@ convert_kernel_args()
                        gKernelArgs.kernel_args_range[i].size);
        }
 
-       // Set correct kernel stack addresses.
-       for (uint32 i = 0; i < gKernelArgs.num_cpus; i++) {
-               gKernelArgs.cpu_kstack[i].start = fix_address(
-                       gKernelArgs.cpu_kstack[i].start);
-       }
-
        // Fix driver settings files.
        driver_settings_file* file = gKernelArgs.driver_settings;
        fix_address(gKernelArgs.driver_settings);
@@ -293,6 +301,27 @@ convert_kernel_args()
 }
 
 
+static void
+long_smp_start_kernel(void)
+{
+       uint32 cpu = smp_get_current_cpu();
+
+       // Important.  Make sure supervisor threads can fault on read only 
pages...
+       asm("movl %%eax, %%cr0" : : "a" ((1 << 31) | (1 << 16) | (1 << 5) | 1));
+       asm("cld");
+       asm("fninit");
+
+       // Fix our kernel stack address.
+       gKernelArgs.cpu_kstack[cpu].start
+               = fix_address(gKernelArgs.cpu_kstack[cpu].start);
+
+       long_enter_kernel(cpu, gKernelArgs.cpu_kstack[cpu].start
+               + gKernelArgs.cpu_kstack[cpu].size);
+
+       panic("Shouldn't get here");
+}
+
+
 void
 long_start_kernel()
 {
@@ -305,8 +334,7 @@ long_start_kernel()
        preloaded_elf64_image *image = static_cast<preloaded_elf64_image *>(
                gKernelArgs.kernel_image.Pointer());
 
-       // TODO: x86_64 SMP, disable for now.
-       gKernelArgs.num_cpus = 1;
+       smp_init_other_cpus();
 
        long_gdt_init();
        long_idt_init();
@@ -315,23 +343,22 @@ long_start_kernel()
 
        debug_cleanup();
 
-       // Calculate the arguments for long_enter_kernel().
-       uint64 entry = image->elf_header.e_entry;
-       uint64 stackTop = gKernelArgs.cpu_kstack[0].start
-               + gKernelArgs.cpu_kstack[0].size;
-       uint64 kernelArgs = (addr_t)&gKernelArgs;
+       // Save the kernel entry point address.
+       gLongKernelEntry = image->elf_header.e_entry;
+       dprintf("kernel entry at %#llx\n", gLongKernelEntry);
 
-       dprintf("kernel entry at %#llx, stack %#llx, args %#llx\n", entry,
-               stackTop, kernelArgs);
+       // Fix our kernel stack address.
+       gKernelArgs.cpu_kstack[0].start
+               = fix_address(gKernelArgs.cpu_kstack[0].start);
 
        // We're about to enter the kernel -- disable console output.
        stdout = NULL;
 
+       smp_boot_other_cpus(long_smp_start_kernel);
+
        // Enter the kernel!
-       long_enter_kernel(gKernelArgs.arch_args.phys_pgdir,
-               gKernelArgs.arch_args.phys_gdt, gKernelArgs.arch_args.vir_gdt,
-               entry, stackTop, kernelArgs, 0);
+       long_enter_kernel(0, gKernelArgs.cpu_kstack[0].start
+               + gKernelArgs.cpu_kstack[0].size);
 
        panic("Shouldn't get here");
 }
-
diff --git a/src/system/boot/platform/bios_ia32/long.h 
b/src/system/boot/platform/bios_ia32/long.h
index 084b5b3..e29d2aa 100644
--- a/src/system/boot/platform/bios_ia32/long.h
+++ b/src/system/boot/platform/bios_ia32/long.h
@@ -9,10 +9,6 @@
 #include <SupportDefs.h>
 
 
-extern "C" void long_enter_kernel(uint32 physPML4, uint32 physGDT,
-       uint64 virtGDT, uint64 entry, uint64 stackTop, uint64 kernelArgs,
-       int currentCPU);
-
 extern void long_start_kernel();
 
 
diff --git a/src/system/boot/platform/bios_ia32/long_asm.S 
b/src/system/boot/platform/bios_ia32/long_asm.S
index 30bfd2b..8c07f39 100644
--- a/src/system/boot/platform/bios_ia32/long_asm.S
+++ b/src/system/boot/platform/bios_ia32/long_asm.S
@@ -17,15 +17,17 @@
 .code32
 
 
-/*!    void long_enter_kernel(uint32 physPML4, uint32 physGDT, uint64 virtGDT,
-               uint64 entry, uint64 stackTop, uint64 kernelArgs, int 
currentCPU);
-*/
+/*!    void long_enter_kernel(int currentCPU, uint64 stackTop); */
 FUNCTION(long_enter_kernel):
+       // Preserve the arguments. We may no longer be able to use the stack 
once
+       // paging is disabled.
+       movl    4(%esp), %ebx
+       movl    8(%esp), %edi
+       movl    12(%esp), %esi
+
        // We're about to disable paging, so we need to load the the physical
        // address of our GDT.
-       movl    8(%esp), %eax
-       movl    %eax, (long_gdtr + 2)
-       lgdtl   (long_gdtr)
+       lgdtl   long_phys_gdtr
 
        // Currently running with 32-bit paging tables at an identity mapped
        // address. To switch to 64-bit paging we must first disable 32-bit 
paging,
@@ -40,11 +42,11 @@ FUNCTION(long_enter_kernel):
        movl    %eax, %cr4
 
        // Point CR3 to the kernel's PML4.
-       movl    4(%esp), %eax
+       movl    gLongPhysicalPML4, %eax
        movl    %eax, %cr3
 
        // Enable long mode by setting EFER.LME.
-       movl    $0xC0000080, %ecx
+       movl    $0xc0000080, %ecx
        rdmsr
        orl             $(1 << 8), %eax
        wrmsr
@@ -68,32 +70,41 @@ FUNCTION(long_enter_kernel):
        mov             %ax, %fs
        mov             %ax, %gs
 
-       // Clear the high 32 bits of RSP.
-       movl    %esp, %esp
-
        // Load the virtual address of the GDT.
-       movq    12(%rsp), %rax
-       movq    %rax, long_gdtr + 2(%rip)
-       lgdtq   long_gdtr(%rip)
+       lgdtq   long_virt_gdtr(%rip)
 
-       // Get the entry point address, arguments and new stack pointer.
-       movq    20(%rsp), %rax
-       movq    36(%rsp), %rdi
-       movl    44(%rsp), %esi
-       movq    28(%rsp), %rsp
+       // Set the stack pointer.
+       movl    %edi, %esp
+       shl             $32, %rsi
+       orq             %rsi, %rsp
 
        // Clear the stack frame/RFLAGS.
        xorq    %rbp, %rbp
        push    $0
        popf
 
-       // Call the kernel entry point.
+       // Get arguments and call the kernel entry point.
+       leaq    gKernelArgs(%rip), %rdi
+       movl    %ebx, %esi
+       movq    gLongKernelEntry(%rip), %rax
        call    *%rax
 
        
 .data
 
 
-long_gdtr:
+long_phys_gdtr:
+       .word   GDT_LIMIT - 1
+SYMBOL(gLongPhysicalGDT):
+       .long   0
+
+long_virt_gdtr:
        .word   GDT_LIMIT - 1
+SYMBOL(gLongVirtualGDT):
+       .quad   0
+
+SYMBOL(gLongPhysicalPML4):
+       .long   0
+
+SYMBOL(gLongKernelEntry):
        .quad   0
diff --git a/src/system/boot/platform/bios_ia32/smp.cpp 
b/src/system/boot/platform/bios_ia32/smp.cpp
index a7ec21b..0c6c5f7 100644
--- a/src/system/boot/platform/bios_ia32/smp.cpp
+++ b/src/system/boot/platform/bios_ia32/smp.cpp
@@ -20,8 +20,10 @@
 #include <boot/menu.h>
 #include <arch/x86/apic.h>
 #include <arch/x86/arch_acpi.h>
+#include <arch/x86/arch_cpu.h>
 #include <arch/x86/arch_smp.h>
 #include <arch/x86/arch_system_info.h>
+#include <arch/x86/descriptors.h>
 
 #include "mmu.h"
 #include "acpi.h"
@@ -37,10 +39,6 @@
 #      define TRACE(x) ;
 #endif
 
-struct gdt_idt_descr {
-       uint16 a;
-       uint32 *b;
-} _PACKED;
 
 static struct scan_spots_struct smp_scan_spots[] = {
        { 0x9fc00, 0xa0000, 0xa0000 - 0x9fc00 },
@@ -54,9 +52,6 @@ extern "C" void smp_trampoline(void);
 extern "C" void smp_trampoline_end(void);
 
 
-static int smp_get_current_cpu(void);
-
-
 static uint32
 apic_read(uint32 offset)
 {
@@ -71,22 +66,6 @@ apic_write(uint32 offset, uint32 data)
 }
 
 
-static int
-smp_get_current_cpu(void)
-{
-       if (gKernelArgs.arch_args.apic == NULL)
-               return 0;
-
-       uint8 apicID = apic_read(APIC_ID) >> 24;
-       for (uint32 i = 0; i < gKernelArgs.num_cpus; i++) {
-               if (gKernelArgs.arch_args.cpu_apic_id[i] == apicID)
-                       return i;
-       }
-
-       return 0;
-}
-
-
 static mp_floating_struct *
 smp_mp_probe(uint32 base, uint32 limit)
 {
@@ -341,56 +320,6 @@ smp_do_acpi_config(void)
 }
 
 
-/*!    Target function of the trampoline code.
-       The trampoline code should have the pgdir and a gdt set up for us,
-       along with us being on the final stack for this processor. We need
-       to set up the local APIC and load the global idt and gdt. When we're
-       done, we'll jump into the kernel with the cpu number as an argument.
-*/
-static int
-smp_cpu_ready(void)
-{
-       uint32 curr_cpu = smp_get_current_cpu();
-       struct gdt_idt_descr idt_descr;
-       struct gdt_idt_descr gdt_descr;
-
-       //TRACE(("smp_cpu_ready: entry cpu %ld\n", curr_cpu));
-
-       preloaded_elf32_image *image = static_cast<preloaded_elf32_image *>(
-               gKernelArgs.kernel_image.Pointer());
-
-       // Important.  Make sure supervisor threads can fault on read only 
pages...
-       asm("movl %%eax, %%cr0" : : "a" ((1 << 31) | (1 << 16) | (1 << 5) | 1));
-       asm("cld");
-       asm("fninit");
-
-       // Set up the final idt
-       idt_descr.a = IDT_LIMIT - 1;
-       idt_descr.b = (uint32 *)(addr_t)gKernelArgs.arch_args.vir_idt;
-
-       asm("lidt       %0;"
-               : : "m" (idt_descr));
-
-       // Set up the final gdt
-       gdt_descr.a = GDT_LIMIT - 1;
-       gdt_descr.b = (uint32 *)gKernelArgs.arch_args.vir_gdt;
-
-       asm("lgdt       %0;"
-               : : "m" (gdt_descr));
-
-       asm("pushl  %0; "                                       // push the cpu 
number
-               "pushl  %1;     "                                       // 
kernel args
-               "pushl  $0x0;"                                  // dummy retval 
for call to main
-               "pushl  %2;     "                                       // this 
is the start address
-               "ret;           "                                       // jump.
-               : : "g" (curr_cpu), "g" (&gKernelArgs),
-                       "g" (image->elf_header.e_entry));
-
-       // no where to return to
-       return 0;
-}
-
-
 static void
 calculate_apic_timer_conversion_factor(void)
 {
@@ -429,6 +358,22 @@ calculate_apic_timer_conversion_factor(void)
 //     #pragma mark -
 
 
+int
+smp_get_current_cpu(void)
+{
+       if (gKernelArgs.arch_args.apic == NULL)
+               return 0;
+
+       uint8 apicID = apic_read(APIC_ID) >> 24;
+       for (uint32 i = 0; i < gKernelArgs.num_cpus; i++) {
+               if (gKernelArgs.arch_args.cpu_apic_id[i] == apicID)
+                       return i;
+       }
+
+       return 0;
+}
+
+
 void
 smp_init_other_cpus(void)
 {
@@ -476,7 +421,7 @@ smp_init_other_cpus(void)
 
 
 void
-smp_boot_other_cpus(void)
+smp_boot_other_cpus(void (*entryFunc)())
 {
        if (gKernelArgs.num_cpus < 2)
                return;
@@ -516,7 +461,7 @@ smp_boot_other_cpus(void)
                tempStack = (finalStack
                        + (KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * 
B_PAGE_SIZE)
                                / sizeof(uint32)) - 1;
-               *tempStack = (uint32)&smp_cpu_ready;
+               *tempStack = (uint32)entryFunc;
 
                // set the trampoline stack up
                tempStack = (uint32 *)(trampolineStack + B_PAGE_SIZE - 4);
@@ -525,15 +470,20 @@ smp_boot_other_cpus(void)
                        + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE - 
sizeof(uint32);
                tempStack--;
                // page dir
-               *tempStack = gKernelArgs.arch_args.phys_pgdir;
+               *tempStack = x86_read_cr3() & 0xfffff000;
 
                // put a gdt descriptor at the bottom of the stack
                *((uint16 *)trampolineStack) = 0x18 - 1; // LIMIT
                *((uint32 *)(trampolineStack + 2)) = trampolineStack + 8;
 
-               // put the gdt at the bottom
-               memcpy(&((uint32 *)trampolineStack)[2],
-                       (void *)gKernelArgs.arch_args.vir_gdt, 6 * 4);
+               // construct a temporary gdt at the bottom
+               segment_descriptor* tempGDT
+                       = (segment_descriptor*)&((uint32 *)trampolineStack)[2];
+               clear_segment_descriptor(&tempGDT[0]);
+               set_segment_descriptor(&tempGDT[1], 0, 0xffffffff, 
DT_CODE_READABLE,
+                       DPL_KERNEL);
+               set_segment_descriptor(&tempGDT[2], 0, 0xffffffff, 
DT_DATA_WRITEABLE,
+                       DPL_KERNEL);
 
                /* clear apic errors */
                if (gKernelArgs.arch_args.cpu_apic_version[i] & 0xf0) {
diff --git a/src/system/boot/platform/bios_ia32/smp.h 
b/src/system/boot/platform/bios_ia32/smp.h
index bf942a0..2380e63 100644
--- a/src/system/boot/platform/bios_ia32/smp.h
+++ b/src/system/boot/platform/bios_ia32/smp.h
@@ -19,7 +19,9 @@ extern "C" {
 
 extern void smp_init(void);
 extern void smp_init_other_cpus(void);
-extern void smp_boot_other_cpus(void);
+extern void smp_boot_other_cpus(void (*entryFunc)());
+
+extern int smp_get_current_cpu(void);
 
 #ifdef __cplusplus
 }
diff --git a/src/system/boot/platform/bios_ia32/start.cpp 
b/src/system/boot/platform/bios_ia32/start.cpp
index 717b2c2..2cc7212 100644
--- a/src/system/boot/platform/bios_ia32/start.cpp
+++ b/src/system/boot/platform/bios_ia32/start.cpp
@@ -73,6 +73,55 @@ platform_boot_options(void)
 }
 
 
+/*!    Target function of the SMP trampoline code.
+       The trampoline code should have the pgdir and a gdt set up for us,
+       along with us being on the final stack for this processor. We need
+       to set up the local APIC and load the global idt and gdt. When we're
+       done, we'll jump into the kernel with the cpu number as an argument.
+*/
+static void
+smp_start_kernel(void)
+{
+       uint32 curr_cpu = smp_get_current_cpu();
+       struct gdt_idt_descr idt_descr;
+       struct gdt_idt_descr gdt_descr;
+
+       //TRACE(("smp_cpu_ready: entry cpu %ld\n", curr_cpu));
+
+       preloaded_elf32_image *image = static_cast<preloaded_elf32_image *>(
+               gKernelArgs.kernel_image.Pointer());
+
+       // Important.  Make sure supervisor threads can fault on read only 
pages...
+       asm("movl %%eax, %%cr0" : : "a" ((1 << 31) | (1 << 16) | (1 << 5) | 1));
+       asm("cld");
+       asm("fninit");
+
+       // Set up the final idt
+       idt_descr.limit = IDT_LIMIT - 1;
+       idt_descr.base = (uint32 *)(addr_t)gKernelArgs.arch_args.vir_idt;
+
+       asm("lidt       %0;"
+               : : "m" (idt_descr));
+
+       // Set up the final gdt
+       gdt_descr.limit = GDT_LIMIT - 1;
+       gdt_descr.base = (uint32 *)gKernelArgs.arch_args.vir_gdt;
+
+       asm("lgdt       %0;"
+               : : "m" (gdt_descr));
+
+       asm("pushl  %0; "                                       // push the cpu 
number
+               "pushl  %1;     "                                       // 
kernel args
+               "pushl  $0x0;"                                  // dummy retval 
for call to main
+               "pushl  %2;     "                                       // this 
is the start address
+               "ret;           "                                       // jump.
+               : : "g" (curr_cpu), "g" (&gKernelArgs),
+                       "g" (image->elf_header.e_entry));
+
+       panic("kernel returned!\n");
+}
+
+
 extern "C" void
 platform_start_kernel(void)
 {
@@ -99,7 +148,7 @@ platform_start_kernel(void)
        // We're about to enter the kernel -- disable console output.
        stdout = NULL;
 
-       smp_boot_other_cpus();
+       smp_boot_other_cpus(smp_start_kernel);
 
        dprintf("kernel entry at %lx\n", image->elf_header.e_entry);
 
diff --git a/src/system/kernel/arch/x86/32/int.cpp 
b/src/system/kernel/arch/x86/32/int.cpp
index c49ec88..b290c0d 100644
--- a/src/system/kernel/arch/x86/32/int.cpp
+++ b/src/system/kernel/arch/x86/32/int.cpp
@@ -62,10 +62,7 @@ static const int kInterruptNameCount = 20;
 
 #define MAX_ARGS 16
 
-typedef struct {
-       uint32 a, b;
-} desc_table;
-static desc_table* sIDTs[B_MAX_CPU_COUNT];
+static interrupt_descriptor* sIDTs[B_MAX_CPU_COUNT];
 
 // table with functions handling respective interrupts
 typedef void interrupt_handler_function(struct iframe* frame);
@@ -80,7 +77,7 @@ extern void hardware_interrupt(struct iframe* frame);
 /*!    Initializes a descriptor in an IDT.
 */
 static void
-set_gate(desc_table *gate_addr, addr_t addr, int type, int dpl)
+set_gate(interrupt_descriptor *gate_addr, addr_t addr, int type, int dpl)
 {
        unsigned int gate1; // first byte of gate desc
        unsigned int gate2; // second byte of gate desc
@@ -353,7 +350,7 @@ arch_int_init(struct kernel_args *args)
        interrupt_handler_function** table;
 
        // set the global sIDT variable
-       sIDTs[0] = (desc_table *)(addr_t)args->arch_args.vir_idt;
+       sIDTs[0] = (interrupt_descriptor *)(addr_t)args->arch_args.vir_idt;
 
        // setup the standard programmable interrupt controller
        pic_init();
@@ -668,7 +665,7 @@ arch_int_init_post_vm(struct kernel_args *args)
        int32 cpuCount = smp_get_num_cpus();
        if (cpuCount > 0) {
                size_t areaSize = ROUNDUP(cpuCount * idtSize, B_PAGE_SIZE);
-               desc_table* idt;
+               interrupt_descriptor* idt;
                virtual_address_restrictions virtualRestrictions = {};
                virtualRestrictions.address_specification = 
B_ANY_KERNEL_ADDRESS;
                physical_address_restrictions physicalRestrictions = {};
diff --git a/src/system/kernel/arch/x86/64/stubs.cpp 
b/src/system/kernel/arch/x86/64/stubs.cpp
index 813e00c..72b95c6 100644
--- a/src/system/kernel/arch/x86/64/stubs.cpp
+++ b/src/system/kernel/arch/x86/64/stubs.cpp
@@ -270,34 +270,6 @@ arch_debug_call_with_fault_handler(cpu_ent* cpu, jmp_buf 
jumpBuffer,
 }
 
 
-status_t
-arch_smp_init(kernel_args *args)
-{
-       return B_OK;
-}
-
-
-status_t
-arch_smp_per_cpu_init(kernel_args *args, int32 cpu)
-{
-       return B_OK;
-}
-
-
-void
-arch_smp_send_broadcast_ici(void)
-{
-
-}
-
-
-void
-arch_smp_send_ici(int32 target_cpu)
-{
-
-}
-
-
 // The software breakpoint instruction (int3).
 const uint8 kX86SoftwareBreakpoint[1] = { 0xcc };
 
diff --git a/src/system/kernel/arch/x86/Jamfile 
b/src/system/kernel/arch/x86/Jamfile
index 014c713..4d4329b 100644
--- a/src/system/kernel/arch/x86/Jamfile
+++ b/src/system/kernel/arch/x86/Jamfile
@@ -48,7 +48,6 @@ if $(TARGET_ARCH) = x86_64 {
 
                arch_commpage.cpp
                arch_debug.cpp
-               arch_smp.cpp
                arch_user_debugger.cpp
                apm.cpp
                bios.cpp
@@ -83,6 +82,7 @@ local archGenericSources =
        arch_int.cpp
        arch_platform.cpp
        arch_real_time_clock.cpp
+       arch_smp.cpp
        arch_system_info.cpp
        arch_thread.cpp
        arch_timer.cpp
diff --git a/src/system/kernel/arch/x86/arch_cpu.cpp 
b/src/system/kernel/arch/x86/arch_cpu.cpp
index 9fe0d79..12b8f28 100644
--- a/src/system/kernel/arch/x86/arch_cpu.cpp
+++ b/src/system/kernel/arch/x86/arch_cpu.cpp
@@ -349,7 +349,7 @@ x86_init_fpu(void)
 static void
 load_tss(int cpu)
 {
-       short seg = ((TSS_BASE_SEGMENT + cpu) << 3) | DPL_KERNEL;
+       short seg = (TSS_SEGMENT(cpu) << 3) | DPL_KERNEL;
        asm("ltr %%ax" : : "a" (seg));
 }
 
@@ -789,7 +789,8 @@ arch_cpu_init_percpu(kernel_args* args, int cpu)
                        uint16  limit;
                        void*   address;
                } _PACKED descriptor = {
-                       256 * 8 - 1,    // 256 descriptors, 8 bytes each (-1 
for "limit")
+                       256 * sizeof(interrupt_descriptor) - 1,
+                               // 256 descriptors (-1 for "limit")
                        x86_get_idt(cpu)
                };
 
diff --git a/src/system/kernel/arch/x86/arch_smp.cpp 
b/src/system/kernel/arch/x86/arch_smp.cpp
index a63051b..b1aedd8 100644
--- a/src/system/kernel/arch/x86/arch_smp.cpp
+++ b/src/system/kernel/arch/x86/arch_smp.cpp
@@ -52,7 +52,7 @@ static int32
 x86_spurious_interrupt(void *data)
 {
        // spurious interrupt
-       TRACE(("spurious interrupt on cpu %ld\n", smp_get_current_cpu()));
+       TRACE(("spurious interrupt on cpu %" B_PRId32 "\n", 
smp_get_current_cpu()));
 
        // spurious interrupts must not be acknowledged as it does not expect
        // a end of interrupt - if we still do it we would loose the next best
@@ -65,7 +65,7 @@ static int32
 x86_smp_error_interrupt(void *data)
 {
        // smp error interrupt
-       TRACE(("smp error interrupt on cpu %ld\n", smp_get_current_cpu()));
+       TRACE(("smp error interrupt on cpu %" B_PRId32 "\n", 
smp_get_current_cpu()));
        return B_HANDLED_INTERRUPT;
 }
 
@@ -104,7 +104,8 @@ status_t
 arch_smp_per_cpu_init(kernel_args *args, int32 cpu)
 {
        // set up the local apic on the current cpu
-       TRACE(("arch_smp_init_percpu: setting up the apic on cpu %ld\n", cpu));
+       TRACE(("arch_smp_init_percpu: setting up the apic on cpu %" B_PRId32 
"\n",
+               cpu));
        apic_per_cpu_init(args, cpu);
 
        // setup FPU and SSE if supported
@@ -154,7 +155,7 @@ arch_smp_send_ici(int32 target_cpu)
                asm volatile ("pause;");
 
        if (timeout == 0)
-               panic("arch_smp_send_ici: timeout, target_cpu %ld", target_cpu);
+               panic("arch_smp_send_ici: timeout, target_cpu %" B_PRId32, 
target_cpu);
 
        restore_interrupts(state);
 }


Other related posts: