|
|
1.1 root 1: /*
2: * Linux initialization.
3: *
4: * Copyright (C) 1996 The University of Utah and the Computer Systems
5: * Laboratory at the University of Utah (CSL)
6: *
7: * This program is free software; you can redistribute it and/or modify
8: * it under the terms of the GNU General Public License as published by
9: * the Free Software Foundation; either version 2, or (at your option)
10: * any later version.
11: *
12: * This program is distributed in the hope that it will be useful,
13: * but WITHOUT ANY WARRANTY; without even the implied warranty of
14: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15: * GNU General Public License for more details.
16: *
17: * You should have received a copy of the GNU General Public License
18: * along with this program; if not, write to the Free Software
19: * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
20: *
21: * Author: Shantanu Goel, University of Utah CSL
22: */
23:
24: /*
25: * linux/init/main.c
26: *
27: * Copyright (C) 1991, 1992 Linus Torvalds
28: */
29:
30: #include <sys/types.h>
31:
32: #include <mach/vm_param.h>
33: #include <mach/vm_prot.h>
34: #include <mach/machine.h>
35:
36: #include <vm/vm_page.h>
37: #include <kern/kalloc.h>
38:
39: #include <machine/spl.h>
40: #include <machine/pmap.h>
41: #include <machine/vm_param.h>
1.1.1.2 ! root 42: #include <machine/model_dep.h>
1.1 root 43:
44: #define MACH_INCLUDE
45: #include <linux/sched.h>
46: #include <linux/mm.h>
47: #include <linux/interrupt.h>
48: #include <linux/delay.h>
49: #include <linux/ioport.h>
50: #include <linux/string.h>
1.1.1.2 ! root 51: #include <linux/pci.h>
! 52: #include <linux/dev/glue/glue.h>
1.1 root 53:
54: #include <asm/system.h>
55: #include <asm/io.h>
56:
57: /*
58: * Timing loop count.
59: */
60: unsigned long loops_per_sec = 1;
61:
1.1.1.2 ! root 62: #if defined(__SMP__) && defined(__i386__)
! 63: unsigned long smp_loops_per_tick = 1000000;
! 64: #endif
! 65:
1.1 root 66: /*
67: * End of physical memory.
68: */
69: unsigned long high_memory;
70:
71: /*
72: * Flag to indicate auto-configuration is in progress.
73: */
74: int linux_auto_config = 1;
75:
76: /*
77: * Hard drive parameters obtained from the BIOS.
78: */
79: struct drive_info_struct
80: {
81: char dummy[32];
82: } drive_info;
83:
84: /*
85: * Forward declarations.
86: */
87: static void calibrate_delay (void);
88:
89: /*
90: * Amount of contiguous memory to allocate for initialization.
91: */
92: #define CONTIG_ALLOC (512 * 1024)
93:
94: /*
95: * Initialize Linux drivers.
96: */
97: void
98: linux_init (void)
99: {
100: int addr;
101: unsigned memory_start, memory_end;
102: vm_page_t pages;
103:
104: /*
105: * Initialize memory size.
106: */
107: high_memory = phys_last_addr;
108: init_IRQ ();
109: linux_sched_init ();
110:
111: /*
112: * Set loop count.
113: */
114: calibrate_delay ();
115:
116: /*
117: * Initialize drive info.
118: */
119: addr = *((unsigned *) phystokv (0x104));
120: memcpy (&drive_info,
121: (void *) ((addr & 0xffff) + ((addr >> 12) & 0xffff0)), 16);
122: addr = *((unsigned *) phystokv (0x118));
123: memcpy ((char *) &drive_info + 16,
124: (void *) ((addr & 0xffff) + ((addr >> 12) & 0xffff0)), 16);
125:
126: /*
127: * Initialize Linux memory allocator.
128: */
129: linux_kmem_init ();
130:
131: /*
132: * Allocate contiguous memory below 16 MB.
133: */
134: memory_start = (unsigned long) alloc_contig_mem (CONTIG_ALLOC,
135: 16 * 1024 * 1024,
136: 0, &pages);
137: if (memory_start == 0)
138: panic ("linux_init: alloc_contig_mem failed");
139: memory_end = memory_start + CONTIG_ALLOC;
140:
141: /*
142: * Initialize PCI bus.
143: */
144: memory_start = pci_init (memory_start, memory_end);
145:
146: if (memory_start > memory_end)
147: panic ("linux_init: ran out memory");
148:
149: /*
150: * Free unused memory.
151: */
1.1.1.2 ! root 152: while (pages && phystokv(pages->phys_addr) < round_page (memory_start))
1.1 root 153: pages = (vm_page_t) pages->pageq.next;
154: if (pages)
155: free_contig_mem (pages);
156:
157: /*
158: * Initialize devices.
159: */
160: #ifdef CONFIG_INET
161: linux_net_emulation_init ();
162: #endif
1.1.1.2 ! root 163:
1.1 root 164: cli ();
165: device_setup ();
166:
1.1.1.2 ! root 167: #ifdef CONFIG_PCMCIA
! 168: /*
! 169: * Initialize pcmcia.
! 170: */
! 171: pcmcia_init ();
! 172: #endif
! 173:
1.1 root 174: restore_IRQ ();
1.1.1.2 ! root 175:
1.1 root 176: linux_auto_config = 0;
177: }
178:
179: #ifndef NBPW
180: #define NBPW 32
181: #endif
182:
183: /*
184: * Allocate contiguous memory with the given constraints.
185: * This routine is horribly inefficient but it is presently
186: * only used during initialization so it's not that bad.
187: */
188: void *
189: alloc_contig_mem (unsigned size, unsigned limit,
190: unsigned mask, vm_page_t * pages)
191: {
192: int i, j, bits_len;
193: unsigned *bits, len;
194: void *m;
195: vm_page_t p, page_list, tail, prev;
196: vm_offset_t addr, max_addr;
197:
198: if (size == 0)
199: return (NULL);
200: size = round_page (size);
201: if ((size >> PAGE_SHIFT) > vm_page_free_count)
202: return (NULL);
203:
204: /* Allocate bit array. */
205: max_addr = phys_last_addr;
206: if (max_addr > limit)
207: max_addr = limit;
208: bits_len = ((((max_addr >> PAGE_SHIFT) + NBPW - 1) / NBPW)
209: * sizeof (unsigned));
210: bits = (unsigned *) kalloc (bits_len);
211: if (!bits)
212: return (NULL);
213: memset (bits, 0, bits_len);
214:
215: /*
216: * Walk the page free list and set a bit for every usable page.
217: */
218: simple_lock (&vm_page_queue_free_lock);
219: p = vm_page_queue_free;
220: while (p)
221: {
222: if (p->phys_addr < limit)
223: (bits[(p->phys_addr >> PAGE_SHIFT) / NBPW]
224: |= 1 << ((p->phys_addr >> PAGE_SHIFT) % NBPW));
225: p = (vm_page_t) p->pageq.next;
226: }
227:
228: /*
229: * Scan bit array for contiguous pages.
230: */
231: len = 0;
232: m = NULL;
233: for (i = 0; len < size && i < bits_len / sizeof (unsigned); i++)
234: for (j = 0; len < size && j < NBPW; j++)
235: if (!(bits[i] & (1 << j)))
236: {
237: len = 0;
238: m = NULL;
239: }
240: else
241: {
242: if (len == 0)
243: {
244: addr = ((vm_offset_t) (i * NBPW + j)
245: << PAGE_SHIFT);
246: if ((addr & mask) == 0)
247: {
248: len += PAGE_SIZE;
249: m = (void *) addr;
250: }
251: }
252: else
253: len += PAGE_SIZE;
254: }
255:
256: if (len != size)
257: {
258: simple_unlock (&vm_page_queue_free_lock);
259: kfree ((vm_offset_t) bits, bits_len);
260: return (NULL);
261: }
262:
263: /*
264: * Remove pages from free list
265: * and construct list to return to caller.
266: */
267: page_list = NULL;
268: for (len = 0; len < size; len += PAGE_SIZE, addr += PAGE_SIZE)
269: {
270: prev = NULL;
271: for (p = vm_page_queue_free; p; p = (vm_page_t) p->pageq.next)
272: {
273: if (p->phys_addr == addr)
274: break;
275: prev = p;
276: }
277: if (!p)
278: panic ("alloc_contig_mem: page not on free list");
279: if (prev)
280: prev->pageq.next = p->pageq.next;
281: else
282: vm_page_queue_free = (vm_page_t) p->pageq.next;
283: p->free = FALSE;
284: p->pageq.next = NULL;
285: if (!page_list)
286: page_list = tail = p;
287: else
288: {
289: tail->pageq.next = (queue_entry_t) p;
290: tail = p;
291: }
292: vm_page_free_count--;
293: }
294:
295: simple_unlock (&vm_page_queue_free_lock);
296: kfree ((vm_offset_t) bits, bits_len);
297: if (pages)
298: *pages = page_list;
1.1.1.2 ! root 299: return phystokv(m);
1.1 root 300: }
301:
302: /*
303: * Free memory allocated by alloc_contig_mem.
304: */
305: void
306: free_contig_mem (vm_page_t pages)
307: {
308: int i;
309: vm_page_t p;
310:
311: for (p = pages, i = 0; p->pageq.next; p = (vm_page_t) p->pageq.next, i++)
312: p->free = TRUE;
313: p->free = TRUE;
314: simple_lock (&vm_page_queue_free_lock);
315: vm_page_free_count += i + 1;
316: p->pageq.next = (queue_entry_t) vm_page_queue_free;
317: vm_page_queue_free = pages;
318: simple_unlock (&vm_page_queue_free_lock);
319: }
320:
321: /* This is the number of bits of precision for the loops_per_second. Each
322: * bit takes on average 1.5/HZ seconds. This (like the original) is a little
323: * better than 1%
324: */
325: #define LPS_PREC 8
326:
327: static void
328: calibrate_delay (void)
329: {
330: int ticks;
331: int loopbit;
332: int lps_precision = LPS_PREC;
333:
334: loops_per_sec = (1 << 12);
335:
336: #ifndef MACH
337: printk ("Calibrating delay loop.. ");
338: #endif
339: while (loops_per_sec <<= 1)
340: {
341: /* wait for "start of" clock tick */
342: ticks = jiffies;
343: while (ticks == jiffies)
344: /* nothing */ ;
345: /* Go .. */
346: ticks = jiffies;
347: __delay (loops_per_sec);
348: ticks = jiffies - ticks;
349: if (ticks)
350: break;
351: }
352:
353: /* Do a binary approximation to get loops_per_second set to equal one clock
354: * (up to lps_precision bits)
355: */
356: loops_per_sec >>= 1;
357: loopbit = loops_per_sec;
358: while (lps_precision-- && (loopbit >>= 1))
359: {
360: loops_per_sec |= loopbit;
361: ticks = jiffies;
362: while (ticks == jiffies);
363: ticks = jiffies;
364: __delay (loops_per_sec);
365: if (jiffies != ticks) /* longer than 1 tick */
366: loops_per_sec &= ~loopbit;
367: }
368:
369: /* finally, adjust loops per second in terms of seconds instead of clocks */
370: loops_per_sec *= HZ;
371: /* Round the value and print it */
372: #ifndef MACH
373: printk ("ok - %lu.%02lu BogoMIPS\n",
374: (loops_per_sec + 2500) / 500000,
375: ((loops_per_sec + 2500) / 5000) % 100);
376: #endif
377:
378: #if defined(__SMP__) && defined(__i386__)
379: smp_loops_per_tick = loops_per_sec / 400;
380: #endif
381: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.