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/param.h>
263ddc2cdeSBreno Leitao #include <sys/kernel.h>
273ddc2cdeSBreno Leitao #include <sys/systm.h>
283ddc2cdeSBreno Leitao #include <sys/module.h>
293ddc2cdeSBreno Leitao #include <sys/types.h>
303ddc2cdeSBreno Leitao #include <sys/proc.h>
313ddc2cdeSBreno Leitao
323ddc2cdeSBreno Leitao #include <vm/vm.h>
333ddc2cdeSBreno Leitao #include <vm/pmap.h>
343ddc2cdeSBreno Leitao
353ddc2cdeSBreno Leitao #include <machine/bus.h>
36*9411e24dSBrandon Bergren #include <machine/elf.h>
37*9411e24dSBrandon Bergren #include <machine/param.h>
383ddc2cdeSBreno Leitao
393ddc2cdeSBreno Leitao #include <dev/ofw/openfirm.h>
403ddc2cdeSBreno Leitao #include <dev/ofw/ofw_bus.h>
413ddc2cdeSBreno Leitao #include <dev/ofw/ofw_bus_subr.h>
423ddc2cdeSBreno Leitao
433ddc2cdeSBreno Leitao #include "opt_md.h"
443ddc2cdeSBreno Leitao
453ddc2cdeSBreno Leitao extern u_char *mfs_root;
465d8c3a06SLeandro Lupori extern int mfs_root_size;
473ddc2cdeSBreno Leitao
485d8c3a06SLeandro Lupori static void ofw_initrd_probe_and_attach(void *junk);
493ddc2cdeSBreno Leitao
505d8c3a06SLeandro Lupori SYSINIT(ofw_initrd_probe_and_attach, SI_SUB_KMEM, SI_ORDER_ANY,
515d8c3a06SLeandro Lupori ofw_initrd_probe_and_attach, NULL);
523ddc2cdeSBreno Leitao
535d8c3a06SLeandro Lupori static void
ofw_initrd_probe_and_attach(void * junk)545d8c3a06SLeandro Lupori ofw_initrd_probe_and_attach(void *junk)
553ddc2cdeSBreno Leitao {
563ddc2cdeSBreno Leitao phandle_t chosen;
573ddc2cdeSBreno Leitao vm_paddr_t start, end;
583ddc2cdeSBreno Leitao pcell_t cell[2];
593ddc2cdeSBreno Leitao ssize_t size;
60*9411e24dSBrandon Bergren u_char *taste;
61*9411e24dSBrandon Bergren Elf_Ehdr ehdr;
623ddc2cdeSBreno Leitao
635d8c3a06SLeandro Lupori if (!hw_direct_map)
645d8c3a06SLeandro Lupori return;
653ddc2cdeSBreno Leitao
663ddc2cdeSBreno Leitao chosen = OF_finddevice("/chosen");
675d8c3a06SLeandro Lupori if (chosen <= 0)
685d8c3a06SLeandro Lupori return;
695d8c3a06SLeandro Lupori
705d8c3a06SLeandro Lupori if (!OF_hasprop(chosen, "linux,initrd-start") ||
715d8c3a06SLeandro Lupori !OF_hasprop(chosen, "linux,initrd-end"))
725d8c3a06SLeandro Lupori return;
733ddc2cdeSBreno Leitao
743ddc2cdeSBreno Leitao size = OF_getencprop(chosen, "linux,initrd-start", cell, sizeof(cell));
753ddc2cdeSBreno Leitao if (size == 4)
763ddc2cdeSBreno Leitao start = cell[0];
773ddc2cdeSBreno Leitao else if (size == 8)
783ddc2cdeSBreno Leitao start = (uint64_t)cell[0] << 32 | cell[1];
793ddc2cdeSBreno Leitao else {
805d8c3a06SLeandro Lupori printf("ofw_initrd: Wrong linux,initrd-start size\n");
815d8c3a06SLeandro Lupori return;
823ddc2cdeSBreno Leitao }
833ddc2cdeSBreno Leitao
843ddc2cdeSBreno Leitao size = OF_getencprop(chosen, "linux,initrd-end", cell, sizeof(cell));
853ddc2cdeSBreno Leitao if (size == 4)
863ddc2cdeSBreno Leitao end = cell[0];
873ddc2cdeSBreno Leitao else if (size == 8)
883ddc2cdeSBreno Leitao end = (uint64_t)cell[0] << 32 | cell[1];
893ddc2cdeSBreno Leitao else{
905d8c3a06SLeandro Lupori printf("ofw_initrd: Wrong linux,initrd-end size\n");
915d8c3a06SLeandro Lupori return;
923ddc2cdeSBreno Leitao }
933ddc2cdeSBreno Leitao
943ddc2cdeSBreno Leitao if (end - start > 0) {
95*9411e24dSBrandon Bergren taste = (u_char*) PHYS_TO_DMAP(start);
96*9411e24dSBrandon Bergren memcpy(&ehdr, taste, sizeof(ehdr));
97*9411e24dSBrandon Bergren
98*9411e24dSBrandon Bergren if (IS_ELF(ehdr)) {
99*9411e24dSBrandon Bergren printf("ofw_initrd: initrd is kernel image!\n");
100*9411e24dSBrandon Bergren return;
101*9411e24dSBrandon Bergren }
102*9411e24dSBrandon Bergren
103*9411e24dSBrandon Bergren mfs_root = taste;
1043ddc2cdeSBreno Leitao mfs_root_size = end - start;
1055d8c3a06SLeandro Lupori printf("ofw_initrd: initrd loaded at 0x%08lx-0x%08lx\n",
1065d8c3a06SLeandro Lupori start, end);
1075d8c3a06SLeandro Lupori }
1083ddc2cdeSBreno Leitao }
109