Source to bsd/dev/i386/unix_startup.c


Enter a symbol's name here to quickly find it.

/*
 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
 *
 * @APPLE_LICENSE_HEADER_START@
 * 
 * The contents of this file constitute Original Code as defined in and
 * are subject to the Apple Public Source License Version 1.1 (the
 * "License").  You may not use this file except in compliance with the
 * License.  Please obtain a copy of the License at
 * http://www.apple.com/publicsource and read it before using this file.
 * 
 * This Original Code and all software distributed under the License are
 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
 * License for the specific language governing rights and limitations
 * under the License.
 * 
 * @APPLE_LICENSE_HEADER_END@
 */
/*
 * Copyright (c) 1992,7 NeXT Computer, Inc.
 *
 * Unix data structure initialization.
 *
 * HISTORY
 *
 * 11 Mar 1997 Eryk Vershen @ NeXT
 *	Modified from hppa version.
 * 26 May 1992 ? at NeXT
 *	Created from 68k version.
 */

#include <mach_nbc.h>
#import <mach/mach_types.h>

#import <vm/vm_kern.h>
#include <mach/vm_prot.h>

#import <sys/param.h>
#import <sys/buf.h>
#import <sys/clist.h>
#import <sys/mbuf.h>
#import <sys/systm.h>
#import <sys/tty.h>
#import <bsd/dev/ppc/cons.h>


extern vm_map_t	mb_map;
/*
 * Declare these as initialized data so we can patch them.
 */
int             niobuf = 0;

#ifdef	NBUF
int		nbuf = NBUF;
#else
int		nbuf = 0;
#endif
#ifdef	NMFSBUF
int	nmfsbuf = NMFSBUF
#else
int	nmfsbuf = 0;
#endif
#ifdef	BUFPAGES
int		bufpages = BUFPAGES;
#else
int		bufpages = 0;
#endif

int  		srv = 0;          /* Flag indicates a server boot when set */
int             ncl = 0;

vm_map_t	buffer_map;
vm_map_t	bufferhdr_map;




void
bsd_startupearly()
{
    vm_offset_t		v, firstaddr, trash_offset;
    vm_size_t		size;
    kern_return_t	ret;


    /*
     *      Since these pages are virtual-size pages (larger
     *      than physical page size), use only one page
     *      per buffer.
     */
    if (bufpages == 0) {
		bufpages = atop(mem_size / 50);
    }

    if (nbuf == 0) {
#if     PRIVATE_BUFS
	    nbuf = 100;
#else   PRIVATE_BUFS
	/* Go for a 1-1 correspondence between the number of buffer
	 * headers and bufpages.  Then add some extra (empty) buffer
	 * headers to aid clustering.
	 */
	if ((nbuf = bufpages) < 16)
			nbuf = 16;
	nbuf += 64;
#endif  PRIVATE_BUFS
    }

    if (bufpages > nbuf * (MAXBSIZE / page_size))
	bufpages = nbuf * (MAXBSIZE / page_size);
    if (niobuf == 0) {
		if ((niobuf = bufpages / (MAXPHYSIO / page_size)) > 1024)
			niobuf = 1024;
		if (niobuf < 32)
			niobuf = 32;
	}

	size = (nbuf + niobuf) * sizeof (struct buf);
	size = round_page(size);

   	 ret = kmem_suballoc(kernel_map,
			&firstaddr,
			size,
			FALSE,
			TRUE,
			&bufferhdr_map);

	if (ret != KERN_SUCCESS) 
		panic("Failed to create bufferhdr_map\n");
	
	if (kernel_memory_allocate(bufferhdr_map, &firstaddr, size,
   		0,
		KMA_HERE | KMA_KOBJECT) != KERN_SUCCESS)
			panic("Failed to allocate bufferhdr_map\n");

	buf = (struct buf * )firstaddr;
	bzero(buf,size);


	/*
	 * Unless set at the boot command line, mfs gets no more than
	 * half of the system's bufs.  Hack to prevent buf starvation
	 * and system hang.
	 */
	if (nmfsbuf == 0)
		nmfsbuf = nbuf / 2;

    if (mem_size > (64 * 1024 * 1024)) {
            int scale;
	    extern u_long tcp_sendspace;
	    extern u_long tcp_recvspace;

	    if ((nmbclusters = ncl) == 0) {
	            if ((nmbclusters = ((mem_size / 16) / MCLBYTES)) > 4096)
		            nmbclusters = 8192;
	    }
	    if ((scale = nmbclusters / NMBCLUSTERS) > 1) {
	            tcp_sendspace *= scale;
		    tcp_recvspace *= scale;

		    if (tcp_sendspace > (32 * 1024))
		            tcp_sendspace = 32 * 1024;
		    if (tcp_recvspace > (32 * 1024))
		            tcp_recvspace = 32 * 1024;
	    }
    }

}

void
bsd_bufferinit()
{
    unsigned int	i;
    vm_offset_t		v;
    vm_size_t		size;
    kern_return_t	ret;
    vm_offset_t		trash_offset, firstaddr;
    int			base, residual;

    cons.t_dev = makedev(12, 0);


	bsd_startupearly();

	size = round_page(nbuf * MAXBSIZE) + (niobuf * MAXPHYSIO);
   	 ret = kmem_suballoc(kernel_map,
			&firstaddr,
			size,
			TRUE,
			TRUE,
			&buffer_map);

	if (ret != KERN_SUCCESS) 
		panic("Failed to create buffer_map\n");
	buffers = firstaddr;
	base = bufpages / nbuf;
	residual = bufpages % nbuf;

    for (i = 0; i < nbuf; i++) {
	vm_size_t	thisbsize;
	vm_offset_t	curbuf;

	/*
	 * First <residual> buffers get (base+1) physical pages
	 * allocated for them.  The rest get (base) physical pages.
	 *
	 * The rest of each buffer occupies virtual space,
	 * but has no physical memory allocated for it.
	 */

	thisbsize = page_size*(i < residual ? base+1 : base);
	curbuf = (vm_offset_t)buffers + i * MAXBSIZE;
	if (thisbsize) {

	ret = vm_map_enter(buffer_map, &curbuf, thisbsize,
			  (vm_offset_t) 0, FALSE,
			  VM_OBJECT_NULL, (vm_offset_t) 0, FALSE,
			  VM_PROT_DEFAULT, VM_PROT_ALL, VM_INHERIT_DEFAULT);
	if (ret != KERN_SUCCESS) {
		panic("Failed to allocate buffer cache pages\n");
	}
	ret = vm_map_wire(buffer_map, curbuf, curbuf+thisbsize, VM_PROT_READ | VM_PROT_WRITE, FALSE);
	if (ret != KERN_SUCCESS)
		panic("Failed to wire buffer cache pages\n");

	} else {
		//printf("skipping allocating buffer page to buf %d\n",i);
	}
    }