-/* $OpenBSD: armv7_machdep.c,v 1.33 2016/07/26 22:10:10 patrick Exp $ */
+/* $OpenBSD: armv7_machdep.c,v 1.34 2016/07/30 08:07:01 kettenis Exp $ */
/* $NetBSD: lubbock_machdep.c,v 1.2 2003/07/15 00:25:06 lukem Exp $ */
/*
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * Machine dependant functions for kernel setup for Intel IQ80310 evaluation
- * boards using RedBoot firmware.
- */
-
-/*
- * DIP switches:
- *
- * S19: no-dot: set RB_KDB. enter kgdb session.
- * S20: no-dot: set RB_SINGLE. don't go multi user mode.
+ * Machine dependant functions for kernel setup for ARMv7 boards using
+ * u-boot/EFI firmware.
*/
#include <sys/param.h>
int bootstrap_bs_map(void *, bus_addr_t, bus_size_t, int,
bus_space_handle_t *);
void process_kernel_args(char *);
-void parse_uboot_tags(void *);
void consinit(void);
-void bootconfig_dram(BootConfig *, psize_t *, psize_t *);
bs_protos(bs_notimpl);
* It should be responsible for setting up everything that must be
* in place when main is called.
* This includes
- * Taking a copy of the boot configuration structure.
+ * Taking a copy of the FDT.
* Initialising the physical console so characters can be printed.
- * Setting up page tables for the kernel
- * Relocating the kernel to the bottom of physical memory
+ * Setting up page tables for the kernel.
*/
u_int
initarm(void *arg0, void *arg1, void *arg2)
pv_addr_t kernel_l1pt;
pv_addr_t fdt;
paddr_t loadaddr;
+ struct fdt_reg reg;
paddr_t memstart;
psize_t memsize;
+ paddr_t memend;
void *config;
+ size_t size;
+ void *node;
extern uint32_t esym; /* &_end if no symbols are loaded */
/* early bus_space_map support */
tmp_bs_tag.bs_map = bootstrap_bs_map;
/*
- * Now, map the bootconfig/FDT area.
+ * Now, map the FDT area.
*
* As we don't know the size of a possible FDT, map the size of a
* typical bootstrap bs map. The FDT might not be aligned, so this
- * might take up to two L1_S_SIZEd mappings. In the unlikely case
- * that the FDT is bigger than L1_S_SIZE (0x00100000), we need to
- * remap it.
+ * might take up to two L1_S_SIZEd mappings.
*
* XXX: There's (currently) no way to unmap a bootstrap mapping, so
* we might lose a bit of the bootstrap address space.
*/
bootstrap_bs_map(NULL, (bus_addr_t)arg2, L1_S_SIZE, 0,
(bus_space_handle_t *)&config);
- if (fdt_init(config) && fdt_get_size(config) != 0) {
- uint32_t size = fdt_get_size(config);
- if (size > L1_S_SIZE)
- bootstrap_bs_map(NULL, (bus_addr_t)arg2, size, 0,
- (bus_space_handle_t *)&config);
- }
- if (fdt_init(config) && fdt_get_size(config) != 0) {
- struct fdt_reg reg;
- void *node;
+ if (!fdt_init(config) || fdt_get_size(config) == 0)
+ panic("initarm: no FDT");
- node = fdt_find_node("/memory");
- if (node == NULL || fdt_get_reg(node, 0, ®))
- panic("initarm: no memory specificed");
+ node = fdt_find_node("/chosen");
+ if (node != NULL) {
+ char *args, *duid;
+ int len;
- memstart = reg.addr;
- memsize = reg.size;
- physical_start = reg.addr;
- physical_end = MIN(reg.addr + reg.size, (paddr_t)-PAGE_SIZE);
-
- node = fdt_find_node("/chosen");
- if (node != NULL) {
- char *args, *duid;
- int len;
-
- len = fdt_node_property(node, "bootargs", &args);
- if (len > 0)
- process_kernel_args(args);
-
- len = fdt_node_property(node, "openbsd,bootduid", &duid);
- if (len == sizeof(bootduid))
- memcpy(bootduid, duid, sizeof(bootduid));
- }
+ len = fdt_node_property(node, "bootargs", &args);
+ if (len > 0)
+ process_kernel_args(args);
+
+ len = fdt_node_property(node, "openbsd,bootduid", &duid);
+ if (len == sizeof(bootduid))
+ memcpy(bootduid, duid, sizeof(bootduid));
}
- /* XXX: Use FDT information. */
+ node = fdt_find_node("/memory");
+ if (node == NULL || fdt_get_reg(node, 0, ®))
+ panic("initarm: no memory specificed");
+
+ memstart = reg.addr;
+ memsize = reg.size;
+ physical_start = reg.addr;
+ physical_end = MIN(reg.addr + reg.size, (paddr_t)-PAGE_SIZE);
+
platform_init();
platform_disable_l2_if_needed();
printf("arg0 %p arg1 %p arg2 %p\n", arg0, arg1, arg2);
- if (fdt_get_size(config) == 0) {
- parse_uboot_tags(config);
-
- /*
- * Examine the boot args string for options we need to know about
- * now.
- */
- process_kernel_args(bootconfig.bootstring);
-
- /* normally u-boot will set up bootconfig.dramblocks */
- bootconfig_dram(&bootconfig, &memstart, &memsize);
-
- /*
- * Set up the variables that define the availablilty of
- * physical memory.
- *
- * XXX pmap_bootstrap() needs an enema.
- */
- physical_start = bootconfig.dram[0].address;
- physical_end = MIN((uint64_t)physical_start +
- (bootconfig.dram[0].pages * PAGE_SIZE), (paddr_t)-PAGE_SIZE);
- }
-
#ifdef RAMDISK_HOOKS
boothowto |= RB_DFLTROOT;
#endif /* RAMDISK_HOOKS */
- physical_freestart = (((unsigned long)esym - KERNEL_TEXT_BASE +0xfff) & ~0xfff) + loadaddr;
- physical_freeend = MIN((uint64_t)memstart+memsize, (paddr_t)-PAGE_SIZE);
+ physical_freestart = (((unsigned long)esym - KERNEL_TEXT_BASE + 0xfff) & ~0xfff) + loadaddr;
+ physical_freeend = MIN((uint64_t)physical_end, (paddr_t)-PAGE_SIZE);
physmem = (physical_end - physical_start) / PAGE_SIZE;
/*
* Allocate pages for an FDT copy.
*/
- if (fdt_get_size(config) != 0) {
- uint32_t size = fdt_get_size(config);
- valloc_pages(fdt, round_page(size) / PAGE_SIZE);
- memcpy((void *)fdt.pv_pa, config, size);
- }
+ size = fdt_get_size(config);
+ valloc_pages(fdt, round_page(size) / PAGE_SIZE);
+ memcpy((void *)fdt.pv_pa, config, size);
/*
* XXX Defer this to later so that we can reclaim the memory
- * XXX used by the RedBoot page tables.
*/
alloc_pages(msgbufphys, round_page(MSGBUFSIZE) / PAGE_SIZE);
PROT_READ | PROT_WRITE | PROT_EXEC, PTE_CACHE);
/* Map the FDT. */
- if (fdt.pv_va && fdt.pv_pa)
- pmap_map_chunk(l1pagetable, fdt.pv_va, fdt.pv_pa,
- round_page(fdt_get_size((void *)fdt.pv_pa)),
- PROT_READ | PROT_WRITE, PTE_CACHE);
+ pmap_map_chunk(l1pagetable, fdt.pv_va, fdt.pv_pa,
+ round_page(fdt_get_size((void *)fdt.pv_pa)),
+ PROT_READ | PROT_WRITE, PTE_CACHE);
/*
* map integrated peripherals at same address in l1pagetable
undefined_handler_address = (u_int)undefinedinstruction_bounce;
/* Now we can reinit the FDT, using the virtual address. */
- if (fdt.pv_va && fdt.pv_pa)
- fdt_init((void *)fdt.pv_va);
+ fdt_init((void *)fdt.pv_va);
/* Initialise the undefined instruction handlers */
#ifdef VERBOSE_INIT_ARM
physsegs--;
}
- physsegs = MIN(bootconfig.dramblocks, physsegs);
-
for (i = 1; i < physsegs; i++) {
- paddr_t dramstart = bootconfig.dram[i].address;
- paddr_t dramend = MIN((uint64_t)dramstart +
- bootconfig.dram[i].pages * PAGE_SIZE, (paddr_t)-PAGE_SIZE);
- physmem += (dramend - dramstart) / PAGE_SIZE;
- uvm_page_physload(atop(dramstart), atop(dramend),
- atop(dramstart), atop(dramend), 0);
+ if (fdt_get_reg(node, i, ®))
+ break;
+
+ memstart = reg.addr;
+ memend = MIN(reg.addr + reg.size, (paddr_t)-PAGE_SIZE);
+ physmem += (memend - memstart) / PAGE_SIZE;
+ uvm_page_physload(atop(memstart), atop(memend),
+ atop(memstart), atop(memend), 0);
}
/* Boot strap pmap telling it where the kernel page table is */
#endif
}
}
-
-void
-bootconfig_dram(BootConfig *bootconfig, psize_t *memstart, psize_t *memsize)
-{
- int loop;
-
- if (bootconfig->dramblocks == 0)
- panic("%s: dramblocks not set up!", __func__);
-
- *memstart = bootconfig->dram[0].address;
- *memsize = bootconfig->dram[0].pages * PAGE_SIZE;
- printf("memory size derived from u-boot\n");
- for (loop = 0; loop < bootconfig->dramblocks; loop++) {
- printf("bootconf.mem[%d].address = %08x pages %d/0x%08x\n",
- loop, bootconfig->dram[loop].address, bootconfig->dram[loop].pages,
- bootconfig->dram[loop].pages * PAGE_SIZE);
- }
-}
+++ /dev/null
-/* $OpenBSD: uboot_tags.c,v 1.1 2013/09/04 14:38:25 patrick Exp $ */
-/*
- * Copyright (c) 2011 Dale Rahn <drahn@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/systm.h>
-
-#include <machine/bootconfig.h>
-
-struct uboot_tag_header {
- uint32_t size;
- uint32_t tag;
-};
-struct uboot_tag_core {
- uint32_t flags;
- uint32_t pagesize;
- uint32_t rootdev;
-};
-struct uboot_tag_serialnr {
- uint32_t low;
- uint32_t high;
-};
-struct uboot_tag_revision {
- uint32_t rev;
-};
-struct uboot_tag_mem32 {
- uint32_t size;
- uint32_t start;
-};
-struct uboot_tag_cmdline {
- char cmdline[1];
-};
-
-#define ATAG_CORE 0x54410001
-#define ATAG_MEM 0x54410002
-#define ATAG_CMDLINE 0x54410009
-#define ATAG_SERIAL 0x54410006
-#define ATAG_REVISION 0x54410007
-#define ATAG_NONE 0x00000000
-struct uboot_tag {
- struct uboot_tag_header hdr;
- union {
- struct uboot_tag_core core;
- struct uboot_tag_mem32 mem;
- struct uboot_tag_revision rev;
- struct uboot_tag_serialnr serialnr;
- struct uboot_tag_cmdline cmdline;
- } u;
-};
-
-int parse_uboot_tags(void *handle);
-int
-parse_uboot_tags(void *handle)
-{
- uint32_t *p;
- struct uboot_tag *tag;
- int i;
-
- p = handle;
- tag = (struct uboot_tag *)p;
-
- while(tag != NULL && tag->hdr.size < 4096 &&
- tag->hdr.tag != ATAG_NONE) {
- switch (tag->hdr.tag) {
- case ATAG_CORE:
- printf("atag core flags %x pagesize %x rootdev %x\n",
- tag->u.core.flags,
- tag->u.core.pagesize,
- tag->u.core.rootdev);
- break;
- case ATAG_MEM:
- printf("atag mem start 0x%08x size 0x%x\n",
- tag->u.mem.start,
- tag->u.mem.size);
-
- i = bootconfig.dramblocks -1;
- if (bootconfig.dramblocks != 0 &&
- (tag->u.mem.start == bootconfig.dram[i].address +
- (bootconfig.dram[i].pages * PAGE_SIZE))) {
- bootconfig.dram[i].pages =
- bootconfig.dram[i].pages +
- tag->u.mem.size / PAGE_SIZE;
- } else {
- i = bootconfig.dramblocks;
- bootconfig.dram[i].address = tag->u.mem.start;
- bootconfig.dram[i].pages = tag->u.mem.size
- / PAGE_SIZE;
- bootconfig.dramblocks = i + 1;
- }
-
- break;
- case ATAG_CMDLINE:
- printf("atag cmdline [%s]\n",
- tag->u.cmdline.cmdline);
- strncpy(bootconfig.bootstring, tag->u.cmdline.cmdline,
- sizeof(bootconfig.bootstring));
- break;
- case ATAG_SERIAL:
- printf("atag serial 0x%08x:%08x\n",
- tag->u.serialnr.high,
- tag->u.serialnr.low);
- break;
- case ATAG_REVISION:
- printf("atag revision %08x\n",
- tag->u.rev.rev);
- break;
- default:
- printf("uboot tag unknown 0x%08x size %d\n",
- tag->hdr.tag,
- tag->hdr.size);
- }
- p = p + tag->hdr.size;
- tag = (struct uboot_tag *)p;
- }
-
- return 0;
-}