1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright 2021 Joyent, Inc.
  24  */
  25 
  26 /*
  27  * sun4u common CPC subroutines.
  28  */
  29 
  30 #include <sys/types.h>
  31 #include <sys/time.h>
  32 #include <sys/atomic.h>
  33 #include <sys/thread.h>
  34 #include <sys/regset.h>
  35 #include <sys/archsystm.h>
  36 #include <sys/machsystm.h>
  37 #include <sys/cpc_impl.h>
  38 #include <sys/cpc_ultra.h>
  39 #include <sys/sunddi.h>
  40 #include <sys/intr.h>
  41 #include <sys/ivintr.h>
  42 #include <sys/x_call.h>
  43 #include <sys/cpuvar.h>
  44 #include <sys/machcpuvar.h>
  45 #include <sys/cpc_pcbe.h>
  46 #include <sys/modctl.h>
  47 #include <sys/sdt.h>
  48 #include <sys/kcpc.h>
  49 
  50 uint64_t        cpc_level15_inum = 0;   /* used in interrupt.s */
  51 int             cpc_has_overflow_intr;  /* set in cheetah.c */
  52 
  53 extern kcpc_ctx_t *kcpc_overflow_intr(caddr_t arg, uint64_t bitmap);
  54 extern int kcpc_counts_include_idle;
  55 
  56 /*
  57  * Called on the boot CPU during startup.
  58  */
  59 void
  60 kcpc_hw_init(void)
  61 {
  62         if ((cpc_has_overflow_intr) && (cpc_level15_inum == 0)) {
  63                 cpc_level15_inum = add_softintr(PIL_15,
  64                     kcpc_hw_overflow_intr, NULL, SOFTINT_MT);
  65         }
  66 
  67         /*
  68          * Make sure the boot CPU gets set up.
  69          */
  70         kcpc_hw_startup_cpu(CPU->cpu_flags);
  71 }
  72 
  73 /*
  74  * Prepare for CPC interrupts and install an idle thread CPC context.
  75  */
  76 void
  77 kcpc_hw_startup_cpu(ushort_t cpflags)
  78 {
  79         cpu_t           *cp = CPU;
  80         kthread_t       *t = cp->cpu_idle_thread;
  81 
  82         ASSERT(t->t_bound_cpu == cp);
  83 
  84         if (cpc_has_overflow_intr && (cpflags & CPU_FROZEN) == 0) {
  85                 int pstate_save = disable_vec_intr();
  86 
  87                 ASSERT(cpc_level15_inum != 0);
  88 
  89                 intr_enqueue_req(PIL_15, cpc_level15_inum);
  90                 enable_vec_intr(pstate_save);
  91         }
  92 
  93         mutex_init(&cp->cpu_cpc_ctxlock, "cpu_cpc_ctxlock", MUTEX_DEFAULT, 0);
  94 
  95         if (kcpc_counts_include_idle)
  96                 return;
  97 
  98         installctx(t, cp, kcpc_idle_save, kcpc_idle_restore, NULL, NULL,
  99             NULL, NULL, NULL);
 100 }
 101 
 102 /*
 103  * Examine the processor and load an appropriate PCBE.
 104  */
 105 int
 106 kcpc_hw_load_pcbe(void)
 107 {
 108         uint64_t        ver = ultra_getver();
 109 
 110         return (kcpc_pcbe_tryload(NULL, ULTRA_VER_MANUF(ver),
 111             ULTRA_VER_IMPL(ver), ULTRA_VER_MASK(ver)));
 112 }
 113 
 114 /*ARGSUSED*/
 115 int
 116 kcpc_hw_cpu_hook(processorid_t cpuid, ulong_t *kcpc_cpumap)
 117 {
 118         return (0);
 119 }
 120 
 121 int
 122 kcpc_hw_lwp_hook(void)
 123 {
 124         return (0);
 125 }