Home | History | Annotate | Line # | Download | only in marvell
marvell_machdep.c revision 1.7
      1  1.7   tsutsui /*	$NetBSD: marvell_machdep.c,v 1.7 2012/03/31 02:36:31 tsutsui Exp $ */
      2  1.1  kiyohara /*
      3  1.1  kiyohara  * Copyright (c) 2007, 2008, 2010 KIYOHARA Takashi
      4  1.1  kiyohara  * All rights reserved.
      5  1.1  kiyohara  *
      6  1.1  kiyohara  * Redistribution and use in source and binary forms, with or without
      7  1.1  kiyohara  * modification, are permitted provided that the following conditions
      8  1.1  kiyohara  * are met:
      9  1.1  kiyohara  * 1. Redistributions of source code must retain the above copyright
     10  1.1  kiyohara  *    notice, this list of conditions and the following disclaimer.
     11  1.1  kiyohara  * 2. Redistributions in binary form must reproduce the above copyright
     12  1.1  kiyohara  *    notice, this list of conditions and the following disclaimer in the
     13  1.1  kiyohara  *    documentation and/or other materials provided with the distribution.
     14  1.1  kiyohara  *
     15  1.1  kiyohara  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     16  1.1  kiyohara  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     17  1.1  kiyohara  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     18  1.1  kiyohara  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
     19  1.1  kiyohara  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     20  1.1  kiyohara  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     21  1.1  kiyohara  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     22  1.1  kiyohara  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     23  1.1  kiyohara  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
     24  1.1  kiyohara  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     25  1.1  kiyohara  * POSSIBILITY OF SUCH DAMAGE.
     26  1.1  kiyohara  */
     27  1.1  kiyohara #include <sys/cdefs.h>
     28  1.7   tsutsui __KERNEL_RCSID(0, "$NetBSD: marvell_machdep.c,v 1.7 2012/03/31 02:36:31 tsutsui Exp $");
     29  1.1  kiyohara 
     30  1.1  kiyohara #include "opt_evbarm_boardtype.h"
     31  1.1  kiyohara #include "opt_ddb.h"
     32  1.1  kiyohara #include "opt_pci.h"
     33  1.1  kiyohara #include "opt_mvsoc.h"
     34  1.1  kiyohara #include "com.h"
     35  1.1  kiyohara #include "gtpci.h"
     36  1.1  kiyohara #include "mvpex.h"
     37  1.1  kiyohara 
     38  1.1  kiyohara #include <sys/param.h>
     39  1.1  kiyohara #include <sys/kernel.h>
     40  1.1  kiyohara #include <sys/reboot.h>
     41  1.1  kiyohara #include <sys/systm.h>
     42  1.1  kiyohara #include <sys/termios.h>
     43  1.1  kiyohara 
     44  1.1  kiyohara #include <prop/proplib.h>
     45  1.1  kiyohara 
     46  1.1  kiyohara #include <dev/cons.h>
     47  1.1  kiyohara #include <dev/md.h>
     48  1.1  kiyohara 
     49  1.1  kiyohara #include <dev/marvell/marvellreg.h>
     50  1.1  kiyohara #include <dev/marvell/marvellvar.h>
     51  1.1  kiyohara #include <dev/pci/pcireg.h>
     52  1.1  kiyohara #include <dev/pci/pcivar.h>
     53  1.1  kiyohara 
     54  1.1  kiyohara #include <machine/autoconf.h>
     55  1.1  kiyohara #include <machine/bootconfig.h>
     56  1.1  kiyohara #include <machine/pci_machdep.h>
     57  1.1  kiyohara 
     58  1.1  kiyohara #include <uvm/uvm_extern.h>
     59  1.1  kiyohara 
     60  1.1  kiyohara #include <arm/db_machdep.h>
     61  1.1  kiyohara #include <arm/undefined.h>
     62  1.1  kiyohara #include <arm/arm32/machdep.h>
     63  1.1  kiyohara 
     64  1.1  kiyohara #include <arm/marvell/mvsocreg.h>
     65  1.1  kiyohara #include <arm/marvell/mvsocvar.h>
     66  1.1  kiyohara #include <arm/marvell/orionreg.h>
     67  1.1  kiyohara #include <arm/marvell/kirkwoodreg.h>
     68  1.1  kiyohara #include <arm/marvell/mvsocgppvar.h>
     69  1.1  kiyohara 
     70  1.1  kiyohara #include <evbarm/marvell/marvellreg.h>
     71  1.1  kiyohara #include <evbarm/marvell/marvellvar.h>
     72  1.1  kiyohara 
     73  1.1  kiyohara #include <ddb/db_extern.h>
     74  1.1  kiyohara #include <ddb/db_sym.h>
     75  1.1  kiyohara 
     76  1.1  kiyohara #include "ksyms.h"
     77  1.1  kiyohara 
     78  1.1  kiyohara 
     79  1.1  kiyohara /* Kernel text starts 2MB in from the bottom of the kernel address space. */
     80  1.1  kiyohara #define KERNEL_TEXT_BASE	(KERNEL_BASE + 0x00000000)
     81  1.1  kiyohara #define KERNEL_VM_BASE		(KERNEL_BASE + 0x01000000)
     82  1.1  kiyohara 
     83  1.1  kiyohara /*
     84  1.1  kiyohara  * The range 0xc1000000 - 0xccffffff is available for kernel VM space
     85  1.1  kiyohara  * Core-logic registers and I/O mappings occupy 0xfd000000 - 0xffffffff
     86  1.1  kiyohara  */
     87  1.1  kiyohara #define KERNEL_VM_SIZE		0x0c000000
     88  1.1  kiyohara 
     89  1.1  kiyohara /*
     90  1.1  kiyohara  * Address to call from cpu_reset() to reset the machine.
     91  1.5       wiz  * This is machine architecture dependent as it varies depending
     92  1.1  kiyohara  * on where the ROM appears when you turn the MMU off.
     93  1.1  kiyohara  */
     94  1.1  kiyohara 
     95  1.1  kiyohara u_int cpu_reset_address = 0xffff0000;
     96  1.1  kiyohara 
     97  1.1  kiyohara /* Define various stack sizes in pages */
     98  1.1  kiyohara #define IRQ_STACK_SIZE	1
     99  1.1  kiyohara #define ABT_STACK_SIZE	1
    100  1.1  kiyohara #ifdef IPKDB
    101  1.1  kiyohara #define UND_STACK_SIZE	2
    102  1.1  kiyohara #else
    103  1.1  kiyohara #define UND_STACK_SIZE	1
    104  1.1  kiyohara #endif
    105  1.1  kiyohara 
    106  1.1  kiyohara BootConfig bootconfig;		/* Boot config storage */
    107  1.4  jakllsch static char bootargs[MAX_BOOT_STRING];
    108  1.1  kiyohara char *boot_args = NULL;
    109  1.1  kiyohara 
    110  1.1  kiyohara vm_offset_t physical_start;
    111  1.1  kiyohara vm_offset_t physical_freestart;
    112  1.1  kiyohara vm_offset_t physical_freeend;
    113  1.1  kiyohara vm_offset_t physical_end;
    114  1.1  kiyohara u_int free_pages;
    115  1.1  kiyohara int physmem = 0;
    116  1.1  kiyohara 
    117  1.1  kiyohara /* Physical and virtual addresses for some global pages */
    118  1.1  kiyohara pv_addr_t systempage;
    119  1.1  kiyohara pv_addr_t irqstack;
    120  1.1  kiyohara pv_addr_t undstack;
    121  1.1  kiyohara pv_addr_t abtstack;
    122  1.1  kiyohara pv_addr_t kernelstack;
    123  1.1  kiyohara 
    124  1.1  kiyohara vm_offset_t msgbufphys;
    125  1.1  kiyohara 
    126  1.1  kiyohara extern u_int data_abort_handler_address;
    127  1.1  kiyohara extern u_int prefetch_abort_handler_address;
    128  1.1  kiyohara extern u_int undefined_handler_address;
    129  1.1  kiyohara 
    130  1.1  kiyohara extern char _end[];
    131  1.1  kiyohara 
    132  1.1  kiyohara #define KERNEL_PT_SYS		0   /* Page table for mapping proc0 zero page */
    133  1.1  kiyohara #define KERNEL_PT_KERNEL	1	/* Page table for mapping kernel */
    134  1.1  kiyohara #define KERNEL_PT_KERNEL_NUM	4
    135  1.1  kiyohara #define KERNEL_PT_VMDATA	(KERNEL_PT_KERNEL + KERNEL_PT_KERNEL_NUM)
    136  1.1  kiyohara /* Page tables for mapping kernel VM */
    137  1.1  kiyohara #define KERNEL_PT_VMDATA_NUM	4	/* start with 16MB of KVM */
    138  1.1  kiyohara #define NUM_KERNEL_PTS		(KERNEL_PT_VMDATA + KERNEL_PT_VMDATA_NUM)
    139  1.1  kiyohara 
    140  1.1  kiyohara pv_addr_t kernel_pt_table[NUM_KERNEL_PTS];
    141  1.1  kiyohara 
    142  1.1  kiyohara /*
    143  1.1  kiyohara  * Macros to translate between physical and virtual for a subset of the
    144  1.1  kiyohara  * kernel address space.  *Not* for general use.
    145  1.1  kiyohara  */
    146  1.1  kiyohara #define KERNEL_BASE_PHYS	physical_start
    147  1.1  kiyohara #define KERN_VTOPHYS(va) \
    148  1.1  kiyohara 	((paddr_t)((vaddr_t)va - KERNEL_BASE + KERNEL_BASE_PHYS))
    149  1.1  kiyohara #define KERN_PHYSTOV(pa) \
    150  1.1  kiyohara 	((vaddr_t)((paddr_t)pa - KERNEL_BASE_PHYS + KERNEL_BASE))
    151  1.1  kiyohara 
    152  1.1  kiyohara 
    153  1.1  kiyohara #include "com.h"
    154  1.1  kiyohara #if NCOM > 0
    155  1.1  kiyohara #include <dev/ic/comreg.h>
    156  1.1  kiyohara #include <dev/ic/comvar.h>
    157  1.1  kiyohara #endif
    158  1.1  kiyohara 
    159  1.1  kiyohara #ifndef CONSPEED
    160  1.1  kiyohara #define CONSPEED	B115200	/* It's a setting of the default of u-boot */
    161  1.1  kiyohara #endif
    162  1.1  kiyohara #ifndef CONMODE
    163  1.1  kiyohara #define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
    164  1.1  kiyohara 
    165  1.1  kiyohara int comcnspeed = CONSPEED;
    166  1.1  kiyohara int comcnmode = CONMODE;
    167  1.1  kiyohara #endif
    168  1.1  kiyohara 
    169  1.1  kiyohara #include "opt_kgdb.h"
    170  1.1  kiyohara #ifdef KGDB
    171  1.1  kiyohara #include <sys/kgdb.h>
    172  1.1  kiyohara #endif
    173  1.1  kiyohara 
    174  1.1  kiyohara static void marvell_device_register(device_t, void *);
    175  1.1  kiyohara #if NGTPCI > 0 || NMVPEX > 0
    176  1.1  kiyohara static void marvell_startend_by_tag(int, uint64_t *, uint64_t *);
    177  1.1  kiyohara #endif
    178  1.1  kiyohara 
    179  1.3  jakllsch static void
    180  1.3  jakllsch marvell_system_reset(void)
    181  1.3  jakllsch {
    182  1.3  jakllsch 	/* unmask soft reset */
    183  1.3  jakllsch 	write_mlmbreg(MVSOC_MLMB_RSTOUTNMASKR,
    184  1.3  jakllsch 	    MVSOC_MLMB_RSTOUTNMASKR_SOFTRSTOUTEN);
    185  1.3  jakllsch 	/* assert soft reset */
    186  1.3  jakllsch 	write_mlmbreg(MVSOC_MLMB_SSRR, MVSOC_MLMB_SSRR_SYSTEMSOFTRST);
    187  1.3  jakllsch 	/* if we're still running, jump to the reset address */
    188  1.3  jakllsch 	cpu_reset();
    189  1.3  jakllsch 	/*NOTREACHED*/
    190  1.3  jakllsch }
    191  1.1  kiyohara 
    192  1.1  kiyohara void
    193  1.1  kiyohara cpu_reboot(int howto, char *bootstr)
    194  1.1  kiyohara {
    195  1.1  kiyohara 
    196  1.1  kiyohara 	/*
    197  1.1  kiyohara 	 * If we are still cold then hit the air brakes
    198  1.1  kiyohara 	 * and crash to earth fast
    199  1.1  kiyohara 	 */
    200  1.1  kiyohara 	if (cold) {
    201  1.1  kiyohara 		doshutdownhooks();
    202  1.1  kiyohara 		printf("The operating system has halted.\r\n");
    203  1.1  kiyohara 		printf("Please press any key to reboot.\r\n");
    204  1.1  kiyohara 		cngetc();
    205  1.1  kiyohara 		printf("rebooting...\r\n");
    206  1.3  jakllsch 		marvell_system_reset();
    207  1.1  kiyohara 	}
    208  1.1  kiyohara 
    209  1.1  kiyohara 	/*
    210  1.1  kiyohara 	 * If RB_NOSYNC was not specified sync the discs.
    211  1.1  kiyohara 	 * Note: Unless cold is set to 1 here, syslogd will die during the
    212  1.1  kiyohara 	 * unmount.  It looks like syslogd is getting woken up only to find
    213  1.1  kiyohara 	 * that it cannot page part of the binary in as the filesystem has
    214  1.1  kiyohara 	 * been unmounted.
    215  1.1  kiyohara 	 */
    216  1.1  kiyohara 	if (!(howto & RB_NOSYNC))
    217  1.1  kiyohara 		bootsync();
    218  1.1  kiyohara 
    219  1.1  kiyohara 	/* Say NO to interrupts */
    220  1.1  kiyohara 	splhigh();
    221  1.1  kiyohara 
    222  1.1  kiyohara 	/* Do a dump if requested. */
    223  1.1  kiyohara 	if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP)
    224  1.1  kiyohara 		dumpsys();
    225  1.1  kiyohara 
    226  1.1  kiyohara 	/* Run any shutdown hooks */
    227  1.1  kiyohara 	doshutdownhooks();
    228  1.1  kiyohara 
    229  1.1  kiyohara 	/* Make sure IRQ's are disabled */
    230  1.1  kiyohara 	IRQdisable;
    231  1.1  kiyohara 
    232  1.1  kiyohara 	if (howto & RB_HALT) {
    233  1.1  kiyohara 		printf("The operating system has halted.\r\n");
    234  1.1  kiyohara 		printf("Please press any key to reboot.\r\n");
    235  1.1  kiyohara 		cngetc();
    236  1.1  kiyohara 	}
    237  1.1  kiyohara 
    238  1.1  kiyohara 	printf("rebooting...\r\n");
    239  1.3  jakllsch 	marvell_system_reset();
    240  1.1  kiyohara 
    241  1.1  kiyohara 	/*NOTREACHED*/
    242  1.1  kiyohara }
    243  1.1  kiyohara 
    244  1.1  kiyohara static inline
    245  1.1  kiyohara pd_entry_t *
    246  1.1  kiyohara read_ttb(void)
    247  1.1  kiyohara {
    248  1.1  kiyohara 	long ttb;
    249  1.1  kiyohara 
    250  1.1  kiyohara 	__asm volatile("mrc	p15, 0, %0, c2, c0, 0" : "=r" (ttb));
    251  1.1  kiyohara 
    252  1.1  kiyohara 	return (pd_entry_t *)(ttb & ~((1<<14)-1));
    253  1.1  kiyohara }
    254  1.1  kiyohara 
    255  1.1  kiyohara /*
    256  1.1  kiyohara  * Static device mappings. These peripheral registers are mapped at
    257  1.1  kiyohara  * fixed virtual addresses very early in initarm() so that we can use
    258  1.1  kiyohara  * them while booting the kernel, and stay at the same address
    259  1.1  kiyohara  * throughout whole kernel's life time.
    260  1.1  kiyohara  *
    261  1.1  kiyohara  * We use this table twice; once with bootstrap page table, and once
    262  1.1  kiyohara  * with kernel's page table which we build up in initarm().
    263  1.1  kiyohara  *
    264  1.1  kiyohara  * Since we map these registers into the bootstrap page table using
    265  1.1  kiyohara  * pmap_devmap_bootstrap() which calls pmap_map_chunk(), we map
    266  1.1  kiyohara  * registers segment-aligned and segment-rounded in order to avoid
    267  1.1  kiyohara  * using the 2nd page tables.
    268  1.1  kiyohara  */
    269  1.1  kiyohara #define _A(a)	((a) & ~L1_S_OFFSET)
    270  1.1  kiyohara #define _S(s)	(((s) + L1_S_SIZE - 1) & ~(L1_S_SIZE-1))
    271  1.1  kiyohara 
    272  1.1  kiyohara static const struct pmap_devmap marvell_devmap[] = {
    273  1.1  kiyohara 	{
    274  1.1  kiyohara 		MARVELL_INTERREGS_VBASE,
    275  1.1  kiyohara 		_A(MARVELL_INTERREGS_PBASE),
    276  1.1  kiyohara 		_S(MARVELL_INTERREGS_SIZE),
    277  1.1  kiyohara 		VM_PROT_READ|VM_PROT_WRITE,
    278  1.1  kiyohara 		PTE_NOCACHE,
    279  1.1  kiyohara 	},
    280  1.1  kiyohara 
    281  1.1  kiyohara 	{ 0, 0, 0, 0, 0 }
    282  1.1  kiyohara };
    283  1.1  kiyohara 
    284  1.1  kiyohara #undef  _A
    285  1.1  kiyohara #undef  _S
    286  1.1  kiyohara 
    287  1.4  jakllsch extern uint32_t *u_boot_args[];
    288  1.1  kiyohara 
    289  1.1  kiyohara /*
    290  1.1  kiyohara  * u_int initarm(...)
    291  1.1  kiyohara  *
    292  1.1  kiyohara  * Initial entry point on startup. This gets called before main() is
    293  1.1  kiyohara  * entered.
    294  1.1  kiyohara  * It should be responsible for setting up everything that must be
    295  1.1  kiyohara  * in place when main is called.
    296  1.1  kiyohara  * This includes
    297  1.1  kiyohara  *   Taking a copy of the boot configuration structure.
    298  1.1  kiyohara  *   Initialising the physical console so characters can be printed.
    299  1.1  kiyohara  *   Setting up page tables for the kernel
    300  1.1  kiyohara  *   Relocating the kernel to the bottom of physical memory
    301  1.1  kiyohara  */
    302  1.1  kiyohara u_int
    303  1.1  kiyohara initarm(void *arg)
    304  1.1  kiyohara {
    305  1.1  kiyohara 	uint32_t target, attr, base, size;
    306  1.1  kiyohara 	u_int l1pagetable;
    307  1.1  kiyohara 	int loop, pt_index, cs, memtag = 0, iotag = 0, window;
    308  1.1  kiyohara 
    309  1.1  kiyohara 	/* map some peripheral registers */
    310  1.1  kiyohara 	pmap_devmap_bootstrap((vaddr_t)read_ttb(), marvell_devmap);
    311  1.1  kiyohara 
    312  1.1  kiyohara 	mvsoc_bootstrap(MARVELL_INTERREGS_VBASE);
    313  1.1  kiyohara 
    314  1.1  kiyohara 	/* Get ready for splfoo() */
    315  1.1  kiyohara 	switch (mvsoc_model()) {
    316  1.1  kiyohara #ifdef ORION
    317  1.1  kiyohara 	case MARVELL_ORION_1_88F1181:
    318  1.1  kiyohara 	case MARVELL_ORION_1_88F5082:
    319  1.1  kiyohara 	case MARVELL_ORION_1_88F5180N:
    320  1.1  kiyohara 	case MARVELL_ORION_1_88F5181:
    321  1.1  kiyohara 	case MARVELL_ORION_1_88F5182:
    322  1.1  kiyohara 	case MARVELL_ORION_1_88F6082:
    323  1.1  kiyohara 	case MARVELL_ORION_1_88F6183:
    324  1.1  kiyohara 	case MARVELL_ORION_1_88W8660:
    325  1.1  kiyohara 	case MARVELL_ORION_2_88F1281:
    326  1.1  kiyohara 	case MARVELL_ORION_2_88F5281:
    327  1.1  kiyohara 		orion_intr_bootstrap();
    328  1.1  kiyohara 
    329  1.1  kiyohara 		memtag = ORION_TAG_PEX0_MEM;
    330  1.1  kiyohara 		iotag = ORION_TAG_PEX0_IO;
    331  1.1  kiyohara 		nwindow = ORION_MLMB_NWINDOW;
    332  1.1  kiyohara 		nremap = ORION_MLMB_NREMAP;
    333  1.1  kiyohara 
    334  1.1  kiyohara 		orion_getclks(MARVELL_INTERREGS_VBASE);
    335  1.1  kiyohara 		break;
    336  1.1  kiyohara #endif	/* ORION */
    337  1.1  kiyohara 
    338  1.1  kiyohara #ifdef KIRKWOOD
    339  1.1  kiyohara 	case MARVELL_KIRKWOOD_88F6180:
    340  1.1  kiyohara 	case MARVELL_KIRKWOOD_88F6192:
    341  1.1  kiyohara 	case MARVELL_KIRKWOOD_88F6281:
    342  1.1  kiyohara 		kirkwood_intr_bootstrap();
    343  1.1  kiyohara 
    344  1.1  kiyohara 		memtag = KIRKWOOD_TAG_PEX_MEM;
    345  1.1  kiyohara 		iotag = KIRKWOOD_TAG_PEX_IO;
    346  1.1  kiyohara 		nwindow = KIRKWOOD_MLMB_NWINDOW;
    347  1.1  kiyohara 		nremap = KIRKWOOD_MLMB_NREMAP;
    348  1.1  kiyohara 
    349  1.1  kiyohara 		kirkwood_getclks(MARVELL_INTERREGS_VBASE);
    350  1.1  kiyohara 		break;
    351  1.1  kiyohara #endif	/* KIRKWOOD */
    352  1.1  kiyohara 
    353  1.1  kiyohara #ifdef MV78XX0
    354  1.1  kiyohara 	case MARVELL_MV78XX0_MV78100:
    355  1.1  kiyohara 	case MARVELL_MV78XX0_MV78200:
    356  1.1  kiyohara 		mv78xx0_intr_bootstrap();
    357  1.1  kiyohara 
    358  1.1  kiyohara 		memtag = MV78XX0_TAG_PEX_MEM;
    359  1.1  kiyohara 		iotag = MV78XX0_TAG_PEX_IO;
    360  1.1  kiyohara 		nwindow = MV78XX0_MLMB_NWINDOW;
    361  1.1  kiyohara 		nremap = MV78XX0_MLMB_NREMAP;
    362  1.1  kiyohara 
    363  1.1  kiyohara 		mv78xx0_getclks(MARVELL_INTERREGS_VBASE);
    364  1.1  kiyohara 		break;
    365  1.1  kiyohara #endif	/* MV78XX0 */
    366  1.1  kiyohara 
    367  1.1  kiyohara 	default:
    368  1.1  kiyohara 		/* We can't output console here yet... */
    369  1.1  kiyohara 		panic("unknown model...\n");
    370  1.1  kiyohara 
    371  1.1  kiyohara 		/* NOTREACHED */
    372  1.1  kiyohara 	}
    373  1.1  kiyohara 
    374  1.1  kiyohara 	/* Reset PCI-Express space to window register. */
    375  1.1  kiyohara 	window = mvsoc_target(memtag, &target, &attr, NULL, NULL);
    376  1.1  kiyohara 	write_mlmbreg(MVSOC_MLMB_WCR(window),
    377  1.1  kiyohara 	    MVSOC_MLMB_WCR_WINEN |
    378  1.1  kiyohara 	    MVSOC_MLMB_WCR_TARGET(target) |
    379  1.1  kiyohara 	    MVSOC_MLMB_WCR_ATTR(attr) |
    380  1.1  kiyohara 	    MVSOC_MLMB_WCR_SIZE(MARVELL_PEXMEM_SIZE));
    381  1.1  kiyohara 	write_mlmbreg(MVSOC_MLMB_WBR(window),
    382  1.1  kiyohara 	    MARVELL_PEXMEM_PBASE & MVSOC_MLMB_WBR_BASE_MASK);
    383  1.1  kiyohara #ifdef PCI_NETBSD_CONFIGURE
    384  1.1  kiyohara 	if (window < nremap) {
    385  1.1  kiyohara 		write_mlmbreg(MVSOC_MLMB_WRLR(window),
    386  1.1  kiyohara 		    MARVELL_PEXMEM_PBASE & MVSOC_MLMB_WRLR_REMAP_MASK);
    387  1.1  kiyohara 		write_mlmbreg(MVSOC_MLMB_WRHR(window), 0);
    388  1.1  kiyohara 	}
    389  1.1  kiyohara #endif
    390  1.1  kiyohara 	window = mvsoc_target(iotag, &target, &attr, NULL, NULL);
    391  1.1  kiyohara 	write_mlmbreg(MVSOC_MLMB_WCR(window),
    392  1.1  kiyohara 	    MVSOC_MLMB_WCR_WINEN |
    393  1.1  kiyohara 	    MVSOC_MLMB_WCR_TARGET(target) |
    394  1.1  kiyohara 	    MVSOC_MLMB_WCR_ATTR(attr) |
    395  1.1  kiyohara 	    MVSOC_MLMB_WCR_SIZE(MARVELL_PEXIO_SIZE));
    396  1.1  kiyohara 	write_mlmbreg(MVSOC_MLMB_WBR(window),
    397  1.1  kiyohara 	    MARVELL_PEXIO_PBASE & MVSOC_MLMB_WBR_BASE_MASK);
    398  1.1  kiyohara #ifdef PCI_NETBSD_CONFIGURE
    399  1.1  kiyohara 	if (window < nremap) {
    400  1.1  kiyohara 		write_mlmbreg(MVSOC_MLMB_WRLR(window),
    401  1.1  kiyohara 		    MARVELL_PEXIO_PBASE & MVSOC_MLMB_WRLR_REMAP_MASK);
    402  1.1  kiyohara 		write_mlmbreg(MVSOC_MLMB_WRHR(window), 0);
    403  1.1  kiyohara 	}
    404  1.1  kiyohara #endif
    405  1.1  kiyohara 
    406  1.1  kiyohara 	/*
    407  1.1  kiyohara 	 * Heads up ... Setup the CPU / MMU / TLB functions
    408  1.1  kiyohara 	 */
    409  1.1  kiyohara 	if (set_cpufuncs())
    410  1.1  kiyohara 		panic("cpu not recognized!");
    411  1.1  kiyohara 
    412  1.1  kiyohara 	/*
    413  1.1  kiyohara 	 * U-Boot doesn't use the virtual memory.
    414  1.1  kiyohara 	 *
    415  1.1  kiyohara 	 * Physical Address Range     Description
    416  1.1  kiyohara 	 * -----------------------    ----------------------------------
    417  1.1  kiyohara 	 * 0x00000000 - 0x0fffffff    SDRAM Bank 0 (max 256MB)
    418  1.1  kiyohara 	 * 0x10000000 - 0x1fffffff    SDRAM Bank 1 (max 256MB)
    419  1.1  kiyohara 	 * 0x20000000 - 0x2fffffff    SDRAM Bank 2 (max 256MB)
    420  1.1  kiyohara 	 * 0x30000000 - 0x3fffffff    SDRAM Bank 3 (max 256MB)
    421  1.1  kiyohara 	 * 0xf1000000 - 0xf10fffff    SoC Internal Registers
    422  1.1  kiyohara 	 */
    423  1.1  kiyohara 
    424  1.1  kiyohara 	cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT);
    425  1.1  kiyohara 
    426  1.1  kiyohara 	consinit();
    427  1.1  kiyohara 
    428  1.1  kiyohara 	/* Talk to the user */
    429  1.1  kiyohara #define BDSTR(s)	_BDSTR(s)
    430  1.1  kiyohara #define _BDSTR(s)	#s
    431  1.1  kiyohara 	printf("\nNetBSD/evbarm (" BDSTR(EVBARM_BOARDTYPE) ") booting ...\n");
    432  1.1  kiyohara 
    433  1.4  jakllsch 	/* copy command line U-Boot gave us */
    434  1.4  jakllsch 	strncpy(bootargs, (char *)u_boot_args[3], sizeof(bootargs));
    435  1.4  jakllsch 
    436  1.1  kiyohara #ifdef VERBOSE_INIT_ARM
    437  1.1  kiyohara 	printf("initarm: Configuring system ...\n");
    438  1.1  kiyohara #endif
    439  1.1  kiyohara 
    440  1.1  kiyohara 	bootconfig.dramblocks = 0;
    441  1.1  kiyohara 	physical_end = physmem = 0;
    442  1.1  kiyohara 	for (cs = MARVELL_TAG_SDRAM_CS0; cs <= MARVELL_TAG_SDRAM_CS3; cs++) {
    443  1.1  kiyohara 		mvsoc_target(cs, &target, &attr, &base, &size);
    444  1.1  kiyohara 		if (size == 0)
    445  1.1  kiyohara 			continue;
    446  1.1  kiyohara 
    447  1.1  kiyohara 		bootconfig.dram[bootconfig.dramblocks].address = base;
    448  1.1  kiyohara 		bootconfig.dram[bootconfig.dramblocks].pages = size / PAGE_SIZE;
    449  1.1  kiyohara 
    450  1.1  kiyohara 		if (base != physical_end)
    451  1.1  kiyohara 			panic("memory hole not support");
    452  1.1  kiyohara 
    453  1.1  kiyohara 		physical_end += size;
    454  1.1  kiyohara 		physmem += size / PAGE_SIZE;
    455  1.1  kiyohara 
    456  1.1  kiyohara 		bootconfig.dramblocks++;
    457  1.1  kiyohara 	}
    458  1.1  kiyohara 
    459  1.1  kiyohara 	/*
    460  1.1  kiyohara 	 * Set up the variables that define the availablilty of
    461  1.1  kiyohara 	 * physical memory.  For now, we're going to set
    462  1.1  kiyohara 	 * physical_freestart to 0xa0008000 (where the kernel
    463  1.1  kiyohara 	 * was loaded), and allocate the memory we need downwards.
    464  1.1  kiyohara 	 * If we get too close to the L1 table that we set up, we
    465  1.1  kiyohara 	 * will panic.  We will update physical_freestart and
    466  1.1  kiyohara 	 * physical_freeend later to reflect what pmap_bootstrap()
    467  1.1  kiyohara 	 * wants to see.
    468  1.1  kiyohara 	 *
    469  1.1  kiyohara 	 * XXX pmap_bootstrap() needs an enema.
    470  1.1  kiyohara 	 */
    471  1.1  kiyohara 	physical_start = bootconfig.dram[0].address;
    472  1.1  kiyohara 
    473  1.1  kiyohara 	/*
    474  1.1  kiyohara 	 * Our kernel is at the beginning of memory, so set our free space to
    475  1.1  kiyohara 	 * all the memory after the kernel.
    476  1.1  kiyohara 	 */
    477  1.1  kiyohara 	physical_freestart = KERN_VTOPHYS(round_page((vaddr_t)_end));
    478  1.1  kiyohara 	physical_freeend = physical_end;
    479  1.1  kiyohara 
    480  1.1  kiyohara #ifdef VERBOSE_INIT_ARM
    481  1.1  kiyohara 	/* Tell the user about the memory */
    482  1.1  kiyohara 	printf("physmemory: %d pages at 0x%08lx -> 0x%08lx\n", physmem,
    483  1.1  kiyohara 	    physical_start, physical_end - 1);
    484  1.1  kiyohara #endif
    485  1.1  kiyohara 
    486  1.1  kiyohara 	/*
    487  1.1  kiyohara 	 * Okay, the kernel starts 8kB in from the bottom of physical
    488  1.1  kiyohara 	 * memory.  We are going to allocate our bootstrap pages upwards
    489  1.1  kiyohara 	 * from physical_freestart.
    490  1.1  kiyohara 	 *
    491  1.1  kiyohara 	 * We need to allocate some fixed page tables to get the kernel
    492  1.1  kiyohara 	 * going.  We allocate one page directory and a number of page
    493  1.1  kiyohara 	 * tables and store the physical addresses in the kernel_pt_table
    494  1.1  kiyohara 	 * array.
    495  1.1  kiyohara 	 *
    496  1.1  kiyohara 	 * The kernel page directory must be on a 16K boundary.  The page
    497  1.1  kiyohara 	 * tables must be on 4K bounaries.  What we do is allocate the
    498  1.1  kiyohara 	 * page directory on the first 16K boundary that we encounter, and
    499  1.1  kiyohara 	 * the page tables on 4K boundaries otherwise.  Since we allocate
    500  1.1  kiyohara 	 * at least 3 L2 page tables, we are guaranteed to encounter at
    501  1.1  kiyohara 	 * least one 16K aligned region.
    502  1.1  kiyohara 	 */
    503  1.1  kiyohara 
    504  1.1  kiyohara #ifdef VERBOSE_INIT_ARM
    505  1.1  kiyohara 	printf("Allocating page tables\n");
    506  1.1  kiyohara #endif
    507  1.1  kiyohara 
    508  1.1  kiyohara 	free_pages = (physical_freeend - physical_freestart) / PAGE_SIZE;
    509  1.1  kiyohara 
    510  1.1  kiyohara #ifdef VERBOSE_INIT_ARM
    511  1.1  kiyohara 	printf("freestart = 0x%08lx, free_pages = %d (0x%08x)\n",
    512  1.1  kiyohara 	    physical_freestart, free_pages, free_pages);
    513  1.1  kiyohara #endif
    514  1.1  kiyohara 
    515  1.1  kiyohara 	/*
    516  1.1  kiyohara 	 * Define a macro to simplify memory allocation.  As we allocate the
    517  1.1  kiyohara 	 * memory, make sure that we don't walk over our temporary first level
    518  1.1  kiyohara 	 * translation table.
    519  1.1  kiyohara 	 */
    520  1.1  kiyohara #define valloc_pages(var, np)						\
    521  1.1  kiyohara 	(var).pv_pa = physical_freestart;				\
    522  1.1  kiyohara 	physical_freestart += ((np) * PAGE_SIZE);			\
    523  1.1  kiyohara 	if (physical_freestart > (physical_freeend - L1_TABLE_SIZE))	\
    524  1.1  kiyohara 		panic("initarm: out of memory");			\
    525  1.1  kiyohara 	free_pages -= (np);						\
    526  1.1  kiyohara 	(var).pv_va = KERN_PHYSTOV((var).pv_pa);			\
    527  1.1  kiyohara 	memset((char *)(var).pv_va, 0, ((np) * PAGE_SIZE));
    528  1.1  kiyohara 
    529  1.1  kiyohara 	pt_index = 0;
    530  1.1  kiyohara 	kernel_l1pt.pv_pa = 0;
    531  1.1  kiyohara 	kernel_l1pt.pv_va = 0;
    532  1.1  kiyohara 	for (loop = 0; loop <= NUM_KERNEL_PTS; ++loop) {
    533  1.1  kiyohara 		/* Are we 16KB aligned for an L1 ? */
    534  1.1  kiyohara 		if ((physical_freestart & (L1_TABLE_SIZE - 1)) == 0 &&
    535  1.1  kiyohara 		    kernel_l1pt.pv_pa == 0) {
    536  1.1  kiyohara 			valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE);
    537  1.1  kiyohara 		} else {
    538  1.1  kiyohara 			valloc_pages(kernel_pt_table[pt_index],
    539  1.1  kiyohara 			    L2_TABLE_SIZE / PAGE_SIZE);
    540  1.1  kiyohara 			++pt_index;
    541  1.1  kiyohara 		}
    542  1.1  kiyohara 	}
    543  1.1  kiyohara 
    544  1.1  kiyohara 	/* This should never be able to happen but better confirm that. */
    545  1.1  kiyohara 	if (!kernel_l1pt.pv_pa ||
    546  1.1  kiyohara 	    (kernel_l1pt.pv_pa & (L1_TABLE_SIZE - 1)) != 0)
    547  1.1  kiyohara 		panic("initarm: Failed to align the kernel page directory");
    548  1.1  kiyohara 
    549  1.1  kiyohara 	/*
    550  1.1  kiyohara 	 * Allocate a page for the system page mapped to V0x00000000
    551  1.1  kiyohara 	 * This page will just contain the system vectors and can be
    552  1.1  kiyohara 	 * shared by all processes.
    553  1.1  kiyohara 	 */
    554  1.1  kiyohara 	valloc_pages(systempage, 1);
    555  1.1  kiyohara 	systempage.pv_va = 0x00000000;
    556  1.1  kiyohara 
    557  1.1  kiyohara 	/* Allocate stacks for all modes */
    558  1.1  kiyohara 	valloc_pages(irqstack, IRQ_STACK_SIZE);
    559  1.1  kiyohara 	valloc_pages(abtstack, ABT_STACK_SIZE);
    560  1.1  kiyohara 	valloc_pages(undstack, UND_STACK_SIZE);
    561  1.1  kiyohara 	valloc_pages(kernelstack, UPAGES);
    562  1.1  kiyohara 
    563  1.1  kiyohara #ifdef VERBOSE_INIT_ARM
    564  1.1  kiyohara 	printf("IRQ stack: p0x%08lx v0x%08lx\n", irqstack.pv_pa,
    565  1.1  kiyohara 	    irqstack.pv_va);
    566  1.1  kiyohara 	printf("ABT stack: p0x%08lx v0x%08lx\n", abtstack.pv_pa,
    567  1.1  kiyohara 	    abtstack.pv_va);
    568  1.1  kiyohara 	printf("UND stack: p0x%08lx v0x%08lx\n", undstack.pv_pa,
    569  1.1  kiyohara 	    undstack.pv_va);
    570  1.1  kiyohara 	printf("SVC stack: p0x%08lx v0x%08lx\n", kernelstack.pv_pa,
    571  1.1  kiyohara 	    kernelstack.pv_va);
    572  1.1  kiyohara #endif
    573  1.1  kiyohara 
    574  1.1  kiyohara 	/* Allocate the message buffer. */
    575  1.1  kiyohara 	{
    576  1.1  kiyohara 		pv_addr_t msgbuf;
    577  1.1  kiyohara 
    578  1.1  kiyohara 		valloc_pages(msgbuf, round_page(MSGBUFSIZE) / PAGE_SIZE);
    579  1.1  kiyohara 		msgbufphys = msgbuf.pv_pa;
    580  1.1  kiyohara 	}
    581  1.1  kiyohara 
    582  1.1  kiyohara 	/*
    583  1.1  kiyohara 	 * Ok we have allocated physical pages for the primary kernel
    584  1.1  kiyohara 	 * page tables
    585  1.1  kiyohara 	 */
    586  1.1  kiyohara 
    587  1.1  kiyohara #ifdef VERBOSE_INIT_ARM
    588  1.1  kiyohara 	printf("Creating L1 page table at 0x%08lx\n", kernel_l1pt.pv_pa);
    589  1.1  kiyohara #endif
    590  1.1  kiyohara 
    591  1.1  kiyohara 	/*
    592  1.1  kiyohara 	 * Now we start construction of the L1 page table
    593  1.1  kiyohara 	 * We start by mapping the L2 page tables into the L1.
    594  1.1  kiyohara 	 * This means that we can replace L1 mappings later on if necessary
    595  1.1  kiyohara 	 */
    596  1.1  kiyohara 	l1pagetable = kernel_l1pt.pv_va;
    597  1.1  kiyohara 
    598  1.1  kiyohara 	/* Map the L2 pages tables in the L1 page table */
    599  1.1  kiyohara 	pmap_link_l2pt(l1pagetable, 0x00000000,
    600  1.1  kiyohara 	    &kernel_pt_table[KERNEL_PT_SYS]);
    601  1.1  kiyohara 	for (loop = 0; loop < KERNEL_PT_KERNEL_NUM; loop++)
    602  1.1  kiyohara 		pmap_link_l2pt(l1pagetable, KERNEL_BASE + loop * 0x00400000,
    603  1.1  kiyohara 		    &kernel_pt_table[KERNEL_PT_KERNEL + loop]);
    604  1.1  kiyohara 	for (loop = 0; loop < KERNEL_PT_VMDATA_NUM; loop++)
    605  1.1  kiyohara 		pmap_link_l2pt(l1pagetable, KERNEL_VM_BASE + loop * 0x00400000,
    606  1.1  kiyohara 		    &kernel_pt_table[KERNEL_PT_VMDATA + loop]);
    607  1.1  kiyohara 
    608  1.1  kiyohara 	/* update the top of the kernel VM */
    609  1.1  kiyohara 	pmap_curmaxkvaddr =
    610  1.1  kiyohara 	    KERNEL_VM_BASE + (KERNEL_PT_VMDATA_NUM * 0x00400000);
    611  1.1  kiyohara 
    612  1.1  kiyohara #ifdef VERBOSE_INIT_ARM
    613  1.1  kiyohara 	printf("Mapping kernel\n");
    614  1.1  kiyohara #endif
    615  1.1  kiyohara 
    616  1.1  kiyohara 	/* Now we fill in the L2 pagetable for the kernel static code/data */
    617  1.1  kiyohara 	{
    618  1.1  kiyohara 		extern char etext[], _end[];
    619  1.1  kiyohara 		size_t textsize = (uintptr_t)etext - KERNEL_TEXT_BASE;
    620  1.1  kiyohara 		size_t totalsize = (uintptr_t)_end - KERNEL_TEXT_BASE;
    621  1.1  kiyohara 		u_int logical;
    622  1.1  kiyohara 
    623  1.1  kiyohara 		textsize = (textsize + PGOFSET) & ~PGOFSET;
    624  1.1  kiyohara 		totalsize = (totalsize + PGOFSET) & ~PGOFSET;
    625  1.1  kiyohara 
    626  1.1  kiyohara 		logical = 0x00000000;	/* offset of kernel in RAM */
    627  1.1  kiyohara 
    628  1.1  kiyohara 		logical += pmap_map_chunk(l1pagetable, KERNEL_BASE + logical,
    629  1.1  kiyohara 		    physical_start + logical, textsize,
    630  1.1  kiyohara 		    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
    631  1.1  kiyohara 		logical += pmap_map_chunk(l1pagetable, KERNEL_BASE + logical,
    632  1.1  kiyohara 		    physical_start + logical, totalsize - textsize,
    633  1.1  kiyohara 		    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
    634  1.1  kiyohara 	}
    635  1.1  kiyohara 
    636  1.1  kiyohara #ifdef VERBOSE_INIT_ARM
    637  1.1  kiyohara 	printf("Constructing L2 page tables\n");
    638  1.1  kiyohara #endif
    639  1.1  kiyohara 
    640  1.1  kiyohara 	/* Map the stack pages */
    641  1.1  kiyohara 	pmap_map_chunk(l1pagetable, irqstack.pv_va, irqstack.pv_pa,
    642  1.1  kiyohara 	    IRQ_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
    643  1.1  kiyohara 	pmap_map_chunk(l1pagetable, abtstack.pv_va, abtstack.pv_pa,
    644  1.1  kiyohara 	    ABT_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
    645  1.1  kiyohara 	pmap_map_chunk(l1pagetable, undstack.pv_va, undstack.pv_pa,
    646  1.1  kiyohara 	    UND_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
    647  1.1  kiyohara 	pmap_map_chunk(l1pagetable, kernelstack.pv_va, kernelstack.pv_pa,
    648  1.1  kiyohara 	    UPAGES * PAGE_SIZE, VM_PROT_READ | VM_PROT_WRITE, PTE_CACHE);
    649  1.1  kiyohara 
    650  1.1  kiyohara 	pmap_map_chunk(l1pagetable, kernel_l1pt.pv_va, kernel_l1pt.pv_pa,
    651  1.1  kiyohara 	    L1_TABLE_SIZE, VM_PROT_READ | VM_PROT_WRITE, PTE_PAGETABLE);
    652  1.1  kiyohara 
    653  1.1  kiyohara 	for (loop = 0; loop < NUM_KERNEL_PTS; ++loop)
    654  1.1  kiyohara 		pmap_map_chunk(l1pagetable, kernel_pt_table[loop].pv_va,
    655  1.1  kiyohara 		    kernel_pt_table[loop].pv_pa, L2_TABLE_SIZE,
    656  1.1  kiyohara 		    VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);
    657  1.1  kiyohara 
    658  1.1  kiyohara 	/* Map the vector page. */
    659  1.1  kiyohara 	pmap_map_entry(l1pagetable, ARM_VECTORS_LOW, systempage.pv_pa,
    660  1.1  kiyohara 	    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
    661  1.1  kiyohara 
    662  1.1  kiyohara 	/*
    663  1.1  kiyohara 	 * Map integrated peripherals at same address in first level page
    664  1.1  kiyohara 	 * table so that we can continue to use console.
    665  1.1  kiyohara 	 */
    666  1.1  kiyohara 	pmap_devmap_bootstrap(l1pagetable, marvell_devmap);
    667  1.1  kiyohara 
    668  1.1  kiyohara 	/*
    669  1.1  kiyohara 	 * Now we have the real page tables in place so we can switch to them.
    670  1.1  kiyohara 	 * Once this is done we will be running with the REAL kernel page
    671  1.1  kiyohara 	 * tables.
    672  1.1  kiyohara 	 */
    673  1.1  kiyohara 
    674  1.1  kiyohara 	/* Switch tables */
    675  1.1  kiyohara #ifdef VERBOSE_INIT_ARM
    676  1.1  kiyohara 	printf("switching to new L1 page table  @%#lx...", kernel_l1pt.pv_pa);
    677  1.1  kiyohara #endif
    678  1.1  kiyohara 
    679  1.1  kiyohara 	cpu_setttb(kernel_l1pt.pv_pa);
    680  1.1  kiyohara 	cpu_tlb_flushID();
    681  1.1  kiyohara 	cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2));
    682  1.1  kiyohara 
    683  1.1  kiyohara 	/*
    684  1.1  kiyohara 	 * Moved from cpu_startup() as data_abort_handler() references
    685  1.1  kiyohara 	 * this during uvm init.
    686  1.1  kiyohara 	 */
    687  1.1  kiyohara 	uvm_lwp_setuarea(&lwp0, kernelstack.pv_va);
    688  1.1  kiyohara 
    689  1.1  kiyohara #ifdef VERBOSE_INIT_ARM
    690  1.1  kiyohara 	printf("bootstrap done.\n");
    691  1.1  kiyohara #endif
    692  1.1  kiyohara 
    693  1.1  kiyohara 	arm32_vector_init(ARM_VECTORS_LOW, ARM_VEC_ALL);
    694  1.1  kiyohara 
    695  1.1  kiyohara 	/*
    696  1.1  kiyohara 	 * Pages were allocated during the secondary bootstrap for the
    697  1.1  kiyohara 	 * stacks for different CPU modes.
    698  1.1  kiyohara 	 * We must now set the r13 registers in the different CPU modes to
    699  1.1  kiyohara 	 * point to these stacks.
    700  1.1  kiyohara 	 * Since the ARM stacks use STMFD etc. we must set r13 to the top end
    701  1.1  kiyohara 	 * of the stack memory.
    702  1.1  kiyohara 	 */
    703  1.1  kiyohara #ifdef VERBOSE_INIT_ARM
    704  1.1  kiyohara 	printf("init subsystems: stacks ");
    705  1.1  kiyohara #endif
    706  1.1  kiyohara 
    707  1.1  kiyohara 	set_stackptr(PSR_IRQ32_MODE,
    708  1.1  kiyohara 	    irqstack.pv_va + IRQ_STACK_SIZE * PAGE_SIZE);
    709  1.1  kiyohara 	set_stackptr(PSR_ABT32_MODE,
    710  1.1  kiyohara 	    abtstack.pv_va + ABT_STACK_SIZE * PAGE_SIZE);
    711  1.1  kiyohara 	set_stackptr(PSR_UND32_MODE,
    712  1.1  kiyohara 	    undstack.pv_va + UND_STACK_SIZE * PAGE_SIZE);
    713  1.1  kiyohara 
    714  1.1  kiyohara 	/*
    715  1.1  kiyohara 	 * Well we should set a data abort handler.
    716  1.1  kiyohara 	 * Once things get going this will change as we will need a proper
    717  1.1  kiyohara 	 * handler.
    718  1.1  kiyohara 	 * Until then we will use a handler that just panics but tells us
    719  1.1  kiyohara 	 * why.
    720  1.1  kiyohara 	 * Initialisation of the vectors will just panic on a data abort.
    721  1.1  kiyohara 	 * This just fills in a slightly better one.
    722  1.1  kiyohara 	 */
    723  1.1  kiyohara #ifdef VERBOSE_INIT_ARM
    724  1.1  kiyohara 	printf("vectors ");
    725  1.1  kiyohara #endif
    726  1.1  kiyohara 	data_abort_handler_address = (u_int)data_abort_handler;
    727  1.1  kiyohara 	prefetch_abort_handler_address = (u_int)prefetch_abort_handler;
    728  1.1  kiyohara 	undefined_handler_address = (u_int)undefinedinstruction_bounce;
    729  1.1  kiyohara 
    730  1.1  kiyohara 	/* Initialise the undefined instruction handlers */
    731  1.1  kiyohara #ifdef VERBOSE_INIT_ARM
    732  1.1  kiyohara 	printf("undefined ");
    733  1.1  kiyohara #endif
    734  1.1  kiyohara 	undefined_init();
    735  1.1  kiyohara 
    736  1.1  kiyohara 	/* Load memory into UVM. */
    737  1.1  kiyohara #ifdef VERBOSE_INIT_ARM
    738  1.1  kiyohara 	printf("page ");
    739  1.1  kiyohara #endif
    740  1.1  kiyohara 	uvm_setpagesize();	/* initialize PAGE_SIZE-dependent variables */
    741  1.1  kiyohara 	uvm_page_physload(atop(physical_freestart), atop(physical_freeend),
    742  1.1  kiyohara 	    atop(physical_freestart), atop(physical_freeend),
    743  1.1  kiyohara 	    VM_FREELIST_DEFAULT);
    744  1.1  kiyohara 
    745  1.1  kiyohara 	/* Boot strap pmap telling it where the kernel page table is */
    746  1.1  kiyohara #ifdef VERBOSE_INIT_ARM
    747  1.1  kiyohara 	printf("pmap ");
    748  1.1  kiyohara #endif
    749  1.1  kiyohara 	pmap_bootstrap(KERNEL_VM_BASE, KERNEL_VM_BASE + KERNEL_VM_SIZE);
    750  1.1  kiyohara 
    751  1.1  kiyohara #ifdef VERBOSE_INIT_ARM
    752  1.1  kiyohara 	printf("done.\n");
    753  1.1  kiyohara #endif
    754  1.1  kiyohara 
    755  1.1  kiyohara #ifdef __HAVE_MEMORY_DISK__
    756  1.1  kiyohara 	md_root_setconf(memory_disk, sizeof memory_disk);
    757  1.1  kiyohara #endif
    758  1.1  kiyohara 
    759  1.4  jakllsch 	boot_args = bootargs;
    760  1.4  jakllsch 	parse_mi_bootargs(boot_args);
    761  1.4  jakllsch 
    762  1.1  kiyohara #ifdef BOOTHOWTO
    763  1.1  kiyohara 	boothowto |= BOOTHOWTO;
    764  1.1  kiyohara #endif
    765  1.1  kiyohara 
    766  1.1  kiyohara #ifdef KGDB
    767  1.1  kiyohara 	if (boothowto & RB_KDB) {
    768  1.1  kiyohara 		kgdb_debug_init = 1;
    769  1.1  kiyohara 		kgdb_connect(1);
    770  1.1  kiyohara 	}
    771  1.1  kiyohara #endif
    772  1.1  kiyohara 
    773  1.1  kiyohara #ifdef DDB
    774  1.1  kiyohara 	db_machine_init();
    775  1.1  kiyohara 	if (boothowto & RB_KDB)
    776  1.1  kiyohara 		Debugger();
    777  1.1  kiyohara #endif
    778  1.1  kiyohara 
    779  1.1  kiyohara 	/* we've a specific device_register routine */
    780  1.1  kiyohara 	evbarm_device_register = marvell_device_register;
    781  1.1  kiyohara 
    782  1.1  kiyohara 	/* We return the new stack pointer address */
    783  1.1  kiyohara 	return(kernelstack.pv_va + USPACE_SVC_STACK_TOP);
    784  1.1  kiyohara }
    785  1.1  kiyohara 
    786  1.1  kiyohara void
    787  1.1  kiyohara consinit(void)
    788  1.1  kiyohara {
    789  1.1  kiyohara 	static int consinit_called = 0;
    790  1.1  kiyohara 
    791  1.1  kiyohara 	if (consinit_called != 0)
    792  1.1  kiyohara 		return;
    793  1.1  kiyohara 
    794  1.1  kiyohara 	consinit_called = 1;
    795  1.1  kiyohara 
    796  1.1  kiyohara #if NCOM > 0
    797  1.1  kiyohara 	{
    798  1.1  kiyohara 		extern int mvuart_cnattach(bus_space_tag_t, bus_addr_t, int,
    799  1.1  kiyohara 					   uint32_t, int);
    800  1.1  kiyohara 
    801  1.1  kiyohara 		if (mvuart_cnattach(&mvsoc_bs_tag,
    802  1.1  kiyohara 		    MARVELL_INTERREGS_VBASE + MVSOC_COM0_BASE,
    803  1.1  kiyohara 		    comcnspeed, mvTclk, comcnmode))
    804  1.1  kiyohara 			panic("can't init serial console");
    805  1.1  kiyohara 	}
    806  1.1  kiyohara #else
    807  1.1  kiyohara 	panic("serial console not configured");
    808  1.1  kiyohara #endif
    809  1.1  kiyohara }
    810  1.1  kiyohara 
    811  1.1  kiyohara 
    812  1.1  kiyohara static void
    813  1.1  kiyohara marvell_device_register(device_t dev, void *aux)
    814  1.1  kiyohara {
    815  1.1  kiyohara 	prop_dictionary_t dict = device_properties(dev);
    816  1.1  kiyohara 
    817  1.1  kiyohara #if NCOM > 0
    818  1.1  kiyohara 	if (device_is_a(dev, "com") &&
    819  1.1  kiyohara 	    device_is_a(device_parent(dev), "mvsoc"))
    820  1.1  kiyohara 		prop_dictionary_set_uint32(dict, "frequency", mvTclk);
    821  1.1  kiyohara #endif
    822  1.1  kiyohara 	if (device_is_a(dev, "gtidmac")) {
    823  1.1  kiyohara 		prop_dictionary_set_uint32(dict,
    824  1.1  kiyohara 		    "dmb_speed", mvTclk * sizeof(uint32_t));	/* XXXXXX */
    825  1.1  kiyohara 		prop_dictionary_set_uint32(dict,
    826  1.1  kiyohara 		    "xore-irq-begin", ORION_IRQ_XOR0);
    827  1.1  kiyohara 	}
    828  1.1  kiyohara #if NGTPCI > 0 && defined(ORION)
    829  1.1  kiyohara 	if (device_is_a(dev, "gtpci")) {
    830  1.1  kiyohara 		extern struct bus_space
    831  1.1  kiyohara 		    orion_pci_io_bs_tag, orion_pci_mem_bs_tag;
    832  1.1  kiyohara 		extern struct arm32_pci_chipset arm32_gtpci_chipset;
    833  1.1  kiyohara 
    834  1.1  kiyohara 		prop_data_t io_bs_tag, mem_bs_tag, pc;
    835  1.1  kiyohara 		prop_array_t int2gpp;
    836  1.1  kiyohara 		prop_number_t gpp;
    837  1.1  kiyohara 		uint64_t start, end;
    838  1.1  kiyohara 		int i, j;
    839  1.1  kiyohara 		static struct {
    840  1.1  kiyohara 			const char *boardtype;
    841  1.1  kiyohara 			int pin[PCI_INTERRUPT_PIN_MAX];
    842  1.1  kiyohara 		} hints[] = {
    843  1.1  kiyohara 			{ "kuronas_x4",
    844  1.1  kiyohara 			    { 11, PCI_INTERRUPT_PIN_NONE } },
    845  1.1  kiyohara 
    846  1.1  kiyohara 			{ NULL,
    847  1.1  kiyohara 			    { PCI_INTERRUPT_PIN_NONE } },
    848  1.1  kiyohara 		};
    849  1.1  kiyohara 
    850  1.1  kiyohara 		arm32_gtpci_chipset.pc_conf_v = device_private(dev);
    851  1.1  kiyohara 		arm32_gtpci_chipset.pc_intr_v = device_private(dev);
    852  1.1  kiyohara 
    853  1.1  kiyohara 		io_bs_tag = prop_data_create_data_nocopy(
    854  1.1  kiyohara 		    &orion_pci_io_bs_tag, sizeof(struct bus_space));
    855  1.1  kiyohara 		KASSERT(io_bs_tag != NULL);
    856  1.1  kiyohara 		prop_dictionary_set(dict, "io-bus-tag", io_bs_tag);
    857  1.1  kiyohara 		prop_object_release(io_bs_tag);
    858  1.1  kiyohara 		mem_bs_tag = prop_data_create_data_nocopy(
    859  1.1  kiyohara 		    &orion_pci_mem_bs_tag, sizeof(struct bus_space));
    860  1.1  kiyohara 		KASSERT(mem_bs_tag != NULL);
    861  1.1  kiyohara 		prop_dictionary_set(dict, "mem-bus-tag", mem_bs_tag);
    862  1.1  kiyohara 		prop_object_release(mem_bs_tag);
    863  1.1  kiyohara 
    864  1.1  kiyohara 		pc = prop_data_create_data_nocopy(&arm32_gtpci_chipset,
    865  1.1  kiyohara 		    sizeof(struct arm32_pci_chipset));
    866  1.1  kiyohara 		KASSERT(pc != NULL);
    867  1.1  kiyohara 		prop_dictionary_set(dict, "pci-chipset", pc);
    868  1.1  kiyohara 		prop_object_release(pc);
    869  1.1  kiyohara 
    870  1.1  kiyohara 		marvell_startend_by_tag(ORION_TAG_PCI_IO, &start, &end);
    871  1.1  kiyohara 		prop_dictionary_set_uint64(dict, "iostart", start);
    872  1.1  kiyohara 		prop_dictionary_set_uint64(dict, "ioend", end);
    873  1.1  kiyohara 		marvell_startend_by_tag(ORION_TAG_PCI_MEM, &start, &end);
    874  1.1  kiyohara 		prop_dictionary_set_uint64(dict, "memstart", start);
    875  1.1  kiyohara 		prop_dictionary_set_uint64(dict, "memend", end);
    876  1.1  kiyohara 		prop_dictionary_set_uint32(dict,
    877  1.1  kiyohara 		    "cache-line-size", arm_dcache_align);
    878  1.1  kiyohara 
    879  1.1  kiyohara 		/* Setup the hint for interrupt-pin. */
    880  1.1  kiyohara #define BDSTR(s)		_BDSTR(s)
    881  1.1  kiyohara #define _BDSTR(s)		#s
    882  1.1  kiyohara #define THIS_BOARD(str)		(strcmp(str, BDSTR(EVBARM_BOARDTYPE)) == 0)
    883  1.1  kiyohara 		for (i = 0; hints[i].boardtype != NULL; i++)
    884  1.1  kiyohara 			if (THIS_BOARD(hints[i].boardtype))
    885  1.1  kiyohara 				break;
    886  1.1  kiyohara 		if (hints[i].boardtype == NULL)
    887  1.1  kiyohara 			return;
    888  1.1  kiyohara 
    889  1.1  kiyohara 		int2gpp =
    890  1.1  kiyohara 		    prop_array_create_with_capacity(PCI_INTERRUPT_PIN_MAX + 1);
    891  1.1  kiyohara 
    892  1.1  kiyohara 		/* first set dummy */
    893  1.1  kiyohara 		gpp = prop_number_create_integer(0);
    894  1.1  kiyohara 		prop_array_add(int2gpp, gpp);
    895  1.1  kiyohara 		prop_object_release(gpp);
    896  1.1  kiyohara 
    897  1.1  kiyohara 		for (j = 0; hints[i].pin[j] != PCI_INTERRUPT_PIN_NONE; j++) {
    898  1.1  kiyohara 			gpp = prop_number_create_integer(hints[i].pin[j]);
    899  1.1  kiyohara 			prop_array_add(int2gpp, gpp);
    900  1.1  kiyohara 			prop_object_release(gpp);
    901  1.1  kiyohara 		}
    902  1.1  kiyohara 		prop_dictionary_set(dict, "int2gpp", int2gpp);
    903  1.1  kiyohara 	}
    904  1.1  kiyohara #endif	/* NGTPCI > 0 && defined(ORION) */
    905  1.1  kiyohara #if NMVPEX > 0
    906  1.1  kiyohara 	if (device_is_a(dev, "mvpex")) {
    907  1.1  kiyohara #ifdef ORION
    908  1.1  kiyohara 		extern struct bus_space
    909  1.1  kiyohara 		    orion_pex0_io_bs_tag, orion_pex0_mem_bs_tag,
    910  1.1  kiyohara 		    orion_pex1_io_bs_tag, orion_pex1_mem_bs_tag;
    911  1.1  kiyohara #endif
    912  1.1  kiyohara #ifdef KIRKWOOD
    913  1.1  kiyohara 		extern struct bus_space
    914  1.1  kiyohara 		    kirkwood_pex_io_bs_tag, kirkwood_pex_mem_bs_tag;
    915  1.1  kiyohara #endif
    916  1.7   tsutsui 		extern struct arm32_pci_chipset arm32_mvpex0_chipset;
    917  1.7   tsutsui #ifdef ORION
    918  1.7   tsutsui 		extern struct arm32_pci_chipset arm32_mvpex1_chipset;
    919  1.7   tsutsui #endif
    920  1.1  kiyohara 
    921  1.7   tsutsui #ifdef ORION
    922  1.1  kiyohara 		struct marvell_attach_args *mva = aux;
    923  1.7   tsutsui #endif
    924  1.1  kiyohara 		struct bus_space *mvpex_io_bs_tag, *mvpex_mem_bs_tag;
    925  1.1  kiyohara 		struct arm32_pci_chipset *arm32_mvpex_chipset;
    926  1.1  kiyohara 		prop_data_t io_bs_tag, mem_bs_tag, pc;
    927  1.1  kiyohara 		uint64_t start, end;
    928  1.1  kiyohara 		int iotag, memtag;
    929  1.1  kiyohara 
    930  1.1  kiyohara 		switch (mvsoc_model()) {
    931  1.1  kiyohara #ifdef ORION
    932  1.1  kiyohara 		case MARVELL_ORION_1_88F5180N:
    933  1.1  kiyohara 		case MARVELL_ORION_1_88F5181:
    934  1.1  kiyohara 		case MARVELL_ORION_1_88F5182:
    935  1.1  kiyohara 		case MARVELL_ORION_1_88W8660:
    936  1.1  kiyohara 		case MARVELL_ORION_2_88F5281:
    937  1.1  kiyohara 			if (mva->mva_offset == MVSOC_PEX_BASE) {
    938  1.1  kiyohara 				mvpex_io_bs_tag = &orion_pex0_io_bs_tag;
    939  1.1  kiyohara 				mvpex_mem_bs_tag = &orion_pex0_mem_bs_tag;
    940  1.1  kiyohara 				arm32_mvpex_chipset = &arm32_mvpex0_chipset;
    941  1.1  kiyohara 				iotag = ORION_TAG_PEX0_IO;
    942  1.1  kiyohara 				memtag = ORION_TAG_PEX0_MEM;
    943  1.1  kiyohara 			} else {
    944  1.1  kiyohara 				mvpex_io_bs_tag = &orion_pex1_io_bs_tag;
    945  1.1  kiyohara 				mvpex_mem_bs_tag = &orion_pex1_mem_bs_tag;
    946  1.1  kiyohara 				arm32_mvpex_chipset = &arm32_mvpex1_chipset;
    947  1.1  kiyohara 				iotag = ORION_TAG_PEX1_IO;
    948  1.1  kiyohara 				memtag = ORION_TAG_PEX1_MEM;
    949  1.1  kiyohara 			}
    950  1.1  kiyohara 			break;
    951  1.1  kiyohara #endif
    952  1.1  kiyohara 
    953  1.1  kiyohara #ifdef KIRKWOOD
    954  1.1  kiyohara 		case MARVELL_KIRKWOOD_88F6180:
    955  1.1  kiyohara 		case MARVELL_KIRKWOOD_88F6192:
    956  1.1  kiyohara 		case MARVELL_KIRKWOOD_88F6281:
    957  1.1  kiyohara 			mvpex_io_bs_tag = &kirkwood_pex_io_bs_tag;
    958  1.1  kiyohara 			mvpex_mem_bs_tag = &kirkwood_pex_mem_bs_tag;
    959  1.1  kiyohara 			arm32_mvpex_chipset = &arm32_mvpex0_chipset;
    960  1.1  kiyohara 			iotag = KIRKWOOD_TAG_PEX_IO;
    961  1.1  kiyohara 			memtag = KIRKWOOD_TAG_PEX_MEM;
    962  1.1  kiyohara 			break;
    963  1.1  kiyohara #endif
    964  1.1  kiyohara 
    965  1.1  kiyohara 		default:
    966  1.1  kiyohara 			return;
    967  1.1  kiyohara 		}
    968  1.1  kiyohara 
    969  1.1  kiyohara 		arm32_mvpex_chipset->pc_conf_v = device_private(dev);
    970  1.1  kiyohara 		arm32_mvpex_chipset->pc_intr_v = device_private(dev);
    971  1.1  kiyohara 
    972  1.1  kiyohara 		io_bs_tag = prop_data_create_data_nocopy(
    973  1.1  kiyohara 		    mvpex_io_bs_tag, sizeof(struct bus_space));
    974  1.1  kiyohara 		KASSERT(io_bs_tag != NULL);
    975  1.1  kiyohara 		prop_dictionary_set(dict, "io-bus-tag", io_bs_tag);
    976  1.1  kiyohara 		prop_object_release(io_bs_tag);
    977  1.1  kiyohara 		mem_bs_tag = prop_data_create_data_nocopy(
    978  1.1  kiyohara 		    mvpex_mem_bs_tag, sizeof(struct bus_space));
    979  1.1  kiyohara 		KASSERT(mem_bs_tag != NULL);
    980  1.1  kiyohara 		prop_dictionary_set(dict, "mem-bus-tag", mem_bs_tag);
    981  1.1  kiyohara 		prop_object_release(mem_bs_tag);
    982  1.1  kiyohara 
    983  1.1  kiyohara 		pc = prop_data_create_data_nocopy(arm32_mvpex_chipset,
    984  1.1  kiyohara 		    sizeof(struct arm32_pci_chipset));
    985  1.1  kiyohara 		KASSERT(pc != NULL);
    986  1.1  kiyohara 		prop_dictionary_set(dict, "pci-chipset", pc);
    987  1.1  kiyohara 		prop_object_release(pc);
    988  1.1  kiyohara 
    989  1.1  kiyohara 		marvell_startend_by_tag(iotag, &start, &end);
    990  1.1  kiyohara 		prop_dictionary_set_uint64(dict, "iostart", start);
    991  1.1  kiyohara 		prop_dictionary_set_uint64(dict, "ioend", end);
    992  1.1  kiyohara 		marvell_startend_by_tag(memtag, &start, &end);
    993  1.1  kiyohara 		prop_dictionary_set_uint64(dict, "memstart", start);
    994  1.1  kiyohara 		prop_dictionary_set_uint64(dict, "memend", end);
    995  1.1  kiyohara 		prop_dictionary_set_uint32(dict,
    996  1.1  kiyohara 		    "cache-line-size", arm_dcache_align);
    997  1.1  kiyohara 	}
    998  1.1  kiyohara #endif
    999  1.1  kiyohara }
   1000  1.1  kiyohara 
   1001  1.1  kiyohara #if NGTPCI > 0 || NMVPEX > 0
   1002  1.1  kiyohara static void
   1003  1.1  kiyohara marvell_startend_by_tag(int tag, uint64_t *start, uint64_t *end)
   1004  1.1  kiyohara {
   1005  1.1  kiyohara 	uint32_t base, size;
   1006  1.1  kiyohara 	int win;
   1007  1.1  kiyohara 
   1008  1.1  kiyohara 	win = mvsoc_target(tag, NULL, NULL, &base, &size);
   1009  1.1  kiyohara 	if (size != 0) {
   1010  1.1  kiyohara 		if (win < nremap)
   1011  1.1  kiyohara 			*start = read_mlmbreg(MVSOC_MLMB_WRLR(win)) |
   1012  1.1  kiyohara 			    ((read_mlmbreg(MVSOC_MLMB_WRHR(win)) << 16) << 16);
   1013  1.1  kiyohara 		else
   1014  1.1  kiyohara 			*start = base;
   1015  1.1  kiyohara 		*end = *start + size - 1;
   1016  1.1  kiyohara 	}
   1017  1.1  kiyohara }
   1018  1.1  kiyohara #endif
   1019