usr/src/uts/i86pc/os/startup.c
author mws
Sat, 27 Aug 2005 15:17:06 -0700
changeset 437 76c202dd62bf
parent 423 6cbc492798ce
child 770 0eda482eb80f
permissions -rw-r--r--
PSARC 2005/483 SMBIOS Support for Solaris 6313638 SMBIOS Support for Solaris 6230033 prtdiag should be implemented for Solaris x86 6313668 bmc driver should not have its own private smbios reader 6313670 post_startup_mmu_initialization() is useless and can be deleted
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     1
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     2
 * CDDL HEADER START
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     3
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     5
 * Common Development and Distribution License, Version 1.0 only
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     6
 * (the "License").  You may not use this file except in compliance
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     7
 * with the License.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     8
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     9
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    10
 * or http://www.opensolaris.org/os/licensing.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    11
 * See the License for the specific language governing permissions
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    12
 * and limitations under the License.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    13
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    14
 * When distributing Covered Code, include this CDDL HEADER in each
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    15
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    16
 * If applicable, add the following below this CDDL HEADER, with the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    17
 * fields enclosed by brackets "[]" replaced with your own identifying
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    18
 * information: Portions Copyright [yyyy] [name of copyright owner]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    19
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    20
 * CDDL HEADER END
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    21
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    22
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    23
 * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    24
 * Use is subject to license terms.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    25
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    26
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    27
#pragma ident	"%Z%%M%	%I%	%E% SMI"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    28
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    29
#include <sys/types.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    30
#include <sys/t_lock.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    31
#include <sys/param.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    32
#include <sys/sysmacros.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    33
#include <sys/signal.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    34
#include <sys/systm.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    35
#include <sys/user.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    36
#include <sys/mman.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    37
#include <sys/vm.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    38
#include <sys/conf.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    39
#include <sys/avintr.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    40
#include <sys/autoconf.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    41
#include <sys/disp.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    42
#include <sys/class.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    43
#include <sys/bitmap.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    44
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    45
#include <sys/privregs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    46
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    47
#include <sys/proc.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    48
#include <sys/buf.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    49
#include <sys/kmem.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    50
#include <sys/kstat.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    51
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    52
#include <sys/reboot.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    53
#include <sys/uadmin.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    54
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    55
#include <sys/cred.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    56
#include <sys/vnode.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    57
#include <sys/file.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    58
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    59
#include <sys/procfs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    60
#include <sys/acct.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    61
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    62
#include <sys/vfs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    63
#include <sys/dnlc.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    64
#include <sys/var.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    65
#include <sys/cmn_err.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    66
#include <sys/utsname.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    67
#include <sys/debug.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    68
#include <sys/kdi.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    69
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    70
#include <sys/dumphdr.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    71
#include <sys/bootconf.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    72
#include <sys/varargs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    73
#include <sys/promif.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    74
#include <sys/prom_emul.h>	/* for create_prom_prop */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    75
#include <sys/modctl.h>		/* for "procfs" hack */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    76
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    77
#include <sys/consdev.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    78
#include <sys/frame.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    79
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    80
#include <sys/sunddi.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    81
#include <sys/sunndi.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    82
#include <sys/ndi_impldefs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    83
#include <sys/ddidmareq.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    84
#include <sys/psw.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    85
#include <sys/regset.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    86
#include <sys/clock.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    87
#include <sys/pte.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    88
#include <sys/mmu.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    89
#include <sys/tss.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    90
#include <sys/stack.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    91
#include <sys/trap.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    92
#include <sys/pic.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    93
#include <sys/fp.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    94
#include <vm/anon.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    95
#include <vm/as.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    96
#include <vm/page.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    97
#include <vm/seg.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    98
#include <vm/seg_dev.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    99
#include <vm/seg_kmem.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   100
#include <vm/seg_kpm.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   101
#include <vm/seg_map.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   102
#include <vm/seg_vn.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   103
#include <vm/seg_kp.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   104
#include <sys/memnode.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   105
#include <vm/vm_dep.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   106
#include <sys/swap.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   107
#include <sys/thread.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   108
#include <sys/sysconf.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   109
#include <sys/vm_machparam.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   110
#include <sys/archsystm.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   111
#include <sys/machsystm.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   112
#include <vm/hat.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   113
#include <vm/hat_i86.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   114
#include <sys/pmem.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   115
#include <sys/instance.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   116
#include <sys/smp_impldefs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   117
#include <sys/x86_archext.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   118
#include <sys/segments.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   119
#include <sys/clconf.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   120
#include <sys/kobj.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   121
#include <sys/kobj_lex.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   122
#include <sys/prom_emul.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   123
#include <sys/cpc_impl.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   124
#include <sys/chip.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   125
#include <sys/x86_archext.h>
437
76c202dd62bf PSARC 2005/483 SMBIOS Support for Solaris
mws
parents: 423
diff changeset
   126
#include <sys/smbios.h>
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   127
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   128
extern void progressbar_init(void);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   129
extern void progressbar_start(void);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   130
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   131
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   132
 * XXX make declaration below "static" when drivers no longer use this
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   133
 * interface.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   134
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   135
extern caddr_t p0_va;	/* Virtual address for accessing physical page 0 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   136
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   137
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   138
 * segkp
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   139
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   140
extern int segkp_fromheap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   141
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   142
static void kvm_init(void);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   143
static void startup_init(void);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   144
static void startup_memlist(void);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   145
static void startup_modules(void);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   146
static void startup_bop_gone(void);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   147
static void startup_vm(void);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   148
static void startup_end(void);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   149
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   150
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   151
 * Declare these as initialized data so we can patch them.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   152
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   153
pgcnt_t physmem = 0;	/* memory size in pages, patch if you want less */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   154
pgcnt_t obp_pages;	/* Memory used by PROM for its text and data */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   155
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   156
char *kobj_file_buf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   157
int kobj_file_bufsize;	/* set in /etc/system */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   158
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   159
/* Global variables for MP support. Used in mp_startup */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   160
caddr_t	rm_platter_va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   161
uint32_t rm_platter_pa;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   162
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   163
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   164
 * Some CPUs have holes in the middle of the 64-bit virtual address range.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   165
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   166
uintptr_t hole_start, hole_end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   167
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   168
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   169
 * kpm mapping window
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   170
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   171
caddr_t kpm_vbase;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   172
size_t  kpm_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   173
static int kpm_desired = 0;		/* Do we want to try to use segkpm? */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   174
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   175
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   176
 * VA range that must be preserved for boot until we release all of its
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   177
 * mappings.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   178
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   179
#if defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   180
static void *kmem_setaside;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   181
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   182
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   183
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   184
 * Configuration parameters set at boot time.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   185
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   186
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   187
caddr_t econtig;		/* end of first block of contiguous kernel */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   188
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   189
struct bootops		*bootops = 0;	/* passed in from boot */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   190
struct bootops		**bootopsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   191
struct boot_syscalls	*sysp;		/* passed in from boot */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   192
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   193
char bootblock_fstype[16];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   194
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   195
char kern_bootargs[OBP_MAXPATHLEN];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   196
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   197
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   198
 * new memory fragmentations are possible in startup() due to BOP_ALLOCs. this
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   199
 * depends on number of BOP_ALLOC calls made and requested size, memory size
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   200
 * combination and whether boot.bin memory needs to be freed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   201
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   202
#define	POSS_NEW_FRAGMENTS	12
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   203
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   204
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   205
 * VM data structures
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   206
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   207
long page_hashsz;		/* Size of page hash table (power of two) */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   208
struct page *pp_base;		/* Base of initial system page struct array */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   209
struct page **page_hash;	/* Page hash table */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   210
struct seg ktextseg;		/* Segment used for kernel executable image */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   211
struct seg kvalloc;		/* Segment used for "valloc" mapping */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   212
struct seg kpseg;		/* Segment used for pageable kernel virt mem */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   213
struct seg kmapseg;		/* Segment used for generic kernel mappings */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   214
struct seg kdebugseg;		/* Segment used for the kernel debugger */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   215
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   216
struct seg *segkmap = &kmapseg;	/* Kernel generic mapping segment */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   217
struct seg *segkp = &kpseg;	/* Pageable kernel virtual memory segment */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   218
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   219
#if defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   220
struct seg kvseg_core;		/* Segment used for the core heap */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   221
struct seg kpmseg;		/* Segment used for physical mapping */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   222
struct seg *segkpm = &kpmseg;	/* 64bit kernel physical mapping segment */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   223
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   224
struct seg *segkpm = NULL;	/* Unused on IA32 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   225
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   226
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   227
caddr_t segkp_base;		/* Base address of segkp */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   228
#if defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   229
pgcnt_t segkpsize = btop(SEGKPDEFSIZE);	/* size of segkp segment in pages */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   230
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   231
pgcnt_t segkpsize = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   232
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   233
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   234
struct memseg *memseg_base;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   235
struct vnode unused_pages_vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   236
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   237
#define	FOURGB	0x100000000LL
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   238
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   239
struct memlist *memlist;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   240
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   241
caddr_t s_text;		/* start of kernel text segment */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   242
caddr_t e_text;		/* end of kernel text segment */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   243
caddr_t s_data;		/* start of kernel data segment */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   244
caddr_t e_data;		/* end of kernel data segment */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   245
caddr_t modtext;	/* start of loadable module text reserved */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   246
caddr_t e_modtext;	/* end of loadable module text reserved */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   247
caddr_t moddata;	/* start of loadable module data reserved */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   248
caddr_t e_moddata;	/* end of loadable module data reserved */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   249
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   250
struct memlist *phys_install;	/* Total installed physical memory */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   251
struct memlist *phys_avail;	/* Total available physical memory */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   252
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   253
static void memlist_add(uint64_t, uint64_t, struct memlist *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   254
	struct memlist **);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   255
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   256
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   257
 * kphysm_init returns the number of pages that were processed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   258
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   259
static pgcnt_t kphysm_init(page_t *, struct memseg *, pgcnt_t, pgcnt_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   260
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   261
#define	IO_PROP_SIZE	64	/* device property size */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   262
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   263
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   264
 * a couple useful roundup macros
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   265
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   266
#define	ROUND_UP_PAGE(x)	\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   267
	((uintptr_t)P2ROUNDUP((uintptr_t)(x), (uintptr_t)MMU_PAGESIZE))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   268
#define	ROUND_UP_LPAGE(x)	\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   269
	((uintptr_t)P2ROUNDUP((uintptr_t)(x), mmu.level_size[1]))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   270
#define	ROUND_UP_4MEG(x)	\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   271
	((uintptr_t)P2ROUNDUP((uintptr_t)(x), (uintptr_t)FOURMB_PAGESIZE))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   272
#define	ROUND_UP_TOPLEVEL(x)	\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   273
	((uintptr_t)P2ROUNDUP((uintptr_t)(x), mmu.level_size[mmu.max_level]))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   274
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   275
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   276
 *	32-bit Kernel's Virtual memory layout.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   277
 *		+-----------------------+
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   278
 *		|	psm 1-1 map	|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   279
 *		|	exec args area	|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   280
 * 0xFFC00000  -|-----------------------|- ARGSBASE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   281
 *		|	debugger	|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   282
 * 0xFF800000  -|-----------------------|- SEGDEBUGBASE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   283
 *		|      Kernel Data	|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   284
 * 0xFEC00000  -|-----------------------|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   285
 *              |      Kernel Text	|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   286
 * 0xFE800000  -|-----------------------|- KERNEL_TEXT
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   287
 * 		|     LUFS sinkhole	|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   288
 * 0xFE000000  -|-----------------------|- lufs_addr
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   289
 * ---         -|-----------------------|- valloc_base + valloc_sz
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   290
 * 		|   early pp structures	|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   291
 * 		|   memsegs, memlists, 	|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   292
 * 		|   page hash, etc.	|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   293
 * ---	       -|-----------------------|- valloc_base (floating)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   294
 * 		|     ptable_va    	|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   295
 * 0xFDFFE000  -|-----------------------|- ekernelheap, ptable_va
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   296
 *		|			|  (segkp is an arena under the heap)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   297
 *		|			|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   298
 *		|	kvseg		|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   299
 *		|			|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   300
 *		|			|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   301
 * ---         -|-----------------------|- kernelheap (floating)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   302
 * 		|        Segkmap	|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   303
 * 0xC3002000  -|-----------------------|- segkmap_start (floating)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   304
 *		|	Red Zone	|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   305
 * 0xC3000000  -|-----------------------|- kernelbase / userlimit (floating)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   306
 *		|			|			||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   307
 *		|     Shared objects	|			\/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   308
 *		|			|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   309
 *		:			:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   310
 *		|	user data	|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   311
 *		|-----------------------|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   312
 *		|	user text	|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   313
 * 0x08048000  -|-----------------------|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   314
 *		|	user stack	|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   315
 *		:			:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   316
 *		|	invalid		|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   317
 * 0x00000000	+-----------------------+
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   318
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   319
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   320
 *		64-bit Kernel's Virtual memory layout. (assuming 64 bit app)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   321
 *			+-----------------------+
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   322
 *			|	psm 1-1 map	|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   323
 *			|	exec args area	|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   324
 * 0xFFFFFFFF.FFC00000  |-----------------------|- ARGSBASE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   325
 *			|	debugger (?)	|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   326
 * 0xFFFFFFFF.FF800000  |-----------------------|- SEGDEBUGBASE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   327
 *			|      unused    	|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   328
 *			+-----------------------+
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   329
 *			|      Kernel Data	|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   330
 * 0xFFFFFFFF.FBC00000  |-----------------------|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   331
 *			|      Kernel Text	|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   332
 * 0xFFFFFFFF.FB800000  |-----------------------|- KERNEL_TEXT
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   333
 * 			|     LUFS sinkhole	|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   334
 * 0xFFFFFFFF.FB000000 -|-----------------------|- lufs_addr
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   335
 * ---                  |-----------------------|- valloc_base + valloc_sz
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   336
 * 			|   early pp structures	|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   337
 * 			|   memsegs, memlists, 	|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   338
 * 			|   page hash, etc.	|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   339
 * ---                  |-----------------------|- valloc_base
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   340
 * 			|     ptable_va    	|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   341
 * ---                  |-----------------------|- ptable_va
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   342
 * 			|      Core heap	| (used for loadable modules)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   343
 * 0xFFFFFFFF.C0000000  |-----------------------|- core_base / ekernelheap
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   344
 *			|	 Kernel		|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   345
 *			|	  heap		|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   346
 * 0xFFFFFXXX.XXX00000  |-----------------------|- kernelheap (floating)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   347
 *			|	 segkmap	|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   348
 * 0xFFFFFXXX.XXX00000  |-----------------------|- segkmap_start (floating)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   349
 *			|    device mappings	|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   350
 * 0xFFFFFXXX.XXX00000  |-----------------------|- toxic_addr (floating)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   351
 *			|	  segkp		|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   352
 * ---                  |-----------------------|- segkp_base
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   353
 *			|	 segkpm		|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   354
 * 0xFFFFFE00.00000000  |-----------------------|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   355
 *			|	Red Zone	|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   356
 * 0xFFFFFD80.00000000  |-----------------------|- KERNELBASE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   357
 *			|     User stack	|- User space memory
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   358
 * 			|			|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   359
 * 			| shared objects, etc	|	(grows downwards)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   360
 *			:			:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   361
 * 			|			|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   362
 * 0xFFFF8000.00000000  |-----------------------|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   363
 * 			|			|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   364
 * 			| VA Hole / unused	|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   365
 * 			|			|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   366
 * 0x00008000.00000000  |-----------------------|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   367
 *			|			|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   368
 *			|			|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   369
 *			:			:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   370
 *			|	user heap	|	(grows upwards)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   371
 *			|			|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   372
 *			|	user data	|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   373
 *			|-----------------------|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   374
 *			|	user text	|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   375
 * 0x00000000.04000000  |-----------------------|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   376
 *			|	invalid		|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   377
 * 0x00000000.00000000	+-----------------------+
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   378
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   379
 * A 32 bit app on the 64 bit kernel sees the same layout as on the 32 bit
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   380
 * kernel, except that userlimit is raised to 0xfe000000
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   381
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   382
 * Floating values:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   383
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   384
 * valloc_base: start of the kernel's memory management/tracking data
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   385
 * structures.  This region contains page_t structures for the lowest 4GB
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   386
 * of physical memory, memsegs, memlists, and the page hash.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   387
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   388
 * core_base: start of the kernel's "core" heap area on 64-bit systems.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   389
 * This area is intended to be used for global data as well as for module
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   390
 * text/data that does not fit into the nucleus pages.  The core heap is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   391
 * restricted to a 2GB range, allowing every address within it to be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   392
 * accessed using rip-relative addressing
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   393
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   394
 * ekernelheap: end of kernelheap and start of segmap.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   395
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   396
 * kernelheap: start of kernel heap.  On 32-bit systems, this starts right
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   397
 * above a red zone that separates the user's address space from the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   398
 * kernel's.  On 64-bit systems, it sits above segkp and segkpm.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   399
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   400
 * segkmap_start: start of segmap. The length of segmap can be modified
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   401
 * by changing segmapsize in /etc/system (preferred) or eeprom (deprecated).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   402
 * The default length is 16MB on 32-bit systems and 64MB on 64-bit systems.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   403
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   404
 * kernelbase: On a 32-bit kernel the default value of 0xd4000000 will be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   405
 * decreased by 2X the size required for page_t.  This allows the kernel
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   406
 * heap to grow in size with physical memory.  With sizeof(page_t) == 80
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   407
 * bytes, the following shows the values of kernelbase and kernel heap
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   408
 * sizes for different memory configurations (assuming default segmap and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   409
 * segkp sizes).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   410
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   411
 *	mem	size for	kernelbase	kernel heap
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   412
 *	size	page_t's			size
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   413
 *	----	---------	----------	-----------
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   414
 *	1gb	0x01400000	0xd1800000	684MB
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   415
 *	2gb	0x02800000	0xcf000000	704MB
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   416
 *	4gb	0x05000000	0xca000000	744MB
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   417
 *	6gb	0x07800000	0xc5000000	784MB
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   418
 *	8gb	0x0a000000	0xc0000000	824MB
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   419
 *	16gb	0x14000000	0xac000000	984MB
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   420
 *	32gb	0x28000000	0x84000000	1304MB
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   421
 *	64gb	0x50000000	0x34000000	1944MB (*)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   422
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   423
 * kernelbase is less than the abi minimum of 0xc0000000 for memory
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   424
 * configurations above 8gb.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   425
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   426
 * (*) support for memory configurations above 32gb will require manual tuning
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   427
 * of kernelbase to balance out the need of user applications.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   428
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   429
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   430
void init_intr_threads(struct cpu *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   431
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   432
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   433
 * Dummy spl priority masks
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   434
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   435
static unsigned char	dummy_cpu_pri[MAXIPL + 1] = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   436
	0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   437
	0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   438
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   439
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   440
/* real-time-clock initialization parameters */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   441
long gmt_lag;		/* offset in seconds of gmt to local time */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   442
extern long process_rtc_config_file(void);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   443
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   444
char		*final_kernelheap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   445
char		*boot_kernelheap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   446
uintptr_t	kernelbase;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   447
uintptr_t	eprom_kernelbase;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   448
size_t		segmapsize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   449
static uintptr_t segmap_reserved;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   450
uintptr_t	segkmap_start;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   451
int		segmapfreelists;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   452
pgcnt_t		boot_npages;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   453
pgcnt_t		npages;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   454
size_t		core_size;		/* size of "core" heap */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   455
uintptr_t	core_base;		/* base address of "core" heap */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   456
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   457
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   458
 * List of bootstrap pages. We mark these as allocated in startup.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   459
 * release_bootstrap() will free them when we're completely done with
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   460
 * the bootstrap.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   461
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   462
static page_t *bootpages, *rd_pages;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   463
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   464
struct system_hardware system_hardware;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   465
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   466
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   467
 * Enable some debugging messages concerning memory usage...
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   468
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   469
 * XX64 There should only be one print routine once memlist usage between
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   470
 * vmx and the kernel is cleaned up and there is a single memlist structure
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   471
 * shared between kernel and boot.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   472
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   473
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   474
print_boot_memlist(char *title, struct memlist *mp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   475
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   476
	prom_printf("MEMLIST: %s:\n", title);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   477
	while (mp != NULL)  {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   478
		prom_printf("\tAddress 0x%" PRIx64 ", size 0x%" PRIx64 "\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   479
		    mp->address, mp->size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   480
		mp = mp->next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   481
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   482
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   483
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   484
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   485
print_kernel_memlist(char *title, struct memlist *mp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   486
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   487
	prom_printf("MEMLIST: %s:\n", title);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   488
	while (mp != NULL)  {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   489
		prom_printf("\tAddress 0x%" PRIx64 ", size 0x%" PRIx64 "\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   490
		    mp->address, mp->size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   491
		mp = mp->next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   492
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   493
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   494
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   495
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   496
 * XX64 need a comment here.. are these just default values, surely
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   497
 * we read the "cpuid" type information to figure this out.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   498
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   499
int	l2cache_sz = 0x80000;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   500
int	l2cache_linesz = 0x40;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   501
int	l2cache_assoc = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   502
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   503
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   504
 * on 64 bit we use a predifined VA range for mapping devices in the kernel
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   505
 * on 32 bit the mappings are intermixed in the heap, so we use a bit map
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   506
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   507
#ifdef __amd64
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   508
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   509
vmem_t		*device_arena;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   510
uintptr_t	toxic_addr = (uintptr_t)NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   511
size_t		toxic_size = 1 * 1024 * 1024 * 1024; /* Sparc uses 1 gig too */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   512
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   513
#else	/* __i386 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   514
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   515
ulong_t		*toxic_bit_map;	/* one bit for each 4k of VA in heap_arena */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   516
size_t		toxic_bit_map_len = 0;	/* in bits */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   517
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   518
#endif	/* __i386 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   519
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   520
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   521
 * Simple boot time debug facilities
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   522
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   523
static char *prm_dbg_str[] = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   524
	"%s:%d: '%s' is 0x%x\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   525
	"%s:%d: '%s' is 0x%llx\n"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   526
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   527
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   528
int prom_debug;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   529
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   530
#define	PRM_DEBUG(q)	if (prom_debug) 	\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   531
	prom_printf(prm_dbg_str[sizeof (q) >> 3], "startup.c", __LINE__, #q, q);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   532
#define	PRM_POINT(q)	if (prom_debug) 	\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   533
	prom_printf("%s:%d: %s\n", "startup.c", __LINE__, q);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   534
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   535
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   536
 * This structure is used to keep track of the intial allocations
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   537
 * done in startup_memlist(). The value of NUM_ALLOCATIONS needs to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   538
 * be >= the number of ADD_TO_ALLOCATIONS() executed in the code.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   539
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   540
#define	NUM_ALLOCATIONS 7
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   541
int num_allocations = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   542
struct {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   543
	void **al_ptr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   544
	size_t al_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   545
} allocations[NUM_ALLOCATIONS];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   546
size_t valloc_sz = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   547
uintptr_t valloc_base;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   548
extern uintptr_t ptable_va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   549
extern size_t ptable_sz;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   550
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   551
#define	ADD_TO_ALLOCATIONS(ptr, size) {					\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   552
		size = ROUND_UP_PAGE(size);		 		\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   553
		if (num_allocations == NUM_ALLOCATIONS)			\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   554
			panic("too many ADD_TO_ALLOCATIONS()");		\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   555
		allocations[num_allocations].al_ptr = (void**)&ptr;	\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   556
		allocations[num_allocations].al_size = size;		\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   557
		valloc_sz += size;					\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   558
		++num_allocations;				 	\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   559
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   560
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   561
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   562
perform_allocations(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   563
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   564
	caddr_t mem;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   565
	int i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   566
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   567
	mem = BOP_ALLOC(bootops, (caddr_t)valloc_base, valloc_sz, BO_NO_ALIGN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   568
	if (mem != (caddr_t)valloc_base)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   569
		panic("BOP_ALLOC() failed");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   570
	bzero(mem, valloc_sz);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   571
	for (i = 0; i < num_allocations; ++i) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   572
		*allocations[i].al_ptr = (void *)mem;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   573
		mem += allocations[i].al_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   574
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   575
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   576
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   577
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   578
 * Our world looks like this at startup time.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   579
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   580
 * In a 32-bit OS, boot loads the kernel text at 0xfe800000 and kernel data
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   581
 * at 0xfec00000.  On a 64-bit OS, kernel text and data are loaded at
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   582
 * 0xffffffff.fe800000 and 0xffffffff.fec00000 respectively.  Those
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   583
 * addresses are fixed in the binary at link time.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   584
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   585
 * On the text page:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   586
 * unix/genunix/krtld/module text loads.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   587
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   588
 * On the data page:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   589
 * unix/genunix/krtld/module data loads and space for page_t's.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   590
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   591
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   592
 * Machine-dependent startup code
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   593
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   594
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   595
startup(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   596
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   597
	extern void startup_bios_disk();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   598
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   599
	 * Make sure that nobody tries to use sekpm until we have
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   600
	 * initialized it properly.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   601
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   602
#if defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   603
	kpm_desired = kpm_enable;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   604
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   605
	kpm_enable = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   606
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   607
	progressbar_init();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   608
	startup_init();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   609
	startup_memlist();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   610
	startup_modules();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   611
	startup_bios_disk();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   612
	startup_bop_gone();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   613
	startup_vm();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   614
	startup_end();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   615
	progressbar_start();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   616
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   617
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   618
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   619
startup_init()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   620
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   621
	PRM_POINT("startup_init() starting...");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   622
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   623
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   624
	 * Complete the extraction of cpuid data
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   625
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   626
	cpuid_pass2(CPU);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   627
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   628
	(void) check_boot_version(BOP_GETVERSION(bootops));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   629
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   630
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   631
	 * Check for prom_debug in boot environment
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   632
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   633
	if (BOP_GETPROPLEN(bootops, "prom_debug") >= 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   634
		++prom_debug;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   635
		PRM_POINT("prom_debug found in boot enviroment");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   636
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   637
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   638
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   639
	 * Collect node, cpu and memory configuration information.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   640
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   641
	get_system_configuration();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   642
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   643
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   644
	 * Halt if this is an unsupported processor.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   645
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   646
	if (x86_type == X86_TYPE_486 || x86_type == X86_TYPE_CYRIX_486) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   647
		printf("\n486 processor (\"%s\") detected.\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   648
		    CPU->cpu_brandstr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   649
		halt("This processor is not supported by this release "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   650
		    "of Solaris.");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   651
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   652
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   653
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   654
	 * Set up dummy values till psm spl code installed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   655
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   656
	CPU->cpu_pri_data = dummy_cpu_pri;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   657
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   658
	PRM_POINT("startup_init() done");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   659
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   660
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   661
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   662
 * Callback for copy_memlist_filter() to filter nucleus, kadb/kmdb, (ie.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   663
 * everything mapped above KERNEL_TEXT) pages from phys_avail. Note it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   664
 * also filters out physical page zero.  There is some reliance on the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   665
 * boot loader allocating only a few contiguous physical memory chunks.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   666
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   667
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   668
avail_filter(uint64_t *addr, uint64_t *size)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   669
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   670
	uintptr_t va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   671
	uintptr_t next_va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   672
	pfn_t pfn;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   673
	uint64_t pfn_addr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   674
	uint64_t pfn_eaddr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   675
	uint_t prot;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   676
	size_t len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   677
	uint_t change;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   678
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   679
	if (prom_debug)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   680
		prom_printf("\tFilter: in: a=%" PRIx64 ", s=%" PRIx64 "\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   681
		    *addr, *size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   682
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   683
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   684
	 * page zero is required for BIOS.. never make it available
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   685
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   686
	if (*addr == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   687
		*addr += MMU_PAGESIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   688
		*size -= MMU_PAGESIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   689
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   690
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   691
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   692
	 * First we trim from the front of the range. Since hat_boot_probe()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   693
	 * walks ranges in virtual order, but addr/size are physical, we need
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   694
	 * to the list until no changes are seen.  This deals with the case
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   695
	 * where page "p" is mapped at v, page "p + PAGESIZE" is mapped at w
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   696
	 * but w < v.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   697
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   698
	do {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   699
		change = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   700
		for (va = KERNEL_TEXT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   701
		    *size > 0 && hat_boot_probe(&va, &len, &pfn, &prot) != 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   702
		    va = next_va) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   703
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   704
			next_va = va + len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   705
			pfn_addr = ptob((uint64_t)pfn);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   706
			pfn_eaddr = pfn_addr + len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   707
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   708
			if (pfn_addr <= *addr && pfn_eaddr > *addr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   709
				change = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   710
				while (*size > 0 && len > 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   711
					*addr += MMU_PAGESIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   712
					*size -= MMU_PAGESIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   713
					len -= MMU_PAGESIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   714
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   715
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   716
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   717
		if (change && prom_debug)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   718
			prom_printf("\t\ttrim: a=%" PRIx64 ", s=%" PRIx64 "\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   719
			    *addr, *size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   720
	} while (change);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   721
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   722
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   723
	 * Trim pages from the end of the range.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   724
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   725
	for (va = KERNEL_TEXT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   726
	    *size > 0 && hat_boot_probe(&va, &len, &pfn, &prot) != 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   727
	    va = next_va) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   728
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   729
		next_va = va + len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   730
		pfn_addr = ptob((uint64_t)pfn);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   731
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   732
		if (pfn_addr >= *addr && pfn_addr < *addr + *size)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   733
			*size = pfn_addr - *addr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   734
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   735
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   736
	if (prom_debug)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   737
		prom_printf("\tFilter out: a=%" PRIx64 ", s=%" PRIx64 "\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   738
		    *addr, *size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   739
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   740
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   741
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   742
kpm_init()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   743
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   744
	struct segkpm_crargs b;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   745
	uintptr_t start, end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   746
	struct memlist	*pmem;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   747
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   748
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   749
	 * These variables were all designed for sfmmu in which segkpm is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   750
	 * mapped using a single pagesize - either 8KB or 4MB.  On x86, we
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   751
	 * might use 2+ page sizes on a single machine, so none of these
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   752
	 * variables have a single correct value.  They are set up as if we
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   753
	 * always use a 4KB pagesize, which should do no harm.  In the long
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   754
	 * run, we should get rid of KPM's assumption that only a single
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   755
	 * pagesize is used.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   756
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   757
	kpm_pgshft = MMU_PAGESHIFT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   758
	kpm_pgsz =  MMU_PAGESIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   759
	kpm_pgoff = MMU_PAGEOFFSET;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   760
	kpmp2pshft = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   761
	kpmpnpgs = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   762
	ASSERT(((uintptr_t)kpm_vbase & (kpm_pgsz - 1)) == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   763
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   764
	PRM_POINT("about to create segkpm");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   765
	rw_enter(&kas.a_lock, RW_WRITER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   766
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   767
	if (seg_attach(&kas, kpm_vbase, kpm_size, segkpm) < 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   768
		panic("cannot attach segkpm");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   769
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   770
	b.prot = PROT_READ | PROT_WRITE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   771
	b.nvcolors = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   772
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   773
	if (segkpm_create(segkpm, (caddr_t)&b) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   774
		panic("segkpm_create segkpm");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   775
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   776
	rw_exit(&kas.a_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   777
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   778
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   779
	 * Map each of the memsegs into the kpm segment, coalesing adjacent
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   780
	 * memsegs to allow mapping with the largest possible pages.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   781
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   782
	pmem = phys_install;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   783
	start = pmem->address;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   784
	end = start + pmem->size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   785
	for (;;) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   786
		if (pmem == NULL || pmem->address > end) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   787
			hat_devload(kas.a_hat, kpm_vbase + start,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   788
			    end - start, mmu_btop(start),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   789
			    PROT_READ | PROT_WRITE,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   790
			    HAT_LOAD | HAT_LOAD_LOCK | HAT_LOAD_NOCONSIST);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   791
			if (pmem == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   792
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   793
			start = pmem->address;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   794
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   795
		end = pmem->address + pmem->size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   796
		pmem = pmem->next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   797
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   798
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   799
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   800
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   801
 * The purpose of startup memlist is to get the system to the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   802
 * point where it can use kmem_alloc()'s that operate correctly
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   803
 * relying on BOP_ALLOC(). This includes allocating page_ts,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   804
 * page hash table, vmem initialized, etc.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   805
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   806
 * Boot's versions of physinstalled and physavail are insufficient for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   807
 * the kernel's purposes. Specifically we don't know which pages that
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   808
 * are not in physavail can be reclaimed after boot is gone.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   809
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   810
 * This code solves the problem by dividing the address space
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   811
 * into 3 regions as it takes over the MMU from the booter.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   812
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   813
 * 1) Any (non-nucleus) pages that are mapped at addresses above KERNEL_TEXT
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   814
 * can not be used by the kernel.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   815
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   816
 * 2) Any free page that happens to be mapped below kernelbase
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   817
 * is protected until the boot loader is released, but will then be reclaimed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   818
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   819
 * 3) Boot shouldn't use any address in the remaining area between kernelbase
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   820
 * and KERNEL_TEXT.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   821
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   822
 * In the case of multiple mappings to the same page, region 1 has precedence
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   823
 * over region 2.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   824
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   825
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   826
startup_memlist(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   827
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   828
	size_t memlist_sz;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   829
	size_t memseg_sz;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   830
	size_t pagehash_sz;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   831
	size_t pp_sz;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   832
	uintptr_t va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   833
	size_t len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   834
	uint_t prot;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   835
	pfn_t pfn;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   836
	int memblocks;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   837
	caddr_t pagecolor_mem;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   838
	size_t pagecolor_memsz;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   839
	caddr_t page_ctrs_mem;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   840
	size_t page_ctrs_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   841
	struct memlist *current;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   842
	extern void startup_build_mem_nodes(struct memlist *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   843
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   844
	/* XX64 fix these - they should be in include files */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   845
	extern ulong_t cr4_value;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   846
	extern size_t page_coloring_init(uint_t, int, int);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   847
	extern void page_coloring_setup(caddr_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   848
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   849
	PRM_POINT("startup_memlist() starting...");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   850
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   851
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   852
	 * Take the most current snapshot we can by calling mem-update.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   853
	 * For this to work properly, we first have to ask boot for its
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   854
	 * end address.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   855
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   856
	if (BOP_GETPROPLEN(bootops, "memory-update") == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   857
		(void) BOP_GETPROP(bootops, "memory-update", NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   858
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   859
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   860
	 * find if the kernel is mapped on a large page
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   861
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   862
	va = KERNEL_TEXT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   863
	if (hat_boot_probe(&va, &len, &pfn, &prot) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   864
		panic("Couldn't find kernel text boot mapping");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   865
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   866
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   867
	 * Use leftover large page nucleus text/data space for loadable modules.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   868
	 * Use at most MODTEXT/MODDATA.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   869
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   870
	if (len > MMU_PAGESIZE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   871
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   872
		moddata = (caddr_t)ROUND_UP_PAGE(e_data);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   873
		e_moddata = (caddr_t)ROUND_UP_4MEG(e_data);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   874
		if (e_moddata - moddata > MODDATA)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   875
			e_moddata = moddata + MODDATA;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   876
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   877
		modtext = (caddr_t)ROUND_UP_PAGE(e_text);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   878
		e_modtext = (caddr_t)ROUND_UP_4MEG(e_text);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   879
		if (e_modtext - modtext > MODTEXT)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   880
			e_modtext = modtext + MODTEXT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   881
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   882
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   883
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   884
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   885
		PRM_POINT("Kernel NOT loaded on Large Page!");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   886
		e_moddata = moddata = (caddr_t)ROUND_UP_PAGE(e_data);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   887
		e_modtext = modtext = (caddr_t)ROUND_UP_PAGE(e_text);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   888
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   889
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   890
	econtig = e_moddata;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   891
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   892
	PRM_DEBUG(modtext);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   893
	PRM_DEBUG(e_modtext);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   894
	PRM_DEBUG(moddata);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   895
	PRM_DEBUG(e_moddata);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   896
	PRM_DEBUG(econtig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   897
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   898
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   899
	 * For MP machines cr4_value must be set or the non-boot
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   900
	 * CPUs will not be able to start.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   901
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   902
	if (x86_feature & X86_LARGEPAGE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   903
		cr4_value = getcr4();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   904
	PRM_DEBUG(cr4_value);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   905
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   906
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   907
	 * Examine the boot loaders physical memory map to find out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   908
	 * - total memory in system - physinstalled
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   909
	 * - the max physical address - physmax
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   910
	 * - the number of segments the intsalled memory comes in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   911
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   912
	if (prom_debug)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   913
		print_boot_memlist("boot physinstalled",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   914
		    bootops->boot_mem->physinstalled);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   915
	installed_top_size(bootops->boot_mem->physinstalled, &physmax,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   916
	    &physinstalled, &memblocks);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   917
	PRM_DEBUG(physmax);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   918
	PRM_DEBUG(physinstalled);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   919
	PRM_DEBUG(memblocks);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   920
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   921
	if (prom_debug)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   922
		print_boot_memlist("boot physavail",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   923
		    bootops->boot_mem->physavail);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   924
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   925
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   926
	 * Initialize hat's mmu parameters.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   927
	 * Check for enforce-prot-exec in boot environment. It's used to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   928
	 * enable/disable support for the page table entry NX bit.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   929
	 * The default is to enforce PROT_EXEC on processors that support NX.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   930
	 * Boot seems to round up the "len", but 8 seems to be big enough.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   931
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   932
	mmu_init();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   933
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   934
#ifdef	__i386
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   935
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   936
	 * physmax is lowered if there is more memory than can be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   937
	 * physically addressed in 32 bit (PAE/non-PAE) modes.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   938
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   939
	if (mmu.pae_hat) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   940
		if (PFN_ABOVE64G(physmax)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   941
			physinstalled -= (physmax - (PFN_64G - 1));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   942
			physmax = PFN_64G - 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   943
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   944
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   945
		if (PFN_ABOVE4G(physmax)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   946
			physinstalled -= (physmax - (PFN_4G - 1));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   947
			physmax = PFN_4G - 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   948
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   949
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   950
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   951
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   952
	startup_build_mem_nodes(bootops->boot_mem->physinstalled);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   953
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   954
	if (BOP_GETPROPLEN(bootops, "enforce-prot-exec") >= 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   955
		int len = BOP_GETPROPLEN(bootops, "enforce-prot-exec");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   956
		char value[8];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   957
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   958
		if (len < 8)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   959
			(void) BOP_GETPROP(bootops, "enforce-prot-exec", value);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   960
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   961
			(void) strcpy(value, "");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   962
		if (strcmp(value, "off") == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   963
			mmu.pt_nx = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   964
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   965
	PRM_DEBUG(mmu.pt_nx);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   966
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   967
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   968
	 * We will need page_t's for every page in the system, except for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   969
	 * memory mapped at or above above the start of the kernel text segment.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   970
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   971
	 * pages above e_modtext are attributed to kernel debugger (obp_pages)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   972
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   973
	npages = physinstalled - 1; /* avail_filter() skips page 0, so "- 1" */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   974
	obp_pages = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   975
	va = KERNEL_TEXT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   976
	while (hat_boot_probe(&va, &len, &pfn, &prot) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   977
		npages -= len >> MMU_PAGESHIFT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   978
		if (va >= (uintptr_t)e_moddata)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   979
			obp_pages += len >> MMU_PAGESHIFT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   980
		va += len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   981
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   982
	PRM_DEBUG(npages);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   983
	PRM_DEBUG(obp_pages);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   984
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   985
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   986
	 * If physmem is patched to be non-zero, use it instead of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   987
	 * the computed value unless it is larger than the real
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   988
	 * amount of memory on hand.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   989
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   990
	if (physmem == 0 || physmem > npages)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   991
		physmem = npages;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   992
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   993
		npages = physmem;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   994
	PRM_DEBUG(physmem);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   995
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   996
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   997
	 * We now compute the sizes of all the  initial allocations for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   998
	 * structures the kernel needs in order do kmem_alloc(). These
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   999
	 * include:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1000
	 *	memsegs
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1001
	 *	memlists
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1002
	 *	page hash table
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1003
	 *	page_t's
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1004
	 *	page coloring data structs
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1005
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1006
	memseg_sz = sizeof (struct memseg) * (memblocks + POSS_NEW_FRAGMENTS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1007
	ADD_TO_ALLOCATIONS(memseg_base, memseg_sz);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1008
	PRM_DEBUG(memseg_sz);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1009
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1010
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1011
	 * Reserve space for phys_avail/phys_install memlists.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1012
	 * There's no real good way to know exactly how much room we'll need,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1013
	 * but this should be a good upper bound.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1014
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1015
	memlist_sz = ROUND_UP_PAGE(2 * sizeof (struct memlist) *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1016
	    (memblocks + POSS_NEW_FRAGMENTS));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1017
	ADD_TO_ALLOCATIONS(memlist, memlist_sz);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1018
	PRM_DEBUG(memlist_sz);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1019
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1020
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1021
	 * The page structure hash table size is a power of 2
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1022
	 * such that the average hash chain length is PAGE_HASHAVELEN.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1023
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1024
	page_hashsz = npages / PAGE_HASHAVELEN;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1025
	page_hashsz = 1 << highbit(page_hashsz);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1026
	pagehash_sz = sizeof (struct page *) * page_hashsz;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1027
	ADD_TO_ALLOCATIONS(page_hash, pagehash_sz);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1028
	PRM_DEBUG(pagehash_sz);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1029
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1030
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1031
	 * Set aside room for the page structures themselves.  Note: on
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1032
	 * 64-bit systems we don't allocate page_t's for every page here.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1033
	 * We just allocate enough to map the lowest 4GB of physical
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1034
	 * memory, minus those pages that are used for the "nucleus" kernel
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1035
	 * text and data.  The remaining pages are allocated once we can
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1036
	 * map around boot.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1037
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1038
	 * boot_npages is used to allocate an area big enough for our
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1039
	 * initial page_t's. kphym_init may use less than that.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1040
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1041
	boot_npages = npages;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1042
#if defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1043
	if (npages > mmu_btop(FOURGB - (econtig - s_text)))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1044
		boot_npages = mmu_btop(FOURGB - (econtig - s_text));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1045
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1046
	PRM_DEBUG(boot_npages);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1047
	pp_sz = sizeof (struct page) * boot_npages;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1048
	ADD_TO_ALLOCATIONS(pp_base, pp_sz);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1049
	PRM_DEBUG(pp_sz);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1050
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1051
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1052
	 * determine l2 cache info and memory size for page coloring
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1053
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1054
	(void) getl2cacheinfo(CPU,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1055
	    &l2cache_sz, &l2cache_linesz, &l2cache_assoc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1056
	pagecolor_memsz =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1057
	    page_coloring_init(l2cache_sz, l2cache_linesz, l2cache_assoc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1058
	ADD_TO_ALLOCATIONS(pagecolor_mem, pagecolor_memsz);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1059
	PRM_DEBUG(pagecolor_memsz);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1060
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1061
	page_ctrs_size = page_ctrs_sz();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1062
	ADD_TO_ALLOCATIONS(page_ctrs_mem, page_ctrs_size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1063
	PRM_DEBUG(page_ctrs_size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1064
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1065
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1066
	 * valloc_base will be below kernel text
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1067
	 * The extra pages are for the HAT and kmdb to map page tables.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1068
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1069
	valloc_sz = ROUND_UP_LPAGE(valloc_sz);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1070
	valloc_base = KERNEL_TEXT - valloc_sz;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1071
	PRM_DEBUG(valloc_base);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1072
	ptable_va = valloc_base - ptable_sz;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1073
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1074
#if defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1075
	if (eprom_kernelbase && eprom_kernelbase != KERNELBASE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1076
		cmn_err(CE_NOTE, "!kernelbase cannot be changed on 64-bit "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1077
		    "systems.");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1078
	kernelbase = (uintptr_t)KERNELBASE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1079
	core_base = (uintptr_t)COREHEAP_BASE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1080
	core_size = ptable_va - core_base;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1081
#else	/* __i386 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1082
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1083
	 * We configure kernelbase based on:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1084
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1085
	 * 1. user specified kernelbase via eeprom command. Value cannot exceed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1086
	 *    KERNELBASE_MAX. we large page align eprom_kernelbase
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1087
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1088
	 * 2. Default to KERNELBASE and adjust to 2X less the size for page_t.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1089
	 *    On large memory systems we must lower kernelbase to allow
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1090
	 *    enough room for page_t's for all of memory.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1091
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1092
	 * The value set here, might be changed a little later.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1093
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1094
	if (eprom_kernelbase) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1095
		kernelbase = eprom_kernelbase & mmu.level_mask[1];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1096
		if (kernelbase > KERNELBASE_MAX)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1097
			kernelbase = KERNELBASE_MAX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1098
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1099
		kernelbase = (uintptr_t)KERNELBASE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1100
		kernelbase -= ROUND_UP_4MEG(2 * valloc_sz);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1101
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1102
	ASSERT((kernelbase & mmu.level_offset[1]) == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1103
	core_base = ptable_va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1104
	core_size = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1105
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1106
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1107
	PRM_DEBUG(kernelbase);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1108
	PRM_DEBUG(core_base);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1109
	PRM_DEBUG(core_size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1110
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1111
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1112
	 * At this point, we can only use a portion of the kernelheap that
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1113
	 * will be available after we boot.  Both 32-bit and 64-bit systems
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1114
	 * have this limitation, although the reasons are completely
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1115
	 * different.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1116
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1117
	 * On 64-bit systems, the booter only supports allocations in the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1118
	 * upper 4GB of memory, so we have to work with a reduced kernel
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1119
	 * heap until we take over all allocations.  The booter also sits
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1120
	 * in the lower portion of that 4GB range, so we have to raise the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1121
	 * bottom of the heap even further.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1122
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1123
	 * On 32-bit systems we have to leave room to place segmap below
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1124
	 * the heap.  We don't yet know how large segmap will be, so we
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1125
	 * have to be very conservative.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1126
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1127
#if defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1128
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1129
	 * XX64: For now, we let boot have the lower 2GB of the top 4GB
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1130
	 * address range.  In the long run, that should be fixed.  It's
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1131
	 * insane for a booter to need 2 2GB address ranges.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1132
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1133
	boot_kernelheap = (caddr_t)(BOOT_DOUBLEMAP_BASE + BOOT_DOUBLEMAP_SIZE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1134
	segmap_reserved = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1135
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1136
#else	/* __i386 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1137
	segkp_fromheap = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1138
	segmap_reserved = ROUND_UP_LPAGE(MAX(segmapsize, SEGMAPMAX));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1139
	boot_kernelheap = (caddr_t)(ROUND_UP_LPAGE(kernelbase) +
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1140
	    segmap_reserved);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1141
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1142
	PRM_DEBUG(boot_kernelheap);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1143
	kernelheap = boot_kernelheap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1144
	ekernelheap = (char *)core_base;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1145
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1146
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1147
	 * If segmap is too large we can push the bottom of the kernel heap
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1148
	 * higher than the base.  Or worse, it could exceed the top of the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1149
	 * VA space entirely, causing it to wrap around.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1150
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1151
	if (kernelheap >= ekernelheap || (uintptr_t)kernelheap < kernelbase)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1152
		panic("too little memory available for kernelheap,"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1153
			    " use a different kernelbase");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1154
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1155
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1156
	 * Now that we know the real value of kernelbase,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1157
	 * update variables that were initialized with a value of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1158
	 * KERNELBASE (in common/conf/param.c).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1159
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1160
	 * XXX	The problem with this sort of hackery is that the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1161
	 *	compiler just may feel like putting the const declarations
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1162
	 *	(in param.c) into the .text section.  Perhaps they should
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1163
	 *	just be declared as variables there?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1164
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1165
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1166
#if defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1167
	ASSERT(_kernelbase == KERNELBASE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1168
	ASSERT(_userlimit == USERLIMIT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1169
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1170
	 * As one final sanity check, verify that the "red zone" between
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1171
	 * kernel and userspace is exactly the size we expected.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1172
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1173
	ASSERT(_kernelbase == (_userlimit + (2 * 1024 * 1024)));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1174
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1175
	*(uintptr_t *)&_kernelbase = kernelbase;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1176
	*(uintptr_t *)&_userlimit = kernelbase;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1177
	*(uintptr_t *)&_userlimit32 = _userlimit;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1178
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1179
	PRM_DEBUG(_kernelbase);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1180
	PRM_DEBUG(_userlimit);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1181
	PRM_DEBUG(_userlimit32);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1182
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1183
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1184
	 * do all the initial allocations
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1185
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1186
	perform_allocations();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1187
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1188
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1189
	 * Initialize the kernel heap. Note 3rd argument must be > 1st.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1190
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1191
	kernelheap_init(kernelheap, ekernelheap, kernelheap + MMU_PAGESIZE,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1192
	    (void *)core_base, (void *)ptable_va);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1193
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1194
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1195
	 * Build phys_install and phys_avail in kernel memspace.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1196
	 * - phys_install should be all memory in the system.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1197
	 * - phys_avail is phys_install minus any memory mapped before this
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1198
	 *    point above KERNEL_TEXT.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1199
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1200
	current = phys_install = memlist;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1201
	copy_memlist_filter(bootops->boot_mem->physinstalled, &current, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1202
	if ((caddr_t)current > (caddr_t)memlist + memlist_sz)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1203
		panic("physinstalled was too big!");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1204
	if (prom_debug)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1205
		print_kernel_memlist("phys_install", phys_install);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1206
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1207
	phys_avail = current;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1208
	PRM_POINT("Building phys_avail:\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1209
	copy_memlist_filter(bootops->boot_mem->physinstalled, &current,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1210
	    avail_filter);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1211
	if ((caddr_t)current > (caddr_t)memlist + memlist_sz)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1212
		panic("physavail was too big!");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1213
	if (prom_debug)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1214
		print_kernel_memlist("phys_avail", phys_avail);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1215
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1216
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1217
	 * setup page coloring
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1218
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1219
	page_coloring_setup(pagecolor_mem);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1220
	page_lock_init();	/* currently a no-op */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1221
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1222
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1223
	 * free page list counters
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1224
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1225
	(void) page_ctrs_alloc(page_ctrs_mem);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1226
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1227
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1228
	 * Initialize the page structures from the memory lists.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1229
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1230
	availrmem_initial = availrmem = freemem = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1231
	PRM_POINT("Calling kphysm_init()...");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1232
	boot_npages = kphysm_init(pp_base, memseg_base, 0, boot_npages);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1233
	PRM_POINT("kphysm_init() done");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1234
	PRM_DEBUG(boot_npages);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1235
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1236
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1237
	 * Now that page_t's have been initialized, remove all the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1238
	 * initial allocation pages from the kernel free page lists.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1239
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1240
	boot_mapin((caddr_t)valloc_base, valloc_sz);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1241
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1242
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1243
	 * Initialize kernel memory allocator.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1244
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1245
	kmem_init();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1246
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1247
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1248
	 * print this out early so that we know what's going on
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1249
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1250
	cmn_err(CE_CONT, "?features: %b\n", x86_feature, FMT_X86_FEATURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1251
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1252
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1253
	 * Initialize bp_mapin().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1254
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1255
	bp_init(MMU_PAGESIZE, HAT_STORECACHING_OK);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1256
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1257
#if defined(__i386)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1258
	if (eprom_kernelbase && (eprom_kernelbase != kernelbase))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1259
		cmn_err(CE_WARN, "kernelbase value, User specified 0x%lx, "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1260
		    "System using 0x%lx",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1261
		    (uintptr_t)eprom_kernelbase, (uintptr_t)kernelbase);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1262
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1263
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1264
#ifdef	KERNELBASE_ABI_MIN
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1265
	if (kernelbase < (uintptr_t)KERNELBASE_ABI_MIN) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1266
		cmn_err(CE_NOTE, "!kernelbase set to 0x%lx, system is not "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1267
		    "i386 ABI compliant.", (uintptr_t)kernelbase);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1268
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1269
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1270
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1271
	PRM_POINT("startup_memlist() done");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1272
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1273
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1274
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1275
startup_modules(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1276
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1277
	unsigned int i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1278
	extern void impl_setup_ddi(void);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1279
	extern void prom_setup(void);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1280
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1281
	PRM_POINT("startup_modules() starting...");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1282
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1283
	 * Initialize ten-micro second timer so that drivers will
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1284
	 * not get short changed in their init phase. This was
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1285
	 * not getting called until clkinit which, on fast cpu's
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1286
	 * caused the drv_usecwait to be way too short.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1287
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1288
	microfind();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1289
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1290
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1291
	 * Read the GMT lag from /etc/rtc_config.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1292
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1293
	gmt_lag = process_rtc_config_file();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1294
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1295
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1296
	 * Calculate default settings of system parameters based upon
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1297
	 * maxusers, yet allow to be overridden via the /etc/system file.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1298
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1299
	param_calc(0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1300
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1301
	mod_setup();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1302
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1303
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1304
	 * Setup machine check architecture on P6
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1305
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1306
	setup_mca();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1307
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1308
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1309
	 * Initialize system parameters.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1310
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1311
	param_init();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1312
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1313
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1314
	 * maxmem is the amount of physical memory we're playing with.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1315
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1316
	maxmem = physmem;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1317
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1318
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1319
	 * Initialize the hat layer.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1320
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1321
	hat_init();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1322
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1323
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1324
	 * Initialize segment management stuff.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1325
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1326
	seg_init();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1327
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1328
	if (modload("fs", "specfs") == -1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1329
		halt("Can't load specfs");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1330
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1331
	if (modload("fs", "devfs") == -1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1332
		halt("Can't load devfs");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1333
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1334
	dispinit();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1335
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1336
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1337
	 * This is needed here to initialize hw_serial[] for cluster booting.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1338
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1339
	if ((i = modload("misc", "sysinit")) != (unsigned int)-1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1340
		(void) modunload(i);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1341
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1342
		cmn_err(CE_CONT, "sysinit load failed");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1343
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1344
	/* Read cluster configuration data. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1345
	clconf_init();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1346
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1347
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1348
	 * Create a kernel device tree. First, create rootnex and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1349
	 * then invoke bus specific code to probe devices.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1350
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1351
	setup_ddi();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1352
	impl_setup_ddi();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1353
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1354
	 * Fake a prom tree such that /dev/openprom continues to work
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1355
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1356
	prom_setup();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1357
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1358
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1359
	 * Load all platform specific modules
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1360
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1361
	psm_modload();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1362
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1363
	PRM_POINT("startup_modules() done");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1364
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1365
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1366
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1367
startup_bop_gone(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1368
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1369
	PRM_POINT("startup_bop_gone() starting...");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1370
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1371
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1372
	 * Do final allocations of HAT data structures that need to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1373
	 * be allocated before quiescing the boot loader.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1374
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1375
	PRM_POINT("Calling hat_kern_alloc()...");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1376
	hat_kern_alloc();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1377
	PRM_POINT("hat_kern_alloc() done");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1378
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1379
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1380
	 * Setup MTRR (Memory type range registers)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1381
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1382
	setup_mtrr();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1383
	PRM_POINT("startup_bop_gone() done");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1384
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1385
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1386
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1387
 * Walk through the pagetables looking for pages mapped in by boot.  If the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1388
 * setaside flag is set the pages are expected to be returned to the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1389
 * kernel later in boot, so we add them to the bootpages list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1390
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1391
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1392
protect_boot_range(uintptr_t low, uintptr_t high, int setaside)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1393
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1394
	uintptr_t va = low;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1395
	size_t len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1396
	uint_t prot;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1397
	pfn_t pfn;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1398
	page_t *pp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1399
	pgcnt_t boot_protect_cnt = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1400
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1401
	while (hat_boot_probe(&va, &len, &pfn, &prot) != 0 && va < high) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1402
		if (va + len >= high)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1403
			panic("0x%lx byte mapping at 0x%p exceeds boot's "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1404
			    "legal range.", len, (void *)va);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1405
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1406
		while (len > 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1407
			pp = page_numtopp_alloc(pfn);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1408
			if (pp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1409
				if (setaside == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1410
					panic("Unexpected mapping by boot.  "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1411
					    "addr=%p pfn=%lx\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1412
					    (void *)va, pfn);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1413
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1414
				pp->p_next = bootpages;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1415
				bootpages = pp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1416
				++boot_protect_cnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1417
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1418
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1419
			++pfn;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1420
			len -= MMU_PAGESIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1421
			va += MMU_PAGESIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1422
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1423
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1424
	PRM_DEBUG(boot_protect_cnt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1425
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1426
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1427
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1428
startup_vm(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1429
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1430
	struct segmap_crargs a;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1431
	extern void hat_kern_setup(void);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1432
	pgcnt_t pages_left;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1433
423
6cbc492798ce 6294795 The behavior of malloc is different between solaris 10 and nevada
davemq
parents: 0
diff changeset
  1434
	extern int exec_lpg_disable, use_brk_lpg, use_stk_lpg, use_zmap_lpg;
6cbc492798ce 6294795 The behavior of malloc is different between solaris 10 and nevada
davemq
parents: 0
diff changeset
  1435
	extern pgcnt_t auto_lpg_min_physmem;
6cbc492798ce 6294795 The behavior of malloc is different between solaris 10 and nevada
davemq
parents: 0
diff changeset
  1436
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1437
	PRM_POINT("startup_vm() starting...");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1438
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1439
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1440
	 * The next two loops are done in distinct steps in order
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1441
	 * to be sure that any page that is doubly mapped (both above
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1442
	 * KERNEL_TEXT and below kernelbase) is dealt with correctly.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1443
	 * Note this may never happen, but it might someday.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1444
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1445
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1446
	bootpages = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1447
	PRM_POINT("Protecting boot pages");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1448
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1449
	 * Protect any pages mapped above KERNEL_TEXT that somehow have
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1450
	 * page_t's. This can only happen if something weird allocated
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1451
	 * in this range (like kadb/kmdb).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1452
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1453
	protect_boot_range(KERNEL_TEXT, (uintptr_t)-1, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1454
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1455
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1456
	 * Before we can take over memory allocation/mapping from the boot
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1457
	 * loader we must remove from our free page lists any boot pages that
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1458
	 * will stay mapped until release_bootstrap().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1459
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1460
	protect_boot_range(0, kernelbase, 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1461
#if defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1462
	protect_boot_range(BOOT_DOUBLEMAP_BASE,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1463
	    BOOT_DOUBLEMAP_BASE + BOOT_DOUBLEMAP_SIZE, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1464
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1465
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1466
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1467
	 * Copy in boot's page tables, set up extra page tables for the kernel,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1468
	 * and switch to the kernel's context.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1469
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1470
	PRM_POINT("Calling hat_kern_setup()...");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1471
	hat_kern_setup();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1472
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1473
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1474
	 * It is no longer safe to call BOP_ALLOC(), so make sure we don't.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1475
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1476
	bootops->bsys_alloc = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1477
	PRM_POINT("hat_kern_setup() done");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1478
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1479
	hat_cpu_online(CPU);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1480
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1481
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1482
	 * Before we call kvm_init(), we need to establish the final size
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1483
	 * of the kernel's heap.  So, we need to figure out how much space
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1484
	 * to set aside for segkp, segkpm, and segmap.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1485
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1486
	final_kernelheap = (caddr_t)ROUND_UP_LPAGE(kernelbase);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1487
#if defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1488
	if (kpm_desired) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1489
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1490
		 * Segkpm appears at the bottom of the kernel's address
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1491
		 * range.  To detect accidental overruns of the user
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1492
		 * address space, we leave a "red zone" of unmapped memory
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1493
		 * between kernelbase and the beginning of segkpm.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1494
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1495
		kpm_vbase = final_kernelheap + KERNEL_REDZONE_SIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1496
		kpm_size = mmu_ptob(physmax);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1497
		PRM_DEBUG(kpm_vbase);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1498
		PRM_DEBUG(kpm_size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1499
		final_kernelheap =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1500
		    (caddr_t)ROUND_UP_TOPLEVEL(kpm_vbase + kpm_size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1501
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1502
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1503
	if (!segkp_fromheap) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1504
		size_t sz = mmu_ptob(segkpsize);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1505
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1506
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1507
		 * determine size of segkp and adjust the bottom of the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1508
		 * kernel's heap.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1509
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1510
		if (sz < SEGKPMINSIZE || sz > SEGKPMAXSIZE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1511
			sz = SEGKPDEFSIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1512
			cmn_err(CE_WARN, "!Illegal value for segkpsize. "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1513
			    "segkpsize has been reset to %ld pages",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1514
			    mmu_btop(sz));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1515
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1516
		sz = MIN(sz, MAX(SEGKPMINSIZE, mmu_ptob(physmem)));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1517
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1518
		segkpsize = mmu_btop(ROUND_UP_LPAGE(sz));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1519
		segkp_base = final_kernelheap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1520
		PRM_DEBUG(segkpsize);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1521
		PRM_DEBUG(segkp_base);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1522
		final_kernelheap = segkp_base + mmu_ptob(segkpsize);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1523
		PRM_DEBUG(final_kernelheap);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1524
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1525
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1526
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1527
	 * put the range of VA for device mappings next
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1528
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1529
	toxic_addr = (uintptr_t)final_kernelheap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1530
	PRM_DEBUG(toxic_addr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1531
	final_kernelheap = (char *)toxic_addr + toxic_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1532
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1533
	PRM_DEBUG(final_kernelheap);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1534
	ASSERT(final_kernelheap < boot_kernelheap);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1535
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1536
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1537
	 * Users can change segmapsize through eeprom or /etc/system.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1538
	 * If the variable is tuned through eeprom, there is no upper
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1539
	 * bound on the size of segmap.  If it is tuned through
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1540
	 * /etc/system on 32-bit systems, it must be no larger than we
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1541
	 * planned for in startup_memlist().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1542
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1543
	segmapsize = MAX(ROUND_UP_LPAGE(segmapsize), SEGMAPDEFAULT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1544
	segkmap_start = ROUND_UP_LPAGE((uintptr_t)final_kernelheap);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1545
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1546
#if defined(__i386)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1547
	if (segmapsize > segmap_reserved) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1548
		cmn_err(CE_NOTE, "!segmapsize may not be set > 0x%lx in "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1549
		    "/etc/system.  Use eeprom.", (long)SEGMAPMAX);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1550
		segmapsize = segmap_reserved;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1551
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1552
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1553
	 * 32-bit systems don't have segkpm or segkp, so segmap appears at
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1554
	 * the bottom of the kernel's address range.  Set aside space for a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1555
	 * red zone just below the start of segmap.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1556
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1557
	segkmap_start += KERNEL_REDZONE_SIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1558
	segmapsize -= KERNEL_REDZONE_SIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1559
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1560
	final_kernelheap = (char *)(segkmap_start + segmapsize);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1561
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1562
	PRM_DEBUG(segkmap_start);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1563
	PRM_DEBUG(segmapsize);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1564
	PRM_DEBUG(final_kernelheap);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1565
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1566
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1567
	 * Initialize VM system
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1568
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1569
	PRM_POINT("Calling kvm_init()...");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1570
	kvm_init();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1571
	PRM_POINT("kvm_init() done");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1572
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1573
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1574
	 * Tell kmdb that the VM system is now working
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1575
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1576
	if (boothowto & RB_DEBUG)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1577
		kdi_dvec_vmready();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1578
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1579
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1580
	 * Mangle the brand string etc.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1581
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1582
	cpuid_pass3(CPU);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1583
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1584
	PRM_DEBUG(final_kernelheap);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1585
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1586
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1587
	 * Now that we can use memory outside the top 4GB (on 64-bit
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1588
	 * systems) and we know the size of segmap, we can set the final
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1589
	 * size of the kernel's heap.  Note: on 64-bit systems we still
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1590
	 * can't touch anything in the bottom half of the top 4GB range
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1591
	 * because boot still has pages mapped there.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1592
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1593
	if (final_kernelheap < boot_kernelheap) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1594
		kernelheap_extend(final_kernelheap, boot_kernelheap);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1595
#if defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1596
		kmem_setaside = vmem_xalloc(heap_arena, BOOT_DOUBLEMAP_SIZE,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1597
		    MMU_PAGESIZE, 0, 0, (void *)(BOOT_DOUBLEMAP_BASE),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1598
		    (void *)(BOOT_DOUBLEMAP_BASE + BOOT_DOUBLEMAP_SIZE),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1599
		    VM_NOSLEEP | VM_BESTFIT | VM_PANIC);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1600
		PRM_DEBUG(kmem_setaside);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1601
		if (kmem_setaside == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1602
			panic("Could not protect boot's memory");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1603
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1604
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1605
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1606
	 * Now that the kernel heap may have grown significantly, we need
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1607
	 * to make all the remaining page_t's available to back that memory.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1608
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1609
	 * XX64 this should probably wait till after release boot-strap too.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1610
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1611
	pages_left = npages - boot_npages;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1612
	if (pages_left > 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1613
		PRM_DEBUG(pages_left);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1614
		(void) kphysm_init(NULL, memseg_base, boot_npages, pages_left);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1615
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1616
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1617
#if defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1618
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1619
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1620
	 * Create the device arena for toxic (to dtrace/kmdb) mappings.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1621
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1622
	device_arena = vmem_create("device", (void *)toxic_addr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1623
	    toxic_size, MMU_PAGESIZE, NULL, NULL, NULL, 0, VM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1624
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1625
#else	/* __i386 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1626
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1627
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1628
	 * allocate the bit map that tracks toxic pages
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1629
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1630
	toxic_bit_map_len = btop((ulong_t)(ptable_va - kernelbase));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1631
	PRM_DEBUG(toxic_bit_map_len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1632
	toxic_bit_map =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1633
	    kmem_zalloc(BT_SIZEOFMAP(toxic_bit_map_len), KM_NOSLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1634
	ASSERT(toxic_bit_map != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1635
	PRM_DEBUG(toxic_bit_map);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1636
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1637
#endif	/* __i386 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1638
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1639
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1640
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1641
	 * Now that we've got more VA, as well as the ability to allocate from
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1642
	 * it, tell the debugger.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1643
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1644
	if (boothowto & RB_DEBUG)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1645
		kdi_dvec_memavail();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1646
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1647
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1648
	 * The following code installs a special page fault handler (#pf)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1649
	 * to work around a pentium bug.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1650
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1651
#if !defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1652
	if (x86_type == X86_TYPE_P5) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1653
		gate_desc_t *newidt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1654
		desctbr_t    newidt_r;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1655
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1656
		if ((newidt = kmem_zalloc(MMU_PAGESIZE, KM_NOSLEEP)) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1657
			panic("failed to install pentium_pftrap");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1658
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1659
		bcopy(idt0, newidt, sizeof (idt0));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1660
		set_gatesegd(&newidt[T_PGFLT], &pentium_pftrap,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1661
		    KCS_SEL, 0, SDT_SYSIGT, SEL_KPL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1662
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1663
		(void) as_setprot(&kas, (caddr_t)newidt, MMU_PAGESIZE,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1664
		    PROT_READ|PROT_EXEC);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1665
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1666
		newidt_r.dtr_limit = sizeof (idt0) - 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1667
		newidt_r.dtr_base = (uintptr_t)newidt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1668
		CPU->cpu_idt = newidt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1669
		wr_idtr(&newidt_r);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1670
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1671
#endif	/* !__amd64 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1672
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1673
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1674
	 * Map page pfn=0 for drivers, such as kd, that need to pick up
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1675
	 * parameters left there by controllers/BIOS.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1676
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1677
	PRM_POINT("setup up p0_va");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1678
	p0_va = i86devmap(0, 1, PROT_READ);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1679
	PRM_DEBUG(p0_va);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1680
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1681
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1682
	 * If the following is true, someone has patched phsymem to be less
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1683
	 * than the number of pages that the system actually has.  Remove
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1684
	 * pages until system memory is limited to the requested amount.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1685
	 * Since we have allocated page structures for all pages, we
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1686
	 * correct the amount of memory we want to remove by the size of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1687
	 * the memory used to hold page structures for the non-used pages.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1688
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1689
	if (physmem < npages) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1690
		uint_t diff;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1691
		offset_t off;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1692
		struct page *pp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1693
		caddr_t rand_vaddr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1694
		struct seg kseg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1695
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1696
		cmn_err(CE_WARN, "limiting physmem to %lu pages", physmem);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1697
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1698
		off = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1699
		diff = npages - physmem;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1700
		diff -= mmu_btopr(diff * sizeof (struct page));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1701
		kseg.s_as = &kas;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1702
		while (diff--) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1703
			rand_vaddr = (caddr_t)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1704
			    (((uintptr_t)&unused_pages_vp >> 7) ^
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1705
			    (uintptr_t)((u_offset_t)off >> MMU_PAGESHIFT));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1706
			pp = page_create_va(&unused_pages_vp, off, MMU_PAGESIZE,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1707
				PG_WAIT | PG_EXCL, &kseg, rand_vaddr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1708
			if (pp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1709
				panic("limited physmem too much!");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1710
				/*NOTREACHED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1711
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1712
			page_io_unlock(pp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1713
			page_downgrade(pp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1714
			availrmem--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1715
			off += MMU_PAGESIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1716
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1717
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1718
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1719
	cmn_err(CE_CONT, "?mem = %luK (0x%lx)\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1720
	    physinstalled << (MMU_PAGESHIFT - 10), ptob(physinstalled));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1721
423
6cbc492798ce 6294795 The behavior of malloc is different between solaris 10 and nevada
davemq
parents: 0
diff changeset
  1722
	/* For small memory systems disable automatic large pages. */
6cbc492798ce 6294795 The behavior of malloc is different between solaris 10 and nevada
davemq
parents: 0
diff changeset
  1723
	if (physmem < auto_lpg_min_physmem) {
6cbc492798ce 6294795 The behavior of malloc is different between solaris 10 and nevada
davemq
parents: 0
diff changeset
  1724
		exec_lpg_disable = 1;
6cbc492798ce 6294795 The behavior of malloc is different between solaris 10 and nevada
davemq
parents: 0
diff changeset
  1725
		use_brk_lpg = 0;
6cbc492798ce 6294795 The behavior of malloc is different between solaris 10 and nevada
davemq
parents: 0
diff changeset
  1726
		use_stk_lpg = 0;
6cbc492798ce 6294795 The behavior of malloc is different between solaris 10 and nevada
davemq
parents: 0
diff changeset
  1727
		use_zmap_lpg = 0;
6cbc492798ce 6294795 The behavior of malloc is different between solaris 10 and nevada
davemq
parents: 0
diff changeset
  1728
	}
6cbc492798ce 6294795 The behavior of malloc is different between solaris 10 and nevada
davemq
parents: 0
diff changeset
  1729
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1730
	PRM_POINT("Calling hat_init_finish()...");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1731
	hat_init_finish();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1732
	PRM_POINT("hat_init_finish() done");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1733
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1734
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1735
	 * Initialize the segkp segment type.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1736
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1737
	rw_enter(&kas.a_lock, RW_WRITER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1738
	if (!segkp_fromheap) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1739
		if (seg_attach(&kas, (caddr_t)segkp_base, mmu_ptob(segkpsize),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1740
		    segkp) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1741
			panic("startup: cannot attach segkp");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1742
			/*NOTREACHED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1743
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1744
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1745
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1746
		 * For 32 bit x86 systems, we will have segkp under the heap.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1747
		 * There will not be a segkp segment.  We do, however, need
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1748
		 * to fill in the seg structure.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1749
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1750
		segkp->s_as = &kas;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1751
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1752
	if (segkp_create(segkp) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1753
		panic("startup: segkp_create failed");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1754
		/*NOTREACHED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1755
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1756
	PRM_DEBUG(segkp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1757
	rw_exit(&kas.a_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1758
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1759
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1760
	 * kpm segment
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1761
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1762
	segmap_kpm = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1763
	if (kpm_desired) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1764
		kpm_init();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1765
		kpm_enable = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1766
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1767
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1768
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1769
	 * Now create segmap segment.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1770
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1771
	rw_enter(&kas.a_lock, RW_WRITER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1772
	if (seg_attach(&kas, (caddr_t)segkmap_start, segmapsize, segkmap) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1773
		panic("cannot attach segkmap");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1774
		/*NOTREACHED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1775
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1776
	PRM_DEBUG(segkmap);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1777
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1778
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1779
	 * The 64 bit HAT permanently maps only segmap's page tables.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1780
	 * The 32 bit HAT maps the heap's page tables too.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1781
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1782
#if defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1783
	hat_kmap_init(segkmap_start, segmapsize);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1784
#else /* __i386 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1785
	ASSERT(segkmap_start + segmapsize == (uintptr_t)final_kernelheap);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1786
	hat_kmap_init(segkmap_start, (uintptr_t)ekernelheap - segkmap_start);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1787
#endif /* __i386 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1788
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1789
	a.prot = PROT_READ | PROT_WRITE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1790
	a.shmsize = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1791
	a.nfreelist = segmapfreelists;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1792
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1793
	if (segmap_create(segkmap, (caddr_t)&a) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1794
		panic("segmap_create segkmap");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1795
	rw_exit(&kas.a_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1796
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1797
	setup_vaddr_for_ppcopy(CPU);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1798
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1799
	segdev_init();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1800
	pmem_init();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1801
	PRM_POINT("startup_vm() done");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1802
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1803
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1804
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1805
startup_end(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1806
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1807
	extern void setx86isalist(void);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1808
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1809
	PRM_POINT("startup_end() starting...");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1810
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1811
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1812
	 * Perform tasks that get done after most of the VM
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1813
	 * initialization has been done but before the clock
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1814
	 * and other devices get started.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1815
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1816
	kern_setup1();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1817
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1818
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1819
	 * Perform CPC initialization for this CPU.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1820
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1821
	kcpc_hw_init(CPU);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1822
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1823
#if defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1824
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1825
	 * Validate support for syscall/sysret
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1826
	 * XX64 -- include SSE, SSE2, etc. here too?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1827
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1828
	if ((x86_feature & X86_ASYSC) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1829
		cmn_err(CE_WARN,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1830
		    "cpu%d does not support syscall/sysret", CPU->cpu_id);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1831
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1832
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1833
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1834
	 * Configure the system.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1835
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1836
	PRM_POINT("Calling configure()...");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1837
	configure();		/* set up devices */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1838
	PRM_POINT("configure() done");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1839
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1840
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1841
	 * Set the isa_list string to the defined instruction sets we
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1842
	 * support.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1843
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1844
	setx86isalist();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1845
	init_intr_threads(CPU);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1846
	psm_install();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1847
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1848
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1849
	 * We're done with bootops.  We don't unmap the bootstrap yet because
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1850
	 * we're still using bootsvcs.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1851
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1852
	PRM_POINT("zeroing out bootops");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1853
	*bootopsp = (struct bootops *)0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1854
	bootops = (struct bootops *)NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1855
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1856
	PRM_POINT("Enabling interrupts");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1857
	(*picinitf)();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1858
	sti();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1859
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1860
	(void) add_avsoftintr((void *)&softlevel1_hdl, 1, softlevel1,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1861
		"softlevel1", NULL, NULL); /* XXX to be moved later */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1862
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1863
	PRM_POINT("startup_end() done");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1864
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1865
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1866
extern char hw_serial[];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1867
char *_hs1107 = hw_serial;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1868
ulong_t  _bdhs34;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1869
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1870
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1871
post_startup(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1872
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1873
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1874
	 * Set the system wide, processor-specific flags to be passed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1875
	 * to userland via the aux vector for performance hints and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1876
	 * instruction set extensions.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1877
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1878
	bind_hwcap();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1879
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1880
	/*
437
76c202dd62bf PSARC 2005/483 SMBIOS Support for Solaris
mws
parents: 423
diff changeset
  1881
	 * Load the System Management BIOS into the global ksmbios handle,
76c202dd62bf PSARC 2005/483 SMBIOS Support for Solaris
mws
parents: 423
diff changeset
  1882
	 * if an SMBIOS is present on this system.
76c202dd62bf PSARC 2005/483 SMBIOS Support for Solaris
mws
parents: 423
diff changeset
  1883
	 */
76c202dd62bf PSARC 2005/483 SMBIOS Support for Solaris
mws
parents: 423
diff changeset
  1884
	ksmbios = smbios_open(NULL, SMB_VERSION, ksmbios_flags, NULL);
76c202dd62bf PSARC 2005/483 SMBIOS Support for Solaris
mws
parents: 423
diff changeset
  1885
76c202dd62bf PSARC 2005/483 SMBIOS Support for Solaris
mws
parents: 423
diff changeset
  1886
	/*
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1887
	 * Startup memory scrubber.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1888
	 */
437
76c202dd62bf PSARC 2005/483 SMBIOS Support for Solaris
mws
parents: 423
diff changeset
  1889
	memscrub_init();
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1890
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1891
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1892
	 * Perform forceloading tasks for /etc/system.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1893
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1894
	(void) mod_sysctl(SYS_FORCELOAD, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1895
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1896
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1897
	 * ON4.0: Force /proc module in until clock interrupt handle fixed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1898
	 * ON4.0: This must be fixed or restated in /etc/systems.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1899
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1900
	(void) modload("fs", "procfs");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1901
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1902
#if defined(__i386)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1903
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1904
	 * Check for required functional Floating Point hardware,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1905
	 * unless FP hardware explicitly disabled.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1906
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1907
	if (fpu_exists && (fpu_pentium_fdivbug || fp_kind == FP_NO))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1908
		halt("No working FP hardware found");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1909
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1910
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1911
	maxmem = freemem;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1912
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1913
	add_cpunode2devtree(CPU->cpu_id, CPU->cpu_m.mcpu_cpi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1914
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1915
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1916
	 * Perform the formal initialization of the boot chip,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1917
	 * and associate the boot cpu with it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1918
	 * This must be done after the cpu node for CPU has been
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1919
	 * added to the device tree, when the necessary probing to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1920
	 * know the chip type and chip "id" is performed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1921
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1922
	chip_cpu_init(CPU);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1923
	chip_cpu_assign(CPU);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1924
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1925
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1926
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1927
pp_in_ramdisk(page_t *pp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1928
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1929
	extern uint64_t ramdisk_start, ramdisk_end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1930
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1931
	return ((pp->p_pagenum >= btop(ramdisk_start)) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1932
	    (pp->p_pagenum < btopr(ramdisk_end)));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1933
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1934
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1935
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1936
release_bootstrap(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1937
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1938
	int root_is_ramdisk;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1939
	pfn_t pfn;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1940
	page_t *pp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1941
	extern void kobj_boot_unmountroot(void);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1942
	extern dev_t rootdev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1943
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1944
	/* unmount boot ramdisk and release kmem usage */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1945
	kobj_boot_unmountroot();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1946
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1947
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1948
	 * We're finished using the boot loader so free its pages.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1949
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1950
	PRM_POINT("Unmapping lower boot pages");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1951
	clear_boot_mappings(0, kernelbase);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1952
#if defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1953
	PRM_POINT("Unmapping upper boot pages");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1954
	clear_boot_mappings(BOOT_DOUBLEMAP_BASE,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1955
	    BOOT_DOUBLEMAP_BASE + BOOT_DOUBLEMAP_SIZE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1956
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1957
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1958
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1959
	 * If root isn't on ramdisk, destroy the hardcoded
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1960
	 * ramdisk node now and release the memory. Else,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1961
	 * ramdisk memory is kept in rd_pages.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1962
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1963
	root_is_ramdisk = (getmajor(rootdev) == ddi_name_to_major("ramdisk"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1964
	if (!root_is_ramdisk) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1965
		dev_info_t *dip = ddi_find_devinfo("ramdisk", -1, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1966
		ASSERT(dip && ddi_get_parent(dip) == ddi_root_node());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1967
		ndi_rele_devi(dip);	/* held from ddi_find_devinfo */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1968
		(void) ddi_remove_child(dip, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1969
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1970
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1971
	PRM_POINT("Releasing boot pages");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1972
	while (bootpages) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1973
		pp = bootpages;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1974
		bootpages = pp->p_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1975
		if (root_is_ramdisk && pp_in_ramdisk(pp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1976
			pp->p_next = rd_pages;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1977
			rd_pages = pp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1978
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1979
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1980
		pp->p_next = (struct page *)0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1981
		page_free(pp, 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1982
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1983
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1984
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1985
	 * Find 1 page below 1 MB so that other processors can boot up.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1986
	 * Make sure it has a kernel VA as well as a 1:1 mapping.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1987
	 * We should have just free'd one up.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1988
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1989
	if (use_mp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1990
		for (pfn = 1; pfn < btop(1*1024*1024); pfn++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1991
			if (page_numtopp_alloc(pfn) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1992
				continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1993
			rm_platter_va = i86devmap(pfn, 1,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1994
			    PROT_READ | PROT_WRITE | PROT_EXEC);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1995
			rm_platter_pa = ptob(pfn);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1996
			hat_devload(kas.a_hat,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1997
			    (caddr_t)(uintptr_t)rm_platter_pa, MMU_PAGESIZE,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1998
			    pfn, PROT_READ | PROT_WRITE | PROT_EXEC,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1999
			    HAT_LOAD_NOCONSIST);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2000
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2001
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2002
		if (pfn == btop(1*1024*1024))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2003
			panic("No page available for starting "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2004
			    "other processors");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2005
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2006
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2007
#if defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2008
	PRM_POINT("Returning boot's VA space to kernel heap");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2009
	if (kmem_setaside != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2010
		vmem_free(heap_arena, kmem_setaside, BOOT_DOUBLEMAP_SIZE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2011
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2012
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2013
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2014
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2015
 * Initialize the platform-specific parts of a page_t.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2016
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2017
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2018
add_physmem_cb(page_t *pp, pfn_t pnum)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2019
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2020
	pp->p_pagenum = pnum;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2021
	pp->p_mapping = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2022
	pp->p_embed = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2023
	pp->p_share = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2024
	pp->p_mlentry = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2025
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2026
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2027
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2028
 * kphysm_init() initializes physical memory.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2029
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2030
static pgcnt_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2031
kphysm_init(
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2032
	page_t *inpp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2033
	struct memseg *memsegp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2034
	pgcnt_t start,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2035
	pgcnt_t npages)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2036
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2037
	struct memlist	*pmem;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2038
	struct memseg	*cur_memseg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2039
	struct memseg	**memsegpp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2040
	pfn_t		base_pfn;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2041
	pgcnt_t		num;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2042
	pgcnt_t		total_skipped = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2043
	pgcnt_t		skipping = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2044
	pgcnt_t		pages_done = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2045
	pgcnt_t		largepgcnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2046
	uint64_t	addr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2047
	uint64_t	size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2048
	page_t		*pp = inpp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2049
	int		dobreak = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2050
	extern pfn_t	ddiphysmin;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2051
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2052
	ASSERT(page_hash != NULL && page_hashsz != 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2053
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2054
	for (cur_memseg = memsegp; cur_memseg->pages != NULL; cur_memseg++);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2055
	ASSERT(cur_memseg == memsegp || start > 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2056
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2057
	for (pmem = phys_avail; pmem && npages; pmem = pmem->next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2058
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2059
		 * In a 32 bit kernel can't use higher memory if we're
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2060
		 * not booting in PAE mode. This check takes care of that.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2061
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2062
		addr = pmem->address;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2063
		size = pmem->size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2064
		if (btop(addr) > physmax)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2065
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2066
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2067
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2068
		 * align addr and size - they may not be at page boundaries
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2069
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2070
		if ((addr & MMU_PAGEOFFSET) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2071
			addr += MMU_PAGEOFFSET;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2072
			addr &= ~(uint64_t)MMU_PAGEOFFSET;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2073
			size -= addr - pmem->address;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2074
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2075
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2076
		/* only process pages below physmax */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2077
		if (btop(addr + size) > physmax)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2078
			size = ptob(physmax - btop(addr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2079
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2080
		num = btop(size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2081
		if (num == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2082
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2083
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2084
		if (total_skipped < start) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2085
			if (start - total_skipped > num) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2086
				total_skipped += num;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2087
				continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2088
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2089
			skipping = start - total_skipped;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2090
			num -= skipping;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2091
			addr += (MMU_PAGESIZE * skipping);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2092
			total_skipped = start;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2093
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2094
		if (num == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2095
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2096
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2097
		if (num > npages)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2098
			num = npages;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2099
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2100
		npages -= num;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2101
		pages_done += num;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2102
		base_pfn = btop(addr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2103
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2104
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2105
		 * If the caller didn't provide space for the page
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2106
		 * structures, carve them out of the memseg they will
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2107
		 * represent.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2108
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2109
		if (pp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2110
			pgcnt_t pp_pgs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2111
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2112
			if (num <= 1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2113
				continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2114
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2115
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2116
			 * Compute how many of the pages we need to use for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2117
			 * page_ts
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2118
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2119
			pp_pgs = (num * sizeof (page_t)) / MMU_PAGESIZE + 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2120
			while (mmu_ptob(pp_pgs - 1) / sizeof (page_t) >=
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2121
			    num - pp_pgs + 1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2122
				--pp_pgs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2123
			PRM_DEBUG(pp_pgs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2124
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2125
			pp = vmem_alloc(heap_arena, mmu_ptob(pp_pgs),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2126
			    VM_NOSLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2127
			if (pp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2128
				cmn_err(CE_WARN, "Unable to add %ld pages to "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2129
				    "the system.", num);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2130
				continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2131
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2132
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2133
			hat_devload(kas.a_hat, (void *)pp, mmu_ptob(pp_pgs),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2134
			    base_pfn, PROT_READ | PROT_WRITE | HAT_UNORDERED_OK,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2135
			    HAT_LOAD | HAT_LOAD_LOCK | HAT_LOAD_NOCONSIST);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2136
			bzero(pp, mmu_ptob(pp_pgs));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2137
			num -= pp_pgs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2138
			base_pfn += pp_pgs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2139
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2140
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2141
		if (prom_debug)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2142
			prom_printf("MEMSEG addr=0x%" PRIx64
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2143
			    " pgs=0x%lx pfn 0x%lx-0x%lx\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2144
			    addr, num, base_pfn, base_pfn + num);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2145
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2146
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2147
		 * drop pages below ddiphysmin to simplify ddi memory
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2148
		 * allocation with non-zero addr_lo requests.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2149
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2150
		if (base_pfn < ddiphysmin) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2151
			if (base_pfn + num <= ddiphysmin) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2152
				/* drop entire range below ddiphysmin */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2153
				continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2154
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2155
			/* adjust range to ddiphysmin */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2156
			pp += (ddiphysmin - base_pfn);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2157
			num -= (ddiphysmin - base_pfn);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2158
			base_pfn = ddiphysmin;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2159
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2160
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2161
		 * Build the memsegs entry
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2162
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2163
		cur_memseg->pages = pp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2164
		cur_memseg->epages = pp + num;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2165
		cur_memseg->pages_base = base_pfn;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2166
		cur_memseg->pages_end = base_pfn + num;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2167
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2168
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2169
		 * insert in memseg list in decreasing pfn range order.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2170
		 * Low memory is typically more fragmented such that this
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2171
		 * ordering keeps the larger ranges at the front of the list
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2172
		 * for code that searches memseg.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2173
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2174
		memsegpp = &memsegs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2175
		for (;;) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2176
			if (*memsegpp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2177
				/* empty memsegs */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2178
				memsegs = cur_memseg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2179
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2180
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2181
			/* check for continuity with start of memsegpp */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2182
			if (cur_memseg->pages_end == (*memsegpp)->pages_base) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2183
				if (cur_memseg->epages == (*memsegpp)->pages) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2184
					/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2185
					 * contiguous pfn and page_t's. Merge
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2186
					 * cur_memseg into *memsegpp. Drop
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2187
					 * cur_memseg
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2188
					 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2189
					(*memsegpp)->pages_base =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2190
					    cur_memseg->pages_base;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2191
					(*memsegpp)->pages =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2192
					    cur_memseg->pages;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2193
					/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2194
					 * check if contiguous with the end of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2195
					 * the next memseg.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2196
					 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2197
					if ((*memsegpp)->next &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2198
					    ((*memsegpp)->pages_base ==
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2199
					    (*memsegpp)->next->pages_end)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2200
						cur_memseg = *memsegpp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2201
						memsegpp = &((*memsegpp)->next);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2202
						dobreak = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2203
					} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2204
						break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2205
					}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2206
				} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2207
					/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2208
					 * contiguous pfn but not page_t's.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2209
					 * drop last pfn/page_t in cur_memseg
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2210
					 * to prevent creation of large pages
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2211
					 * with noncontiguous page_t's if not
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2212
					 * aligned to largest page boundary.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2213
					 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2214
					largepgcnt = page_get_pagecnt(
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2215
					    page_num_pagesizes() - 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2216
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2217
					if (cur_memseg->pages_end &
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2218
					    (largepgcnt - 1)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2219
						num--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2220
						cur_memseg->epages--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2221
						cur_memseg->pages_end--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2222
					}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2223
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2224
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2225
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2226
			/* check for continuity with end of memsegpp */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2227
			if (cur_memseg->pages_base == (*memsegpp)->pages_end) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2228
				if (cur_memseg->pages == (*memsegpp)->epages) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2229
					/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2230
					 * contiguous pfn and page_t's. Merge
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2231
					 * cur_memseg into *memsegpp. Drop
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2232
					 * cur_memseg.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2233
					 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2234
					if (dobreak) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2235
						/* merge previously done */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2236
						cur_memseg->pages =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2237
						    (*memsegpp)->pages;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2238
						cur_memseg->pages_base =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2239
						    (*memsegpp)->pages_base;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2240
						cur_memseg->next =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2241
						    (*memsegpp)->next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2242
					} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2243
						(*memsegpp)->pages_end =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2244
						    cur_memseg->pages_end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2245
						(*memsegpp)->epages =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2246
						    cur_memseg->epages;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2247
					}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2248
					break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2249
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2250
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2251
				 * contiguous pfn but not page_t's.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2252
				 * drop first pfn/page_t in cur_memseg
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2253
				 * to prevent creation of large pages
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2254
				 * with noncontiguous page_t's if not
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2255
				 * aligned to largest page boundary.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2256
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2257
				largepgcnt = page_get_pagecnt(
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2258
				    page_num_pagesizes() - 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2259
				if (base_pfn & (largepgcnt - 1)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2260
					num--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2261
					base_pfn++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2262
					cur_memseg->pages++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2263
					cur_memseg->pages_base++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2264
					pp = cur_memseg->pages;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2265
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2266
				if (dobreak)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2267
					break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2268
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2269
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2270
			if (cur_memseg->pages_base >=
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2271
			    (*memsegpp)->pages_end) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2272
				cur_memseg->next = *memsegpp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2273
				*memsegpp = cur_memseg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2274
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2275
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2276
			if ((*memsegpp)->next == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2277
				cur_memseg->next = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2278
				(*memsegpp)->next = cur_memseg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2279
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2280
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2281
			memsegpp = &((*memsegpp)->next);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2282
			ASSERT(*memsegpp != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2283
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2284
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2285
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2286
		 * add_physmem() initializes the PSM part of the page
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2287
		 * struct by calling the PSM back with add_physmem_cb().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2288
		 * In addition it coalesces pages into larger pages as
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2289
		 * it initializes them.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2290
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2291
		add_physmem(pp, num, base_pfn);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2292
		cur_memseg++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2293
		availrmem_initial += num;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2294
		availrmem += num;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2295
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2296
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2297
		 * If the caller provided the page frames to us, then
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2298
		 * advance in that list.  Otherwise, prepare to allocate
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2299
		 * our own page frames for the next memseg.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2300
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2301
		pp = (inpp == NULL) ? NULL : pp + num;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2302
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2303
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2304
	PRM_DEBUG(availrmem_initial);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2305
	PRM_DEBUG(availrmem);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2306
	PRM_DEBUG(freemem);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2307
	build_pfn_hash();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2308
	return (pages_done);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2309
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2310
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2311
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2312
 * Kernel VM initialization.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2313
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2314
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2315
kvm_init(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2316
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2317
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2318
	extern void _start();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2319
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2320
	ASSERT((caddr_t)_start == s_text);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2321
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2322
	ASSERT((((uintptr_t)s_text) & MMU_PAGEOFFSET) == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2323
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2324
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2325
	 * Put the kernel segments in kernel address space.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2326
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2327
	rw_enter(&kas.a_lock, RW_WRITER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2328
	as_avlinit(&kas);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2329
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2330
	(void) seg_attach(&kas, s_text, e_moddata - s_text, &ktextseg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2331
	(void) segkmem_create(&ktextseg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2332
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2333
	(void) seg_attach(&kas, (caddr_t)valloc_base, valloc_sz, &kvalloc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2334
	(void) segkmem_create(&kvalloc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2335
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2336
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2337
	 * We're about to map out /boot.  This is the beginning of the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2338
	 * system resource management transition. We can no longer
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2339
	 * call into /boot for I/O or memory allocations.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2340
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2341
	 * XX64 - Is this still correct with kernelheap_extend() being called
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2342
	 * later than this????
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2343
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2344
	(void) seg_attach(&kas, final_kernelheap,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2345
	    ekernelheap - final_kernelheap, &kvseg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2346
	(void) segkmem_create(&kvseg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2347
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2348
#if defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2349
	(void) seg_attach(&kas, (caddr_t)core_base, core_size, &kvseg_core);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2350
	(void) segkmem_create(&kvseg_core);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2351
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2352
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2353
	(void) seg_attach(&kas, (caddr_t)SEGDEBUGBASE, (size_t)SEGDEBUGSIZE,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2354
	    &kdebugseg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2355
	(void) segkmem_create(&kdebugseg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2356
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2357
	rw_exit(&kas.a_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2358
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2359
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2360
	 * Ensure that the red zone at kernelbase is never accessible.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2361
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2362
	(void) as_setprot(&kas, (caddr_t)kernelbase, KERNEL_REDZONE_SIZE, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2363
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2364
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2365
	 * Make the text writable so that it can be hot patched by DTrace.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2366
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2367
	(void) as_setprot(&kas, s_text, e_modtext - s_text,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2368
	    PROT_READ | PROT_WRITE | PROT_EXEC);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2369
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2370
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2371
	 * Make data writable until end.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2372
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2373
	(void) as_setprot(&kas, s_data, e_moddata - s_data,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2374
	    PROT_READ | PROT_WRITE | PROT_EXEC);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2375
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2376
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2377
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2378
 * These are MTTR registers supported by P6
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2379
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2380
static struct	mtrrvar	mtrrphys_arr[MAX_MTRRVAR];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2381
static uint64_t mtrr64k, mtrr16k1, mtrr16k2;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2382
static uint64_t mtrr4k1, mtrr4k2, mtrr4k3;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2383
static uint64_t mtrr4k4, mtrr4k5, mtrr4k6;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2384
static uint64_t mtrr4k7, mtrr4k8, mtrrcap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2385
uint64_t mtrrdef, pat_attr_reg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2386
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2387
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2388
 * Disable reprogramming of MTRRs by default.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2389
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2390
int	enable_relaxed_mtrr = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2391
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2392
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2393
 * These must serve for Pentium, Pentium Pro (P6/Pentium II/Pentium III)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2394
 * and Pentium 4, and yes, they are named 0, 1, 2, 4, 3 in ascending
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2395
 * address order (starting from 0x400).  The Pentium 4 only implements
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2396
 * 4 sets, and while they are named 0-3 in the doc, the corresponding
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2397
 * names for P6 are 0,1,2,4.  So define these arrays in address order
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2398
 * so that they work for both pre-Pentium4 and Pentium 4 processors.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2399
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2400
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2401
static uint_t	mci_ctl[] = {REG_MC0_CTL, REG_MC1_CTL, REG_MC2_CTL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2402
		    REG_MC4_CTL, REG_MC3_CTL};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2403
static uint_t	mci_status[] = {REG_MC0_STATUS, REG_MC1_STATUS, REG_MC2_STATUS,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2404
		    REG_MC4_STATUS, REG_MC3_STATUS};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2405
static uint_t	mci_addr[] = {REG_MC0_ADDR, REG_MC1_ADDR, REG_MC2_ADDR,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2406
		    REG_MC4_ADDR, REG_MC3_ADDR};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2407
static int	mca_cnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2408
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2409
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2410
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2411
setup_mca()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2412
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2413
	int 		i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2414
	uint64_t	allzeros;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2415
	uint64_t	allones;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2416
	uint64_t	mca_cap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2417
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2418
	if (!(x86_feature & X86_MCA))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2419
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2420
	(void) rdmsr(REG_MCG_CAP, &mca_cap);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2421
	allones = 0xffffffffffffffffULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2422
	if (mca_cap & MCG_CAP_CTL_P)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2423
		(void) wrmsr(REG_MCG_CTL, &allones);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2424
	mca_cnt = mca_cap & MCG_CAP_COUNT_MASK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2425
	if (mca_cnt > P6_MCG_CAP_COUNT)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2426
		mca_cnt = P6_MCG_CAP_COUNT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2427
	for (i = 1; i < mca_cnt; i++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2428
		(void) wrmsr(mci_ctl[i], &allones);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2429
	allzeros = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2430
	for (i = 0; i < mca_cnt; i++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2431
		(void) wrmsr(mci_status[i], &allzeros);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2432
	setcr4(getcr4() | CR4_MCE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2433
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2434
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2435
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2436
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2437
mca_exception(struct regs *rp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2438
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2439
	uint64_t	status, addr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2440
	uint64_t	allzeros;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2441
	uint64_t	buf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2442
	int		i, ret = 1, errcode, mserrcode;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2443
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2444
	allzeros = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2445
	(void) rdmsr(REG_MCG_STATUS, &buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2446
	status = buf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2447
	if (status & MCG_STATUS_RIPV)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2448
		ret = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2449
	if (status & MCG_STATUS_EIPV)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2450
		cmn_err(CE_WARN, "MCE at 0x%lx", rp->r_pc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2451
	(void) wrmsr(REG_MCG_STATUS, &allzeros);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2452
	for (i = 0; i < mca_cnt; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2453
		(void) rdmsr(mci_status[i], &buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2454
		status = buf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2455
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2456
		 * If status register not valid skip this bank
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2457
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2458
		if (!(status & MCI_STATUS_VAL))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2459
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2460
		errcode = status & MCI_STATUS_ERRCODE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2461
		mserrcode = (status  >> MSERRCODE_SHFT) & MCI_STATUS_ERRCODE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2462
		if (status & MCI_STATUS_ADDRV) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2463
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2464
			 * If mci_addr contains the address where
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2465
			 * error occurred, display the address
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2466
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2467
			(void) rdmsr(mci_addr[i], &buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2468
			addr = buf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2469
			cmn_err(CE_WARN, "MCE: Bank %d: error code 0x%x:"\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2470
			    "addr = 0x%" PRIx64 ", model errcode = 0x%x", i,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2471
			    errcode, addr, mserrcode);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2472
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2473
			cmn_err(CE_WARN,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2474
			    "MCE: Bank %d: error code 0x%x, mserrcode = 0x%x",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2475
			    i, errcode, mserrcode);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2476
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2477
		(void) wrmsr(mci_status[i], &allzeros);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2478
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2479
	return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2480
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2481
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2482
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2483
setup_mtrr()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2484
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2485
	int i, ecx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2486
	int vcnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2487
	struct	mtrrvar	*mtrrphys;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2488
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2489
	if (!(x86_feature & X86_MTRR))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2490
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2491
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2492
	(void) rdmsr(REG_MTRRCAP, &mtrrcap);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2493
	(void) rdmsr(REG_MTRRDEF, &mtrrdef);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2494
	if (mtrrcap & MTRRCAP_FIX) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2495
		(void) rdmsr(REG_MTRR64K, &mtrr64k);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2496
		(void) rdmsr(REG_MTRR16K1, &mtrr16k1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2497
		(void) rdmsr(REG_MTRR16K2, &mtrr16k2);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2498
		(void) rdmsr(REG_MTRR4K1, &mtrr4k1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2499
		(void) rdmsr(REG_MTRR4K2, &mtrr4k2);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2500
		(void) rdmsr(REG_MTRR4K3, &mtrr4k3);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2501
		(void) rdmsr(REG_MTRR4K4, &mtrr4k4);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2502
		(void) rdmsr(REG_MTRR4K5, &mtrr4k5);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2503
		(void) rdmsr(REG_MTRR4K6, &mtrr4k6);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2504
		(void) rdmsr(REG_MTRR4K7, &mtrr4k7);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2505
		(void) rdmsr(REG_MTRR4K8, &mtrr4k8);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2506
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2507
	if ((vcnt = (mtrrcap & MTRRCAP_VCNTMASK)) > MAX_MTRRVAR)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2508
		vcnt = MAX_MTRRVAR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2509
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2510
	for (i = 0, ecx = REG_MTRRPHYSBASE0, mtrrphys = mtrrphys_arr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2511
		i <  vcnt - 1; i++, ecx += 2, mtrrphys++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2512
		(void) rdmsr(ecx, &mtrrphys->mtrrphys_base);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2513
		(void) rdmsr(ecx + 1, &mtrrphys->mtrrphys_mask);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2514
		if ((x86_feature & X86_PAT) && enable_relaxed_mtrr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2515
			mtrrphys->mtrrphys_mask &= ~MTRRPHYSMASK_V;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2516
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2517
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2518
	if (x86_feature & X86_PAT) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2519
		if (enable_relaxed_mtrr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2520
			mtrrdef = MTRR_TYPE_WB|MTRRDEF_FE|MTRRDEF_E;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2521
		pat_attr_reg = PAT_DEFAULT_ATTRIBUTE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2522
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2523
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2524
	mtrr_sync();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2525
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2526
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2527
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2528
 * Sync current cpu mtrr with the incore copy of mtrr.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2529
 * This function has to be invoked with interrupts disabled
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2530
 * Currently we do not capture other cpu's. This is invoked on cpu0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2531
 * just after reading /etc/system.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2532
 * On other cpu's its invoked from mp_startup().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2533
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2534
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2535
mtrr_sync()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2536
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2537
	uint64_t my_mtrrdef;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2538
	uint_t	crvalue, cr0_orig;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2539
	int	vcnt, i, ecx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2540
	struct	mtrrvar	*mtrrphys;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2541
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2542
	cr0_orig = crvalue = getcr0();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2543
	crvalue |= CR0_CD;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2544
	crvalue &= ~CR0_NW;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2545
	setcr0(crvalue);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2546
	invalidate_cache();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2547
	setcr3(getcr3());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2548
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2549
	if (x86_feature & X86_PAT) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2550
		(void) wrmsr(REG_MTRRPAT, &pat_attr_reg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2551
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2552
	(void) rdmsr(REG_MTRRDEF, &my_mtrrdef);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2553
	my_mtrrdef &= ~MTRRDEF_E;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2554
	(void) wrmsr(REG_MTRRDEF, &my_mtrrdef);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2555
	if (mtrrcap & MTRRCAP_FIX) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2556
		(void) wrmsr(REG_MTRR64K, &mtrr64k);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2557
		(void) wrmsr(REG_MTRR16K1, &mtrr16k1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2558
		(void) wrmsr(REG_MTRR16K2, &mtrr16k2);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2559
		(void) wrmsr(REG_MTRR4K1, &mtrr4k1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2560
		(void) wrmsr(REG_MTRR4K2, &mtrr4k2);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2561
		(void) wrmsr(REG_MTRR4K3, &mtrr4k3);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2562
		(void) wrmsr(REG_MTRR4K4, &mtrr4k4);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2563
		(void) wrmsr(REG_MTRR4K5, &mtrr4k5);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2564
		(void) wrmsr(REG_MTRR4K6, &mtrr4k6);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2565
		(void) wrmsr(REG_MTRR4K7, &mtrr4k7);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2566
		(void) wrmsr(REG_MTRR4K8, &mtrr4k8);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2567
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2568
	if ((vcnt = (mtrrcap & MTRRCAP_VCNTMASK)) > MAX_MTRRVAR)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2569
		vcnt = MAX_MTRRVAR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2570
	for (i = 0, ecx = REG_MTRRPHYSBASE0, mtrrphys = mtrrphys_arr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2571
		i <  vcnt - 1; i++, ecx += 2, mtrrphys++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2572
		(void) wrmsr(ecx, &mtrrphys->mtrrphys_base);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2573
		(void) wrmsr(ecx + 1, &mtrrphys->mtrrphys_mask);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2574
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2575
	(void) wrmsr(REG_MTRRDEF, &mtrrdef);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2576
	setcr3(getcr3());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2577
	invalidate_cache();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2578
	setcr0(cr0_orig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2579
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2580
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2581
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2582
 * resync mtrr so that BIOS is happy. Called from mdboot
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2583
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2584
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2585
mtrr_resync()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2586
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2587
	if ((x86_feature & X86_PAT) && enable_relaxed_mtrr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2588
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2589
		 * We could have changed the default mtrr definition.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2590
		 * Put it back to uncached which is what it is at power on
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2591
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2592
		mtrrdef = MTRR_TYPE_UC|MTRRDEF_FE|MTRRDEF_E;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2593
		mtrr_sync();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2594
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2595
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2596
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2597
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2598
get_system_configuration()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2599
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2600
	char	prop[32];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2601
	u_longlong_t nodes_ll, cpus_pernode_ll, lvalue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2602
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2603
	if (((BOP_GETPROPLEN(bootops, "nodes") > sizeof (prop)) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2604
		(BOP_GETPROP(bootops, "nodes", prop) < 0) 	||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2605
		(kobj_getvalue(prop, &nodes_ll) == -1) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2606
		(nodes_ll > MAXNODES))			   ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2607
	    ((BOP_GETPROPLEN(bootops, "cpus_pernode") > sizeof (prop)) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2608
		(BOP_GETPROP(bootops, "cpus_pernode", prop) < 0) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2609
		(kobj_getvalue(prop, &cpus_pernode_ll) == -1))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2610
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2611
		system_hardware.hd_nodes = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2612
		system_hardware.hd_cpus_per_node = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2613
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2614
		system_hardware.hd_nodes = (int)nodes_ll;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2615
		system_hardware.hd_cpus_per_node = (int)cpus_pernode_ll;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2616
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2617
	if ((BOP_GETPROPLEN(bootops, "kernelbase") > sizeof (prop)) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2618
		(BOP_GETPROP(bootops, "kernelbase", prop) < 0) 	||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2619
		(kobj_getvalue(prop, &lvalue) == -1))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2620
			eprom_kernelbase = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2621
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2622
			eprom_kernelbase = (uintptr_t)lvalue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2623
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2624
	if ((BOP_GETPROPLEN(bootops, "segmapsize") > sizeof (prop)) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2625
	    (BOP_GETPROP(bootops, "segmapsize", prop) < 0) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2626
	    (kobj_getvalue(prop, &lvalue) == -1)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2627
		segmapsize = SEGMAPDEFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2628
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2629
		segmapsize = (uintptr_t)lvalue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2630
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2631
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2632
	if ((BOP_GETPROPLEN(bootops, "segmapfreelists") > sizeof (prop)) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2633
	    (BOP_GETPROP(bootops, "segmapfreelists", prop) < 0) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2634
	    (kobj_getvalue(prop, &lvalue) == -1)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2635
		segmapfreelists = 0;	/* use segmap driver default */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2636
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2637
		segmapfreelists = (int)lvalue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2638
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2639
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2640
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2641
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2642
 * Add to a memory list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2643
 * start = start of new memory segment
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2644
 * len = length of new memory segment in bytes
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2645
 * new = pointer to a new struct memlist
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2646
 * memlistp = memory list to which to add segment.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2647
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2648
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2649
memlist_add(
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2650
	uint64_t start,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2651
	uint64_t len,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2652
	struct memlist *new,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2653
	struct memlist **memlistp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2654
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2655
	struct memlist *cur;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2656
	uint64_t end = start + len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2657
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2658
	new->address = start;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2659
	new->size = len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2660
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2661
	cur = *memlistp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2662
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2663
	while (cur) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2664
		if (cur->address >= end) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2665
			new->next = cur;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2666
			*memlistp = new;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2667
			new->prev = cur->prev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2668
			cur->prev = new;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2669
			return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2670
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2671
		ASSERT(cur->address + cur->size <= start);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2672
		if (cur->next == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2673
			cur->next = new;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2674
			new->prev = cur;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2675
			new->next = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2676
			return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2677
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2678
		memlistp = &cur->next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2679
		cur = cur->next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2680
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2681
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2682
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2683
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2684
kobj_vmem_init(vmem_t **text_arena, vmem_t **data_arena)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2685
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2686
	size_t tsize = e_modtext - modtext;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2687
	size_t dsize = e_moddata - moddata;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2688
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2689
	*text_arena = vmem_create("module_text", tsize ? modtext : NULL, tsize,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2690
	    1, segkmem_alloc, segkmem_free, heaptext_arena, 0, VM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2691
	*data_arena = vmem_create("module_data", dsize ? moddata : NULL, dsize,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2692
	    1, segkmem_alloc, segkmem_free, heap32_arena, 0, VM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2693
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2694
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2695
caddr_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2696
kobj_text_alloc(vmem_t *arena, size_t size)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2697
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2698
	return (vmem_alloc(arena, size, VM_SLEEP | VM_BESTFIT));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2699
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2700
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2701
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2702
caddr_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2703
kobj_texthole_alloc(caddr_t addr, size_t size)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2704
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2705
	panic("unexpected call to kobj_texthole_alloc()");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2706
	/*NOTREACHED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2707
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2708
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2709
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2710
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2711
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2712
kobj_texthole_free(caddr_t addr, size_t size)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2713
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2714
	panic("unexpected call to kobj_texthole_free()");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2715
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2716
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2717
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2718
 * This is called just after configure() in startup().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2719
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2720
 * The ISALIST concept is a bit hopeless on Intel, because
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2721
 * there's no guarantee of an ever-more-capable processor
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2722
 * given that various parts of the instruction set may appear
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2723
 * and disappear between different implementations.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2724
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2725
 * While it would be possible to correct it and even enhance
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2726
 * it somewhat, the explicit hardware capability bitmask allows
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2727
 * more flexibility.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2728
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2729
 * So, we just leave this alone.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2730
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2731
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2732
setx86isalist(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2733
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2734
	char *tp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2735
	size_t len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2736
	extern char *isa_list;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2737
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2738
#define	TBUFSIZE	1024
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2739
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2740
	tp = kmem_alloc(TBUFSIZE, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2741
	*tp = '\0';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2742
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2743
#if defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2744
	(void) strcpy(tp, "amd64 ");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2745
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2746
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2747
	switch (x86_vendor) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2748
	case X86_VENDOR_Intel:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2749
	case X86_VENDOR_AMD:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2750
	case X86_VENDOR_TM:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2751
		if (x86_feature & X86_CMOV) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2752
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2753
			 * Pentium Pro or later
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2754
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2755
			(void) strcat(tp, "pentium_pro");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2756
			(void) strcat(tp, x86_feature & X86_MMX ?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2757
			    "+mmx pentium_pro " : " ");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2758
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2759
		/*FALLTHROUGH*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2760
	case X86_VENDOR_Cyrix:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2761
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2762
		 * The Cyrix 6x86 does not have any Pentium features
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2763
		 * accessible while not at privilege level 0.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2764
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2765
		if (x86_feature & X86_CPUID) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2766
			(void) strcat(tp, "pentium");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2767
			(void) strcat(tp, x86_feature & X86_MMX ?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2768
			    "+mmx pentium " : " ");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2769
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2770
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2771
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2772
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2773
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2774
	(void) strcat(tp, "i486 i386 i86");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2775
	len = strlen(tp) + 1;   /* account for NULL at end of string */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2776
	isa_list = strcpy(kmem_alloc(len, KM_SLEEP), tp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2777
	kmem_free(tp, TBUFSIZE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2778
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2779
#undef TBUFSIZE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2780
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2781
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2782
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2783
#ifdef __amd64
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2784
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2785
void *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2786
device_arena_alloc(size_t size, int vm_flag)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2787
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2788
	return (vmem_alloc(device_arena, size, vm_flag));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2789
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2790
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2791
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2792
device_arena_free(void *vaddr, size_t size)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2793
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2794
	vmem_free(device_arena, vaddr, size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2795
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2796
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2797
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2798
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2799
void *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2800
device_arena_alloc(size_t size, int vm_flag)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2801
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2802
	caddr_t	vaddr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2803
	uintptr_t v;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2804
	size_t	start;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2805
	size_t	end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2806
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2807
	vaddr = vmem_alloc(heap_arena, size, vm_flag);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2808
	if (vaddr == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2809
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2810
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2811
	v = (uintptr_t)vaddr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2812
	ASSERT(v >= kernelbase);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2813
	ASSERT(v + size <= ptable_va);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2814
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2815
	start = btop(v - kernelbase);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2816
	end = btop(v + size - 1 - kernelbase);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2817
	ASSERT(start < toxic_bit_map_len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2818
	ASSERT(end < toxic_bit_map_len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2819
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2820
	while (start <= end) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2821
		BT_ATOMIC_SET(toxic_bit_map, start);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2822
		++start;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2823
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2824
	return (vaddr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2825
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2826
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2827
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2828
device_arena_free(void *vaddr, size_t size)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2829
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2830
	uintptr_t v = (uintptr_t)vaddr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2831
	size_t	start;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2832
	size_t	end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2833
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2834
	ASSERT(v >= kernelbase);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2835
	ASSERT(v + size <= ptable_va);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2836
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2837
	start = btop(v - kernelbase);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2838
	end = btop(v + size - 1 - kernelbase);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2839
	ASSERT(start < toxic_bit_map_len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2840
	ASSERT(end < toxic_bit_map_len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2841
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2842
	while (start <= end) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2843
		ASSERT(BT_TEST(toxic_bit_map, start) != 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2844
		BT_ATOMIC_CLEAR(toxic_bit_map, start);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2845
		++start;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2846
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2847
	vmem_free(heap_arena, vaddr, size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2848
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2849
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2850
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2851
 * returns 1st address in range that is in device arena, or NULL
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2852
 * if len is not NULL it returns the length of the toxic range
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2853
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2854
void *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2855
device_arena_contains(void *vaddr, size_t size, size_t *len)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2856
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2857
	uintptr_t v = (uintptr_t)vaddr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2858
	uintptr_t eaddr = v + size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2859
	size_t start;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2860
	size_t end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2861
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2862
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2863
	 * if called very early by kmdb, just return NULL
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2864
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2865
	if (toxic_bit_map == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2866
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2867
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2868
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2869
	 * First check if we're completely outside the bitmap range.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2870
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2871
	if (v >= ptable_va || eaddr < kernelbase)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2872
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2873
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2874
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2875
	 * Trim ends of search to look at only what the bitmap covers.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2876
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2877
	if (v < kernelbase)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2878
		v = kernelbase;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2879
	start = btop(v - kernelbase);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2880
	end = btop(eaddr - kernelbase);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2881
	if (end >= toxic_bit_map_len)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2882
		end = toxic_bit_map_len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2883
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2884
	if (bt_range(toxic_bit_map, &start, &end, end) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2885
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2886
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2887
	v = kernelbase + ptob(start);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2888
	if (len != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2889
		*len = ptob(end - start);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2890
	return ((void *)v);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2891
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2892
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2893
#endif