efi_loader: efi_device_path: Pass net udevice as argument
In preparation to support multiple EFI net objects, support constructing device paths using an ethernet device different than the default. Add a udevice argument to the device path generation, and keep the callsites with eth_get_dev() to preserve existing functionality. Signed-off-by: Adriano Cordova <adriano.cordova@canonical.com>
This commit is contained in:

committed by
Heinrich Schuchardt

parent
6a832d4b2e
commit
267b0a7ddf
@@ -925,8 +925,8 @@ struct efi_device_path *efi_dp_from_part(struct blk_desc *desc, int part);
|
|||||||
struct efi_device_path *efi_dp_part_node(struct blk_desc *desc, int part);
|
struct efi_device_path *efi_dp_part_node(struct blk_desc *desc, int part);
|
||||||
struct efi_device_path *efi_dp_from_file(const struct efi_device_path *dp,
|
struct efi_device_path *efi_dp_from_file(const struct efi_device_path *dp,
|
||||||
const char *path);
|
const char *path);
|
||||||
struct efi_device_path *efi_dp_from_eth(void);
|
struct efi_device_path *efi_dp_from_eth(struct udevice *dev);
|
||||||
struct efi_device_path *efi_dp_from_http(const char *server);
|
struct efi_device_path *efi_dp_from_http(const char *server, struct udevice *dev);
|
||||||
struct efi_device_path *efi_dp_from_mem(uint32_t mem_type,
|
struct efi_device_path *efi_dp_from_mem(uint32_t mem_type,
|
||||||
uint64_t start_address,
|
uint64_t start_address,
|
||||||
size_t size);
|
size_t size);
|
||||||
|
@@ -954,20 +954,20 @@ struct efi_device_path *efi_dp_from_uart(void)
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct efi_device_path __maybe_unused *efi_dp_from_eth(void)
|
struct efi_device_path __maybe_unused *efi_dp_from_eth(struct udevice *dev)
|
||||||
{
|
{
|
||||||
void *buf, *start;
|
void *buf, *start;
|
||||||
unsigned dpsize = 0;
|
unsigned dpsize = 0;
|
||||||
|
|
||||||
assert(eth_get_dev());
|
assert(dev);
|
||||||
|
|
||||||
dpsize += dp_size(eth_get_dev());
|
dpsize += dp_size(dev);
|
||||||
|
|
||||||
start = buf = efi_alloc(dpsize + sizeof(END));
|
start = buf = efi_alloc(dpsize + sizeof(END));
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
buf = dp_fill(buf, eth_get_dev());
|
buf = dp_fill(buf, dev);
|
||||||
|
|
||||||
*((struct efi_device_path *)buf) = END;
|
*((struct efi_device_path *)buf) = END;
|
||||||
|
|
||||||
@@ -984,11 +984,13 @@ struct efi_device_path __maybe_unused *efi_dp_from_eth(void)
|
|||||||
* @ip: IPv4 local address
|
* @ip: IPv4 local address
|
||||||
* @mask: network mask
|
* @mask: network mask
|
||||||
* @srv: IPv4 remote/server address
|
* @srv: IPv4 remote/server address
|
||||||
|
* @dev: net udevice
|
||||||
* Return: pointer to device path, NULL on error
|
* Return: pointer to device path, NULL on error
|
||||||
*/
|
*/
|
||||||
static struct efi_device_path *efi_dp_from_ipv4(struct efi_ipv4_address *ip,
|
static struct efi_device_path *efi_dp_from_ipv4(struct efi_ipv4_address *ip,
|
||||||
struct efi_ipv4_address *mask,
|
struct efi_ipv4_address *mask,
|
||||||
struct efi_ipv4_address *srv)
|
struct efi_ipv4_address *srv,
|
||||||
|
struct udevice *dev)
|
||||||
{
|
{
|
||||||
struct efi_device_path *dp1, *dp2, *pos;
|
struct efi_device_path *dp1, *dp2, *pos;
|
||||||
struct {
|
struct {
|
||||||
@@ -1010,7 +1012,7 @@ static struct efi_device_path *efi_dp_from_ipv4(struct efi_ipv4_address *ip,
|
|||||||
pos = &dp.end;
|
pos = &dp.end;
|
||||||
memcpy(pos, &END, sizeof(END));
|
memcpy(pos, &END, sizeof(END));
|
||||||
|
|
||||||
dp1 = efi_dp_from_eth();
|
dp1 = efi_dp_from_eth(dev);
|
||||||
if (!dp1)
|
if (!dp1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@@ -1029,9 +1031,10 @@ static struct efi_device_path *efi_dp_from_ipv4(struct efi_ipv4_address *ip,
|
|||||||
* and an END node.
|
* and an END node.
|
||||||
*
|
*
|
||||||
* @server: URI of remote server
|
* @server: URI of remote server
|
||||||
|
* @dev: net udevice
|
||||||
* Return: pointer to HTTP device path, NULL on error
|
* Return: pointer to HTTP device path, NULL on error
|
||||||
*/
|
*/
|
||||||
struct efi_device_path *efi_dp_from_http(const char *server)
|
struct efi_device_path *efi_dp_from_http(const char *server, struct udevice *dev)
|
||||||
{
|
{
|
||||||
struct efi_device_path *dp1, *dp2;
|
struct efi_device_path *dp1, *dp2;
|
||||||
struct efi_device_path_uri *uridp;
|
struct efi_device_path_uri *uridp;
|
||||||
@@ -1047,10 +1050,11 @@ struct efi_device_path *efi_dp_from_http(const char *server)
|
|||||||
|
|
||||||
efi_net_get_addr(&ip, &mask, NULL);
|
efi_net_get_addr(&ip, &mask, NULL);
|
||||||
|
|
||||||
dp1 = efi_dp_from_ipv4(&ip, &mask, NULL);
|
dp1 = efi_dp_from_ipv4(&ip, &mask, NULL, dev);
|
||||||
if (!dp1)
|
if (!dp1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
|
||||||
strcpy(tmp, "http://");
|
strcpy(tmp, "http://");
|
||||||
|
|
||||||
if (server) {
|
if (server) {
|
||||||
|
@@ -952,14 +952,12 @@ efi_status_t efi_net_register(void)
|
|||||||
if (r != EFI_SUCCESS)
|
if (r != EFI_SUCCESS)
|
||||||
goto failure_to_add_protocol;
|
goto failure_to_add_protocol;
|
||||||
|
|
||||||
if (net_dp)
|
if (!net_dp)
|
||||||
r = efi_add_protocol(&netobj->header, &efi_guid_device_path,
|
efi_net_set_dp("Net", NULL);
|
||||||
net_dp);
|
r = efi_add_protocol(&netobj->header, &efi_guid_device_path,
|
||||||
else
|
net_dp);
|
||||||
r = efi_net_set_dp("Net", NULL);
|
|
||||||
if (r != EFI_SUCCESS)
|
if (r != EFI_SUCCESS)
|
||||||
goto failure_to_add_protocol;
|
goto failure_to_add_protocol;
|
||||||
|
|
||||||
r = efi_add_protocol(&netobj->header, &efi_pxe_base_code_protocol_guid,
|
r = efi_add_protocol(&netobj->header, &efi_pxe_base_code_protocol_guid,
|
||||||
&netobj->pxe);
|
&netobj->pxe);
|
||||||
if (r != EFI_SUCCESS)
|
if (r != EFI_SUCCESS)
|
||||||
@@ -1077,58 +1075,18 @@ out_of_resources:
|
|||||||
*/
|
*/
|
||||||
efi_status_t efi_net_set_dp(const char *dev, const char *server)
|
efi_status_t efi_net_set_dp(const char *dev, const char *server)
|
||||||
{
|
{
|
||||||
efi_status_t ret = EFI_SUCCESS;
|
efi_free_pool(net_dp);
|
||||||
struct efi_handler *phandler;
|
|
||||||
struct efi_device_path *old_net_dp, *new_net_dp;
|
|
||||||
|
|
||||||
old_net_dp = net_dp;
|
net_dp = NULL;
|
||||||
new_net_dp = NULL;
|
|
||||||
if (!strcmp(dev, "Net"))
|
if (!strcmp(dev, "Net"))
|
||||||
new_net_dp = efi_dp_from_eth();
|
net_dp = efi_dp_from_eth(eth_get_dev());
|
||||||
else if (!strcmp(dev, "Http"))
|
else if (!strcmp(dev, "Http"))
|
||||||
new_net_dp = efi_dp_from_http(server);
|
net_dp = efi_dp_from_http(server, eth_get_dev());
|
||||||
|
|
||||||
if (!new_net_dp) {
|
if (!net_dp)
|
||||||
return EFI_OUT_OF_RESOURCES;
|
return EFI_OUT_OF_RESOURCES;
|
||||||
}
|
|
||||||
|
|
||||||
// If netobj is not started yet, end here.
|
|
||||||
if (!netobj) {
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
phandler = NULL;
|
|
||||||
efi_search_protocol(&netobj->header, &efi_guid_device_path, &phandler);
|
|
||||||
|
|
||||||
// If the device path protocol is not yet installed, install it
|
|
||||||
if (!phandler)
|
|
||||||
goto add;
|
|
||||||
|
|
||||||
// If it is already installed, try to update it
|
|
||||||
ret = efi_reinstall_protocol_interface(&netobj->header, &efi_guid_device_path,
|
|
||||||
old_net_dp, new_net_dp);
|
|
||||||
if (ret != EFI_SUCCESS)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
net_dp = new_net_dp;
|
|
||||||
efi_free_pool(old_net_dp);
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
add:
|
|
||||||
ret = efi_add_protocol(&netobj->header, &efi_guid_device_path,
|
|
||||||
new_net_dp);
|
|
||||||
if (ret != EFI_SUCCESS)
|
|
||||||
goto error;
|
|
||||||
exit:
|
|
||||||
net_dp = new_net_dp;
|
|
||||||
efi_free_pool(old_net_dp);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
error:
|
|
||||||
// Failed, restore
|
|
||||||
efi_free_pool(new_net_dp);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user