xref: /freebsd/sys/powerpc/ofw/ofw_initrd.c (revision 9411e24df3c518227a10206ce2bae2e2f05a901c)
13ddc2cdeSBreno Leitao /*-
23ddc2cdeSBreno Leitao  * Copyright (C) 2018 Breno Leitao
33ddc2cdeSBreno Leitao  *
43ddc2cdeSBreno Leitao  * Redistribution and use in source and binary forms, with or without
53ddc2cdeSBreno Leitao  * modification, are permitted provided that the following conditions
63ddc2cdeSBreno Leitao  * are met:
73ddc2cdeSBreno Leitao  * 1. Redistributions of source code must retain the above copyright
83ddc2cdeSBreno Leitao  *    notice, this list of conditions and the following disclaimer.
93ddc2cdeSBreno Leitao  * 2. Redistributions in binary form must reproduce the above copyright
103ddc2cdeSBreno Leitao  *    notice, this list of conditions and the following disclaimer in the
113ddc2cdeSBreno Leitao  *    documentation and/or other materials provided with the distribution.
123ddc2cdeSBreno Leitao  *
133ddc2cdeSBreno Leitao  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
143ddc2cdeSBreno Leitao  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
153ddc2cdeSBreno Leitao  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
163ddc2cdeSBreno Leitao  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
173ddc2cdeSBreno Leitao  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
183ddc2cdeSBreno Leitao  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
193ddc2cdeSBreno Leitao  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
203ddc2cdeSBreno Leitao  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
213ddc2cdeSBreno Leitao  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
223ddc2cdeSBreno Leitao  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
233ddc2cdeSBreno Leitao  */
243ddc2cdeSBreno Leitao 
253ddc2cdeSBreno Leitao #include <sys/cdefs.h>
263ddc2cdeSBreno Leitao __FBSDID("$FreeBSD$");
273ddc2cdeSBreno Leitao 
283ddc2cdeSBreno Leitao #include <sys/param.h>
293ddc2cdeSBreno Leitao #include <sys/kernel.h>
303ddc2cdeSBreno Leitao #include <sys/systm.h>
313ddc2cdeSBreno Leitao #include <sys/module.h>
323ddc2cdeSBreno Leitao #include <sys/types.h>
333ddc2cdeSBreno Leitao #include <sys/proc.h>
343ddc2cdeSBreno Leitao 
353ddc2cdeSBreno Leitao #include <vm/vm.h>
363ddc2cdeSBreno Leitao #include <vm/pmap.h>
373ddc2cdeSBreno Leitao 
383ddc2cdeSBreno Leitao #include <machine/bus.h>
39*9411e24dSBrandon Bergren #include <machine/elf.h>
40*9411e24dSBrandon Bergren #include <machine/param.h>
413ddc2cdeSBreno Leitao 
423ddc2cdeSBreno Leitao #include <dev/ofw/openfirm.h>
433ddc2cdeSBreno Leitao #include <dev/ofw/ofw_bus.h>
443ddc2cdeSBreno Leitao #include <dev/ofw/ofw_bus_subr.h>
453ddc2cdeSBreno Leitao 
463ddc2cdeSBreno Leitao #include "opt_md.h"
473ddc2cdeSBreno Leitao 
483ddc2cdeSBreno Leitao extern u_char *mfs_root;
495d8c3a06SLeandro Lupori extern int mfs_root_size;
503ddc2cdeSBreno Leitao 
515d8c3a06SLeandro Lupori static void ofw_initrd_probe_and_attach(void *junk);
523ddc2cdeSBreno Leitao 
535d8c3a06SLeandro Lupori SYSINIT(ofw_initrd_probe_and_attach, SI_SUB_KMEM, SI_ORDER_ANY,
545d8c3a06SLeandro Lupori     ofw_initrd_probe_and_attach, NULL);
553ddc2cdeSBreno Leitao 
565d8c3a06SLeandro Lupori static void
575d8c3a06SLeandro Lupori ofw_initrd_probe_and_attach(void *junk)
583ddc2cdeSBreno Leitao {
593ddc2cdeSBreno Leitao 	phandle_t chosen;
603ddc2cdeSBreno Leitao 	vm_paddr_t start, end;
613ddc2cdeSBreno Leitao 	pcell_t cell[2];
623ddc2cdeSBreno Leitao 	ssize_t size;
63*9411e24dSBrandon Bergren 	u_char *taste;
64*9411e24dSBrandon Bergren 	Elf_Ehdr ehdr;
653ddc2cdeSBreno Leitao 
665d8c3a06SLeandro Lupori 	if (!hw_direct_map)
675d8c3a06SLeandro Lupori 		return;
683ddc2cdeSBreno Leitao 
693ddc2cdeSBreno Leitao 	chosen = OF_finddevice("/chosen");
705d8c3a06SLeandro Lupori 	if (chosen <= 0)
715d8c3a06SLeandro Lupori 		return;
725d8c3a06SLeandro Lupori 
735d8c3a06SLeandro Lupori 	if (!OF_hasprop(chosen, "linux,initrd-start") ||
745d8c3a06SLeandro Lupori 	    !OF_hasprop(chosen, "linux,initrd-end"))
755d8c3a06SLeandro Lupori 		return;
763ddc2cdeSBreno Leitao 
773ddc2cdeSBreno Leitao 	size = OF_getencprop(chosen, "linux,initrd-start", cell, sizeof(cell));
783ddc2cdeSBreno Leitao 	if (size == 4)
793ddc2cdeSBreno Leitao 		start = cell[0];
803ddc2cdeSBreno Leitao 	else if (size == 8)
813ddc2cdeSBreno Leitao 		start = (uint64_t)cell[0] << 32 | cell[1];
823ddc2cdeSBreno Leitao 	else {
835d8c3a06SLeandro Lupori 		printf("ofw_initrd: Wrong linux,initrd-start size\n");
845d8c3a06SLeandro Lupori 		return;
853ddc2cdeSBreno Leitao 	}
863ddc2cdeSBreno Leitao 
873ddc2cdeSBreno Leitao 	size = OF_getencprop(chosen, "linux,initrd-end", cell, sizeof(cell));
883ddc2cdeSBreno Leitao 	if (size == 4)
893ddc2cdeSBreno Leitao 		end = cell[0];
903ddc2cdeSBreno Leitao 	else if (size == 8)
913ddc2cdeSBreno Leitao 		end = (uint64_t)cell[0] << 32 | cell[1];
923ddc2cdeSBreno Leitao 	else{
935d8c3a06SLeandro Lupori 		printf("ofw_initrd: Wrong linux,initrd-end size\n");
945d8c3a06SLeandro Lupori 		return;
953ddc2cdeSBreno Leitao 	}
963ddc2cdeSBreno Leitao 
973ddc2cdeSBreno Leitao 	if (end - start > 0) {
98*9411e24dSBrandon Bergren 		taste = (u_char*) PHYS_TO_DMAP(start);
99*9411e24dSBrandon Bergren 		memcpy(&ehdr, taste, sizeof(ehdr));
100*9411e24dSBrandon Bergren 
101*9411e24dSBrandon Bergren 		if (IS_ELF(ehdr)) {
102*9411e24dSBrandon Bergren 			printf("ofw_initrd: initrd is kernel image!\n");
103*9411e24dSBrandon Bergren 			return;
104*9411e24dSBrandon Bergren 		}
105*9411e24dSBrandon Bergren 
106*9411e24dSBrandon Bergren 		mfs_root = taste;
1073ddc2cdeSBreno Leitao 		mfs_root_size = end - start;
1085d8c3a06SLeandro Lupori 		printf("ofw_initrd: initrd loaded at 0x%08lx-0x%08lx\n",
1095d8c3a06SLeandro Lupori 			start, end);
1105d8c3a06SLeandro Lupori 	}
1113ddc2cdeSBreno Leitao }
1123ddc2cdeSBreno Leitao 
113