1*7780107dSmpi /* $OpenBSD: cpu.h,v 1.82 2024/10/23 07:41:44 mpi Exp $ */ 23180e169Smiod /* 33180e169Smiod * Copyright (c) 1996 Nivas Madhur 43180e169Smiod * Copyright (c) 1992, 1993 53180e169Smiod * The Regents of the University of California. All rights reserved. 63180e169Smiod * 73180e169Smiod * This software was developed by the Computer Systems Engineering group 83180e169Smiod * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 93180e169Smiod * contributed to Berkeley. 103180e169Smiod * 113180e169Smiod * All advertising materials mentioning features or use of this software 123180e169Smiod * must display the following acknowledgement: 133180e169Smiod * This product includes software developed by the University of 143180e169Smiod * California, Lawrence Berkeley Laboratory. 153180e169Smiod * 163180e169Smiod * Redistribution and use in source and binary forms, with or without 173180e169Smiod * modification, are permitted provided that the following conditions 183180e169Smiod * are met: 193180e169Smiod * 1. Redistributions of source code must retain the above copyright 203180e169Smiod * notice, this list of conditions and the following disclaimer. 213180e169Smiod * 2. Redistributions in binary form must reproduce the above copyright 223180e169Smiod * notice, this list of conditions and the following disclaimer in the 233180e169Smiod * documentation and/or other materials provided with the distribution. 243180e169Smiod * 3. Neither the name of the University nor the names of its contributors 253180e169Smiod * may be used to endorse or promote products derived from this software 263180e169Smiod * without specific prior written permission. 273180e169Smiod * 283180e169Smiod * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 293180e169Smiod * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 303180e169Smiod * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 313180e169Smiod * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 323180e169Smiod * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 333180e169Smiod * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 343180e169Smiod * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 353180e169Smiod * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 363180e169Smiod * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 373180e169Smiod * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 383180e169Smiod * SUCH DAMAGE. 393180e169Smiod */ 403180e169Smiod 412fa72412Spirofti #ifndef _M88K_CPU_H_ 422fa72412Spirofti #define _M88K_CPU_H_ 433180e169Smiod 443180e169Smiod /* 454d868bdaSmiod * CTL_MACHDEP definitions. 463180e169Smiod */ 473180e169Smiod #define CPU_CONSDEV 1 /* dev_t: console terminal device */ 48ca48064eSmiod #define CPU_CPUTYPE 2 /* int: cpu type */ 49ca48064eSmiod #define CPU_MAXID 3 /* number of valid machdep ids */ 503180e169Smiod 513180e169Smiod #define CTL_MACHDEP_NAMES { \ 523180e169Smiod { 0, 0 }, \ 533180e169Smiod { "console_device", CTLTYPE_STRUCT }, \ 54ca48064eSmiod { "cputype", CTLTYPE_INT }, \ 553180e169Smiod } 563180e169Smiod 573180e169Smiod #ifdef _KERNEL 583180e169Smiod 59b6fc7041Smiod #include <machine/atomic.h> 603180e169Smiod #include <machine/pcb.h> 613367ca7dSmiod #include <machine/psl.h> 620934804cSmiod #include <machine/intr.h> 63882ee9bcScheloha #include <sys/clockintr.h> 6445053f4aSart #include <sys/queue.h> 650934804cSmiod #include <sys/sched.h> 661a1181a9Sjsg #include <sys/srp.h> 679f71c9adSaoyama #include <uvm/uvm_percpu.h> 680934804cSmiod 690934804cSmiod #if defined(MULTIPROCESSOR) 700934804cSmiod #if !defined(MAX_CPUS) || MAX_CPUS > 4 710934804cSmiod #undef MAX_CPUS 720934804cSmiod #define MAX_CPUS 4 730934804cSmiod #endif 740934804cSmiod #else 7577d59b8aSaoyama #if !defined(MAX_CPUS) 760934804cSmiod #undef MAX_CPUS 770934804cSmiod #define MAX_CPUS 1 780934804cSmiod #endif 7977d59b8aSaoyama #endif 803180e169Smiod 8187fa3cf5Smiod #ifndef _LOCORE 8287fa3cf5Smiod 8369d29e1eSmiod #include <machine/lock.h> 8469d29e1eSmiod 850934804cSmiod /* 860934804cSmiod * Per-CPU data structure 870934804cSmiod */ 8887fa3cf5Smiod 898e726268Smiod struct pmap; 908e726268Smiod 910934804cSmiod struct cpu_info { 92e8c48788Smiod volatile u_int ci_flags; 9384d9d96fSmiod #define CIF_ALIVE 0x01 /* cpu initialized */ 9484d9d96fSmiod #define CIF_PRIMARY 0x02 /* primary cpu */ 950934804cSmiod 960934804cSmiod struct proc *ci_curproc; /* current process... */ 978e726268Smiod struct pcb *ci_curpcb; /* ...its pcb... */ 988e726268Smiod struct pmap *ci_curpmap; /* ...and its pmap */ 990934804cSmiod 1000934804cSmiod u_int ci_cpuid; /* cpu number */ 1014d868bdaSmiod 102bee5e359Smiod /* 10369d29e1eSmiod * Function pointers used within mplock to ensure 10469d29e1eSmiod * non-interruptability. 10569d29e1eSmiod */ 10669d29e1eSmiod uint32_t (*ci_mp_atomic_begin) 10769d29e1eSmiod (__cpu_simple_lock_t *lock, uint *csr); 10869d29e1eSmiod void (*ci_mp_atomic_end) 10969d29e1eSmiod (uint32_t psr, __cpu_simple_lock_t *lock, uint csr); 11069d29e1eSmiod 11169d29e1eSmiod /* 11210d5fe2dSmiod * Other processor-dependent routines 11310d5fe2dSmiod */ 11410d5fe2dSmiod void (*ci_zeropage)(vaddr_t); 11510d5fe2dSmiod void (*ci_copypage)(vaddr_t, vaddr_t); 11610d5fe2dSmiod 11710d5fe2dSmiod /* 118bee5e359Smiod * The following fields are used differently depending on 119bee5e359Smiod * the processor type. Think of them as an anonymous union 120bee5e359Smiod * of two anonymous structs. 121bee5e359Smiod */ 122bee5e359Smiod u_int ci_cpudep0; 123bee5e359Smiod u_int ci_cpudep1; 124bee5e359Smiod u_int ci_cpudep2; 125bee5e359Smiod u_int ci_cpudep3; 126bee5e359Smiod u_int ci_cpudep4; 127bee5e359Smiod u_int ci_cpudep5; 128d1a7ae11Smiod u_int ci_cpudep6; 129d1a7ae11Smiod u_int ci_cpudep7; 1300934804cSmiod 131bee5e359Smiod /* 88100 fields */ 132bee5e359Smiod #define ci_pfsr_i0 ci_cpudep0 /* instruction... */ 133bee5e359Smiod #define ci_pfsr_i1 ci_cpudep1 134bee5e359Smiod #define ci_pfsr_d0 ci_cpudep2 /* ...and data CMMU PFSRs */ 135bee5e359Smiod #define ci_pfsr_d1 ci_cpudep3 136bee5e359Smiod 137bee5e359Smiod /* 88110 fields */ 13860c4ac0aSmiod #define ci_ipi_arg1 ci_cpudep0 /* Complex IPI arguments */ 13960c4ac0aSmiod #define ci_ipi_arg2 ci_cpudep1 14060c4ac0aSmiod #define ci_h_sxip ci_cpudep2 /* trapframe values */ 14160c4ac0aSmiod #define ci_h_epsr ci_cpudep3 /* for hardclock */ 14260c4ac0aSmiod #define ci_s_sxip ci_cpudep4 /* and softclock */ 14360c4ac0aSmiod #define ci_s_epsr ci_cpudep5 144bee5e359Smiod 145bee5e359Smiod struct schedstate_percpu 146bee5e359Smiod ci_schedstate; /* scheduling state */ 1470934804cSmiod int ci_want_resched; /* need_resched() invoked */ 1480934804cSmiod 149*7780107dSmpi u_int ci_idepth; /* interrupt depth */ 1500934804cSmiod 15184d9d96fSmiod int ci_ddb_state; /* ddb status */ 1527625720eSmiod #define CI_DDB_RUNNING 0 1537625720eSmiod #define CI_DDB_ENTERDDB 1 1547625720eSmiod #define CI_DDB_INDDB 2 155a663b1dfSmiod #define CI_DDB_PAUSE 3 156a663b1dfSmiod 1573b873c4eSmiod u_int32_t ci_randseed; /* per-cpu random seed */ 1583b873c4eSmiod 15984d9d96fSmiod int ci_ipi; /* pending ipis */ 160a663b1dfSmiod #define CI_IPI_NOTIFY 0x00000001 161a663b1dfSmiod #define CI_IPI_HARDCLOCK 0x00000002 162a663b1dfSmiod #define CI_IPI_STATCLOCK 0x00000004 163a663b1dfSmiod #define CI_IPI_DDB 0x00000008 164bee5e359Smiod /* 88110 simple ipi */ 165d4c6e0e5Smiod #define CI_IPI_TLB_FLUSH_KERNEL 0x00000010 166d4c6e0e5Smiod #define CI_IPI_TLB_FLUSH_USER 0x00000020 167bee5e359Smiod /* 88110 complex ipi */ 168d4c6e0e5Smiod #define CI_IPI_CACHE_FLUSH 0x00000040 169d4c6e0e5Smiod #define CI_IPI_ICACHE_FLUSH 0x00000080 170bee5e359Smiod #define CI_IPI_DMA_CACHECTL 0x00000100 171d5f250e9Smiod void (*ci_softipi_cb)(void); /* 88110 softipi callback */ 172ac5996fcSmiod 1738db9df62Saoyama #if defined(MULTIPROCESSOR) 1748db9df62Saoyama struct srp_hazard ci_srp_hazards[SRP_HAZARD_NUM]; 1759f71c9adSaoyama #define __HAVE_UVM_PERCPU 1769f71c9adSaoyama struct uvm_pmr_cache ci_uvm; /* [o] page cache */ 1778db9df62Saoyama #endif 178ac5996fcSmiod #ifdef DIAGNOSTIC 179ac5996fcSmiod int ci_mutex_level; 180ac5996fcSmiod #endif 1816377c2eaSmpi #ifdef GPROF 1826377c2eaSmpi struct gmonparam *ci_gmon; 1831d970828Scheloha struct clockintr ci_gmonclock; 1846377c2eaSmpi #endif 185c737cf90Scheloha struct clockqueue ci_queue; 1861a4a9ab2Scheloha char ci_panicbuf[512]; 1870934804cSmiod }; 1880934804cSmiod 1890934804cSmiod extern cpuid_t master_cpu; 1900934804cSmiod extern struct cpu_info m88k_cpus[MAX_CPUS]; 1910934804cSmiod 1920934804cSmiod #define CPU_INFO_ITERATOR cpuid_t 1930934804cSmiod #define CPU_INFO_FOREACH(cii, ci) \ 1940934804cSmiod for ((cii) = 0; (cii) < MAX_CPUS; (cii)++) \ 19584d9d96fSmiod if (((ci) = &m88k_cpus[cii])->ci_flags & CIF_ALIVE) 1960934804cSmiod #define CPU_INFO_UNIT(ci) ((ci)->ci_cpuid) 197e3444f33Sart #define MAXCPUS MAX_CPUS 1980934804cSmiod 1990934804cSmiod #if defined(MULTIPROCESSOR) 2000934804cSmiod 20176b27a1cSmiod static __inline__ struct cpu_info * 20276b27a1cSmiod curcpu(void) 20376b27a1cSmiod { 20476b27a1cSmiod struct cpu_info *cpuptr; 20576b27a1cSmiod 2062df76cc2Sguenther __asm__ volatile ("ldcr %0, %%cr17" : "=r" (cpuptr)); 20776b27a1cSmiod return cpuptr; 20876b27a1cSmiod } 2090934804cSmiod 21084d9d96fSmiod #define CPU_IS_PRIMARY(ci) ((ci)->ci_flags & CIF_PRIMARY) 211d73de46fSkettenis #define CPU_IS_RUNNING(ci) ((ci)->ci_flags & CIF_ALIVE) 2120934804cSmiod 2130934804cSmiod void cpu_boot_secondary_processors(void); 2149e1fcc5aSmiod void cpu_unidle(struct cpu_info *); 215a663b1dfSmiod void m88k_send_ipi(int, cpuid_t); 216a663b1dfSmiod void m88k_broadcast_ipi(int); 2170934804cSmiod 2180934804cSmiod #else /* MULTIPROCESSOR */ 2190934804cSmiod 2200934804cSmiod #define curcpu() (&m88k_cpus[0]) 2219e1fcc5aSmiod #define cpu_unidle(ci) do { /* nothing */ } while (0) 2220934804cSmiod #define CPU_IS_PRIMARY(ci) 1 223d73de46fSkettenis #define CPU_IS_RUNNING(ci) 1 2240934804cSmiod 2250934804cSmiod #endif /* MULTIPROCESSOR */ 2260934804cSmiod 227b43d7c27Sjca #define CPU_BUSY_CYCLE() __asm volatile ("" ::: "memory") 22865f535b7Suebayasi 2298adebe84Smiod struct cpu_info *set_cpu_number(cpuid_t); 23078e3ae4dSmiod 2310934804cSmiod /* 2320934804cSmiod * The md code may hardcode this in some very specific situations. 2330934804cSmiod */ 2340934804cSmiod #if !defined(cpu_number) 2350934804cSmiod #define cpu_number() curcpu()->ci_cpuid 2360934804cSmiod #endif 2370934804cSmiod 2380934804cSmiod #define curpcb curcpu()->ci_curpcb 23987fa3cf5Smiod 24001802d2cSdlg unsigned int cpu_rnd_messybits(void); 24101802d2cSdlg 24287fa3cf5Smiod #endif /* _LOCORE */ 24387fa3cf5Smiod 2443180e169Smiod /* 2453180e169Smiod * definitions of cpu-dependent requirements 2463180e169Smiod * referenced in generic code 2473180e169Smiod */ 2483180e169Smiod 24999c8499eSmiod #define cpu_idle_enter() do { /* nothing */ } while (0) 25045053f4aSart #define cpu_idle_cycle() do { /* nothing */ } while (0) 25199c8499eSmiod #define cpu_idle_leave() do { /* nothing */ } while (0) 25245053f4aSart 2530934804cSmiod #if defined(MULTIPROCESSOR) 2540934804cSmiod #include <sys/mplock.h> 2550934804cSmiod #endif 2560934804cSmiod 2573180e169Smiod /* 258d17bebc4Smiod * Arguments to clockintr_dispatch encapsulate the previous 2593180e169Smiod * machine state in an opaque clockframe. CLKF_INTR is only valid 2603180e169Smiod * if the process is in kernel mode. Clockframe is really trapframe, 2613180e169Smiod * so pointer to clockframe can be safely cast into a pointer to 2623180e169Smiod * trapframe. 2633180e169Smiod */ 2643180e169Smiod struct clockframe { 2653180e169Smiod struct trapframe tf; 2663180e169Smiod }; 2673180e169Smiod 268a331c5a6Smiod #define CLKF_USERMODE(framep) (((framep)->tf.tf_epsr & PSR_MODE) == 0) 269a331c5a6Smiod #define CLKF_PC(framep) ((framep)->tf.tf_sxip & XIP_ADDR) 2700934804cSmiod #define CLKF_INTR(framep) \ 271*7780107dSmpi (((struct cpu_info *)(framep)->tf.tf_cpu)->ci_idepth > 1) 2723180e169Smiod 273a331c5a6Smiod #define aston(p) ((p)->p_md.md_astpending = 1) 2743180e169Smiod 2753180e169Smiod /* 2764516c5b4Smiod * This is used during profiling to integrate system time. 2774516c5b4Smiod */ 2784516c5b4Smiod #define PC_REGS(regs) \ 2794516c5b4Smiod (CPU_IS88110 ? ((regs)->exip & XIP_ADDR) : \ 2804516c5b4Smiod ((regs)->sxip & XIP_V ? (regs)->sxip & XIP_ADDR : \ 2814516c5b4Smiod ((regs)->snip & NIP_V ? (regs)->snip & NIP_ADDR : \ 2824516c5b4Smiod (regs)->sfip & FIP_ADDR))) 2834516c5b4Smiod #define PROC_PC(p) PC_REGS((struct reg *)((p)->p_md.md_tf)) 2841eaa59e7Sguenther #define PROC_STACK(p) ((p)->p_md.md_tf->tf_sp) 2854516c5b4Smiod 2862c9d4ccbSart #define clear_resched(ci) (ci)->ci_want_resched = 0 2873180e169Smiod 2883180e169Smiod /* 2893180e169Smiod * Give a profiling tick to the current process when the user profiling 2900934804cSmiod * buffer pages are invalid. On the m88k, request an ast to send us 2913180e169Smiod * through trap(), marking the proc as needing a profiling tick. 2923180e169Smiod */ 29329514732Sart #define need_proftick(p) aston(p) 2943180e169Smiod 2959e1fcc5aSmiod void need_resched(struct cpu_info *); 29680a92716Smiod void signotify(struct proc *); 297bee5e359Smiod void softipi(void); 2983180e169Smiod 29978e3ae4dSmiod int badaddr(vaddr_t addr, int size); 300a83c48b9Smiod void set_vbr(register_t); 301a83c48b9Smiod extern register_t kernel_vbr; 3023180e169Smiod 303d62ebcb2Sderaadt #define copyinsn(p, v, ip) copyin32((v), (ip)) 304d62ebcb2Sderaadt 3053180e169Smiod #endif /* _KERNEL */ 3062fa72412Spirofti #endif /* _M88K_CPU_H_ */ 307