diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/cachedhcp.c | 75 | ||||
-rw-r--r-- | src/core/image.c | 11 | ||||
-rw-r--r-- | src/core/main.c | 3 | ||||
-rw-r--r-- | src/core/mp.c | 67 | ||||
-rw-r--r-- | src/core/null_mp.c | 37 | ||||
-rw-r--r-- | src/core/settings.c | 107 |
6 files changed, 284 insertions, 16 deletions
diff --git a/src/core/cachedhcp.c b/src/core/cachedhcp.c index 57226e16..04945e64 100644 --- a/src/core/cachedhcp.c +++ b/src/core/cachedhcp.c @@ -46,11 +46,20 @@ struct cached_dhcp_packet { struct dhcp_packet *dhcppkt; /** VLAN tag (if applicable) */ unsigned int vlan; + /** Flags */ + unsigned int flags; }; +/** Cached DHCP packet should be retained */ +#define CACHEDHCP_RETAIN 0x0001 + +/** Cached DHCP packet has been used */ +#define CACHEDHCP_USED 0x0002 + /** Cached DHCPACK */ struct cached_dhcp_packet cached_dhcpack = { .name = DHCP_SETTINGS_NAME, + .flags = CACHEDHCP_RETAIN, }; /** Cached ProxyDHCPOFFER */ @@ -101,8 +110,8 @@ static int cachedhcp_apply ( struct cached_dhcp_packet *cache, size_t ll_addr_len; int rc; - /* Do nothing if cache is empty */ - if ( ! cache->dhcppkt ) + /* Do nothing if cache is empty or already in use */ + if ( ( ! cache->dhcppkt ) || ( cache->flags & CACHEDHCP_USED ) ) return 0; chaddr = cache->dhcppkt->dhcphdr->chaddr; @@ -169,8 +178,12 @@ static int cachedhcp_apply ( struct cached_dhcp_packet *cache, return rc; } - /* Free cached DHCP packet */ - cachedhcp_free ( cache ); + /* Mark as used */ + cache->flags |= CACHEDHCP_USED; + + /* Free cached DHCP packet, if applicable */ + if ( ! ( cache->flags & CACHEDHCP_RETAIN ) ) + cachedhcp_free ( cache ); return 0; } @@ -246,10 +259,10 @@ int cachedhcp_record ( struct cached_dhcp_packet *cache, unsigned int vlan, } /** - * Cached DHCP packet startup function + * Cached DHCP packet early startup function * */ -static void cachedhcp_startup ( void ) { +static void cachedhcp_startup_early ( void ) { /* Apply cached ProxyDHCPOFFER, if any */ cachedhcp_apply ( &cached_proxydhcp, NULL ); @@ -258,6 +271,20 @@ static void cachedhcp_startup ( void ) { /* Apply cached PXEBSACK, if any */ cachedhcp_apply ( &cached_pxebs, NULL ); cachedhcp_free ( &cached_pxebs ); +} + +/** + * Cache DHCP packet late startup function + * + */ +static void cachedhcp_startup_late ( void ) { + + /* Clear retention flag */ + cached_dhcpack.flags &= ~CACHEDHCP_RETAIN; + + /* Free cached DHCPACK, if used by a network device */ + if ( cached_dhcpack.flags & CACHEDHCP_USED ) + cachedhcp_free ( &cached_dhcpack ); /* Report unclaimed DHCPACK, if any. Do not free yet, since * it may still be claimed by a dynamically created device @@ -284,10 +311,16 @@ static void cachedhcp_shutdown ( int booting __unused ) { cachedhcp_free ( &cached_dhcpack ); } -/** Cached DHCPACK startup function */ -struct startup_fn cachedhcp_startup_fn __startup_fn ( STARTUP_LATE ) = { - .name = "cachedhcp", - .startup = cachedhcp_startup, +/** Cached DHCP packet early startup function */ +struct startup_fn cachedhcp_early_fn __startup_fn ( STARTUP_EARLY ) = { + .name = "cachedhcp1", + .startup = cachedhcp_startup_early, +}; + +/** Cached DHCP packet late startup function */ +struct startup_fn cachedhcp_late_fn __startup_fn ( STARTUP_LATE ) = { + .name = "cachedhcp2", + .startup = cachedhcp_startup_late, .shutdown = cachedhcp_shutdown, }; @@ -309,3 +342,25 @@ struct net_driver cachedhcp_driver __net_driver = { .name = "cachedhcp", .probe = cachedhcp_probe, }; + +/** + * Recycle cached DHCPACK + * + * @v netdev Network device + * @v priv Private data + */ +void cachedhcp_recycle ( struct net_device *netdev ) { + struct cached_dhcp_packet *cache = &cached_dhcpack; + struct settings *settings; + + /* Return DHCPACK to cache, if applicable */ + settings = find_child_settings ( netdev_settings ( netdev ), + cache->name ); + if ( cache->dhcppkt && ( settings == &cache->dhcppkt->settings ) ) { + DBGC ( colour, "CACHEDHCP %s recycled from %s\n", + cache->name, netdev->name ); + assert ( cache->flags & CACHEDHCP_USED ); + unregister_settings ( settings ); + cache->flags &= ~CACHEDHCP_USED; + } +} diff --git a/src/core/image.c b/src/core/image.c index 3e65b5ed..bf0e4f75 100644 --- a/src/core/image.c +++ b/src/core/image.c @@ -134,10 +134,13 @@ int image_set_uri ( struct image *image, struct uri *uri ) { int rc; /* Set name, if image does not already have one */ - if ( uri->path && ( ! ( image->name && image->name[0] ) ) ) { - name = basename ( ( char * ) uri->path ); - if ( ( rc = image_set_name ( image, name ) ) != 0 ) - return rc; + if ( ! ( image->name && image->name[0] ) ) { + name = ( uri->path ? uri->path : uri->opaque ); + if ( name ) { + name = basename ( ( char * ) name ); + if ( ( rc = image_set_name ( image, name ) ) != 0 ) + return rc; + } } /* Update image URI */ diff --git a/src/core/main.c b/src/core/main.c index 638dea9c..3db83649 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -32,9 +32,8 @@ __asmcall int main ( void ) { initialise(); /* Some devices take an unreasonably long time to initialise */ - printf ( "%s initialising devices...", product_short_name ); + printf ( "%s initialising devices...\n", product_short_name ); startup(); - printf ( "ok\n" ); /* Attempt to boot */ if ( ( rc = ipxe ( NULL ) ) != 0 ) diff --git a/src/core/mp.c b/src/core/mp.c new file mode 100644 index 00000000..146d70a6 --- /dev/null +++ b/src/core/mp.c @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2024 Michael Brown <mbrown@fensystems.co.uk>. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +/** @file + * + * Multiprocessor functions + * + */ + +#include <ipxe/timer.h> +#include <ipxe/mp.h> + +/** Time to wait for application processors */ +#define MP_MAX_CPUID_WAIT_MS 10 + +/** + * Get boot CPU identifier + * + * @ret id Boot CPU identifier + */ +unsigned int mp_boot_cpuid ( void ) { + unsigned int max = 0; + + /* Update maximum to accommodate boot processor */ + mp_exec_boot ( mp_update_max_cpuid, &max ); + DBGC ( &mp_call, "MP boot processor ID is %#x\n", max ); + + return max; +} + +/** + * Get maximum CPU identifier + * + * @ret max Maximum CPU identifier + */ +unsigned int mp_max_cpuid ( void ) { + unsigned int max = mp_boot_cpuid(); + + /* Update maximum to accommodate application processors */ + mp_start_all ( mp_update_max_cpuid, &max ); + mdelay ( MP_MAX_CPUID_WAIT_MS ); + DBGC ( &mp_call, "MP observed maximum CPU ID is %#x\n", max ); + + return max; +} diff --git a/src/core/null_mp.c b/src/core/null_mp.c new file mode 100644 index 00000000..0fa69303 --- /dev/null +++ b/src/core/null_mp.c @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2024 Michael Brown <mbrown@fensystems.co.uk>. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +/** + * @file + * + * Null multiprocessor API + * + */ + +#include <ipxe/mp.h> + +PROVIDE_MPAPI_INLINE ( null, mp_address ); +PROVIDE_MPAPI_INLINE ( null, mp_exec_boot ); +PROVIDE_MPAPI_INLINE ( null, mp_start_all ); diff --git a/src/core/settings.c b/src/core/settings.c index bece1afe..aa4bbae2 100644 --- a/src/core/settings.c +++ b/src/core/settings.c @@ -2698,6 +2698,113 @@ struct builtin_setting unixtime_builtin_setting __builtin_setting = { }; /** + * Fetch current working URI-related setting + * + * @v data Buffer to fill with setting data + * @v len Length of buffer + * @v rel Relative URI string + * @ret len Length of setting data, or negative error + */ +static int cwuri_fetch_uri ( void *data, size_t len, const char *rel ) { + struct uri *reluri; + struct uri *uri; + char *uristring; + int ret; + + /* Check that current working URI is set */ + if ( ! cwuri ) { + ret = -ENOENT; + goto err_unset; + } + + /* Construct relative URI */ + reluri = parse_uri ( rel ); + if ( ! reluri ) { + ret = -ENOMEM; + goto err_parse; + } + + /* Construct resolved URI */ + uri = resolve_uri ( cwuri, reluri ); + if ( ! uri ) { + ret = -ENOMEM; + goto err_resolve; + } + + /* Format URI string into allocated buffer (with NUL) */ + uristring = format_uri_alloc ( uri ); + if ( ! uristring ) { + ret = -ENOMEM; + goto err_format; + } + + /* Copy URI string to buffer */ + strncpy ( data, uristring, len ); + ret = strlen ( uristring ); + + free ( uristring ); + err_format: + uri_put ( uri ); + err_resolve: + uri_put ( reluri ); + err_parse: + err_unset: + return ret; +} + +/** + * Fetch current working URI setting + * + * @v data Buffer to fill with setting data + * @v len Length of buffer + * @ret len Length of setting data, or negative error + */ +static int cwuri_fetch ( void *data, size_t len ) { + + return cwuri_fetch_uri ( data, len, "" ); +} + +/** + * Fetch current working directory URI setting + * + * @v data Buffer to fill with setting data + * @v len Length of buffer + * @ret len Length of setting data, or negative error + */ +static int cwduri_fetch ( void *data, size_t len ) { + + return cwuri_fetch_uri ( data, len, "." ); +} + +/** Current working URI setting */ +const struct setting cwuri_setting __setting ( SETTING_MISC, cwuri ) = { + .name = "cwuri", + .description = "Current working URI", + .type = &setting_type_string, + .scope = &builtin_scope, +}; + +/** Current working directory URI setting */ +const struct setting cwduri_setting __setting ( SETTING_MISC, cwduri ) = { + .name = "cwduri", + .description = "Current working directory URI", + .type = &setting_type_string, + .scope = &builtin_scope, +}; + +/** Current working URI built-in setting */ +struct builtin_setting cwuri_builtin_setting __builtin_setting = { + .setting = &cwuri_setting, + .fetch = cwuri_fetch, +}; + +/** Current working directory URI built-in setting */ +struct builtin_setting cwduri_builtin_setting __builtin_setting = { + .setting = &cwduri_setting, + .fetch = cwduri_fetch, +}; + +/** * Fetch built-in setting * * @v settings Settings block |