Пример #1
0
uintptr_t
powerpc_init(vm_offset_t fdt, vm_offset_t toc, vm_offset_t ofentry, void *mdp)
{
	struct		pcpu *pc;
	vm_offset_t	startkernel, endkernel;
	void		*kmdp;
        char		*env;
        bool		ofw_bootargs = false;
#ifdef DDB
	vm_offset_t ksym_start;
	vm_offset_t ksym_end;
#endif

	kmdp = NULL;

	/* First guess at start/end kernel positions */
	startkernel = __startkernel;
	endkernel = __endkernel;

	/* Check for ePAPR loader, which puts a magic value into r6 */
	if (mdp == (void *)0x65504150)
		mdp = NULL;

#ifdef AIM
	/*
	 * If running from an FDT, make sure we are in real mode to avoid
	 * tromping on firmware page tables. Everything in the kernel assumes
	 * 1:1 mappings out of firmware, so this won't break anything not
	 * already broken. This doesn't work if there is live OF, since OF
	 * may internally use non-1:1 mappings.
	 */
	if (ofentry == 0)
		mtmsr(mfmsr() & ~(PSL_IR | PSL_DR));
#endif

	/*
	 * Parse metadata if present and fetch parameters.  Must be done
	 * before console is inited so cninit gets the right value of
	 * boothowto.
	 */
	if (mdp != NULL) {
		preload_metadata = mdp;
		kmdp = preload_search_by_type("elf kernel");
		if (kmdp != NULL) {
			boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int);
			init_static_kenv(MD_FETCH(kmdp, MODINFOMD_ENVP, char *),
			    0);
			endkernel = ulmax(endkernel, MD_FETCH(kmdp,
			    MODINFOMD_KERNEND, vm_offset_t));
#ifdef DDB
			ksym_start = MD_FETCH(kmdp, MODINFOMD_SSYM, uintptr_t);
			ksym_end = MD_FETCH(kmdp, MODINFOMD_ESYM, uintptr_t);
			db_fetch_ksymtab(ksym_start, ksym_end);
#endif
		}
Пример #2
0
uintptr_t
powerpc_init(vm_offset_t fdt, vm_offset_t toc, vm_offset_t ofentry, void *mdp)
{
	struct		pcpu *pc;
	vm_offset_t	startkernel, endkernel;
	void		*kmdp;
        char		*env;
#ifdef DDB
	vm_offset_t ksym_start;
	vm_offset_t ksym_end;
#endif

	kmdp = NULL;

	/* First guess at start/end kernel positions */
	startkernel = __startkernel;
	endkernel = __endkernel;

	/* Check for ePAPR loader, which puts a magic value into r6 */
	if (mdp == (void *)0x65504150)
		mdp = NULL;

	/*
	 * Parse metadata if present and fetch parameters.  Must be done
	 * before console is inited so cninit gets the right value of
	 * boothowto.
	 */
	if (mdp != NULL) {
		preload_metadata = mdp;
		kmdp = preload_search_by_type("elf kernel");
		if (kmdp != NULL) {
			boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int);
			init_static_kenv(MD_FETCH(kmdp, MODINFOMD_ENVP, char *),
			    0);
			endkernel = ulmax(endkernel, MD_FETCH(kmdp,
			    MODINFOMD_KERNEND, vm_offset_t));
#ifdef DDB
			ksym_start = MD_FETCH(kmdp, MODINFOMD_SSYM, uintptr_t);
			ksym_end = MD_FETCH(kmdp, MODINFOMD_ESYM, uintptr_t);
			db_fetch_ksymtab(ksym_start, ksym_end);
#endif
		}
Пример #3
0
static vm_offset_t
freebsd_parse_boot_param(struct arm_boot_params *abp)
{
	vm_offset_t lastaddr = 0;
	void *mdp;
	void *kmdp;
#ifdef DDB
	vm_offset_t ksym_start;
	vm_offset_t ksym_end;
#endif

	/*
	 * Mask metadata pointer: it is supposed to be on page boundary. If
	 * the first argument (mdp) doesn't point to a valid address the
	 * bootloader must have passed us something else than the metadata
	 * ptr, so we give up.  Also give up if we cannot find metadta section
	 * the loader creates that we get all this data out of.
	 */

	if ((mdp = (void *)(abp->abp_r0 & ~PAGE_MASK)) == NULL)
		return 0;
	preload_metadata = mdp;
	kmdp = preload_search_by_type("elf kernel");
	if (kmdp == NULL)
		return 0;

	boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int);
	loader_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *);
	init_static_kenv(loader_envp, 0);
	lastaddr = MD_FETCH(kmdp, MODINFOMD_KERNEND, vm_offset_t);
#ifdef DDB
	ksym_start = MD_FETCH(kmdp, MODINFOMD_SSYM, uintptr_t);
	ksym_end = MD_FETCH(kmdp, MODINFOMD_ESYM, uintptr_t);
	db_fetch_ksymtab(ksym_start, ksym_end);
#endif
	return lastaddr;
}
Пример #4
0
/*
 * Fix kernel_kseg0_end address in case trampoline placed debug sympols 
 * data there
 */
void
mips_postboot_fixup(void)
{
	static char fake_preload[256];
	caddr_t preload_ptr = (caddr_t)&fake_preload[0];
	size_t size = 0;

#define PRELOAD_PUSH_VALUE(type, value) do {		\
	*(type *)(preload_ptr + size) = (value);	\
	size += sizeof(type);				\
} while (0);

	/*
	 * Provide kernel module file information
	 */
	PRELOAD_PUSH_VALUE(uint32_t, MODINFO_NAME);
	PRELOAD_PUSH_VALUE(uint32_t, strlen("kernel") + 1);
	strcpy((char*)(preload_ptr + size), "kernel");
	size += strlen("kernel") + 1;
	size = roundup(size, sizeof(u_long));

	PRELOAD_PUSH_VALUE(uint32_t, MODINFO_TYPE);
	PRELOAD_PUSH_VALUE(uint32_t, strlen("elf kernel") + 1);
	strcpy((char*)(preload_ptr + size), "elf kernel");
	size += strlen("elf kernel") + 1;
	size = roundup(size, sizeof(u_long));

	PRELOAD_PUSH_VALUE(uint32_t, MODINFO_ADDR);
	PRELOAD_PUSH_VALUE(uint32_t, sizeof(vm_offset_t));
	PRELOAD_PUSH_VALUE(vm_offset_t, KERNLOADADDR);
	size = roundup(size, sizeof(u_long));

	PRELOAD_PUSH_VALUE(uint32_t, MODINFO_SIZE);
	PRELOAD_PUSH_VALUE(uint32_t, sizeof(size_t));
	PRELOAD_PUSH_VALUE(size_t, (size_t)&end - KERNLOADADDR);
	size = roundup(size, sizeof(u_long));

	/* End marker */
	PRELOAD_PUSH_VALUE(uint32_t, 0);
	PRELOAD_PUSH_VALUE(uint32_t, 0);

#undef	PRELOAD_PUSH_VALUE

	KASSERT((size < sizeof(fake_preload)),
		("fake preload size is more thenallocated"));

	preload_metadata = (void *)fake_preload;

#ifdef DDB
	Elf_Size *trampoline_data = (Elf_Size*)kernel_kseg0_end;
	Elf_Size symtabsize = 0;
	vm_offset_t ksym_start;
	vm_offset_t ksym_end;

	if (trampoline_data[0] == SYMTAB_MAGIC) {
		symtabsize = trampoline_data[1];
		kernel_kseg0_end += 2 * sizeof(Elf_Size);
		/* start of .symtab */
		ksym_start = kernel_kseg0_end;
		kernel_kseg0_end += symtabsize;
		/* end of .strtab */
		ksym_end = kernel_kseg0_end;
		db_fetch_ksymtab(ksym_start, ksym_end);
	}
#endif
}
Пример #5
0
u_int
booke_init(uint32_t arg1, uint32_t arg2)
{
	struct pcpu *pc;
	void *kmdp, *mdp;
	vm_offset_t dtbp, end;
#ifdef DDB
	vm_offset_t ksym_start;
	vm_offset_t ksym_end;
#endif

	kmdp = NULL;

	end = (uintptr_t)_end;
	dtbp = (vm_offset_t)NULL;

	/* Set up TLB initially */
	bootinfo = NULL;
	tlb1_init();

	/*
	 * 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.
	 *  -   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.
	 */
	
	if (arg1 == 0)				/* Juniper loader */
		mdp = (void *)arg2;
	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;
	else					/* U-Boot */
		mdp = NULL;

	/*
	 * Parse metadata and fetch parameters.
	 */
	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 *);
			dtbp = MD_FETCH(kmdp, MODINFOMD_DTBP, vm_offset_t);
			end = MD_FETCH(kmdp, MODINFOMD_KERNEND, vm_offset_t);

			bootinfo = (uint32_t *)preload_search_info(kmdp,
			    MODINFO_METADATA | MODINFOMD_BOOTINFO);

#ifdef DDB
			ksym_start = MD_FETCH(kmdp, MODINFOMD_SSYM, uintptr_t);
			ksym_end = MD_FETCH(kmdp, MODINFOMD_ESYM, uintptr_t);
			db_fetch_ksymtab(ksym_start, ksym_end);
#endif
		}
Пример #6
0
uintptr_t
powerpc_init(vm_offset_t fdt, vm_offset_t toc, vm_offset_t ofentry, void *mdp,
    uint32_t mdp_cookie)
{
	struct		pcpu *pc;
	struct cpuref	bsp;
	vm_offset_t	startkernel, endkernel;
	char		*env;
        bool		ofw_bootargs = false;
#ifdef DDB
	vm_offset_t ksym_start;
	vm_offset_t ksym_end;
#endif

	/* First guess at start/end kernel positions */
	startkernel = __startkernel;
	endkernel = __endkernel;

	/*
	 * If the metadata pointer cookie is not set to the magic value,
	 * the number in mdp should be treated as nonsense.
	 */
	if (mdp_cookie != 0xfb5d104d)
		mdp = NULL;

#if !defined(BOOKE)
	/*
	 * On BOOKE the BSS is already cleared and some variables
	 * initialized.  Do not wipe them out.
	 */
	bzero(__sbss_start, __sbss_end - __sbss_start);
	bzero(__bss_start, _end - __bss_start);
#endif

	cpu_feature_setup();

#ifdef AIM
	aim_early_init(fdt, toc, ofentry, mdp, mdp_cookie);
#endif

	/*
	 * Parse metadata if present and fetch parameters.  Must be done
	 * before console is inited so cninit gets the right value of
	 * boothowto.
	 */
	if (mdp != NULL) {
		void *kmdp = NULL;
		char *envp = NULL;
		uintptr_t md_offset = 0;
		vm_paddr_t kernelendphys;

#ifdef AIM
		if ((uintptr_t)&powerpc_init > DMAP_BASE_ADDRESS)
			md_offset = DMAP_BASE_ADDRESS;
#else /* BOOKE */
		md_offset = VM_MIN_KERNEL_ADDRESS - kernload;
#endif

		preload_metadata = mdp;
		if (md_offset > 0) {
			preload_metadata += md_offset;
			preload_bootstrap_relocate(md_offset);
		}
		kmdp = preload_search_by_type("elf kernel");
		if (kmdp != NULL) {
			boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int);
			envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *);
			if (envp != NULL)
				envp += md_offset;
			init_static_kenv(envp, 0);
			if (fdt == 0) {
				fdt = MD_FETCH(kmdp, MODINFOMD_DTBP, uintptr_t);
				if (fdt != 0)
					fdt += md_offset;
			}
			kernelendphys = MD_FETCH(kmdp, MODINFOMD_KERNEND,
			    vm_offset_t);
			if (kernelendphys != 0)
				kernelendphys += md_offset;
			endkernel = ulmax(endkernel, kernelendphys);
#ifdef DDB
			ksym_start = MD_FETCH(kmdp, MODINFOMD_SSYM, uintptr_t);
			ksym_end = MD_FETCH(kmdp, MODINFOMD_ESYM, uintptr_t);
			db_fetch_ksymtab(ksym_start, ksym_end);
#endif
		}