#include <cpus.h>
#include <platforms.h>
#include <mach_kdb.h>
#include <himem.h>
#include <fast_idle.h>
#include <mach/i386/vm_param.h>
#include <string.h>
#include <mach/vm_param.h>
#include <mach/vm_prot.h>
#include <mach/machine.h>
#include <mach/time_value.h>
#include <kern/etap_macros.h>
#include <kern/spl.h>
#include <kern/assert.h>
#include <kern/debug.h>
#include <kern/misc_protos.h>
#include <kern/cpu_data.h>
#include <kern/processor.h>
#include <vm/vm_page.h>
#include <vm/pmap.h>
#include <vm/vm_kern.h>
#include <i386/pmap.h>
#include <i386/ipl.h>
#include <i386/pio.h>
#include <i386/misc_protos.h>
#include <i386/mp_slave_boot.h>
#ifdef __MACHO__
#include <mach/boot_info.h>
#include <mach/thread_status.h>
#endif
vm_size_t mem_size = 0;
vm_offset_t first_addr = 0;
vm_offset_t first_avail = 0;
vm_offset_t last_addr;
uint64_t max_mem;
uint64_t sane_size;
vm_offset_t avail_start, avail_end;
vm_offset_t virtual_avail, virtual_end;
vm_offset_t hole_start, hole_end;
vm_offset_t avail_next;
unsigned int avail_remaining;
int cnvmem = 0;
int extmem = 0;
#ifndef __MACHO__
extern char edata, end;
#endif
#ifdef __MACHO__
#include <mach-o/loader.h>
vm_offset_t edata, etext, end;
extern struct mach_header _mh_execute_header;
void *sectTEXTB; int sectSizeTEXT;
void *sectDATAB; int sectSizeDATA;
void *sectOBJCB; int sectSizeOBJC;
void *sectLINKB; int sectSizeLINK;
void *sectPRELINKB; int sectSizePRELINK;
#endif
void
i386_vm_init(unsigned int maxmem, KernelBootArgs_t *args)
{
int i,j;
vm_size_t bios_hole_size;
#ifdef __MACHO__
sectTEXTB = (void *) getsegdatafromheader(
&_mh_execute_header, "__TEXT", §SizeTEXT);
sectDATAB = (void *) getsegdatafromheader(
&_mh_execute_header, "__DATA", §SizeDATA);
sectOBJCB = (void *) getsegdatafromheader(
&_mh_execute_header, "__OBJC", §SizeOBJC);
sectLINKB = (void *) getsegdatafromheader(
&_mh_execute_header, "__LINKEDIT", §SizeLINK);
sectPRELINKB = (void *) getsegdatafromheader(
&_mh_execute_header, "__PRELINK", §SizePRELINK);
etext = (vm_offset_t) sectTEXTB + sectSizeTEXT;
edata = (vm_offset_t) sectDATAB + sectSizeDATA;
#endif
#ifndef __MACHO__
bzero((char *)&edata,(unsigned)(&end - &edata));
#endif
cnvmem = args->convmem;
extmem = args->extmem;
set_cpu_model();
vm_set_page_size();
etap_init_phase1();
#if NCPUS > 1
first_addr = MP_FIRST_ADDR;
#else
first_addr = 0x1000;
#endif
last_addr = 1024*1024 + extmem*1024;
bios_hole_size = 1024*1024 - trunc_page((vm_offset_t)(1024 * cnvmem));
hole_start = trunc_page((vm_offset_t)(1024 * cnvmem));
hole_end = round_page((vm_offset_t)first_avail);
#define M (1024*1024)
#define MAXMEM (512*M)
if ((maxmem == 0) && (last_addr - bios_hole_size > MAXMEM)) {
printf("Physical memory %d MB, "\
"maximum usable memory limited to %d MB\n",
(last_addr - bios_hole_size)/M, MAXMEM/M);
maxmem = MAXMEM;
}
if (maxmem != 0) {
if (maxmem < (last_addr) - bios_hole_size)
last_addr = maxmem + bios_hole_size;
}
first_addr = round_page(first_addr);
last_addr = trunc_page(last_addr);
mem_size = last_addr - bios_hole_size;
max_mem = (uint64_t)mem_size;
sane_size = max_mem;
avail_start = first_addr;
avail_end = last_addr;
avail_next = avail_start;
#if NCPUS > 1
interrupt_stack_alloc();
#endif
pmap_bootstrap(0);
avail_remaining = atop((avail_end - avail_start) -
(hole_end - hole_start));
}
unsigned int
pmap_free_pages(void)
{
return avail_remaining;
}
boolean_t
pmap_next_page(
ppnum_t *pn)
{
if (avail_next == avail_end)
return FALSE;
if (avail_next == hole_start)
avail_next = hole_end;
*pn = (ppnum_t)i386_btop(avail_next);
avail_next += PAGE_SIZE;
avail_remaining--;
return TRUE;
}
boolean_t
pmap_valid_page(
vm_offset_t x)
{
return ((avail_start <= x) && (x < avail_end));
}