Date: Mon, 12 Oct 2020 17:32:21 -0700 From: Mark Millard <marklmi@yahoo.com> To: Kyle Evans <kevans@FreeBSD.org>, freebsd-arm <freebsd-arm@freebsd.org> Subject: Re: RPi4B: an example of what RAM u-boot reserves during operation [patch included] Message-ID: <B178FB1A-B4EA-4B0E-9FAD-D58463E1321E@yahoo.com> In-Reply-To: <A0293335-6DE2-452F-B179-0CCAFE5076BB@yahoo.com> References: <A0293335-6DE2-452F-B179-0CCAFE5076BB@yahoo.com>
next in thread | previous in thread | raw e-mail | index | archive | help
On 2020-Oct-12, at 11:19, Mark Millard <marklmi at yahoo.com> wrote: > U-Boot> bdinfo > boot_params =3D 0x0000000000000100 > . . . > lmb_dump_all: > memory.cnt =3D 0x2 > memory.size =3D 0x0 > memory.reg[0x0].base =3D 0x0 > .size =3D 0x3e000000 > memory.reg[0x1].base =3D 0x40000000 > .size =3D 0xbc000000 >=20 > reserved.cnt =3D 0x2 > reserved.size =3D 0x0 > reserved.reg[0x0].base =3D 0x0 > .size =3D 0x1000 > reserved.reg[0x1].base =3D 0x3db47b30 > .size =3D 0x4b84d0 > . . . >=20 > That: >=20 > reserved.reg[0x0].base =3D 0x0 > .size =3D 0x1000 >=20 > means that armstub8-gic.bin is not fully > protected at this point in u-boot's execution. >=20 > Basically boot_fdt_add_mem_rsv_regions is all that > is used currently and it does not take into account > CONFIG_RPI_EFI_NR_SPIN_PAGES=3D2 : >=20 > /** > * boot_fdt_add_mem_rsv_regions - Mark the memreserve and = reserved-memory > * sections as unusable > * @lmb: pointer to lmb handle, will be used for memory mgmt > * @fdt_blob: pointer to fdt blob base address > * > * Adds the and reserved-memorymemreserve regions in the dtb to the lmb = block. > * Adding the memreserve regions prevents u-boot from using them to = store the > * initrd or the fdt blob. > */ > void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob) > { > uint64_t addr, size; > int i, total, ret; > int nodeoffset, subnode; > struct fdt_resource res; >=20 > if (fdt_check_header(fdt_blob) !=3D 0) > return; >=20 > /* process memreserve sections */ > total =3D fdt_num_mem_rsv(fdt_blob); > for (i =3D 0; i < total; i++) { > if (fdt_get_mem_rsv(fdt_blob, i, &addr, &size) !=3D 0) > continue; > boot_fdt_reserve_region(lmb, addr, size); > } >=20 > /* process reserved-memory */ > nodeoffset =3D fdt_subnode_offset(fdt_blob, 0, = "reserved-memory"); > if (nodeoffset >=3D 0) { > subnode =3D fdt_first_subnode(fdt_blob, nodeoffset); > while (subnode >=3D 0) { > /* check if this subnode has a reg property */ > ret =3D fdt_get_resource(fdt_blob, subnode, = "reg", 0, > &res); > if (!ret && fdtdec_get_is_enabled(fdt_blob, = subnode)) { > addr =3D res.start; > size =3D res.end - res.start + 1; > boot_fdt_reserve_region(lmb, addr, = size); > } >=20 > subnode =3D fdt_next_subnode(fdt_blob, = subnode); > } > } > } >=20 >=20 The patch later below causes u-boot to protect the first 2 pages during its operations, not just the first page (just 1 indicated by the firmware's supplied fdt): U-Boot> bdinfo lmb_dump_all: . . . reserved.cnt =3D 0x2 reserved.size =3D 0x0 reserved.reg[0x0].base =3D 0x0 .size =3D 0x2000 reserved.reg[0x1].base =3D 0x3db47b30 .size =3D 0x4b84d0 . . . u-boot's code does not deal with merging overlaps, just adjacent ranges. So the new code covers just base 0x1000u size 0x1000u as reserved, leaving how base 0x0u size 0x1000u was covered as it was. The patch looks like (up to whitespace variance via email handling): # diff -u board/raspberrypi/rpi/rpi.c.orig board/raspberrypi/rpi/rpi.c --- board/raspberrypi/rpi/rpi.c.orig 2020-10-05 08:15:32.000000000 = -0700 +++ board/raspberrypi/rpi/rpi.c 2020-10-12 17:12:10.371941000 -0700 @@ -12,6 +12,7 @@ #include <fdt_simplefb.h> #include <init.h> #include <lcd.h> +#include <lmb.h> #include <memalign.h> #include <mmc.h> #include <asm/gpio.h> @@ -494,4 +495,28 @@ #endif =20 return 0; +} + +void board_lmb_reserve(struct lmb *lmb) +{ +#ifdef CONFIG_EFI_LOADER + /* + * NOTE: lmb_reserve (and more) does not deal with overlaps with + * pre-existing reservations. + * But board_lmb_reserve is called before the original + * first-page is added. So use knowledge of what will = happen + * later to avoid overlaps. + */ + + phys_addr_t base =3D 0x0u; + phys_addr_t size =3D CONFIG_RPI_EFI_NR_SPIN_PAGES << = EFI_PAGE_SHIFT; + + if (size <=3D EFI_PAGE_SIZE) return; + + /* Avoid future overlap */ + base +=3D EFI_PAGE_SIZE; + size -=3D EFI_PAGE_SIZE; + + lmb_reserve(lmb, base, size); +#endif } ft_board_setup already used CONFIG_RPI_EFI_NR_SPIN_PAGES based on only checking CONFIG_EFI_LOADER, so I did the same above. =3D=3D=3D Mark Millard marklmi at yahoo.com ( dsl-only.net went away in early 2018-Mar)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?B178FB1A-B4EA-4B0E-9FAD-D58463E1321E>