1 /* $NetBSD: cpu.h,v 1.63 2003/01/22 21:58:28 pk Exp $ */ 2 3 /* 4 * Copyright (c) 1992, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This software was developed by the Computer Systems Engineering group 8 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 9 * contributed to Berkeley. 10 * 11 * All advertising materials mentioning features or use of this software 12 * must display the following acknowledgement: 13 * This product includes software developed by the University of 14 * California, Lawrence Berkeley Laboratory. 15 * 16 * Redistribution and use in source and binary forms, with or without 17 * modification, are permitted provided that the following conditions 18 * are met: 19 * 1. Redistributions of source code must retain the above copyright 20 * notice, this list of conditions and the following disclaimer. 21 * 2. Redistributions in binary form must reproduce the above copyright 22 * notice, this list of conditions and the following disclaimer in the 23 * documentation and/or other materials provided with the distribution. 24 * 3. All advertising materials mentioning features or use of this software 25 * must display the following acknowledgement: 26 * This product includes software developed by the University of 27 * California, Berkeley and its contributors. 28 * 4. Neither the name of the University nor the names of its contributors 29 * may be used to endorse or promote products derived from this software 30 * without specific prior written permission. 31 * 32 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 33 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 34 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 35 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 36 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 40 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 41 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 42 * SUCH DAMAGE. 43 * 44 * @(#)cpu.h 8.4 (Berkeley) 1/5/94 45 */ 46 47 #ifndef _CPU_H_ 48 #define _CPU_H_ 49 50 /* 51 * CTL_MACHDEP definitions. 52 */ 53 #define CPU_BOOTED_KERNEL 1 /* string: booted kernel name */ 54 #define CPU_BOOTED_DEVICE 2 /* string: device booted from */ 55 #define CPU_BOOT_ARGS 3 /* string: args booted with */ 56 #define CPU_ARCH 4 /* integer: cpu architecture version */ 57 #define CPU_MAXID 5 /* number of valid machdep ids */ 58 59 #define CTL_MACHDEP_NAMES { \ 60 { 0, 0 }, \ 61 { "booted_kernel", CTLTYPE_STRING }, \ 62 { "booted_device", CTLTYPE_STRING }, \ 63 { "boot_args", CTLTYPE_STRING }, \ 64 { "cpu_arch", CTLTYPE_INT }, \ 65 } 66 67 #ifdef _KERNEL 68 /* 69 * Exported definitions unique to SPARC cpu support. 70 */ 71 72 #if !defined(_LKM) && defined(_KERNEL_OPT) 73 #include "opt_multiprocessor.h" 74 #include "opt_lockdebug.h" 75 #include "opt_sparc_arch.h" 76 #endif 77 78 #include <machine/intr.h> 79 #include <machine/psl.h> 80 #include <sparc/sparc/cpuvar.h> 81 #include <sparc/sparc/intreg.h> 82 83 /* 84 * definitions of cpu-dependent requirements 85 * referenced in generic code 86 */ 87 #define curcpu() (cpuinfo.ci_self) 88 #define curlwp (cpuinfo.ci_curlwp) 89 #define CPU_IS_PRIMARY(ci) ((ci)->master) 90 91 #define cpu_swapin(p) /* nothing */ 92 #define cpu_swapout(p) /* nothing */ 93 #define cpu_wait(p) /* nothing */ 94 #define cpu_number() (cpuinfo.ci_cpuid) 95 #define cpu_proc_fork(p1, p2) /* nothing */ 96 97 #if defined(MULTIPROCESSOR) 98 void cpu_boot_secondary_processors __P((void)); 99 #endif 100 101 /* 102 * Arguments to hardclock, softclock and statclock encapsulate the 103 * previous machine state in an opaque clockframe. The ipl is here 104 * as well for strayintr (see locore.s:interrupt and intr.c:strayintr). 105 * Note that CLKF_INTR is valid only if CLKF_USERMODE is false. 106 */ 107 struct clockframe { 108 u_int psr; /* psr before interrupt, excluding PSR_ET */ 109 u_int pc; /* pc at interrupt */ 110 u_int npc; /* npc at interrupt */ 111 u_int ipl; /* actual interrupt priority level */ 112 u_int fp; /* %fp at interrupt */ 113 }; 114 typedef struct clockframe clockframe; 115 116 extern int eintstack[]; 117 118 #define CLKF_USERMODE(framep) (((framep)->psr & PSR_PS) == 0) 119 #define CLKF_BASEPRI(framep) (((framep)->psr & PSR_PIL) == 0) 120 #define CLKF_LOPRI(framep,n) (((framep)->psr & PSR_PIL) < (n) << 8) 121 #define CLKF_PC(framep) ((framep)->pc) 122 #if defined(MULTIPROCESSOR) 123 #define CLKF_INTR(framep) \ 124 ((framep)->fp > (u_int)cpuinfo.eintstack - INT_STACK_SIZE && \ 125 (framep)->fp < (u_int)cpuinfo.eintstack) 126 #else 127 #define CLKF_INTR(framep) ((framep)->fp < (u_int)eintstack) 128 #endif 129 130 void softintr_init __P((void)); 131 void *softnet_cookie; 132 133 #define setsoftnet() softintr_schedule(softnet_cookie); 134 135 /* 136 * Preempt the current process on the target CPU if in interrupt from 137 * user mode, or after the current trap/syscall if in system mode. 138 */ 139 #define need_resched(ci) do { \ 140 (ci)->want_resched = 1; \ 141 (ci)->want_ast = 1; \ 142 \ 143 /* Just interrupt the target CPU, so it can notice its AST */ \ 144 if ((ci)->ci_cpuid != cpu_number()) \ 145 XCALL0(sparc_noop, 1U << (ci)->ci_cpuid); \ 146 } while(0) 147 148 /* 149 * Give a profiling tick to the current process when the user profiling 150 * buffer pages are invalid. On the sparc, request an ast to send us 151 * through trap(), marking the proc as needing a profiling tick. 152 */ 153 #define need_proftick(p) ((p)->p_flag |= P_OWEUPC, cpuinfo.want_ast = 1) 154 155 /* 156 * Notify the current process (p) that it has a signal pending, 157 * process as soon as possible. 158 */ 159 #define signotify(p) (cpuinfo.want_ast = 1) 160 161 /* CPU architecture version */ 162 extern int cpu_arch; 163 164 /* Number of CPUs in the system */ 165 extern int ncpu; 166 167 /* 168 * Interrupt handler chains. Interrupt handlers should return 0 for 169 * ``not me'' or 1 (``I took care of it''). intr_establish() inserts a 170 * handler into the list. The handler is called with its (single) 171 * argument, or with a pointer to a clockframe if ih_arg is NULL. 172 */ 173 extern struct intrhand { 174 int (*ih_fun)(void *); 175 void *ih_arg; 176 struct intrhand *ih_next; 177 int ih_classipl; 178 } *intrhand[15]; 179 180 void intr_establish(int level, int classipl, struct intrhand *, 181 void (*fastvec)(void)); 182 void intr_disestablish(int level, struct intrhand *); 183 184 void intr_lock_kernel(void); 185 void intr_unlock_kernel(void); 186 187 /* disksubr.c */ 188 struct dkbad; 189 int isbad(struct dkbad *bt, int, int, int); 190 /* machdep.c */ 191 int ldcontrolb(caddr_t); 192 void dumpconf(void); 193 caddr_t reserve_dumppages(caddr_t); 194 /* clock.c */ 195 struct timeval; 196 void lo_microtime(struct timeval *); 197 void schedintr(void *); 198 /* locore.s */ 199 struct fpstate; 200 void savefpstate(struct fpstate *); 201 void loadfpstate(struct fpstate *); 202 int probeget(caddr_t, int); 203 void write_all_windows(void); 204 void write_user_windows(void); 205 void proc_trampoline(void); 206 void switchexit(struct lwp *, void (*)(struct lwp *)); 207 struct pcb; 208 void snapshot(struct pcb *); 209 struct frame *getfp(void); 210 int xldcontrolb(caddr_t, struct pcb *); 211 void copywords(const void *, void *, size_t); 212 void qcopy(const void *, void *, size_t); 213 void qzero(void *, size_t); 214 /* trap.c */ 215 void kill_user_windows(struct lwp *); 216 int rwindow_save(struct lwp *); 217 /* cons.c */ 218 int cnrom(void); 219 /* zs.c */ 220 void zsconsole(struct tty *, int, int, void (**)(struct tty *, int)); 221 #ifdef KGDB 222 void zs_kgdb_init(void); 223 #endif 224 /* fb.c */ 225 void fb_unblank(void); 226 /* cache.c */ 227 void cache_flush(caddr_t, u_int); 228 /* kgdb_stub.c */ 229 #ifdef KGDB 230 void kgdb_attach(int (*)(void *), void (*)(void *, int), void *); 231 void kgdb_connect(int); 232 void kgdb_panic(void); 233 #endif 234 /* emul.c */ 235 struct trapframe; 236 int fixalign(struct lwp *, struct trapframe *); 237 int emulinstr(int, struct trapframe *); 238 /* cpu.c */ 239 void mp_pause_cpus(void); 240 void mp_resume_cpus(void); 241 void mp_halt_cpus(void); 242 #ifdef DDB 243 void mp_pause_cpus_ddb(void); 244 void mp_resume_cpus_ddb(void); 245 #endif 246 /* msiiep.c */ 247 void msiiep_swap_endian(int); 248 /* intr.c */ 249 u_int setitr(u_int); 250 u_int getitr(void); 251 252 /* 253 * 254 * The SPARC has a Trap Base Register (TBR) which holds the upper 20 bits 255 * of the trap vector table. The next eight bits are supplied by the 256 * hardware when the trap occurs, and the bottom four bits are always 257 * zero (so that we can shove up to 16 bytes of executable code---exactly 258 * four instructions---into each trap vector). 259 * 260 * The hardware allocates half the trap vectors to hardware and half to 261 * software. 262 * 263 * Traps have priorities assigned (lower number => higher priority). 264 */ 265 266 struct trapvec { 267 int tv_instr[4]; /* the four instructions */ 268 }; 269 extern struct trapvec *trapbase; /* the 256 vectors */ 270 271 extern void wzero __P((void *, u_int)); 272 extern void wcopy __P((const void *, void *, u_int)); 273 274 #endif /* _KERNEL */ 275 #endif /* _CPU_H_ */ 276