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); }