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 2007 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 #pragma ident   "%Z%%M% %I%     %E% SMI"
  27 
  28 /*
  29  * Kernel/Debugger Interface (KDI) routines.  Called during debugger under
  30  * various system states (boot, while running, while the debugger has control).
  31  * Functions intended for use while the debugger has control may not grab any
  32  * locks or perform any functions that assume the availability of other system
  33  * services.
  34  */
  35 
  36 #include <sys/systm.h>
  37 #include <sys/x86_archext.h>
  38 #include <sys/kdi_impl.h>
  39 #include <sys/smp_impldefs.h>
  40 #include <sys/psm_types.h>
  41 #include <sys/segments.h>
  42 #include <sys/archsystm.h>
  43 #include <sys/controlregs.h>
  44 #include <sys/trap.h>
  45 #include <sys/kobj.h>
  46 #include <sys/kobj_impl.h>
  47 #include <sys/hypervisor.h>
  48 #include <sys/bootconf.h>
  49 #include <sys/bootinfo.h>
  50 #include <sys/promif.h>
  51 #include <sys/evtchn_impl.h>
  52 #include <sys/cpu.h>
  53 #include <vm/kboot_mmu.h>
  54 #include <vm/hat_pte.h>
  55 
  56 static volatile int kdi_slaves_go;
  57 
  58 /*
  59  * These are not safe against dropping into kmdb when fbt::: is active. This is
  60  * also broken on i86pc...
  61  */
  62 
  63 void
  64 kdi_idtr_write(desctbr_t *idtr)
  65 {
  66         gate_desc_t *idt = (gate_desc_t *)idtr->dtr_base;
  67         uint_t nidt = (idtr->dtr_limit + 1) / sizeof (*idt);
  68         uint_t vec;
  69 
  70         for (vec = 0; vec < nidt; vec++, idt++)
  71                 xen_idt_write(idt, vec);
  72 }
  73 
  74 void
  75 kdi_idt_write(gate_desc_t *gate, uint_t vec)
  76 {
  77         gate_desc_t *idt = CPU->cpu_m.mcpu_idt;
  78 
  79         /*
  80          * See kdi_idtr_set().
  81          */
  82         if (idt != NULL)
  83                 idt[vec] = *gate;
  84 
  85         xen_idt_write(gate, vec);
  86 }
  87 
  88 ulong_t
  89 kdi_dreg_get(int reg)
  90 {
  91         return (__hypercall1(__HYPERVISOR_get_debugreg, (long)reg));
  92 }
  93 
  94 void
  95 kdi_dreg_set(int reg, ulong_t value)
  96 {
  97         (void) __hypercall2(__HYPERVISOR_set_debugreg, (long)reg, value);
  98 }
  99 
 100 void
 101 kdi_flush_caches(void)
 102 {
 103 }
 104 
 105 /*
 106  * To avoid domains sucking up CPU while sitting in kmdb, we make all the slave
 107  * CPUs wait for a wake-up evtchn.  The master CPU, meanwhile, sleeps for
 108  * console activity.
 109  */
 110 
 111 extern void kdi_slave_entry(void);
 112 
 113 void
 114 kdi_stop_slaves(int cpu, int doxc)
 115 {
 116         if (doxc)
 117                 kdi_xc_others(cpu, kdi_slave_entry);
 118         kdi_slaves_go = 0;
 119 }
 120 
 121 void
 122 kdi_start_slaves(void)
 123 {
 124         int c;
 125 
 126         kdi_slaves_go = 1;
 127 
 128         for (c = 0; c < NCPU; c++) {
 129                 if (cpu[c] == NULL || !(cpu[c]->cpu_flags & CPU_READY))
 130                         continue;
 131                 ec_try_ipi(XC_CPUPOKE_PIL, c);
 132         }
 133 }
 134 
 135 /*ARGSUSED*/
 136 static int
 137 check_slave(void *arg)
 138 {
 139         return (kdi_slaves_go == 1);
 140 }
 141 
 142 void
 143 kdi_slave_wait(void)
 144 {
 145         if (!(cpu[CPU->cpu_id]->cpu_flags & CPU_READY))
 146                 return;
 147 
 148         ec_wait_on_ipi(XC_CPUPOKE_PIL, check_slave, NULL);
 149 }
 150 
 151 /*
 152  * Caution.
 153  * These routines are called -extremely- early, during kmdb initialization.
 154  *
 155  * Many common kernel functions assume that %gs has been initialized,
 156  * and fail horribly if it hasn't.  At this point, the boot code has
 157  * reserved a descriptor for us (KMDBGS_SEL) in it's GDT; arrange for it
 158  * to point at a dummy cpu_t, temporarily at least.
 159  *
 160  * Note that kmdb entry relies on the fake cpu_t having zero cpu_idt/cpu_id.
 161  */
 162 
 163 #if defined(__amd64)
 164 
 165 void *
 166 boot_kdi_tmpinit(void)
 167 {
 168         cpu_t *cpu = kobj_zalloc(sizeof (*cpu), KM_TMP);
 169         user_desc_t *bgdt;
 170         uint64_t gdtpa;
 171         ulong_t ma[1];
 172 
 173         cpu->cpu_self = cpu;
 174 
 175         /*
 176          * (Note that we had better switch to a -new- GDT before
 177          * we discard the KM_TMP mappings, or disaster will ensue.)
 178          */
 179         bgdt = kobj_zalloc(PAGESIZE, KM_TMP);
 180         ASSERT(((uintptr_t)bgdt & PAGEOFFSET) == 0);
 181 
 182         init_boot_gdt(bgdt);
 183 
 184         gdtpa = pfn_to_pa(va_to_pfn(bgdt));
 185         ma[0] = (ulong_t)(pa_to_ma(gdtpa) >> PAGESHIFT);
 186         kbm_read_only((uintptr_t)bgdt, gdtpa);
 187         if (HYPERVISOR_set_gdt(ma, PAGESIZE / sizeof (user_desc_t)))
 188                 panic("boot_kdi_tmpinit:HYPERVISOR_set_gdt() failed");
 189 
 190         load_segment_registers(B64CODE_SEL, 0, 0, B32DATA_SEL);
 191 
 192         /*
 193          * Now point %gsbase to our temp cpu structure.
 194          */
 195         xen_set_segment_base(SEGBASE_GS_KERNEL, (ulong_t)cpu);
 196         return (0);
 197 }
 198 
 199 /*ARGSUSED*/
 200 void
 201 boot_kdi_tmpfini(void *old)
 202 {
 203         /*
 204          * This breaks, why do we need it anyway?
 205          */
 206 #if 0   /* XXPV */
 207         load_segment_registers(B64CODE_SEL, 0, KMDBGS_SEL, B32DATA_SEL);
 208 #endif
 209 }
 210 
 211 #elif defined(__i386)
 212 
 213 /*
 214  * Sigh.  We're called before we've initialized the kernels GDT, living
 215  * off the hypervisor's default GDT.  For kmdb's sake, we switch now to
 216  * a GDT that looks like dboot's GDT; very shortly we'll initialize and
 217  * switch to the kernel's GDT.
 218  */
 219 
 220 void *
 221 boot_kdi_tmpinit(void)
 222 {
 223         cpu_t *cpu = kobj_zalloc(sizeof (*cpu), KM_TMP);
 224         user_desc_t *bgdt;
 225         uint64_t gdtpa;
 226         ulong_t ma[1];
 227 
 228         cpu->cpu_self = cpu;
 229 
 230         /*
 231          * (Note that we had better switch to a -new- GDT before
 232          * we discard the KM_TMP mappings, or disaster will ensue.)
 233          */
 234         bgdt = kobj_zalloc(PAGESIZE, KM_TMP);
 235 
 236         ASSERT(((uintptr_t)bgdt & PAGEOFFSET) == 0);
 237         gdtpa = pfn_to_pa(va_to_pfn(bgdt));
 238 
 239         init_boot_gdt(bgdt);
 240 
 241         set_usegd(&bgdt[GDT_BGSTMP],
 242             cpu, sizeof (*cpu), SDT_MEMRWA, SEL_KPL, SDP_BYTES, SDP_OP32);
 243 
 244         ma[0] = (ulong_t)(pa_to_ma(gdtpa) >> PAGESHIFT);
 245         kbm_read_only((uintptr_t)bgdt, gdtpa);
 246         if (HYPERVISOR_set_gdt(ma, PAGESIZE / sizeof (user_desc_t)))
 247                 panic("boot_kdi_tmpinit:HYPERVISOR_set_gdt() failed");
 248 
 249         load_segment_registers(B32CODE_SEL, B32DATA_SEL, B32DATA_SEL, 0,
 250             KMDBGS_SEL, B32DATA_SEL);
 251         return (0);
 252 }
 253 
 254 /*ARGSUSED*/
 255 void
 256 boot_kdi_tmpfini(void *old)
 257 {
 258         load_segment_registers(B32CODE_SEL, B32DATA_SEL, B32DATA_SEL, 0,
 259             0, B32DATA_SEL);
 260 }
 261 
 262 #endif  /* __i386 */