|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.