/* [<][>][^][v][top][bottom][index][help] */
1 /*
2 * Copyright (c) 2009
3 * The President and Fellows of Harvard College.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30 #ifndef _CPU_H_
31 #define _CPU_H_
32
33
34 #include <spinlock.h>
35 #include <threadlist.h>
36 #include <machine/vm.h> /* for TLBSHOOTDOWN_MAX */
37
38
39 /*
40 * Per-cpu structure
41 *
42 * Note: curcpu is defined by <current.h>.
43 *
44 * cpu->c_self should always be used when *using* the address of curcpu
45 * (as opposed to merely dereferencing it) in case curcpu is defined as
46 * a pointer with a fixed address and a per-cpu mapping in the MMU.
47 */
48
49 struct cpu {
50 /*
51 * Fixed after allocation.
52 */
53 struct cpu *c_self; /* Canonical address of this struct */
54 unsigned c_number; /* This cpu's cpu number */
55 unsigned c_hardware_number; /* Hardware-defined cpu number */
56
57 /*
58 * Accessed only by this cpu.
59 */
60 struct thread *c_curthread; /* Current thread on cpu */
61 struct threadlist c_zombies; /* List of exited threads */
62 unsigned c_hardclocks; /* Counter of hardclock() calls */
63
64 /*
65 * Accessed by other cpus.
66 * Protected by the runqueue lock.
67 */
68 bool c_isidle; /* True if this cpu is idle */
69 struct threadlist c_runqueue; /* Run queue for this cpu */
70 struct spinlock c_runqueue_lock;
71
72 /*
73 * Accessed by other cpus.
74 * Protected by the IPI lock.
75 *
76 * If c_numshootdown is -1 (TLBSHOOTDOWN_ALL), all mappings
77 * should be invalidated. This is used if more than
78 * TLBSHOOTDOWN_MAX mappings are going to be invalidated at
79 * once. TLBSHOOTDOWN_MAX is MD and chosen based on when it
80 * becomes more efficient just to flush the whole TLB.
81 *
82 * struct tlbshootdown is machine-dependent and might
83 * reasonably be either an address space and vaddr pair, or a
84 * paddr, or something else.
85 */
86 uint32_t c_ipi_pending; /* One bit for each IPI number */
87 struct tlbshootdown c_shootdown[TLBSHOOTDOWN_MAX];
88 int c_numshootdown;
89 struct spinlock c_ipi_lock;
90 };
91
92 #define TLBSHOOTDOWN_ALL (-1)
93
94 /*
95 * Initialization functions.
96 *
97 * cpu_create creates a cpu; it is suitable for calling from driver-
98 * or bus-specific code that looks for secondary CPUs.
99 *
100 * cpu_create calls cpu_machdep_init.
101 *
102 * cpu_start_secondary is the platform-dependent assembly language
103 * entry point for new CPUs; it can be found in start.S. It calls
104 * cpu_hatch after having claimed the startup stack and thread created
105 * for the cpu.
106 */
107 struct cpu *cpu_create(unsigned hardware_number);
108 void cpu_machdep_init(struct cpu *);
109 /*ASMLINKAGE*/ void cpu_start_secondary(void);
110 void cpu_hatch(unsigned software_number);
111
112 /*
113 * Return a string describing the CPU type.
114 */
115 const char *cpu_identify(void);
116
117 /*
118 * Hardware-level interrupt on/off, for the current CPU.
119 *
120 * These should only be used by the spl code.
121 */
122 void cpu_irqoff(void);
123 void cpu_irqon(void);
124
125 /*
126 * Idle or shut down (respectively) the processor.
127 *
128 * cpu_idle() sits around (in a low-power state if possible) until it
129 * thinks something interesting may have happened, such as an
130 * interrupt. Then it returns. (It may be wrong, so it should always
131 * be called in a loop checking some other condition.) It must be
132 * called with interrupts off to avoid race conditions, although
133 * interrupts may be delivered before it returns.
134 *
135 * cpu_halt sits around (in a low-power state if possible) until the
136 * external reset is pushed. Interrupts should be disabled. It does
137 * not return. It should not allow interrupts to be delivered.
138 */
139 void cpu_idle(void);
140 void cpu_halt(void);
141
142 /*
143 * Interprocessor interrupts.
144 *
145 * From time to time it is necessary to poke another CPU. System
146 * boards of multiprocessor machines provide a way to do this.
147 *
148 * TLB shootdown is done by the VM system when more than one processor
149 * has (or may have) a page mapped in the MMU and it is being changed
150 * or otherwise needs to be invalidated across all CPUs.
151 *
152 * ipi_send sends an IPI to one CPU.
153 * ipi_broadcast sends an IPI to all CPUs except the current one.
154 * ipi_tlbshootdown is like ipi_send but carries TLB shootdown data.
155 *
156 * interprocessor_interrupt is called on the target CPU when an IPI is
157 * received.
158 */
159
160 /* IPI types */
161 #define IPI_PANIC 0 /* System has called panic() */
162 #define IPI_OFFLINE 1 /* CPU is requested to go offline */
163 #define IPI_UNIDLE 2 /* Runnable threads are available */
164 #define IPI_TLBSHOOTDOWN 3 /* MMU mapping(s) need invalidation */
165
166 void ipi_send(struct cpu *target, int code);
167 void ipi_broadcast(int code);
168 void ipi_tlbshootdown(struct cpu *target, const struct tlbshootdown *mapping);
169
170 void interprocessor_interrupt(void);
171
172
173 #endif /* _CPU_H_ */