#ifndef _I386AT_MP_H_
#define _I386AT_MP_H_
#include <cpus.h>
#include <platforms.h>
#include <mp_v1_1.h>
#include <mach_rt.h>
#include <mach_assert.h>
#if NCPUS > 1
#include <i386/apic.h>
#include <i386/AT386/mp/mp_events.h>
#define CPU_NUMBER(r) \
movl EXT(lapic_id), r ; \
movl 0(r),r ; \
shrl $LAPIC_ID_SHIFT, r; \
andl $LAPIC_ID_MASK, r
#define MP_IPL SPL6
#ifndef ASSEMBLER
#include <kern/lock.h>
extern cpu_int_word[];
extern real_ncpus;
extern wncpu;
decl_simple_lock_data(extern,kdb_lock)
extern int kdb_cpu;
extern int kdb_debug;
extern int kdb_is_slave[];
extern int kdb_active[];
#endif
#define i_bit(bit, word) ((long)(*(word)) & ((long)1 << (bit)))
#define MP_DEV_OP_MAX 4
#define MP_DEV_WAIT MP_DEV_OP_MAX
#define MP_DEV_OP_START 0
#define MP_DEV_OP_INTR 1
#define MP_DEV_OP_TIMEO 2
#define MP_DEV_OP_CALLB 3
#else
#define at386_io_lock_state()
#define at386_io_lock(op) (TRUE)
#define at386_io_unlock()
#if MP_V1_1
#include <i386/apic.h>
#endif
#endif
#if MACH_RT
#define _DISABLE_PREEMPTION(r) \
movl $CPD_PREEMPTION_LEVEL,r ; \
incl %gs:(r)
#define _ENABLE_PREEMPTION(r) \
movl $CPD_PREEMPTION_LEVEL,r ; \
decl %gs:(r) ; \
jne 9f ; \
pushl %eax ; \
pushl %ecx ; \
pushl %edx ; \
call EXT(kernel_preempt_check) ; \
popl %edx ; \
popl %ecx ; \
popl %eax ; \
9:
#define _ENABLE_PREEMPTION_NO_CHECK(r) \
movl $CPD_PREEMPTION_LEVEL,r ; \
decl %gs:(r)
#if MACH_ASSERT
#define DISABLE_PREEMPTION(r) \
pushl %eax; \
pushl %ecx; \
pushl %edx; \
call EXT(_disable_preemption); \
popl %edx; \
popl %ecx; \
popl %eax
#define ENABLE_PREEMPTION(r) \
pushl %eax; \
pushl %ecx; \
pushl %edx; \
call EXT(_enable_preemption); \
popl %edx; \
popl %ecx; \
popl %eax
#define ENABLE_PREEMPTION_NO_CHECK(r) \
pushl %eax; \
pushl %ecx; \
pushl %edx; \
call EXT(_enable_preemption_no_check); \
popl %edx; \
popl %ecx; \
popl %eax
#if NCPUS > 1
#define MP_DISABLE_PREEMPTION(r) \
pushl %eax; \
pushl %ecx; \
pushl %edx; \
call EXT(_mp_disable_preemption); \
popl %edx; \
popl %ecx; \
popl %eax
#define MP_ENABLE_PREEMPTION(r) \
pushl %eax; \
pushl %ecx; \
pushl %edx; \
call EXT(_mp_enable_preemption); \
popl %edx; \
popl %ecx; \
popl %eax
#define MP_ENABLE_PREEMPTION_NO_CHECK(r) \
pushl %eax; \
pushl %ecx; \
pushl %edx; \
call EXT(_mp_enable_preemption_no_check); \
popl %edx; \
popl %ecx; \
popl %eax
#else
#define MP_DISABLE_PREEMPTION(r)
#define MP_ENABLE_PREEMPTION(r)
#define MP_ENABLE_PREEMPTION_NO_CHECK(r)
#endif
#else
#define DISABLE_PREEMPTION(r) _DISABLE_PREEMPTION(r)
#define ENABLE_PREEMPTION(r) _ENABLE_PREEMPTION(r)
#define ENABLE_PREEMPTION_NO_CHECK(r) _ENABLE_PREEMPTION_NO_CHECK(r)
#if NCPUS > 1
#define MP_DISABLE_PREEMPTION(r) _DISABLE_PREEMPTION(r)
#define MP_ENABLE_PREEMPTION(r) _ENABLE_PREEMPTION(r)
#define MP_ENABLE_PREEMPTION_NO_CHECK(r) _ENABLE_PREEMPTION_NO_CHECK(r)
#else
#define MP_DISABLE_PREEMPTION(r)
#define MP_ENABLE_PREEMPTION(r)
#define MP_ENABLE_PREEMPTION_NO_CHECK(r)
#endif
#endif
#else
#define DISABLE_PREEMPTION(r)
#define ENABLE_PREEMPTION(r)
#define ENABLE_PREEMPTION_NO_CHECK(r)
#define MP_DISABLE_PREEMPTION(r)
#define MP_ENABLE_PREEMPTION(r)
#define MP_ENABLE_PREEMPTION_NO_CHECK(r)
#endif
#endif