void __init init_apic_mappings(void) { unsigned long apic_phys; if ( x2apic_enabled ) goto __next; /* * If no local APIC can be found then set up a fake all * zeroes page to simulate the local APIC and another * one for the IO-APIC. */ if (!smp_found_config && detect_init_APIC()) { apic_phys = __pa(alloc_xenheap_page()); clear_page(__va(apic_phys)); } else apic_phys = mp_lapic_addr; set_fixmap_nocache(FIX_APIC_BASE, apic_phys); apic_printk(APIC_VERBOSE, "mapped APIC to %08lx (%08lx)\n", APIC_BASE, apic_phys); __next: /* * Fetch the APIC ID of the BSP in case we have a * default configuration (or the MP table is broken). */ if (boot_cpu_physical_apicid == -1U) boot_cpu_physical_apicid = get_apic_id(); x86_cpu_to_apicid[0] = get_apic_id(); init_ioapic_mappings(); }
/* * For some reason the destination shorthand for self is not valid * when used with the NMI delivery mode. This is documented in Tables * 8-3 and 8-4 in IA32 Reference Manual Volume 3. We send the IPI to * our own APIC ID explicitly which is valid. */ void self_nmi(void) { u32 id = get_apic_id(); local_irq_disable(); apic_wait_icr_idle(); apic_icr_write(APIC_DM_NMI | APIC_DEST_PHYSICAL, id); local_irq_enable(); }
/* * For some reason the destination shorthand for self is not valid * when used with the NMI delivery mode. This is documented in Tables * 8-3 and 8-4 in IA32 Reference Manual Volume 3. We send the IPI to * our own APIC ID explicitly which is valid. */ void self_nmi(void) { unsigned long flags; u32 id = get_apic_id(); local_irq_save(flags); apic_wait_icr_idle(); apic_icr_write(APIC_DM_NMI | APIC_DEST_PHYSICAL, id); local_irq_restore(flags); }
void idle() { while(1) { wprintk(L"IDLE @ CPU%u\n", use_smp == true ? get_apic_id() : 0); schedule(); } return; }
/* * This initializes the IO-APIC and APIC hardware if this is * a UP kernel. */ int __init APIC_init_uniprocessor (void) { if (enable_local_apic < 0) clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability); if (!smp_found_config && !cpu_has_apic) { skip_ioapic_setup = 1; return -1; } /* * Complain if the BIOS pretends there is one. */ if (!cpu_has_apic && APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) { printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n", boot_cpu_physical_apicid); clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability); skip_ioapic_setup = 1; return -1; } verify_local_APIC(); connect_bsp_APIC(); /* * Hack: In case of kdump, after a crash, kernel might be booting * on a cpu with non-zero lapic id. But boot_cpu_physical_apicid * might be zero if read from MP tables. Get it from LAPIC. */ #ifdef CONFIG_CRASH_DUMP boot_cpu_physical_apicid = get_apic_id(); #endif physids_clear(phys_cpu_present_map); physid_set(boot_cpu_physical_apicid, phys_cpu_present_map); setup_local_APIC(); if (nmi_watchdog == NMI_LOCAL_APIC) check_nmi_watchdog(); #ifdef CONFIG_X86_IO_APIC if (smp_found_config) if (!skip_ioapic_setup && nr_ioapics) setup_IO_APIC(); #endif setup_boot_APIC_clock(); return 0; }
void ap_task_init() { struct thread *t_idle; tss_t *tss; uint16_t selektor; // IDLE-Thread fuer den AP erzeugen... t_idle = get_current_thread(); t_idle->cr3 = kernel_cr3; t_idle->esp0 = ((uint32_t) t_idle) + PAGE_SIZE;; t_idle->state = THREAD_IDLE; t_idle->priority = 0; disable_interrupts(); t_idle->counter = t_idle->priority; t_idle->need_reschedule = 0; enable_interrupts(); // IDLE-Thread in die Thread-Liste aufnehmen... add_thread(t_idle); // TSS initialiesieren und laden... tss = (tss_t *) (t_idle + 1); selektor = TSS_SELEKTOR(get_apic_id()); memset(tss, 0, sizeof(tss_t)); tss->esp0 = t_idle->esp0; tss->ss0 = KERNEL_DATA_SELEKTOR; set_tss_deskriptor(BSP_TSS_SELEKTOR, tss); load_tr(BSP_TSS_SELEKTOR); t_idle->tss = tss; return; }
static void do_nmi_trigger(unsigned char key) { printk("Triggering NMI on APIC ID %x\n", get_apic_id()); self_nmi(); }
int hard_smp_processor_id(void) { return get_apic_id(); }