2008-03-03 17:17:00 +00:00
|
|
|
/*-
|
2012-05-30 17:34:40 +00:00
|
|
|
* Copyright (C) 2006-2012 Semihalf
|
2008-03-03 17:17:00 +00:00
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
|
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
|
|
|
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
|
|
|
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
|
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
|
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
|
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
/*-
|
|
|
|
* Copyright (C) 2001 Benno Rice
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR
|
|
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
|
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
|
|
* IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
|
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|
|
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
|
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
|
|
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
|
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
* $NetBSD: machdep.c,v 1.74.2.1 2000/11/01 16:13:48 tv Exp $
|
|
|
|
*/
|
|
|
|
/*-
|
|
|
|
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
|
|
|
|
* Copyright (C) 1995, 1996 TooLs GmbH.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
* 3. All advertising materials mentioning features or use of this software
|
|
|
|
* must display the following acknowledgement:
|
|
|
|
* This product includes software developed by TooLs GmbH.
|
|
|
|
* 4. The name of TooLs GmbH may not be used to endorse or promote products
|
|
|
|
* derived from this software without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
|
|
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
|
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
|
|
* IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
|
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|
|
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
|
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
|
|
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
|
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <sys/cdefs.h>
|
|
|
|
__FBSDID("$FreeBSD$");
|
|
|
|
|
|
|
|
#include "opt_compat.h"
|
2009-04-21 17:04:01 +00:00
|
|
|
#include "opt_ddb.h"
|
2008-03-03 17:17:00 +00:00
|
|
|
#include "opt_kstack_pages.h"
|
2011-01-17 23:54:50 +00:00
|
|
|
#include "opt_platform.h"
|
2008-03-03 17:17:00 +00:00
|
|
|
|
|
|
|
#include <sys/cdefs.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/param.h>
|
|
|
|
#include <sys/proc.h>
|
|
|
|
#include <sys/systm.h>
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <sys/bio.h>
|
|
|
|
#include <sys/buf.h>
|
|
|
|
#include <sys/bus.h>
|
|
|
|
#include <sys/cons.h>
|
|
|
|
#include <sys/cpu.h>
|
|
|
|
#include <sys/kdb.h>
|
|
|
|
#include <sys/kernel.h>
|
|
|
|
#include <sys/lock.h>
|
|
|
|
#include <sys/mutex.h>
|
2013-03-09 02:32:23 +00:00
|
|
|
#include <sys/rwlock.h>
|
2008-03-03 17:17:00 +00:00
|
|
|
#include <sys/sysctl.h>
|
|
|
|
#include <sys/exec.h>
|
|
|
|
#include <sys/ktr.h>
|
2010-06-30 18:03:42 +00:00
|
|
|
#include <sys/syscallsubr.h>
|
2008-03-03 17:17:00 +00:00
|
|
|
#include <sys/sysproto.h>
|
|
|
|
#include <sys/signalvar.h>
|
|
|
|
#include <sys/sysent.h>
|
|
|
|
#include <sys/imgact.h>
|
|
|
|
#include <sys/msgbuf.h>
|
|
|
|
#include <sys/ptrace.h>
|
|
|
|
|
|
|
|
#include <vm/vm.h>
|
|
|
|
#include <vm/pmap.h>
|
|
|
|
#include <vm/vm_page.h>
|
|
|
|
#include <vm/vm_object.h>
|
|
|
|
#include <vm/vm_pager.h>
|
|
|
|
|
|
|
|
#include <machine/cpu.h>
|
|
|
|
#include <machine/kdb.h>
|
|
|
|
#include <machine/reg.h>
|
|
|
|
#include <machine/vmparam.h>
|
|
|
|
#include <machine/spr.h>
|
|
|
|
#include <machine/hid.h>
|
|
|
|
#include <machine/psl.h>
|
|
|
|
#include <machine/trap.h>
|
|
|
|
#include <machine/md_var.h>
|
|
|
|
#include <machine/mmuvar.h>
|
|
|
|
#include <machine/sigframe.h>
|
2012-05-30 17:34:40 +00:00
|
|
|
#include <machine/machdep.h>
|
2008-03-03 17:17:00 +00:00
|
|
|
#include <machine/metadata.h>
|
2009-05-14 00:34:26 +00:00
|
|
|
#include <machine/platform.h>
|
2008-03-03 17:17:00 +00:00
|
|
|
|
|
|
|
#include <sys/linker.h>
|
|
|
|
#include <sys/reboot.h>
|
|
|
|
|
2013-10-26 19:50:40 +00:00
|
|
|
#include <contrib/libfdt/libfdt.h>
|
Convert Freescale PowerPC platforms to FDT convention.
The following systems are affected:
- MPC8555CDS
- MPC8572DS
This overhaul covers the following major changes:
- All integrated peripherals drivers for Freescale MPC85XX SoC, which are
currently in the FreeBSD source tree are reworked and adjusted so they
derive config data out of the device tree blob (instead of hard coded /
tabelarized values).
- This includes: LBC, PCI / PCI-Express, I2C, DS1553, OpenPIC, TSEC, SEC,
QUICC, UART, CFI.
- Thanks to the common FDT infrastrucutre (fdtbus, simplebus) we retire
ocpbus(4) driver, which was based on hard-coded config data.
Note that world for these platforms has to be built WITH_FDT.
Reviewed by: imp
Sponsored by: The FreeBSD Foundation
2010-07-11 21:08:29 +00:00
|
|
|
#include <dev/fdt/fdt_common.h>
|
|
|
|
#include <dev/ofw/openfirm.h>
|
|
|
|
|
2009-04-21 17:04:01 +00:00
|
|
|
#ifdef DDB
|
|
|
|
extern vm_offset_t ksym_start, ksym_end;
|
|
|
|
#endif
|
|
|
|
|
2008-03-03 17:17:00 +00:00
|
|
|
#ifdef DEBUG
|
|
|
|
#define debugf(fmt, args...) printf(fmt, ##args)
|
|
|
|
#else
|
|
|
|
#define debugf(fmt, args...)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
extern unsigned char kernel_text[];
|
|
|
|
extern unsigned char _etext[];
|
|
|
|
extern unsigned char _edata[];
|
|
|
|
extern unsigned char __bss_start[];
|
|
|
|
extern unsigned char __sbss_start[];
|
|
|
|
extern unsigned char __sbss_end[];
|
|
|
|
extern unsigned char _end[];
|
|
|
|
|
2011-01-17 23:54:50 +00:00
|
|
|
/*
|
|
|
|
* Bootinfo is passed to us by legacy loaders. Save the address of the
|
|
|
|
* structure to handle backward compatibility.
|
|
|
|
*/
|
|
|
|
uint32_t *bootinfo;
|
|
|
|
|
2008-03-03 17:17:00 +00:00
|
|
|
struct kva_md_info kmi;
|
|
|
|
struct pcpu __pcpu[MAXCPU];
|
|
|
|
struct trapframe frame0;
|
|
|
|
int cold = 1;
|
|
|
|
long realmem = 0;
|
|
|
|
long Maxmem = 0;
|
|
|
|
char machine[] = "powerpc";
|
|
|
|
SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, "");
|
|
|
|
|
2008-09-24 00:28:46 +00:00
|
|
|
int cacheline_size = 32;
|
|
|
|
|
2008-03-03 17:17:00 +00:00
|
|
|
SYSCTL_INT(_machdep, CPU_CACHELINE, cacheline_size,
|
2008-09-24 00:28:46 +00:00
|
|
|
CTLFLAG_RD, &cacheline_size, 0, "");
|
2008-03-03 17:17:00 +00:00
|
|
|
|
2009-04-04 00:22:44 +00:00
|
|
|
int hw_direct_map = 0;
|
|
|
|
|
2012-05-26 13:36:18 +00:00
|
|
|
static void cpu_booke_startup(void *);
|
|
|
|
SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_booke_startup, NULL);
|
2008-03-03 17:17:00 +00:00
|
|
|
|
|
|
|
void print_kernel_section_addr(void);
|
2008-12-17 15:31:15 +00:00
|
|
|
void print_kenv(void);
|
2011-05-28 04:10:44 +00:00
|
|
|
u_int booke_init(uint32_t, uint32_t);
|
2008-03-03 17:17:00 +00:00
|
|
|
|
2012-01-30 07:56:00 +00:00
|
|
|
extern int elf32_nxstack;
|
|
|
|
|
2008-03-03 17:17:00 +00:00
|
|
|
static void
|
2012-05-26 13:36:18 +00:00
|
|
|
cpu_booke_startup(void *dummy)
|
2008-03-03 17:17:00 +00:00
|
|
|
{
|
2013-10-20 23:02:16 +00:00
|
|
|
int indx;
|
|
|
|
unsigned long size;
|
2008-03-03 17:17:00 +00:00
|
|
|
|
|
|
|
/* Initialise the decrementer-based clock. */
|
|
|
|
decr_init();
|
|
|
|
|
|
|
|
/* Good {morning,afternoon,evening,night}. */
|
|
|
|
cpu_setup(PCPU_GET(cpuid));
|
|
|
|
|
2013-10-20 23:02:16 +00:00
|
|
|
printf("real memory = %lu (%ld MB)\n", ptoa(physmem),
|
2008-08-26 17:07:37 +00:00
|
|
|
ptoa(physmem) / 1048576);
|
2008-03-03 17:17:00 +00:00
|
|
|
realmem = physmem;
|
|
|
|
|
|
|
|
/* Display any holes after the first chunk of extended memory. */
|
|
|
|
if (bootverbose) {
|
|
|
|
printf("Physical memory chunk(s):\n");
|
|
|
|
for (indx = 0; phys_avail[indx + 1] != 0; indx += 2) {
|
2008-08-26 17:07:37 +00:00
|
|
|
size = phys_avail[indx + 1] - phys_avail[indx];
|
2008-12-17 15:31:15 +00:00
|
|
|
|
2013-10-20 23:02:16 +00:00
|
|
|
printf("0x%08x - 0x%08x, %lu bytes (%lu pages)\n",
|
2008-12-17 15:31:15 +00:00
|
|
|
phys_avail[indx], phys_avail[indx + 1] - 1,
|
|
|
|
size, size / PAGE_SIZE);
|
2008-03-03 17:17:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
vm_ksubmap_init(&kmi);
|
|
|
|
|
2014-03-22 10:26:09 +00:00
|
|
|
printf("avail memory = %lu (%ld MB)\n", ptoa(vm_cnt.v_free_count),
|
|
|
|
ptoa(vm_cnt.v_free_count) / 1048576);
|
2008-03-03 17:17:00 +00:00
|
|
|
|
|
|
|
/* Set up buffers, so they can be used to read disk labels. */
|
|
|
|
bufinit();
|
|
|
|
vm_pager_bufferinit();
|
2012-01-30 07:56:00 +00:00
|
|
|
|
|
|
|
/* Cpu supports execution permissions on the pages. */
|
|
|
|
elf32_nxstack = 1;
|
2008-03-03 17:17:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static char *
|
|
|
|
kenv_next(char *cp)
|
|
|
|
{
|
|
|
|
|
|
|
|
if (cp != NULL) {
|
|
|
|
while (*cp != 0)
|
|
|
|
cp++;
|
|
|
|
cp++;
|
|
|
|
if (*cp == 0)
|
|
|
|
cp = NULL;
|
|
|
|
}
|
|
|
|
return (cp);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2008-12-17 15:31:15 +00:00
|
|
|
print_kenv(void)
|
2008-03-03 17:17:00 +00:00
|
|
|
{
|
|
|
|
int len;
|
|
|
|
char *cp;
|
|
|
|
|
|
|
|
debugf("loader passed (static) kenv:\n");
|
|
|
|
if (kern_envp == NULL) {
|
|
|
|
debugf(" no env, null ptr\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
debugf(" kern_envp = 0x%08x\n", (u_int32_t)kern_envp);
|
|
|
|
|
|
|
|
len = 0;
|
|
|
|
for (cp = kern_envp; cp != NULL; cp = kenv_next(cp))
|
|
|
|
debugf(" %x %s\n", (u_int32_t)cp, cp);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
print_kernel_section_addr(void)
|
|
|
|
{
|
|
|
|
|
|
|
|
debugf("kernel image addresses:\n");
|
2008-12-17 15:31:15 +00:00
|
|
|
debugf(" kernel_text = 0x%08x\n", (uint32_t)kernel_text);
|
|
|
|
debugf(" _etext (sdata) = 0x%08x\n", (uint32_t)_etext);
|
|
|
|
debugf(" _edata = 0x%08x\n", (uint32_t)_edata);
|
|
|
|
debugf(" __sbss_start = 0x%08x\n", (uint32_t)__sbss_start);
|
|
|
|
debugf(" __sbss_end = 0x%08x\n", (uint32_t)__sbss_end);
|
|
|
|
debugf(" __sbss_start = 0x%08x\n", (uint32_t)__bss_start);
|
|
|
|
debugf(" _end = 0x%08x\n", (uint32_t)_end);
|
2008-03-03 17:17:00 +00:00
|
|
|
}
|
|
|
|
|
2013-10-26 19:50:40 +00:00
|
|
|
static int
|
|
|
|
booke_check_for_fdt(uint32_t arg1, vm_offset_t *dtbp)
|
|
|
|
{
|
|
|
|
void *ptr;
|
|
|
|
|
|
|
|
if (arg1 % 8 != 0)
|
|
|
|
return (-1);
|
|
|
|
|
|
|
|
ptr = (void *)pmap_early_io_map(arg1, PAGE_SIZE);
|
|
|
|
if (fdt_check_header(ptr) != 0)
|
|
|
|
return (-1);
|
|
|
|
|
|
|
|
*dtbp = (vm_offset_t)ptr;
|
|
|
|
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
2008-08-26 17:07:37 +00:00
|
|
|
u_int
|
2011-05-28 04:10:44 +00:00
|
|
|
booke_init(uint32_t arg1, uint32_t arg2)
|
2008-03-03 17:17:00 +00:00
|
|
|
{
|
|
|
|
struct pcpu *pc;
|
2011-05-28 04:10:44 +00:00
|
|
|
void *kmdp, *mdp;
|
Convert Freescale PowerPC platforms to FDT convention.
The following systems are affected:
- MPC8555CDS
- MPC8572DS
This overhaul covers the following major changes:
- All integrated peripherals drivers for Freescale MPC85XX SoC, which are
currently in the FreeBSD source tree are reworked and adjusted so they
derive config data out of the device tree blob (instead of hard coded /
tabelarized values).
- This includes: LBC, PCI / PCI-Express, I2C, DS1553, OpenPIC, TSEC, SEC,
QUICC, UART, CFI.
- Thanks to the common FDT infrastrucutre (fdtbus, simplebus) we retire
ocpbus(4) driver, which was based on hard-coded config data.
Note that world for these platforms has to be built WITH_FDT.
Reviewed by: imp
Sponsored by: The FreeBSD Foundation
2010-07-11 21:08:29 +00:00
|
|
|
vm_offset_t dtbp, end;
|
2008-03-03 17:17:00 +00:00
|
|
|
|
|
|
|
kmdp = NULL;
|
|
|
|
|
2011-05-28 04:10:44 +00:00
|
|
|
end = (uintptr_t)_end;
|
Convert Freescale PowerPC platforms to FDT convention.
The following systems are affected:
- MPC8555CDS
- MPC8572DS
This overhaul covers the following major changes:
- All integrated peripherals drivers for Freescale MPC85XX SoC, which are
currently in the FreeBSD source tree are reworked and adjusted so they
derive config data out of the device tree blob (instead of hard coded /
tabelarized values).
- This includes: LBC, PCI / PCI-Express, I2C, DS1553, OpenPIC, TSEC, SEC,
QUICC, UART, CFI.
- Thanks to the common FDT infrastrucutre (fdtbus, simplebus) we retire
ocpbus(4) driver, which was based on hard-coded config data.
Note that world for these platforms has to be built WITH_FDT.
Reviewed by: imp
Sponsored by: The FreeBSD Foundation
2010-07-11 21:08:29 +00:00
|
|
|
dtbp = (vm_offset_t)NULL;
|
2008-03-03 17:17:00 +00:00
|
|
|
|
2013-10-26 19:50:40 +00:00
|
|
|
/* Set up TLB initially */
|
|
|
|
bootinfo = NULL;
|
|
|
|
tlb1_init();
|
|
|
|
|
2011-05-28 04:10:44 +00:00
|
|
|
/*
|
|
|
|
* Handle the various ways we can get loaded and started:
|
|
|
|
* - FreeBSD's loader passes the pointer to the metadata
|
|
|
|
* in arg1, with arg2 undefined. arg1 has a value that's
|
|
|
|
* relative to the kernel's link address (i.e. larger
|
|
|
|
* than 0xc0000000).
|
|
|
|
* - Juniper's loader passes the metadata pointer in arg2
|
|
|
|
* and sets arg1 to zero. This is to signal that the
|
|
|
|
* loader maps the kernel and starts it at its link
|
|
|
|
* address (unlike the FreeBSD loader).
|
|
|
|
* - U-Boot passes the standard argc and argv parameters
|
|
|
|
* in arg1 and arg2 (resp). arg1 is between 1 and some
|
|
|
|
* relatively small number, such as 64K. arg2 is the
|
|
|
|
* physical address of the argv vector.
|
2013-10-26 19:50:40 +00:00
|
|
|
* - ePAPR loaders pass an FDT blob in r3 (arg1) and the magic hex
|
|
|
|
* string 0x45504150 ('ePAP') in r6 (which has been lost by now).
|
|
|
|
* r4 (arg2) is supposed to be set to zero, but is not always.
|
2011-05-28 04:10:44 +00:00
|
|
|
*/
|
2013-10-26 19:50:40 +00:00
|
|
|
|
|
|
|
if (arg1 == 0) /* Juniper loader */
|
2011-05-28 04:10:44 +00:00
|
|
|
mdp = (void *)arg2;
|
2013-10-26 19:50:40 +00:00
|
|
|
else if (booke_check_for_fdt(arg1, &dtbp) == 0) { /* ePAPR */
|
|
|
|
end = roundup(end, 8);
|
|
|
|
memmove((void *)end, (void *)dtbp, fdt_totalsize((void *)dtbp));
|
|
|
|
dtbp = end;
|
|
|
|
end += fdt_totalsize((void *)dtbp);
|
|
|
|
mdp = NULL;
|
|
|
|
} else if (arg1 > (uintptr_t)kernel_text) /* FreeBSD loader */
|
|
|
|
mdp = (void *)arg1;
|
2011-05-28 04:10:44 +00:00
|
|
|
else /* U-Boot */
|
|
|
|
mdp = NULL;
|
|
|
|
|
2008-03-03 17:17:00 +00:00
|
|
|
/*
|
Convert Freescale PowerPC platforms to FDT convention.
The following systems are affected:
- MPC8555CDS
- MPC8572DS
This overhaul covers the following major changes:
- All integrated peripherals drivers for Freescale MPC85XX SoC, which are
currently in the FreeBSD source tree are reworked and adjusted so they
derive config data out of the device tree blob (instead of hard coded /
tabelarized values).
- This includes: LBC, PCI / PCI-Express, I2C, DS1553, OpenPIC, TSEC, SEC,
QUICC, UART, CFI.
- Thanks to the common FDT infrastrucutre (fdtbus, simplebus) we retire
ocpbus(4) driver, which was based on hard-coded config data.
Note that world for these platforms has to be built WITH_FDT.
Reviewed by: imp
Sponsored by: The FreeBSD Foundation
2010-07-11 21:08:29 +00:00
|
|
|
* Parse metadata and fetch parameters.
|
2008-03-03 17:17:00 +00:00
|
|
|
*/
|
|
|
|
if (mdp != NULL) {
|
|
|
|
preload_metadata = mdp;
|
|
|
|
kmdp = preload_search_by_type("elf kernel");
|
|
|
|
if (kmdp != NULL) {
|
|
|
|
boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int);
|
|
|
|
kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *);
|
Convert Freescale PowerPC platforms to FDT convention.
The following systems are affected:
- MPC8555CDS
- MPC8572DS
This overhaul covers the following major changes:
- All integrated peripherals drivers for Freescale MPC85XX SoC, which are
currently in the FreeBSD source tree are reworked and adjusted so they
derive config data out of the device tree blob (instead of hard coded /
tabelarized values).
- This includes: LBC, PCI / PCI-Express, I2C, DS1553, OpenPIC, TSEC, SEC,
QUICC, UART, CFI.
- Thanks to the common FDT infrastrucutre (fdtbus, simplebus) we retire
ocpbus(4) driver, which was based on hard-coded config data.
Note that world for these platforms has to be built WITH_FDT.
Reviewed by: imp
Sponsored by: The FreeBSD Foundation
2010-07-11 21:08:29 +00:00
|
|
|
dtbp = MD_FETCH(kmdp, MODINFOMD_DTBP, vm_offset_t);
|
2008-03-03 17:17:00 +00:00
|
|
|
end = MD_FETCH(kmdp, MODINFOMD_KERNEND, vm_offset_t);
|
2011-01-17 23:54:50 +00:00
|
|
|
|
|
|
|
bootinfo = (uint32_t *)preload_search_info(kmdp,
|
|
|
|
MODINFO_METADATA | MODINFOMD_BOOTINFO);
|
|
|
|
|
2009-04-21 17:04:01 +00:00
|
|
|
#ifdef DDB
|
|
|
|
ksym_start = MD_FETCH(kmdp, MODINFOMD_SSYM, uintptr_t);
|
|
|
|
ksym_end = MD_FETCH(kmdp, MODINFOMD_ESYM, uintptr_t);
|
|
|
|
#endif
|
2008-03-03 17:17:00 +00:00
|
|
|
}
|
|
|
|
} else {
|
2011-05-28 04:10:44 +00:00
|
|
|
bzero(__sbss_start, __sbss_end - __sbss_start);
|
|
|
|
bzero(__bss_start, _end - __bss_start);
|
2008-03-03 17:17:00 +00:00
|
|
|
}
|
|
|
|
|
2011-01-17 23:54:50 +00:00
|
|
|
#if defined(FDT_DTB_STATIC)
|
|
|
|
/*
|
|
|
|
* In case the device tree blob was not retrieved (from metadata) try
|
|
|
|
* to use the statically embedded one.
|
|
|
|
*/
|
|
|
|
if (dtbp == (vm_offset_t)NULL)
|
|
|
|
dtbp = (vm_offset_t)&fdt_static_dtb;
|
|
|
|
#endif
|
|
|
|
|
Convert Freescale PowerPC platforms to FDT convention.
The following systems are affected:
- MPC8555CDS
- MPC8572DS
This overhaul covers the following major changes:
- All integrated peripherals drivers for Freescale MPC85XX SoC, which are
currently in the FreeBSD source tree are reworked and adjusted so they
derive config data out of the device tree blob (instead of hard coded /
tabelarized values).
- This includes: LBC, PCI / PCI-Express, I2C, DS1553, OpenPIC, TSEC, SEC,
QUICC, UART, CFI.
- Thanks to the common FDT infrastrucutre (fdtbus, simplebus) we retire
ocpbus(4) driver, which was based on hard-coded config data.
Note that world for these platforms has to be built WITH_FDT.
Reviewed by: imp
Sponsored by: The FreeBSD Foundation
2010-07-11 21:08:29 +00:00
|
|
|
if (OF_install(OFW_FDT, 0) == FALSE)
|
|
|
|
while (1);
|
|
|
|
|
|
|
|
if (OF_init((void *)dtbp) != 0)
|
|
|
|
while (1);
|
|
|
|
|
|
|
|
OF_interpret("perform-fixup", 0);
|
2012-05-30 17:34:40 +00:00
|
|
|
|
2013-10-26 19:50:40 +00:00
|
|
|
/* Reset TLB1 to get rid of temporary mappings */
|
2013-10-26 18:18:14 +00:00
|
|
|
tlb1_init();
|
|
|
|
|
2009-05-21 11:43:37 +00:00
|
|
|
/* Reset Time Base */
|
|
|
|
mttb(0);
|
|
|
|
|
2008-03-03 17:17:00 +00:00
|
|
|
/* Init params/tunables that can be overridden by the loader. */
|
|
|
|
init_param1();
|
|
|
|
|
|
|
|
/* Start initializing proc0 and thread0. */
|
2010-02-15 14:38:30 +00:00
|
|
|
proc_linkup0(&proc0, &thread0);
|
2008-03-03 17:17:00 +00:00
|
|
|
thread0.td_frame = &frame0;
|
|
|
|
|
|
|
|
/* Set up per-cpu data and store the pointer in SPR general 0. */
|
|
|
|
pc = &__pcpu[0];
|
|
|
|
pcpu_init(pc, 0, sizeof(struct pcpu));
|
|
|
|
pc->pc_curthread = &thread0;
|
2013-11-11 17:37:50 +00:00
|
|
|
#ifdef __powerpc64__
|
|
|
|
__asm __volatile("mr 13,%0" :: "r"(pc->pc_curthread));
|
|
|
|
#else
|
|
|
|
__asm __volatile("mr 2,%0" :: "r"(pc->pc_curthread));
|
|
|
|
#endif
|
2008-03-03 17:17:00 +00:00
|
|
|
__asm __volatile("mtsprg 0, %0" :: "r"(pc));
|
|
|
|
|
|
|
|
/* Initialize system mutexes. */
|
|
|
|
mutex_init();
|
|
|
|
|
|
|
|
/* Initialize the console before printing anything. */
|
|
|
|
cninit();
|
|
|
|
|
|
|
|
/* Print out some debug info... */
|
2011-05-28 04:10:44 +00:00
|
|
|
debugf("%s: console initialized\n", __func__);
|
2008-12-17 15:31:15 +00:00
|
|
|
debugf(" arg3 mdp = 0x%08x\n", (u_int32_t)mdp);
|
2008-03-03 17:17:00 +00:00
|
|
|
debugf(" end = 0x%08x\n", (u_int32_t)end);
|
|
|
|
debugf(" boothowto = 0x%08x\n", boothowto);
|
|
|
|
debugf(" kernel ccsrbar = 0x%08x\n", CCSRBAR_VA);
|
|
|
|
debugf(" MSR = 0x%08x\n", mfmsr());
|
2012-05-27 10:25:20 +00:00
|
|
|
#if defined(BOOKE_E500)
|
2008-12-17 15:31:15 +00:00
|
|
|
debugf(" HID0 = 0x%08x\n", mfspr(SPR_HID0));
|
|
|
|
debugf(" HID1 = 0x%08x\n", mfspr(SPR_HID1));
|
2009-05-21 11:43:37 +00:00
|
|
|
debugf(" BUCSR = 0x%08x\n", mfspr(SPR_BUCSR));
|
2012-05-27 10:25:20 +00:00
|
|
|
#endif
|
2008-12-17 15:31:15 +00:00
|
|
|
|
Convert Freescale PowerPC platforms to FDT convention.
The following systems are affected:
- MPC8555CDS
- MPC8572DS
This overhaul covers the following major changes:
- All integrated peripherals drivers for Freescale MPC85XX SoC, which are
currently in the FreeBSD source tree are reworked and adjusted so they
derive config data out of the device tree blob (instead of hard coded /
tabelarized values).
- This includes: LBC, PCI / PCI-Express, I2C, DS1553, OpenPIC, TSEC, SEC,
QUICC, UART, CFI.
- Thanks to the common FDT infrastrucutre (fdtbus, simplebus) we retire
ocpbus(4) driver, which was based on hard-coded config data.
Note that world for these platforms has to be built WITH_FDT.
Reviewed by: imp
Sponsored by: The FreeBSD Foundation
2010-07-11 21:08:29 +00:00
|
|
|
debugf(" dtbp = 0x%08x\n", (uint32_t)dtbp);
|
|
|
|
|
2008-03-03 17:17:00 +00:00
|
|
|
print_kernel_section_addr();
|
2008-12-17 15:31:15 +00:00
|
|
|
print_kenv();
|
2012-05-27 10:25:20 +00:00
|
|
|
#if defined(BOOKE_E500)
|
2008-03-03 17:17:00 +00:00
|
|
|
//tlb1_print_entries();
|
|
|
|
//tlb1_print_tlbentries();
|
2012-05-27 10:25:20 +00:00
|
|
|
#endif
|
2008-03-03 17:17:00 +00:00
|
|
|
|
|
|
|
kdb_init();
|
|
|
|
|
|
|
|
#ifdef KDB
|
|
|
|
if (boothowto & RB_KDB)
|
|
|
|
kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger");
|
|
|
|
#endif
|
|
|
|
|
2009-05-14 00:34:26 +00:00
|
|
|
/* Initialise platform module */
|
|
|
|
platform_probe_and_attach();
|
|
|
|
|
2008-03-03 17:17:00 +00:00
|
|
|
/* Initialise virtual memory. */
|
|
|
|
pmap_mmu_install(MMU_TYPE_BOOKE, 0);
|
2011-05-28 04:10:44 +00:00
|
|
|
pmap_bootstrap((uintptr_t)kernel_text, end);
|
2012-11-03 22:02:12 +00:00
|
|
|
pmap_bootstrapped = 1;
|
2008-03-03 17:17:00 +00:00
|
|
|
debugf("MSR = 0x%08x\n", mfmsr());
|
2012-05-27 10:25:20 +00:00
|
|
|
#if defined(BOOKE_E500)
|
2008-03-03 17:17:00 +00:00
|
|
|
//tlb1_print_entries();
|
|
|
|
//tlb1_print_tlbentries();
|
2012-05-27 10:25:20 +00:00
|
|
|
#endif
|
2008-03-03 17:17:00 +00:00
|
|
|
|
|
|
|
/* Initialize params/tunables that are derived from memsize. */
|
|
|
|
init_param2(physmem);
|
|
|
|
|
|
|
|
/* Finish setting up thread0. */
|
|
|
|
thread0.td_pcb = (struct pcb *)
|
2008-08-26 17:07:37 +00:00
|
|
|
((thread0.td_kstack + thread0.td_kstack_pages * PAGE_SIZE -
|
|
|
|
sizeof(struct pcb)) & ~15);
|
2008-03-03 17:17:00 +00:00
|
|
|
bzero((void *)thread0.td_pcb, sizeof(struct pcb));
|
|
|
|
pc->pc_curpcb = thread0.td_pcb;
|
|
|
|
|
|
|
|
/* Initialise the message buffer. */
|
2011-01-21 10:26:26 +00:00
|
|
|
msgbufinit(msgbufp, msgbufsize);
|
2008-03-03 17:17:00 +00:00
|
|
|
|
|
|
|
/* Enable Machine Check interrupt. */
|
|
|
|
mtmsr(mfmsr() | PSL_ME);
|
|
|
|
isync();
|
|
|
|
|
2012-05-30 17:34:40 +00:00
|
|
|
/* Enable L1 caches */
|
|
|
|
booke_enable_l1_cache();
|
2008-03-08 05:36:25 +00:00
|
|
|
|
2011-05-28 04:10:44 +00:00
|
|
|
debugf("%s: SP = 0x%08x\n", __func__,
|
|
|
|
((uintptr_t)thread0.td_pcb - 16) & ~15);
|
2008-08-26 17:07:37 +00:00
|
|
|
|
|
|
|
return (((uintptr_t)thread0.td_pcb - 16) & ~15);
|
2008-03-03 17:17:00 +00:00
|
|
|
}
|
|
|
|
|
2009-05-21 11:43:37 +00:00
|
|
|
#define RES_GRANULE 32
|
|
|
|
extern uint32_t tlb0_miss_locks[];
|
|
|
|
|
2008-03-03 17:17:00 +00:00
|
|
|
/* Initialise a struct pcpu. */
|
|
|
|
void
|
|
|
|
cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t sz)
|
|
|
|
{
|
|
|
|
|
2009-01-13 15:41:58 +00:00
|
|
|
pcpu->pc_tid_next = TID_MIN;
|
2009-05-21 11:43:37 +00:00
|
|
|
|
|
|
|
#ifdef SMP
|
|
|
|
uint32_t *ptr;
|
|
|
|
int words_per_gran = RES_GRANULE / sizeof(uint32_t);
|
|
|
|
|
|
|
|
ptr = &tlb0_miss_locks[cpuid * words_per_gran];
|
|
|
|
pcpu->pc_booke_tlb_lock = ptr;
|
2010-11-11 13:35:23 +00:00
|
|
|
*ptr = TLB_UNLOCKED;
|
2009-05-21 11:43:37 +00:00
|
|
|
*(ptr + 1) = 0; /* recurse counter */
|
|
|
|
#endif
|
2008-03-03 17:17:00 +00:00
|
|
|
}
|
|
|
|
|
2009-05-18 18:37:18 +00:00
|
|
|
/*
|
|
|
|
* Flush the D-cache for non-DMA I/O so that the I-cache can
|
|
|
|
* be made coherent later.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
cpu_flush_dcache(void *ptr, size_t len)
|
|
|
|
{
|
2012-07-02 21:11:01 +00:00
|
|
|
register_t addr, off;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Align the address to a cacheline and adjust the length
|
|
|
|
* accordingly. Then round the length to a multiple of the
|
|
|
|
* cacheline for easy looping.
|
|
|
|
*/
|
|
|
|
addr = (uintptr_t)ptr;
|
|
|
|
off = addr & (cacheline_size - 1);
|
|
|
|
addr -= off;
|
|
|
|
len = (len + off + cacheline_size - 1) & ~(cacheline_size - 1);
|
|
|
|
|
|
|
|
while (len > 0) {
|
|
|
|
__asm __volatile ("dcbf 0,%0" :: "r"(addr));
|
|
|
|
__asm __volatile ("sync");
|
|
|
|
addr += cacheline_size;
|
|
|
|
len -= cacheline_size;
|
|
|
|
}
|
2009-05-18 18:37:18 +00:00
|
|
|
}
|
|
|
|
|
2008-03-03 17:17:00 +00:00
|
|
|
void
|
|
|
|
spinlock_enter(void)
|
|
|
|
{
|
|
|
|
struct thread *td;
|
2010-11-05 13:42:58 +00:00
|
|
|
register_t msr;
|
2008-03-03 17:17:00 +00:00
|
|
|
|
|
|
|
td = curthread;
|
2010-11-05 13:42:58 +00:00
|
|
|
if (td->td_md.md_spinlock_count == 0) {
|
|
|
|
msr = intr_disable();
|
|
|
|
td->td_md.md_spinlock_count = 1;
|
|
|
|
td->td_md.md_saved_msr = msr;
|
|
|
|
} else
|
|
|
|
td->td_md.md_spinlock_count++;
|
2008-03-03 17:17:00 +00:00
|
|
|
critical_enter();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
spinlock_exit(void)
|
|
|
|
{
|
|
|
|
struct thread *td;
|
2010-11-05 13:42:58 +00:00
|
|
|
register_t msr;
|
2008-03-03 17:17:00 +00:00
|
|
|
|
|
|
|
td = curthread;
|
|
|
|
critical_exit();
|
2010-11-05 13:42:58 +00:00
|
|
|
msr = td->td_md.md_saved_msr;
|
2008-03-03 17:17:00 +00:00
|
|
|
td->td_md.md_spinlock_count--;
|
|
|
|
if (td->td_md.md_spinlock_count == 0)
|
2010-11-05 13:42:58 +00:00
|
|
|
intr_restore(msr);
|
2008-03-03 17:17:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Shutdown the CPU as much as possible. */
|
|
|
|
void
|
|
|
|
cpu_halt(void)
|
|
|
|
{
|
|
|
|
|
|
|
|
mtmsr(mfmsr() & ~(PSL_CE | PSL_EE | PSL_ME | PSL_DE));
|
2012-05-26 13:36:18 +00:00
|
|
|
while (1)
|
|
|
|
;
|
2008-03-03 17:17:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
ptrace_set_pc(struct thread *td, unsigned long addr)
|
|
|
|
{
|
|
|
|
struct trapframe *tf;
|
|
|
|
|
|
|
|
tf = td->td_frame;
|
|
|
|
tf->srr0 = (register_t)addr;
|
|
|
|
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
ptrace_single_step(struct thread *td)
|
|
|
|
{
|
|
|
|
struct trapframe *tf;
|
|
|
|
|
|
|
|
tf = td->td_frame;
|
|
|
|
tf->srr1 |= PSL_DE;
|
2009-02-27 12:08:24 +00:00
|
|
|
tf->cpu.booke.dbcr0 |= (DBCR0_IDM | DBCR0_IC);
|
2008-03-03 17:17:00 +00:00
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
ptrace_clear_single_step(struct thread *td)
|
|
|
|
{
|
|
|
|
struct trapframe *tf;
|
|
|
|
|
|
|
|
tf = td->td_frame;
|
|
|
|
tf->srr1 &= ~PSL_DE;
|
2009-02-27 12:08:24 +00:00
|
|
|
tf->cpu.booke.dbcr0 &= ~(DBCR0_IDM | DBCR0_IC);
|
2008-03-03 17:17:00 +00:00
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
kdb_cpu_clear_singlestep(void)
|
|
|
|
{
|
|
|
|
register_t r;
|
|
|
|
|
|
|
|
r = mfspr(SPR_DBCR0);
|
|
|
|
mtspr(SPR_DBCR0, r & ~DBCR0_IC);
|
|
|
|
kdb_frame->srr1 &= ~PSL_DE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
kdb_cpu_set_singlestep(void)
|
|
|
|
{
|
|
|
|
register_t r;
|
|
|
|
|
|
|
|
r = mfspr(SPR_DBCR0);
|
|
|
|
mtspr(SPR_DBCR0, r | DBCR0_IC | DBCR0_IDM);
|
|
|
|
kdb_frame->srr1 |= PSL_DE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
bzero(void *buf, size_t len)
|
|
|
|
{
|
|
|
|
caddr_t p;
|
|
|
|
|
|
|
|
p = buf;
|
|
|
|
|
|
|
|
while (((vm_offset_t) p & (sizeof(u_long) - 1)) && len) {
|
|
|
|
*p++ = 0;
|
|
|
|
len--;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (len >= sizeof(u_long) * 8) {
|
|
|
|
*(u_long*) p = 0;
|
|
|
|
*((u_long*) p + 1) = 0;
|
|
|
|
*((u_long*) p + 2) = 0;
|
|
|
|
*((u_long*) p + 3) = 0;
|
|
|
|
len -= sizeof(u_long) * 8;
|
|
|
|
*((u_long*) p + 4) = 0;
|
|
|
|
*((u_long*) p + 5) = 0;
|
|
|
|
*((u_long*) p + 6) = 0;
|
|
|
|
*((u_long*) p + 7) = 0;
|
|
|
|
p += sizeof(u_long) * 8;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (len >= sizeof(u_long)) {
|
|
|
|
*(u_long*) p = 0;
|
|
|
|
len -= sizeof(u_long);
|
|
|
|
p += sizeof(u_long);
|
|
|
|
}
|
|
|
|
|
|
|
|
while (len) {
|
|
|
|
*p++ = 0;
|
|
|
|
len--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|