diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/binman_sym.h | 51 | ||||
-rw-r--r-- | include/bloblist.h | 62 | ||||
-rw-r--r-- | include/dm/device.h | 25 | ||||
-rw-r--r-- | include/dm/ofnode.h | 66 | ||||
-rw-r--r-- | include/dm/root.h | 45 | ||||
-rw-r--r-- | include/dm/tag.h | 32 | ||||
-rw-r--r-- | include/dm/test.h | 7 | ||||
-rw-r--r-- | include/dm/util.h | 11 | ||||
-rw-r--r-- | include/os.h | 7 | ||||
-rw-r--r-- | include/spl.h | 2 |
10 files changed, 275 insertions, 33 deletions
diff --git a/include/binman_sym.h b/include/binman_sym.h index 72e6765fe5..528d7e4e90 100644 --- a/include/binman_sym.h +++ b/include/binman_sym.h @@ -11,9 +11,11 @@ #ifndef __BINMAN_SYM_H #define __BINMAN_SYM_H +/* BSYM in little endian, keep in sync with tools/binman/elf.py */ +#define BINMAN_SYM_MAGIC_VALUE (0x4d595342UL) #define BINMAN_SYM_MISSING (-1UL) -#ifdef CONFIG_BINMAN +#if CONFIG_IS_ENABLED(BINMAN_SYMBOLS) /** * binman_symname() - Internal function to get a binman symbol name @@ -63,6 +65,37 @@ section(".binman_sym"))) /** + * _binman_sym_magic - Internal magic symbol for validity checks + * + * When building images, binman fills in this symbol with the magic + * value #defined above. This is used to check at runtime if the + * symbol values were filled in and are OK to use. + */ +extern ulong _binman_sym_magic; + +/** + * DECLARE_BINMAN_MAGIC_SYM - Declare the internal magic symbol + * + * This macro declares the _binman_sym_magic symbol so that it exists. + * Declaring it here would cause errors during linking due to multiple + * definitions of the symbol. + */ +#define DECLARE_BINMAN_MAGIC_SYM \ + ulong _binman_sym_magic \ + __attribute__((aligned(4), section(".binman_sym"))) + +/** + * BINMAN_SYMS_OK - Check if the symbol values are valid + * + * This macro checks if the magic symbol's value is filled properly, + * which indicates that other symbols are OK to use as well. + * + * Return: 1 if binman symbol values are usable, 0 if not + */ +#define BINMAN_SYMS_OK \ + (*(ulong *)&_binman_sym_magic == BINMAN_SYM_MAGIC_VALUE) + +/** * binman_sym() - Access a previously declared symbol * * This is used to get the value of a symbol. E.g.: @@ -72,12 +105,16 @@ * @_type: Type f the symbol (e.g. unsigned long) * @entry_name: Name of the entry to look for (e.g. 'u_boot_spl') * @_prop_name: Property value to get from that entry (e.g. 'pos') - * @returns value of that property (filled in by binman) + * + * Return: value of that property (filled in by binman), or + * BINMAN_SYM_MISSING if the value is unavailable */ #define binman_sym(_type, _entry_name, _prop_name) \ - (*(_type *)&binman_symname(_entry_name, _prop_name)) + (BINMAN_SYMS_OK ? \ + (*(_type *)&binman_symname(_entry_name, _prop_name)) : \ + BINMAN_SYM_MISSING) -#else /* !BINMAN */ +#else /* !CONFIG_IS_ENABLED(BINMAN_SYMBOLS) */ #define binman_sym_declare(_type, _entry_name, _prop_name) @@ -85,8 +122,12 @@ #define binman_sym_extern(_type, _entry_name, _prop_name) +#define DECLARE_BINMAN_MAGIC_SYM + +#define BINMAN_SYMS_OK (0) + #define binman_sym(_type, _entry_name, _prop_name) BINMAN_SYM_MISSING -#endif /* BINMAN */ +#endif /* CONFIG_IS_ENABLED(BINMAN_SYMBOLS) */ #endif diff --git a/include/bloblist.h b/include/bloblist.h index d0e128acf1..9684bfd5f4 100644 --- a/include/bloblist.h +++ b/include/bloblist.h @@ -3,8 +3,66 @@ * This provides a standard way of passing information between boot phases * (TPL -> SPL -> U-Boot proper.) * - * A list of blobs of data, tagged with their owner. The list resides in memory - * and can be updated by SPL, U-Boot, etc. + * It consists of a list of blobs of data, tagged with their owner / contents. + * The list resides in memory and can be updated by SPL, U-Boot, etc. + * + * Design goals for bloblist: + * + * 1. Small and efficient structure. This avoids UUIDs or 16-byte name fields, + * since a 32-bit tag provides enough space for all the tags we will even need. + * If UUIDs are desired, they can be added inside a particular blob. + * + * 2. Avoids use of pointers, so the structure can be relocated in memory. The + * data in each blob is inline, rather than using pointers. + * + * 3. Bloblist is designed to start small in TPL or SPL, when only a few things + * are needed, like the memory size or whether console output should be enabled. + * Then it can grow in U-Boot proper, e.g. to include space for ACPI tables. + * + * 4. The bloblist structure is simple enough that it can be implemented in a + * small amount of C code. The API does not require use of strings or UUIDs, + * which would add to code size. For Thumb-2 the code size needed in SPL is + * approximately 940 bytes (e.g. for chromebook_bob). + * + * 5. Bloblist uses 16-byte alignment internally and is designed to start on a + * 16-byte boundary. Its headers are multiples of 16 bytes. This makes it easier + * to deal with data structures which need this level of alignment, such as ACPI + * tables. For use in SPL and TPL the alignment can be relaxed, since it can be + * relocated to an aligned address in U-Boot proper. + * + * 6. Bloblist is designed to be passed to Linux as reserved memory. While linux + * doesn't understand the bloblist header, it can be passed the indivdual blobs. + * For example, ACPI tables can reside in a blob and the address of those is + * passed to Linux, without Linux ever being away of the existence of a + * bloblist. Having all the blobs contiguous in memory simplifies the + * reserved-memory space. + * + * 7. Bloblist tags are defined in the enum below. There is an area for + * project-specific stuff (e.g. U-Boot, TF-A) and vendor-specific stuff, e.g. + * something used only on a particular SoC. There is also a private area for + * temporary, local use. + * + * 8. Bloblist includes a simple checksum, so that each boot phase can update + * this and allow the next phase to check that all is well. While the bloblist + * is small, this is quite cheap to calculate. When it grows (e.g. in U-Boot\ + * proper), the CPU is likely running faster, so it is not prohibitive. Having + * said that, U-Boot is often the last phase that uses bloblist, so calculating + * the checksum there may not be necessary. + * + * 9. It would be possible to extend bloblist to support a non-contiguous + * structure, e.g. by creating a blob type that points to the next bloblist. + * This does not seem necessary for now. It adds complexity and code. We can + * always just copy it. + * + * 10. Bloblist is designed for simple structures, those that can be defined by + * a single C struct. More complex structures should be passed in a device tree. + * There are some exceptions, chiefly the various binary structures that Intel + * is fond of creating. But device tree provides a dictionary-type format which + * is fairly efficient (for use in U-Boot proper and Linux at least), along with + * a schema and a good set of tools. New formats should be designed around + * device tree rather than creating new binary formats, unless they are needed + * early in boot (where libfdt's 3KB of overhead is too large) and are trival + * enough to be described by a C struct. * * Copyright 2018 Google, Inc * Written by Simon Glass <sjg@chromium.org> diff --git a/include/dm/device.h b/include/dm/device.h index 5bdb10653f..12c6ba37ff 100644 --- a/include/dm/device.h +++ b/include/dm/device.h @@ -11,6 +11,7 @@ #define _DM_DEVICE_H #include <dm/ofnode.h> +#include <dm/tag.h> #include <dm/uclass-id.h> #include <fdtdec.h> #include <linker_lists.h> @@ -547,6 +548,30 @@ void *dev_get_parent_priv(const struct udevice *dev); void *dev_get_uclass_priv(const struct udevice *dev); /** + * dev_get_attach_ptr() - Get the value of an attached pointed tag + * + * The tag is assumed to hold a pointer, if it exists + * + * @dev: Device to look at + * @tag: Tag to access + * @return value of tag, or NULL if there is no tag of this type + */ +void *dev_get_attach_ptr(const struct udevice *dev, enum dm_tag_t tag); + +/** + * dev_get_attach_size() - Get the size of an attached tag + * + * Core tags have an automatic-allocation mechanism where the allocated size is + * defined by the device, parent or uclass. This returns the size associated + * with a particular tag + * + * @dev: Device to look at + * @tag: Tag to access + * @return size of auto-allocated data, 0 if none + */ +int dev_get_attach_size(const struct udevice *dev, enum dm_tag_t tag); + +/** * dev_get_parent() - Get the parent of a device * * @child: Child to check diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 2c4d72d77f..bb60433124 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -1182,6 +1182,33 @@ int ofnode_write_string(ofnode node, const char *propname, const char *value); int ofnode_set_enabled(ofnode node, bool value); /** + * ofnode_get_phy_node() - Get PHY node for a MAC (if not fixed-link) + * + * This function parses PHY handle from the Ethernet controller's ofnode + * (trying all possible PHY handle property names), and returns the PHY ofnode. + * + * Before this is used, ofnode_phy_is_fixed_link() should be checked first, and + * if the result to that is true, this function should not be called. + * + * @eth_node: ofnode belonging to the Ethernet controller + * Return: ofnode of the PHY, if it exists, otherwise an invalid ofnode + */ +ofnode ofnode_get_phy_node(ofnode eth_node); + +/** + * ofnode_read_phy_mode() - Read PHY connection type from a MAC node + * + * This function parses the "phy-mode" / "phy-connection-type" property and + * returns the corresponding PHY interface type. + * + * @mac_node: ofnode containing the property + * Return: one of PHY_INTERFACE_MODE_* constants, PHY_INTERFACE_MODE_NA on + * error + */ +phy_interface_t ofnode_read_phy_mode(ofnode mac_node); + +#if CONFIG_IS_ENABLED(DM) +/** * ofnode_conf_read_bool() - Read a boolean value from the U-Boot config * * This reads a property from the /config node of the devicetree. @@ -1218,30 +1245,21 @@ int ofnode_conf_read_int(const char *prop_name, int default_val); */ const char *ofnode_conf_read_str(const char *prop_name); -/** - * ofnode_get_phy_node() - Get PHY node for a MAC (if not fixed-link) - * - * This function parses PHY handle from the Ethernet controller's ofnode - * (trying all possible PHY handle property names), and returns the PHY ofnode. - * - * Before this is used, ofnode_phy_is_fixed_link() should be checked first, and - * if the result to that is true, this function should not be called. - * - * @eth_node: ofnode belonging to the Ethernet controller - * Return: ofnode of the PHY, if it exists, otherwise an invalid ofnode - */ -ofnode ofnode_get_phy_node(ofnode eth_node); +#else /* CONFIG_DM */ +static inline bool ofnode_conf_read_bool(const char *prop_name) +{ + return false; +} -/** - * ofnode_read_phy_mode() - Read PHY connection type from a MAC node - * - * This function parses the "phy-mode" / "phy-connection-type" property and - * returns the corresponding PHY interface type. - * - * @mac_node: ofnode containing the property - * Return: one of PHY_INTERFACE_MODE_* constants, PHY_INTERFACE_MODE_NA on - * error - */ -phy_interface_t ofnode_read_phy_mode(ofnode mac_node); +static inline int ofnode_conf_read_int(const char *prop_name, int default_val) +{ + return default_val; +} + +static inline const char *ofnode_conf_read_str(const char *prop_name) +{ + return NULL; +} +#endif /* CONFIG_DM */ #endif diff --git a/include/dm/root.h b/include/dm/root.h index e888fb993c..b2f30a842f 100644 --- a/include/dm/root.h +++ b/include/dm/root.h @@ -9,12 +9,50 @@ #ifndef _DM_ROOT_H_ #define _DM_ROOT_H_ +#include <dm/tag.h> + struct udevice; /* Head of the uclass list if CONFIG_OF_PLATDATA_INST is enabled */ extern struct list_head uclass_head; /** + * struct dm_stats - Information about driver model memory usage + * + * @total_size: All data + * @dev_count: Number of devices + * @dev_size: Size of all devices (just the struct udevice) + * @dev_name_size: Bytes used by device names + * @uc_count: Number of uclasses + * @uc_size: Size of all uclasses (just the struct uclass) + * @tag_count: Number of tags + * @tag_size: Bytes used by all tags + * @uc_attach_count: Number of uclasses with attached data (priv) + * @uc_attach_size: Total size of that attached data + * @attach_count_total: Total number of attached data items for all udevices and + * uclasses + * @attach_size_total: Total number of bytes of attached data + * @attach_count: Number of devices with attached, for each type + * @attach_size: Total number of bytes of attached data, for each type + */ +struct dm_stats { + int total_size; + int dev_count; + int dev_size; + int dev_name_size; + int uc_count; + int uc_size; + int tag_count; + int tag_size; + int uc_attach_count; + int uc_attach_size; + int attach_count_total; + int attach_size_total; + int attach_count[DM_TAG_ATTACH_COUNT]; + int attach_size[DM_TAG_ATTACH_COUNT]; +}; + +/** * dm_root() - Return pointer to the top of the driver tree * * This function returns pointer to the root node of the driver tree, @@ -141,4 +179,11 @@ static inline int dm_remove_devices_flags(uint flags) { return 0; } */ void dm_get_stats(int *device_countp, int *uclass_countp); +/** + * dm_get_mem() - Get stats on memory usage in driver model + * + * @stats: Place to put the information + */ +void dm_get_mem(struct dm_stats *stats); + #endif diff --git a/include/dm/tag.h b/include/dm/tag.h index 54fc31eb15..745088ffcf 100644 --- a/include/dm/tag.h +++ b/include/dm/tag.h @@ -10,11 +10,23 @@ #include <linux/list.h> #include <linux/types.h> +struct dm_stats; struct udevice; enum dm_tag_t { + /* Types of core tags that can be attached to devices */ + DM_TAG_PLAT, + DM_TAG_PARENT_PLAT, + DM_TAG_UC_PLAT, + + DM_TAG_PRIV, + DM_TAG_PARENT_PRIV, + DM_TAG_UC_PRIV, + DM_TAG_DRIVER_DATA, + DM_TAG_ATTACH_COUNT, + /* EFI_LOADER */ - DM_TAG_EFI = 0, + DM_TAG_EFI = DM_TAG_ATTACH_COUNT, DM_TAG_COUNT, }; @@ -107,4 +119,22 @@ int dev_tag_del(struct udevice *dev, enum dm_tag_t tag); */ int dev_tag_del_all(struct udevice *dev); +/** + * dev_tag_collect_stats() - Collect information on driver model performance + * + * This collects information on how driver model is performing. For now it only + * includes memory usage + * + * @stats: Place to put the collected information + */ +void dev_tag_collect_stats(struct dm_stats *stats); + +/** + * tag_get_name() - Get the name of a tag + * + * @tag: Tag to look up, which must be valid + * Returns: Name of tag + */ +const char *tag_get_name(enum dm_tag_t tag); + #endif /* _DM_TAG_H */ diff --git a/include/dm/test.h b/include/dm/test.h index 4919064cc0..b593750921 100644 --- a/include/dm/test.h +++ b/include/dm/test.h @@ -93,6 +93,13 @@ struct dm_test_uclass_priv { }; /** + * struct dm_test_uclass_plat - private plat data for test uclass + */ +struct dm_test_uclass_plat { + char dummy[32]; +}; + +/** * struct dm_test_parent_data - parent's information on each child * * @sum: Test value used to check parent data works correctly diff --git a/include/dm/util.h b/include/dm/util.h index 4428f045b7..e10c6060ce 100644 --- a/include/dm/util.h +++ b/include/dm/util.h @@ -6,6 +6,8 @@ #ifndef __DM_UTIL_H #define __DM_UTIL_H +struct dm_stats; + #if CONFIG_IS_ENABLED(DM_WARN) #define dm_warn(fmt...) log(LOGC_DM, LOGL_WARNING, ##fmt) #else @@ -25,7 +27,7 @@ struct list_head; int list_count_items(struct list_head *head); /* Dump out a tree of all devices */ -void dm_dump_all(void); +void dm_dump_tree(void); /* Dump out a list of uclasses and their devices */ void dm_dump_uclass(void); @@ -48,6 +50,13 @@ void dm_dump_driver_compat(void); /* Dump out a list of drivers with static platform data */ void dm_dump_static_driver_info(void); +/** + * dm_dump_mem() - Dump stats on memory usage in driver model + * + * @mem: Stats to dump + */ +void dm_dump_mem(struct dm_stats *stats); + #if CONFIG_IS_ENABLED(OF_PLATDATA_INST) && CONFIG_IS_ENABLED(READ_ONLY) void *dm_priv_to_rw(void *priv); #else diff --git a/include/os.h b/include/os.h index 10e198cf50..148178787b 100644 --- a/include/os.h +++ b/include/os.h @@ -17,6 +17,13 @@ struct rtc_time; struct sandbox_state; /** + * os_printf() - print directly to OS console + * + * @format: format string + */ +int os_printf(const char *format, ...); + +/** * Access to the OS read() system call * * @fd: File descriptor as returned by os_open() diff --git a/include/spl.h b/include/spl.h index cc78bc3e31..aac6648f94 100644 --- a/include/spl.h +++ b/include/spl.h @@ -288,6 +288,8 @@ binman_sym_extern(ulong, u_boot_any, image_pos); binman_sym_extern(ulong, u_boot_any, size); binman_sym_extern(ulong, u_boot_spl, image_pos); binman_sym_extern(ulong, u_boot_spl, size); +binman_sym_extern(ulong, u_boot_vpl, image_pos); +binman_sym_extern(ulong, u_boot_vpl, size); /** * spl_get_image_pos() - get the image position of the next phase |