The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/osfmk/i386/mp.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
    3  *
    4  * @APPLE_LICENSE_HEADER_START@
    5  * 
    6  * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
    7  * 
    8  * This file contains Original Code and/or Modifications of Original Code
    9  * as defined in and that are subject to the Apple Public Source License
   10  * Version 2.0 (the 'License'). You may not use this file except in
   11  * compliance with the License. Please obtain a copy of the License at
   12  * http://www.opensource.apple.com/apsl/ and read it before using this
   13  * file.
   14  * 
   15  * The Original Code and all software distributed under the License are
   16  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
   17  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
   18  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
   19  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
   20  * Please see the License for the specific language governing rights and
   21  * limitations under the License.
   22  * 
   23  * @APPLE_LICENSE_HEADER_END@
   24  */
   25 /*
   26  * @OSF_COPYRIGHT@
   27  */
   28 /* 
   29  * Mach Operating System
   30  * Copyright (c) 1991,1990 Carnegie Mellon University
   31  * All Rights Reserved.
   32  * 
   33  * Permission to use, copy, modify and distribute this software and its
   34  * documentation is hereby granted, provided that both the copyright
   35  * notice and this permission notice appear in all copies of the
   36  * software, derivative works or modified versions, and any portions
   37  * thereof, and that both notices appear in supporting documentation.
   38  * 
   39  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
   40  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
   41  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   42  * 
   43  * Carnegie Mellon requests users of this software to return to
   44  * 
   45  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   46  *  School of Computer Science
   47  *  Carnegie Mellon University
   48  *  Pittsburgh PA 15213-3890
   49  * 
   50  * any improvements or extensions that they make and grant Carnegie Mellon
   51  * the rights to redistribute these changes.
   52  */
   53 
   54 /*
   55  */
   56 
   57 #ifndef _I386AT_MP_H_
   58 #define _I386AT_MP_H_
   59 
   60 #if     !defined(NCPUS)
   61 #include <cpus.h>
   62 #endif  /* !defined(NCPUS) */
   63 
   64 #if     NCPUS > 1
   65 
   66 #ifndef DEBUG
   67 #include <debug.h>
   68 #endif
   69 #if     DEBUG
   70 #define MP_DEBUG 1
   71 #endif
   72 
   73 #include <i386/apic.h>
   74 #include <i386/mp_events.h>
   75 
   76 #define SPURIOUS_INTERRUPT      0xDD    
   77 #define INTERPROCESS_INTERRUPT  0xDE
   78 #define APIC_ERROR_INTERRUPT    0xDF
   79 
   80 #define LAPIC_ID_MAX            (LAPIC_ID_MASK)
   81 
   82 #ifndef ASSEMBLER
   83 extern void lapic_dump(void);
   84 extern void lapic_interrupt(int interrupt, void *state);
   85 extern int  lapic_to_cpu[];
   86 extern int  cpu_to_lapic[];
   87 extern void lapic_cpu_map(int lapic, int cpu_num);
   88 #endif  /* ASSEMBLER */
   89 
   90 #define CPU_NUMBER(r)                           \
   91         movl    EXT(lapic_id),r;                \
   92         movl    0(r),r;                         \
   93         shrl    $(LAPIC_ID_SHIFT),r;            \
   94         andl    $(LAPIC_ID_MASK),r;             \
   95         movl    EXT(lapic_to_cpu)(,r,4),r
   96 
   97 
   98 #define MP_IPL          SPL6    /* software interrupt level */
   99 
  100 /* word describing the reason for the interrupt, one per cpu */
  101 
  102 #ifndef ASSEMBLER
  103 #include <kern/lock.h>
  104 extern  int     real_ncpus;             /* real number of cpus */
  105 extern  int     wncpu;                  /* wanted number of cpus */
  106 decl_simple_lock_data(extern,kdb_lock)  /* kdb lock             */
  107 decl_simple_lock_data(extern,mp_putc_lock)
  108 
  109 extern  int     kdb_cpu;                /* current cpu running kdb      */
  110 extern  int     kdb_debug;
  111 extern  int     kdb_is_slave[];
  112 extern  int     kdb_active[];
  113 
  114 extern  volatile boolean_t mp_kdp_trap;
  115 extern  void    mp_trap_enter();
  116 extern  void    mp_trap_exit();
  117 
  118 /*
  119  * All cpu rendezvous:
  120  */
  121 extern void mp_rendezvous(void (*setup_func)(void *),
  122                           void (*action_func)(void *),
  123                           void (*teardown_func)(void *),
  124                           void *arg);
  125 
  126 #if MP_DEBUG
  127 typedef struct {
  128         uint64_t        time;
  129         int             cpu;
  130         mp_event_t      event;
  131 } cpu_signal_event_t;
  132 
  133 #define LOG_NENTRIES    100
  134 typedef struct {
  135         uint64_t                count[MP_LAST];
  136         int                     next_entry;
  137         cpu_signal_event_t      entry[LOG_NENTRIES];
  138 } cpu_signal_event_log_t;
  139 
  140 extern cpu_signal_event_log_t   cpu_signal[NCPUS];
  141 extern cpu_signal_event_log_t   cpu_handle[NCPUS];
  142 
  143 #define DBGLOG(log,_cpu,_event) {                                       \
  144         cpu_signal_event_log_t  *logp = &log[cpu_number()];             \
  145         int                     next = logp->next_entry;                \
  146         cpu_signal_event_t      *eventp = &logp->entry[next];           \
  147         boolean_t               spl = ml_set_interrupts_enabled(FALSE); \
  148                                                                         \
  149         logp->count[_event]++;                                          \
  150                                                                         \
  151         eventp->time = rdtsc64();                                       \
  152         eventp->cpu = _cpu;                                             \
  153         eventp->event = _event;                                         \
  154         if (next == (LOG_NENTRIES - 1))                                 \
  155                 logp->next_entry = 0;                                   \
  156         else                                                            \
  157                 logp->next_entry++;                                     \
  158                                                                         \
  159         (void) ml_set_interrupts_enabled(spl);                          \
  160 }
  161 #else   /* MP_DEBUG */
  162 #define DBGLOG(log,_cpu,_event)
  163 #endif  /* MP_DEBUG */
  164 
  165 #endif  /* ASSEMBLER */
  166 
  167 #define i_bit(bit, word)        ((long)(*(word)) & ((long)1 << (bit)))
  168 
  169 
  170 /* 
  171  *      Device driver synchronization. 
  172  *
  173  *      at386_io_lock(op) and at386_io_unlock() are called
  174  *      by device drivers when accessing H/W. The underlying 
  175  *      Processing is machine dependant. But the op argument
  176  *      to the at386_io_lock is generic
  177  */
  178 
  179 #define MP_DEV_OP_MAX     4
  180 #define MP_DEV_WAIT       MP_DEV_OP_MAX /* Wait for the lock */
  181 
  182 /*
  183  * If the caller specifies an op value different than MP_DEV_WAIT, the
  184  * at386_io_lock function must return true if lock was successful else
  185  * false
  186  */
  187 
  188 #define MP_DEV_OP_START 0       /* If lock busy, register a pending start op */
  189 #define MP_DEV_OP_INTR  1       /* If lock busy, register a pending intr */
  190 #define MP_DEV_OP_TIMEO 2       /* If lock busy, register a pending timeout */
  191 #define MP_DEV_OP_CALLB 3       /* If lock busy, register a pending callback */
  192 
  193 #else   /* NCPUS > 1 */
  194 #define at386_io_lock_state()
  195 #define at386_io_lock(op)       (TRUE)
  196 #define at386_io_unlock()
  197 #define mp_trap_enter()
  198 #define mp_trap_exit()
  199 #include        <i386/apic.h>
  200 #endif  /* NCPUS > 1 */
  201 
  202 #if     MACH_RT
  203 #define _DISABLE_PREEMPTION(r)                                  \
  204         movl    $ CPD_PREEMPTION_LEVEL,r                        ;       \
  205         incl    %gs:(r)
  206 
  207 #define _ENABLE_PREEMPTION(r)                                   \
  208         movl    $ CPD_PREEMPTION_LEVEL,r                        ;       \
  209         decl    %gs:(r)                                 ;       \
  210         jne     9f                                      ;       \
  211         pushl   %eax                                    ;       \
  212         pushl   %ecx                                    ;       \
  213         pushl   %edx                                    ;       \
  214         call    EXT(kernel_preempt_check)               ;       \
  215         popl    %edx                                    ;       \
  216         popl    %ecx                                    ;       \
  217         popl    %eax                                    ;       \
  218 9:      
  219 
  220 #define _ENABLE_PREEMPTION_NO_CHECK(r)                          \
  221         movl    $ CPD_PREEMPTION_LEVEL,r                        ;       \
  222         decl    %gs:(r)
  223 
  224 #if     MACH_ASSERT
  225 #define DISABLE_PREEMPTION(r)                                   \
  226         pushl   %eax;                                           \
  227         pushl   %ecx;                                           \
  228         pushl   %edx;                                           \
  229         call    EXT(_disable_preemption);                       \
  230         popl    %edx;                                           \
  231         popl    %ecx;                                           \
  232         popl    %eax
  233 #define ENABLE_PREEMPTION(r)                                    \
  234         pushl   %eax;                                           \
  235         pushl   %ecx;                                           \
  236         pushl   %edx;                                           \
  237         call    EXT(_enable_preemption);                        \
  238         popl    %edx;                                           \
  239         popl    %ecx;                                           \
  240         popl    %eax
  241 #define ENABLE_PREEMPTION_NO_CHECK(r)                           \
  242         pushl   %eax;                                           \
  243         pushl   %ecx;                                           \
  244         pushl   %edx;                                           \
  245         call    EXT(_enable_preemption_no_check);               \
  246         popl    %edx;                                           \
  247         popl    %ecx;                                           \
  248         popl    %eax
  249 #if     NCPUS > 1
  250 #define MP_DISABLE_PREEMPTION(r)                                        \
  251         pushl   %eax;                                           \
  252         pushl   %ecx;                                           \
  253         pushl   %edx;                                           \
  254         call    EXT(_mp_disable_preemption);                    \
  255         popl    %edx;                                           \
  256         popl    %ecx;                                           \
  257         popl    %eax
  258 #define MP_ENABLE_PREEMPTION(r)                                 \
  259         pushl   %eax;                                           \
  260         pushl   %ecx;                                           \
  261         pushl   %edx;                                           \
  262         call    EXT(_mp_enable_preemption);                     \
  263         popl    %edx;                                           \
  264         popl    %ecx;                                           \
  265         popl    %eax
  266 #define MP_ENABLE_PREEMPTION_NO_CHECK(r)                                \
  267         pushl   %eax;                                           \
  268         pushl   %ecx;                                           \
  269         pushl   %edx;                                           \
  270         call    EXT(_mp_enable_preemption_no_check);            \
  271         popl    %edx;                                           \
  272         popl    %ecx;                                           \
  273         popl    %eax
  274 #else   /* NCPUS > 1 */
  275 #define MP_DISABLE_PREEMPTION(r)
  276 #define MP_ENABLE_PREEMPTION(r)
  277 #define MP_ENABLE_PREEMPTION_NO_CHECK(r)
  278 #endif  /* NCPUS > 1 */
  279 #else   /* MACH_ASSERT */
  280 #define DISABLE_PREEMPTION(r)                   _DISABLE_PREEMPTION(r)
  281 #define ENABLE_PREEMPTION(r)                    _ENABLE_PREEMPTION(r)
  282 #define ENABLE_PREEMPTION_NO_CHECK(r)           _ENABLE_PREEMPTION_NO_CHECK(r)
  283 #if     NCPUS > 1
  284 #define MP_DISABLE_PREEMPTION(r)                _DISABLE_PREEMPTION(r)
  285 #define MP_ENABLE_PREEMPTION(r)                 _ENABLE_PREEMPTION(r)
  286 #define MP_ENABLE_PREEMPTION_NO_CHECK(r)        _ENABLE_PREEMPTION_NO_CHECK(r)
  287 #else   /* NCPUS > 1 */
  288 #define MP_DISABLE_PREEMPTION(r)
  289 #define MP_ENABLE_PREEMPTION(r)
  290 #define MP_ENABLE_PREEMPTION_NO_CHECK(r)
  291 #endif  /* NCPUS > 1 */
  292 #endif  /* MACH_ASSERT */
  293 
  294 #else   /* MACH_RT */
  295 #define DISABLE_PREEMPTION(r)
  296 #define ENABLE_PREEMPTION(r)
  297 #define ENABLE_PREEMPTION_NO_CHECK(r)
  298 #define MP_DISABLE_PREEMPTION(r)
  299 #define MP_ENABLE_PREEMPTION(r)
  300 #define MP_ENABLE_PREEMPTION_NO_CHECK(r)
  301 #endif  /* MACH_RT */
  302 
  303 #endif /* _I386AT_MP_H_ */

Cache object: 67539aa750f5d4d7ceec60c97d120143


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.