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