xref: /illumos-gate/usr/src/uts/i86pc/os/startup.c (revision f0089e39)
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