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