Annotation of kernel/machdep/ppc/unix_startup.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
                      7:  * Reserved.  This file contains Original Code and/or Modifications of
                      8:  * Original Code as defined in and that are subject to the Apple Public
                      9:  * Source License Version 1.1 (the "License").  You may not use this file
                     10:  * except in compliance with the License.  Please obtain a copy of the
                     11:  * License at http://www.apple.com/publicsource and read it before using
                     12:  * this file.
                     13:  * 
                     14:  * The Original Code and all software distributed under the License are
                     15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     19:  * License for the specific language governing rights and limitations
                     20:  * under the License.
                     21:  * 
                     22:  * @APPLE_LICENSE_HEADER_END@
                     23:  */
                     24: 
                     25: /*
                     26:  * Copyright (c) 1992,7 NeXT Computer, Inc.
                     27:  *
                     28:  * Unix data structure initialization.
                     29:  *
                     30:  * HISTORY
                     31:  *
                     32:  * 11 Mar 1997 Eryk Vershen @ NeXT
                     33:  *     Modified from hppa version.
                     34:  * 26 May 1992 ? at NeXT
                     35:  *     Created from 68k version.
                     36:  */
                     37: 
                     38: #include <mach_nbc.h>
                     39: #import <mach/mach_types.h>
                     40: 
                     41: #import <vm/vm_kern.h>
                     42: #import <vm/vm_page.h>
                     43: 
                     44: #import <kern/time_stamp.h>
                     45: 
                     46: #import <sys/param.h>
                     47: #import <sys/buf.h>
                     48: #import <sys/callout.h>
                     49: #import <sys/clist.h>
                     50: #import <sys/mbuf.h>
                     51: #import <sys/systm.h>
                     52: #import <sys/tty.h>
                     53: #import <bsd/dev/ppc/cons.h>
                     54: 
                     55: /*
                     56:  * Declare these as initialized data so we can patch them.
                     57:  */
                     58: int             niobuf = 0;
                     59: 
                     60: #ifdef NBUF
                     61: int            nbuf = NBUF;
                     62: #else
                     63: int            nbuf = 0;
                     64: #endif
                     65: #ifdef NMFSBUF
                     66: int    nmfsbuf = NMFSBUF
                     67: #else
                     68: int    nmfsbuf = 0;
                     69: #endif
                     70: #ifdef BUFPAGES
                     71: int            bufpages = BUFPAGES;
                     72: #else
                     73: int            bufpages = 0;
                     74: #endif
                     75: int            show_space = 0;
                     76: int            srv = 0;          /* Flag indicates a server boot when set */
                     77: int             ncl = 0;
                     78: vm_map_t       buffer_map;
                     79: 
                     80: /*
                     81:  * Machine-dependent startup code
                     82:  */
                     83: /*
                     84:  * Machine-dependent early startup code
                     85:  */
                     86: 
                     87: #define valloc(name, type, num)                                         \
                     88:     (name) = (type *)(v); (v) = (vm_offset_t)((name)+(num))
                     89: 
                     90: #define valloclim(name, type, num, lim)                                 \
                     91:     (name) = (type *)(v); (v) = (vm_offset_t)((lim) = ((name)+(num)));
                     92: 
                     93: vm_size_t
                     94: buffer_map_sizer(void)
                     95: {
                     96:     /*
                     97:      *      Since these pages are virtual-size pages (larger
                     98:      *      than physical page size), use only one page
                     99:      *      per buffer.
                    100:      */
                    101:     if (bufpages == 0) {
                    102: #if MACH_NBC
                    103:             if (srv) {
                    104:                    if (mem_size > (64 * 1024 * 1024)) {
                    105:                            bufpages = atop(mem_size) / 2;
                    106:                            
                    107:                            if ((mem_size - ptoa(bufpages)) < (64 * 1024 * 1024))
                    108:                                    bufpages = atop(mem_size - (64 * 1024 * 1024));
                    109:                    } else {
                    110:                            bufpages = atop(mem_size / 100);
                    111:                            bufpages = bufpages * 3; /* 3% */
                    112:                    }
                    113:            } else {
                    114:                     bufpages = atop(mem_size / 100);
                    115:                    bufpages = bufpages * 3;  /* 3% */
                    116:            }
                    117: #else
                    118:            bufpages = atop(mem_size / 20) & ~1; /* force even */
                    119: 
                    120: #endif /* MACH_NBC */
                    121:     }
                    122: 
                    123:     if (nbuf == 0) {
                    124: #if     PRIVATE_BUFS
                    125:             nbuf = 100;
                    126: #else   PRIVATE_BUFS
                    127:            /* Go for a 1-1 correspondence between the number of buffer
                    128:             * headers and bufpages.  Then add some extra (empty) buffer
                    129:             * headers to aid clustering.
                    130:             */
                    131:            if (bufpages > 60000)
                    132:                    bufpages = 60000;
                    133:            if ((nbuf = bufpages) < 16)
                    134:                    nbuf = 16;
                    135:            nbuf += 64;
                    136: #endif  PRIVATE_BUFS
                    137:     } else if (nbuf > 60000)
                    138:             nbuf = 60000;
                    139: 
                    140:     if (bufpages > nbuf * (MAXBSIZE / page_size))
                    141:             bufpages = nbuf * (MAXBSIZE / page_size);
                    142: 
                    143:     if (niobuf == 0) {
                    144:             niobuf = bufpages / (MAXPHYSIO / page_size);
                    145:            if (niobuf < 128)
                    146:                    niobuf = 128;
                    147:     }
                    148:     if (niobuf > 4096)
                    149:             niobuf = 4096;
                    150: 
                    151:     return (round_page(((vm_size_t)nbuf * MAXBSIZE)) + ((vm_size_t)niobuf * MAXPHYSIO));
                    152: }
                    153: 
                    154: void
                    155: startup_early(vm_offset_t *first_avail)
                    156: {
                    157:     vm_offset_t                v;
                    158: 
                    159:     v = *first_avail;
                    160:     (void) buffer_map_sizer();
                    161: 
                    162:     valloc(buf, struct buf, nbuf + niobuf);
                    163: 
                    164:        /*
                    165:         * Unless set at the boot command line, mfs gets no more than
                    166:         * half of the system's bufs.  Hack to prevent buf starvation
                    167:         * and system hang.
                    168:         */
                    169:        if (nmfsbuf == 0)
                    170:                nmfsbuf = nbuf / 2;
                    171: 
                    172:     /*
                    173:      * Clear space allocated thus far, and make r/w entries
                    174:      * for the space in the kernel map.
                    175:      */
                    176: 
                    177:     bzero(*first_avail, v - *first_avail);
                    178:     *first_avail = v;
                    179: 
                    180:     if ((mem_size > (64 * 1024 * 1024)) || ncl) {
                    181:             int scale;
                    182:            extern u_long tcp_sendspace;
                    183:            extern u_long tcp_recvspace;
                    184: 
                    185:            if ((nmbclusters = ncl) == 0) {
                    186:                    if ((nmbclusters = ((mem_size / 16) / MCLBYTES)) > 8192)
                    187:                            nmbclusters = 8192;
                    188:            }
                    189:            if ((scale = nmbclusters / NMBCLUSTERS) > 1) {
                    190:                    tcp_sendspace *= scale;
                    191:                    tcp_recvspace *= scale;
                    192: 
                    193:                    if (tcp_sendspace > (32 * 1024))
                    194:                            tcp_sendspace = 32 * 1024;
                    195:                    if (tcp_recvspace > (32 * 1024))
                    196:                            tcp_recvspace = 32 * 1024;
                    197:            }
                    198:     }
                    199: }
                    200: 
                    201: 
                    202: void
                    203: startup(
                    204:     vm_offset_t                firstaddr
                    205: )
                    206: {
                    207:     unsigned int       i;
                    208:     vm_size_t          map_size;
                    209:     kern_return_t      ret;
                    210:     vm_offset_t                buffer_max;
                    211:     int                        base, residual;
                    212:     extern int         vm_page_free_count;
                    213: 
                    214:     cons.t_dev = makedev(12, 0);
                    215: 
                    216:     /*
                    217:      * Good {morning,afternoon,evening,night}.
                    218:      */
                    219:     panic_init();
                    220: 
                    221: #define MEG    (1024*1024)
                    222:     printf("physical memory = %d.%d%d megabytes.\n",
                    223:        mem_size/MEG,
                    224:        ((mem_size%MEG)*10)/MEG,
                    225:        ((mem_size%(MEG/10))*100)/MEG);
                    226: 
                    227:     /*
                    228:      * Allocate space for system data structures.
                    229:      * The first available real memory address is in "firstaddr".
                    230:      * The first available kernel virtual address is in "v".
                    231:      * As pages of kernel virtual memory are allocated, "v" is incremented.
                    232:      * As pages of memory are allocated and cleared,
                    233:      * "firstaddr" is incremented.
                    234:      * An index into the kernel page table corresponding to the
                    235:      * virtual memory address maintained in "v" is kept in "mapaddr".
                    236:      */
                    237: 
                    238:     /*
                    239:      * Since the virtual memory system has already been set up,
                    240:      * we cannot bypass it to allocate memory as the old code
                    241:      * DOES.  we therefore make two passes over the table
                    242:      * allocation code.  The first pass merely calculates the
                    243:      * size needed for the various data structures.  The
                    244:      * second pass allocates the memory and then sets the
                    245:      * actual addresses.  The code must not change any of
                    246:      * the allocated sizes between the two passes.
                    247:      */
                    248:     firstaddr = round_page(firstaddr);
                    249:     map_size = buffer_map_sizer();
                    250: 
                    251:     /*
                    252:      * Between the following find, and the next one below
                    253:      * we can't cause any other memory to be allocated.  Since
                    254:      * below is the first place we really need an object, it
                    255:      * will cause the object zone to be expanded, and will
                    256:      * use our memory!  Therefore we allocate a dummy object
                    257:      * here.  This is all a hack of course.
                    258:      */
                    259:     ret = vm_map_find(kernel_map, vm_object_allocate(0), (vm_offset_t) 0,
                    260:                &firstaddr, map_size, TRUE);
                    261:     ASSERT(ret == KERN_SUCCESS);
                    262:     vm_map_remove(kernel_map, firstaddr, firstaddr + map_size);
                    263: 
                    264:     /*
                    265:      * Now allocate buffers proper.  They are different than the above
                    266:      * in that they usually occupy more virtual memory than physical.
                    267:      */
                    268:     buffers = (void *)firstaddr;
                    269:     base = bufpages / nbuf;
                    270:     residual = bufpages % nbuf;
                    271: 
                    272:     /*
                    273:      * Allocate virtual memory for buffer pool.
                    274:      */
                    275:     buffer_map = kmem_suballoc(kernel_map,
                    276:                               &firstaddr, &buffer_max, map_size, TRUE);
                    277:     ret = vm_map_find(buffer_map, 
                    278:                      vm_object_allocate(map_size), (vm_offset_t) 0,
                    279:                      &firstaddr, map_size, FALSE);
                    280: 
                    281:     ASSERT(ret == KERN_SUCCESS);
                    282:     ASSERT(page_size == CLBYTES);
                    283: 
                    284:     for (i = 0; i < nbuf; i++) {
                    285:        vm_size_t       thisbsize;
                    286:        vm_offset_t     curbuf;
                    287: 
                    288:        /*
                    289:         * First <residual> buffers get (base+1) physical pages
                    290:         * allocated for them.  The rest get (base) physical pages.
                    291:         *
                    292:         * The rest of each buffer occupies virtual space,
                    293:         * but has no physical memory allocated for it.
                    294:         */
                    295: 
                    296:        thisbsize = page_size*(i < residual ? base+1 : base);
                    297:        curbuf = (vm_offset_t)buffers + i * MAXBSIZE;
                    298:        vm_map_pageable(buffer_map, curbuf, curbuf+thisbsize, FALSE);
                    299:     }
                    300: 
                    301:     {
                    302:        register int    nbytes;
                    303: 
                    304:        nbytes = ptoa(bufpages);
                    305:        printf("using %d buffers containing %d.%d%d megabytes of memory\n",
                    306:                nbuf,
                    307:                nbytes/MEG,
                    308:                ((nbytes%MEG)*10)/MEG,
                    309:                ((nbytes%(MEG/10))*100)/MEG);
                    310: 
                    311:        nbytes = ptoa(vm_page_free_count);
                    312:        printf("available memory = %d.%d%d megabytes. vm_page_free_count = %x\n",
                    313:                nbytes/MEG,
                    314:                ((nbytes%MEG)*10)/MEG,
                    315:                ((nbytes%(MEG/10))*100)/MEG,
                    316:                vm_page_free_count);
                    317:     }
                    318: 
                    319:     /*
                    320:      * Initialize memory allocator and swap
                    321:      * and user page table maps.
                    322:      */
                    323:     mb_map = kmem_suballoc(kernel_map,
                    324:                (vm_offset_t *) &mbutl,
                    325:                (vm_offset_t *) &embutl,
                    326:                (vm_size_t) (nmbclusters * MCLBYTES),
                    327:                FALSE);
                    328: 
                    329:     /*
                    330:      * Set up buffers, so they can be used to read disk labels.
                    331:      */
                    332:     bufinit();
                    333: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.