xref: /linux/arch/arc/kernel/setup.c (revision abe11ddea1d759f9995a9a4636c28c9b40856ca8)
1 /*
2  * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  */
8 
9 #include <linux/seq_file.h>
10 #include <linux/fs.h>
11 #include <linux/delay.h>
12 #include <linux/root_dev.h>
13 #include <linux/console.h>
14 #include <linux/module.h>
15 #include <linux/cpu.h>
16 #include <linux/of_fdt.h>
17 #include <asm/sections.h>
18 #include <asm/arcregs.h>
19 #include <asm/tlb.h>
20 #include <asm/cache.h>
21 #include <asm/setup.h>
22 #include <asm/page.h>
23 #include <asm/irq.h>
24 #include <asm/arcregs.h>
25 #include <asm/prom.h>
26 
27 #define FIX_PTR(x)  __asm__ __volatile__(";" : "+r"(x))
28 
29 int running_on_hw = 1;	/* vs. on ISS */
30 
31 char __initdata command_line[COMMAND_LINE_SIZE];
32 
33 struct task_struct *_current_task[NR_CPUS];	/* For stack switching */
34 
35 struct cpuinfo_arc cpuinfo_arc700[NR_CPUS];
36 
37 void __init read_arc_build_cfg_regs(void)
38 {
39 	read_decode_mmu_bcr();
40 	read_decode_cache_bcr();
41 }
42 
43 /*
44  * Initialize and setup the processor core
45  * This is called by all the CPUs thus should not do special case stuff
46  *    such as only for boot CPU etc
47  */
48 
49 void __init setup_processor(void)
50 {
51 	read_arc_build_cfg_regs();
52 	arc_init_IRQ();
53 	arc_mmu_init();
54 	arc_cache_init();
55 }
56 
57 void __init __attribute__((weak)) arc_platform_early_init(void)
58 {
59 }
60 
61 void __init setup_arch(char **cmdline_p)
62 {
63 	int rc;
64 
65 #ifdef CONFIG_CMDLINE_UBOOT
66 	/* Make sure that a whitespace is inserted before */
67 	strlcat(command_line, " ", sizeof(command_line));
68 #endif
69 	/*
70 	 * Append .config cmdline to base command line, which might already
71 	 * contain u-boot "bootargs" (handled by head.S, if so configured)
72 	 */
73 	strlcat(command_line, CONFIG_CMDLINE, sizeof(command_line));
74 
75 	/* Save unparsed command line copy for /proc/cmdline */
76 	strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
77 	*cmdline_p = command_line;
78 
79 	rc = setup_machine_fdt(__dtb_start);
80 
81 	/* To force early parsing of things like mem=xxx */
82 	parse_early_param();
83 
84 	/* Platform/board specific: e.g. early console registration */
85 	arc_platform_early_init();
86 
87 	setup_processor();
88 
89 	setup_arch_memory();
90 
91 	unflatten_device_tree();
92 
93 	/* Can be issue if someone passes cmd line arg "ro"
94 	 * But that is unlikely so keeping it as it is
95 	 */
96 	root_mountflags &= ~MS_RDONLY;
97 
98 	console_verbose();
99 
100 #if defined(CONFIG_VT) && defined(CONFIG_DUMMY_CONSOLE)
101 	conswitchp = &dummy_con;
102 #endif
103 
104 }
105 
106 /*
107  *  Get CPU information for use by the procfs.
108  */
109 
110 #define cpu_to_ptr(c)	((void *)(0xFFFF0000 | (unsigned int)(c)))
111 #define ptr_to_cpu(p)	(~0xFFFF0000UL & (unsigned int)(p))
112 
113 static int show_cpuinfo(struct seq_file *m, void *v)
114 {
115 	char *str;
116 	int cpu_id = ptr_to_cpu(v);
117 
118 	str = (char *)__get_free_page(GFP_TEMPORARY);
119 	if (!str)
120 		goto done;
121 
122 	seq_printf(m, "ARC700 #%d\n", cpu_id);
123 
124 	seq_printf(m, "Bogo MIPS : \t%lu.%02lu\n",
125 		   loops_per_jiffy / (500000 / HZ),
126 		   (loops_per_jiffy / (5000 / HZ)) % 100);
127 
128 	free_page((unsigned long)str);
129 done:
130 	seq_printf(m, "\n\n");
131 
132 	return 0;
133 }
134 
135 static void *c_start(struct seq_file *m, loff_t *pos)
136 {
137 	/*
138 	 * Callback returns cpu-id to iterator for show routine, NULL to stop.
139 	 * However since NULL is also a valid cpu-id (0), we use a round-about
140 	 * way to pass it w/o having to kmalloc/free a 2 byte string.
141 	 * Encode cpu-id as 0xFFcccc, which is decoded by show routine.
142 	 */
143 	return *pos < num_possible_cpus() ? cpu_to_ptr(*pos) : NULL;
144 }
145 
146 static void *c_next(struct seq_file *m, void *v, loff_t *pos)
147 {
148 	++*pos;
149 	return c_start(m, pos);
150 }
151 
152 static void c_stop(struct seq_file *m, void *v)
153 {
154 }
155 
156 const struct seq_operations cpuinfo_op = {
157 	.start	= c_start,
158 	.next	= c_next,
159 	.stop	= c_stop,
160 	.show	= show_cpuinfo
161 };
162 
163 static DEFINE_PER_CPU(struct cpu, cpu_topology);
164 
165 static int __init topology_init(void)
166 {
167 	int cpu;
168 
169 	for_each_present_cpu(cpu)
170 	    register_cpu(&per_cpu(cpu_topology, cpu), cpu);
171 
172 	return 0;
173 }
174 
175 subsys_initcall(topology_init);
176