17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5100b72f4Sandrei * Common Development and Distribution License (the "License"). 6100b72f4Sandrei * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 21d6694327SYuri Pankov 227c478bd9Sstevel@tonic-gate /* 230db3240dSStephen Hanson * Copyright (c) 1993, 2010, Oracle and/or its affiliates. All rights reserved. 249e3e4df2SGarrett D'Amore * Copyright 2012 DEY Storage Systems, Inc. All rights reserved. 25d6694327SYuri Pankov * Copyright 2017 Nexenta Systems, Inc. 26575694f6SJason King * Copyright 2020 Joyent, Inc. 27af868f46SMatthew Ahrens * Copyright (c) 2015 by Delphix. All rights reserved. 28fdcca78fSJoshua M. Clulow * Copyright 2020 Oxide Computer Company 29860b5cc8Scneira * Copyright (c) 2020 Carlos Neira <cneirabustos@gmail.com> 307c478bd9Sstevel@tonic-gate */ 31a3114836SGerry Liu /* 32a3114836SGerry Liu * Copyright (c) 2010, Intel Corporation. 33a3114836SGerry Liu * All rights reserved. 34a3114836SGerry Liu */ 357c478bd9Sstevel@tonic-gate 367c478bd9Sstevel@tonic-gate #include <sys/types.h> 377c478bd9Sstevel@tonic-gate #include <sys/t_lock.h> 387c478bd9Sstevel@tonic-gate #include <sys/param.h> 397c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h> 407c478bd9Sstevel@tonic-gate #include <sys/signal.h> 417c478bd9Sstevel@tonic-gate #include <sys/systm.h> 427c478bd9Sstevel@tonic-gate #include <sys/user.h> 437c478bd9Sstevel@tonic-gate #include <sys/mman.h> 447c478bd9Sstevel@tonic-gate #include <sys/vm.h> 457c478bd9Sstevel@tonic-gate #include <sys/conf.h> 467c478bd9Sstevel@tonic-gate #include <sys/avintr.h> 477c478bd9Sstevel@tonic-gate #include <sys/autoconf.h> 487c478bd9Sstevel@tonic-gate #include <sys/disp.h> 497c478bd9Sstevel@tonic-gate #include <sys/class.h> 507c478bd9Sstevel@tonic-gate #include <sys/bitmap.h> 517c478bd9Sstevel@tonic-gate 527c478bd9Sstevel@tonic-gate #include <sys/privregs.h> 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate #include <sys/proc.h> 557c478bd9Sstevel@tonic-gate #include <sys/buf.h> 567c478bd9Sstevel@tonic-gate #include <sys/kmem.h> 57ae115bc7Smrj #include <sys/mem.h> 587c478bd9Sstevel@tonic-gate #include <sys/kstat.h> 597c478bd9Sstevel@tonic-gate 607c478bd9Sstevel@tonic-gate #include <sys/reboot.h> 617c478bd9Sstevel@tonic-gate 627c478bd9Sstevel@tonic-gate #include <sys/cred.h> 637c478bd9Sstevel@tonic-gate #include <sys/vnode.h> 647c478bd9Sstevel@tonic-gate #include <sys/file.h> 657c478bd9Sstevel@tonic-gate 667c478bd9Sstevel@tonic-gate #include <sys/procfs.h> 677c478bd9Sstevel@tonic-gate 687c478bd9Sstevel@tonic-gate #include <sys/vfs.h> 697c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h> 707c478bd9Sstevel@tonic-gate #include <sys/utsname.h> 717c478bd9Sstevel@tonic-gate #include <sys/debug.h> 727c478bd9Sstevel@tonic-gate #include <sys/kdi.h> 737c478bd9Sstevel@tonic-gate 747c478bd9Sstevel@tonic-gate #include <sys/dumphdr.h> 757c478bd9Sstevel@tonic-gate #include <sys/bootconf.h> 76a3114836SGerry Liu #include <sys/memlist_plat.h> 777c478bd9Sstevel@tonic-gate #include <sys/varargs.h> 787c478bd9Sstevel@tonic-gate #include <sys/promif.h> 79fdcca78fSJoshua M. Clulow #include <sys/prom_debug.h> 80843e1988Sjohnlev #include <sys/modctl.h> 817c478bd9Sstevel@tonic-gate 827c478bd9Sstevel@tonic-gate #include <sys/sunddi.h> 837c478bd9Sstevel@tonic-gate #include <sys/sunndi.h> 847c478bd9Sstevel@tonic-gate #include <sys/ndi_impldefs.h> 857c478bd9Sstevel@tonic-gate #include <sys/ddidmareq.h> 867c478bd9Sstevel@tonic-gate #include <sys/psw.h> 877c478bd9Sstevel@tonic-gate #include <sys/regset.h> 887c478bd9Sstevel@tonic-gate #include <sys/clock.h> 897c478bd9Sstevel@tonic-gate #include <sys/pte.h> 907c478bd9Sstevel@tonic-gate #include <sys/tss.h> 917c478bd9Sstevel@tonic-gate #include <sys/stack.h> 927c478bd9Sstevel@tonic-gate #include <sys/trap.h> 937c478bd9Sstevel@tonic-gate #include <sys/fp.h> 941d03c31eSjohnlev #include <vm/kboot_mmu.h> 957c478bd9Sstevel@tonic-gate #include <vm/anon.h> 967c478bd9Sstevel@tonic-gate #include <vm/as.h> 977c478bd9Sstevel@tonic-gate #include <vm/page.h> 987c478bd9Sstevel@tonic-gate #include <vm/seg.h> 997c478bd9Sstevel@tonic-gate #include <vm/seg_dev.h> 1007c478bd9Sstevel@tonic-gate #include <vm/seg_kmem.h> 1017c478bd9Sstevel@tonic-gate #include <vm/seg_kpm.h> 1027c478bd9Sstevel@tonic-gate #include <vm/seg_map.h> 1037c478bd9Sstevel@tonic-gate #include <vm/seg_vn.h> 1047c478bd9Sstevel@tonic-gate #include <vm/seg_kp.h> 1057c478bd9Sstevel@tonic-gate #include <sys/memnode.h> 1067c478bd9Sstevel@tonic-gate #include <vm/vm_dep.h> 1077c478bd9Sstevel@tonic-gate #include <sys/thread.h> 1087c478bd9Sstevel@tonic-gate #include <sys/sysconf.h> 1097c478bd9Sstevel@tonic-gate #include <sys/vm_machparam.h> 1107c478bd9Sstevel@tonic-gate #include <sys/archsystm.h> 1117c478bd9Sstevel@tonic-gate #include <sys/machsystm.h> 1127c478bd9Sstevel@tonic-gate #include <vm/hat.h> 1137c478bd9Sstevel@tonic-gate #include <vm/hat_i86.h> 1147c478bd9Sstevel@tonic-gate #include <sys/pmem.h> 1157c478bd9Sstevel@tonic-gate #include <sys/smp_impldefs.h> 1167c478bd9Sstevel@tonic-gate #include <sys/x86_archext.h> 117a563a037Sbholler #include <sys/cpuvar.h> 1187c478bd9Sstevel@tonic-gate #include <sys/segments.h> 1197c478bd9Sstevel@tonic-gate #include <sys/clconf.h> 1207c478bd9Sstevel@tonic-gate #include <sys/kobj.h> 1217c478bd9Sstevel@tonic-gate #include <sys/kobj_lex.h> 1227c478bd9Sstevel@tonic-gate #include <sys/cpc_impl.h> 1237aec1d6eScindi #include <sys/cpu_module.h> 12484ab085aSmws #include <sys/smbios.h> 125ae115bc7Smrj #include <sys/debug_info.h> 1261d03c31eSjohnlev #include <sys/bootinfo.h> 127a288e5a9SJoshua M. Clulow #include <sys/ddi_periodic.h> 1285679c89fSjv #include <sys/systeminfo.h> 12919397407SSherry Moore #include <sys/multiboot.h> 1300181461bSKeith M Wesolowski #include <sys/ramdisk.h> 131575694f6SJason King #include <sys/tsc.h> 132575694f6SJason King #include <sys/clock.h> 133ae115bc7Smrj 134a3114836SGerry Liu #ifdef __xpv 1351d03c31eSjohnlev 136843e1988Sjohnlev #include <sys/hypervisor.h> 137843e1988Sjohnlev #include <sys/xen_mmu.h> 138843e1988Sjohnlev #include <sys/evtchn_impl.h> 139843e1988Sjohnlev #include <sys/gnttab.h> 140843e1988Sjohnlev #include <sys/xpv_panic.h> 141843e1988Sjohnlev #include <xen/sys/xenbus_comms.h> 142843e1988Sjohnlev #include <xen/public/physdev.h> 1431d03c31eSjohnlev 144843e1988Sjohnlev extern void xen_late_startup(void); 145ae115bc7Smrj 1461d03c31eSjohnlev struct xen_evt_data cpu0_evt_data; 1471d03c31eSjohnlev 148a3114836SGerry Liu #else /* __xpv */ 149a3114836SGerry Liu #include <sys/memlist_impl.h> 150a3114836SGerry Liu 151a3114836SGerry Liu extern void mem_config_init(void); 1521d03c31eSjohnlev #endif /* __xpv */ 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate extern void progressbar_init(void); 1559acbbeafSnn extern void brand_init(void); 15606fb6a36Sdv extern void pcf_init(void); 1570e751525SEric Saxe extern void pg_init(void); 1586a59053bSAlex Wilson extern void ssp_init(void); 1597c478bd9Sstevel@tonic-gate 160d7d93655Sblakej extern int size_pse_array(pgcnt_t, int); 161d7d93655Sblakej 162ed5289f9SKen Erickson #if defined(_SOFT_HOSTID) 163ed5289f9SKen Erickson 164ed5289f9SKen Erickson static int32_t set_soft_hostid(void); 165ed5289f9SKen Erickson static char hostid_file[] = "/etc/hostid"; 166ed5289f9SKen Erickson 167ed5289f9SKen Erickson #endif 168ed5289f9SKen Erickson 16994f1124eSVikram Hegde void *gfx_devinfo_list; 170ed5289f9SKen Erickson 17186ef0a63SRichard Lowe #if !defined(__xpv) 1723a634bfcSVikram Hegde extern void immu_startup(void); 1733a634bfcSVikram Hegde #endif 1743a634bfcSVikram Hegde 1757c478bd9Sstevel@tonic-gate /* 1767c478bd9Sstevel@tonic-gate * XXX make declaration below "static" when drivers no longer use this 1777c478bd9Sstevel@tonic-gate * interface. 1787c478bd9Sstevel@tonic-gate */ 1797c478bd9Sstevel@tonic-gate extern caddr_t p0_va; /* Virtual address for accessing physical page 0 */ 1807c478bd9Sstevel@tonic-gate 1817c478bd9Sstevel@tonic-gate /* 1827c478bd9Sstevel@tonic-gate * segkp 1837c478bd9Sstevel@tonic-gate */ 1847c478bd9Sstevel@tonic-gate extern int segkp_fromheap; 1857c478bd9Sstevel@tonic-gate 1867c478bd9Sstevel@tonic-gate static void kvm_init(void); 1877c478bd9Sstevel@tonic-gate static void startup_init(void); 1887c478bd9Sstevel@tonic-gate static void startup_memlist(void); 189ae115bc7Smrj static void startup_kmem(void); 1907c478bd9Sstevel@tonic-gate static void startup_modules(void); 1917c478bd9Sstevel@tonic-gate static void startup_vm(void); 192575694f6SJason King #ifndef __xpv 193575694f6SJason King static void startup_tsc(void); 194575694f6SJason King #endif 1957c478bd9Sstevel@tonic-gate static void startup_end(void); 19635b1ab99Sjosephb static void layout_kernel_va(void); 1977c478bd9Sstevel@tonic-gate 1987c478bd9Sstevel@tonic-gate /* 1997c478bd9Sstevel@tonic-gate * Declare these as initialized data so we can patch them. 2007c478bd9Sstevel@tonic-gate */ 20135b1ab99Sjosephb 20235b1ab99Sjosephb /* 20335b1ab99Sjosephb * For now we can handle memory with physical addresses up to about 20435b1ab99Sjosephb * 64 Terabytes. This keeps the kernel above the VA hole, leaving roughly 20535b1ab99Sjosephb * half the VA space for seg_kpm. When systems get bigger than 64TB this 20635b1ab99Sjosephb * code will need revisiting. There is an implicit assumption that there 20735b1ab99Sjosephb * are no *huge* holes in the physical address space too. 20835b1ab99Sjosephb */ 20935b1ab99Sjosephb #define TERABYTE (1ul << 40) 21035b1ab99Sjosephb #define PHYSMEM_MAX64 mmu_btop(64 * TERABYTE) 21135b1ab99Sjosephb #define PHYSMEM PHYSMEM_MAX64 21235b1ab99Sjosephb #define AMD64_VA_HOLE_END 0xFFFF800000000000ul 21335b1ab99Sjosephb 21435b1ab99Sjosephb 21535b1ab99Sjosephb pgcnt_t physmem = PHYSMEM; 2167c478bd9Sstevel@tonic-gate pgcnt_t obp_pages; /* Memory used by PROM for its text and data */ 2177c478bd9Sstevel@tonic-gate 2180b35c8bcSToomas Soome extern char *kobj_file_buf; 2190b35c8bcSToomas Soome extern int kobj_file_bufsize; /* set in /etc/system */ 2207c478bd9Sstevel@tonic-gate 2217c478bd9Sstevel@tonic-gate /* Global variables for MP support. Used in mp_startup */ 22219397407SSherry Moore caddr_t rm_platter_va = 0; 2237c478bd9Sstevel@tonic-gate uint32_t rm_platter_pa; 2247c478bd9Sstevel@tonic-gate 22583f9b804Skchow int auto_lpg_disable = 1; 22683f9b804Skchow 2277c478bd9Sstevel@tonic-gate /* 2287c478bd9Sstevel@tonic-gate * Some CPUs have holes in the middle of the 64-bit virtual address range. 2297c478bd9Sstevel@tonic-gate */ 2307c478bd9Sstevel@tonic-gate uintptr_t hole_start, hole_end; 2317c478bd9Sstevel@tonic-gate 2327c478bd9Sstevel@tonic-gate /* 2337c478bd9Sstevel@tonic-gate * kpm mapping window 2347c478bd9Sstevel@tonic-gate */ 2357c478bd9Sstevel@tonic-gate caddr_t kpm_vbase; 2367c478bd9Sstevel@tonic-gate size_t kpm_size; 23735b1ab99Sjosephb static int kpm_desired; 23835b1ab99Sjosephb static uintptr_t segkpm_base = (uintptr_t)SEGKPM_BASE; 2397c478bd9Sstevel@tonic-gate 2407c478bd9Sstevel@tonic-gate /* 2417c478bd9Sstevel@tonic-gate * Configuration parameters set at boot time. 2427c478bd9Sstevel@tonic-gate */ 2437c478bd9Sstevel@tonic-gate 2447c478bd9Sstevel@tonic-gate caddr_t econtig; /* end of first block of contiguous kernel */ 2457c478bd9Sstevel@tonic-gate 2467c478bd9Sstevel@tonic-gate struct bootops *bootops = 0; /* passed in from boot */ 2477c478bd9Sstevel@tonic-gate struct bootops **bootopsp; 2487c478bd9Sstevel@tonic-gate struct boot_syscalls *sysp; /* passed in from boot */ 2497c478bd9Sstevel@tonic-gate 2507c478bd9Sstevel@tonic-gate char bootblock_fstype[16]; 2517c478bd9Sstevel@tonic-gate 2527c478bd9Sstevel@tonic-gate char kern_bootargs[OBP_MAXPATHLEN]; 25319397407SSherry Moore char kern_bootfile[OBP_MAXPATHLEN]; 2547c478bd9Sstevel@tonic-gate 255ad23a2dbSjohansen /* 256ad23a2dbSjohansen * ZFS zio segment. This allows us to exclude large portions of ZFS data that 257ad23a2dbSjohansen * gets cached in kmem caches on the heap. If this is set to zero, we allocate 258ad23a2dbSjohansen * zio buffers from their own segment, otherwise they are allocated from the 259ad23a2dbSjohansen * heap. The optimization of allocating zio buffers from their own segment is 260ad23a2dbSjohansen * only valid on 64-bit kernels. 261ad23a2dbSjohansen */ 262ad23a2dbSjohansen int segzio_fromheap = 0; 263ad23a2dbSjohansen 2643ce2fcdcSRobert Mustacchi /* 2653ce2fcdcSRobert Mustacchi * Give folks an escape hatch for disabling SMAP via kmdb. Doesn't work 2663ce2fcdcSRobert Mustacchi * post-boot. 2673ce2fcdcSRobert Mustacchi */ 2683ce2fcdcSRobert Mustacchi int disable_smap = 0; 2693ce2fcdcSRobert Mustacchi 2707c478bd9Sstevel@tonic-gate /* 2717c478bd9Sstevel@tonic-gate * new memory fragmentations are possible in startup() due to BOP_ALLOCs. this 2727c478bd9Sstevel@tonic-gate * depends on number of BOP_ALLOC calls made and requested size, memory size 2737c478bd9Sstevel@tonic-gate * combination and whether boot.bin memory needs to be freed. 2747c478bd9Sstevel@tonic-gate */ 2757c478bd9Sstevel@tonic-gate #define POSS_NEW_FRAGMENTS 12 2767c478bd9Sstevel@tonic-gate 2777c478bd9Sstevel@tonic-gate /* 2787c478bd9Sstevel@tonic-gate * VM data structures 2797c478bd9Sstevel@tonic-gate */ 2807c478bd9Sstevel@tonic-gate long page_hashsz; /* Size of page hash table (power of two) */ 281cb15d5d9SPeter Rival unsigned int page_hashsz_shift; /* log2(page_hashsz) */ 2827c478bd9Sstevel@tonic-gate struct page *pp_base; /* Base of initial system page struct array */ 2837c478bd9Sstevel@tonic-gate struct page **page_hash; /* Page hash table */ 284d7d93655Sblakej pad_mutex_t *pse_mutex; /* Locks protecting pp->p_selock */ 285d7d93655Sblakej size_t pse_table_size; /* Number of mutexes in pse_mutex[] */ 286d7d93655Sblakej int pse_shift; /* log2(pse_table_size) */ 2877c478bd9Sstevel@tonic-gate struct seg ktextseg; /* Segment used for kernel executable image */ 2887c478bd9Sstevel@tonic-gate struct seg kvalloc; /* Segment used for "valloc" mapping */ 2897c478bd9Sstevel@tonic-gate struct seg kpseg; /* Segment used for pageable kernel virt mem */ 2907c478bd9Sstevel@tonic-gate struct seg kmapseg; /* Segment used for generic kernel mappings */ 2917c478bd9Sstevel@tonic-gate struct seg kdebugseg; /* Segment used for the kernel debugger */ 2927c478bd9Sstevel@tonic-gate 2937c478bd9Sstevel@tonic-gate struct seg *segkmap = &kmapseg; /* Kernel generic mapping segment */ 294ae115bc7Smrj static struct seg *segmap = &kmapseg; /* easier to use name for in here */ 295ae115bc7Smrj 2967c478bd9Sstevel@tonic-gate struct seg *segkp = &kpseg; /* Pageable kernel virtual memory segment */ 2977c478bd9Sstevel@tonic-gate 2980b35c8bcSToomas Soome extern struct seg kvseg_core; /* Segment used for the core heap */ 2997c478bd9Sstevel@tonic-gate struct seg kpmseg; /* Segment used for physical mapping */ 3007c478bd9Sstevel@tonic-gate struct seg *segkpm = &kpmseg; /* 64bit kernel physical mapping segment */ 3017c478bd9Sstevel@tonic-gate 3027c478bd9Sstevel@tonic-gate caddr_t segkp_base; /* Base address of segkp */ 303ad23a2dbSjohansen caddr_t segzio_base; /* Base address of segzio */ 304860b5cc8Scneira pgcnt_t segkpsize; /* size of segkp segment in pages */ 30504909c8cSJohn Levon caddr_t segkvmm_base; 30604909c8cSJohn Levon pgcnt_t segkvmmsize; 30704909c8cSJohn Levon pgcnt_t segziosize; 3087c478bd9Sstevel@tonic-gate 309a3114836SGerry Liu /* 310a3114836SGerry Liu * A static DR page_t VA map is reserved that can map the page structures 311a3114836SGerry Liu * for a domain's entire RA space. The pages that back this space are 312a3114836SGerry Liu * dynamically allocated and need not be physically contiguous. The DR 313a3114836SGerry Liu * map size is derived from KPM size. 314a3114836SGerry Liu * This mechanism isn't used by x86 yet, so just stubs here. 315a3114836SGerry Liu */ 316a3114836SGerry Liu int ppvm_enable = 0; /* Static virtual map for page structs */ 317a3114836SGerry Liu page_t *ppvm_base = NULL; /* Base of page struct map */ 318a3114836SGerry Liu pgcnt_t ppvm_size = 0; /* Size of page struct map */ 319a3114836SGerry Liu 320ae115bc7Smrj /* 321ae115bc7Smrj * VA range available to the debugger 322ae115bc7Smrj */ 323