Implement flashing from scratch rom

This commit is contained in:
Jeremy Soller
2019-11-20 15:08:17 -07:00
parent 68ed5913dd
commit 97db2bd339
8 changed files with 120 additions and 46 deletions

View File

@ -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);

View File

@ -1,5 +1,6 @@
#include <board/acpi.h>
#include <board/pmc.h>
#include <board/scratch.h>
#include <common/debug.h>
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);

View File

@ -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

View File

@ -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;

View File

@ -1,5 +1,7 @@
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#define printf printf_small
#include <scratch/pmc.h>
@ -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);
}

View File

@ -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;
}

View 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;
}

View File

@ -1,9 +1,13 @@
#include <stdio.h>
#include <mcs51/8051.h>
#include <common/i2c.h>
#ifdef I2C_DEBUGGER
#include <common/i2c.h>
#endif
int putchar(int c) {
unsigned char byte = (unsigned char)c;
SBUF = byte;
#ifdef I2C_DEBUGGER
i2c_send(I2C_DEBUGGER, &byte, 1);
#endif