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