aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r--arch/arm/kernel/Makefile2
-rw-r--r--arch/arm/kernel/etm.c641
-rw-r--r--arch/arm/kernel/head-nommu.S2
-rw-r--r--arch/arm/kernel/head.S2
-rw-r--r--arch/arm/kernel/vmlinux.lds.S85
5 files changed, 671 insertions, 61 deletions
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 79087dd6d869..e7ccf7e697ce 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -17,6 +17,8 @@ obj-y := compat.o elf.o entry-armv.o entry-common.o irq.o \
17 process.o ptrace.o return_address.o setup.o signal.o \ 17 process.o ptrace.o return_address.o setup.o signal.o \
18 sys_arm.o stacktrace.o time.o traps.o 18 sys_arm.o stacktrace.o time.o traps.o
19 19
20obj-$(CONFIG_OC_ETM) += etm.o
21
20obj-$(CONFIG_ISA_DMA_API) += dma.o 22obj-$(CONFIG_ISA_DMA_API) += dma.o
21obj-$(CONFIG_ARCH_ACORN) += ecard.o 23obj-$(CONFIG_ARCH_ACORN) += ecard.o
22obj-$(CONFIG_FIQ) += fiq.o 24obj-$(CONFIG_FIQ) += fiq.o
diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c
new file mode 100644
index 000000000000..827753966301
--- /dev/null
+++ b/arch/arm/kernel/etm.c
@@ -0,0 +1,641 @@
1/*
2 * linux/arch/arm/kernel/etm.c
3 *
4 * Driver for ARM's Embedded Trace Macrocell and Embedded Trace Buffer.
5 *
6 * Copyright (C) 2009 Nokia Corporation.
7 * Alexander Shishkin
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/types.h>
17#include <linux/io.h>
18#include <linux/sysrq.h>
19#include <linux/device.h>
20#include <linux/clk.h>
21#include <linux/amba/bus.h>
22#include <linux/fs.h>
23#include <linux/uaccess.h>
24#include <linux/miscdevice.h>
25#include <linux/vmalloc.h>
26#include <linux/mutex.h>
27#include <asm/hardware/coresight.h>
28#include <asm/sections.h>
29
30MODULE_LICENSE("GPL");
31MODULE_AUTHOR("Alexander Shishkin");
32
33static struct tracectx tracer;
34
35static inline bool trace_isrunning(struct tracectx *t)
36{
37 return !!(t->flags & TRACER_RUNNING);
38}
39
40static int etm_setup_address_range(struct tracectx *t, int n,
41 unsigned long start, unsigned long end, int exclude, int data)
42{
43 u32 flags = ETMAAT_ARM | ETMAAT_IGNCONTEXTID | ETMAAT_NSONLY | \
44 ETMAAT_NOVALCMP;
45
46 if (n < 1 || n > t->ncmppairs)
47 return -EINVAL;
48
49 /* comparators and ranges are numbered starting with 1 as opposed
50 * to bits in a word */
51 n--;
52
53 if (data)
54 flags |= ETMAAT_DLOADSTORE;
55 else
56 flags |= ETMAAT_IEXEC;
57
58 /* first comparator for the range */
59 etm_writel(t, flags, ETMR_COMP_ACC_TYPE(n * 2));
60 etm_writel(t, start, ETMR_COMP_VAL(n * 2));
61
62 /* second comparator is right next to it */
63 etm_writel(t, flags, ETMR_COMP_ACC_TYPE(n * 2 + 1));
64 etm_writel(t, end, ETMR_COMP_VAL(n * 2 + 1));
65
66 flags = exclude ? ETMTE_INCLEXCL : 0;
67 etm_writel(t, flags | (1 << n), ETMR_TRACEENCTRL);
68
69 return 0;
70}
71
72static int trace_start(struct tracectx *t)
73{
74 u32 v;
75 unsigned long timeout = TRACER_TIMEOUT;
76
77 etb_unlock(t);
78
79 etb_writel(t, 0, ETBR_FORMATTERCTRL);
80 etb_writel(t, 1, ETBR_CTRL);
81
82 etb_lock(t);
83
84 /* configure etm */
85 v = ETMCTRL_OPTS | ETMCTRL_PROGRAM | ETMCTRL_PORTSIZE(t->etm_portsz);
86
87 if (t->flags & TRACER_CYCLE_ACC)
88 v |= ETMCTRL_CYCLEACCURATE;
89
90 etm_unlock(t);
91
92 etm_writel(t, v, ETMR_CTRL);
93
94 while (!(etm_readl(t, ETMR_CTRL) & ETMCTRL_PROGRAM) && --timeout)
95 ;
96 if (!timeout) {
97 dev_dbg(t->dev, "Waiting for progbit to assert timed out\n");
98 etm_lock(t);
99 return -EFAULT;
100 }
101
102 etm_setup_address_range(t, 1, (unsigned long)_stext,
103 (unsigned long)_etext, 0, 0);
104 etm_writel(t, 0, ETMR_TRACEENCTRL2);
105 etm_writel(t, 0, ETMR_TRACESSCTRL);
106 etm_writel(t, 0x6f, ETMR_TRACEENEVT);
107
108 v &= ~ETMCTRL_PROGRAM;
109 v |= ETMCTRL_PORTSEL;
110
111 etm_writel(t, v, ETMR_CTRL);
112
113 timeout = TRACER_TIMEOUT;
114 while (etm_readl(t, ETMR_CTRL) & ETMCTRL_PROGRAM && --timeout)
115 ;
116 if (!timeout) {
117 dev_dbg(t->dev, "Waiting for progbit to deassert timed out\n");
118 etm_lock(t);
119 return -EFAULT;
120 }
121
122 etm_lock(t);
123
124 t->flags |= TRACER_RUNNING;
125
126 return 0;
127}
128
129static int trace_stop(struct tracectx *t)
130{
131 unsigned long timeout = TRACER_TIMEOUT;
132
133 etm_unlock(t);
134
135 etm_writel(t, 0x440, ETMR_CTRL);
136 while (!(etm_readl(t, ETMR_CTRL) & ETMCTRL_PROGRAM) && --timeout)
137 ;
138 if (!timeout) {
139 dev_dbg(t->dev, "Waiting for progbit to assert timed out\n");
140 etm_lock(t);
141 return -EFAULT;
142 }
143
144 etm_lock(t);
145
146 etb_unlock(t);
147 etb_writel(t, ETBFF_MANUAL_FLUSH, ETBR_FORMATTERCTRL);
148
149 timeout = TRACER_TIMEOUT;
150 while (etb_readl(t, ETBR_FORMATTERCTRL) &
151 ETBFF_MANUAL_FLUSH && --timeout)
152 ;
153 if (!timeout) {
154 dev_dbg(t->dev, "Waiting for formatter flush to commence "
155 "timed out\n");
156 etb_lock(t);
157 return -EFAULT;
158 }
159
160 etb_writel(t, 0, ETBR_CTRL);
161
162 etb_lock(t);
163
164 t->flags &= ~TRACER_RUNNING;
165
166 return 0;
167}
168
169static int etb_getdatalen(struct tracectx *t)
170{
171 u32 v;
172 int rp, wp;
173
174 v = etb_readl(t, ETBR_STATUS);
175
176 if (v & 1)
177 return t->etb_bufsz;
178
179 rp = etb_readl(t, ETBR_READADDR);
180 wp = etb_readl(t, ETBR_WRITEADDR);
181
182 if (rp > wp) {
183 etb_writel(t, 0, ETBR_READADDR);
184 etb_writel(t, 0, ETBR_WRITEADDR);
185
186 return 0;
187 }
188
189 return wp - rp;
190}
191
192/* sysrq+v will always stop the running trace and leave it at that */
193static void etm_dump(void)
194{
195 struct tracectx *t = &tracer;
196 u32 first = 0;
197 int length;
198
199 if (!t->etb_regs) {
200 printk(KERN_INFO "No tracing hardware found\n");
201 return;
202 }
203
204 if (trace_isrunning(t))
205 trace_stop(t);
206
207 etb_unlock(t);
208
209 length = etb_getdatalen(t);
210
211 if (length == t->etb_bufsz)
212 first = etb_readl(t, ETBR_WRITEADDR);
213
214 etb_writel(t, first, ETBR_READADDR);
215
216 printk(KERN_INFO "Trace buffer contents length: %d\n", length);
217 printk(KERN_INFO "--- ETB buffer begin ---\n");
218 for (; length; length--)
219 printk("%08x", cpu_to_be32(etb_readl(t, ETBR_READMEM)));
220 printk(KERN_INFO "\n--- ETB buffer end ---\n");
221
222 /* deassert the overflow bit */
223 etb_writel(t, 1, ETBR_CTRL);
224 etb_writel(t, 0, ETBR_CTRL);
225
226 etb_writel(t, 0, ETBR_TRIGGERCOUNT);
227 etb_writel(t, 0, ETBR_READADDR);
228 etb_writel(t, 0, ETBR_WRITEADDR);
229
230 etb_lock(t);
231}
232
233static void sysrq_etm_dump(int key, struct tty_struct *tty)
234{
235 dev_dbg(tracer.dev, "Dumping ETB buffer\n");
236 etm_dump();
237}
238
239static struct sysrq_key_op sysrq_etm_op = {
240 .handler = sysrq_etm_dump,
241 .help_msg = "ETM buffer dump",
242 .action_msg = "etm",
243};
244
245static int etb_open(struct inode *inode, struct file *file)
246{
247 if (!tracer.etb_regs)
248 return -ENODEV;
249
250 file->private_data = &tracer;
251
252 return nonseekable_open(inode, file);
253}
254
255static ssize_t etb_read(struct file *file, char __user *data,
256 size_t len, loff_t *ppos)
257{
258 int total, i;
259 long length;
260 struct tracectx *t = file->private_data;
261 u32 first = 0;
262 u32 *buf;
263
264 mutex_lock(&t->mutex);
265
266 if (trace_isrunning(t)) {
267 length = 0;
268 goto out;
269 }
270
271 etb_unlock(t);
272
273 total = etb_getdatalen(t);
274 if (total == t->etb_bufsz)
275 first = etb_readl(t, ETBR_WRITEADDR);
276
277 etb_writel(t, first, ETBR_READADDR);
278
279 length = min(total * 4, (int)len);
280 buf = vmalloc(length);
281
282 dev_dbg(t->dev, "ETB buffer length: %d\n", total);
283 dev_dbg(t->dev, "ETB status reg: %x\n", etb_readl(t, ETBR_STATUS));
284 for (i = 0; i < length / 4; i++)
285 buf[i] = etb_readl(t, ETBR_READMEM);
286
287 /* the only way to deassert overflow bit in ETB status is this */
288 etb_writel(t, 1, ETBR_CTRL);
289 etb_writel(t, 0, ETBR_CTRL);
290
291 etb_writel(t, 0, ETBR_WRITEADDR);
292 etb_writel(t, 0, ETBR_READADDR);
293 etb_writel(t, 0, ETBR_TRIGGERCOUNT);
294
295 etb_lock(t);
296
297 length -= copy_to_user(data, buf, length);
298 vfree(buf);
299
300out:
301 mutex_unlock(&t->mutex);
302
303 return length;
304}
305
306static int etb_release(struct inode *inode, struct file *file)
307{
308 /* there's nothing to do here, actually */
309 return 0;
310}
311
312static const struct file_operations etb_fops = {
313 .owner = THIS_MODULE,
314 .read = etb_read,
315 .open = etb_open,
316 .release = etb_release,
317};
318
319static struct miscdevice etb_miscdev = {
320 .name = "tracebuf",
321 .minor = 0,
322 .fops = &etb_fops,
323};
324
325static int __init etb_probe(struct amba_device *dev, struct amba_id *id)
326{
327 struct tracectx *t = &tracer;
328 int ret = 0;
329
330 ret = amba_request_regions(dev, NULL);
331 if (ret)
332 goto out;
333
334 t->etb_regs = ioremap_nocache(dev->res.start, resource_size(&dev->res));
335 if (!t->etb_regs) {
336 ret = -ENOMEM;
337 goto out_release;
338 }
339
340 amba_set_drvdata(dev, t);
341
342 etb_miscdev.parent = &dev->dev;
343
344 ret = misc_register(&etb_miscdev);
345 if (ret)
346 goto out_unmap;
347
348 t->emu_clk = clk_get(&dev->dev, "emu_src_ck");
349 if (IS_ERR(t->emu_clk)) {
350 dev_dbg(&dev->dev, "Failed to obtain emu_src_ck.\n");
351 return -EFAULT;
352 }
353
354 clk_enable(t->emu_clk);
355
356 etb_unlock(t);
357 t->etb_bufsz = etb_readl(t, ETBR_DEPTH);
358 dev_dbg(&dev->dev, "Size: %x\n", t->etb_bufsz);
359
360 /* make sure trace capture is disabled */
361 etb_writel(t, 0, ETBR_CTRL);
362 etb_writel(t, 0x1000, ETBR_FORMATTERCTRL);
363 etb_lock(t);
364
365 dev_dbg(&dev->dev, "ETB AMBA driver initialized.\n");
366
367out:
368 return ret;
369
370out_unmap:
371 amba_set_drvdata(dev, NULL);
372 iounmap(t->etb_regs);
373
374out_release:
375 amba_release_regions(dev);
376
377 return ret;
378}
379
380static int etb_remove(struct amba_device *dev)
381{
382 struct tracectx *t = amba_get_drvdata(dev);
383
384 amba_set_drvdata(dev, NULL);
385
386 iounmap(t->etb_regs);
387 t->etb_regs = NULL;
388
389 clk_disable(t->emu_clk);
390 clk_put(t->emu_clk);
391
392 amba_release_regions(dev);
393
394 return 0;
395}
396
397static struct amba_id etb_ids[] = {
398 {
399 .id = 0x0003b907,
400 .mask = 0x0007ffff,
401 },
402 { 0, 0 },
403};
404
405static struct amba_driver etb_driver = {
406 .drv = {
407 .name = "etb",
408 .owner = THIS_MODULE,
409 },
410 .probe = etb_probe,
411 .remove = etb_remove,
412 .id_table = etb_ids,
413};
414
415/* use a sysfs file "trace_running" to start/stop tracing */
416static ssize_t trace_running_show(struct kobject *kobj,
417 struct kobj_attribute *attr,
418 char *buf)
419{
420 return sprintf(buf, "%x\n", trace_isrunning(&tracer));
421}
422
423static ssize_t trace_running_store(struct kobject *kobj,
424 struct kobj_attribute *attr,
425 const char *buf, size_t n)
426{
427 unsigned int value;
428 int ret;
429
430 if (sscanf(buf, "%u", &value) != 1)
431 return -EINVAL;
432
433 mutex_lock(&tracer.mutex);
434 ret = value ? trace_start(&tracer) : trace_stop(&tracer);
435 mutex_unlock(&tracer.mutex);
436
437 return ret ? : n;
438}
439
440static struct kobj_attribute trace_running_attr =
441 __ATTR(trace_running, 0644, trace_running_show, trace_running_store);
442
443static ssize_t trace_info_show(struct kobject *kobj,
444 struct kobj_attribute *attr,
445 char *buf)
446{
447 u32 etb_wa, etb_ra, etb_st, etb_fc, etm_ctrl, etm_st;
448 int datalen;
449
450 etb_unlock(&tracer);
451 datalen = etb_getdatalen(&tracer);
452 etb_wa = etb_readl(&tracer, ETBR_WRITEADDR);
453 etb_ra = etb_readl(&tracer, ETBR_READADDR);
454 etb_st = etb_readl(&tracer, ETBR_STATUS);
455 etb_fc = etb_readl(&tracer, ETBR_FORMATTERCTRL);
456 etb_lock(&tracer);
457
458 etm_unlock(&tracer);
459 etm_ctrl = etm_readl(&tracer, ETMR_CTRL);
460 etm_st = etm_readl(&tracer, ETMR_STATUS);
461 etm_lock(&tracer);
462
463 return sprintf(buf, "Trace buffer len: %d\nComparator pairs: %d\n"
464 "ETBR_WRITEADDR:\t%08x\n"
465 "ETBR_READADDR:\t%08x\n"
466 "ETBR_STATUS:\t%08x\n"
467 "ETBR_FORMATTERCTRL:\t%08x\n"
468 "ETMR_CTRL:\t%08x\n"
469 "ETMR_STATUS:\t%08x\n",
470 datalen,
471 tracer.ncmppairs,
472 etb_wa,
473 etb_ra,
474 etb_st,
475 etb_fc,
476 etm_ctrl,
477 etm_st
478 );
479}
480
481static struct kobj_attribute trace_info_attr =
482 __ATTR(trace_info, 0444, trace_info_show, NULL);
483
484static ssize_t trace_mode_show(struct kobject *kobj,
485 struct kobj_attribute *attr,
486 char *buf)
487{
488 return sprintf(buf, "%d %d\n",
489 !!(tracer.flags & TRACER_CYCLE_ACC),
490 tracer.etm_portsz);
491}
492
493static ssize_t trace_mode_store(struct kobject *kobj,
494 struct kobj_attribute *attr,
495 const char *buf, size_t n)
496{
497 unsigned int cycacc, portsz;
498
499 if (sscanf(buf, "%u %u", &cycacc, &portsz) != 2)
500 return -EINVAL;
501
502 mutex_lock(&tracer.mutex);
503 if (cycacc)
504 tracer.flags |= TRACER_CYCLE_ACC;
505 else
506 tracer.flags &= ~TRACER_CYCLE_ACC;
507
508 tracer.etm_portsz = portsz & 0x0f;
509 mutex_unlock(&tracer.mutex);
510
511 return n;
512}
513
514static struct kobj_attribute trace_mode_attr =
515 __ATTR(trace_mode, 0644, trace_mode_show, trace_mode_store);
516
517static int __init etm_probe(struct amba_device *dev, struct amba_id *id)
518{
519 struct tracectx *t = &tracer;
520 int ret = 0;
521
522 if (t->etm_regs) {
523 dev_dbg(&dev->dev, "ETM already initialized\n");
524 ret = -EBUSY;
525 goto out;
526 }
527
528 ret = amba_request_regions(dev, NULL);
529 if (ret)
530 goto out;
531
532 t->etm_regs = ioremap_nocache(dev->res.start, resource_size(&dev->res));
533 if (!t->etm_regs) {
534 ret = -ENOMEM;
535 goto out_release;
536 }
537
538 amba_set_drvdata(dev, t);
539
540 mutex_init(&t->mutex);
541 t->dev = &dev->dev;
542 t->flags = TRACER_CYCLE_ACC;
543 t->etm_portsz = 1;
544
545 etm_unlock(t);
546 ret = etm_readl(t, CSCR_PRSR);
547
548 t->ncmppairs = etm_readl(t, ETMR_CONFCODE) & 0xf;
549 etm_writel(t, 0x440, ETMR_CTRL);
550 etm_lock(t);
551
552 ret = sysfs_create_file(&dev->dev.kobj,
553 &trace_running_attr.attr);
554 if (ret)
555 goto out_unmap;
556
557 /* failing to create any of these two is not fatal */
558 ret = sysfs_create_file(&dev->dev.kobj, &trace_info_attr.attr);
559 if (ret)
560 dev_dbg(&dev->dev, "Failed to create trace_info in sysfs\n");
561
562 ret = sysfs_create_file(&dev->dev.kobj, &trace_mode_attr.attr);
563 if (ret)
564 dev_dbg(&dev->dev, "Failed to create trace_mode in sysfs\n");
565
566 dev_dbg(t->dev, "ETM AMBA driver initialized.\n");
567
568out:
569 return ret;
570
571out_unmap:
572 amba_set_drvdata(dev, NULL);
573 iounmap(t->etm_regs);
574
575out_release:
576 amba_release_regions(dev);
577
578 return ret;
579}
580
581static int etm_remove(struct amba_device *dev)
582{
583 struct tracectx *t = amba_get_drvdata(dev);
584
585 amba_set_drvdata(dev, NULL);
586
587 iounmap(t->etm_regs);
588 t->etm_regs = NULL;
589
590 amba_release_regions(dev);
591
592 sysfs_remove_file(&dev->dev.kobj, &trace_running_attr.attr);
593 sysfs_remove_file(&dev->dev.kobj, &trace_info_attr.attr);
594 sysfs_remove_file(&dev->dev.kobj, &trace_mode_attr.attr);
595
596 return 0;
597}
598
599static struct amba_id etm_ids[] = {
600 {
601 .id = 0x0003b921,
602 .mask = 0x0007ffff,
603 },
604 { 0, 0 },
605};
606
607static struct amba_driver etm_driver = {
608 .drv = {
609 .name = "etm",
610 .owner = THIS_MODULE,
611 },
612 .probe = etm_probe,
613 .remove = etm_remove,
614 .id_table = etm_ids,
615};
616
617static int __init etm_init(void)
618{
619 int retval;
620
621 retval = amba_driver_register(&etb_driver);
622 if (retval) {
623 printk(KERN_ERR "Failed to register etb\n");
624 return retval;
625 }
626
627 retval = amba_driver_register(&etm_driver);
628 if (retval) {
629 amba_driver_unregister(&etb_driver);
630 printk(KERN_ERR "Failed to probe etm\n");
631 return retval;
632 }
633
634 /* not being able to install this handler is not fatal */
635 (void)register_sysrq_key('v', &sysrq_etm_op);
636
637 return 0;
638}
639
640device_initcall(etm_init);
641
diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S
index e5dfc2895e24..573b803dc6bf 100644
--- a/arch/arm/kernel/head-nommu.S
+++ b/arch/arm/kernel/head-nommu.S
@@ -32,7 +32,7 @@
32 * numbers for r1. 32 * numbers for r1.
33 * 33 *
34 */ 34 */
35 .section ".text.head", "ax" 35 __HEAD
36ENTRY(stext) 36ENTRY(stext)
37 setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode 37 setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode
38 @ and irqs disabled 38 @ and irqs disabled
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 38ccbe1d3b2c..eb62bf947212 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -74,7 +74,7 @@
74 * crap here - that's what the boot loader (or in extreme, well justified 74 * crap here - that's what the boot loader (or in extreme, well justified
75 * circumstances, zImage) is for. 75 * circumstances, zImage) is for.
76 */ 76 */
77 .section ".text.head", "ax" 77 __HEAD
78ENTRY(stext) 78ENTRY(stext)
79 setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode 79 setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode
80 @ and irqs disabled 80 @ and irqs disabled
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index aecf87dfbaec..71151bd87a36 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -24,13 +24,11 @@ SECTIONS
24#else 24#else
25 . = PAGE_OFFSET + TEXT_OFFSET; 25 . = PAGE_OFFSET + TEXT_OFFSET;
26#endif 26#endif
27 .text.head : {
28 _stext = .;
29 _sinittext = .;
30 *(.text.head)
31 }
32 27
33 .init : { /* Init code and data */ 28 .init : { /* Init code and data */
29 _stext = .;
30 _sinittext = .;
31 HEAD_TEXT
34 INIT_TEXT 32 INIT_TEXT
35 _einittext = .; 33 _einittext = .;
36 __proc_info_begin = .; 34 __proc_info_begin = .;
@@ -42,43 +40,31 @@ SECTIONS
42 __tagtable_begin = .; 40 __tagtable_begin = .;
43 *(.taglist.init) 41 *(.taglist.init)
44 __tagtable_end = .; 42 __tagtable_end = .;
45 . = ALIGN(16); 43
46 __setup_start = .; 44 INIT_SETUP(16)
47 *(.init.setup) 45
48 __setup_end = .;
49 __early_begin = .; 46 __early_begin = .;
50 *(.early_param.init) 47 *(.early_param.init)
51 __early_end = .; 48 __early_end = .;
52 __initcall_start = .; 49
53 INITCALLS 50 INIT_CALLS
54 __initcall_end = .; 51 CON_INITCALL
55 __con_initcall_start = .; 52 SECURITY_INITCALL
56 *(.con_initcall.init) 53 INIT_RAM_FS
57 __con_initcall_end = .; 54
58 __security_initcall_start = .;
59 *(.security_initcall.init)
60 __security_initcall_end = .;
61#ifdef CONFIG_BLK_DEV_INITRD
62 . = ALIGN(32);
63 __initramfs_start = .;
64 usr/built-in.o(.init.ramfs)
65 __initramfs_end = .;
66#endif
67 . = ALIGN(PAGE_SIZE);
68 __per_cpu_load = .;
69 __per_cpu_start = .;
70 *(.data.percpu.page_aligned)
71 *(.data.percpu)
72 *(.data.percpu.shared_aligned)
73 __per_cpu_end = .;
74#ifndef CONFIG_XIP_KERNEL 55#ifndef CONFIG_XIP_KERNEL
75 __init_begin = _stext; 56 __init_begin = _stext;
76 INIT_DATA 57 INIT_DATA
77 . = ALIGN(PAGE_SIZE);
78 __init_end = .;
79#endif 58#endif
80 } 59 }
81 60
61 PERCPU(PAGE_SIZE)
62
63#ifndef CONFIG_XIP_KERNEL
64 . = ALIGN(PAGE_SIZE);
65 __init_end = .;
66#endif
67
82 /DISCARD/ : { /* Exit code and data */ 68 /DISCARD/ : { /* Exit code and data */
83 EXIT_TEXT 69 EXIT_TEXT
84 EXIT_DATA 70 EXIT_DATA
@@ -157,7 +143,7 @@ SECTIONS
157 * first, the init task union, aligned 143 * first, the init task union, aligned
158 * to an 8192 byte boundary. 144 * to an 8192 byte boundary.
159 */ 145 */
160 *(.data.init_task) 146 INIT_TASK_DATA(THREAD_SIZE)
161 147
162#ifdef CONFIG_XIP_KERNEL 148#ifdef CONFIG_XIP_KERNEL
163 . = ALIGN(PAGE_SIZE); 149 . = ALIGN(PAGE_SIZE);
@@ -167,17 +153,8 @@ SECTIONS
167 __init_end = .; 153 __init_end = .;
168#endif 154#endif
169 155
170 . = ALIGN(PAGE_SIZE); 156 NOSAVE_DATA
171 __nosave_begin = .; 157 CACHELINE_ALIGNED_DATA(32)
172 *(.data.nosave)
173 . = ALIGN(PAGE_SIZE);
174 __nosave_end = .;
175
176 /*
177 * then the cacheline aligned data
178 */
179 . = ALIGN(32);
180 *(.data.cacheline_aligned)
181 158
182 /* 159 /*
183 * The exception fixup table (might need resorting at runtime) 160 * The exception fixup table (might need resorting at runtime)
@@ -256,20 +233,10 @@ SECTIONS
256 } 233 }
257#endif 234#endif
258 235
259 .bss : { 236 BSS_SECTION(0, 0, 0)
260 __bss_start = .; /* BSS */ 237 _end = .;
261 *(.bss) 238
262 *(COMMON) 239 STABS_DEBUG
263 __bss_stop = .;
264 _end = .;
265 }
266 /* Stabs debugging sections. */
267 .stab 0 : { *(.stab) }
268 .stabstr 0 : { *(.stabstr) }
269 .stab.excl 0 : { *(.stab.excl) }
270 .stab.exclstr 0 : { *(.stab.exclstr) }
271 .stab.index 0 : { *(.stab.index) }
272 .stab.indexstr 0 : { *(.stab.indexstr) }
273 .comment 0 : { *(.comment) } 240 .comment 0 : { *(.comment) }
274} 241}
275 242