|
|
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;
1.1.1.3 root 101: unsigned long memory_start, memory_end;
1.1 root 102: vm_page_t pages;
103:
104: /*
105: * Initialize memory size.
106: */
1.1.1.4 ! root 107: high_memory = vm_page_seg_end(VM_PAGE_SEL_DIRECTMAP);
1.1 root 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: */
1.1.1.3 root 134: memory_start = alloc_contig_mem (CONTIG_ALLOC, 16 * 1024 * 1024, 0, &pages);
1.1 root 135: if (memory_start == 0)
136: panic ("linux_init: alloc_contig_mem failed");
137: memory_end = memory_start + CONTIG_ALLOC;
138:
139: /*
140: * Initialize PCI bus.
141: */
142: memory_start = pci_init (memory_start, memory_end);
143:
144: if (memory_start > memory_end)
145: panic ("linux_init: ran out memory");
146:
147: /*
148: * Initialize devices.
149: */
150: #ifdef CONFIG_INET
151: linux_net_emulation_init ();
152: #endif
1.1.1.2 root 153:
1.1 root 154: cli ();
155: device_setup ();
156:
1.1.1.2 root 157: #ifdef CONFIG_PCMCIA
158: /*
159: * Initialize pcmcia.
160: */
161: pcmcia_init ();
162: #endif
163:
1.1 root 164: restore_IRQ ();
1.1.1.2 root 165:
1.1 root 166: linux_auto_config = 0;
167: }
168:
169: #ifndef NBPW
170: #define NBPW 32
171: #endif
172:
173: /*
174: * Allocate contiguous memory with the given constraints.
175: */
1.1.1.3 root 176: unsigned long
1.1 root 177: alloc_contig_mem (unsigned size, unsigned limit,
178: unsigned mask, vm_page_t * pages)
179: {
1.1.1.3 root 180: vm_page_t p;
1.1 root 181:
1.1.1.3 root 182: p = vm_page_grab_contig(size, VM_PAGE_SEL_DMA);
1.1 root 183:
1.1.1.3 root 184: if (p == NULL)
185: return 0;
1.1 root 186:
187: if (pages)
1.1.1.3 root 188: *pages = p;
189:
190: return phystokv(vm_page_to_pa(p));
1.1 root 191: }
192:
193: /*
194: * Free memory allocated by alloc_contig_mem.
195: */
196: void
1.1.1.3 root 197: free_contig_mem (vm_page_t pages, unsigned size)
1.1 root 198: {
1.1.1.3 root 199: vm_page_free_contig(pages, size);
1.1 root 200: }
201:
202: /* This is the number of bits of precision for the loops_per_second. Each
203: * bit takes on average 1.5/HZ seconds. This (like the original) is a little
204: * better than 1%
205: */
206: #define LPS_PREC 8
207:
208: static void
209: calibrate_delay (void)
210: {
211: int ticks;
212: int loopbit;
213: int lps_precision = LPS_PREC;
214:
215: loops_per_sec = (1 << 12);
216:
217: #ifndef MACH
218: printk ("Calibrating delay loop.. ");
219: #endif
220: while (loops_per_sec <<= 1)
221: {
222: /* wait for "start of" clock tick */
223: ticks = jiffies;
224: while (ticks == jiffies)
225: /* nothing */ ;
226: /* Go .. */
227: ticks = jiffies;
228: __delay (loops_per_sec);
229: ticks = jiffies - ticks;
230: if (ticks)
231: break;
232: }
233:
234: /* Do a binary approximation to get loops_per_second set to equal one clock
235: * (up to lps_precision bits)
236: */
237: loops_per_sec >>= 1;
238: loopbit = loops_per_sec;
239: while (lps_precision-- && (loopbit >>= 1))
240: {
241: loops_per_sec |= loopbit;
242: ticks = jiffies;
243: while (ticks == jiffies);
244: ticks = jiffies;
245: __delay (loops_per_sec);
246: if (jiffies != ticks) /* longer than 1 tick */
247: loops_per_sec &= ~loopbit;
248: }
249:
250: /* finally, adjust loops per second in terms of seconds instead of clocks */
251: loops_per_sec *= HZ;
252: /* Round the value and print it */
253: #ifndef MACH
254: printk ("ok - %lu.%02lu BogoMIPS\n",
255: (loops_per_sec + 2500) / 500000,
256: ((loops_per_sec + 2500) / 5000) % 100);
257: #endif
258:
259: #if defined(__SMP__) && defined(__i386__)
260: smp_loops_per_tick = loops_per_sec / 400;
261: #endif
262: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.