WIP - refactored
diff --git a/src/hci/commands/shim_cmd.c b/src/hci/commands/shim_cmd.c
index 54ed2b2..1667e03 100644
--- a/src/hci/commands/shim_cmd.c
+++ b/src/hci/commands/shim_cmd.c
@@ -38,22 +38,26 @@
 
 /** "shim" options */
 struct shim_options {
-	/** Always download shim */
-	int always;
 	/** Download timeout */
 	unsigned long timeout;
 	/** Crutch image name or URI */
 	char *crutch;
+	/** Require third party loader */
+	int require_loader;
+	/** Allow PXE base code protocol */
+	int allow_pxe;
 };
 
 /** "shim" option list */
 static struct option_descriptor shim_opts[] = {
-	OPTION_DESC ( "always", 'a', no_argument,
-		      struct shim_options, always, parse_flag ),
 	OPTION_DESC ( "timeout", 't', required_argument,
 		      struct shim_options, timeout, parse_timeout ),
 	OPTION_DESC ( "crutch", 'c', required_argument,
 		      struct shim_options, crutch, parse_string ),
+	OPTION_DESC ( "require-loader", 'l', no_argument,
+		      struct shim_options, require_loader, parse_flag ),
+	OPTION_DESC ( "allow-pxe", 'p', no_argument,
+		      struct shim_options, allow_pxe, parse_flag ),
 };
 
 /** "shim" command descriptor */
@@ -82,7 +86,7 @@
 
 	/* Decide whether or not to download images */
 	kernel = find_image_tag ( &selected_image );
-	download = ( ( kernel && efi_can_load ( kernel ) ) ? opts.always : 1 );
+	download = ( ! ( kernel && efi_can_load ( kernel ) ) );
 
 	/* Parse name/URI string */
 	name_uri = argv[optind];
@@ -102,7 +106,8 @@
 	}
 
 	/* (Un)register as shim */
-	if ( ( rc = shim ( image, crutch ) ) != 0 )
+	if ( ( rc = shim ( image, crutch, opts.require_loader,
+			   opts.allow_pxe ) ) != 0 )
 		goto err_shim;
 
  err_shim:
diff --git a/src/image/efi_image.c b/src/image/efi_image.c
index 039ac8f..104753a 100644
--- a/src/image/efi_image.c
+++ b/src/image/efi_image.c
@@ -209,7 +209,9 @@
 	}
 
 	/* Install shim special handling if applicable */
-	if ( shim && ( ( rc = efi_shim_install ( snpdev->handle ) ) != 0 ) ) {
+	if ( shim &&
+	     ( ( rc = efi_shim_install ( shim, snpdev->handle,
+					 &cmdline ) ) != 0 ) ){
 		DBGC ( image, "EFIIMAGE %s could not install shim handling: "
 		       "%s\n", image->name, strerror ( rc ) );
 		goto err_shim_install;
diff --git a/src/include/ipxe/efi/efi_shim.h b/src/include/ipxe/efi/efi_shim.h
index 4a44a4f..bf35adc 100644
--- a/src/include/ipxe/efi/efi_shim.h
+++ b/src/include/ipxe/efi/efi_shim.h
@@ -17,7 +17,8 @@
 extern struct image_tag efi_shim __image_tag;
 extern struct image_tag efi_shim_crutch __image_tag;
 
-extern int efi_shim_install ( EFI_HANDLE handle );
+extern int efi_shim_install ( struct image *shim, EFI_HANDLE handle,
+			      wchar_t **cmdline );
 extern void efi_shim_uninstall ( void );
 
 #endif /* _IPXE_EFI_SHIM_H */
diff --git a/src/interface/efi/efi_shim.c b/src/interface/efi/efi_shim.c
index 673b2d8..42faaa6 100644
--- a/src/interface/efi/efi_shim.c
+++ b/src/interface/efi/efi_shim.c
@@ -24,9 +24,11 @@
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 
 #include <string.h>
+#include <stdlib.h>
 #include <errno.h>
 #include <ipxe/image.h>
 #include <ipxe/efi/efi.h>
+#include <ipxe/efi/efi_strings.h>
 #include <ipxe/efi/efi_shim.h>
 #include <ipxe/efi/Protocol/PxeBaseCode.h>
 #include <ipxe/efi/Protocol/ShimLock.h>
@@ -175,12 +177,47 @@
 }
 
 /**
- * Install UEFI shim special handling
+ * Update command line
  *
- * @v handle		EFI handle
+ * @v shim		Shim image
+ * @v cmdline		Command line to update
  * @ret rc		Return status code
  */
-int efi_shim_install ( EFI_HANDLE handle ) {
+static int efi_shim_cmdline ( struct image *shim, wchar_t **cmdline ) {
+	wchar_t *shimcmdline;
+	int len;
+	int rc;
+
+	/* Construct new command line */
+	len = ( shim->cmdline ?
+		efi_asprintf ( &shimcmdline, "%s %s", shim->name,
+			       shim->cmdline ) :
+		efi_asprintf ( &shimcmdline, "%s %ls", shim->name,
+			       *cmdline ) );
+	if ( len < 0 ) {
+		rc = len;
+		DBGC ( &efi_shim, "SHIM could not construct command line: "
+		       "%s\n", strerror ( rc ) );
+		return rc;
+	}
+
+	/* Replace command line */
+	free ( *cmdline );
+	*cmdline = shimcmdline;
+
+	return 0;
+}
+
+/**
+ * Install UEFI shim special handling
+ *
+ * @v shim		Shim image
+ * @v handle		EFI device handle
+ * @v cmdline		Command line to update
+ * @ret rc		Return status code
+ */
+int efi_shim_install ( struct image *shim, EFI_HANDLE handle,
+		       wchar_t **cmdline ) {
 	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
 	int rc;
 
@@ -195,8 +232,13 @@
 		goto err_inhibit_pxe;
 	}
 
+	/* Update command line */
+	if ( ( rc = efi_shim_cmdline ( shim, cmdline ) ) != 0 )
+		goto err_cmdline;
+
 	return 0;
 
+ err_cmdline:
  err_inhibit_pxe:
 	bs->GetMemoryMap = efi_shim_orig_map;
 	return rc;