armadaxp_machdep.c revision 1.8.4.2 1 1.8.4.2 yamt /* $NetBSD: armadaxp_machdep.c,v 1.8.4.2 2014/05/22 11:39:39 yamt Exp $ */
2 1.8.4.2 yamt /*******************************************************************************
3 1.8.4.2 yamt Copyright (C) Marvell International Ltd. and its affiliates
4 1.8.4.2 yamt
5 1.8.4.2 yamt Developed by Semihalf
6 1.8.4.2 yamt
7 1.8.4.2 yamt ********************************************************************************
8 1.8.4.2 yamt Marvell BSD License
9 1.8.4.2 yamt
10 1.8.4.2 yamt If you received this File from Marvell, you may opt to use, redistribute and/or
11 1.8.4.2 yamt modify this File under the following licensing terms.
12 1.8.4.2 yamt Redistribution and use in source and binary forms, with or without modification,
13 1.8.4.2 yamt are permitted provided that the following conditions are met:
14 1.8.4.2 yamt
15 1.8.4.2 yamt * Redistributions of source code must retain the above copyright notice,
16 1.8.4.2 yamt this list of conditions and the following disclaimer.
17 1.8.4.2 yamt
18 1.8.4.2 yamt * Redistributions in binary form must reproduce the above copyright
19 1.8.4.2 yamt notice, this list of conditions and the following disclaimer in the
20 1.8.4.2 yamt documentation and/or other materials provided with the distribution.
21 1.8.4.2 yamt
22 1.8.4.2 yamt * Neither the name of Marvell nor the names of its contributors may be
23 1.8.4.2 yamt used to endorse or promote products derived from this software without
24 1.8.4.2 yamt specific prior written permission.
25 1.8.4.2 yamt
26 1.8.4.2 yamt THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
27 1.8.4.2 yamt ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28 1.8.4.2 yamt WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29 1.8.4.2 yamt DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
30 1.8.4.2 yamt ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
31 1.8.4.2 yamt (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32 1.8.4.2 yamt LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
33 1.8.4.2 yamt ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 1.8.4.2 yamt (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 1.8.4.2 yamt SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 1.8.4.2 yamt
37 1.8.4.2 yamt *******************************************************************************/
38 1.8.4.2 yamt
39 1.8.4.2 yamt #include <sys/cdefs.h>
40 1.8.4.2 yamt __KERNEL_RCSID(0, "$NetBSD: armadaxp_machdep.c,v 1.8.4.2 2014/05/22 11:39:39 yamt Exp $");
41 1.8.4.2 yamt
42 1.8.4.2 yamt #include "opt_machdep.h"
43 1.8.4.2 yamt #include "opt_mvsoc.h"
44 1.8.4.2 yamt #include "opt_evbarm_boardtype.h"
45 1.8.4.2 yamt #include "opt_com.h"
46 1.8.4.2 yamt #include "opt_ddb.h"
47 1.8.4.2 yamt #include "opt_kgdb.h"
48 1.8.4.2 yamt #include "opt_pci.h"
49 1.8.4.2 yamt #include "opt_ipkdb.h"
50 1.8.4.2 yamt
51 1.8.4.2 yamt #include <sys/bus.h>
52 1.8.4.2 yamt #include <sys/param.h>
53 1.8.4.2 yamt #include <sys/device.h>
54 1.8.4.2 yamt #include <sys/systm.h>
55 1.8.4.2 yamt #include <sys/kernel.h>
56 1.8.4.2 yamt #include <sys/exec.h>
57 1.8.4.2 yamt #include <sys/proc.h>
58 1.8.4.2 yamt #include <sys/msgbuf.h>
59 1.8.4.2 yamt #include <sys/reboot.h>
60 1.8.4.2 yamt #include <sys/termios.h>
61 1.8.4.2 yamt #include <sys/ksyms.h>
62 1.8.4.2 yamt
63 1.8.4.2 yamt #include <uvm/uvm_extern.h>
64 1.8.4.2 yamt
65 1.8.4.2 yamt #include <sys/conf.h>
66 1.8.4.2 yamt #include <dev/cons.h>
67 1.8.4.2 yamt #include <dev/md.h>
68 1.8.4.2 yamt
69 1.8.4.2 yamt #include <dev/pci/pcireg.h>
70 1.8.4.2 yamt #include <dev/pci/pcivar.h>
71 1.8.4.2 yamt #include <machine/pci_machdep.h>
72 1.8.4.2 yamt
73 1.8.4.2 yamt #include <machine/db_machdep.h>
74 1.8.4.2 yamt #include <ddb/db_sym.h>
75 1.8.4.2 yamt #include <ddb/db_extern.h>
76 1.8.4.2 yamt #ifdef KGDB
77 1.8.4.2 yamt #include <sys/kgdb.h>
78 1.8.4.2 yamt #endif
79 1.8.4.2 yamt
80 1.8.4.2 yamt #include <machine/bootconfig.h>
81 1.8.4.2 yamt #include <machine/autoconf.h>
82 1.8.4.2 yamt #include <machine/cpu.h>
83 1.8.4.2 yamt #include <machine/frame.h>
84 1.8.4.2 yamt #include <arm/armreg.h>
85 1.8.4.2 yamt #include <arm/undefined.h>
86 1.8.4.2 yamt
87 1.8.4.2 yamt #include <arm/arm32/machdep.h>
88 1.8.4.2 yamt
89 1.8.4.2 yamt #include <arm/marvell/mvsocreg.h>
90 1.8.4.2 yamt #include <arm/marvell/mvsocvar.h>
91 1.8.4.2 yamt #include <arm/marvell/armadaxpreg.h>
92 1.8.4.2 yamt
93 1.8.4.2 yamt #include <evbarm/marvell/marvellreg.h>
94 1.8.4.2 yamt #include <evbarm/marvell/marvellvar.h>
95 1.8.4.2 yamt
96 1.8.4.2 yamt #include "mvpex.h"
97 1.8.4.2 yamt #include "com.h"
98 1.8.4.2 yamt #if NCOM > 0
99 1.8.4.2 yamt #include <dev/ic/comreg.h>
100 1.8.4.2 yamt #include <dev/ic/comvar.h>
101 1.8.4.2 yamt #endif
102 1.8.4.2 yamt
103 1.8.4.2 yamt /*
104 1.8.4.2 yamt * Address to call from cpu_reset() to reset the machine.
105 1.8.4.2 yamt * This is machine architecture dependent as it varies depending
106 1.8.4.2 yamt * on where the ROM appears when you turn the MMU off.
107 1.8.4.2 yamt */
108 1.8.4.2 yamt
109 1.8.4.2 yamt BootConfig bootconfig; /* Boot config storage */
110 1.8.4.2 yamt char *boot_args = NULL;
111 1.8.4.2 yamt char *boot_file = NULL;
112 1.8.4.2 yamt
113 1.8.4.2 yamt extern int KERNEL_BASE_phys[];
114 1.8.4.2 yamt
115 1.8.4.2 yamt /*
116 1.8.4.2 yamt * Put some bogus settings of the MEMSTART and MEMSIZE
117 1.8.4.2 yamt * if they are not defined in kernel configuration file.
118 1.8.4.2 yamt */
119 1.8.4.2 yamt #ifndef MEMSTART
120 1.8.4.2 yamt #define MEMSTART 0x00000000UL
121 1.8.4.2 yamt #endif
122 1.8.4.2 yamt #ifndef MEMSIZE
123 1.8.4.2 yamt #define MEMSIZE 0x40000000UL
124 1.8.4.2 yamt #endif
125 1.8.4.2 yamt
126 1.8.4.2 yamt #ifndef STARTUP_PAGETABLE_ADDR
127 1.8.4.2 yamt #define STARTUP_PAGETABLE_ADDR 0x00000000UL
128 1.8.4.2 yamt #endif
129 1.8.4.2 yamt
130 1.8.4.2 yamt /* Physical offset of the kernel from MEMSTART */
131 1.8.4.2 yamt #define KERNEL_OFFSET (paddr_t)&KERNEL_BASE_phys
132 1.8.4.2 yamt /* Kernel base virtual address */
133 1.8.4.2 yamt #define KERNEL_TEXT_BASE (KERNEL_BASE + KERNEL_OFFSET)
134 1.8.4.2 yamt
135 1.8.4.2 yamt #define KERNEL_VM_BASE (KERNEL_BASE + 0x40000000)
136 1.8.4.2 yamt #define KERNEL_VM_SIZE 0x14000000
137 1.8.4.2 yamt
138 1.8.4.2 yamt /* Prototypes */
139 1.8.4.2 yamt extern int armadaxp_l2_init(bus_addr_t);
140 1.8.4.2 yamt extern void armadaxp_io_coherency_init(void);
141 1.8.4.2 yamt
142 1.8.4.2 yamt void consinit(void);
143 1.8.4.2 yamt #ifdef KGDB
144 1.8.4.2 yamt static void kgdb_port_init(void);
145 1.8.4.2 yamt #endif
146 1.8.4.2 yamt
147 1.8.4.2 yamt static void axp_device_register(device_t dev, void *aux);
148 1.8.4.2 yamt
149 1.8.4.2 yamt static void
150 1.8.4.2 yamt axp_system_reset(void)
151 1.8.4.2 yamt {
152 1.8.4.2 yamt extern vaddr_t misc_base;
153 1.8.4.2 yamt
154 1.8.4.2 yamt #define write_miscreg(r, v) (*(volatile uint32_t *)(misc_base + (r)) = (v))
155 1.8.4.2 yamt
156 1.8.4.2 yamt cpu_reset_address = 0;
157 1.8.4.2 yamt
158 1.8.4.2 yamt /* Unmask soft reset */
159 1.8.4.2 yamt write_miscreg(ARMADAXP_MISC_RSTOUTNMASKR,
160 1.8.4.2 yamt ARMADAXP_MISC_RSTOUTNMASKR_GLOBALSOFTRSTOUTEN);
161 1.8.4.2 yamt /* Assert soft reset */
162 1.8.4.2 yamt write_miscreg(ARMADAXP_MISC_SSRR, ARMADAXP_MISC_SSRR_GLOBALSOFTRST);
163 1.8.4.2 yamt
164 1.8.4.2 yamt while (1);
165 1.8.4.2 yamt }
166 1.8.4.2 yamt
167 1.8.4.2 yamt /*
168 1.8.4.2 yamt * Static device mappings. These peripheral registers are mapped at
169 1.8.4.2 yamt * fixed virtual addresses very early in initarm() so that we can use
170 1.8.4.2 yamt * them while booting the kernel, and stay at the same address
171 1.8.4.2 yamt * throughout whole kernel's life time.
172 1.8.4.2 yamt *
173 1.8.4.2 yamt * We use this table twice; once with bootstrap page table, and once
174 1.8.4.2 yamt * with kernel's page table which we build up in initarm().
175 1.8.4.2 yamt *
176 1.8.4.2 yamt * Since we map these registers into the bootstrap page table using
177 1.8.4.2 yamt * pmap_devmap_bootstrap() which calls pmap_map_chunk(), we map
178 1.8.4.2 yamt * registers segment-aligned and segment-rounded in order to avoid
179 1.8.4.2 yamt * using the 2nd page tables.
180 1.8.4.2 yamt */
181 1.8.4.2 yamt
182 1.8.4.2 yamt #define _A(a) ((a) & ~L1_S_OFFSET)
183 1.8.4.2 yamt #define _S(s) (((s) + L1_S_SIZE - 1) & ~(L1_S_SIZE-1))
184 1.8.4.2 yamt
185 1.8.4.2 yamt static const struct pmap_devmap devmap[] = {
186 1.8.4.2 yamt {
187 1.8.4.2 yamt /* Internal registers */
188 1.8.4.2 yamt .pd_va = _A(MARVELL_INTERREGS_VBASE),
189 1.8.4.2 yamt .pd_pa = _A(MARVELL_INTERREGS_PBASE),
190 1.8.4.2 yamt .pd_size = _S(MARVELL_INTERREGS_SIZE),
191 1.8.4.2 yamt .pd_prot = VM_PROT_READ|VM_PROT_WRITE,
192 1.8.4.2 yamt .pd_cache = PTE_NOCACHE
193 1.8.4.2 yamt },
194 1.8.4.2 yamt {0, 0, 0, 0, 0}
195 1.8.4.2 yamt };
196 1.8.4.2 yamt
197 1.8.4.2 yamt #undef _A
198 1.8.4.2 yamt #undef _S
199 1.8.4.2 yamt
200 1.8.4.2 yamt static inline pd_entry_t *
201 1.8.4.2 yamt read_ttb(void)
202 1.8.4.2 yamt {
203 1.8.4.2 yamt return (pd_entry_t *)(armreg_ttbr_read() & ~((1<<14)-1));
204 1.8.4.2 yamt }
205 1.8.4.2 yamt
206 1.8.4.2 yamt static int
207 1.8.4.2 yamt axp_pcie_free_win(void)
208 1.8.4.2 yamt {
209 1.8.4.2 yamt /* Find first disabled window */
210 1.8.4.2 yamt for (size_t i = 0; i < ARMADAXP_MLMB_NWINDOW; i++) {
211 1.8.4.2 yamt if ((read_mlmbreg(MVSOC_MLMB_WCR(i)) &
212 1.8.4.2 yamt MVSOC_MLMB_WCR_WINEN) == 0) {
213 1.8.4.2 yamt return i;
214 1.8.4.2 yamt }
215 1.8.4.2 yamt }
216 1.8.4.2 yamt /* If there is no free window, return erroneous value */
217 1.8.4.2 yamt return (-1);
218 1.8.4.2 yamt }
219 1.8.4.2 yamt
220 1.8.4.2 yamt static void
221 1.8.4.2 yamt reset_axp_pcie_win(void)
222 1.8.4.2 yamt {
223 1.8.4.2 yamt uint32_t target, attr;
224 1.8.4.2 yamt int memtag = 0, iotag = 0, window, i;
225 1.8.4.2 yamt uint32_t membase;
226 1.8.4.2 yamt uint32_t iobase;
227 1.8.4.2 yamt uint32_t tags[] = { ARMADAXP_TAG_PEX00_MEM, ARMADAXP_TAG_PEX00_IO,
228 1.8.4.2 yamt ARMADAXP_TAG_PEX01_MEM, ARMADAXP_TAG_PEX01_IO,
229 1.8.4.2 yamt ARMADAXP_TAG_PEX02_MEM, ARMADAXP_TAG_PEX02_IO,
230 1.8.4.2 yamt ARMADAXP_TAG_PEX03_MEM, ARMADAXP_TAG_PEX03_IO,
231 1.8.4.2 yamt ARMADAXP_TAG_PEX2_MEM, ARMADAXP_TAG_PEX2_IO,
232 1.8.4.2 yamt ARMADAXP_TAG_PEX3_MEM, ARMADAXP_TAG_PEX3_IO};
233 1.8.4.2 yamt
234 1.8.4.2 yamt nwindow = ARMADAXP_MLMB_NWINDOW;
235 1.8.4.2 yamt nremap = ARMADAXP_MLMB_NREMAP;
236 1.8.4.2 yamt membase = MARVELL_PEXMEM_PBASE;
237 1.8.4.2 yamt iobase = MARVELL_PEXIO_PBASE;
238 1.8.4.2 yamt for (i = 0; i < __arraycount(tags) / 2; i++) {
239 1.8.4.2 yamt memtag = tags[2 * i];
240 1.8.4.2 yamt iotag = tags[(2 * i) + 1];
241 1.8.4.2 yamt
242 1.8.4.2 yamt /* Reset PCI-Express space to window register. */
243 1.8.4.2 yamt window = mvsoc_target(memtag, &target, &attr, NULL, NULL);
244 1.8.4.2 yamt
245 1.8.4.2 yamt /* Find free window if we've got spurious one */
246 1.8.4.2 yamt if (window >= nwindow) {
247 1.8.4.2 yamt window = axp_pcie_free_win();
248 1.8.4.2 yamt /* Just break if there is no free windows left */
249 1.8.4.2 yamt if (window < 0) {
250 1.8.4.2 yamt aprint_error(": no free windows for PEX MEM\n");
251 1.8.4.2 yamt break;
252 1.8.4.2 yamt }
253 1.8.4.2 yamt }
254 1.8.4.2 yamt write_mlmbreg(MVSOC_MLMB_WCR(window),
255 1.8.4.2 yamt MVSOC_MLMB_WCR_WINEN |
256 1.8.4.2 yamt MVSOC_MLMB_WCR_TARGET(target) |
257 1.8.4.2 yamt MVSOC_MLMB_WCR_ATTR(attr) |
258 1.8.4.2 yamt MVSOC_MLMB_WCR_SIZE(MARVELL_PEXMEM_SIZE));
259 1.8.4.2 yamt write_mlmbreg(MVSOC_MLMB_WBR(window),
260 1.8.4.2 yamt membase & MVSOC_MLMB_WBR_BASE_MASK);
261 1.8.4.2 yamt #ifdef PCI_NETBSD_CONFIGURE
262 1.8.4.2 yamt if (window < nremap) {
263 1.8.4.2 yamt write_mlmbreg(MVSOC_MLMB_WRLR(window),
264 1.8.4.2 yamt membase & MVSOC_MLMB_WRLR_REMAP_MASK);
265 1.8.4.2 yamt write_mlmbreg(MVSOC_MLMB_WRHR(window), 0);
266 1.8.4.2 yamt }
267 1.8.4.2 yamt #endif
268 1.8.4.2 yamt window = mvsoc_target(iotag, &target, &attr, NULL, NULL);
269 1.8.4.2 yamt
270 1.8.4.2 yamt /* Find free window if we've got spurious one */
271 1.8.4.2 yamt if (window >= nwindow) {
272 1.8.4.2 yamt window = axp_pcie_free_win();
273 1.8.4.2 yamt /* Just break if there is no free windows left */
274 1.8.4.2 yamt if (window < 0) {
275 1.8.4.2 yamt aprint_error(": no free windows for PEX I/O\n");
276 1.8.4.2 yamt break;
277 1.8.4.2 yamt }
278 1.8.4.2 yamt }
279 1.8.4.2 yamt write_mlmbreg(MVSOC_MLMB_WCR(window),
280 1.8.4.2 yamt MVSOC_MLMB_WCR_WINEN |
281 1.8.4.2 yamt MVSOC_MLMB_WCR_TARGET(target) |
282 1.8.4.2 yamt MVSOC_MLMB_WCR_ATTR(attr) |
283 1.8.4.2 yamt MVSOC_MLMB_WCR_SIZE(MARVELL_PEXIO_SIZE));
284 1.8.4.2 yamt write_mlmbreg(MVSOC_MLMB_WBR(window),
285 1.8.4.2 yamt iobase & MVSOC_MLMB_WBR_BASE_MASK);
286 1.8.4.2 yamt #ifdef PCI_NETBSD_CONFIGURE
287 1.8.4.2 yamt if (window < nremap) {
288 1.8.4.2 yamt write_mlmbreg(MVSOC_MLMB_WRLR(window),
289 1.8.4.2 yamt iobase & MVSOC_MLMB_WRLR_REMAP_MASK);
290 1.8.4.2 yamt write_mlmbreg(MVSOC_MLMB_WRHR(window), 0);
291 1.8.4.2 yamt }
292 1.8.4.2 yamt #endif
293 1.8.4.2 yamt membase += MARVELL_PEXMEM_SIZE;
294 1.8.4.2 yamt iobase += MARVELL_PEXIO_SIZE;
295 1.8.4.2 yamt }
296 1.8.4.2 yamt }
297 1.8.4.2 yamt
298 1.8.4.2 yamt /*
299 1.8.4.2 yamt * u_int initarm(...)
300 1.8.4.2 yamt *
301 1.8.4.2 yamt * Initial entry point on startup. This gets called before main() is
302 1.8.4.2 yamt * entered.
303 1.8.4.2 yamt * It should be responsible for setting up everything that must be
304 1.8.4.2 yamt * in place when main is called.
305 1.8.4.2 yamt * This includes
306 1.8.4.2 yamt * Taking a copy of the boot configuration structure.
307 1.8.4.2 yamt * Initialising the physical console so characters can be printed.
308 1.8.4.2 yamt * Setting up page tables for the kernel
309 1.8.4.2 yamt * Relocating the kernel to the bottom of physical memory
310 1.8.4.2 yamt */
311 1.8.4.2 yamt u_int
312 1.8.4.2 yamt initarm(void *arg)
313 1.8.4.2 yamt {
314 1.8.4.2 yamt cpu_reset_address = axp_system_reset;
315 1.8.4.2 yamt
316 1.8.4.2 yamt mvsoc_bootstrap(MARVELL_INTERREGS_VBASE);
317 1.8.4.2 yamt
318 1.8.4.2 yamt /* Set CPU functions */
319 1.8.4.2 yamt if (set_cpufuncs())
320 1.8.4.2 yamt panic("cpu not recognized!");
321 1.8.4.2 yamt
322 1.8.4.2 yamt /*
323 1.8.4.2 yamt * Map devices into the initial page table
324 1.8.4.2 yamt * in order to use early console during initialization process.
325 1.8.4.2 yamt * consinit is going to use this mapping.
326 1.8.4.2 yamt */
327 1.8.4.2 yamt pmap_devmap_bootstrap((vaddr_t)read_ttb(), devmap);
328 1.8.4.2 yamt
329 1.8.4.2 yamt /* Initialize system console */
330 1.8.4.2 yamt consinit();
331 1.8.4.2 yamt
332 1.8.4.2 yamt /* Reset PCI-Express space to window register. */
333 1.8.4.2 yamt reset_axp_pcie_win();
334 1.8.4.2 yamt
335 1.8.4.2 yamt /* Get CPU, system and timebase frequencies */
336 1.8.4.2 yamt extern vaddr_t misc_base;
337 1.8.4.2 yamt misc_base = MARVELL_INTERREGS_VBASE + ARMADAXP_MISC_BASE;
338 1.8.4.2 yamt armadaxp_getclks();
339 1.8.4.2 yamt mvsoc_clkgating = armadaxp_clkgating;
340 1.8.4.2 yamt
341 1.8.4.2 yamt /* Preconfigure interrupts */
342 1.8.4.2 yamt armadaxp_intr_bootstrap(MARVELL_INTERREGS_PBASE);
343 1.8.4.2 yamt
344 1.8.4.2 yamt #ifdef L2CACHE_ENABLE
345 1.8.4.2 yamt /* Initialize L2 Cache */
346 1.8.4.2 yamt (void)armadaxp_l2_init(MARVELL_INTERREGS_PBASE);
347 1.8.4.2 yamt #endif
348 1.8.4.2 yamt
349 1.8.4.2 yamt #ifdef AURORA_IO_CACHE_COHERENCY
350 1.8.4.2 yamt /* Initialize cache coherency */
351 1.8.4.2 yamt armadaxp_io_coherency_init();
352 1.8.4.2 yamt #endif
353 1.8.4.2 yamt
354 1.8.4.2 yamt #ifdef KGDB
355 1.8.4.2 yamt kgdb_port_init();
356 1.8.4.2 yamt #endif
357 1.8.4.2 yamt
358 1.8.4.2 yamt #ifdef VERBOSE_INIT_ARM
359 1.8.4.2 yamt /* Talk to the user */
360 1.8.4.2 yamt #define BDSTR(s) _BDSTR(s)
361 1.8.4.2 yamt #define _BDSTR(s) #s
362 1.8.4.2 yamt printf("\nNetBSD/evbarm (" BDSTR(EVBARM_BOARDTYPE) ") booting ...\n");
363 1.8.4.2 yamt #endif
364 1.8.4.2 yamt
365 1.8.4.2 yamt #ifdef __HAVE_MM_MD_DIRECT_MAPPED_PHYS
366 1.8.4.2 yamt const bool mapallmem_p = true;
367 1.8.4.2 yamt #else
368 1.8.4.2 yamt const bool mapallmem_p = false;
369 1.8.4.2 yamt #endif
370 1.8.4.2 yamt
371 1.8.4.2 yamt #ifdef VERBOSE_INIT_ARM
372 1.8.4.2 yamt printf("initarm: Configuring system ...\n");
373 1.8.4.2 yamt #endif
374 1.8.4.2 yamt psize_t memsize = MEMSIZE;
375 1.8.4.2 yamt if (mapallmem_p && memsize > KERNEL_VM_BASE - KERNEL_BASE) {
376 1.8.4.2 yamt printf("%s: dropping RAM size from %luMB to %uMB\n",
377 1.8.4.2 yamt __func__, (unsigned long) (memsize >> 20),
378 1.8.4.2 yamt (KERNEL_VM_BASE - KERNEL_BASE) >> 20);
379 1.8.4.2 yamt memsize = KERNEL_VM_BASE - KERNEL_BASE;
380 1.8.4.2 yamt }
381 1.8.4.2 yamt /* Fake bootconfig structure for the benefit of pmap.c. */
382 1.8.4.2 yamt bootconfig.dramblocks = 1;
383 1.8.4.2 yamt bootconfig.dram[0].address = MEMSTART;
384 1.8.4.2 yamt bootconfig.dram[0].pages = memsize / PAGE_SIZE;
385 1.8.4.2 yamt
386 1.8.4.2 yamt physical_start = bootconfig.dram[0].address;
387 1.8.4.2 yamt physical_end = physical_start + (bootconfig.dram[0].pages * PAGE_SIZE);
388 1.8.4.2 yamt
389 1.8.4.2 yamt arm32_bootmem_init(0, physical_end, (uintptr_t) KERNEL_BASE_phys);
390 1.8.4.2 yamt arm32_kernel_vm_init(KERNEL_VM_BASE, ARM_VECTORS_LOW, 0,
391 1.8.4.2 yamt devmap, mapallmem_p);
392 1.8.4.2 yamt
393 1.8.4.2 yamt /* we've a specific device_register routine */
394 1.8.4.2 yamt evbarm_device_register = axp_device_register;
395 1.8.4.2 yamt
396 1.8.4.2 yamt return initarm_common(KERNEL_VM_BASE, KERNEL_VM_SIZE, NULL, 0);
397 1.8.4.2 yamt }
398 1.8.4.2 yamt
399 1.8.4.2 yamt #ifndef CONSADDR
400 1.8.4.2 yamt #error Specify the address of the UART with the CONSADDR option.
401 1.8.4.2 yamt #endif
402 1.8.4.2 yamt #ifndef CONSPEED
403 1.8.4.2 yamt #define CONSPEED B115200
404 1.8.4.2 yamt #endif
405 1.8.4.2 yamt #ifndef CONMODE
406 1.8.4.2 yamt #define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
407 1.8.4.2 yamt #endif
408 1.8.4.2 yamt #ifndef CONSFREQ
409 1.8.4.2 yamt #define CONSFREQ 0
410 1.8.4.2 yamt #endif
411 1.8.4.2 yamt static const int comcnspeed = CONSPEED;
412 1.8.4.2 yamt static const int comcnfreq = CONSFREQ;
413 1.8.4.2 yamt static const tcflag_t comcnmode = CONMODE;
414 1.8.4.2 yamt static const bus_addr_t comcnaddr = (bus_addr_t)CONSADDR;
415 1.8.4.2 yamt
416 1.8.4.2 yamt void
417 1.8.4.2 yamt consinit(void)
418 1.8.4.2 yamt {
419 1.8.4.2 yamt static bool consinit_called = false;
420 1.8.4.2 yamt
421 1.8.4.2 yamt if (consinit_called)
422 1.8.4.2 yamt return;
423 1.8.4.2 yamt consinit_called = true;
424 1.8.4.2 yamt
425 1.8.4.2 yamt #if NCOM > 0
426 1.8.4.2 yamt extern int mvuart_cnattach(bus_space_tag_t, bus_addr_t, int,
427 1.8.4.2 yamt uint32_t, int);
428 1.8.4.2 yamt
429 1.8.4.2 yamt if (mvuart_cnattach(&mvsoc_bs_tag, comcnaddr, comcnspeed,
430 1.8.4.2 yamt comcnfreq ? comcnfreq : mvTclk , comcnmode))
431 1.8.4.2 yamt panic("Serial console can not be initialized.");
432 1.8.4.2 yamt #endif
433 1.8.4.2 yamt }
434 1.8.4.2 yamt
435 1.8.4.2 yamt #ifdef KGDB
436 1.8.4.2 yamt #ifndef KGDB_DEVADDR
437 1.8.4.2 yamt #error Specify the address of the kgdb UART with the KGDB_DEVADDR option.
438 1.8.4.2 yamt #endif
439 1.8.4.2 yamt #ifndef KGDB_DEVRATE
440 1.8.4.2 yamt #define KGDB_DEVRATE B115200
441 1.8.4.2 yamt #endif
442 1.8.4.2 yamt #define MVUART_SIZE 0x20
443 1.8.4.2 yamt
444 1.8.4.2 yamt #ifndef KGDB_DEVMODE
445 1.8.4.2 yamt #define KGDB_DEVMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
446 1.8.4.2 yamt #endif
447 1.8.4.2 yamt static const vaddr_t comkgdbaddr = KGDB_DEVADDR;
448 1.8.4.2 yamt static const int comkgdbspeed = KGDB_DEVRATE;
449 1.8.4.2 yamt static const int comkgdbmode = KGDB_DEVMODE;
450 1.8.4.2 yamt
451 1.8.4.2 yamt void
452 1.8.4.2 yamt static kgdb_port_init(void)
453 1.8.4.2 yamt {
454 1.8.4.2 yamt static int kgdbsinit_called = 0;
455 1.8.4.2 yamt
456 1.8.4.2 yamt if (kgdbsinit_called != 0)
457 1.8.4.2 yamt return;
458 1.8.4.2 yamt kgdbsinit_called = 1;
459 1.8.4.2 yamt
460 1.8.4.2 yamt if (com_kgdb_attach(&mvsoc_bs_tag, comkgdbaddr, comkgdbspeed,
461 1.8.4.2 yamt MVUART_SIZE, COM_TYPE_16550_NOERS, comkgdbmode))
462 1.8.4.2 yamt panic("KGDB uart can not be initialized.");
463 1.8.4.2 yamt }
464 1.8.4.2 yamt #endif
465 1.8.4.2 yamt
466 1.8.4.2 yamt #if NMVPEX > 0
467 1.8.4.2 yamt static void
468 1.8.4.2 yamt marvell_startend_by_tag(int tag, uint64_t *start, uint64_t *end)
469 1.8.4.2 yamt {
470 1.8.4.2 yamt
471 1.8.4.2 yamt uint32_t base, size;
472 1.8.4.2 yamt int win;
473 1.8.4.2 yamt
474 1.8.4.2 yamt win = mvsoc_target(tag, NULL, NULL, &base, &size);
475 1.8.4.2 yamt if (size != 0) {
476 1.8.4.2 yamt if (win < nremap)
477 1.8.4.2 yamt *start = read_mlmbreg(MVSOC_MLMB_WRLR(win)) |
478 1.8.4.2 yamt ((read_mlmbreg(MVSOC_MLMB_WRHR(win)) << 16) << 16);
479 1.8.4.2 yamt else
480 1.8.4.2 yamt *start = base;
481 1.8.4.2 yamt *end = *start + size - 1;
482 1.8.4.2 yamt } else
483 1.8.4.2 yamt *start = *end = 0;
484 1.8.4.2 yamt }
485 1.8.4.2 yamt #endif
486 1.8.4.2 yamt
487 1.8.4.2 yamt static void
488 1.8.4.2 yamt axp_device_register(device_t dev, void *aux)
489 1.8.4.2 yamt {
490 1.8.4.2 yamt prop_dictionary_t dict = device_properties(dev);
491 1.8.4.2 yamt
492 1.8.4.2 yamt #if NCOM > 0
493 1.8.4.2 yamt if (device_is_a(dev, "com") &&
494 1.8.4.2 yamt device_is_a(device_parent(dev), "mvsoc"))
495 1.8.4.2 yamt prop_dictionary_set_uint32(dict, "frequency", mvTclk);
496 1.8.4.2 yamt #endif
497 1.8.4.2 yamt
498 1.8.4.2 yamt #if NMVPEX > 0
499 1.8.4.2 yamt extern struct bus_space
500 1.8.4.2 yamt armadaxp_pex00_io_bs_tag, armadaxp_pex00_mem_bs_tag,
501 1.8.4.2 yamt armadaxp_pex01_io_bs_tag, armadaxp_pex01_mem_bs_tag,
502 1.8.4.2 yamt armadaxp_pex02_io_bs_tag, armadaxp_pex02_mem_bs_tag,
503 1.8.4.2 yamt armadaxp_pex03_io_bs_tag, armadaxp_pex03_mem_bs_tag,
504 1.8.4.2 yamt armadaxp_pex2_io_bs_tag, armadaxp_pex2_mem_bs_tag,
505 1.8.4.2 yamt armadaxp_pex3_io_bs_tag, armadaxp_pex3_mem_bs_tag;
506 1.8.4.2 yamt extern struct arm32_pci_chipset arm32_mvpex0_chipset,
507 1.8.4.2 yamt arm32_mvpex1_chipset, arm32_mvpex2_chipset,
508 1.8.4.2 yamt arm32_mvpex3_chipset, arm32_mvpex4_chipset,
509 1.8.4.2 yamt arm32_mvpex5_chipset;
510 1.8.4.2 yamt
511 1.8.4.2 yamt struct marvell_attach_args *mva = aux;
512 1.8.4.2 yamt
513 1.8.4.2 yamt if (device_is_a(dev, "mvpex")) {
514 1.8.4.2 yamt struct bus_space *mvpex_io_bs_tag, *mvpex_mem_bs_tag;
515 1.8.4.2 yamt struct arm32_pci_chipset *arm32_mvpex_chipset;
516 1.8.4.2 yamt prop_data_t io_bs_tag, mem_bs_tag, pc;
517 1.8.4.2 yamt uint64_t start, end;
518 1.8.4.2 yamt int iotag, memtag;
519 1.8.4.2 yamt
520 1.8.4.2 yamt if (mva->mva_offset == MVSOC_PEX_BASE) {
521 1.8.4.2 yamt mvpex_io_bs_tag = &armadaxp_pex00_io_bs_tag;
522 1.8.4.2 yamt mvpex_mem_bs_tag = &armadaxp_pex00_mem_bs_tag;
523 1.8.4.2 yamt arm32_mvpex_chipset = &arm32_mvpex0_chipset;
524 1.8.4.2 yamt iotag = ARMADAXP_TAG_PEX00_IO;
525 1.8.4.2 yamt memtag = ARMADAXP_TAG_PEX00_MEM;
526 1.8.4.2 yamt } else if (mva->mva_offset == MVSOC_PEX_BASE + 0x4000) {
527 1.8.4.2 yamt mvpex_io_bs_tag = &armadaxp_pex01_io_bs_tag;
528 1.8.4.2 yamt mvpex_mem_bs_tag = &armadaxp_pex01_mem_bs_tag;
529 1.8.4.2 yamt arm32_mvpex_chipset = &arm32_mvpex1_chipset;
530 1.8.4.2 yamt iotag = ARMADAXP_TAG_PEX01_IO;
531 1.8.4.2 yamt memtag = ARMADAXP_TAG_PEX01_MEM;
532 1.8.4.2 yamt } else if (mva->mva_offset == MVSOC_PEX_BASE + 0x8000) {
533 1.8.4.2 yamt mvpex_io_bs_tag = &armadaxp_pex02_io_bs_tag;
534 1.8.4.2 yamt mvpex_mem_bs_tag = &armadaxp_pex02_mem_bs_tag;
535 1.8.4.2 yamt arm32_mvpex_chipset = &arm32_mvpex2_chipset;
536 1.8.4.2 yamt iotag = ARMADAXP_TAG_PEX02_IO;
537 1.8.4.2 yamt memtag = ARMADAXP_TAG_PEX02_MEM;
538 1.8.4.2 yamt } else if (mva->mva_offset == MVSOC_PEX_BASE + 0xc000) {
539 1.8.4.2 yamt mvpex_io_bs_tag = &armadaxp_pex03_io_bs_tag;
540 1.8.4.2 yamt mvpex_mem_bs_tag = &armadaxp_pex03_mem_bs_tag;
541 1.8.4.2 yamt arm32_mvpex_chipset = &arm32_mvpex3_chipset;
542 1.8.4.2 yamt iotag = ARMADAXP_TAG_PEX03_IO;
543 1.8.4.2 yamt memtag = ARMADAXP_TAG_PEX03_MEM;
544 1.8.4.2 yamt } else if (mva->mva_offset == MVSOC_PEX_BASE + 0x2000) {
545 1.8.4.2 yamt mvpex_io_bs_tag = &armadaxp_pex2_io_bs_tag;
546 1.8.4.2 yamt mvpex_mem_bs_tag = &armadaxp_pex2_mem_bs_tag;
547 1.8.4.2 yamt arm32_mvpex_chipset = &arm32_mvpex4_chipset;
548 1.8.4.2 yamt iotag = ARMADAXP_TAG_PEX2_IO;
549 1.8.4.2 yamt memtag = ARMADAXP_TAG_PEX2_MEM;
550 1.8.4.2 yamt } else {
551 1.8.4.2 yamt mvpex_io_bs_tag = &armadaxp_pex3_io_bs_tag;
552 1.8.4.2 yamt mvpex_mem_bs_tag = &armadaxp_pex3_mem_bs_tag;
553 1.8.4.2 yamt arm32_mvpex_chipset = &arm32_mvpex5_chipset;
554 1.8.4.2 yamt iotag = ARMADAXP_TAG_PEX3_IO;
555 1.8.4.2 yamt memtag = ARMADAXP_TAG_PEX3_MEM;
556 1.8.4.2 yamt }
557 1.8.4.2 yamt
558 1.8.4.2 yamt arm32_mvpex_chipset->pc_conf_v = device_private(dev);
559 1.8.4.2 yamt arm32_mvpex_chipset->pc_intr_v = device_private(dev);
560 1.8.4.2 yamt
561 1.8.4.2 yamt io_bs_tag = prop_data_create_data_nocopy(
562 1.8.4.2 yamt mvpex_io_bs_tag, sizeof(struct bus_space));
563 1.8.4.2 yamt KASSERT(io_bs_tag != NULL);
564 1.8.4.2 yamt prop_dictionary_set(dict, "io-bus-tag", io_bs_tag);
565 1.8.4.2 yamt prop_object_release(io_bs_tag);
566 1.8.4.2 yamt mem_bs_tag = prop_data_create_data_nocopy(
567 1.8.4.2 yamt mvpex_mem_bs_tag, sizeof(struct bus_space));
568 1.8.4.2 yamt KASSERT(mem_bs_tag != NULL);
569 1.8.4.2 yamt prop_dictionary_set(dict, "mem-bus-tag", mem_bs_tag);
570 1.8.4.2 yamt prop_object_release(mem_bs_tag);
571 1.8.4.2 yamt
572 1.8.4.2 yamt pc = prop_data_create_data_nocopy(arm32_mvpex_chipset,
573 1.8.4.2 yamt sizeof(struct arm32_pci_chipset));
574 1.8.4.2 yamt KASSERT(pc != NULL);
575 1.8.4.2 yamt prop_dictionary_set(dict, "pci-chipset", pc);
576 1.8.4.2 yamt prop_object_release(pc);
577 1.8.4.2 yamt
578 1.8.4.2 yamt marvell_startend_by_tag(iotag, &start, &end);
579 1.8.4.2 yamt prop_dictionary_set_uint64(dict, "iostart", start);
580 1.8.4.2 yamt prop_dictionary_set_uint64(dict, "ioend", end);
581 1.8.4.2 yamt marvell_startend_by_tag(memtag, &start, &end);
582 1.8.4.2 yamt prop_dictionary_set_uint64(dict, "memstart", start);
583 1.8.4.2 yamt prop_dictionary_set_uint64(dict, "memend", end);
584 1.8.4.2 yamt prop_dictionary_set_uint32(dict,
585 1.8.4.2 yamt "cache-line-size", arm_dcache_align);
586 1.8.4.2 yamt }
587 1.8.4.2 yamt #endif
588 1.8.4.2 yamt }
589