Sync with sys/i386/i386/machdep.c revision up to 1.354.

This commit is contained in:
KATO Takenori 1999-07-08 12:48:53 +00:00
parent 159f868e26
commit 65d65bc193
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=48681
2 changed files with 296 additions and 304 deletions

View File

@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
* $Id: machdep.c,v 1.123 1999/07/03 08:31:32 kato Exp $
* $Id: machdep.c,v 1.124 1999/07/05 08:52:54 msmith Exp $
*/
#include "apm.h"
@ -361,12 +361,14 @@ again:
nbuf = 30;
if( physmem > 1024)
nbuf += min((physmem - 1024) / 8, 2048);
if( physmem > 65536)
nbuf += (physmem - 65536) / 20;
}
nswbuf = max(min(nbuf/4, 64), 16);
nswbuf = max(min(nbuf/4, 256), 16);
valloc(swbuf, struct buf, nswbuf);
valloc(buf, struct buf, nbuf);
v = bufhashinit(v);
/*
* End of first pass, size has been calculated so allocate memory
@ -520,6 +522,9 @@ sendsig(catcher, sig, mask, code)
* Process has trashed its stack; give it an illegal
* instruction to halt it in its tracks.
*/
#ifdef DEBUG
printf("process %d has trashed its stack\n", p->p_pid);
#endif
SIGACTION(p, SIGILL) = SIG_DFL;
sig = sigmask(SIGILL);
p->p_sigignore &= ~sig;
@ -539,36 +544,50 @@ sendsig(catcher, sig, mask, code)
sig = p->p_sysent->sv_sigsize + 1;
}
sf.sf_signum = sig;
sf.sf_code = code;
sf.sf_scp = &fp->sf_sc;
sf.sf_scp = (register_t)&fp->sf_siginfo.si_sc;
if (p->p_sigacts->ps_siginfo & sigmask(sig)) {
/*
* Signal handler installed with SA_SIGINFO.
*/
sf.sf_arg2 = (register_t)&fp->sf_siginfo;
sf.sf_siginfo.si_signo = sig;
sf.sf_siginfo.si_code = code;
sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher;
} else {
/*
* Old FreeBSD-style arguments.
*/
sf.sf_arg2 = code;
sf.sf_ahu.sf_handler = catcher;
}
sf.sf_addr = (char *) regs->tf_err;
sf.sf_handler = catcher;
/* save scratch registers */
sf.sf_sc.sc_eax = regs->tf_eax;
sf.sf_sc.sc_ebx = regs->tf_ebx;
sf.sf_sc.sc_ecx = regs->tf_ecx;
sf.sf_sc.sc_edx = regs->tf_edx;
sf.sf_sc.sc_esi = regs->tf_esi;
sf.sf_sc.sc_edi = regs->tf_edi;
sf.sf_sc.sc_cs = regs->tf_cs;
sf.sf_sc.sc_ds = regs->tf_ds;
sf.sf_sc.sc_ss = regs->tf_ss;
sf.sf_sc.sc_es = regs->tf_es;
sf.sf_sc.sc_fs = regs->tf_fs;
sf.sf_sc.sc_isp = regs->tf_isp;
sf.sf_siginfo.si_sc.sc_eax = regs->tf_eax;
sf.sf_siginfo.si_sc.sc_ebx = regs->tf_ebx;
sf.sf_siginfo.si_sc.sc_ecx = regs->tf_ecx;
sf.sf_siginfo.si_sc.sc_edx = regs->tf_edx;
sf.sf_siginfo.si_sc.sc_esi = regs->tf_esi;
sf.sf_siginfo.si_sc.sc_edi = regs->tf_edi;
sf.sf_siginfo.si_sc.sc_cs = regs->tf_cs;
sf.sf_siginfo.si_sc.sc_ds = regs->tf_ds;
sf.sf_siginfo.si_sc.sc_ss = regs->tf_ss;
sf.sf_siginfo.si_sc.sc_es = regs->tf_es;
sf.sf_siginfo.si_sc.sc_fs = regs->tf_fs;
sf.sf_siginfo.si_sc.sc_isp = regs->tf_isp;
/*
* Build the signal context to be used by sigreturn.
*/
sf.sf_sc.sc_onstack = oonstack;
sf.sf_sc.sc_mask = mask;
sf.sf_sc.sc_sp = regs->tf_esp;
sf.sf_sc.sc_fp = regs->tf_ebp;
sf.sf_sc.sc_pc = regs->tf_eip;
sf.sf_sc.sc_ps = regs->tf_eflags;
sf.sf_sc.sc_trapno = regs->tf_trapno;
sf.sf_sc.sc_err = regs->tf_err;
sf.sf_siginfo.si_sc.sc_onstack = oonstack;
sf.sf_siginfo.si_sc.sc_mask = mask;
sf.sf_siginfo.si_sc.sc_sp = regs->tf_esp;
sf.sf_siginfo.si_sc.sc_fp = regs->tf_ebp;
sf.sf_siginfo.si_sc.sc_pc = regs->tf_eip;
sf.sf_siginfo.si_sc.sc_ps = regs->tf_eflags;
sf.sf_siginfo.si_sc.sc_trapno = regs->tf_trapno;
sf.sf_siginfo.si_sc.sc_err = regs->tf_err;
/*
* If we're a vm86 process, we want to save the segment registers.
@ -579,13 +598,13 @@ sendsig(catcher, sig, mask, code)
struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs;
struct vm86_kernel *vm86 = &p->p_addr->u_pcb.pcb_ext->ext_vm86;
sf.sf_sc.sc_gs = tf->tf_vm86_gs;
sf.sf_sc.sc_fs = tf->tf_vm86_fs;
sf.sf_sc.sc_es = tf->tf_vm86_es;
sf.sf_sc.sc_ds = tf->tf_vm86_ds;
sf.sf_siginfo.si_sc.sc_gs = tf->tf_vm86_gs;
sf.sf_siginfo.si_sc.sc_fs = tf->tf_vm86_fs;
sf.sf_siginfo.si_sc.sc_es = tf->tf_vm86_es;
sf.sf_siginfo.si_sc.sc_ds = tf->tf_vm86_ds;
if (vm86->vm86_has_vme == 0)
sf.sf_sc.sc_ps = (tf->tf_eflags & ~(PSL_VIF | PSL_VIP))
sf.sf_siginfo.si_sc.sc_ps = (tf->tf_eflags & ~(PSL_VIF | PSL_VIP))
| (vm86->vm86_eflags & (PSL_VIF | PSL_VIP));
/*
@ -651,7 +670,7 @@ sigreturn(p, uap)
*/
scp = uap->sigcntxp;
fp = (struct sigframe *)
((caddr_t)scp - offsetof(struct sigframe, sf_sc));
((caddr_t)scp - offsetof(struct sigframe, sf_siginfo.si_sc));
if (useracc((caddr_t)fp, sizeof (*fp), B_WRITE) == 0)
return(EFAULT);
@ -1131,16 +1150,15 @@ sdtossd(sd, ssd)
#define PHYSMAP_SIZE (2 * 8)
/*
* Populate the (physmap) array with base/length pairs describing the
* Populate the (physmap) array with base/bound pairs describing the
* available physical memory in the system, then test this memory and
* build the phys_avail array describing the actually-available memory.
*
* Total memory size may be constrained by the kernel environment variable
* hw.physmem or the compile-time define MAXMEM.
* If we cannot accurately determine the physical memory map, then use
* value from the 0xE801 call, and failing that, the RTC.
*
* If we cannot accurately determine the physical memory map, and the
* value from the RTC seems dubious, trust the value of hw.physmem/MAXMEM
* instead, but require a speculative probe of memory.
* Total memory size may be set by the kernel environment variable
* hw.physmem or the compile-time define MAXMEM.
*/
static void
getmemsize_pc98(int first)
@ -1358,13 +1376,11 @@ getmemsize(int first)
{
int i, physmap_idx, pa_indx;
u_int basemem, extmem;
int speculative_mprobe = FALSE;
struct vm86frame vmf;
struct vm86context vmc;
vm_offset_t pa, physmap[PHYSMAP_SIZE];
pt_entry_t pte;
u_int64_t AllowMem, MaxMem, sanity;
const char *cp, *ep;
const char *cp;
struct {
u_int64_t base;
u_int64_t length;
@ -1374,46 +1390,6 @@ getmemsize(int first)
bzero(&vmf, sizeof(struct vm86frame));
bzero(physmap, sizeof(physmap));
/*
* hw.maxmem is a size in bytes; we also allow k, m, and g suffixes
* for the appropriate modifiers.
* After this calculation, AllowMem is either 0 (no memory size cap)
* or the maximum memory size desired in bytes.
*/
AllowMem = 0;
if ((cp = getenv("hw.physmem")) != NULL) {
sanity = AllowMem = strtouq(cp, &ep, 0);
if ((ep != cp) && (*ep != 0)) {
switch(*ep) {
case 'g':
case 'G':
AllowMem <<= 10;
case 'm':
case 'M':
AllowMem <<= 10;
case 'k':
case 'K':
AllowMem <<= 10;
break;
default:
AllowMem = sanity = 0;
}
if (AllowMem < sanity)
AllowMem = 0;
}
if (AllowMem == 0)
printf("Warning: invalid memory limit '%s' specified\n", cp);
}
#ifdef MAXMEM
if (AllowMem == 0)
AllowMem = MAXMEM * (u_int64_t)1024;
#endif
if ((AllowMem != 0) && (boothowto & RB_VERBOSE))
printf("Physical memory use limited to %uk\n", (u_int)(AllowMem / 1024));
MaxMem = AllowMem;
if (AllowMem == 0)
AllowMem = (u_int64_t)1 << 32; /* 4GB limit imposed by 32-bit pmap */
/*
* Perform "base memory" related probes & setup
*/
@ -1500,18 +1476,11 @@ getmemsize(int first)
if (smap->length == 0)
goto next_run;
if (smap->base >= AllowMem) {
printf("%uk of memory above %uk ignored\n",
(u_int)(smap->length / 1024), (u_int)(AllowMem / 1024));
if (smap->base >= 0xffffffff) {
printf("%uK of memory above 4GB ignored\n",
(u_int)(smap->length / 1024));
goto next_run;
}
if ((smap->base + smap->length) >= AllowMem) {
printf("%uk region truncated to %uk to fit %uk limit\n",
(u_int)(smap->length / 1024),
(u_int)((AllowMem - smap->base) / 1024),
(u_int)(AllowMem / 1024));
smap->length = AllowMem - smap->base;
}
for (i = 0; i <= physmap_idx; i += 2) {
if (smap->base < physmap[i + 1]) {
@ -1538,71 +1507,48 @@ getmemsize(int first)
next_run:
} while (vmf.vmf_ebx != 0);
if (physmap[1] != 0)
goto physmap_done;
/*
* If we failed above, try memory map with INT 15:E801
*/
if (physmap[1] == 0) {
vmf.vmf_ax = 0xE801;
if (vm86_intcall(0x15, &vmf) == 0) {
extmem = vmf.vmf_cx + vmf.vmf_dx * 64;
} else {
vmf.vmf_ax = 0xE801;
if (vm86_intcall(0x15, &vmf) == 0) {
extmem = vmf.vmf_cx + vmf.vmf_dx * 64;
} else {
#if 0
vmf.vmf_ah = 0x88;
vm86_intcall(0x15, &vmf);
extmem = vmf.vmf_ax;
vmf.vmf_ah = 0x88;
vm86_intcall(0x15, &vmf);
extmem = vmf.vmf_ax;
#else
/*
* Prefer the RTC value for extended memory, or
* hw.physmem/MAXMEM overrides.
*/
if (MaxMem > (1024 * 1024)) { /* < 1MB is insane */
extmem = (MaxMem / 1024) - 1024;
} else {
extmem = rtcin(RTC_EXTLO) + (rtcin(RTC_EXTHI) << 8);
}
/*
* If the value from the RTC is >= 16M, there is a good
* chance that it's lying. Compaq systems never report
* more than 16M, and no system can honestly report more
* than 64M. We should end up here only on extremely
* old and broken systems. In any case, qualify the value
* that we've got here by actually checking for physical
* memory later on.
*/
if (extmem >= 16 * 1024)
speculative_mprobe = TRUE;
#endif
}
/*
* Special hack for chipsets that still remap the 384k hole when
* there's 16MB of memory - this really confuses people that
* are trying to use bus mastering ISA controllers with the
* "16MB limit"; they only have 16MB, but the remapping puts
* them beyond the limit.
*
* If extended memory is between 15-16MB (16-17MB phys address range),
* chop it to 15MB.
* Prefer the RTC value for extended memory.
*/
if ((extmem > 15 * 1024) && (extmem < 16 * 1024))
extmem = 15 * 1024;
physmap[0] = 0;
physmap[1] = basemem * 1024;
physmap_idx = 2;
physmap[physmap_idx] = 0x100000;
physmap[physmap_idx + 1] = physmap[physmap_idx] + extmem * 1024;
extmem = rtcin(RTC_EXTLO) + (rtcin(RTC_EXTHI) << 8);
#endif
}
/*
* Maxmem isn't the "maximum memory", it's one larger than the
* highest page of the physical address space. It should be
* called something like "Maxphyspage". We fiddle it again
* later based on the results of the memory test.
* Special hack for chipsets that still remap the 384k hole when
* there's 16MB of memory - this really confuses people that
* are trying to use bus mastering ISA controllers with the
* "16MB limit"; they only have 16MB, but the remapping puts
* them beyond the limit.
*
* If extended memory is between 15-16MB (16-17MB phys address range),
* chop it to 15MB.
*/
Maxmem = physmap[physmap_idx + 1] / PAGE_SIZE;
if ((extmem > 15 * 1024) && (extmem < 16 * 1024))
extmem = 15 * 1024;
physmap[0] = 0;
physmap[1] = basemem * 1024;
physmap_idx = 2;
physmap[physmap_idx] = 0x100000;
physmap[physmap_idx + 1] = physmap[physmap_idx] + extmem * 1024;
physmap_done:
/*
* Now, physmap contains a map of physical memory.
*/
@ -1614,6 +1560,63 @@ next_run:
/* look for the MP hardware - needed for apic addresses */
mp_probe();
#endif
/*
* Maxmem isn't the "maximum memory", it's one larger than the
* highest page of the physical address space. It should be
* called something like "Maxphyspage". We may adjust this
* based on ``hw.physmem'' and the results of the memory test.
*/
Maxmem = atop(physmap[physmap_idx + 1]);
#ifdef MAXMEM
Maxmem = MAXMEM / 4;
#endif
/*
* hw.maxmem is a size in bytes; we also allow k, m, and g suffixes
* for the appropriate modifiers. This overrides MAXMEM.
*/
if ((cp = getenv("hw.physmem")) != NULL) {
u_int64_t AllowMem, sanity;
const char *ep;
sanity = AllowMem = strtouq(cp, &ep, 0);
if ((ep != cp) && (*ep != 0)) {
switch(*ep) {
case 'g':
case 'G':
AllowMem <<= 10;
case 'm':
case 'M':
AllowMem <<= 10;
case 'k':
case 'K':
AllowMem <<= 10;
break;
default:
AllowMem = sanity = 0;
}
if (AllowMem < sanity)
AllowMem = 0;
}
if (AllowMem == 0)
printf("Ignoring invalid memory size of '%s'\n", cp);
else
Maxmem = atop(AllowMem);
}
if (atop(physmap[physmap_idx + 1]) != Maxmem &&
(boothowto & RB_VERBOSE))
printf("Physical memory use set to %uK\n", Maxmem * 4);
/*
* If Maxmem has been increased beyond what the system has detected,
* extend the last memory segment to the new limit.
*/
if (atop(physmap[physmap_idx + 1]) < Maxmem)
physmap[physmap_idx + 1] = ptoa(Maxmem);
/* call pmap initialization to make new kernel address space */
pmap_bootstrap(first, 0);
@ -1637,10 +1640,6 @@ next_run:
for (i = 0; i <= physmap_idx; i += 2) {
vm_offset_t end;
if (boothowto & RB_VERBOSE)
printf("Testing memory %uk to %uk\n",
(u_int)(physmap[i] / 1024),
(u_int)((physmap[i] + physmap[i+1]) / 1024));
end = ptoa(Maxmem);
if (physmap[i + 1] < end)
end = trunc_page(physmap[i + 1]);
@ -1719,9 +1718,6 @@ next_run:
*/
if (phys_avail[pa_indx] == pa) {
phys_avail[pa_indx] += PAGE_SIZE;
if (speculative_mprobe == TRUE &&
phys_avail[pa_indx] >= (64*1024*1024))
end += PAGE_SIZE;
} else {
pa_indx++;
if (pa_indx == PHYS_AVAIL_ARRAY_END) {

View File

@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
* $Id: machdep.c,v 1.123 1999/07/03 08:31:32 kato Exp $
* $Id: machdep.c,v 1.124 1999/07/05 08:52:54 msmith Exp $
*/
#include "apm.h"
@ -361,12 +361,14 @@ again:
nbuf = 30;
if( physmem > 1024)
nbuf += min((physmem - 1024) / 8, 2048);
if( physmem > 65536)
nbuf += (physmem - 65536) / 20;
}
nswbuf = max(min(nbuf/4, 64), 16);
nswbuf = max(min(nbuf/4, 256), 16);
valloc(swbuf, struct buf, nswbuf);
valloc(buf, struct buf, nbuf);
v = bufhashinit(v);
/*
* End of first pass, size has been calculated so allocate memory
@ -520,6 +522,9 @@ sendsig(catcher, sig, mask, code)
* Process has trashed its stack; give it an illegal
* instruction to halt it in its tracks.
*/
#ifdef DEBUG
printf("process %d has trashed its stack\n", p->p_pid);
#endif
SIGACTION(p, SIGILL) = SIG_DFL;
sig = sigmask(SIGILL);
p->p_sigignore &= ~sig;
@ -539,36 +544,50 @@ sendsig(catcher, sig, mask, code)
sig = p->p_sysent->sv_sigsize + 1;
}
sf.sf_signum = sig;
sf.sf_code = code;
sf.sf_scp = &fp->sf_sc;
sf.sf_scp = (register_t)&fp->sf_siginfo.si_sc;
if (p->p_sigacts->ps_siginfo & sigmask(sig)) {
/*
* Signal handler installed with SA_SIGINFO.
*/
sf.sf_arg2 = (register_t)&fp->sf_siginfo;
sf.sf_siginfo.si_signo = sig;
sf.sf_siginfo.si_code = code;
sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher;
} else {
/*
* Old FreeBSD-style arguments.
*/
sf.sf_arg2 = code;
sf.sf_ahu.sf_handler = catcher;
}
sf.sf_addr = (char *) regs->tf_err;
sf.sf_handler = catcher;
/* save scratch registers */
sf.sf_sc.sc_eax = regs->tf_eax;
sf.sf_sc.sc_ebx = regs->tf_ebx;
sf.sf_sc.sc_ecx = regs->tf_ecx;
sf.sf_sc.sc_edx = regs->tf_edx;
sf.sf_sc.sc_esi = regs->tf_esi;
sf.sf_sc.sc_edi = regs->tf_edi;
sf.sf_sc.sc_cs = regs->tf_cs;
sf.sf_sc.sc_ds = regs->tf_ds;
sf.sf_sc.sc_ss = regs->tf_ss;
sf.sf_sc.sc_es = regs->tf_es;
sf.sf_sc.sc_fs = regs->tf_fs;
sf.sf_sc.sc_isp = regs->tf_isp;
sf.sf_siginfo.si_sc.sc_eax = regs->tf_eax;
sf.sf_siginfo.si_sc.sc_ebx = regs->tf_ebx;
sf.sf_siginfo.si_sc.sc_ecx = regs->tf_ecx;
sf.sf_siginfo.si_sc.sc_edx = regs->tf_edx;
sf.sf_siginfo.si_sc.sc_esi = regs->tf_esi;
sf.sf_siginfo.si_sc.sc_edi = regs->tf_edi;
sf.sf_siginfo.si_sc.sc_cs = regs->tf_cs;
sf.sf_siginfo.si_sc.sc_ds = regs->tf_ds;
sf.sf_siginfo.si_sc.sc_ss = regs->tf_ss;
sf.sf_siginfo.si_sc.sc_es = regs->tf_es;
sf.sf_siginfo.si_sc.sc_fs = regs->tf_fs;
sf.sf_siginfo.si_sc.sc_isp = regs->tf_isp;
/*
* Build the signal context to be used by sigreturn.
*/
sf.sf_sc.sc_onstack = oonstack;
sf.sf_sc.sc_mask = mask;
sf.sf_sc.sc_sp = regs->tf_esp;
sf.sf_sc.sc_fp = regs->tf_ebp;
sf.sf_sc.sc_pc = regs->tf_eip;
sf.sf_sc.sc_ps = regs->tf_eflags;
sf.sf_sc.sc_trapno = regs->tf_trapno;
sf.sf_sc.sc_err = regs->tf_err;
sf.sf_siginfo.si_sc.sc_onstack = oonstack;
sf.sf_siginfo.si_sc.sc_mask = mask;
sf.sf_siginfo.si_sc.sc_sp = regs->tf_esp;
sf.sf_siginfo.si_sc.sc_fp = regs->tf_ebp;
sf.sf_siginfo.si_sc.sc_pc = regs->tf_eip;
sf.sf_siginfo.si_sc.sc_ps = regs->tf_eflags;
sf.sf_siginfo.si_sc.sc_trapno = regs->tf_trapno;
sf.sf_siginfo.si_sc.sc_err = regs->tf_err;
/*
* If we're a vm86 process, we want to save the segment registers.
@ -579,13 +598,13 @@ sendsig(catcher, sig, mask, code)
struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs;
struct vm86_kernel *vm86 = &p->p_addr->u_pcb.pcb_ext->ext_vm86;
sf.sf_sc.sc_gs = tf->tf_vm86_gs;
sf.sf_sc.sc_fs = tf->tf_vm86_fs;
sf.sf_sc.sc_es = tf->tf_vm86_es;
sf.sf_sc.sc_ds = tf->tf_vm86_ds;
sf.sf_siginfo.si_sc.sc_gs = tf->tf_vm86_gs;
sf.sf_siginfo.si_sc.sc_fs = tf->tf_vm86_fs;
sf.sf_siginfo.si_sc.sc_es = tf->tf_vm86_es;
sf.sf_siginfo.si_sc.sc_ds = tf->tf_vm86_ds;
if (vm86->vm86_has_vme == 0)
sf.sf_sc.sc_ps = (tf->tf_eflags & ~(PSL_VIF | PSL_VIP))
sf.sf_siginfo.si_sc.sc_ps = (tf->tf_eflags & ~(PSL_VIF | PSL_VIP))
| (vm86->vm86_eflags & (PSL_VIF | PSL_VIP));
/*
@ -651,7 +670,7 @@ sigreturn(p, uap)
*/
scp = uap->sigcntxp;
fp = (struct sigframe *)
((caddr_t)scp - offsetof(struct sigframe, sf_sc));
((caddr_t)scp - offsetof(struct sigframe, sf_siginfo.si_sc));
if (useracc((caddr_t)fp, sizeof (*fp), B_WRITE) == 0)
return(EFAULT);
@ -1131,16 +1150,15 @@ sdtossd(sd, ssd)
#define PHYSMAP_SIZE (2 * 8)
/*
* Populate the (physmap) array with base/length pairs describing the
* Populate the (physmap) array with base/bound pairs describing the
* available physical memory in the system, then test this memory and
* build the phys_avail array describing the actually-available memory.
*
* Total memory size may be constrained by the kernel environment variable
* hw.physmem or the compile-time define MAXMEM.
* If we cannot accurately determine the physical memory map, then use
* value from the 0xE801 call, and failing that, the RTC.
*
* If we cannot accurately determine the physical memory map, and the
* value from the RTC seems dubious, trust the value of hw.physmem/MAXMEM
* instead, but require a speculative probe of memory.
* Total memory size may be set by the kernel environment variable
* hw.physmem or the compile-time define MAXMEM.
*/
static void
getmemsize_pc98(int first)
@ -1358,13 +1376,11 @@ getmemsize(int first)
{
int i, physmap_idx, pa_indx;
u_int basemem, extmem;
int speculative_mprobe = FALSE;
struct vm86frame vmf;
struct vm86context vmc;
vm_offset_t pa, physmap[PHYSMAP_SIZE];
pt_entry_t pte;
u_int64_t AllowMem, MaxMem, sanity;
const char *cp, *ep;
const char *cp;
struct {
u_int64_t base;
u_int64_t length;
@ -1374,46 +1390,6 @@ getmemsize(int first)
bzero(&vmf, sizeof(struct vm86frame));
bzero(physmap, sizeof(physmap));
/*
* hw.maxmem is a size in bytes; we also allow k, m, and g suffixes
* for the appropriate modifiers.
* After this calculation, AllowMem is either 0 (no memory size cap)
* or the maximum memory size desired in bytes.
*/
AllowMem = 0;
if ((cp = getenv("hw.physmem")) != NULL) {
sanity = AllowMem = strtouq(cp, &ep, 0);
if ((ep != cp) && (*ep != 0)) {
switch(*ep) {
case 'g':
case 'G':
AllowMem <<= 10;
case 'm':
case 'M':
AllowMem <<= 10;
case 'k':
case 'K':
AllowMem <<= 10;
break;
default:
AllowMem = sanity = 0;
}
if (AllowMem < sanity)
AllowMem = 0;
}
if (AllowMem == 0)
printf("Warning: invalid memory limit '%s' specified\n", cp);
}
#ifdef MAXMEM
if (AllowMem == 0)
AllowMem = MAXMEM * (u_int64_t)1024;
#endif
if ((AllowMem != 0) && (boothowto & RB_VERBOSE))
printf("Physical memory use limited to %uk\n", (u_int)(AllowMem / 1024));
MaxMem = AllowMem;
if (AllowMem == 0)
AllowMem = (u_int64_t)1 << 32; /* 4GB limit imposed by 32-bit pmap */
/*
* Perform "base memory" related probes & setup
*/
@ -1500,18 +1476,11 @@ getmemsize(int first)
if (smap->length == 0)
goto next_run;
if (smap->base >= AllowMem) {
printf("%uk of memory above %uk ignored\n",
(u_int)(smap->length / 1024), (u_int)(AllowMem / 1024));
if (smap->base >= 0xffffffff) {
printf("%uK of memory above 4GB ignored\n",
(u_int)(smap->length / 1024));
goto next_run;
}
if ((smap->base + smap->length) >= AllowMem) {
printf("%uk region truncated to %uk to fit %uk limit\n",
(u_int)(smap->length / 1024),
(u_int)((AllowMem - smap->base) / 1024),
(u_int)(AllowMem / 1024));
smap->length = AllowMem - smap->base;
}
for (i = 0; i <= physmap_idx; i += 2) {
if (smap->base < physmap[i + 1]) {
@ -1538,71 +1507,48 @@ getmemsize(int first)
next_run:
} while (vmf.vmf_ebx != 0);
if (physmap[1] != 0)
goto physmap_done;
/*
* If we failed above, try memory map with INT 15:E801
*/
if (physmap[1] == 0) {
vmf.vmf_ax = 0xE801;
if (vm86_intcall(0x15, &vmf) == 0) {
extmem = vmf.vmf_cx + vmf.vmf_dx * 64;
} else {
vmf.vmf_ax = 0xE801;
if (vm86_intcall(0x15, &vmf) == 0) {
extmem = vmf.vmf_cx + vmf.vmf_dx * 64;
} else {
#if 0
vmf.vmf_ah = 0x88;
vm86_intcall(0x15, &vmf);
extmem = vmf.vmf_ax;
vmf.vmf_ah = 0x88;
vm86_intcall(0x15, &vmf);
extmem = vmf.vmf_ax;
#else
/*
* Prefer the RTC value for extended memory, or
* hw.physmem/MAXMEM overrides.
*/
if (MaxMem > (1024 * 1024)) { /* < 1MB is insane */
extmem = (MaxMem / 1024) - 1024;
} else {
extmem = rtcin(RTC_EXTLO) + (rtcin(RTC_EXTHI) << 8);
}
/*
* If the value from the RTC is >= 16M, there is a good
* chance that it's lying. Compaq systems never report
* more than 16M, and no system can honestly report more
* than 64M. We should end up here only on extremely
* old and broken systems. In any case, qualify the value
* that we've got here by actually checking for physical
* memory later on.
*/
if (extmem >= 16 * 1024)
speculative_mprobe = TRUE;
#endif
}
/*
* Special hack for chipsets that still remap the 384k hole when
* there's 16MB of memory - this really confuses people that
* are trying to use bus mastering ISA controllers with the
* "16MB limit"; they only have 16MB, but the remapping puts
* them beyond the limit.
*
* If extended memory is between 15-16MB (16-17MB phys address range),
* chop it to 15MB.
* Prefer the RTC value for extended memory.
*/
if ((extmem > 15 * 1024) && (extmem < 16 * 1024))
extmem = 15 * 1024;
physmap[0] = 0;
physmap[1] = basemem * 1024;
physmap_idx = 2;
physmap[physmap_idx] = 0x100000;
physmap[physmap_idx + 1] = physmap[physmap_idx] + extmem * 1024;
extmem = rtcin(RTC_EXTLO) + (rtcin(RTC_EXTHI) << 8);
#endif
}
/*
* Maxmem isn't the "maximum memory", it's one larger than the
* highest page of the physical address space. It should be
* called something like "Maxphyspage". We fiddle it again
* later based on the results of the memory test.
* Special hack for chipsets that still remap the 384k hole when
* there's 16MB of memory - this really confuses people that
* are trying to use bus mastering ISA controllers with the
* "16MB limit"; they only have 16MB, but the remapping puts
* them beyond the limit.
*
* If extended memory is between 15-16MB (16-17MB phys address range),
* chop it to 15MB.
*/
Maxmem = physmap[physmap_idx + 1] / PAGE_SIZE;
if ((extmem > 15 * 1024) && (extmem < 16 * 1024))
extmem = 15 * 1024;
physmap[0] = 0;
physmap[1] = basemem * 1024;
physmap_idx = 2;
physmap[physmap_idx] = 0x100000;
physmap[physmap_idx + 1] = physmap[physmap_idx] + extmem * 1024;
physmap_done:
/*
* Now, physmap contains a map of physical memory.
*/
@ -1614,6 +1560,63 @@ next_run:
/* look for the MP hardware - needed for apic addresses */
mp_probe();
#endif
/*
* Maxmem isn't the "maximum memory", it's one larger than the
* highest page of the physical address space. It should be
* called something like "Maxphyspage". We may adjust this
* based on ``hw.physmem'' and the results of the memory test.
*/
Maxmem = atop(physmap[physmap_idx + 1]);
#ifdef MAXMEM
Maxmem = MAXMEM / 4;
#endif
/*
* hw.maxmem is a size in bytes; we also allow k, m, and g suffixes
* for the appropriate modifiers. This overrides MAXMEM.
*/
if ((cp = getenv("hw.physmem")) != NULL) {
u_int64_t AllowMem, sanity;
const char *ep;
sanity = AllowMem = strtouq(cp, &ep, 0);
if ((ep != cp) && (*ep != 0)) {
switch(*ep) {
case 'g':
case 'G':
AllowMem <<= 10;
case 'm':
case 'M':
AllowMem <<= 10;
case 'k':
case 'K':
AllowMem <<= 10;
break;
default:
AllowMem = sanity = 0;
}
if (AllowMem < sanity)
AllowMem = 0;
}
if (AllowMem == 0)
printf("Ignoring invalid memory size of '%s'\n", cp);
else
Maxmem = atop(AllowMem);
}
if (atop(physmap[physmap_idx + 1]) != Maxmem &&
(boothowto & RB_VERBOSE))
printf("Physical memory use set to %uK\n", Maxmem * 4);
/*
* If Maxmem has been increased beyond what the system has detected,
* extend the last memory segment to the new limit.
*/
if (atop(physmap[physmap_idx + 1]) < Maxmem)
physmap[physmap_idx + 1] = ptoa(Maxmem);
/* call pmap initialization to make new kernel address space */
pmap_bootstrap(first, 0);
@ -1637,10 +1640,6 @@ next_run:
for (i = 0; i <= physmap_idx; i += 2) {
vm_offset_t end;
if (boothowto & RB_VERBOSE)
printf("Testing memory %uk to %uk\n",
(u_int)(physmap[i] / 1024),
(u_int)((physmap[i] + physmap[i+1]) / 1024));
end = ptoa(Maxmem);
if (physmap[i + 1] < end)
end = trunc_page(physmap[i + 1]);
@ -1719,9 +1718,6 @@ next_run:
*/
if (phys_avail[pa_indx] == pa) {
phys_avail[pa_indx] += PAGE_SIZE;
if (speculative_mprobe == TRUE &&
phys_avail[pa_indx] >= (64*1024*1024))
end += PAGE_SIZE;
} else {
pa_indx++;
if (pa_indx == PHYS_AVAIL_ARRAY_END) {