Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/parisc/kernel/setup.c
26295 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
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 <[email protected]>
7
* Modifications copyright 1999 SuSE GmbH (Philipp Rumpf)
8
* Modifications copyright 2000 Martin K. Petersen <[email protected]>
9
* Modifications copyright 2000 Philipp Rumpf <[email protected]>
10
* Modifications copyright 2001 Ryan Bradetich <[email protected]>
11
*
12
* Initial PA-RISC Version: 04-23-1999 by Helge Deller
13
*/
14
15
#include <linux/kernel.h>
16
#include <linux/initrd.h>
17
#include <linux/init.h>
18
#include <linux/console.h>
19
#include <linux/seq_file.h>
20
#define PCI_DEBUG
21
#include <linux/pci.h>
22
#undef PCI_DEBUG
23
#include <linux/proc_fs.h>
24
#include <linux/export.h>
25
#include <linux/sched.h>
26
#include <linux/sched/clock.h>
27
#include <linux/start_kernel.h>
28
29
#include <asm/cacheflush.h>
30
#include <asm/processor.h>
31
#include <asm/sections.h>
32
#include <asm/pdc.h>
33
#include <asm/led.h>
34
#include <asm/pdc_chassis.h>
35
#include <asm/io.h>
36
#include <asm/setup.h>
37
#include <asm/unwind.h>
38
#include <asm/smp.h>
39
40
static char __initdata command_line[COMMAND_LINE_SIZE];
41
42
static void __init setup_cmdline(char **cmdline_p)
43
{
44
extern unsigned int boot_args[];
45
char *p;
46
47
*cmdline_p = command_line;
48
49
/* boot_args[0] is free-mem start, boot_args[1] is ptr to command line */
50
if (boot_args[0] < 64)
51
return; /* return if called from hpux boot loader */
52
53
/* Collect stuff passed in from the boot loader */
54
strscpy(boot_command_line, (char *)__va(boot_args[1]),
55
COMMAND_LINE_SIZE);
56
57
/* autodetect console type (if not done by palo yet) */
58
p = boot_command_line;
59
if (!str_has_prefix(p, "console=") && !strstr(p, " console=")) {
60
strlcat(p, " console=", COMMAND_LINE_SIZE);
61
if (PAGE0->mem_cons.cl_class == CL_DUPLEX)
62
strlcat(p, "ttyS0", COMMAND_LINE_SIZE);
63
else
64
strlcat(p, "tty0", COMMAND_LINE_SIZE);
65
}
66
67
/* default to use early console */
68
if (!strstr(p, "earlycon"))
69
strlcat(p, " earlycon=pdc", COMMAND_LINE_SIZE);
70
71
#ifdef CONFIG_BLK_DEV_INITRD
72
/* did palo pass us a ramdisk? */
73
if (boot_args[2] != 0) {
74
initrd_start = (unsigned long)__va(boot_args[2]);
75
initrd_end = (unsigned long)__va(boot_args[3]);
76
}
77
#endif
78
79
strscpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
80
}
81
82
#ifdef CONFIG_PA11
83
static void __init dma_ops_init(void)
84
{
85
switch (boot_cpu_data.cpu_type) {
86
case pcx:
87
/*
88
* We've got way too many dependencies on 1.1 semantics
89
* to support 1.0 boxes at this point.
90
*/
91
panic( "PA-RISC Linux currently only supports machines that conform to\n"
92
"the PA-RISC 1.1 or 2.0 architecture specification.\n");
93
94
case pcxl2:
95
default:
96
break;
97
}
98
}
99
#endif
100
101
void __init setup_arch(char **cmdline_p)
102
{
103
unwind_init();
104
105
init_per_cpu(smp_processor_id()); /* Set Modes & Enable FP */
106
107
#ifdef CONFIG_64BIT
108
printk(KERN_INFO "The 64-bit Kernel has started...\n");
109
#else
110
printk(KERN_INFO "The 32-bit Kernel has started...\n");
111
#endif
112
113
printk(KERN_INFO "Kernel default page size is %d KB. Huge pages ",
114
(int)(PAGE_SIZE / 1024));
115
#ifdef CONFIG_HUGETLB_PAGE
116
printk(KERN_CONT "enabled with %d MB physical and %d MB virtual size",
117
1 << (REAL_HPAGE_SHIFT - 20), 1 << (HPAGE_SHIFT - 20));
118
#else
119
printk(KERN_CONT "disabled");
120
#endif
121
printk(KERN_CONT ".\n");
122
123
/*
124
* Check if initial kernel page mappings are sufficient.
125
* panic early if not, else we may access kernel functions
126
* and variables which can't be reached.
127
*/
128
if (__pa((unsigned long) &_end) >= KERNEL_INITIAL_SIZE)
129
panic("KERNEL_INITIAL_ORDER too small!");
130
131
#ifdef CONFIG_64BIT
132
if(parisc_narrow_firmware) {
133
printk(KERN_INFO "Kernel is using PDC in 32-bit mode.\n");
134
}
135
#endif
136
setup_pdc();
137
setup_cmdline(cmdline_p);
138
collect_boot_cpu_data();
139
do_memory_inventory(); /* probe for physical memory */
140
parisc_cache_init();
141
paging_init();
142
143
#ifdef CONFIG_PA11
144
dma_ops_init();
145
#endif
146
147
clear_sched_clock_stable();
148
}
149
150
/*
151
* Display CPU info for all CPUs.
152
*/
153
static void *
154
c_start (struct seq_file *m, loff_t *pos)
155
{
156
/* Looks like the caller will call repeatedly until we return
157
* 0, signaling EOF perhaps. This could be used to sequence
158
* through CPUs for example. Since we print all cpu info in our
159
* show_cpuinfo() disregarding 'pos' (which I assume is 'v' above)
160
* we only allow for one "position". */
161
return ((long)*pos < 1) ? (void *)1 : NULL;
162
}
163
164
static void *
165
c_next (struct seq_file *m, void *v, loff_t *pos)
166
{
167
++*pos;
168
return c_start(m, pos);
169
}
170
171
static void
172
c_stop (struct seq_file *m, void *v)
173
{
174
}
175
176
const struct seq_operations cpuinfo_op = {
177
.start = c_start,
178
.next = c_next,
179
.stop = c_stop,
180
.show = show_cpuinfo
181
};
182
183
static struct resource central_bus = {
184
.name = "Central Bus",
185
.start = F_EXTEND(0xfff80000),
186
.end = F_EXTEND(0xfffaffff),
187
.flags = IORESOURCE_MEM,
188
};
189
190
static struct resource local_broadcast = {
191
.name = "Local Broadcast",
192
.start = F_EXTEND(0xfffb0000),
193
.end = F_EXTEND(0xfffdffff),
194
.flags = IORESOURCE_MEM,
195
};
196
197
static struct resource global_broadcast = {
198
.name = "Global Broadcast",
199
.start = F_EXTEND(0xfffe0000),
200
.end = F_EXTEND(0xffffffff),
201
.flags = IORESOURCE_MEM,
202
};
203
204
static int __init parisc_init_resources(void)
205
{
206
int result;
207
208
result = request_resource(&iomem_resource, &central_bus);
209
if (result < 0) {
210
printk(KERN_ERR
211
"%s: failed to claim %s address space!\n",
212
__FILE__, central_bus.name);
213
return result;
214
}
215
216
result = request_resource(&iomem_resource, &local_broadcast);
217
if (result < 0) {
218
printk(KERN_ERR
219
"%s: failed to claim %s address space!\n",
220
__FILE__, local_broadcast.name);
221
return result;
222
}
223
224
result = request_resource(&iomem_resource, &global_broadcast);
225
if (result < 0) {
226
printk(KERN_ERR
227
"%s: failed to claim %s address space!\n",
228
__FILE__, global_broadcast.name);
229
return result;
230
}
231
232
return 0;
233
}
234
235
static int __init parisc_init(void)
236
{
237
u32 osid = (OS_ID_LINUX << 16);
238
239
parisc_init_resources();
240
do_device_inventory(); /* probe for hardware */
241
242
parisc_pdc_chassis_init();
243
244
/* set up a new led state on systems shipped LED State panel */
245
pdc_chassis_send_status(PDC_CHASSIS_DIRECT_BSTART);
246
247
/* tell PDC we're Linux. Nevermind failure. */
248
pdc_stable_write(0x40, &osid, sizeof(osid));
249
250
/* start with known state */
251
flush_cache_all_local();
252
flush_tlb_all_local(NULL);
253
254
processor_init();
255
#ifdef CONFIG_SMP
256
pr_info("CPU(s): %d out of %d %s at %d.%06d MHz online\n",
257
num_online_cpus(), num_present_cpus(),
258
#else
259
pr_info("CPU(s): 1 x %s at %d.%06d MHz\n",
260
#endif
261
boot_cpu_data.cpu_name,
262
boot_cpu_data.cpu_hz / 1000000,
263
boot_cpu_data.cpu_hz % 1000000 );
264
265
#if defined(CONFIG_64BIT) && defined(CONFIG_SMP)
266
/* Don't serialize TLB flushes if we run on one CPU only. */
267
if (num_online_cpus() == 1)
268
pa_serialize_tlb_flushes = 0;
269
#endif
270
271
apply_alternatives_all();
272
parisc_setup_cache_timing();
273
return 0;
274
}
275
arch_initcall(parisc_init);
276
277
void __init start_parisc(void)
278
{
279
int ret, cpunum;
280
struct pdc_coproc_cfg coproc_cfg;
281
282
/* check QEMU/SeaBIOS marker in PAGE0 */
283
running_on_qemu = (memcmp(&PAGE0->pad0, "SeaBIOS", 8) == 0);
284
285
cpunum = smp_processor_id();
286
287
init_cpu_topology();
288
289
set_firmware_width_unlocked();
290
291
ret = pdc_coproc_cfg_unlocked(&coproc_cfg);
292
if (ret >= 0 && coproc_cfg.ccr_functional) {
293
mtctl(coproc_cfg.ccr_functional, 10);
294
295
per_cpu(cpu_data, cpunum).fp_rev = coproc_cfg.revision;
296
per_cpu(cpu_data, cpunum).fp_model = coproc_cfg.model;
297
298
asm volatile ("fstd %fr0,8(%sp)");
299
} else {
300
panic("must have an fpu to boot linux");
301
}
302
303
early_trap_init(); /* initialize checksum of fault_vector */
304
305
start_kernel();
306
// not reached
307
}
308
309