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