diff --git a/GNUmakefile b/GNUmakefile index b096524..349079d 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -88,11 +88,9 @@ VIRTIO_HDD_QEMU_ARG="" QEMU_CDROM_ARGS=\ -drive if=pflash,unit=0,format=raw,file=ovmf/ovmf-code-$(KARCH).fd,readonly=on \ - -drive if=pflash,unit=1,format=raw,file=ovmf/ovmf-vars-$(KARCH).fd QEMU_HDD_ARGS=\ -drive if=pflash,unit=0,format=raw,file=ovmf/ovmf-code-$(KARCH).fd,readonly=on \ - -drive if=pflash,unit=1,format=raw,file=ovmf/ovmf-vars-$(KARCH).fd ifeq ($(DRIVE_KIND),block) ifeq ($(KARCH),riscv64) @@ -138,7 +136,7 @@ run: run-$(KARCH) run-hdd: run-hdd-$(KARCH) .PHONY: run-x86_64 -run-x86_64: ovmf/ovmf-code-$(KARCH).fd ovmf/ovmf-vars-$(KARCH).fd $(IMAGE_NAME).iso +run-x86_64: ovmf/ovmf-code-$(KARCH).fd $(IMAGE_NAME).iso qemu-system-$(KARCH) \ -cpu max \ $(QEMUFLAGS) \ @@ -146,7 +144,7 @@ run-x86_64: ovmf/ovmf-code-$(KARCH).fd ovmf/ovmf-vars-$(KARCH).fd $(IMAGE_NAME). $(EXTRA_QEMU_ARGS) .PHONY: run-hdd-x86_64 -run-hdd-x86_64: ovmf/ovmf-code-$(KARCH).fd ovmf/ovmf-vars-$(KARCH).fd $(IMAGE_NAME).hdd +run-hdd-x86_64: ovmf/ovmf-code-$(KARCH).fd $(IMAGE_NAME).hdd qemu-system-$(KARCH) \ -cpu max \ $(QEMUFLAGS) \ @@ -154,7 +152,7 @@ run-hdd-x86_64: ovmf/ovmf-code-$(KARCH).fd ovmf/ovmf-vars-$(KARCH).fd $(IMAGE_NA $(EXTRA_QEMU_ARGS) .PHONY: run-aarch64 -run-aarch64: ovmf/ovmf-code-$(KARCH).fd ovmf/ovmf-vars-$(KARCH).fd $(IMAGE_NAME).iso +run-aarch64: ovmf/ovmf-code-$(KARCH).fd $(IMAGE_NAME).iso qemu-system-$(KARCH) \ -cpu max \ -device ramfb \ @@ -166,7 +164,7 @@ run-aarch64: ovmf/ovmf-code-$(KARCH).fd ovmf/ovmf-vars-$(KARCH).fd $(IMAGE_NAME) $(EXTRA_QEMU_ARGS) .PHONY: run-hdd-aarch64 -run-hdd-aarch64: ovmf/ovmf-code-$(KARCH).fd ovmf/ovmf-vars-$(KARCH).fd $(IMAGE_NAME).hdd +run-hdd-aarch64: ovmf/ovmf-code-$(KARCH).fd $(IMAGE_NAME).hdd qemu-system-$(KARCH) \ -cpu max \ -device ramfb \ @@ -178,7 +176,7 @@ run-hdd-aarch64: ovmf/ovmf-code-$(KARCH).fd ovmf/ovmf-vars-$(KARCH).fd $(IMAGE_N $(EXTRA_QEMU_ARGS) .PHONY: run-riscv64 -run-riscv64: ovmf/ovmf-code-$(KARCH).fd ovmf/ovmf-vars-$(KARCH).fd $(IMAGE_NAME).iso +run-riscv64: ovmf/ovmf-code-$(KARCH).fd $(IMAGE_NAME).iso qemu-system-$(KARCH) \ -cpu max \ -device ramfb \ @@ -190,7 +188,7 @@ run-riscv64: ovmf/ovmf-code-$(KARCH).fd ovmf/ovmf-vars-$(KARCH).fd $(IMAGE_NAME) $(EXTRA_QEMU_ARGS) .PHONY: run-hdd-riscv64 -run-hdd-riscv64: ovmf/ovmf-code-$(KARCH).fd ovmf/ovmf-vars-$(KARCH).fd $(IMAGE_NAME).hdd +run-hdd-riscv64: ovmf/ovmf-code-$(KARCH).fd $(IMAGE_NAME).hdd qemu-system-$(KARCH) \ -cpu max \ -device ramfb \ @@ -202,7 +200,7 @@ run-hdd-riscv64: ovmf/ovmf-code-$(KARCH).fd ovmf/ovmf-vars-$(KARCH).fd $(IMAGE_N $(EXTRA_QEMU_ARGS) .PHONY: run-loongarch64 -run-loongarch64: ovmf/ovmf-code-$(KARCH).fd ovmf/ovmf-vars-$(KARCH).fd $(IMAGE_NAME).iso +run-loongarch64: ovmf/ovmf-code-$(KARCH).fd $(IMAGE_NAME).iso qemu-system-$(KARCH) \ -device ramfb \ -device qemu-xhci \ @@ -213,7 +211,7 @@ run-loongarch64: ovmf/ovmf-code-$(KARCH).fd ovmf/ovmf-vars-$(KARCH).fd $(IMAGE_N $(EXTRA_QEMU_ARGS) .PHONY: run-hdd-loongarch64 -run-hdd-loongarch64: ovmf/ovmf-code-$(KARCH).fd ovmf/ovmf-vars-$(KARCH).fd $(IMAGE_NAME).hdd +run-hdd-loongarch64: ovmf/ovmf-code-$(KARCH).fd $(IMAGE_NAME).hdd qemu-system-$(KARCH) \ -device ramfb \ -device qemu-xhci \ @@ -248,14 +246,6 @@ ovmf/ovmf-code-$(KARCH).fd: riscv64) dd if=/dev/zero of=$@ bs=1 count=0 seek=33554432 2>/dev/null;; \ esac -ovmf/ovmf-vars-$(KARCH).fd: - mkdir -p ovmf - curl -Lo $@ https://github.com/osdev0/edk2-ovmf-nightly/releases/latest/download/ovmf-vars-$(KARCH).fd - case "$(KARCH)" in \ - aarch64) dd if=/dev/zero of=$@ bs=1 count=0 seek=67108864 2>/dev/null;; \ - riscv64) dd if=/dev/zero of=$@ bs=1 count=0 seek=33554432 2>/dev/null;; \ - esac - limine/limine: rm -rf limine git clone https://github.com/limine-bootloader/limine.git --branch=v8.x-binary --depth=1 diff --git a/kernel/get-deps b/kernel/get-deps index 8ab0929..172bb53 100755 --- a/kernel/get-deps +++ b/kernel/get-deps @@ -64,24 +64,22 @@ download_by_hash() { fi } -if ! test -f version; then - clone_repo_commit \ - https://github.com/osdev0/freestnd-c-hdrs-0bsd.git \ - freestnd-c-hdrs-0bsd \ - 0353851fdebe0eb6a4d2c608c5393040d310bf35 +clone_repo_commit \ + https://github.com/osdev0/freestnd-c-hdrs-0bsd.git \ + freestnd-c-hdrs-0bsd \ + 0353851fdebe0eb6a4d2c608c5393040d310bf35 - download_by_hash \ - https://github.com/osdev0/cc-runtime/raw/dcdf5d82973e77edee597a047a3ef66300903de9/cc-runtime.c \ - src/cc-runtime.c \ - 199907f5303ab15a963377fabcc1f2ee736e4ed18d54c59aab08345aa5485e8a +download_by_hash \ + https://github.com/osdev0/cc-runtime/raw/dcdf5d82973e77edee597a047a3ef66300903de9/cc-runtime.c \ + src/cc-runtime.c \ + 199907f5303ab15a963377fabcc1f2ee736e4ed18d54c59aab08345aa5485e8a - download_by_hash \ - https://github.com/limine-bootloader/limine/raw/97c31196a9aec28b36ed9ff64d6df77a061c3d9b/limine.h \ - src/limine.h \ - 3a018a8326adb5e6cff14a8595c775fd88235eb3e5fde4a135132b6398d165d5 +download_by_hash \ + https://github.com/limine-bootloader/limine/raw/97c31196a9aec28b36ed9ff64d6df77a061c3d9b/limine.h \ + src/limine.h \ + 3a018a8326adb5e6cff14a8595c775fd88235eb3e5fde4a135132b6398d165d5 - download_by_hash \ - https://gist.githubusercontent.com/suhas-pai/2a6c1c4d32491aaf363ee3b1b3884390/raw/541482dbc61862bba8a156edaae57faa2995d791/stdatomic.h \ - freestnd-c-hdrs-0bsd/stdatomic.h \ - 5e5d78080b2126535ee724a03082fea398dd5afb98548d95177c738a1fc17abe -fi +download_by_hash \ + https://gist.githubusercontent.com/suhas-pai/2a6c1c4d32491aaf363ee3b1b3884390/raw/541482dbc61862bba8a156edaae57faa2995d791/stdatomic.h \ + freestnd-c-hdrs-0bsd/stdatomic.h \ + 5e5d78080b2126535ee724a03082fea398dd5afb98548d95177c738a1fc17abe diff --git a/kernel/src/fdt/fdt.c b/kernel/src/fdt/fdt.c index 39c203d..5fc6a7b 100644 --- a/kernel/src/fdt/fdt.c +++ b/kernel/src/fdt/fdt.c @@ -172,7 +172,7 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) if (!can_assume(VALID_DTB) && !tagp) return FDT_END; /* premature end */ tag = fdt32_to_cpu(*tagp); - offset += (int)FDT_TAGSIZE; + offset += FDT_TAGSIZE; *nextoffset = -FDT_ERR_BADSTRUCTURE; switch (tag) { @@ -197,7 +197,7 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) return FDT_END; /* premature end */ /* skip-name offset, length and value */ - offset += (int)(sizeof(struct fdt_property) - FDT_TAGSIZE + len); + offset += sizeof(struct fdt_property) - FDT_TAGSIZE + len; if (!can_assume(LATEST) && fdt_version(fdt) < 0x10 && len >= 8 && @@ -217,7 +217,7 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) if (!fdt_offset_ptr(fdt, startoffset, (unsigned)(offset - startoffset))) return FDT_END; /* premature end */ - *nextoffset = FDT_TAGALIGN((unsigned long)offset); + *nextoffset = (int)FDT_TAGALIGN((unsigned long)offset); return tag; } diff --git a/kernel/src/fdt/fdt.h b/kernel/src/fdt/fdt.h index 0b5523b..0c91aa7 100644 --- a/kernel/src/fdt/fdt.h +++ b/kernel/src/fdt/fdt.h @@ -10,57 +10,57 @@ #ifndef __ASSEMBLY__ struct fdt_header { - fdt32_t magic; /* magic word FDT_MAGIC */ - fdt32_t totalsize; /* total size of DT block */ - fdt32_t off_dt_struct; /* offset to structure */ - fdt32_t off_dt_strings; /* offset to strings */ - fdt32_t off_mem_rsvmap; /* offset to memory reserve map */ - fdt32_t version; /* format version */ - fdt32_t last_comp_version; /* last compatible version */ + fdt32_t magic; /* magic word FDT_MAGIC */ + fdt32_t totalsize; /* total size of DT block */ + fdt32_t off_dt_struct; /* offset to structure */ + fdt32_t off_dt_strings; /* offset to strings */ + fdt32_t off_mem_rsvmap; /* offset to memory reserve map */ + fdt32_t version; /* format version */ + fdt32_t last_comp_version; /* last compatible version */ - /* version 2 fields below */ - fdt32_t boot_cpuid_phys; /* Which physical CPU id we're - booting on */ - /* version 3 fields below */ - fdt32_t size_dt_strings; /* size of the strings block */ + /* version 2 fields below */ + fdt32_t boot_cpuid_phys; /* Which physical CPU id we're + booting on */ + /* version 3 fields below */ + fdt32_t size_dt_strings; /* size of the strings block */ - /* version 17 fields below */ - fdt32_t size_dt_struct; /* size of the structure block */ + /* version 17 fields below */ + fdt32_t size_dt_struct; /* size of the structure block */ }; struct fdt_reserve_entry { - fdt64_t address; - fdt64_t size; + fdt64_t address; + fdt64_t size; }; struct fdt_node_header { - fdt32_t tag; - char name[]; + fdt32_t tag; + char name[]; }; struct fdt_property { - fdt32_t tag; - fdt32_t len; - fdt32_t nameoff; - char data[]; + fdt32_t tag; + fdt32_t len; + fdt32_t nameoff; + char data[]; }; #endif /* !__ASSEMBLY */ -#define FDT_MAGIC 0xd00dfeed /* 4: version, 4: total size */ -#define FDT_TAGSIZE sizeof(fdt32_t) +#define FDT_MAGIC 0xd00dfeed /* 4: version, 4: total size */ +#define FDT_TAGSIZE sizeof(fdt32_t) -#define FDT_BEGIN_NODE 0x1 /* Start node: full name */ -#define FDT_END_NODE 0x2 /* End node */ -#define FDT_PROP 0x3 /* Property: name off, - size, content */ -#define FDT_NOP 0x4 /* nop */ -#define FDT_END 0x9 +#define FDT_BEGIN_NODE 0x1 /* Start node: full name */ +#define FDT_END_NODE 0x2 /* End node */ +#define FDT_PROP 0x3 /* Property: name off, + size, content */ +#define FDT_NOP 0x4 /* nop */ +#define FDT_END 0x9 -#define FDT_V1_SIZE (7*sizeof(fdt32_t)) -#define FDT_V2_SIZE (FDT_V1_SIZE + sizeof(fdt32_t)) -#define FDT_V3_SIZE (FDT_V2_SIZE + sizeof(fdt32_t)) -#define FDT_V16_SIZE FDT_V3_SIZE -#define FDT_V17_SIZE (FDT_V16_SIZE + sizeof(fdt32_t)) +#define FDT_V1_SIZE (7*sizeof(fdt32_t)) +#define FDT_V2_SIZE (FDT_V1_SIZE + sizeof(fdt32_t)) +#define FDT_V3_SIZE (FDT_V2_SIZE + sizeof(fdt32_t)) +#define FDT_V16_SIZE FDT_V3_SIZE +#define FDT_V17_SIZE (FDT_V16_SIZE + sizeof(fdt32_t)) #endif /* FDT_H */ diff --git a/kernel/src/fdt/fdt_check.c b/kernel/src/fdt/fdt_check.c index 9590ded..249ac0d 100644 --- a/kernel/src/fdt/fdt_check.c +++ b/kernel/src/fdt/fdt_check.c @@ -12,85 +12,85 @@ int fdt_check_full(const void *fdt, size_t bufsize) { - int err; - int num_memrsv; - int offset, nextoffset = 0; - uint32_t tag; - unsigned int depth = 0; - const void *prop; - const char *propname; - bool expect_end = false; - - if (bufsize < FDT_V1_SIZE) - return -FDT_ERR_TRUNCATED; - if (bufsize < fdt_header_size(fdt)) - return -FDT_ERR_TRUNCATED; - err = fdt_check_header(fdt); - if (err != 0) - return err; - if (bufsize < fdt_totalsize(fdt)) - return -FDT_ERR_TRUNCATED; - - num_memrsv = fdt_num_mem_rsv(fdt); - if (num_memrsv < 0) - return num_memrsv; - - while (1) { - offset = nextoffset; - tag = fdt_next_tag(fdt, offset, &nextoffset); - - if (nextoffset < 0) - return nextoffset; - - /* If we see two root nodes, something is wrong */ - if (expect_end && tag != FDT_END) - return -FDT_ERR_BADSTRUCTURE; - - switch (tag) { - case FDT_NOP: - break; - - case FDT_END: - if (depth != 0) - return -FDT_ERR_BADSTRUCTURE; - return 0; - - case FDT_BEGIN_NODE: - depth++; - if (depth > INT_MAX) - return -FDT_ERR_BADSTRUCTURE; - - /* The root node must have an empty name */ - if (depth == 1) { - const char *name; - int len; - - name = fdt_get_name(fdt, offset, &len); - if (!name) - return len; - - if (*name || len) - return -FDT_ERR_BADSTRUCTURE; - } - break; - - case FDT_END_NODE: - if (depth == 0) - return -FDT_ERR_BADSTRUCTURE; - depth--; - if (depth == 0) - expect_end = true; - break; - - case FDT_PROP: - prop = fdt_getprop_by_offset(fdt, offset, &propname, - &err); - if (!prop) - return err; - break; - - default: - return -FDT_ERR_INTERNAL; - } - } + int err; + int num_memrsv; + int offset, nextoffset = 0; + uint32_t tag; + unsigned int depth = 0; + const void *prop; + const char *propname; + bool expect_end = false; + + if (bufsize < FDT_V1_SIZE) + return -FDT_ERR_TRUNCATED; + if (bufsize < fdt_header_size(fdt)) + return -FDT_ERR_TRUNCATED; + err = fdt_check_header(fdt); + if (err != 0) + return err; + if (bufsize < fdt_totalsize(fdt)) + return -FDT_ERR_TRUNCATED; + + num_memrsv = fdt_num_mem_rsv(fdt); + if (num_memrsv < 0) + return num_memrsv; + + while (1) { + offset = nextoffset; + tag = fdt_next_tag(fdt, offset, &nextoffset); + + if (nextoffset < 0) + return nextoffset; + + /* If we see two root nodes, something is wrong */ + if (expect_end && tag != FDT_END) + return -FDT_ERR_BADSTRUCTURE; + + switch (tag) { + case FDT_NOP: + break; + + case FDT_END: + if (depth != 0) + return -FDT_ERR_BADSTRUCTURE; + return 0; + + case FDT_BEGIN_NODE: + depth++; + if (depth > INT_MAX) + return -FDT_ERR_BADSTRUCTURE; + + /* The root node must have an empty name */ + if (depth == 1) { + const char *name; + int len; + + name = fdt_get_name(fdt, offset, &len); + if (!name) + return len; + + if (*name || len) + return -FDT_ERR_BADSTRUCTURE; + } + break; + + case FDT_END_NODE: + if (depth == 0) + return -FDT_ERR_BADSTRUCTURE; + depth--; + if (depth == 0) + expect_end = true; + break; + + case FDT_PROP: + prop = fdt_getprop_by_offset(fdt, offset, &propname, + &err); + if (!prop) + return err; + break; + + default: + return -FDT_ERR_INTERNAL; + } + } } diff --git a/kernel/src/fdt/fdt_overlay.c b/kernel/src/fdt/fdt_overlay.c index fd50e47..8810ece 100644 --- a/kernel/src/fdt/fdt_overlay.c +++ b/kernel/src/fdt/fdt_overlay.c @@ -102,26 +102,22 @@ int fdt_overlay_target_offset(const void *fdt, const void *fdto, static int overlay_phandle_add_offset(void *fdt, int node, const char *name, uint32_t delta) { - const fdt32_t *val; - uint32_t adj_val; + fdt32_t *valp, val; int len; - val = fdt_getprop(fdt, node, name, &len); - if (!val) + valp = fdt_getprop_w(fdt, node, name, &len); + if (!valp) return len; - if (len != sizeof(*val)) + if (len != sizeof(val)) return -FDT_ERR_BADPHANDLE; - adj_val = fdt32_to_cpu(*val); - if ((adj_val + delta) < adj_val) - return -FDT_ERR_NOPHANDLES; - - adj_val += delta; - if (adj_val == (uint32_t)-1) + val = fdt32_ld(valp); + if (val + delta < val || val + delta == (uint32_t)-1) return -FDT_ERR_NOPHANDLES; - return fdt_setprop_inplace_u32(fdt, node, name, adj_val); + fdt32_st(valp, val + delta); + return 0; } /** @@ -214,8 +210,8 @@ static int overlay_update_local_node_references(void *fdto, fdt_for_each_property_offset(fixup_prop, fdto, fixup_node) { const fdt32_t *fixup_val; - const char *tree_val; const char *name; + char *tree_val; int fixup_len; int tree_len; int i; @@ -227,9 +223,9 @@ static int overlay_update_local_node_references(void *fdto, if ((unsigned long)fixup_len % sizeof(uint32_t)) return -FDT_ERR_BADOVERLAY; - fixup_len /= (int)sizeof(uint32_t); + fixup_len /= sizeof(uint32_t); - tree_val = fdt_getprop(fdto, tree_node, name, &tree_len); + tree_val = fdt_getprop_w(fdto, tree_node, name, &tree_len); if (!tree_val) { if (tree_len == -FDT_ERR_NOTFOUND) return -FDT_ERR_BADOVERLAY; @@ -238,33 +234,15 @@ static int overlay_update_local_node_references(void *fdto, } for (i = 0; i < fixup_len; i++) { - fdt32_t adj_val; - uint32_t poffset; + fdt32_t *refp; - poffset = fdt32_to_cpu(fixup_val[i]); + refp = (fdt32_t *)(void *)(tree_val + fdt32_ld_(fixup_val + i)); /* - * phandles to fixup can be unaligned. - * - * Use a memcpy for the architectures that do - * not support unaligned accesses. + * phandles to fixup can be unaligned, so use + * fdt32_{ld,st}() to read/write them. */ - memcpy(&adj_val, tree_val + poffset, sizeof(adj_val)); - - adj_val = cpu_to_fdt32(fdt32_to_cpu(adj_val) + delta); - - ret = fdt_setprop_inplace_namelen_partial(fdto, - tree_node, - name, - strlen(name), - poffset, - &adj_val, - sizeof(adj_val)); - if (ret == -FDT_ERR_NOSPACE) - return -FDT_ERR_BADOVERLAY; - - if (ret) - return ret; + fdt32_st(refp, fdt32_ld(refp) + delta); } } @@ -338,7 +316,7 @@ static int overlay_update_local_references(void *fdto, uint32_t delta) * @name: Name of the property holding the phandle reference in the overlay * @name_len: number of name characters to consider * @poffset: Offset within the overlay property where the phandle is stored - * @label: Label of the node referenced by the phandle + * @phandle: Phandle referencing the node * * overlay_fixup_one_phandle() resolves an overlay phandle pointing to * a node in the base device tree. @@ -355,30 +333,15 @@ static int overlay_fixup_one_phandle(void *fdt, void *fdto, int symbols_off, const char *path, uint32_t path_len, const char *name, uint32_t name_len, - int poffset, const char *label) + int poffset, uint32_t phandle) { - const char *symbol_path; - uint32_t phandle; + (void)fdt; fdt32_t phandle_prop; - int symbol_off, fixup_off; - int prop_len; + int fixup_off; if (symbols_off < 0) return symbols_off; - symbol_path = fdt_getprop(fdt, symbols_off, label, - &prop_len); - if (!symbol_path) - return prop_len; - - symbol_off = fdt_path_offset(fdt, symbol_path); - if (symbol_off < 0) - return symbol_off; - - phandle = fdt_get_phandle(fdt, symbol_off); - if (!phandle) - return -FDT_ERR_NOTFOUND; - fixup_off = fdt_path_offset_namelen(fdto, path, (int)path_len); if (fixup_off == -FDT_ERR_NOTFOUND) return -FDT_ERR_BADOVERLAY; @@ -417,6 +380,10 @@ static int overlay_fixup_phandle(void *fdt, void *fdto, int symbols_off, const char *value; const char *label; int len; + const char *symbol_path; + int prop_len; + int symbol_off; + uint32_t phandle; value = fdt_getprop_by_offset(fdto, property, &label, &len); @@ -427,6 +394,18 @@ static int overlay_fixup_phandle(void *fdt, void *fdto, int symbols_off, return len; } + symbol_path = fdt_getprop(fdt, symbols_off, label, &prop_len); + if (!symbol_path) + return prop_len; + + symbol_off = fdt_path_offset(fdt, symbol_path); + if (symbol_off < 0) + return symbol_off; + + phandle = fdt_get_phandle(fdt, symbol_off); + if (!phandle) + return -FDT_ERR_NOTFOUND; + do { const char *path, *name, *fixup_end; const char *fixup_str = value; @@ -440,7 +419,7 @@ static int overlay_fixup_phandle(void *fdt, void *fdto, int symbols_off, return -FDT_ERR_BADOVERLAY; fixup_len = fixup_end - fixup_str; - len -= (int)(fixup_len + 1); + len -= fixup_len + 1; value += fixup_len + 1; path = fixup_str; @@ -468,7 +447,7 @@ static int overlay_fixup_phandle(void *fdt, void *fdto, int symbols_off, ret = overlay_fixup_one_phandle(fdt, fdto, symbols_off, path, path_len, name, name_len, - poffset, label); + poffset, phandle); if (ret) return ret; } while (len > 0); @@ -521,6 +500,255 @@ static int overlay_fixup_phandles(void *fdt, void *fdto) return 0; } +/** + * overlay_adjust_local_conflicting_phandle: Changes a phandle value + * @fdto: Device tree overlay + * @node: The node the phandle is set for + * @fdt_phandle: The new value for the phandle + * + * returns: + * 0 on success + * Negative error code on failure + */ +static int overlay_adjust_local_conflicting_phandle(void *fdto, int node, + uint32_t fdt_phandle) +{ + const fdt32_t *php; + int len, ret; + + php = fdt_getprop(fdto, node, "phandle", &len); + if (php && len == sizeof(*php)) { + ret = fdt_setprop_inplace_u32(fdto, node, "phandle", fdt_phandle); + if (ret) + return ret; + } + + php = fdt_getprop(fdto, node, "linux,phandle", &len); + if (php && len == sizeof(*php)) { + ret = fdt_setprop_inplace_u32(fdto, node, "linux,phandle", fdt_phandle); + if (ret) + return ret; + } + + return 0; +} + +/** + * overlay_update_node_conflicting_references - Recursively replace phandle values + * @fdto: Device tree overlay blob + * @tree_node: Node to recurse into + * @fixup_node: Node offset of the matching local fixups node + * @fdt_phandle: Value to replace phandles with + * @fdto_phandle: Value to be replaced + * + * Replaces all phandles with value @fdto_phandle by @fdt_phandle. + * + * returns: + * 0 on success + * Negative error code on failure + */ +static int overlay_update_node_conflicting_references(void *fdto, int tree_node, + int fixup_node, + uint32_t fdt_phandle, + uint32_t fdto_phandle) +{ + int fixup_prop; + int fixup_child; + int ret; + + fdt_for_each_property_offset(fixup_prop, fdto, fixup_node) { + const fdt32_t *fixup_val; + const char *name; + char *tree_val; + int fixup_len; + int tree_len; + int i; + + fixup_val = fdt_getprop_by_offset(fdto, fixup_prop, + &name, &fixup_len); + if (!fixup_val) + return fixup_len; + + if ((unsigned long)fixup_len % sizeof(uint32_t)) + return -FDT_ERR_BADOVERLAY; + fixup_len /= sizeof(uint32_t); + + tree_val = fdt_getprop_w(fdto, tree_node, name, &tree_len); + if (!tree_val) { + if (tree_len == -FDT_ERR_NOTFOUND) + return -FDT_ERR_BADOVERLAY; + + return tree_len; + } + + for (i = 0; i < fixup_len; i++) { + fdt32_t *refp; + uint32_t valp; + + refp = (fdt32_t *)(void *)(tree_val + fdt32_ld_(fixup_val + i)); + valp = fdt32_ld(refp); + + if (valp == fdto_phandle) + fdt32_st(refp, fdt_phandle); + } + } + + fdt_for_each_subnode(fixup_child, fdto, fixup_node) { + const char *fixup_child_name = fdt_get_name(fdto, fixup_child, NULL); + int tree_child; + + tree_child = fdt_subnode_offset(fdto, tree_node, fixup_child_name); + + if (tree_child == -FDT_ERR_NOTFOUND) + return -FDT_ERR_BADOVERLAY; + if (tree_child < 0) + return tree_child; + + ret = overlay_update_node_conflicting_references(fdto, tree_child, + fixup_child, + fdt_phandle, + fdto_phandle); + if (ret) + return ret; + } + + return 0; +} + +/** + * overlay_update_local_conflicting_references - Recursively replace phandle values + * @fdto: Device tree overlay blob + * @fdt_phandle: Value to replace phandles with + * @fdto_phandle: Value to be replaced + * + * Replaces all phandles with value @fdto_phandle by @fdt_phandle. + * + * returns: + * 0 on success + * Negative error code on failure + */ +static int overlay_update_local_conflicting_references(void *fdto, + uint32_t fdt_phandle, + uint32_t fdto_phandle) +{ + int fixups; + + fixups = fdt_path_offset(fdto, "/__local_fixups__"); + if (fixups == -FDT_ERR_NOTFOUND) + return 0; + if (fixups < 0) + return fixups; + + return overlay_update_node_conflicting_references(fdto, 0, fixups, + fdt_phandle, + fdto_phandle); +} + +/** + * overlay_prevent_phandle_overwrite_node - Helper function for overlay_prevent_phandle_overwrite + * @fdt: Base Device tree blob + * @fdtnode: Node in fdt that is checked for an overwrite + * @fdto: Device tree overlay blob + * @fdtonode: Node in fdto matching @fdtnode + * + * returns: + * 0 on success + * Negative error code on failure + */ +static int overlay_prevent_phandle_overwrite_node(void *fdt, int fdtnode, + void *fdto, int fdtonode) +{ + uint32_t fdt_phandle, fdto_phandle; + int fdtochild; + + fdt_phandle = fdt_get_phandle(fdt, fdtnode); + fdto_phandle = fdt_get_phandle(fdto, fdtonode); + + if (fdt_phandle && fdto_phandle) { + int ret; + + ret = overlay_adjust_local_conflicting_phandle(fdto, fdtonode, + fdt_phandle); + if (ret) + return ret; + + ret = overlay_update_local_conflicting_references(fdto, + fdt_phandle, + fdto_phandle); + if (ret) + return ret; + } + + fdt_for_each_subnode(fdtochild, fdto, fdtonode) { + const char *name = fdt_get_name(fdto, fdtochild, NULL); + int fdtchild; + int ret; + + fdtchild = fdt_subnode_offset(fdt, fdtnode, name); + if (fdtchild == -FDT_ERR_NOTFOUND) + /* + * no further overwrites possible here as this node is + * new + */ + continue; + + ret = overlay_prevent_phandle_overwrite_node(fdt, fdtchild, + fdto, fdtochild); + if (ret) + return ret; + } + + return 0; +} + +/** + * overlay_prevent_phandle_overwrite - Fixes overlay phandles to not overwrite base phandles + * @fdt: Base Device Tree blob + * @fdto: Device tree overlay blob + * + * Checks recursively if applying fdto overwrites phandle values in the base + * dtb. When such a phandle is found, the fdto is changed to use the fdt's + * phandle value to not break references in the base. + * + * returns: + * 0 on success + * Negative error code on failure + */ +static int overlay_prevent_phandle_overwrite(void *fdt, void *fdto) +{ + int fragment; + + fdt_for_each_subnode(fragment, fdto, 0) { + int overlay; + int target; + int ret; + + overlay = fdt_subnode_offset(fdto, fragment, "__overlay__"); + if (overlay == -FDT_ERR_NOTFOUND) + continue; + + if (overlay < 0) + return overlay; + + target = fdt_overlay_target_offset(fdt, fdto, fragment, NULL); + if (target == -FDT_ERR_NOTFOUND) + /* + * The subtree doesn't exist in the base, so nothing + * will be overwritten. + */ + continue; + else if (target < 0) + return target; + + ret = overlay_prevent_phandle_overwrite_node(fdt, target, + fdto, overlay); + if (ret) + return ret; + } + + return 0; +} + /** * overlay_apply_node - Merges a node into the base device tree * @fdt: Base Device Tree blob @@ -742,7 +970,7 @@ static int overlay_symbol_update(void *fdt, void *fdto) rel_path = s + len; rel_path_len = e - rel_path - 1; } else if ((e - s) == len - && (memcmp(s, "/__overlay__", (size_t)len - 1) == 0)) { + && (memcmp(s, "/__overlay__", (size_t)(len - 1)) == 0)) { /* //__overlay__ */ rel_path = ""; rel_path_len = 0; @@ -801,7 +1029,7 @@ static int overlay_symbol_update(void *fdt, void *fdto) if (ret < 0) return ret; } else - memcpy(buf, target_path, (unsigned long)len + 1); + memcpy(buf, target_path, (unsigned long)(len + 1)); } else len--; @@ -826,18 +1054,26 @@ int fdt_overlay_apply(void *fdt, void *fdto) if (ret) goto err; + /* Increase all phandles in the fdto by delta */ ret = overlay_adjust_local_phandles(fdto, delta); if (ret) goto err; + /* Adapt the phandle values in fdto to the above increase */ ret = overlay_update_local_references(fdto, delta); if (ret) goto err; + /* Update fdto's phandles using symbols from fdt */ ret = overlay_fixup_phandles(fdt, fdto); if (ret) goto err; + /* Don't overwrite phandles in fdt */ + ret = overlay_prevent_phandle_overwrite(fdt, fdto); + if (ret) + goto err; + ret = overlay_merge(fdt, fdto); if (ret) goto err; diff --git a/kernel/src/fdt/fdt_ro.c b/kernel/src/fdt/fdt_ro.c index 17c9cae..af8e7bc 100644 --- a/kernel/src/fdt/fdt_ro.c +++ b/kernel/src/fdt/fdt_ro.c @@ -68,7 +68,7 @@ const char *fdt_get_string(const void *fdt, int stroffset, int *lenp) len = fdt_size_dt_strings(fdt) - (uint32_t)stroffset; } } else if (fdt_magic(fdt) == FDT_SW_MAGIC) { - unsigned int sw_stroffset = -(unsigned)stroffset; + unsigned int sw_stroffset = (unsigned)-stroffset; if ((stroffset >= 0) || (sw_stroffset > fdt_size_dt_strings(fdt))) @@ -256,6 +256,9 @@ int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen) FDT_RO_PROBE(fdt); + if (!can_assume(VALID_INPUT) && namelen <= 0) + return -FDT_ERR_BADPATH; + /* see if we have an alias */ if (*path != '/') { const char *q = memchr(path, '/', (size_t)(end - p)); @@ -525,16 +528,31 @@ uint32_t fdt_get_phandle(const void *fdt, int nodeoffset) return fdt32_ld_(php); } +static const void *fdt_path_getprop_namelen(const void *fdt, const char *path, + const char *propname, int propnamelen, + int *lenp) +{ + int offset = fdt_path_offset(fdt, path); + + if (offset < 0) + return NULL; + + return fdt_getprop_namelen(fdt, offset, propname, propnamelen, lenp); +} + const char *fdt_get_alias_namelen(const void *fdt, const char *name, int namelen) { - int aliasoffset; + int len; + const char *alias; - aliasoffset = fdt_path_offset(fdt, "/aliases"); - if (aliasoffset < 0) + alias = fdt_path_getprop_namelen(fdt, "/aliases", name, namelen, &len); + + if (!can_assume(VALID_DTB) && + !(alias && len > 0 && alias[len - 1] == '\0' && *alias == '/')) return NULL; - return fdt_getprop_namelen(fdt, aliasoffset, name, namelen, NULL); + return alias; } const char *fdt_get_alias(const void *fdt, const char *name) @@ -542,6 +560,17 @@ const char *fdt_get_alias(const void *fdt, const char *name) return fdt_get_alias_namelen(fdt, name, strlen(name)); } +const char *fdt_get_symbol_namelen(const void *fdt, + const char *name, int namelen) +{ + return fdt_path_getprop_namelen(fdt, "/__symbols__", name, namelen, NULL); +} + +const char *fdt_get_symbol(const void *fdt, const char *name) +{ + return fdt_get_symbol_namelen(fdt, name, strlen(name)); +} + int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen) { int pdepth = 0, p = 0, tmp = 0; @@ -716,7 +745,7 @@ int fdt_stringlist_contains(const char *strlist, int listlen, const char *str) const char *p; while (listlen >= len) { - if (memcmp(str, strlist, (size_t)len+1) == 0) + if (memcmp(str, strlist, (size_t)(len+1)) == 0) return 1; p = memchr(strlist, '\0', (size_t)listlen); if (!p) diff --git a/kernel/src/fdt/fdt_rw.c b/kernel/src/fdt/fdt_rw.c index d558de7..7a26366 100644 --- a/kernel/src/fdt/fdt_rw.c +++ b/kernel/src/fdt/fdt_rw.c @@ -31,7 +31,7 @@ static int fdt_rw_probe_(void *fdt) if (!can_assume(LATEST) && fdt_version(fdt) < 17) return -FDT_ERR_BADVERSION; - if (fdt_blocks_misordered_(fdt, sizeof(struct fdt_reserve_entry), + if ((int)fdt_blocks_misordered_(fdt, sizeof(struct fdt_reserve_entry), (int)fdt_size_dt_struct(fdt))) return -FDT_ERR_BADLAYOUT; if (!can_assume(LATEST) && fdt_version(fdt) > 17) @@ -61,9 +61,9 @@ static int fdt_splice_(void *fdt, void *splicepoint, int oldlen, int newlen) if ((oldlen < 0) || (soff + (size_t)oldlen < soff) || (soff + (size_t)oldlen > dsize)) return -FDT_ERR_BADOFFSET; - if ((p < (char *)fdt) || (dsize + (unsigned)newlen < (unsigned)oldlen)) + if ((p < (char *)fdt) || (dsize + (unsigned int)newlen < (unsigned)oldlen)) return -FDT_ERR_BADOFFSET; - if (dsize - (unsigned)oldlen + (unsigned)newlen > fdt_totalsize(fdt)) + if (dsize - (unsigned)oldlen + (unsigned int)newlen > fdt_totalsize(fdt)) return -FDT_ERR_NOSPACE; memmove(p + newlen, p + oldlen, (unsigned long)((char *)fdt + dsize) - (unsigned long)(p + oldlen)); @@ -73,10 +73,10 @@ static int fdt_splice_(void *fdt, void *splicepoint, int oldlen, int newlen) static int fdt_splice_mem_rsv_(void *fdt, struct fdt_reserve_entry *p, int oldn, int newn) { - int delta = (unsigned long)(newn - oldn) * sizeof(*p); + int delta = (int)((unsigned long)(newn - oldn) * sizeof(*p)); int err; - err = fdt_splice_(fdt, p, (unsigned long)oldn * sizeof(*p), - (unsigned long)newn * sizeof(*p)); + err = fdt_splice_(fdt, p, (int)((unsigned long)oldn * sizeof(*p)), + (int)((unsigned long)newn * sizeof(*p))); if (err) return err; fdt_set_off_dt_struct(fdt, fdt_off_dt_struct(fdt) + (uint32_t)delta); @@ -256,7 +256,7 @@ int fdt_set_name(void *fdt, int nodeoffset, const char *name) if (err) return err; - memcpy(namep, name, (unsigned long)newlen+1); + memcpy(namep, name, (unsigned long)(newlen+1)); return 0; } @@ -364,7 +364,8 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset, } while ((tag == FDT_PROP) || (tag == FDT_NOP)); nh = fdt_offset_ptr_w_(fdt, offset); - nodelen = (int)(sizeof(*nh) + FDT_TAGALIGN((unsigned long)namelen+1) + + nodelen = + (int)(sizeof(*nh) + FDT_TAGALIGN((unsigned long)namelen+1) + FDT_TAGSIZE); err = fdt_splice_struct_(fdt, nh, 0, nodelen); @@ -436,8 +437,8 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize) FDT_RO_PROBE(fdt); - mem_rsv_size = (unsigned long)(fdt_num_mem_rsv(fdt)+1) - * sizeof(struct fdt_reserve_entry); + mem_rsv_size = (int)(((unsigned long)(fdt_num_mem_rsv(fdt)+1)) + * sizeof(struct fdt_reserve_entry)); if (can_assume(LATEST) || fdt_version(fdt) >= 17) { struct_size = (int)fdt_size_dt_struct(fdt); @@ -464,9 +465,8 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize) } /* Need to reorder */ - newsize = (int)FDT_ALIGN(sizeof(struct fdt_header), 8u + - (unsigned)mem_rsv_size + (unsigned)struct_size + - fdt_size_dt_strings(fdt)); + newsize = (int)FDT_ALIGN(sizeof(struct fdt_header), 8u) + mem_rsv_size + + struct_size + (int)fdt_size_dt_strings(fdt); if (bufsize < newsize) return -FDT_ERR_NOSPACE; diff --git a/kernel/src/fdt/fdt_strerror.c b/kernel/src/fdt/fdt_strerror.c index b8c2bf2..1574b23 100644 --- a/kernel/src/fdt/fdt_strerror.c +++ b/kernel/src/fdt/fdt_strerror.c @@ -12,49 +12,49 @@ #include "libfdt_internal.h" struct fdt_errtabent { - const char *str; + const char *str; }; #define FDT_ERRTABENT(val) \ - [(val)] = { .str = #val, } + [(val)] = { .str = #val, } static struct fdt_errtabent fdt_errtable[] = { - FDT_ERRTABENT(FDT_ERR_NOTFOUND), - FDT_ERRTABENT(FDT_ERR_EXISTS), - FDT_ERRTABENT(FDT_ERR_NOSPACE), - - FDT_ERRTABENT(FDT_ERR_BADOFFSET), - FDT_ERRTABENT(FDT_ERR_BADPATH), - FDT_ERRTABENT(FDT_ERR_BADPHANDLE), - FDT_ERRTABENT(FDT_ERR_BADSTATE), - - FDT_ERRTABENT(FDT_ERR_TRUNCATED), - FDT_ERRTABENT(FDT_ERR_BADMAGIC), - FDT_ERRTABENT(FDT_ERR_BADVERSION), - FDT_ERRTABENT(FDT_ERR_BADSTRUCTURE), - FDT_ERRTABENT(FDT_ERR_BADLAYOUT), - FDT_ERRTABENT(FDT_ERR_INTERNAL), - FDT_ERRTABENT(FDT_ERR_BADNCELLS), - FDT_ERRTABENT(FDT_ERR_BADVALUE), - FDT_ERRTABENT(FDT_ERR_BADOVERLAY), - FDT_ERRTABENT(FDT_ERR_NOPHANDLES), - FDT_ERRTABENT(FDT_ERR_BADFLAGS), - FDT_ERRTABENT(FDT_ERR_ALIGNMENT), + FDT_ERRTABENT(FDT_ERR_NOTFOUND), + FDT_ERRTABENT(FDT_ERR_EXISTS), + FDT_ERRTABENT(FDT_ERR_NOSPACE), + + FDT_ERRTABENT(FDT_ERR_BADOFFSET), + FDT_ERRTABENT(FDT_ERR_BADPATH), + FDT_ERRTABENT(FDT_ERR_BADPHANDLE), + FDT_ERRTABENT(FDT_ERR_BADSTATE), + + FDT_ERRTABENT(FDT_ERR_TRUNCATED), + FDT_ERRTABENT(FDT_ERR_BADMAGIC), + FDT_ERRTABENT(FDT_ERR_BADVERSION), + FDT_ERRTABENT(FDT_ERR_BADSTRUCTURE), + FDT_ERRTABENT(FDT_ERR_BADLAYOUT), + FDT_ERRTABENT(FDT_ERR_INTERNAL), + FDT_ERRTABENT(FDT_ERR_BADNCELLS), + FDT_ERRTABENT(FDT_ERR_BADVALUE), + FDT_ERRTABENT(FDT_ERR_BADOVERLAY), + FDT_ERRTABENT(FDT_ERR_NOPHANDLES), + FDT_ERRTABENT(FDT_ERR_BADFLAGS), + FDT_ERRTABENT(FDT_ERR_ALIGNMENT), }; -#define FDT_ERRTABSIZE ((int)(sizeof(fdt_errtable) / sizeof(fdt_errtable[0]))) +#define FDT_ERRTABSIZE ((int)(sizeof(fdt_errtable) / sizeof(fdt_errtable[0]))) const char *fdt_strerror(int errval) { - if (errval > 0) - return ""; - else if (errval == 0) - return ""; - else if (-errval < FDT_ERRTABSIZE) { - const char *s = fdt_errtable[-errval].str; - - if (s) - return s; - } - - return ""; + if (errval > 0) + return ""; + else if (errval == 0) + return ""; + else if (-errval < FDT_ERRTABSIZE) { + const char *s = fdt_errtable[-errval].str; + + if (s) + return s; + } + + return ""; } diff --git a/kernel/src/fdt/fdt_sw.c b/kernel/src/fdt/fdt_sw.c index f3e54a3..92d1de9 100644 --- a/kernel/src/fdt/fdt_sw.c +++ b/kernel/src/fdt/fdt_sw.c @@ -132,9 +132,9 @@ int fdt_create_with_flags(void *buf, int bufsize, uint32_t flags) fdt_set_version(fdt, FDT_LAST_SUPPORTED_VERSION); fdt_set_last_comp_version(fdt, flags); - fdt_set_totalsize(fdt, (uint32_t)bufsize); + fdt_set_totalsize(fdt, (uint32_t)bufsize); - fdt_set_off_mem_rsvmap(fdt, (uint32_t)hdrsize); + fdt_set_off_mem_rsvmap(fdt, hdrsize); fdt_set_off_dt_struct(fdt, fdt_off_mem_rsvmap(fdt)); fdt_set_off_dt_strings(fdt, 0); @@ -310,7 +310,8 @@ int fdt_property_placeholder(void *fdt, const char *name, int len, void **valp) if (nameoff == 0) return -FDT_ERR_NOSPACE; - prop = fdt_grab_space_(fdt, sizeof(*prop) + FDT_TAGALIGN((unsigned long)len)); + prop = fdt_grab_space_(fdt, + sizeof(*prop) + FDT_TAGALIGN((unsigned long)len)); if (! prop) { if (allocated) fdt_del_last_string_(fdt, name); diff --git a/kernel/src/fdt/fdt_wip.c b/kernel/src/fdt/fdt_wip.c index 4cd32fa..2064697 100644 --- a/kernel/src/fdt/fdt_wip.c +++ b/kernel/src/fdt/fdt_wip.c @@ -66,7 +66,7 @@ int fdt_nop_property(void *fdt, int nodeoffset, const char *name) if (!prop) return len; - fdt_nop_region_(prop, (unsigned long)len + sizeof(*prop)); + fdt_nop_region_(prop, (int)((unsigned long)len + sizeof(*prop))); return 0; } diff --git a/kernel/src/fdt/libfdt.h b/kernel/src/fdt/libfdt.h index be23599..d58251e 100644 --- a/kernel/src/fdt/libfdt.h +++ b/kernel/src/fdt/libfdt.h @@ -285,7 +285,7 @@ size_t fdt_header_size(const void *fdt); /** * fdt_header_size_ - internal function to get header size from a version number - * @version: devicetree version number + * @version: device tree version number * * Return: size of DTB header in bytes */ @@ -524,12 +524,37 @@ int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen); * level matching the given component, differentiated only by unit * address). * + * If the path is not absolute (i.e. does not begin with '/'), the + * first component is treated as an alias. That is, the property by + * that name is looked up in the /aliases node, and the value of that + * property used in place of that first component. + * + * For example, for this small fragment + * + * / { + * aliases { + * i2c2 = &foo; // RHS compiles to "/soc@0/i2c@30a40000/eeprom@52" + * }; + * soc@0 { + * foo: i2c@30a40000 { + * bar: eeprom@52 { + * }; + * }; + * }; + * }; + * + * these would be equivalent: + * + * /soc@0/i2c@30a40000/eeprom@52 + * i2c2/eeprom@52 + * * returns: * structure block offset of the node with the requested path (>=0), on * success - * -FDT_ERR_BADPATH, given path does not begin with '/' or is invalid + * -FDT_ERR_BADPATH, given path does not begin with '/' and the first + * component is not a valid alias * -FDT_ERR_NOTFOUND, if the requested node does not exist - * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_BADSTRUCTURE, @@ -574,7 +599,7 @@ const char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp); * structure block offset of the property (>=0), on success * -FDT_ERR_NOTFOUND, if the requested node has no properties * -FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_BEGIN_NODE tag - * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_BADSTRUCTURE, @@ -595,7 +620,7 @@ int fdt_first_property_offset(const void *fdt, int nodeoffset); * structure block offset of the next property (>=0), on success * -FDT_ERR_NOTFOUND, if the given property is the last in its node * -FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_PROP tag - * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_BADSTRUCTURE, @@ -739,7 +764,7 @@ static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset, * to within the device blob itself, not a copy of the value). If * lenp is non-NULL, the length of the property value is also * returned, in the integer pointed to by lenp. If namep is non-NULL, - * the property's namne will also be returned in the char * pointed to + * the property's name will also be returned in the char * pointed to * by namep (this will be a pointer to within the device tree's string * block, not a new copy of the name). * @@ -747,7 +772,7 @@ static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset, * pointer to the property's value * if lenp is non-NULL, *lenp contains the length of the property * value (>=0) - * if namep is non-NULL *namep contiains a pointer to the property + * if namep is non-NULL *namep contains a pointer to the property * name. * NULL, on error * if lenp is non-NULL, *lenp contains an error code (<0): @@ -841,7 +866,7 @@ uint32_t fdt_get_phandle(const void *fdt, int nodeoffset); /** * fdt_get_alias_namelen - get alias based on substring * @fdt: pointer to the device tree blob - * @name: name of the alias th look up + * @name: name of the alias to look up * @namelen: number of characters of name to consider * * Identical to fdt_get_alias(), but only examine the first @namelen @@ -858,7 +883,7 @@ const char *fdt_get_alias_namelen(const void *fdt, /** * fdt_get_alias - retrieve the path referenced by a given alias * @fdt: pointer to the device tree blob - * @name: name of the alias th look up + * @name: name of the alias to look up * * fdt_get_alias() retrieves the value of a given alias. That is, the * value of the property named @name in the node /aliases. @@ -869,6 +894,42 @@ const char *fdt_get_alias_namelen(const void *fdt, */ const char *fdt_get_alias(const void *fdt, const char *name); +/** + * fdt_get_symbol_namelen - get symbol based on substring + * @fdt: pointer to the device tree blob + * @name: name of the symbol to look up + * @namelen: number of characters of name to consider + * + * Identical to fdt_get_symbol(), but only examine the first @namelen + * characters of @name for matching the symbol name. + * + * Return: a pointer to the expansion of the symbol named @name, if it exists, + * NULL otherwise + */ +#ifndef SWIG /* Not available in Python */ +const char *fdt_get_symbol_namelen(const void *fdt, + const char *name, int namelen); +#endif + +/** + * fdt_get_symbol - retrieve the path referenced by a given symbol + * @fdt: pointer to the device tree blob + * @name: name of the symbol to look up + * + * fdt_get_symbol() retrieves the value of a given symbol. That is, + * the value of the property named @name in the node + * /__symbols__. Such a node exists only for a device tree blob that + * has been compiled with the -@ dtc option. Each property corresponds + * to a label appearing in the device tree source, with the name of + * the property being the label and the value being the full path of + * the node it is attached to. + * + * returns: + * a pointer to the expansion of the symbol named 'name', if it exists + * NULL, if the given symbol or the /__symbols__ node does not exist + */ +const char *fdt_get_symbol(const void *fdt, const char *name); + /** * fdt_get_path - determine the full path of a node * @fdt: pointer to the device tree blob @@ -1198,8 +1259,8 @@ const char *fdt_stringlist_get(const void *fdt, int nodeoffset, * * returns: * 0 <= n < FDT_MAX_NCELLS, on success - * 2, if the node has no #address-cells property - * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid + * 2, if the node has no #address-cells property + * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid * #address-cells property * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, @@ -1219,8 +1280,8 @@ int fdt_address_cells(const void *fdt, int nodeoffset); * * returns: * 0 <= n < FDT_MAX_NCELLS, on success - * 1, if the node has no #size-cells property - * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid + * 1, if the node has no #size-cells property + * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid * #size-cells property * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, @@ -1450,7 +1511,7 @@ int fdt_nop_node(void *fdt, int nodeoffset); * fdt_create_with_flags() begins the process of creating a new fdt with * the sequential write interface. * - * fdt creation process must end with fdt_finished() to produce a valid fdt. + * fdt creation process must end with fdt_finish() to produce a valid fdt. * * returns: * 0, on success @@ -1637,7 +1698,7 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name, * @len: length of the property value * @prop_data: return pointer to property data * - * fdt_setprop_placeholer() allocates the named property in the given node. + * fdt_setprop_placeholder() allocates the named property in the given node. * If the property exists it is resized. In either case a pointer to the * property data is returned. * @@ -1968,7 +2029,7 @@ static inline int fdt_appendprop_cell(void *fdt, int nodeoffset, * address and size) to the value of the named property in the given * node, or creates a new property with that value if it does not * already exist. - * If "name" is not specified, a default "reg" is used. + * * Cell sizes are determined by parent's #address-cells and #size-cells. * * This function may insert data into the blob, and will therefore @@ -1998,7 +2059,7 @@ int fdt_appendprop_addrrange(void *fdt, int parent, int nodeoffset, * @nodeoffset: offset of the node whose property to nop * @name: name of the property to nop * - * fdt_del_property() will delete the given property. + * fdt_delprop() will delete the given property. * * This function will delete data from the blob, and will therefore * change the offsets of some existing nodes. @@ -2050,8 +2111,7 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset, * change the offsets of some existing nodes. * * returns: - * structure block offset of the created nodeequested subnode (>=0), on - * success + * structure block offset of the created subnode (>=0), on success * -FDT_ERR_NOTFOUND, if the requested subnode does not exist * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE * tag @@ -2061,7 +2121,7 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset, * blob to contain the new node * -FDT_ERR_NOSPACE * -FDT_ERR_BADLAYOUT - * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_BADSTRUCTURE, @@ -2106,7 +2166,7 @@ int fdt_del_node(void *fdt, int nodeoffset); * returns: * 0, on success * -FDT_ERR_NOSPACE, there's not enough space in the base device tree - * -FDT_ERR_NOTFOUND, the overlay points to some inexistant nodes or + * -FDT_ERR_NOTFOUND, the overlay points to some nonexistent nodes or * properties in the base DT * -FDT_ERR_BADPHANDLE, * -FDT_ERR_BADOVERLAY, diff --git a/kernel/src/fdt/libfdt_internal.h b/kernel/src/fdt/libfdt_internal.h index edecde6..40a28a1 100644 --- a/kernel/src/fdt/libfdt_internal.h +++ b/kernel/src/fdt/libfdt_internal.h @@ -5,7 +5,6 @@ * libfdt - Flat Device Tree manipulation * Copyright (C) 2006 David Gibson, IBM Corporation. */ -#include "libfdt.h" #include "fdt.h" #define FDT_ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) @@ -38,7 +37,7 @@ static inline const struct fdt_reserve_entry *fdt_mem_rsv_(const void *fdt, int { const struct fdt_reserve_entry *rsv_table = (const struct fdt_reserve_entry *)(uint64_t) - ((const char *)fdt + fdt_off_mem_rsvmap(fdt)); + ((const char *)fdt + fdt_off_mem_rsvmap(fdt)); return rsv_table + n; } diff --git a/kernel/src/mm/early.c b/kernel/src/mm/early.c index a7607be..b789b11 100644 --- a/kernel/src/mm/early.c +++ b/kernel/src/mm/early.c @@ -22,9 +22,11 @@ struct freepage_list_info { struct list list; struct list asc_list; - // Number of available pages in this freepages_info struct. + // Number of available pages in this freepage_list_info struct. uint64_t avail_page_count; - // Count of contiguous pages, starting from this one + + // Count of contiguous pages, starting from this one, including the count of + // already allocated pages. uint64_t total_page_count; } __page_aligned; @@ -40,7 +42,7 @@ freepage_list_info_init(struct freepage_list_info *const info, } _Static_assert(sizeof(struct freepage_list_info) <= PAGE_SIZE, - "freepages_info struct must be small enough to store on a " + "freepage_list_info struct must be small enough to store on a " "single page"); // Use two lists of usuable pages: @@ -175,7 +177,7 @@ __debug_optimize(3) uint64_t early_alloc_page() { } // Take the last page out of the list, because the first page stores the - // freepages_info struct. + // freepage_list_info struct. const uint64_t free_page = virt_to_phys(info) + (info->avail_page_count << PAGE_SHIFT); @@ -679,7 +681,7 @@ static void mark_crucial_pages(const struct page_section *const memmap) { } } - // If we couldn't find a corresponding freepages_info struct, then this + // If we couldn't find a corresponding freepage_list_info struct, then this // entire memmap has been used, and needs to be marked as such. const uint64_t memmap_page_count = PAGE_COUNT(memmap->range.size);