os161-1.99
 All Data Structures
cpu.h
00001 /*
00002  * Copyright (c) 2009
00003  *      The President and Fellows of Harvard College.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the University nor the names of its contributors
00014  *    may be used to endorse or promote products derived from this software
00015  *    without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00027  * SUCH DAMAGE.
00028  */
00029 
00030 #ifndef _CPU_H_
00031 #define _CPU_H_
00032 
00033 
00034 #include <spinlock.h>
00035 #include <threadlist.h>
00036 #include <machine/vm.h>  /* for TLBSHOOTDOWN_MAX */
00037 
00038 
00039 /*
00040  * Per-cpu structure
00041  *
00042  * Note: curcpu is defined by <current.h>.
00043  *
00044  * cpu->c_self should always be used when *using* the address of curcpu
00045  * (as opposed to merely dereferencing it) in case curcpu is defined as
00046  * a pointer with a fixed address and a per-cpu mapping in the MMU.
00047  */
00048 
00049 struct cpu {
00050         /*
00051          * Fixed after allocation.
00052          */
00053         struct cpu *c_self;             /* Canonical address of this struct */
00054         unsigned c_number;              /* This cpu's cpu number */
00055         unsigned c_hardware_number;     /* Hardware-defined cpu number */
00056 
00057         /*
00058          * Accessed only by this cpu.
00059          */
00060         struct thread *c_curthread;     /* Current thread on cpu */
00061         struct threadlist c_zombies;    /* List of exited threads */
00062         unsigned c_hardclocks;          /* Counter of hardclock() calls */
00063 
00064         /*
00065          * Accessed by other cpus.
00066          * Protected by the runqueue lock.
00067          */
00068         bool c_isidle;                  /* True if this cpu is idle */
00069         struct threadlist c_runqueue;   /* Run queue for this cpu */
00070         struct spinlock c_runqueue_lock;
00071 
00072         /*
00073          * Accessed by other cpus.
00074          * Protected by the IPI lock.
00075          *
00076          * If c_numshootdown is -1 (TLBSHOOTDOWN_ALL), all mappings
00077          * should be invalidated. This is used if more than
00078          * TLBSHOOTDOWN_MAX mappings are going to be invalidated at
00079          * once. TLBSHOOTDOWN_MAX is MD and chosen based on when it
00080          * becomes more efficient just to flush the whole TLB.
00081          *
00082          * struct tlbshootdown is machine-dependent and might
00083          * reasonably be either an address space and vaddr pair, or a
00084          * paddr, or something else.
00085          */
00086         uint32_t c_ipi_pending;         /* One bit for each IPI number */
00087         struct tlbshootdown c_shootdown[TLBSHOOTDOWN_MAX];
00088         int c_numshootdown;
00089         struct spinlock c_ipi_lock;
00090 };
00091 
00092 #define TLBSHOOTDOWN_ALL  (-1)
00093 
00094 /*
00095  * Initialization functions.
00096  * 
00097  * cpu_create creates a cpu; it is suitable for calling from driver-
00098  * or bus-specific code that looks for secondary CPUs.
00099  *
00100  * cpu_create calls cpu_machdep_init.
00101  *
00102  * cpu_start_secondary is the platform-dependent assembly language
00103  * entry point for new CPUs; it can be found in start.S. It calls
00104  * cpu_hatch after having claimed the startup stack and thread created
00105  * for the cpu.
00106  */
00107 struct cpu *cpu_create(unsigned hardware_number);
00108 void cpu_machdep_init(struct cpu *);
00109 /*ASMLINKAGE*/ void cpu_start_secondary(void);
00110 void cpu_hatch(unsigned software_number);
00111 
00112 /*
00113  * Return a string describing the CPU type.
00114  */
00115 const char *cpu_identify(void);
00116 
00117 /*
00118  * Hardware-level interrupt on/off, for the current CPU.
00119  *
00120  * These should only be used by the spl code.
00121  */
00122 void cpu_irqoff(void);
00123 void cpu_irqon(void);
00124 
00125 /*
00126  * Idle or shut down (respectively) the processor.
00127  *
00128  * cpu_idle() sits around (in a low-power state if possible) until it
00129  * thinks something interesting may have happened, such as an
00130  * interrupt. Then it returns. (It may be wrong, so it should always
00131  * be called in a loop checking some other condition.) It must be
00132  * called with interrupts off to avoid race conditions, although
00133  * interrupts may be delivered before it returns.
00134  *
00135  * cpu_halt sits around (in a low-power state if possible) until the
00136  * external reset is pushed. Interrupts should be disabled. It does
00137  * not return. It should not allow interrupts to be delivered.
00138  */
00139 void cpu_idle(void);
00140 void cpu_halt(void);
00141 
00142 /*
00143  * Interprocessor interrupts.
00144  *
00145  * From time to time it is necessary to poke another CPU. System
00146  * boards of multiprocessor machines provide a way to do this.
00147  *
00148  * TLB shootdown is done by the VM system when more than one processor
00149  * has (or may have) a page mapped in the MMU and it is being changed
00150  * or otherwise needs to be invalidated across all CPUs.
00151  *
00152  * ipi_send sends an IPI to one CPU.
00153  * ipi_broadcast sends an IPI to all CPUs except the current one.
00154  * ipi_tlbshootdown is like ipi_send but carries TLB shootdown data.
00155  *
00156  * interprocessor_interrupt is called on the target CPU when an IPI is
00157  * received.
00158  */
00159 
00160 /* IPI types */
00161 #define IPI_PANIC               0       /* System has called panic() */
00162 #define IPI_OFFLINE             1       /* CPU is requested to go offline */
00163 #define IPI_UNIDLE              2       /* Runnable threads are available */
00164 #define IPI_TLBSHOOTDOWN        3       /* MMU mapping(s) need invalidation */
00165 
00166 void ipi_send(struct cpu *target, int code);
00167 void ipi_broadcast(int code);
00168 void ipi_tlbshootdown(struct cpu *target, const struct tlbshootdown *mapping);
00169 
00170 void interprocessor_interrupt(void);
00171 
00172 
00173 #endif /* _CPU_H_ */
 All Data Structures