The architecture specific code implements the smp_processor_id() function by querying the APIC logical identity register. Because the APIC isn't mapped into the kernel address space at boot, the initial value returned is rigged by setting the APIC base pointer to point at a suitable constant. Once the system starts doing the SMP setup (in smp_boot_cpus()), the APIC is mapped with a vremap() call and the apic pointer is adjusted appropriately. From then on the real APIC logical identity register is read.
Message passing is accomplished using a pair of IPI's on interrupt 13 (unused by the 80486 FPU's in SMP mode) and interrupt 16. Two are used in order to separate messages that cannot be processed until the receiver obtains the kernel spinlock from messages that can be processed immediately. In effect IRQ 13 is a fast IRQ handler that does not obtain the locks, and cannot cause a reschedule, while IRQ 16 is a slow IRQ that must acquire the kernel spinlocks and can cause a reschedule. This interrupt is used for passing on slave timer messages from the processor that receives the timer interrupt to the rest of the processors, so that they can reschedule running tasks.