Implement flashing from scratch rom
This commit is contained in:
@ -30,6 +30,9 @@ uint8_t acpi_read(uint8_t addr) {
|
|||||||
ACPI_8 (0x14, peci_duty);
|
ACPI_8 (0x14, peci_duty);
|
||||||
ACPI_8 (0x15, peci_tcontrol);
|
ACPI_8 (0x15, peci_tcontrol);
|
||||||
ACPI_8 (0x16, peci_tjmax);
|
ACPI_8 (0x16, peci_tjmax);
|
||||||
|
|
||||||
|
// Set size of flash (from old firmware)
|
||||||
|
ACPI_8 (0xE5, 0x80);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG("acpi_read %02X = %02X\n", addr, data);
|
DEBUG("acpi_read %02X = %02X\n", addr, data);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include <board/acpi.h>
|
#include <board/acpi.h>
|
||||||
#include <board/pmc.h>
|
#include <board/pmc.h>
|
||||||
|
#include <board/scratch.h>
|
||||||
#include <common/debug.h>
|
#include <common/debug.h>
|
||||||
|
|
||||||
void pmc_init(void) {
|
void pmc_init(void) {
|
||||||
@ -48,6 +49,12 @@ void pmc_event(struct Pmc * pmc) {
|
|||||||
// TODO: queue is always empty
|
// TODO: queue is always empty
|
||||||
pmc_write(pmc, 0, PMC_TIMEOUT);
|
pmc_write(pmc, 0, PMC_TIMEOUT);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 0xDC:
|
||||||
|
DEBUG(" scratch rom\n");
|
||||||
|
pmc_write(pmc, 0x33, PMC_TIMEOUT);
|
||||||
|
scratch_trampoline();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
DEBUG("pmc data: %02X\n", data);
|
DEBUG("pmc data: %02X\n", data);
|
||||||
|
@ -37,11 +37,18 @@ static void scratch_start(void) __naked {
|
|||||||
__endasm;
|
__endasm;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enter scratch ROM
|
// Enter or exit scratch ROM
|
||||||
int scratch_trampoline(void) {
|
void scratch_trampoline(void) {
|
||||||
// Uses SCAR1, 2, 3, and 4 which are mapped at 0x0800 in data space and are
|
// 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.
|
// 2048 bytes in size. SCAR0 cannot be used due to __pdata overwriting it.
|
||||||
|
|
||||||
|
if ((SCAR1H == 0x00) || (SCAR2H == 0x00) || (SCAR3H == 0x00) || (SCAR4H == 0x00)) {
|
||||||
|
// Disable scratch RAM mapping
|
||||||
|
SCAR1H = 0b11;
|
||||||
|
SCAR2H = 0b11;
|
||||||
|
SCAR3H = 0b11;
|
||||||
|
SCAR4H = 0b11;
|
||||||
|
} else {
|
||||||
int i;
|
int i;
|
||||||
// Copy scratch ROM
|
// Copy scratch ROM
|
||||||
for (i = 0; i < ARRAY_SIZE(scratch_rom) && i < ARRAY_SIZE(scratch_ram); i++) {
|
for (i = 0; i < ARRAY_SIZE(scratch_rom) && i < ARRAY_SIZE(scratch_ram); i++) {
|
||||||
@ -69,12 +76,10 @@ int scratch_trampoline(void) {
|
|||||||
SCAR4L = 0x00;
|
SCAR4L = 0x00;
|
||||||
SCAR4M = 0x08;
|
SCAR4M = 0x08;
|
||||||
SCAR4H = 0x00;
|
SCAR4H = 0x00;
|
||||||
|
}
|
||||||
|
|
||||||
// Jump to scratch reset function
|
// Jump to reset function
|
||||||
__asm__("ljmp 0");
|
__asm__("ljmp 0");
|
||||||
|
|
||||||
// Should never happen
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finish segment located at 0x1000
|
// Finish segment located at 0x1000
|
||||||
|
@ -23,7 +23,7 @@ extern struct Pmc __code PMC_1;
|
|||||||
|
|
||||||
uint8_t pmc_status(struct Pmc * pmc);
|
uint8_t pmc_status(struct Pmc * pmc);
|
||||||
uint8_t pmc_read(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(0x1500) PM1STS;
|
||||||
volatile uint8_t __xdata __at(0x1501) PM1DO;
|
volatile uint8_t __xdata __at(0x1501) PM1DO;
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#define printf printf_small
|
||||||
|
|
||||||
#include <scratch/pmc.h>
|
#include <scratch/pmc.h>
|
||||||
|
|
||||||
@ -28,20 +30,73 @@ static int flash_transaction(uint32_t offset, uint8_t * data, int length, bool r
|
|||||||
return i;
|
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 void pmc_event(struct Pmc * pmc) {
|
||||||
|
static enum PmcState state = PMC_STATE_DEFAULT;
|
||||||
|
|
||||||
uint8_t sts = pmc_status(pmc);
|
uint8_t sts = pmc_status(pmc);
|
||||||
if (sts & PMC_STS_IBF) {
|
if (sts & PMC_STS_IBF) {
|
||||||
uint8_t data = pmc_read(pmc);
|
uint8_t data = pmc_read(pmc);
|
||||||
|
//printf("%x\n", data);
|
||||||
if (sts & PMC_STS_CMD) {
|
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
|
// Main program while running in scratch ROM
|
||||||
void main(void) {
|
void main(void) {
|
||||||
|
printf("scratch\n");
|
||||||
for (;;) {
|
for (;;) {
|
||||||
pmc_event(&PMC_1);
|
pmc_event(&PMC_1);
|
||||||
}
|
}
|
||||||
|
@ -17,16 +17,8 @@ uint8_t pmc_read(struct Pmc * pmc) {
|
|||||||
return *(pmc->data_in);
|
return *(pmc->data_in);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool pmc_wait(struct Pmc * pmc, int timeout) {
|
bool pmc_write(struct Pmc * pmc, uint8_t data) {
|
||||||
while (pmc_status(pmc) & PMC_STS_OBF) {
|
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;
|
|
||||||
*(pmc->data_out) = data;
|
*(pmc->data_out) = data;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
8
src/board/system76/galp3-c/scratch/stdio.c
Normal file
8
src/board/system76/galp3-c/scratch/stdio.c
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#include <mcs51/8051.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int putchar(int c) {
|
||||||
|
unsigned char byte = (unsigned char)c;
|
||||||
|
SBUF = byte;
|
||||||
|
return (int)byte;
|
||||||
|
}
|
@ -1,9 +1,13 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <mcs51/8051.h>
|
||||||
|
|
||||||
#include <common/i2c.h>
|
#ifdef I2C_DEBUGGER
|
||||||
|
#include <common/i2c.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
int putchar(int c) {
|
int putchar(int c) {
|
||||||
unsigned char byte = (unsigned char)c;
|
unsigned char byte = (unsigned char)c;
|
||||||
|
SBUF = byte;
|
||||||
#ifdef I2C_DEBUGGER
|
#ifdef I2C_DEBUGGER
|
||||||
i2c_send(I2C_DEBUGGER, &byte, 1);
|
i2c_send(I2C_DEBUGGER, &byte, 1);
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user