From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wm1-f41.google.com (mail-wm1-f41.google.com [209.85.128.41]) by mx.groups.io with SMTP id smtpd.web10.7328.1594374228310716882 for ; Fri, 10 Jul 2020 02:43:48 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@akeo-ie.20150623.gappssmtp.com header.s=20150623 header.b=jV0Ad2EB; spf=none, err=permanent DNS error (domain: akeo.ie, ip: 209.85.128.41, mailfrom: pete@akeo.ie) Received: by mail-wm1-f41.google.com with SMTP id l17so5449223wmj.0 for ; Fri, 10 Jul 2020 02:43:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=akeo-ie.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=m89MHWvEuuJklU7hUSxJEnmz98jyTxAPFJOnwnQlOMM=; b=jV0Ad2EBlm5xKwn9sdOsmnoDdYq0gxcSMDT7qkXw+qncZ1LNkLmw8Gy/QYCRQmO6vW G6O9zzIkyfdm5tCgM2jnuOL06iXCaOjV02GE6HR4t+U4ed1ibplJiu65iFz5eVs/9A/Y /e9TRBeiLqSQK8RmbqH4tStZ8o0hUjF66kmpORxopcARSH7fLzp++zwEbohYokFxbH+V 9mZMluxdgzuZ69Ac+4KJXh2fozuwhTsPNCAiK72fnwwn1eWJNn5VimGphd19ZHGH8Byy cJWuEtEtztRDcG01gHVFlLV2G09KZTgzN9p13TPgWnlkFC8YeKyV5WeLzqP08xMSxifF kiuA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=m89MHWvEuuJklU7hUSxJEnmz98jyTxAPFJOnwnQlOMM=; b=hJfMuO0AASVS2FlGYQ2xU2+WMHbdUsMmlmL50qlCbzx5UxVf24IJU2F/ZxAT4S8fIQ B4olECFRoOt24psJvRd7/1xzMQaxXISLj8aeqyoHd3N9oqOK3RSpndvAQ0fy4K9fWmjb DQgndM7a4xWS2psfUMjwRPl7Xm/WX4nB9crTpqbuiC83lXypBs2FgqKuAz3B9gOJlXdK DKv567tm+RKmym3bhTk6VNfmiAnNZIQNzgTjDInvjJREfy348DTM7bH/9vN6EAuKbHFN LmZ6AnE1l+P1/LpYe136H1TpfzBvAfrbqnKKqN0ebyZ1yw2So0u2eX1Li77pa4gDMHC/ 2kRw== X-Gm-Message-State: AOAM533H5VMvrKS1IsCoMHtR7+RQa4GgK6GHJLAyhm06w+TMH3pprebx XjmaxQDVrgMfo8wfr2K2XyDfXl5aQnwbTw== X-Google-Smtp-Source: ABdhPJxCvFeGvfAOP1/o4jgSjI3aX09qgWt5fWtzzRdwt51nTBHkfhjXAPJi/GyWyDFmcEar3a4FQg== X-Received: by 2002:a05:600c:2f88:: with SMTP id t8mr4295472wmn.186.1594374226460; Fri, 10 Jul 2020 02:43:46 -0700 (PDT) Return-Path: Received: from localhost.localdomain ([84.203.56.91]) by smtp.gmail.com with ESMTPSA id c194sm8547415wme.8.2020.07.10.02.43.45 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 10 Jul 2020 02:43:45 -0700 (PDT) From: "Pete Batard" To: devel@edk2.groups.io Cc: ard.biesheuvel@arm.com, leif@nuviainc.com, awarkentin@vmware.com, Andrei Warkentin Subject: [edk2-platforms][PATCH v2 1/1] Platform/RaspberryPi/Drivers: Add SD card detection Date: Fri, 10 Jul 2020 10:43:32 +0100 Message-Id: <20200710094332.15976-2-pete@akeo.ie> X-Mailer: git-send-email 2.21.0.windows.1 In-Reply-To: <20200710094332.15976-1-pete@akeo.ie> References: <20200710094332.15976-1-pete@akeo.ie> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit The Raspberry Pi 3 and Pi 4 platforms (with latest EEPROM) can boot straight from USB, without the need for an SD card being present. However, the IsCardPresent () calls from the ArasanMmcHost and SdHost drivers are currently hardwired to return TRUE, which results in straight to USB boot failing due to the SD drivers looping on errors while trying to poke at a non-existent card... Ideally, we would use the Card Detect signal from the uSD slot, to report on the presence or absence of a card, but the Raspberry Pi Foundation did not wire those signals in the Pi 2 and subsequent models, leaving us with only potentially interfering SD commands as means to perform card detection. As a result of this, we are left with no other choice but limit detection to occurring only once, prior to formal SD card init, and then return the detected value for subsequent calls. This, however, is more than good enough for the intended purpose, which is to allow straight to USB boot. Tested on Raspberry Pi 3 and 4, and for both SD controllers. Addresses pftf/RPi3#13, pftf/RPi3#14, pftf/RPi4#37. Signed-off-by: Pete Batard Reviewed-by: Andrei Warkentin Tested-by: Andrei Warkentin --- Platform/RaspberryPi/Drivers/ArasanMmcHostDxe/ArasanMmcHostDxe.c | 66 +++++++++++++++++--- Platform/RaspberryPi/Drivers/SdHostDxe/SdHostDxe.c | 65 ++++++++++++++++--- Platform/RaspberryPi/Include/Protocol/RpiMmcHost.h | 6 ++ 3 files changed, 120 insertions(+), 17 deletions(-) diff --git a/Platform/RaspberryPi/Drivers/ArasanMmcHostDxe/ArasanMmcHostDxe.c b/Platform/RaspberryPi/Drivers/ArasanMmcHostDxe/ArasanMmcHostDxe.c index 6d706af6f276..08e5be1f015f 100644 --- a/Platform/RaspberryPi/Drivers/ArasanMmcHostDxe/ArasanMmcHostDxe.c +++ b/Platform/RaspberryPi/Drivers/ArasanMmcHostDxe/ArasanMmcHostDxe.c @@ -11,7 +11,8 @@ #define DEBUG_MMCHOST_SD DEBUG_VERBOSE -BOOLEAN PreviousIsCardPresent = FALSE; +BOOLEAN CardIsPresent = FALSE; +CARD_DETECT_STATE CardDetectState = CardDetectRequired; UINT32 LastExecutedCommand = (UINT32) -1; STATIC RASPBERRY_PI_FIRMWARE_PROTOCOL *mFwProtocol; @@ -239,14 +240,6 @@ CalculateClockFrequencyDivisor ( return EFI_SUCCESS; } -BOOLEAN -MMCIsCardPresent ( - IN EFI_MMC_HOST_PROTOCOL *This -) -{ - return TRUE; -} - BOOLEAN MMCIsReadOnly ( IN EFI_MMC_HOST_PROTOCOL *This @@ -418,6 +411,10 @@ MMCNotifyState ( DEBUG ((DEBUG_MMCHOST_SD, "ArasanMMCHost: MMCNotifyState(State: %d)\n", State)); + // Stall all operations except init until card detection has occurred. + if (State != MmcHwInitializationState && CardDetectState != CardDetectCompleted) + return EFI_NOT_READY; + switch (State) { case MmcHwInitializationState: { @@ -489,6 +486,57 @@ MMCNotifyState ( return EFI_SUCCESS; } +BOOLEAN +MMCIsCardPresent ( + IN EFI_MMC_HOST_PROTOCOL *This +) +{ + EFI_STATUS Status; + + // + // If we are already in progress (we may get concurrent calls) + // or completed the detection, just return the current value. + // + if (CardDetectState != CardDetectRequired) + return CardIsPresent; + + CardDetectState = CardDetectInProgress; + CardIsPresent = FALSE; + + // + // The two following commands should succeed even if no card is present. + // + Status = MMCNotifyState (This, MmcHwInitializationState); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "MMCIsCardPresent: Error MmcHwInitializationState, Status=%r.\n", Status)); + // If we failed init, go back to requiring card detection + CardDetectState = CardDetectRequired; + return FALSE; + } + + Status = MMCSendCommand (This, MMC_CMD0, 0); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "MMCIsCardPresent: CMD0 Error, Status=%r.\n", Status)); + goto out; + } + + // + // CMD8 should tell us if a card is present. + // + Status = MMCSendCommand (This, MMC_CMD8, CMD8_SD_ARG); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "MMCIsCardPresent: No card detected, Status=%r.\n", Status)); + goto out; + } + + DEBUG ((DEBUG_INFO, "MMCIsCardPresent: Card detected.\n")); + CardIsPresent = TRUE; + +out: + CardDetectState = CardDetectCompleted; + return CardIsPresent; +} + EFI_STATUS MMCReceiveResponse ( IN EFI_MMC_HOST_PROTOCOL *This, diff --git a/Platform/RaspberryPi/Drivers/SdHostDxe/SdHostDxe.c b/Platform/RaspberryPi/Drivers/SdHostDxe/SdHostDxe.c index 2f31c5eb8c46..964b2d3ac5c1 100644 --- a/Platform/RaspberryPi/Drivers/SdHostDxe/SdHostDxe.c +++ b/Platform/RaspberryPi/Drivers/SdHostDxe/SdHostDxe.c @@ -64,6 +64,8 @@ STATIC CONST CHAR8 *mFsmState[] = { "identmode", "datamode", "readdata", "genpulses", "writewait2", "?", "startpowdown" }; #endif /* NDEBUG */ +STATIC BOOLEAN CardIsPresent = FALSE; +STATIC CARD_DETECT_STATE CardDetectState = CardDetectRequired; STATIC UINT32 mLastGoodCmd = MMC_GET_INDX (MMC_CMD0); STATIC inline BOOLEAN @@ -264,14 +266,6 @@ SdHostSetClockFrequency ( return Status; } -STATIC BOOLEAN -SdIsCardPresent ( - IN EFI_MMC_HOST_PROTOCOL *This - ) -{ - return TRUE; -} - STATIC BOOLEAN SdIsReadOnly ( IN EFI_MMC_HOST_PROTOCOL *This @@ -639,6 +633,10 @@ SdNotifyState ( { DEBUG ((DEBUG_MMCHOST_SD, "SdHost: SdNotifyState(State: %d) ", State)); + // Stall all operations except init until card detection has occurred. + if (State != MmcHwInitializationState && CardDetectState != CardDetectCompleted) + return EFI_NOT_READY; + switch (State) { case MmcHwInitializationState: DEBUG ((DEBUG_MMCHOST_SD, "MmcHwInitializationState\n", State)); @@ -718,6 +716,57 @@ SdNotifyState ( return EFI_SUCCESS; } +STATIC BOOLEAN +SdIsCardPresent ( + IN EFI_MMC_HOST_PROTOCOL *This + ) +{ + EFI_STATUS Status; + + // + // If we are already in progress (we may get concurrent calls) + // or completed the detection, just return the current value. + // + if (CardDetectState != CardDetectRequired) + return CardIsPresent; + + CardDetectState = CardDetectInProgress; + CardIsPresent = FALSE; + + // + // The two following commands should succeed even if no card is present. + // + Status = SdNotifyState (This, MmcHwInitializationState); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "SdIsCardPresent: Error MmcHwInitializationState, Status=%r.\n", Status)); + // If we failed init, go back to requiring card detection + CardDetectState = CardDetectRequired; + return FALSE; + } + + Status = SdSendCommand (This, MMC_CMD0, 0); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "SdIsCardPresent: CMD0 Error, Status=%r.\n", Status)); + goto out; + } + + // + // CMD8 should tell us if a card is present. + // + Status = SdSendCommand (This, MMC_CMD8, CMD8_SD_ARG); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "SdIsCardPresent: No card detected, Status=%r.\n", Status)); + goto out; + } + + DEBUG ((DEBUG_INFO, "SdIsCardPresent: Card detected.\n")); + CardIsPresent = TRUE; + +out: + CardDetectState = CardDetectCompleted; + return CardIsPresent; +} + BOOLEAN SdIsMultiBlock ( IN EFI_MMC_HOST_PROTOCOL *This diff --git a/Platform/RaspberryPi/Include/Protocol/RpiMmcHost.h b/Platform/RaspberryPi/Include/Protocol/RpiMmcHost.h index c558e00bf500..78514a31bc4e 100644 --- a/Platform/RaspberryPi/Include/Protocol/RpiMmcHost.h +++ b/Platform/RaspberryPi/Include/Protocol/RpiMmcHost.h @@ -82,6 +82,12 @@ typedef enum _MMC_STATE { MmcDisconnectState, } MMC_STATE; +typedef enum _CARD_DETECT_STATE { + CardDetectRequired = 0, + CardDetectInProgress, + CardDetectCompleted +} CARD_DETECT_STATE; + #define EMMCBACKWARD (0) #define EMMCHS26 (1 << 0) // High-Speed @26MHz at rated device voltages #define EMMCHS52 (1 << 1) // High-Speed @52MHz at rated device voltages -- 2.21.0.windows.1