Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/microblaze/kernel/setup.c
10817 views
1
/*
2
* Copyright (C) 2007-2009 Michal Simek <[email protected]>
3
* Copyright (C) 2007-2009 PetaLogix
4
* Copyright (C) 2006 Atmark Techno, Inc.
5
*
6
* This file is subject to the terms and conditions of the GNU General Public
7
* License. See the file "COPYING" in the main directory of this archive
8
* for more details.
9
*/
10
11
#include <linux/init.h>
12
#include <linux/string.h>
13
#include <linux/seq_file.h>
14
#include <linux/cpu.h>
15
#include <linux/initrd.h>
16
#include <linux/console.h>
17
#include <linux/debugfs.h>
18
19
#include <asm/setup.h>
20
#include <asm/sections.h>
21
#include <asm/page.h>
22
#include <linux/io.h>
23
#include <linux/bug.h>
24
#include <linux/param.h>
25
#include <linux/pci.h>
26
#include <linux/cache.h>
27
#include <linux/of_platform.h>
28
#include <linux/dma-mapping.h>
29
#include <asm/cacheflush.h>
30
#include <asm/entry.h>
31
#include <asm/cpuinfo.h>
32
33
#include <asm/system.h>
34
#include <asm/prom.h>
35
#include <asm/pgtable.h>
36
37
DEFINE_PER_CPU(unsigned int, KSP); /* Saved kernel stack pointer */
38
DEFINE_PER_CPU(unsigned int, KM); /* Kernel/user mode */
39
DEFINE_PER_CPU(unsigned int, ENTRY_SP); /* Saved SP on kernel entry */
40
DEFINE_PER_CPU(unsigned int, R11_SAVE); /* Temp variable for entry */
41
DEFINE_PER_CPU(unsigned int, CURRENT_SAVE); /* Saved current pointer */
42
43
unsigned int boot_cpuid;
44
char cmd_line[COMMAND_LINE_SIZE];
45
46
void __init setup_arch(char **cmdline_p)
47
{
48
*cmdline_p = cmd_line;
49
50
console_verbose();
51
52
unflatten_device_tree();
53
54
/* NOTE I think that this function is not necessary to call */
55
/* irq_early_init(); */
56
setup_cpuinfo();
57
58
microblaze_cache_init();
59
60
setup_memory();
61
62
xilinx_pci_init();
63
64
#if defined(CONFIG_SELFMOD_INTC) || defined(CONFIG_SELFMOD_TIMER)
65
printk(KERN_NOTICE "Self modified code enable\n");
66
#endif
67
68
#ifdef CONFIG_VT
69
#if defined(CONFIG_XILINX_CONSOLE)
70
conswitchp = &xil_con;
71
#elif defined(CONFIG_DUMMY_CONSOLE)
72
conswitchp = &dummy_con;
73
#endif
74
#endif
75
}
76
77
#ifdef CONFIG_MTD_UCLINUX
78
/* Handle both romfs and cramfs types, without generating unnecessary
79
code (ie no point checking for CRAMFS if it's not even enabled) */
80
inline unsigned get_romfs_len(unsigned *addr)
81
{
82
#ifdef CONFIG_ROMFS_FS
83
if (memcmp(&addr[0], "-rom1fs-", 8) == 0) /* romfs */
84
return be32_to_cpu(addr[2]);
85
#endif
86
87
#ifdef CONFIG_CRAMFS
88
if (addr[0] == le32_to_cpu(0x28cd3d45)) /* cramfs */
89
return le32_to_cpu(addr[1]);
90
#endif
91
return 0;
92
}
93
#endif /* CONFIG_MTD_UCLINUX_EBSS */
94
95
void __init machine_early_init(const char *cmdline, unsigned int ram,
96
unsigned int fdt, unsigned int msr)
97
{
98
unsigned long *src, *dst;
99
unsigned int offset = 0;
100
101
/* If CONFIG_MTD_UCLINUX is defined, assume ROMFS is at the
102
* end of kernel. There are two position which we want to check.
103
* The first is __init_end and the second __bss_start.
104
*/
105
#ifdef CONFIG_MTD_UCLINUX
106
int romfs_size;
107
unsigned int romfs_base;
108
char *old_klimit = klimit;
109
110
romfs_base = (ram ? ram : (unsigned int)&__init_end);
111
romfs_size = PAGE_ALIGN(get_romfs_len((unsigned *)romfs_base));
112
if (!romfs_size) {
113
romfs_base = (unsigned int)&__bss_start;
114
romfs_size = PAGE_ALIGN(get_romfs_len((unsigned *)romfs_base));
115
}
116
117
/* Move ROMFS out of BSS before clearing it */
118
if (romfs_size > 0) {
119
memmove(&_ebss, (int *)romfs_base, romfs_size);
120
klimit += romfs_size;
121
}
122
#endif
123
124
/* clearing bss section */
125
memset(__bss_start, 0, __bss_stop-__bss_start);
126
memset(_ssbss, 0, _esbss-_ssbss);
127
128
/* Copy command line passed from bootloader */
129
#ifndef CONFIG_CMDLINE_BOOL
130
if (cmdline && cmdline[0] != '\0')
131
strlcpy(cmd_line, cmdline, COMMAND_LINE_SIZE);
132
#endif
133
134
lockdep_init();
135
136
/* initialize device tree for usage in early_printk */
137
early_init_devtree((void *)_fdt_start);
138
139
#ifdef CONFIG_EARLY_PRINTK
140
setup_early_printk(NULL);
141
#endif
142
143
eprintk("Ramdisk addr 0x%08x, ", ram);
144
if (fdt)
145
eprintk("FDT at 0x%08x\n", fdt);
146
else
147
eprintk("Compiled-in FDT at 0x%08x\n",
148
(unsigned int)_fdt_start);
149
150
#ifdef CONFIG_MTD_UCLINUX
151
eprintk("Found romfs @ 0x%08x (0x%08x)\n",
152
romfs_base, romfs_size);
153
eprintk("#### klimit %p ####\n", old_klimit);
154
BUG_ON(romfs_size < 0); /* What else can we do? */
155
156
eprintk("Moved 0x%08x bytes from 0x%08x to 0x%08x\n",
157
romfs_size, romfs_base, (unsigned)&_ebss);
158
159
eprintk("New klimit: 0x%08x\n", (unsigned)klimit);
160
#endif
161
162
#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
163
if (msr)
164
eprintk("!!!Your kernel has setup MSR instruction but "
165
"CPU don't have it %x\n", msr);
166
#else
167
if (!msr)
168
eprintk("!!!Your kernel not setup MSR instruction but "
169
"CPU have it %x\n", msr);
170
#endif
171
172
/* Do not copy reset vectors. offset = 0x2 means skip the first
173
* two instructions. dst is pointer to MB vectors which are placed
174
* in block ram. If you want to copy reset vector setup offset to 0x0 */
175
#if !CONFIG_MANUAL_RESET_VECTOR
176
offset = 0x2;
177
#endif
178
dst = (unsigned long *) (offset * sizeof(u32));
179
for (src = __ivt_start + offset; src < __ivt_end; src++, dst++)
180
*dst = *src;
181
182
/* Initialize global data */
183
per_cpu(KM, 0) = 0x1; /* We start in kernel mode */
184
per_cpu(CURRENT_SAVE, 0) = (unsigned long)current;
185
}
186
187
#ifdef CONFIG_DEBUG_FS
188
struct dentry *of_debugfs_root;
189
190
static int microblaze_debugfs_init(void)
191
{
192
of_debugfs_root = debugfs_create_dir("microblaze", NULL);
193
194
return of_debugfs_root == NULL;
195
}
196
arch_initcall(microblaze_debugfs_init);
197
#endif
198
199
static int dflt_bus_notify(struct notifier_block *nb,
200
unsigned long action, void *data)
201
{
202
struct device *dev = data;
203
204
/* We are only intereted in device addition */
205
if (action != BUS_NOTIFY_ADD_DEVICE)
206
return 0;
207
208
set_dma_ops(dev, &dma_direct_ops);
209
210
return NOTIFY_DONE;
211
}
212
213
static struct notifier_block dflt_plat_bus_notifier = {
214
.notifier_call = dflt_bus_notify,
215
.priority = INT_MAX,
216
};
217
218
static int __init setup_bus_notifier(void)
219
{
220
bus_register_notifier(&platform_bus_type, &dflt_plat_bus_notifier);
221
222
return 0;
223
}
224
225
arch_initcall(setup_bus_notifier);
226
227