static void ProcessFirmwareEvent(const Uevent& uevent) {
    int booting = IsBooting();

    LOG(INFO) << "firmware: loading '" << uevent.firmware << "' for '" << uevent.path << "'";

    std::string root = "/sys" + uevent.path;
    std::string loading = root + "/loading";
    std::string data = root + "/data";

    unique_fd loading_fd(open(loading.c_str(), O_WRONLY | O_CLOEXEC));
    if (loading_fd == -1) {
        PLOG(ERROR) << "couldn't open firmware loading fd for " << uevent.firmware;
        return;
    }

    unique_fd data_fd(open(data.c_str(), O_WRONLY | O_CLOEXEC));
    if (data_fd == -1) {
        PLOG(ERROR) << "couldn't open firmware data fd for " << uevent.firmware;
        return;
    }

    static const char* firmware_dirs[] = {"/etc/firmware/", "/vendor/firmware/",
                                          "/firmware/image/"};

try_loading_again:
    for (size_t i = 0; i < arraysize(firmware_dirs); i++) {
        std::string file = firmware_dirs[i] + uevent.firmware;
        unique_fd fw_fd(open(file.c_str(), O_RDONLY | O_CLOEXEC));
        struct stat sb;
        if (fw_fd != -1 && fstat(fw_fd, &sb) != -1) {
            LoadFirmware(uevent, root, fw_fd, sb.st_size, loading_fd, data_fd);
            return;
        }
    }

    if (booting) {
        // If we're not fully booted, we may be missing
        // filesystems needed for firmware, wait and retry.
        std::this_thread::sleep_for(100ms);
        booting = IsBooting();
        goto try_loading_again;
    }

    LOG(ERROR) << "firmware: could not find firmware for " << uevent.firmware;

    // Write "-1" as our response to the kernel's firmware request, since we have nothing for it.
    write(loading_fd, "-1", 2);
}
/*************************************************
*   Reloads the CP images.
*
*****************************************************/
static void ReloadCP(void)
{
	int ret;
	int index;

	for (index = 0; (g_cp_imgs[index].img_name != NULL); index++) {
		IPC_DEBUG(DBG_INFO, "LoadFirmware for %s @ %p, size %d\n",
			  g_cp_imgs[index].img_name,
			  (void *)g_cp_imgs[index].ram_addr,
			  g_cp_imgs[index].img_size);
		ret = LoadFirmware(ipcs_get_drvdata(),
				   g_cp_imgs[index].img_name,
				   g_cp_imgs[index].ram_addr,
				   g_cp_imgs[index].img_size);
		IPC_DEBUG(DBG_INFO, "LoadFirmware for %s returned %d\n",
			  g_cp_imgs[index].img_name, ret);
	}
}
示例#3
0
文件: main.c 项目: snowasnow/DeSmuME
int SelectFirmwareFile_Load(GtkWidget *w, gpointer data)
{
	GtkFileFilter *pFilter_nds, *pFilter_bin, *pFilter_any;
	GtkWidget *pFileSelection;
	GtkWidget *pParent;
	gchar *sChemin;

	BOOL oldState = desmume_running();
	Pause();
	
	pParent = GTK_WIDGET(data);
	
	pFilter_nds = gtk_file_filter_new();
	gtk_file_filter_add_pattern(pFilter_nds, "*.nds");
	gtk_file_filter_set_name(pFilter_nds, "Nds binary (.nds)");
	
	pFilter_bin = gtk_file_filter_new();
	gtk_file_filter_add_pattern(pFilter_bin, "*.bin");
	gtk_file_filter_set_name(pFilter_bin, "Binary file (.bin)");
	
	pFilter_any = gtk_file_filter_new();
	gtk_file_filter_add_pattern(pFilter_any, "*");
	gtk_file_filter_set_name(pFilter_any, "All files");

	/* Creation de la fenetre de selection */
	pFileSelection = gtk_file_chooser_dialog_new("Save firmware...",
			GTK_WINDOW(pParent),
			GTK_FILE_CHOOSER_ACTION_OPEN,
			GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
			GTK_STOCK_SAVE, GTK_RESPONSE_OK,
			NULL);
	/* On limite les actions a cette fenetre */
	gtk_window_set_modal(GTK_WINDOW(pFileSelection), TRUE);

	gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(pFileSelection), pFilter_nds);
	gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(pFileSelection), pFilter_bin);
	gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(pFileSelection), pFilter_any);
	
	if(FirmwareFile[0]) gtk_file_chooser_select_uri(GTK_FILE_CHOOSER(pFileSelection), FirmwareFile);
	
	/* Affichage fenetre */
	switch(gtk_dialog_run(GTK_DIALOG(pFileSelection)))
	{
		case GTK_RESPONSE_OK:
			/* Recuperation du chemin */
			sChemin = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(pFileSelection));
			if(LoadFirmware((const char*)sChemin) < 0)
			{
				GtkWidget *pDialog = gtk_message_dialog_new(GTK_WINDOW(pFileSelection), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Unable to load :\n%s", sChemin);
				gtk_dialog_run(GTK_DIALOG(pDialog));
				gtk_widget_destroy(pDialog);
			}
			else
			{
				GtkWidget *pDialog = gtk_message_dialog_new(GTK_WINDOW(pFileSelection), GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "Selected firmware :\n%s", sChemin);
				gtk_dialog_run(GTK_DIALOG(pDialog));
				gtk_widget_destroy(pDialog);
			}

			g_free(sChemin);
			break;
		default:
			break;
	}
	gtk_widget_destroy(pFileSelection);
	
	if(oldState) Launch();
	
}
VbError_t VbSelectFirmware(VbCommonParams *cparams,
                           VbSelectFirmwareParams *fparams)
{
	VbSharedDataHeader *shared =
		(VbSharedDataHeader *)cparams->shared_data_blob;
	VbNvContext vnc;
	VbError_t retval = VBERROR_UNKNOWN; /* Default to error */
	int is_rec = (shared->recovery_reason ? 1 : 0);
	int is_dev = (shared->flags & VBSD_BOOT_DEV_SWITCH_ON ? 1 : 0);
	uint32_t tpm_status = 0;

	/* Start timer */
	shared->timer_vb_select_firmware_enter = VbExGetTimer();

	/* Load NV storage */
	VbExNvStorageRead(vnc.raw);
	VbNvSetup(&vnc);

	if (is_rec) {
		/*
		 * Recovery is requested; go straight to recovery without
		 * checking the RW firmware.
		 */
		VBDEBUG(("VbSelectFirmware() detected recovery request\n"));

		/* Go directly to recovery mode */
		fparams->selected_firmware = VB_SELECT_FIRMWARE_RECOVERY;
	} else {
		/* Chain to LoadFirmware() */
		retval = LoadFirmware(cparams, fparams, &vnc);

		/* Exit if we failed to find an acceptable firmware */
		if (VBERROR_SUCCESS != retval)
			goto VbSelectFirmware_exit;

		/* Translate the selected firmware path */
		if (shared->flags & VBSD_LF_USE_RO_NORMAL) {
			/* Request the read-only normal/dev code path */
			fparams->selected_firmware =
				VB_SELECT_FIRMWARE_READONLY;
		} else if (0 == shared->firmware_index)
			fparams->selected_firmware = VB_SELECT_FIRMWARE_A;
		else {
			fparams->selected_firmware = VB_SELECT_FIRMWARE_B;
		}

		/* Update TPM if necessary */
		if (shared->fw_version_tpm_start < shared->fw_version_tpm) {
			tpm_status =
				RollbackFirmwareWrite(shared->fw_version_tpm);
			if (0 != tpm_status) {
				VBDEBUG(("Can't write FW version to TPM.\n"));
				VbNvSet(&vnc, VBNV_RECOVERY_REQUEST,
					VBNV_RECOVERY_RO_TPM_W_ERROR);
				retval = VBERROR_TPM_WRITE_FIRMWARE;
				goto VbSelectFirmware_exit;
			}
		}

		/* Lock firmware versions in TPM */
		tpm_status = RollbackFirmwareLock();
		if (0 != tpm_status) {
			VBDEBUG(("Unable to lock firmware version in TPM.\n"));
			VbNvSet(&vnc, VBNV_RECOVERY_REQUEST,
				VBNV_RECOVERY_RO_TPM_L_ERROR);
			retval = VBERROR_TPM_LOCK_FIRMWARE;
			goto VbSelectFirmware_exit;
		}
	}

	/*
	 * At this point, we have a good idea of how we are going to
	 * boot. Update the TPM with this state information.
	 */
	tpm_status = SetTPMBootModeState(is_dev, is_rec,
					 shared->fw_keyblock_flags);
	if (0 != tpm_status) {
		VBDEBUG(("Can't update the TPM with boot mode information.\n"));
		if (!is_rec) {
			VbNvSet(&vnc, VBNV_RECOVERY_REQUEST,
				VBNV_RECOVERY_RO_TPM_U_ERROR);
			retval = VBERROR_TPM_SET_BOOT_MODE_STATE;
			goto VbSelectFirmware_exit;
		}
	}

	/* Success! */
	retval = VBERROR_SUCCESS;

 VbSelectFirmware_exit:

	/* Save NV storage */
	VbNvTeardown(&vnc);
	if (vnc.raw_changed)
		VbExNvStorageWrite(vnc.raw);

	/* Stop timer */
	shared->timer_vb_select_firmware_exit = VbExGetTimer();

	/* Should always have a known error code */
	VbAssert(VBERROR_UNKNOWN != retval);

	return retval;
}