#include #include #include #include #include #define MSR_DIVIL_LBAR_FLSH0 0x51400010 /* Flash Chip Select 0 */ #define MSR_DIVIL_LBAR_FLSH1 0x51400011 /* Flash Chip Select 1 */ #define MSR_DIVIL_LBAR_FLSH2 0x51400012 /* Flash Chip Select 2 */ #define MSR_DIVIL_LBAR_FLSH3 0x51400013 /* Flash Chip Select 3 */ #define MSR_DIVIL_BALL_OPTS 0x51400015 #define PIN_OPT_IDE (1ULL<<0) /* 0 for flash, 1 for IDE */ #define MSR_NANDF_DATA 0x5140001B #define MSR_NANDF_CTL 0x5140001C /* Intended value for LBAR_FLSH0: 4KiB, enabled, MMIO, NAND, @0x20000000 */ #define SET_FLSH0 0xFFFFF00720000000ULL int main(int argc, char **argv) { int fd = open("/dev/cpu/0/msr", O_RDWR); uint64_t val; if (fd < 0) { int i; perror("Opening /dev/cpu/0/msr"); printf("Trying to load 'msr' module...\n"); system("modprobe msr"); /* Ick. Might take a while for udev to create the device node... */ for (i=0; i<10; i++) { fd = open("/dev/cpu/0/msr", O_RDWR); if (fd >= 0) goto opened; sleep(1); } return 1; } opened: if (pread(fd, &val, sizeof(val), MSR_DIVIL_LBAR_FLSH0) != sizeof(val)) { printf("Read MSR_DIVIL_LBAR_FLSH0 failed\n"); close(fd); return 1; } if ( ((val >> 32) & 7) != 7) { printf("MSR_DIVIL_LBAR_FLSH0 was %016llx, fixing...\n", val); val = SET_FLSH0; if (pwrite(fd, &val, sizeof(val), MSR_DIVIL_LBAR_FLSH0) != sizeof(val)) { printf("Write MSR_DIVIL_LBAR_FLSH0 failed\n"); close(fd); return 1; } if (pread(fd, &val, sizeof(val), MSR_DIVIL_LBAR_FLSH0) != sizeof(val)) { printf("Read MSR_DIVIL_LBAR_FLSH0 failed\n"); close(fd); return 1; } } printf("MSR_DIVIL_LBAR_FLSH0 is %016llx\n", val); if (pread(fd, &val, sizeof(val), MSR_DIVIL_BALL_OPTS) != sizeof(val)) { printf("Read MSR_DIVIL_BALL_OPTS failed\n"); close(fd); return 1; } if (val & PIN_OPT_IDE) { printf("MSR_DIVIL_BALL_OPTS was %016llx, fixing...\n", val); val &= ~PIN_OPT_IDE; if (pwrite(fd, &val, sizeof(val), MSR_DIVIL_BALL_OPTS) != sizeof(val)) { printf("Write MSR_DIVIL_BALL_OPTS failed\n"); close(fd); return 1; } if (pread(fd, &val, sizeof(val), MSR_DIVIL_BALL_OPTS) != sizeof(val)) { printf("Read MSR_DIVIL_BALL_OPTS failed\n"); close(fd); return 1; } } printf("MSR_DIVIL_BALL_OPTS is %016llx\n", val); if (pread(fd, &val, sizeof(val), MSR_NANDF_DATA) != sizeof(val)) { printf("Read MSR_NANDF_DATA failed\n"); close(fd); return 1; } if (val != 0x01110111ULL) { printf("MSR_NANDF_DATA was %016llx, fixing...\n", val); val = 0x01110111ULL; if (pwrite(fd, &val, sizeof(val), MSR_NANDF_DATA) != sizeof(val)) { printf("Write MSR_NANDF_DATA failed\n"); close(fd); return 1; } if (pread(fd, &val, sizeof(val), MSR_NANDF_DATA) != sizeof(val)) { printf("Read MSR_NANDF_DATA failed\n"); close(fd); return 1; } } printf("MSR_NANDF_DATA is %016llx\n", val); if (pread(fd, &val, sizeof(val), MSR_NANDF_CTL) != sizeof(val)) { printf("Read MSR_NANDF_CTL failed\n"); close(fd); return 1; } if (val != 0x0111ULL) { printf("MSR_NANDF_CTL was %016llx, fixing...\n", val); val = 0x0111ULL; if (pwrite(fd, &val, sizeof(val), MSR_NANDF_CTL) != sizeof(val)) { printf("Write MSR_NANDF_CTL failed\n"); close(fd); return 1; } if (pread(fd, &val, sizeof(val), MSR_NANDF_CTL) != sizeof(val)) { printf("Read MSR_NANDF_CTL failed\n"); close(fd); return 1; } } printf("MSR_NANDF_CTL is %016llx\n", val); }