License cleanup: add SPDX GPL-2.0 license identifier to files with no license
[linux-block.git] / arch / cris / arch-v32 / mm / init.c
CommitLineData
b2441318 1// SPDX-License-Identifier: GPL-2.0
51533b61
MS
2/*
3 * Set up paging and the MMU.
4 *
5 * Copyright (C) 2000-2003, Axis Communications AB.
6 *
7 * Authors: Bjorn Wesen <bjornw@axis.com>
8 * Tobias Anderberg <tobiasa@axis.com>, CRISv32 port.
9 */
51533b61
MS
10#include <linux/mmzone.h>
11#include <linux/init.h>
12#include <linux/bootmem.h>
13#include <linux/mm.h>
51533b61
MS
14#include <asm/pgtable.h>
15#include <asm/page.h>
16#include <asm/types.h>
17#include <asm/mmu.h>
18#include <asm/io.h>
19#include <asm/mmu_context.h>
556dcee7
JN
20#include <arch/hwregs/asm/mmu_defs_asm.h>
21#include <arch/hwregs/supp_reg.h>
51533b61
MS
22
23extern void tlb_init(void);
24
25/*
26 * The kernel is already mapped with linear mapping at kseg_c so there's no
27 * need to map it with a page table. However, head.S also temporarily mapped it
28 * at kseg_4 thus the ksegs are set up again. Also clear the TLB and do various
29 * other paging stuff.
30 */
7ec280c5 31void __init cris_mmu_init(void)
51533b61
MS
32{
33 unsigned long mmu_config;
34 unsigned long mmu_kbase_hi;
35 unsigned long mmu_kbase_lo;
36 unsigned short mmu_page_id;
37
38 /*
39 * Make sure the current pgd table points to something sane, even if it
40 * is most probably not used until the next switch_mm.
41 */
42 per_cpu(current_pgd, smp_processor_id()) = init_mm.pgd;
43
51533b61
MS
44 /* Initialise the TLB. Function found in tlb.c. */
45 tlb_init();
46
7ec280c5
JN
47 /*
48 * Enable exceptions and initialize the kernel segments.
49 * See head.S for differences between ARTPEC-3 and ETRAX FS.
50 */
51533b61
MS
51 mmu_config = ( REG_STATE(mmu, rw_mm_cfg, we, on) |
52 REG_STATE(mmu, rw_mm_cfg, acc, on) |
53 REG_STATE(mmu, rw_mm_cfg, ex, on) |
54 REG_STATE(mmu, rw_mm_cfg, inv, on) |
7ec280c5
JN
55#ifdef CONFIG_CRIS_MACH_ARTPEC3
56 REG_STATE(mmu, rw_mm_cfg, seg_f, page) |
57 REG_STATE(mmu, rw_mm_cfg, seg_e, page) |
58 REG_STATE(mmu, rw_mm_cfg, seg_d, linear) |
59#else
51533b61
MS
60 REG_STATE(mmu, rw_mm_cfg, seg_f, linear) |
61 REG_STATE(mmu, rw_mm_cfg, seg_e, linear) |
62 REG_STATE(mmu, rw_mm_cfg, seg_d, page) |
7ec280c5 63#endif
51533b61
MS
64 REG_STATE(mmu, rw_mm_cfg, seg_c, linear) |
65 REG_STATE(mmu, rw_mm_cfg, seg_b, linear) |
51533b61 66 REG_STATE(mmu, rw_mm_cfg, seg_a, page) |
51533b61
MS
67 REG_STATE(mmu, rw_mm_cfg, seg_9, page) |
68 REG_STATE(mmu, rw_mm_cfg, seg_8, page) |
69 REG_STATE(mmu, rw_mm_cfg, seg_7, page) |
70 REG_STATE(mmu, rw_mm_cfg, seg_6, page) |
71 REG_STATE(mmu, rw_mm_cfg, seg_5, page) |
72 REG_STATE(mmu, rw_mm_cfg, seg_4, page) |
73 REG_STATE(mmu, rw_mm_cfg, seg_3, page) |
74 REG_STATE(mmu, rw_mm_cfg, seg_2, page) |
75 REG_STATE(mmu, rw_mm_cfg, seg_1, page) |
76 REG_STATE(mmu, rw_mm_cfg, seg_0, page));
77
7ec280c5 78 /* See head.S for differences between ARTPEC-3 and ETRAX FS. */
51533b61 79 mmu_kbase_hi = ( REG_FIELD(mmu, rw_mm_kbase_hi, base_f, 0x0) |
7ec280c5
JN
80#ifdef CONFIG_CRIS_MACH_ARTPEC3
81 REG_FIELD(mmu, rw_mm_kbase_hi, base_e, 0x0) |
82 REG_FIELD(mmu, rw_mm_kbase_hi, base_d, 0x5) |
83#else
51533b61
MS
84 REG_FIELD(mmu, rw_mm_kbase_hi, base_e, 0x8) |
85 REG_FIELD(mmu, rw_mm_kbase_hi, base_d, 0x0) |
7ec280c5 86#endif
51533b61 87 REG_FIELD(mmu, rw_mm_kbase_hi, base_c, 0x4) |
51533b61 88 REG_FIELD(mmu, rw_mm_kbase_hi, base_b, 0xb) |
51533b61 89 REG_FIELD(mmu, rw_mm_kbase_hi, base_a, 0x0) |
51533b61
MS
90 REG_FIELD(mmu, rw_mm_kbase_hi, base_9, 0x0) |
91 REG_FIELD(mmu, rw_mm_kbase_hi, base_8, 0x0));
92
93 mmu_kbase_lo = ( REG_FIELD(mmu, rw_mm_kbase_lo, base_7, 0x0) |
94 REG_FIELD(mmu, rw_mm_kbase_lo, base_6, 0x0) |
95 REG_FIELD(mmu, rw_mm_kbase_lo, base_5, 0x0) |
96 REG_FIELD(mmu, rw_mm_kbase_lo, base_4, 0x0) |
97 REG_FIELD(mmu, rw_mm_kbase_lo, base_3, 0x0) |
98 REG_FIELD(mmu, rw_mm_kbase_lo, base_2, 0x0) |
99 REG_FIELD(mmu, rw_mm_kbase_lo, base_1, 0x0) |
100 REG_FIELD(mmu, rw_mm_kbase_lo, base_0, 0x0));
101
102 mmu_page_id = REG_FIELD(mmu, rw_mm_tlb_hi, pid, 0);
103
104 /* Update the instruction MMU. */
105 SUPP_BANK_SEL(BANK_IM);
106 SUPP_REG_WR(RW_MM_CFG, mmu_config);
107 SUPP_REG_WR(RW_MM_KBASE_HI, mmu_kbase_hi);
108 SUPP_REG_WR(RW_MM_KBASE_LO, mmu_kbase_lo);
109 SUPP_REG_WR(RW_MM_TLB_HI, mmu_page_id);
110
111 /* Update the data MMU. */
112 SUPP_BANK_SEL(BANK_DM);
113 SUPP_REG_WR(RW_MM_CFG, mmu_config);
114 SUPP_REG_WR(RW_MM_KBASE_HI, mmu_kbase_hi);
115 SUPP_REG_WR(RW_MM_KBASE_LO, mmu_kbase_lo);
116 SUPP_REG_WR(RW_MM_TLB_HI, mmu_page_id);
117
118 SPEC_REG_WR(SPEC_REG_PID, 0);
119
120 /*
121 * The MMU has been enabled ever since head.S but just to make it
122 * totally obvious enable it here as well.
123 */
124 SUPP_BANK_SEL(BANK_GC);
125 SUPP_REG_WR(RW_GC_CFG, 0xf); /* IMMU, DMMU, ICache, DCache on */
126}
127
7ec280c5 128void __init paging_init(void)
51533b61
MS
129{
130 int i;
131 unsigned long zones_size[MAX_NR_ZONES];
132
133 printk("Setting up paging and the MMU.\n");
134
135 /* Clear out the init_mm.pgd that will contain the kernel's mappings. */
136 for(i = 0; i < PTRS_PER_PGD; i++)
137 swapper_pg_dir[i] = __pgd(0);
138
139 cris_mmu_init();
140
141 /*
142 * Initialize the bad page table and bad page to point to a couple of
143 * allocated pages.
144 */
145 empty_zero_page = (unsigned long) alloc_bootmem_pages(PAGE_SIZE);
146 memset((void *) empty_zero_page, 0, PAGE_SIZE);
147
148 /* All pages are DMA'able in Etrax, so put all in the DMA'able zone. */
149 zones_size[0] = ((unsigned long) high_memory - PAGE_OFFSET) >> PAGE_SHIFT;
150
151 for (i = 1; i < MAX_NR_ZONES; i++)
152 zones_size[i] = 0;
153
154 /*
155 * Use free_area_init_node instead of free_area_init, because it is
156 * designed for systems where the DRAM starts at an address
157 * substantially higher than 0, like us (we start at PAGE_OFFSET). This
158 * saves space in the mem_map page array.
159 */
9109fb7b 160 free_area_init_node(0, zones_size, PAGE_OFFSET >> PAGE_SHIFT, 0);
51533b61
MS
161
162 mem_map = contig_page_data.node_mem_map;
163}