On Wed, Jul 27, 2016 at 11:53:24AM +0200, Mark Kettenis wrote:
> Stop pretending we still support booting without an FDT. The board ID
> is still initialized as some platforms still need it.
>
> This adds code to support multiple memory blocks, such that we an
> support boards with multiple memory banks.
>
> This cleans up some comments as well to reflect the new reality.
>
> ok?
>
>
> Index: arch/armv7/armv7/armv7_machdep.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/armv7/armv7/armv7_machdep.c,v
> retrieving revision 1.33
> diff -u -p -r1.33 armv7_machdep.c
> --- arch/armv7/armv7/armv7_machdep.c 26 Jul 2016 22:10:10 -0000 1.33
> +++ arch/armv7/armv7/armv7_machdep.c 27 Jul 2016 09:49:37 -0000
> @@ -101,15 +101,8 @@
> * 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>
> @@ -208,9 +201,7 @@ char bootargs[MAX_BOOT_STRING];
> 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);
>
> @@ -377,10 +368,9 @@ copy_io_area_map(pd_entry_t *new_pd)
> * 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)
> @@ -390,9 +380,13 @@ initarm(void *arg0, void *arg1, void *ar
> 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 */
> @@ -429,7 +423,7 @@ initarm(void *arg0, void *arg1, void *ar
> 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
> @@ -442,42 +436,38 @@ initarm(void *arg0, void *arg1, void *ar
> */
> 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;
> -
> - node = fdt_find_node("/memory");
> - if (node == NULL || fdt_get_reg(node, 0, ®))
> - panic("initarm: no memory specificed");
> + if (!fdt_init(config) || fdt_get_size(config) == 0)
> + panic("initarm: no FDT");
>
> - 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));
> - }
> - }
> + 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);
There actually was a reason for the second fdt_init(config) call. If
the FDT is bigger than L1_S_SIZE we need to remap it with the correct
size. After the re-map the new VA which spans the whole FDT is now
in the variable "config". But FDT is still initialized with the old
VA that does not span the whole FDT.
Though I wonder if we really have a device tree that is bigger than
L1_S_SIZE, considering that's 1MB. The other issue might be alignment.
When the device tree is passed at the end of an L1 page. But it looks
like our bootloader passes it pretty well aligned, so we should not
run into any L1 page border issues there. Maybe just remove that size
check and remap completely?
Looks good otherwise. I like it.
> +
> + 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));
> + }
> +
> + 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);
>
> - /* XXX: Use FDT information. */
> platform_init();
> platform_disable_l2_if_needed();
>
> @@ -489,35 +479,12 @@ initarm(void *arg0, void *arg1, void *ar
>
> 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;
>
> @@ -618,15 +585,12 @@ initarm(void *arg0, void *arg1, void *ar
> /*
> * 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);
>
> @@ -716,10 +680,9 @@ initarm(void *arg0, void *arg1, void *ar
> 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
> @@ -782,8 +745,7 @@ initarm(void *arg0, void *arg1, void *ar
> 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
> @@ -805,15 +767,15 @@ initarm(void *arg0, void *arg1, void *ar
> 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 */
> @@ -974,23 +936,5 @@ board_startup(void)
> #else
> printf("kernel does not support -c; continuing..\n");
> #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);
> }
> }
> Index: arch/armv7/conf/files.armv7
> ===================================================================
> RCS file: /cvs/src/sys/arch/armv7/conf/files.armv7,v
> retrieving revision 1.19
> diff -u -p -r1.19 files.armv7
> --- arch/armv7/conf/files.armv7 23 May 2016 00:05:35 -0000 1.19
> +++ arch/armv7/conf/files.armv7 27 Jul 2016 09:49:37 -0000
> @@ -13,9 +13,6 @@ file arch/arm/arm/conf.c
> #interrupt API layer
> file arch/armv7/armv7/intr.c
>
> -# u-boot argument support
> -file arch/armv7/armv7/uboot_tags.c
> -
> # CPU support and integrated peripherals
> file arch/arm/arm/irq_dispatch.S
> file arch/arm/arm/softintr.c
>