aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuo Ren <ren_guo@c-sky.com>2018-09-05 02:25:07 -0400
committerGuo Ren <ren_guo@c-sky.com>2018-10-25 11:36:19 -0400
commit9143a9359d051142081b26c3726c928f965c5eb7 (patch)
treedc479bde8b6fe4faf45f2b53519a019708bfe649
parent7c768f845104b7c96954ad536be29797eff6a434 (diff)
csky: Kernel booting
This patch add boot code. Thx boot params is all in dtb and it's the only way to let kernel get bootloader param information. Signed-off-by: Guo Ren <ren_guo@c-sky.com> Reviewed-by: Arnd Bergmann <arnd@arndb.de>
-rw-r--r--arch/csky/kernel/head.S77
-rw-r--r--arch/csky/kernel/setup.c162
-rw-r--r--arch/csky/kernel/vmlinux.lds.S66
3 files changed, 305 insertions, 0 deletions
diff --git a/arch/csky/kernel/head.S b/arch/csky/kernel/head.S
new file mode 100644
index 000000000000..9c4ec473b76b
--- /dev/null
+++ b/arch/csky/kernel/head.S
@@ -0,0 +1,77 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2
3#include <linux/linkage.h>
4#include <linux/init.h>
5#include <asm/page.h>
6#include <abi/entry.h>
7
8__HEAD
9ENTRY(_start)
10 /* set super user mode */
11 lrw a3, DEFAULT_PSR_VALUE
12 mtcr a3, psr
13 psrset ee
14
15 SETUP_MMU a3
16
17 /* set stack point */
18 lrw a3, init_thread_union + THREAD_SIZE
19 mov sp, a3
20
21 jmpi csky_start
22END(_start)
23
24#ifdef CONFIG_SMP
25.align 10
26ENTRY(_start_smp_secondary)
27 /* Invalid I/Dcache BTB BHT */
28 movi a3, 7
29 lsli a3, 16
30 addi a3, (1<<4) | 3
31 mtcr a3, cr17
32
33 tlbi.alls
34
35 /* setup PAGEMASK */
36 movi a3, 0
37 mtcr a3, cr<6, 15>
38
39 /* setup MEL0/MEL1 */
40 grs a0, _start_smp_pc
41_start_smp_pc:
42 bmaski a1, 13
43 andn a0, a1
44 movi a1, 0x00000006
45 movi a2, 0x00001006
46 or a1, a0
47 or a2, a0
48 mtcr a1, cr<2, 15>
49 mtcr a2, cr<3, 15>
50
51 /* setup MEH */
52 mtcr a0, cr<4, 15>
53
54 /* write TLB */
55 bgeni a3, 28
56 mtcr a3, cr<8, 15>
57
58 SETUP_MMU a3
59
60 /* enable MMU */
61 movi a3, 1
62 mtcr a3, cr18
63
64 jmpi _goto_mmu_on
65_goto_mmu_on:
66 lrw a3, DEFAULT_PSR_VALUE
67 mtcr a3, psr
68 psrset ee
69
70 /* set stack point */
71 lrw a3, secondary_stack
72 ld.w a3, (a3, 0)
73 mov sp, a3
74
75 jmpi csky_start_secondary
76END(_start_smp_secondary)
77#endif
diff --git a/arch/csky/kernel/setup.c b/arch/csky/kernel/setup.c
new file mode 100644
index 000000000000..a5e3ab1d5360
--- /dev/null
+++ b/arch/csky/kernel/setup.c
@@ -0,0 +1,162 @@
1// SPDX-License-Identifier: GPL-2.0
2// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
3
4#include <linux/console.h>
5#include <linux/memblock.h>
6#include <linux/bootmem.h>
7#include <linux/initrd.h>
8#include <linux/of.h>
9#include <linux/of_fdt.h>
10#include <linux/start_kernel.h>
11#include <linux/dma-contiguous.h>
12#include <linux/screen_info.h>
13#include <asm/sections.h>
14#include <asm/mmu_context.h>
15#include <asm/pgalloc.h>
16
17#ifdef CONFIG_DUMMY_CONSOLE
18struct screen_info screen_info = {
19 .orig_video_lines = 30,
20 .orig_video_cols = 80,
21 .orig_video_mode = 0,
22 .orig_video_ega_bx = 0,
23 .orig_video_isVGA = 1,
24 .orig_video_points = 8
25};
26#endif
27
28phys_addr_t __init_memblock memblock_end_of_REG0(void)
29{
30 return (memblock.memory.regions[0].base +
31 memblock.memory.regions[0].size);
32}
33
34phys_addr_t __init_memblock memblock_start_of_REG1(void)
35{
36 return memblock.memory.regions[1].base;
37}
38
39size_t __init_memblock memblock_size_of_REG1(void)
40{
41 return memblock.memory.regions[1].size;
42}
43
44static void __init csky_memblock_init(void)
45{
46 unsigned long zone_size[MAX_NR_ZONES];
47 unsigned long zhole_size[MAX_NR_ZONES];
48 signed long size;
49
50 memblock_reserve(__pa(_stext), _end - _stext);
51#ifdef CONFIG_BLK_DEV_INITRD
52 memblock_reserve(__pa(initrd_start), initrd_end - initrd_start);
53#endif
54
55 early_init_fdt_reserve_self();
56 early_init_fdt_scan_reserved_mem();
57
58 memblock_dump_all();
59
60 memset(zone_size, 0, sizeof(zone_size));
61 memset(zhole_size, 0, sizeof(zhole_size));
62
63 min_low_pfn = PFN_UP(memblock_start_of_DRAM());
64 max_pfn = PFN_DOWN(memblock_end_of_DRAM());
65
66 max_low_pfn = PFN_UP(memblock_end_of_REG0());
67 if (max_low_pfn == 0)
68 max_low_pfn = max_pfn;
69
70 size = max_pfn - min_low_pfn;
71
72 if (memblock.memory.cnt > 1) {
73 zone_size[ZONE_NORMAL] =
74 PFN_DOWN(memblock_start_of_REG1()) - min_low_pfn;
75 zhole_size[ZONE_NORMAL] =
76 PFN_DOWN(memblock_start_of_REG1()) - max_low_pfn;
77 } else {
78 if (size <= PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET))
79 zone_size[ZONE_NORMAL] = max_pfn - min_low_pfn;
80 else {
81 zone_size[ZONE_NORMAL] =
82 PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET);
83 max_low_pfn = min_low_pfn + zone_size[ZONE_NORMAL];
84 }
85 }
86
87#ifdef CONFIG_HIGHMEM
88 size = 0;
89 if (memblock.memory.cnt > 1) {
90 size = PFN_DOWN(memblock_size_of_REG1());
91 highstart_pfn = PFN_DOWN(memblock_start_of_REG1());
92 } else {
93 size = max_pfn - min_low_pfn -
94 PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET);
95 highstart_pfn = min_low_pfn +
96 PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET);
97 }
98
99 if (size > 0)
100 zone_size[ZONE_HIGHMEM] = size;
101
102 highend_pfn = max_pfn;
103#endif
104 memblock_set_current_limit(PFN_PHYS(max_low_pfn));
105
106 dma_contiguous_reserve(0);
107
108 free_area_init_node(0, zone_size, min_low_pfn, zhole_size);
109}
110
111void __init setup_arch(char **cmdline_p)
112{
113 *cmdline_p = boot_command_line;
114
115 console_verbose();
116
117 pr_info("Phys. mem: %ldMB\n",
118 (unsigned long) memblock_phys_mem_size()/1024/1024);
119
120 init_mm.start_code = (unsigned long) _stext;
121 init_mm.end_code = (unsigned long) _etext;
122 init_mm.end_data = (unsigned long) _edata;
123 init_mm.brk = (unsigned long) _end;
124
125 parse_early_param();
126
127 csky_memblock_init();
128
129 unflatten_and_copy_device_tree();
130
131#ifdef CONFIG_SMP
132 setup_smp();
133#endif
134
135 sparse_init();
136
137#ifdef CONFIG_HIGHMEM
138 kmap_init();
139#endif
140
141#if defined(CONFIG_VT) && defined(CONFIG_DUMMY_CONSOLE)
142 conswitchp = &dummy_con;
143#endif
144}
145
146asmlinkage __visible void __init csky_start(unsigned int unused, void *param)
147{
148 /* Clean up bss section */
149 memset(__bss_start, 0, __bss_stop - __bss_start);
150
151 pre_trap_init();
152 pre_mmu_init();
153
154 if (param == NULL)
155 early_init_dt_scan(__dtb_start);
156 else
157 early_init_dt_scan(param);
158
159 start_kernel();
160
161 asm volatile("br .\n");
162}
diff --git a/arch/csky/kernel/vmlinux.lds.S b/arch/csky/kernel/vmlinux.lds.S
new file mode 100644
index 000000000000..ae7961b973f2
--- /dev/null
+++ b/arch/csky/kernel/vmlinux.lds.S
@@ -0,0 +1,66 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2
3#include <asm/vmlinux.lds.h>
4#include <asm/page.h>
5
6OUTPUT_ARCH(csky)
7ENTRY(_start)
8
9#ifndef __cskyBE__
10jiffies = jiffies_64;
11#else
12jiffies = jiffies_64 + 4;
13#endif
14
15#define VBR_BASE \
16 . = ALIGN(1024); \
17 vec_base = .; \
18 . += 512;
19
20SECTIONS
21{
22 . = PAGE_OFFSET + PHYS_OFFSET_OFFSET;
23
24 _stext = .;
25 __init_begin = .;
26 HEAD_TEXT_SECTION
27 INIT_TEXT_SECTION(PAGE_SIZE)
28 INIT_DATA_SECTION(PAGE_SIZE)
29 PERCPU_SECTION(L1_CACHE_BYTES)
30 . = ALIGN(PAGE_SIZE);
31 __init_end = .;
32
33 .text : AT(ADDR(.text) - LOAD_OFFSET) {
34 _text = .;
35 IRQENTRY_TEXT
36 SOFTIRQENTRY_TEXT
37 TEXT_TEXT
38 SCHED_TEXT
39 CPUIDLE_TEXT
40 LOCK_TEXT
41 KPROBES_TEXT
42 *(.fixup)
43 *(.gnu.warning)
44 } = 0
45 _etext = .;
46
47 /* __init_begin __init_end must be page aligned for free_initmem */
48 . = ALIGN(PAGE_SIZE);
49
50
51 _sdata = .;
52 RO_DATA_SECTION(PAGE_SIZE)
53 RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
54 _edata = .;
55
56 NOTES
57 EXCEPTION_TABLE(L1_CACHE_BYTES)
58 BSS_SECTION(L1_CACHE_BYTES, PAGE_SIZE, L1_CACHE_BYTES)
59 VBR_BASE
60 _end = . ;
61
62 STABS_DEBUG
63 DWARF_DEBUG
64
65 DISCARDS
66}