/* * Intel SMP support routines. * * (c) 1995 Alan Cox, Building #3 * (c) 1998-99, 2000 Ingo Molnar * * This code is released under the GNU General Public License version 2 or * later. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* * Some notes on x86 processor bugs affecting SMP operation: * * Pentium, Pentium Pro, II, III (and all CPUs) have bugs. * The Linux implications for SMP are handled as follows: * * Pentium III / [Xeon] * None of the E1AP-E3AP errata are visible to the user. * * E1AP. see PII A1AP * E2AP. see PII A2AP * E3AP. see PII A3AP * * Pentium II / [Xeon] * None of the A1AP-A3AP errata are visible to the user. * * A1AP. see PPro 1AP * A2AP. see PPro 2AP * A3AP. see PPro 7AP * * Pentium Pro * None of 1AP-9AP errata are visible to the normal user, * except occasional delivery of 'spurious interrupt' as trap #15. * This is very rare and a non-problem. * * 1AP. Linux maps APIC as non-cacheable * 2AP. worked around in hardware * 3AP. fixed in C0 and above steppings microcode update. * Linux does not use excessive STARTUP_IPIs. * 4AP. worked around in hardware * 5AP. symmetric IO mode (normal Linux operation) not affected. * 'noapic' mode has vector 0xf filled out properly. * 6AP. 'noapic' mode might be affected - fixed in later steppings * 7AP. We do not assume writes to the LVT deassering IRQs * 8AP. We do not enable low power mode (deep sleep) during MP bootup * 9AP. We do not use mixed mode */ /* * The following functions deal with sending IPIs between CPUs. */ static inline int __prepare_ICR (unsigned int shortcut, int vector) { return APIC_DM_FIXED | shortcut | vector; } static inline int __prepare_ICR2 (unsigned int mask) { return SET_APIC_DEST_FIELD(mask); } static inline void check_IPI_mask(cpumask_t cpumask) { /* * Sanity, and necessary. An IPI with no target generates a send accept * error with Pentium and P6 APICs. */ ASSERT(cpus_subset(cpumask, cpu_online_map)); ASSERT(!cpus_empty(cpumask)); } void apic_wait_icr_idle(void) { while ( apic_read( APIC_ICR ) & APIC_ICR_BUSY ) cpu_relax(); } void send_IPI_mask_flat(cpumask_t cpumask, int vector) { unsigned long mask = cpus_addr(cpumask)[0]; unsigned long cfg; unsigned long flags; check_IPI_mask(cpumask); local_irq_save(flags); /* * Wait for idle. */ apic_wait_icr_idle(); /* * prepare target chip field */ cfg = __prepare_ICR2(mask); apic_write_around(APIC_ICR2, cfg); /* * program the ICR */ cfg = __prepare_ICR(0, vector) | APIC_DEST_LOGICAL; /* * Send the IPI. The write to APIC_ICR fires this off. */ apic_write_around(APIC_ICR, cfg); local_irq_restore(flags); } void send_IPI_mask_phys(cpumask_t mask, int vector) { unsigned long cfg, flags; unsigned int query_cpu; check_IPI_mask(mask); /* * Hack. The clustered APIC addressing mode doesn't allow us to send * to an arbitrary mask, so I do a unicasts to each CPU instead. This * should be modified to do 1 message per cluster ID - mbligh */ local_irq_save(flags); for_each_cpu_mask( query_cpu, mask ) { /* * Wait for idle. */ apic_wait_icr_idle(); /* * prepare target chip field */ cfg = __prepare_ICR2(cpu_physical_id(query_cpu)); apic_write_around(APIC_ICR2, cfg); /* * program the ICR */ cfg = __prepare_ICR(0, vector) | APIC_DEST_PHYSICAL; /* * Send the IPI. The write to APIC_ICR fires this off. */ apic_write_around(APIC_ICR, cfg); } local_irq_restore(flags); } static DEFINE_SPINLOCK(flush_lock); static cpumask_t flush_cpumask; static const void *flush_va; static unsigned int flush_flags; fastcall void smp_invalidate_interrupt(void) { ack_APIC_irq(); perfc_incr(ipis); irq_enter(); if ( !__sync_lazy_execstate() || (flush_flags & (FLUSH_TLB_GLOBAL | FLUSH_CACHE)) ) flush_area_local(flush_va, flush_flags); cpu_clear(smp_processor_id(), flush_cpumask); irq_exit(); } void flush_area_mask(cpumask_t mask, const void *va, unsigned int flags) { ASSERT(local_irq_is_enabled()); if ( cpu_isset(smp_processor_id(), mask) ) { flush_area_local(va, flags); cpu_clear(smp_processor_id(), mask); } if ( !cpus_empty(mask) ) { spin_lock(&flush_lock); flush_cpumask = mask; flush_va = va; flush_flags = flags; send_IPI_mask(mask, INVALIDATE_TLB_VECTOR); while ( !cpus_empty(flush_cpumask) ) cpu_relax(); spin_unlock(&flush_lock); } } /* Call with no locks held and interrupts enabled (e.g., softirq context). */ void new_tlbflush_clock_period(void) { cpumask
#
#             LUFA Library
#     Copyright (C) Dean Camera, 2013.
#
#  dean [at] fourwalledcubicle [dot] com
#           www.lufa-lib.org
#

# Makefile for the module build test. This test
# attempts to build as many modules as possible
# under all supported architectures, and include
# all module headers in a simple C and C++
# application.

# Path to the LUFA library core
LUFA_PATH := ../../LUFA/

# Build test cannot be run with multiple parallel jobs
.NOTPARALLEL:

# List of device families per architecture, one device per architecture sub-family
AVR8_FAMILIES   := at90usb1287 at90usb1286 atmega16u4 atmega16u2 at90usb162
XMEGA_FAMILIES  := atxmega128a1u atxmega128a3u atxmega256a3bu atxmega128a4u atxmega128b1 atxmega128b3 atxmega128c3 atxmega32c4
UC3_FAMILIES    := uc3a0256 uc3a1256 uc3a3256 uc3a4256 uc3b0256 uc3b1256

# List of all device families, with a family postfix
DEVICE_FAMILIES := $(AVR8_FAMILIES:%=%.avr8) $(XMEGA_FAMILIES:%=%.xmega) $(UC3_FAMILIES:%=%.uc3)


all: begin $(DEVICE_FAMILIES) clean end

arch_avr8:  begin $(AVR8_FAMILIES:%=%.avr8) end
arch_xmega: begin $(XMEGA_FAMILIES:%=%.xmega) end
arch_uc3:   begin $(UC3_FAMILIES:%=%.uc3) end

begin:
	@echo Executing build test "ModuleTest".
	@echo

end:
	@echo Build test "ModuleTest" complete.
	@echo

%.avr8:
	@echo Building ModuleTest for ARCH=AVR8 MCU=$(@:%.avr8=%)...
	$(MAKE) -f makefile.test clean elf ARCH=AVR8 MCU=$(@:%.avr8=%)

%.xmega:
	@echo Building ModuleTest for ARCH=XMEGA MCU=$(@:%.xmega=%)...
	$(MAKE) -f makefile.test clean elf ARCH=XMEGA MCU=$(@:%.xmega=%)

%.uc3:
	@echo Building ModuleTest for ARCH=UC3 MCU=$(@:%.uc3=%)...
	$(MAKE) -f makefile.test clean elf ARCH=UC3 MCU=$(@:%.uc3=%)

clean:
	$(MAKE) -f makefile.test clean ARCH=AVR8 MCU=$(firstword $(AVR8_FAMILIES))
	$(MAKE) -f makefile.test clean ARCH=XMEGA MCU=$(firstword $(XMEGA_FAMILIES))
	$(MAKE) -f makefile.test clean ARCH=UC3 MCU=$(firstword $(UC3_FAMILIES))

%:

.PHONY: all arch_avr8 arch_xmega arch_uc3 begin end

# Include LUFA build script makefiles
include $(LUFA_PATH)/Build/lufa_core.mk