1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
|
#pragma once
#include <glib.h>
#include <linux/types.h>
#define R_EMMC_ERROR r_emmc_error_quark()
GQuark r_emmc_error_quark(void);
typedef enum {
R_EMMC_ERROR_FAILED,
R_EMMC_ERROR_IOCTL,
R_EMMC_ERROR_BOOTPART_UDA,
R_EMMC_ERROR_BOOTPART_INVALID,
} REmmcError;
#define EMMC_BOOT_PARTITIONS 2
#define INACTIVE_BOOT_PARTITION(part_active) ((part_active + 1) % EMMC_BOOT_PARTITIONS)
#define EXT_CSD_PART_CONFIG 179
#define EXT_CSD_CMD_SET_NORMAL (1 << 0)
#define EXT_CSD_BOOT_CFG_ACC (0x07)
/* From kernel linux/mmc/mmc.h */
#define MMC_SWITCH 6 /* ac [31:0] See below R1b */
#define MMC_SEND_EXT_CSD 8 /* adtc R1 */
#define MMC_SWITCH_MODE_WRITE_BYTE 0x03 /* Set target to value */
/* From kernel linux/mmc/core.h */
#define MMC_RSP_PRESENT (1 << 0)
#define MMC_RSP_CRC (1 << 2) /* expect valid crc */
#define MMC_RSP_BUSY (1 << 3) /* card may send busy */
#define MMC_RSP_OPCODE (1 << 4) /* response contains opcode */
#define MMC_CMD_AC (0 << 5)
#define MMC_CMD_ADTC (1 << 5)
#define MMC_RSP_SPI_S1 (1 << 7) /* one status byte */
#define MMC_RSP_SPI_BUSY (1 << 10) /* card may send busy */
#define MMC_RSP_SPI_R1 (MMC_RSP_SPI_S1)
#define MMC_RSP_SPI_R1B (MMC_RSP_SPI_S1|MMC_RSP_SPI_BUSY)
#define MMC_RSP_R1 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
#define MMC_RSP_R1B (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE|MMC_RSP_BUSY)
/**
* Reads the active eMMC boot partition index of given eMMC device into the
* given variable.
*
* @param device eMMC /dev path (/dev/mmcblkX)
* @param bootpart_active will contain the active boot partition
* (0 for boot0, 1 for boot1, -1 for no active boot partition)
* @param error return location for a GError, or NULL
*
* @return True if succeeded, False if failed
*/
gboolean r_emmc_read_bootpart(const gchar *device, gint *bootpart_active, GError **error)
G_GNUC_WARN_UNUSED_RESULT;
/**
* Set the given boot partition (by index) active.
*
* @param device eMMC /dev path (/dev/mmcblkX)
* @param bootpart_active boot partition to set active (0 or 1)
* @param error return location for a GError, or NULL
*
* @return True if succeeded, False if failed
*/
gboolean r_emmc_write_bootpart(const gchar *device, gint bootpart_active, GError **error)
G_GNUC_WARN_UNUSED_RESULT;
/**
* Set eMMC boot partition to read-only.
*
* @param device eMMC boot partition /dev path (/dev/mmcblkXbootY)
* @param error return location for a GError, or NULL
*
* @return True if succeeded, False if failed
*/
gboolean r_emmc_force_part_ro(const gchar *device, GError **error);
/**
* Set eMMC boot partition to read-write.
*
* @param device eMMC boot partition /dev path (/dev/mmcblkXbootY)
* @param error return location for a GError, or NULL
*
* @return True if succeeded, False if failed
*/
gboolean r_emmc_force_part_rw(const gchar *device, GError **error)
G_GNUC_WARN_UNUSED_RESULT;
|