diff --git a/src/board/system76/galp3-c/acpi.c b/src/board/system76/galp3-c/acpi.c index b295662..f22f463 100644 --- a/src/board/system76/galp3-c/acpi.c +++ b/src/board/system76/galp3-c/acpi.c @@ -30,6 +30,9 @@ uint8_t acpi_read(uint8_t addr) { ACPI_8 (0x14, peci_duty); ACPI_8 (0x15, peci_tcontrol); ACPI_8 (0x16, peci_tjmax); + + // Set size of flash (from old firmware) + ACPI_8 (0xE5, 0x80); } DEBUG("acpi_read %02X = %02X\n", addr, data); diff --git a/src/board/system76/galp3-c/pmc.c b/src/board/system76/galp3-c/pmc.c index 80b6660..a67218d 100644 --- a/src/board/system76/galp3-c/pmc.c +++ b/src/board/system76/galp3-c/pmc.c @@ -1,5 +1,6 @@ #include #include +#include #include void pmc_init(void) { @@ -48,6 +49,12 @@ void pmc_event(struct Pmc * pmc) { // TODO: queue is always empty pmc_write(pmc, 0, PMC_TIMEOUT); break; + + case 0xDC: + DEBUG(" scratch rom\n"); + pmc_write(pmc, 0x33, PMC_TIMEOUT); + scratch_trampoline(); + break; } } else { DEBUG("pmc data: %02X\n", data); diff --git a/src/board/system76/galp3-c/scratch.c b/src/board/system76/galp3-c/scratch.c index 5649f48..5cd1775 100644 --- a/src/board/system76/galp3-c/scratch.c +++ b/src/board/system76/galp3-c/scratch.c @@ -37,44 +37,49 @@ static void scratch_start(void) __naked { __endasm; } -// Enter scratch ROM -int scratch_trampoline(void) { +// Enter or exit scratch ROM +void scratch_trampoline(void) { // Uses SCAR1, 2, 3, and 4 which are mapped at 0x0800 in data space and are // 2048 bytes in size. SCAR0 cannot be used due to __pdata overwriting it. - int i; - // Copy scratch ROM - for (i = 0; i < ARRAY_SIZE(scratch_rom) && i < ARRAY_SIZE(scratch_ram); i++) { - scratch_ram[i] = scratch_rom[i]; + if ((SCAR1H == 0x00) || (SCAR2H == 0x00) || (SCAR3H == 0x00) || (SCAR4H == 0x00)) { + // Disable scratch RAM mapping + SCAR1H = 0b11; + SCAR2H = 0b11; + SCAR3H = 0b11; + SCAR4H = 0b11; + } else { + int i; + // Copy scratch ROM + for (i = 0; i < ARRAY_SIZE(scratch_rom) && i < ARRAY_SIZE(scratch_ram); i++) { + scratch_ram[i] = scratch_rom[i]; + } + + // Fill the rest with nop + for (; i < ARRAY_SIZE(scratch_ram); i++) { + scratch_ram[i] = 0x00; + } + + // Set scratch RAM 1 mapping at 0x0000 and enable + SCAR1L = 0x00; + SCAR1M = 0x00; + SCAR1H = 0x00; + // Set scratch RAM 2 mapping at 0x0400 and enable + SCAR2L = 0x00; + SCAR2M = 0x04; + SCAR2H = 0x00; + // Set scratch RAM 3 mapping at 0x0600 and enable + SCAR3L = 0x00; + SCAR3M = 0x06; + SCAR3H = 0x00; + // Set scratch RAM 4 mapping at 0x0800 and enable + SCAR4L = 0x00; + SCAR4M = 0x08; + SCAR4H = 0x00; } - // Fill the rest with nop - for (; i < ARRAY_SIZE(scratch_ram); i++) { - scratch_ram[i] = 0x00; - } - - // Set scratch RAM 1 mapping at 0x0000 and enable - SCAR1L = 0x00; - SCAR1M = 0x00; - SCAR1H = 0x00; - // Set scratch RAM 2 mapping at 0x0400 and enable - SCAR2L = 0x00; - SCAR2M = 0x04; - SCAR2H = 0x00; - // Set scratch RAM 3 mapping at 0x0600 and enable - SCAR3L = 0x00; - SCAR3M = 0x06; - SCAR3H = 0x00; - // Set scratch RAM 4 mapping at 0x0800 and enable - SCAR4L = 0x00; - SCAR4M = 0x08; - SCAR4H = 0x00; - - // Jump to scratch reset function + // Jump to reset function __asm__("ljmp 0"); - - // Should never happen - return 0; } // Finish segment located at 0x1000 diff --git a/src/board/system76/galp3-c/scratch/include/scratch/pmc.h b/src/board/system76/galp3-c/scratch/include/scratch/pmc.h index 8e02acb..ca36a16 100644 --- a/src/board/system76/galp3-c/scratch/include/scratch/pmc.h +++ b/src/board/system76/galp3-c/scratch/include/scratch/pmc.h @@ -23,7 +23,7 @@ extern struct Pmc __code PMC_1; uint8_t pmc_status(struct Pmc * pmc); uint8_t pmc_read(struct Pmc * pmc); -bool pmc_write(struct Pmc * pmc, uint8_t data, int timeout); +bool pmc_write(struct Pmc * pmc, uint8_t data); volatile uint8_t __xdata __at(0x1500) PM1STS; volatile uint8_t __xdata __at(0x1501) PM1DO; diff --git a/src/board/system76/galp3-c/scratch/main.c b/src/board/system76/galp3-c/scratch/main.c index 6031201..bb04627 100644 --- a/src/board/system76/galp3-c/scratch/main.c +++ b/src/board/system76/galp3-c/scratch/main.c @@ -1,5 +1,7 @@ #include #include +#include +#define printf printf_small #include @@ -28,20 +30,73 @@ static int flash_transaction(uint32_t offset, uint8_t * data, int length, bool r return i; } -#define PMC_TIMEOUT 1000 +enum PmcState { + PMC_STATE_DEFAULT, + PMC_STATE_WRITE, +}; + +static uint8_t __xdata __at(0x1F07) EWDKEYR; static void pmc_event(struct Pmc * pmc) { + static enum PmcState state = PMC_STATE_DEFAULT; + uint8_t sts = pmc_status(pmc); if (sts & PMC_STS_IBF) { uint8_t data = pmc_read(pmc); + //printf("%x\n", data); if (sts & PMC_STS_CMD) { - } else { + switch (state) { + case PMC_STATE_DEFAULT: + switch (data) { + case 0x01: + // Enable follow + ECINDAR3 = 0x0F; + break; + case 0x02: + // Generate high CE# + data = 0; + flash_transaction(0x7FFFFE00, &data, 1, false); + // Fall through + case 0x03: + state = PMC_STATE_WRITE; + break; + case 0x04: + // Read data + flash_transaction(0x7FFFFD00, &data, 1, true); + pmc_write(pmc, data); + break; + case 0x05: + // Disable follow + ECINDAR3 = 0x00; + break; + case 0xFC: + // Clear processor caches + __asm__("mov 0xf7, #1"); + __asm__("nop"); + __asm__("mov 0xf7, #1"); + __asm__("nop"); + __asm__("mov 0xf7, #1"); + __asm__("nop"); + __asm__("mov 0xf7, #1"); + __asm__("nop"); + // Exit scratch ROM by going through trampoline + __asm__("ljmp 0x1000"); + break; + } + break; + case PMC_STATE_WRITE: + // Write command or data + flash_transaction(0x7FFFFD00, &data, 1, false); + state = PMC_STATE_DEFAULT; + break; + } } } } // Main program while running in scratch ROM void main(void) { + printf("scratch\n"); for (;;) { pmc_event(&PMC_1); } diff --git a/src/board/system76/galp3-c/scratch/pmc.c b/src/board/system76/galp3-c/scratch/pmc.c index ee75943..7bba10c 100644 --- a/src/board/system76/galp3-c/scratch/pmc.c +++ b/src/board/system76/galp3-c/scratch/pmc.c @@ -17,16 +17,8 @@ uint8_t pmc_read(struct Pmc * pmc) { return *(pmc->data_in); } -static bool pmc_wait(struct Pmc * pmc, int timeout) { - while (pmc_status(pmc) & PMC_STS_OBF) { - if (timeout == 0) return false; - timeout -= 1; - } - return true; -} - -bool pmc_write(struct Pmc * pmc, uint8_t data, int timeout) { - if (!pmc_wait(pmc, timeout)) return false; +bool pmc_write(struct Pmc * pmc, uint8_t data) { + while (pmc_status(pmc) & PMC_STS_OBF) {} *(pmc->data_out) = data; return true; } diff --git a/src/board/system76/galp3-c/scratch/stdio.c b/src/board/system76/galp3-c/scratch/stdio.c new file mode 100644 index 0000000..1fb9463 --- /dev/null +++ b/src/board/system76/galp3-c/scratch/stdio.c @@ -0,0 +1,8 @@ +#include +#include + +int putchar(int c) { + unsigned char byte = (unsigned char)c; + SBUF = byte; + return (int)byte; +} diff --git a/src/board/system76/galp3-c/stdio.c b/src/board/system76/galp3-c/stdio.c index b394676..a513205 100644 --- a/src/board/system76/galp3-c/stdio.c +++ b/src/board/system76/galp3-c/stdio.c @@ -1,9 +1,13 @@ #include +#include -#include +#ifdef I2C_DEBUGGER + #include +#endif int putchar(int c) { unsigned char byte = (unsigned char)c; + SBUF = byte; #ifdef I2C_DEBUGGER i2c_send(I2C_DEBUGGER, &byte, 1); #endif