Home | History | Annotate | Line # | Download | only in integrator
integrator_machdep.c revision 1.77
      1 /*	$NetBSD: integrator_machdep.c,v 1.77 2019/07/16 14:41:46 skrll Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 2001,2002 ARM Ltd
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  * 3. The name of the company may not be used to endorse or promote
     16  *    products derived from this software without specific prior written
     17  *    permission.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND
     20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL ARM LTD
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 /*
     33  * Copyright (c) 1997,1998 Mark Brinicombe.
     34  * Copyright (c) 1997,1998 Causality Limited.
     35  * All rights reserved.
     36  *
     37  * Redistribution and use in source and binary forms, with or without
     38  * modification, are permitted provided that the following conditions
     39  * are met:
     40  * 1. Redistributions of source code must retain the above copyright
     41  *    notice, this list of conditions and the following disclaimer.
     42  * 2. Redistributions in binary form must reproduce the above copyright
     43  *    notice, this list of conditions and the following disclaimer in the
     44  *    documentation and/or other materials provided with the distribution.
     45  * 3. All advertising materials mentioning features or use of this software
     46  *    must display the following acknowledgement:
     47  *	This product includes software developed by Mark Brinicombe
     48  *	for the NetBSD Project.
     49  * 4. The name of the company nor the name of the author may be used to
     50  *    endorse or promote products derived from this software without specific
     51  *    prior written permission.
     52  *
     53  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
     54  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     55  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     56  * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
     57  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     58  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     59  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     60  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     61  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     62  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     63  * SUCH DAMAGE.
     64  *
     65  * Machine dependent functions for kernel setup for integrator board
     66  *
     67  * Created      : 24/11/97
     68  */
     69 
     70 #include <sys/cdefs.h>
     71 __KERNEL_RCSID(0, "$NetBSD: integrator_machdep.c,v 1.77 2019/07/16 14:41:46 skrll Exp $");
     72 
     73 #include "opt_arm_debug.h"
     74 #include "opt_console.h"
     75 #include "opt_ddb.h"
     76 #include "opt_pmap_debug.h"
     77 
     78 #include <sys/param.h>
     79 #include <sys/device.h>
     80 #include <sys/systm.h>
     81 #include <sys/kernel.h>
     82 #include <sys/exec.h>
     83 #include <sys/proc.h>
     84 #include <sys/msgbuf.h>
     85 #include <sys/reboot.h>
     86 #include <sys/termios.h>
     87 #include <sys/ksyms.h>
     88 #include <sys/bus.h>
     89 #include <sys/cpu.h>
     90 #include <sys/intr.h>
     91 
     92 #include <uvm/uvm_extern.h>
     93 
     94 #include <dev/cons.h>
     95 
     96 #include <machine/db_machdep.h>
     97 #include <ddb/db_sym.h>
     98 #include <ddb/db_extern.h>
     99 
    100 #include <machine/bootconfig.h>
    101 #include <arm/locore.h>
    102 #include <arm/undefined.h>
    103 
    104 #include <arm/arm32/machdep.h>
    105 
    106 #include <evbarm/integrator/integrator_boot.h>
    107 
    108 #include "pci.h"
    109 #include "ksyms.h"
    110 
    111 void ifpga_reset(void) __attribute__((noreturn));
    112 
    113 /*
    114  * The range 0xc1000000 - 0xccffffff is available for kernel VM space
    115  * Core-logic registers and I/O mappings occupy 0xfd000000 - 0xffffffff
    116  */
    117 #define KERNEL_VM_BASE		(KERNEL_BASE + 0x01000000)
    118 #define KERNEL_VM_SIZE		0x0C000000
    119 
    120 BootConfig bootconfig;		/* Boot config storage */
    121 char *boot_args = NULL;
    122 char *boot_file = NULL;
    123 
    124 /* Prototypes */
    125 
    126 static void	integrator_sdram_bounds	(paddr_t *, psize_t *);
    127 
    128 void	consinit(void);
    129 
    130 /* A load of console goo. */
    131 #include "vga.h"
    132 #if NVGA > 0
    133 #include <dev/ic/mc6845reg.h>
    134 #include <dev/ic/pcdisplayvar.h>
    135 #include <dev/ic/vgareg.h>
    136 #include <dev/ic/vgavar.h>
    137 #endif
    138 
    139 #include "pckbc.h"
    140 #if NPCKBC > 0
    141 #include <dev/ic/i8042reg.h>
    142 #include <dev/ic/pckbcvar.h>
    143 #endif
    144 
    145 #include "com.h"
    146 #if NCOM > 0
    147 #include <dev/ic/comreg.h>
    148 #include <dev/ic/comvar.h>
    149 #ifndef CONCOMADDR
    150 #define CONCOMADDR 0x3f8
    151 #endif
    152 #endif
    153 
    154 /*
    155  * Define the default console speed for the board.  This is generally
    156  * what the firmware provided with the board defaults to.
    157  */
    158 #ifndef CONSPEED
    159 #define CONSPEED B115200
    160 #endif
    161 #ifndef CONMODE
    162 #define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
    163 #endif
    164 
    165 int comcnspeed = CONSPEED;
    166 int comcnmode = CONMODE;
    167 
    168 #include "plcom.h"
    169 #if (NPLCOM > 0)
    170 #include <evbarm/dev/plcomreg.h>
    171 #include <evbarm/dev/plcomvar.h>
    172 
    173 #include <evbarm/ifpga/ifpgamem.h>
    174 #include <evbarm/ifpga/ifpgareg.h>
    175 #include <evbarm/ifpga/ifpgavar.h>
    176 #endif
    177 
    178 #ifndef CONSDEVNAME
    179 #define CONSDEVNAME "plcom"
    180 #endif
    181 
    182 #ifndef PLCONSPEED
    183 #define PLCONSPEED B38400
    184 #endif
    185 #ifndef PLCONMODE
    186 #define PLCONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
    187 #endif
    188 #ifndef PLCOMCNUNIT
    189 #define PLCOMCNUNIT -1
    190 #endif
    191 
    192 int plcomcnspeed = PLCONSPEED;
    193 int plcomcnmode = PLCONMODE;
    194 
    195 #if 0
    196 extern struct consdev kcomcons;
    197 static void kcomcnputc(dev_t, int);
    198 #endif
    199 
    200 /*
    201  * void cpu_reboot(int howto, char *bootstr)
    202  *
    203  * Reboots the system
    204  *
    205  * Deal with any syncing, unmounting, dumping and shutdown hooks,
    206  * then reset the CPU.
    207  */
    208 void
    209 cpu_reboot(int howto, char *bootstr)
    210 {
    211 
    212 	/*
    213 	 * If we are still cold then hit the air brakes
    214 	 * and crash to earth fast
    215 	 */
    216 	if (cold) {
    217 		doshutdownhooks();
    218 		pmf_system_shutdown(boothowto);
    219 		printf("The operating system has halted.\n");
    220 		printf("Please press any key to reboot.\n\n");
    221 		cngetc();
    222 		printf("rebooting...\n");
    223 		ifpga_reset();
    224 		/*NOTREACHED*/
    225 	}
    226 
    227 	/* Disable console buffering */
    228 
    229 	/*
    230 	 * If RB_NOSYNC was not specified sync the discs.
    231 	 * Note: Unless cold is set to 1 here, syslogd will die during the
    232 	 * unmount.  It looks like syslogd is getting woken up only to find
    233 	 * that it cannot page part of the binary in as the filesystem has
    234 	 * been unmounted.
    235 	 */
    236 	if (!(howto & RB_NOSYNC))
    237 		bootsync();
    238 
    239 	/* Say NO to interrupts */
    240 	splhigh();
    241 
    242 	/* Do a dump if requested. */
    243 	if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP)
    244 		dumpsys();
    245 
    246 	/* Run any shutdown hooks */
    247 	doshutdownhooks();
    248 
    249 	pmf_system_shutdown(boothowto);
    250 
    251 	/* Make sure IRQ's are disabled */
    252 	IRQdisable;
    253 
    254 	if (howto & RB_HALT) {
    255 		printf("The operating system has halted.\n");
    256 		printf("Please press any key to reboot.\n\n");
    257 		cngetc();
    258 	}
    259 
    260 	printf("rebooting...\n");
    261 	ifpga_reset();
    262 	/*NOTREACHED*/
    263 }
    264 
    265 /* Statically mapped devices. */
    266 static const struct pmap_devmap integrator_devmap[] = {
    267 #if NPLCOM > 0 && defined(PLCONSOLE)
    268 	{
    269 		UART0_BOOT_BASE,
    270 		IFPGA_IO_BASE + IFPGA_UART0,
    271 		1024 * 1024,
    272 		VM_PROT_READ|VM_PROT_WRITE,
    273 		PTE_NOCACHE
    274 	},
    275 
    276 	{
    277 		UART1_BOOT_BASE,
    278 		IFPGA_IO_BASE + IFPGA_UART1,
    279 		1024 * 1024,
    280 		VM_PROT_READ|VM_PROT_WRITE,
    281 		PTE_NOCACHE
    282 	},
    283 #endif
    284 #if NPCI > 0
    285 	{
    286 		IFPGA_PCI_IO_VBASE,
    287 		IFPGA_PCI_IO_BASE,
    288 		IFPGA_PCI_IO_VSIZE,
    289 		VM_PROT_READ|VM_PROT_WRITE,
    290 		PTE_NOCACHE
    291 	},
    292 
    293 	{
    294 		IFPGA_PCI_CONF_VBASE,
    295 		IFPGA_PCI_CONF_BASE,
    296 		IFPGA_PCI_CONF_VSIZE,
    297 		VM_PROT_READ|VM_PROT_WRITE,
    298 		PTE_NOCACHE
    299 	},
    300 #endif
    301 
    302 	{
    303 		0,
    304 		0,
    305 		0,
    306 		0,
    307 		0
    308 	}
    309 };
    310 
    311 /*
    312  * vaddr_t initarm(...)
    313  *
    314  * Initial entry point on startup. This gets called before main() is
    315  * entered.
    316  * It should be responsible for setting up everything that must be
    317  * in place when main is called.
    318  * This includes
    319  *   Taking a copy of the boot configuration structure.
    320  *   Initialising the physical console so characters can be printed.
    321  *   Setting up page tables for the kernel
    322  *   Relocating the kernel to the bottom of physical memory
    323  */
    324 
    325 vaddr_t
    326 initarm(void *arg)
    327 {
    328 	extern int KERNEL_BASE_phys[];
    329 	paddr_t memstart;
    330 	psize_t memsize;
    331 
    332 	/*
    333 	 * Heads up ... Setup the CPU / MMU / TLB functions
    334 	 */
    335 	if (set_cpufuncs())
    336 		panic("cpu not recognized!");
    337 
    338 	/* map some peripheral registers */
    339 
    340 	pmap_devmap_bootstrap((vaddr_t)armreg_ttbr_read() & -L1_TABLE_SIZE,
    341 		integrator_devmap);
    342 
    343 	cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT);
    344 
    345 	consinit();
    346 
    347 	/* Talk to the user */
    348 #define BDSTR(s)        _BDSTR(s)
    349 #define _BDSTR(s)       #s
    350 	printf("\nNetBSD/evbarm (" BDSTR(EVBARM_BOARDTYPE) ") booting ...\n");
    351 
    352 	/*
    353 	 * Fetch the SDRAM start/size from the CM configuration registers.
    354 	 */
    355 	integrator_sdram_bounds(&memstart, &memsize);
    356 
    357 #if defined(INTEGRATOR_CP)
    358 	/*
    359 	 * XXX QEMU reports SDRAM starting at 0x100000, but presents a flat
    360 	 * physical memory model. Set memstart to 0x0, so arm32_bootmem_init
    361 	 * doesn't get fooled later.
    362 	 */
    363 	memstart = 0;
    364 #endif
    365 
    366 #ifdef VERBOSE_INIT_ARM
    367 	printf("initarm: Configuring system ...\n");
    368 #endif
    369 
    370 	/* Fake bootconfig structure for the benefit of pmap.c */
    371 	/* XXX must make the memory description h/w independent */
    372 	bootconfig.dramblocks = 1;
    373 	bootconfig.dram[0].address = memstart;
    374 	bootconfig.dram[0].pages = memsize / PAGE_SIZE;
    375 	bootconfig.dram[0].flags = BOOT_DRAM_CAN_DMA | BOOT_DRAM_PREFER;
    376 
    377 	arm32_bootmem_init(bootconfig.dram[0].address,
    378 		bootconfig.dram[0].pages * PAGE_SIZE, (unsigned int) KERNEL_BASE_phys);
    379 
    380 	arm32_kernel_vm_init(KERNEL_VM_BASE, ARM_VECTORS_LOW, 0, integrator_devmap,
    381 		false);
    382 
    383 #ifdef VERBOSE_INIT_ARM
    384 	printf("done.\n");
    385 #endif
    386 
    387 	return initarm_common(KERNEL_VM_BASE, KERNEL_VM_SIZE, NULL, 0);
    388 }
    389 
    390 void
    391 consinit(void)
    392 {
    393 	static int consinit_called = 0;
    394 #if 0
    395 	char *console = CONSDEVNAME;
    396 #endif
    397 
    398 	if (consinit_called != 0)
    399 		return;
    400 
    401 	consinit_called = 1;
    402 
    403 #if NPLCOM > 0 && defined(PLCONSOLE)
    404 	if (PLCOMCNUNIT == 0) {
    405 		extern struct bus_space ifpga_common_bs_tag;
    406 		static struct plcom_instance ifpga_pi1 = {
    407 #if defined(INTEGRATOR_CP)
    408 			.pi_type = PLCOM_TYPE_PL011,
    409 #else
    410 			.pi_type = PLCOM_TYPE_PL010,
    411 #endif
    412 			.pi_iot = &ifpga_common_bs_tag,
    413 			.pi_size = IFPGA_UART_SIZE,
    414 			.pi_iobase = IFPGA_UART0
    415 		};
    416 
    417 		if (plcomcnattach(&ifpga_pi1, plcomcnspeed, IFPGA_UART_CLK,
    418 		      plcomcnmode, PLCOMCNUNIT))
    419 			panic("can't init serial console");
    420 		return;
    421 	} else if (PLCOMCNUNIT == 1) {
    422 		extern struct bus_space ifpga_common_bs_tag;
    423 		static struct plcom_instance ifpga_pi1 = {
    424 #if defined(INTEGRATOR_CP)
    425 			.pi_type = PLCOM_TYPE_PL011,
    426 #else
    427 			.pi_type = PLCOM_TYPE_PL010,
    428 #endif
    429 			.pi_iot = &ifpga_common_bs_tag,
    430 			.pi_size = IFPGA_UART_SIZE,
    431 			.pi_iobase = IFPGA_UART1
    432 		};
    433 
    434 		if (plcomcnattach(&ifpga_pi1, plcomcnspeed, IFPGA_UART_CLK,
    435 		      plcomcnmode, PLCOMCNUNIT))
    436 			panic("can't init serial console");
    437 		return;
    438 	}
    439 #endif
    440 #if (NCOM > 0)
    441 	if (comcnattach(&isa_io_bs_tag, CONCOMADDR, comcnspeed,
    442 	    COM_FREQ, COM_TYPE_NORMAL, comcnmode))
    443 		panic("can't init serial console @%x", CONCOMADDR);
    444 	return;
    445 #endif
    446 	panic("No serial console configured");
    447 }
    448 
    449 static void
    450 integrator_sdram_bounds(paddr_t *memstart, psize_t *memsize)
    451 {
    452 	volatile unsigned long *cm_sdram
    453 	    = (volatile unsigned long *)0x10000020;
    454 	volatile unsigned long *cm_stat
    455 	    = (volatile unsigned long *)0x10000010;
    456 
    457 	*memstart = *cm_stat & 0x00ff0000;
    458 
    459 	/*
    460 	 * Although the SSRAM overlaps the SDRAM, we can use the wrap-around
    461 	 * to access the entire bank.
    462 	 */
    463 	switch ((*cm_sdram >> 2) & 0x7)
    464 	{
    465 	case 0:
    466 		*memsize = 16 * 1024 * 1024;
    467 		break;
    468 	case 1:
    469 		*memsize = 32 * 1024 * 1024;
    470 		break;
    471 	case 2:
    472 		*memsize = 64 * 1024 * 1024;
    473 		break;
    474 	case 3:
    475 		*memsize = 128 * 1024 * 1024;
    476 		break;
    477 	case 4:
    478 		/* With 256M of memory there is no wrap-around.  */
    479 		*memsize = 256 * 1024 * 1024 - *memstart;
    480 		break;
    481 	default:
    482 		printf("CM_SDRAM retuns unknown value, using 16M\n");
    483 		*memsize = 16 * 1024 * 1024;
    484 		break;
    485 	}
    486 }
    487