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