|
|
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 NeXT Computer, Inc. ! 27: * ! 28: * Unix data structure initialization. ! 29: * ! 30: * HISTORY ! 31: * ! 32: * 26 May 1992 ? at NeXT ! 33: * Created from 68k version. ! 34: */ ! 35: ! 36: #import <mach/mach_types.h> ! 37: ! 38: #import <vm/vm_kern.h> ! 39: #import <vm/vm_page.h> ! 40: ! 41: #import <kernserv/ns_timer.h> ! 42: ! 43: #import <sys/param.h> ! 44: #import <sys/buf.h> ! 45: #import <sys/callout.h> ! 46: #import <sys/clist.h> ! 47: #import <sys/mbuf.h> ! 48: #import <sys/systm.h> ! 49: #import <sys/tty.h> ! 50: ! 51: extern struct tty cons; ! 52: ! 53: #import <kern/assert.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; /* 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: #if SHOW_SPACE ! 87: ! 88: #define valloc(name, type, num) \ ! 89: MACRO_BEGIN \ ! 90: (name) = (type *)(v); (v) = (vm_offset_t)((name)+(num)); \ ! 91: if (show_space) \ ! 92: printf(#name " = %d(0x%x) bytes @%x, %d cells @ %d bytes\n", \ ! 93: num*sizeof(type), \ ! 94: num*sizeof(type), \ ! 95: name, num, sizeof(type)); \ ! 96: MACRO_END ! 97: ! 98: #define valloclim(name, type, num, lim) \ ! 99: MACRO_BEGIN \ ! 100: (name) = (type *)(v); (v) = (vm_offset_t)((lim) = ((name)+(num))); \ ! 101: if (show_space) \ ! 102: printf(#name " = %d(0x%x) bytes @%x, %d cells @ %d bytes\n", \ ! 103: num*sizeof(type), \ ! 104: num*sizeof(type), \ ! 105: name, num, sizeof(type)); \ ! 106: MACRO_END ! 107: ! 108: #else SHOW_SPACE ! 109: ! 110: #define valloc(name, type, num) \ ! 111: (name) = (type *)(v); (v) = (vm_offset_t)((name)+(num)) ! 112: ! 113: #define valloclim(name, type, num, lim) \ ! 114: (name) = (type *)(v); (v) = (vm_offset_t)((lim) = ((name)+(num))); ! 115: ! 116: #endif SHOW_SPACE ! 117: ! 118: vm_size_t ! 119: buffer_map_sizer(void) ! 120: { ! 121: ! 122: /* ! 123: * Since these pages are virtual-size pages (larger ! 124: * than physical page size), use only one page ! 125: * per buffer. ! 126: */ ! 127: if (bufpages == 0) { ! 128: bufpages = atop(mem_size / 50); ! 129: } ! 130: ! 131: if (nbuf == 0) { ! 132: #if PRIVATE_BUFS ! 133: nbuf = 100; ! 134: #else PRIVATE_BUFS ! 135: /* Go for a 1-1 correspondence between the number of buffer ! 136: * headers and bufpages. Then add some extra (empty) buffer ! 137: * headers to aid clustering. ! 138: */ ! 139: if ((nbuf = bufpages) < 16) ! 140: nbuf = 16; ! 141: nbuf += 64; ! 142: #endif PRIVATE_BUFS ! 143: } ! 144: ! 145: if (bufpages > nbuf * (MAXBSIZE / page_size)) ! 146: bufpages = nbuf * (MAXBSIZE / page_size); ! 147: ! 148: if (niobuf == 0) { ! 149: if ((niobuf = bufpages / (MAXPHYSIO / page_size)) > 1024) ! 150: niobuf = 1024; ! 151: if (niobuf < 32) ! 152: niobuf = 32; ! 153: } ! 154: ! 155: return (round_page(((vm_size_t)nbuf * MAXBSIZE)) + ((vm_size_t)niobuf ! 156: * MAXPHYSIO)); ! 157: } ! 158: ! 159: void ! 160: startup_early(void) ! 161: { ! 162: vm_offset_t firstaddr, v; ! 163: mem_region_t rp = mem_region; ! 164: ! 165: v = firstaddr = pmap_phys_to_kern(rp->first_phys_addr); ! 166: (void) buffer_map_sizer(); ! 167: ! 168: valloc(buf, struct buf, nbuf + niobuf); ! 169: ! 170: /* ! 171: * Unless set at the boot command line, mfs gets no more than ! 172: * half of the system's bufs. Hack to prevent buf starvation ! 173: * and system hang. ! 174: */ ! 175: if (nmfsbuf == 0) ! 176: nmfsbuf = nbuf / 2; ! 177: ! 178: /* ! 179: * Clear space allocated thus far, and make r/w entries ! 180: * for the space in the kernel map. ! 181: */ ! 182: ! 183: bzero(firstaddr, v - firstaddr); ! 184: rp->first_phys_addr = pmap_resident_extract(kernel_pmap, v); ! 185: ! 186: if (mem_size > (64 * 1024 * 1024)) { ! 187: int scale; ! 188: extern u_long tcp_sendspace; ! 189: extern u_long tcp_recvspace; ! 190: ! 191: if ((nmbclusters = ncl) == 0) { ! 192: if ((nmbclusters = ((mem_size / 16) / MCLBYTES)) > 4096) ! 193: nmbclusters = 8192; ! 194: } ! 195: if ((scale = nmbclusters / NMBCLUSTERS) > 1) { ! 196: tcp_sendspace *= scale; ! 197: tcp_recvspace *= scale; ! 198: ! 199: if (tcp_sendspace > (32 * 1024)) ! 200: tcp_sendspace = 32 * 1024; ! 201: if (tcp_recvspace > (32 * 1024)) ! 202: tcp_recvspace = 32 * 1024; ! 203: } ! 204: } ! 205: } ! 206: ! 207: ! 208: startup( ! 209: vm_offset_t firstaddr ! 210: ) ! 211: { ! 212: unsigned int i; ! 213: vm_size_t map_size; ! 214: kern_return_t ret; ! 215: vm_offset_t buffer_max; ! 216: int base, residual; ! 217: extern int vm_page_free_count; ! 218: mem_region_t rp = mem_region; ! 219: ! 220: cons.t_dev = makedev(12, 0); ! 221: ! 222: kminit(); ! 223: ! 224: /* ! 225: * Good {morning,afternoon,evening,night}. ! 226: */ ! 227: panic_init(); ! 228: ! 229: printf(version); ! 230: ! 231: #define MEG (1024*1024) ! 232: printf("physical memory = %d.%d%d megabytes.\n", ! 233: mem_size/MEG, ! 234: ((mem_size%MEG)*10)/MEG, ! 235: ((mem_size%(MEG/10))*100)/MEG); ! 236: ! 237: /* ! 238: * Allocate space for system data structures. ! 239: * The first available real memory address is in "firstaddr". ! 240: * The first available kernel virtual address is in "v". ! 241: * As pages of kernel virtual memory are allocated, "v" is incremented. ! 242: * As pages of memory are allocated and cleared, ! 243: * "firstaddr" is incremented. ! 244: * An index into the kernel page table corresponding to the ! 245: * virtual memory address maintained in "v" is kept in "mapaddr". ! 246: */ ! 247: ! 248: /* ! 249: * Since the virtual memory system has already been set up, ! 250: * we cannot bypass it to allocate memory as the old code ! 251: * DOES. we therefore make two passes over the table ! 252: * allocation code. The first pass merely calculates the ! 253: * size needed for the various data structures. The ! 254: * second pass allocates the memory and then sets the ! 255: * actual addresses. The code must not change any of ! 256: * the allocated sizes between the two passes. ! 257: */ ! 258: firstaddr = round_page(firstaddr); ! 259: map_size = buffer_map_sizer(); ! 260: ! 261: /* ! 262: * Between the following find, and the next one below ! 263: * we can't cause any other memory to be allocated. Since ! 264: * below is the first place we really need an object, it ! 265: * will cause the object zone to be expanded, and will ! 266: * use our memory! Therefore we allocate a dummy object ! 267: * here. This is all a hack of course. ! 268: */ ! 269: ret = vm_map_find(kernel_map, vm_object_allocate(0), (vm_offset_t) 0, ! 270: &firstaddr, map_size, TRUE); ! 271: ASSERT(ret == KERN_SUCCESS); ! 272: vm_map_remove(kernel_map, firstaddr, firstaddr + map_size); ! 273: ! 274: /* ! 275: * Now allocate buffers proper. They are different than the above ! 276: * in that they usually occupy more virtual memory than physical. ! 277: */ ! 278: buffers = (void *)firstaddr; ! 279: base = bufpages / nbuf; ! 280: residual = bufpages % nbuf; ! 281: ! 282: /* ! 283: * Allocate virtual memory for buffer pool. ! 284: */ ! 285: buffer_map = kmem_suballoc(kernel_map, ! 286: &firstaddr, &buffer_max, map_size, TRUE); ! 287: ret = vm_map_find(buffer_map, ! 288: vm_object_allocate(map_size), (vm_offset_t) 0, ! 289: &firstaddr, map_size, FALSE); ! 290: ! 291: ASSERT(ret == KERN_SUCCESS); ! 292: ! 293: for (i = 0; i < nbuf; i++) { ! 294: vm_size_t thisbsize; ! 295: vm_offset_t curbuf; ! 296: ! 297: /* ! 298: * First <residual> buffers get (base+1) physical pages ! 299: * allocated for them. The rest get (base) physical pages. ! 300: * ! 301: * The rest of each buffer occupies virtual space, ! 302: * but has no physical memory allocated for it. ! 303: */ ! 304: ! 305: thisbsize = page_size*(i < residual ? base+1 : base); ! 306: curbuf = (vm_offset_t)buffers + i * MAXBSIZE; ! 307: vm_map_pageable(buffer_map, curbuf, curbuf+thisbsize, FALSE); ! 308: } ! 309: ! 310: { ! 311: register int nbytes; ! 312: ! 313: nbytes = ptoa(bufpages); ! 314: printf("using %d buffers containing %d.%d%d megabytes of memory\n", ! 315: nbuf, ! 316: nbytes/MEG, ! 317: ((nbytes%MEG)*10)/MEG, ! 318: ((nbytes%(MEG/10))*100)/MEG); ! 319: ! 320: nbytes = ptoa(vm_page_free_count); ! 321: printf("available memory = %d.%d%d megabytes. vm_page_free_count = %x\n", ! 322: nbytes/MEG, ! 323: ((nbytes%MEG)*10)/MEG, ! 324: ((nbytes%(MEG/10))*100)/MEG, ! 325: vm_page_free_count); ! 326: } ! 327: ! 328: /* ! 329: * Initialize memory allocator and swap ! 330: * and user page table maps. ! 331: */ ! 332: mb_map = kmem_suballoc(kernel_map, ! 333: (vm_offset_t *) &mbutl, ! 334: (vm_offset_t *) &embutl, ! 335: (vm_size_t) (nmbclusters * MCLBYTES), ! 336: FALSE); ! 337: ! 338: /* ! 339: * Set up buffers, so they can be used to read disk labels. ! 340: */ ! 341: bufinit(); ! 342: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.