|
|
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.