diff options
Diffstat (limited to 'arch/parisc/kernel/setup.c')
-rw-r--r-- | arch/parisc/kernel/setup.c | 368 |
1 files changed, 368 insertions, 0 deletions
diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c new file mode 100644 index 000000000000..73e9c34b0948 --- /dev/null +++ b/arch/parisc/kernel/setup.c | |||
@@ -0,0 +1,368 @@ | |||
1 | /* $Id: setup.c,v 1.8 2000/02/02 04:42:38 prumpf Exp $ | ||
2 | * | ||
3 | * Initial setup-routines for HP 9000 based hardware. | ||
4 | * | ||
5 | * Copyright (C) 1991, 1992, 1995 Linus Torvalds | ||
6 | * Modifications for PA-RISC (C) 1999 Helge Deller <deller@gmx.de> | ||
7 | * Modifications copyright 1999 SuSE GmbH (Philipp Rumpf) | ||
8 | * Modifications copyright 2000 Martin K. Petersen <mkp@mkp.net> | ||
9 | * Modifications copyright 2000 Philipp Rumpf <prumpf@tux.org> | ||
10 | * Modifications copyright 2001 Ryan Bradetich <rbradetich@uswest.net> | ||
11 | * | ||
12 | * Initial PA-RISC Version: 04-23-1999 by Helge Deller | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or modify | ||
15 | * it under the terms of the GNU General Public License as published by | ||
16 | * the Free Software Foundation; either version 2, or (at your option) | ||
17 | * any later version. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License | ||
25 | * along with this program; if not, write to the Free Software | ||
26 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
27 | * | ||
28 | */ | ||
29 | |||
30 | #include <linux/config.h> | ||
31 | #include <linux/kernel.h> | ||
32 | #include <linux/initrd.h> | ||
33 | #include <linux/init.h> | ||
34 | #include <linux/console.h> | ||
35 | #include <linux/seq_file.h> | ||
36 | #define PCI_DEBUG | ||
37 | #include <linux/pci.h> | ||
38 | #undef PCI_DEBUG | ||
39 | #include <linux/proc_fs.h> | ||
40 | |||
41 | #include <asm/processor.h> | ||
42 | #include <asm/pdc.h> | ||
43 | #include <asm/led.h> | ||
44 | #include <asm/machdep.h> /* for pa7300lc_init() proto */ | ||
45 | #include <asm/pdc_chassis.h> | ||
46 | #include <asm/io.h> | ||
47 | #include <asm/setup.h> | ||
48 | |||
49 | char command_line[COMMAND_LINE_SIZE]; | ||
50 | |||
51 | /* Intended for ccio/sba/cpu statistics under /proc/bus/{runway|gsc} */ | ||
52 | struct proc_dir_entry * proc_runway_root = NULL; | ||
53 | struct proc_dir_entry * proc_gsc_root = NULL; | ||
54 | struct proc_dir_entry * proc_mckinley_root = NULL; | ||
55 | |||
56 | #if !defined(CONFIG_PA20) && (defined(CONFIG_IOMMU_CCIO) || defined(CONFIG_IOMMU_SBA)) | ||
57 | int parisc_bus_is_phys = 1; /* Assume no IOMMU is present */ | ||
58 | EXPORT_SYMBOL(parisc_bus_is_phys); | ||
59 | #endif | ||
60 | |||
61 | /* This sets the vmerge boundary and size, it's here because it has to | ||
62 | * be available on all platforms (zero means no-virtual merging) */ | ||
63 | unsigned long parisc_vmerge_boundary = 0; | ||
64 | unsigned long parisc_vmerge_max_size = 0; | ||
65 | |||
66 | void __init setup_cmdline(char **cmdline_p) | ||
67 | { | ||
68 | extern unsigned int boot_args[]; | ||
69 | |||
70 | /* Collect stuff passed in from the boot loader */ | ||
71 | |||
72 | /* boot_args[0] is free-mem start, boot_args[1] is ptr to command line */ | ||
73 | if (boot_args[0] < 64) { | ||
74 | /* called from hpux boot loader */ | ||
75 | saved_command_line[0] = '\0'; | ||
76 | } else { | ||
77 | strcpy(saved_command_line, (char *)__va(boot_args[1])); | ||
78 | |||
79 | #ifdef CONFIG_BLK_DEV_INITRD | ||
80 | if (boot_args[2] != 0) /* did palo pass us a ramdisk? */ | ||
81 | { | ||
82 | initrd_start = (unsigned long)__va(boot_args[2]); | ||
83 | initrd_end = (unsigned long)__va(boot_args[3]); | ||
84 | } | ||
85 | #endif | ||
86 | } | ||
87 | |||
88 | strcpy(command_line, saved_command_line); | ||
89 | *cmdline_p = command_line; | ||
90 | } | ||
91 | |||
92 | #ifdef CONFIG_PA11 | ||
93 | void __init dma_ops_init(void) | ||
94 | { | ||
95 | switch (boot_cpu_data.cpu_type) { | ||
96 | case pcx: | ||
97 | /* | ||
98 | * We've got way too many dependencies on 1.1 semantics | ||
99 | * to support 1.0 boxes at this point. | ||
100 | */ | ||
101 | panic( "PA-RISC Linux currently only supports machines that conform to\n" | ||
102 | "the PA-RISC 1.1 or 2.0 architecture specification.\n"); | ||
103 | |||
104 | case pcxs: | ||
105 | case pcxt: | ||
106 | hppa_dma_ops = &pcx_dma_ops; | ||
107 | break; | ||
108 | case pcxl2: | ||
109 | pa7300lc_init(); | ||
110 | case pcxl: /* falls through */ | ||
111 | hppa_dma_ops = &pcxl_dma_ops; | ||
112 | break; | ||
113 | default: | ||
114 | break; | ||
115 | } | ||
116 | } | ||
117 | #endif | ||
118 | |||
119 | extern int init_per_cpu(int cpuid); | ||
120 | extern void collect_boot_cpu_data(void); | ||
121 | |||
122 | void __init setup_arch(char **cmdline_p) | ||
123 | { | ||
124 | #ifdef __LP64__ | ||
125 | extern int parisc_narrow_firmware; | ||
126 | #endif | ||
127 | |||
128 | init_per_cpu(smp_processor_id()); /* Set Modes & Enable FP */ | ||
129 | |||
130 | #ifdef __LP64__ | ||
131 | printk(KERN_INFO "The 64-bit Kernel has started...\n"); | ||
132 | #else | ||
133 | printk(KERN_INFO "The 32-bit Kernel has started...\n"); | ||
134 | #endif | ||
135 | |||
136 | pdc_console_init(); | ||
137 | |||
138 | #ifdef __LP64__ | ||
139 | if(parisc_narrow_firmware) { | ||
140 | printk(KERN_INFO "Kernel is using PDC in 32-bit mode.\n"); | ||
141 | } | ||
142 | #endif | ||
143 | setup_pdc(); | ||
144 | setup_cmdline(cmdline_p); | ||
145 | collect_boot_cpu_data(); | ||
146 | do_memory_inventory(); /* probe for physical memory */ | ||
147 | parisc_cache_init(); | ||
148 | paging_init(); | ||
149 | |||
150 | #ifdef CONFIG_CHASSIS_LCD_LED | ||
151 | /* initialize the LCD/LED after boot_cpu_data is available ! */ | ||
152 | led_init(); /* LCD/LED initialization */ | ||
153 | #endif | ||
154 | |||
155 | #ifdef CONFIG_PA11 | ||
156 | dma_ops_init(); | ||
157 | #endif | ||
158 | |||
159 | #if defined(CONFIG_VT) && defined(CONFIG_DUMMY_CONSOLE) | ||
160 | conswitchp = &dummy_con; /* we use take_over_console() later ! */ | ||
161 | #endif | ||
162 | |||
163 | } | ||
164 | |||
165 | /* | ||
166 | * Display cpu info for all cpu's. | ||
167 | * for parisc this is in processor.c | ||
168 | */ | ||
169 | extern int show_cpuinfo (struct seq_file *m, void *v); | ||
170 | |||
171 | static void * | ||
172 | c_start (struct seq_file *m, loff_t *pos) | ||
173 | { | ||
174 | /* Looks like the caller will call repeatedly until we return | ||
175 | * 0, signaling EOF perhaps. This could be used to sequence | ||
176 | * through CPUs for example. Since we print all cpu info in our | ||
177 | * show_cpuinfo() disregarding 'pos' (which I assume is 'v' above) | ||
178 | * we only allow for one "position". */ | ||
179 | return ((long)*pos < 1) ? (void *)1 : NULL; | ||
180 | } | ||
181 | |||
182 | static void * | ||
183 | c_next (struct seq_file *m, void *v, loff_t *pos) | ||
184 | { | ||
185 | ++*pos; | ||
186 | return c_start(m, pos); | ||
187 | } | ||
188 | |||
189 | static void | ||
190 | c_stop (struct seq_file *m, void *v) | ||
191 | { | ||
192 | } | ||
193 | |||
194 | struct seq_operations cpuinfo_op = { | ||
195 | .start = c_start, | ||
196 | .next = c_next, | ||
197 | .stop = c_stop, | ||
198 | .show = show_cpuinfo | ||
199 | }; | ||
200 | |||
201 | static void __init parisc_proc_mkdir(void) | ||
202 | { | ||
203 | /* | ||
204 | ** Can't call proc_mkdir() until after proc_root_init() has been | ||
205 | ** called by start_kernel(). In other words, this code can't | ||
206 | ** live in arch/.../setup.c because start_parisc() calls | ||
207 | ** start_kernel(). | ||
208 | */ | ||
209 | switch (boot_cpu_data.cpu_type) { | ||
210 | case pcxl: | ||
211 | case pcxl2: | ||
212 | if (NULL == proc_gsc_root) | ||
213 | { | ||
214 | proc_gsc_root = proc_mkdir("bus/gsc", NULL); | ||
215 | } | ||
216 | break; | ||
217 | case pcxt_: | ||
218 | case pcxu: | ||
219 | case pcxu_: | ||
220 | case pcxw: | ||
221 | case pcxw_: | ||
222 | case pcxw2: | ||
223 | if (NULL == proc_runway_root) | ||
224 | { | ||
225 | proc_runway_root = proc_mkdir("bus/runway", NULL); | ||
226 | } | ||
227 | break; | ||
228 | case mako: | ||
229 | if (NULL == proc_mckinley_root) | ||
230 | { | ||
231 | proc_mckinley_root = proc_mkdir("bus/mckinley", NULL); | ||
232 | } | ||
233 | break; | ||
234 | default: | ||
235 | /* FIXME: this was added to prevent the compiler | ||
236 | * complaining about missing pcx, pcxs and pcxt | ||
237 | * I'm assuming they have neither gsc nor runway */ | ||
238 | break; | ||
239 | } | ||
240 | } | ||
241 | |||
242 | static struct resource central_bus = { | ||
243 | .name = "Central Bus", | ||
244 | .start = F_EXTEND(0xfff80000), | ||
245 | .end = F_EXTEND(0xfffaffff), | ||
246 | .flags = IORESOURCE_MEM, | ||
247 | }; | ||
248 | |||
249 | static struct resource local_broadcast = { | ||
250 | .name = "Local Broadcast", | ||
251 | .start = F_EXTEND(0xfffb0000), | ||
252 | .end = F_EXTEND(0xfffdffff), | ||
253 | .flags = IORESOURCE_MEM, | ||
254 | }; | ||
255 | |||
256 | static struct resource global_broadcast = { | ||
257 | .name = "Global Broadcast", | ||
258 | .start = F_EXTEND(0xfffe0000), | ||
259 | .end = F_EXTEND(0xffffffff), | ||
260 | .flags = IORESOURCE_MEM, | ||
261 | }; | ||
262 | |||
263 | static int __init parisc_init_resources(void) | ||
264 | { | ||
265 | int result; | ||
266 | |||
267 | result = request_resource(&iomem_resource, ¢ral_bus); | ||
268 | if (result < 0) { | ||
269 | printk(KERN_ERR | ||
270 | "%s: failed to claim %s address space!\n", | ||
271 | __FILE__, central_bus.name); | ||
272 | return result; | ||
273 | } | ||
274 | |||
275 | result = request_resource(&iomem_resource, &local_broadcast); | ||
276 | if (result < 0) { | ||
277 | printk(KERN_ERR | ||
278 | "%s: failed to claim %saddress space!\n", | ||
279 | __FILE__, local_broadcast.name); | ||
280 | return result; | ||
281 | } | ||
282 | |||
283 | result = request_resource(&iomem_resource, &global_broadcast); | ||
284 | if (result < 0) { | ||
285 | printk(KERN_ERR | ||
286 | "%s: failed to claim %s address space!\n", | ||
287 | __FILE__, global_broadcast.name); | ||
288 | return result; | ||
289 | } | ||
290 | |||
291 | return 0; | ||
292 | } | ||
293 | |||
294 | extern void gsc_init(void); | ||
295 | extern void processor_init(void); | ||
296 | extern void ccio_init(void); | ||
297 | extern void hppb_init(void); | ||
298 | extern void dino_init(void); | ||
299 | extern void iosapic_init(void); | ||
300 | extern void lba_init(void); | ||
301 | extern void sba_init(void); | ||
302 | extern void eisa_init(void); | ||
303 | |||
304 | static int __init parisc_init(void) | ||
305 | { | ||
306 | parisc_proc_mkdir(); | ||
307 | parisc_init_resources(); | ||
308 | do_device_inventory(); /* probe for hardware */ | ||
309 | |||
310 | parisc_pdc_chassis_init(); | ||
311 | |||
312 | /* set up a new led state on systems shipped LED State panel */ | ||
313 | pdc_chassis_send_status(PDC_CHASSIS_DIRECT_BSTART); | ||
314 | |||
315 | processor_init(); | ||
316 | printk(KERN_INFO "CPU(s): %d x %s at %d.%06d MHz\n", | ||
317 | boot_cpu_data.cpu_count, | ||
318 | boot_cpu_data.cpu_name, | ||
319 | boot_cpu_data.cpu_hz / 1000000, | ||
320 | boot_cpu_data.cpu_hz % 1000000 ); | ||
321 | |||
322 | parisc_setup_cache_timing(); | ||
323 | |||
324 | /* These are in a non-obvious order, will fix when we have an iotree */ | ||
325 | #if defined(CONFIG_IOSAPIC) | ||
326 | iosapic_init(); | ||
327 | #endif | ||
328 | #if defined(CONFIG_IOMMU_SBA) | ||
329 | sba_init(); | ||
330 | #endif | ||
331 | #if defined(CONFIG_PCI_LBA) | ||
332 | lba_init(); | ||
333 | #endif | ||
334 | |||
335 | /* CCIO before any potential subdevices */ | ||
336 | #if defined(CONFIG_IOMMU_CCIO) | ||
337 | ccio_init(); | ||
338 | #endif | ||
339 | |||
340 | /* | ||
341 | * Need to register Asp & Wax before the EISA adapters for the IRQ | ||
342 | * regions. EISA must come before PCI to be sure it gets IRQ region | ||
343 | * 0. | ||
344 | */ | ||
345 | #if defined(CONFIG_GSC_LASI) || defined(CONFIG_GSC_WAX) | ||
346 | gsc_init(); | ||
347 | #endif | ||
348 | #ifdef CONFIG_EISA | ||
349 | eisa_init(); | ||
350 | #endif | ||
351 | |||
352 | #if defined(CONFIG_HPPB) | ||
353 | hppb_init(); | ||
354 | #endif | ||
355 | |||
356 | #if defined(CONFIG_GSC_DINO) | ||
357 | dino_init(); | ||
358 | #endif | ||
359 | |||
360 | #ifdef CONFIG_CHASSIS_LCD_LED | ||
361 | register_led_regions(); /* register LED port info in procfs */ | ||
362 | #endif | ||
363 | |||
364 | return 0; | ||
365 | } | ||
366 | |||
367 | arch_initcall(parisc_init); | ||
368 | |||