Use state machine instead of timeout in PMC code

This commit is contained in:
Jeremy Soller 2020-02-17 14:19:05 -07:00
parent ce2318c4f0
commit ac4d15b395
No known key found for this signature in database
GPG Key ID: E988B49EE78A7FB1
8 changed files with 65 additions and 64 deletions

View File

@ -10,10 +10,9 @@ void pmc_init(void) {
*(PMC_2.control) = 0x41; *(PMC_2.control) = 0x41;
} }
#define PMC_TIMEOUT 10000
enum PmcState { enum PmcState {
PMC_STATE_DEFAULT, PMC_STATE_DEFAULT,
PMC_STATE_WRITE,
PMC_STATE_ACPI_READ, PMC_STATE_ACPI_READ,
PMC_STATE_ACPI_WRITE, PMC_STATE_ACPI_WRITE,
PMC_STATE_ACPI_WRITE_ADDR, PMC_STATE_ACPI_WRITE_ADDR,
@ -58,6 +57,18 @@ void pmc_event(struct Pmc * pmc) {
uint8_t burst_timeout; uint8_t burst_timeout;
for (burst_timeout = 1; burst_timeout > 0; burst_timeout--) { for (burst_timeout = 1; burst_timeout > 0; burst_timeout--) {
uint8_t sts = pmc_status(pmc); uint8_t sts = pmc_status(pmc);
if (!(sts & PMC_STS_OBF)) {
switch (state) {
case PMC_STATE_WRITE:
DEBUG("pmc write: %02X\n", state_data);
state = PMC_STATE_DEFAULT;
pmc_write(pmc, state_data);
// Send SCI for OBF=1
pmc_sci_interrupt();
break;
}
}
if (sts & PMC_STS_IBF) { if (sts & PMC_STS_IBF) {
uint8_t data = pmc_read(pmc); uint8_t data = pmc_read(pmc);
if (sts & PMC_STS_CMD) { if (sts & PMC_STS_CMD) {
@ -82,9 +93,8 @@ void pmc_event(struct Pmc * pmc) {
// Set burst bit // Set burst bit
pmc_set_status(pmc, sts | (1 << 4)); pmc_set_status(pmc, sts | (1 << 4));
// Send acknowledgement byte // Send acknowledgement byte
pmc_write(pmc, 0x90, PMC_TIMEOUT); state = PMC_STATE_WRITE;
// Send SCI for OBF=1 state_data = 0x90;
pmc_sci_interrupt();
break; break;
case 0x83: case 0x83:
DEBUG(" burst disable\n"); DEBUG(" burst disable\n");
@ -100,16 +110,15 @@ void pmc_event(struct Pmc * pmc) {
// Clear SCI pending bit // Clear SCI pending bit
pmc_set_status(pmc, sts & ~(1 << 5)); pmc_set_status(pmc, sts & ~(1 << 5));
// Send SCI queue // Send SCI queue
pmc_write(pmc, pmc_sci_queue, PMC_TIMEOUT); state = PMC_STATE_WRITE;
state_data = pmc_sci_queue;
// Clear SCI queue // Clear SCI queue
pmc_sci_queue = 0; pmc_sci_queue = 0;
// Send SCI for OBF=1
pmc_sci_interrupt();
break; break;
case 0xEC: case 0xEC:
DEBUG(" scratch rom\n"); DEBUG(" scratch rom\n");
pmc_write(pmc, 0x76, PMC_TIMEOUT); pmc_write(pmc, 0x76);
scratch_trampoline(); scratch_trampoline();
break; break;
} }
@ -118,11 +127,9 @@ void pmc_event(struct Pmc * pmc) {
switch (state) { switch (state) {
case PMC_STATE_ACPI_READ: case PMC_STATE_ACPI_READ:
state = PMC_STATE_DEFAULT; // Send byte from ACPI space
state = PMC_STATE_WRITE;
state_data = acpi_read(data); state_data = acpi_read(data);
pmc_write(pmc, state_data, PMC_TIMEOUT);
// Send SCI for OBF=1
pmc_sci_interrupt();
break; break;
case PMC_STATE_ACPI_WRITE: case PMC_STATE_ACPI_WRITE:
state = PMC_STATE_ACPI_WRITE_ADDR; state = PMC_STATE_ACPI_WRITE_ADDR;

View File

@ -10,10 +10,9 @@ void pmc_init(void) {
*(PMC_2.control) = 0x41; *(PMC_2.control) = 0x41;
} }
#define PMC_TIMEOUT 10000
enum PmcState { enum PmcState {
PMC_STATE_DEFAULT, PMC_STATE_DEFAULT,
PMC_STATE_WRITE,
PMC_STATE_ACPI_READ, PMC_STATE_ACPI_READ,
PMC_STATE_ACPI_WRITE, PMC_STATE_ACPI_WRITE,
PMC_STATE_ACPI_WRITE_ADDR, PMC_STATE_ACPI_WRITE_ADDR,
@ -58,6 +57,18 @@ void pmc_event(struct Pmc * pmc) {
uint8_t burst_timeout; uint8_t burst_timeout;
for (burst_timeout = 1; burst_timeout > 0; burst_timeout--) { for (burst_timeout = 1; burst_timeout > 0; burst_timeout--) {
uint8_t sts = pmc_status(pmc); uint8_t sts = pmc_status(pmc);
if (!(sts & PMC_STS_OBF)) {
switch (state) {
case PMC_STATE_WRITE:
DEBUG("pmc write: %02X\n", state_data);
state = PMC_STATE_DEFAULT;
pmc_write(pmc, state_data);
// Send SCI for OBF=1
pmc_sci_interrupt();
break;
}
}
if (sts & PMC_STS_IBF) { if (sts & PMC_STS_IBF) {
uint8_t data = pmc_read(pmc); uint8_t data = pmc_read(pmc);
if (sts & PMC_STS_CMD) { if (sts & PMC_STS_CMD) {
@ -82,9 +93,8 @@ void pmc_event(struct Pmc * pmc) {
// Set burst bit // Set burst bit
pmc_set_status(pmc, sts | (1 << 4)); pmc_set_status(pmc, sts | (1 << 4));
// Send acknowledgement byte // Send acknowledgement byte
pmc_write(pmc, 0x90, PMC_TIMEOUT); state = PMC_STATE_WRITE;
// Send SCI for OBF=1 state_data = 0x90;
pmc_sci_interrupt();
break; break;
case 0x83: case 0x83:
DEBUG(" burst disable\n"); DEBUG(" burst disable\n");
@ -100,16 +110,15 @@ void pmc_event(struct Pmc * pmc) {
// Clear SCI pending bit // Clear SCI pending bit
pmc_set_status(pmc, sts & ~(1 << 5)); pmc_set_status(pmc, sts & ~(1 << 5));
// Send SCI queue // Send SCI queue
pmc_write(pmc, pmc_sci_queue, PMC_TIMEOUT); state = PMC_STATE_WRITE;
state_data = pmc_sci_queue;
// Clear SCI queue // Clear SCI queue
pmc_sci_queue = 0; pmc_sci_queue = 0;
// Send SCI for OBF=1
pmc_sci_interrupt();
break; break;
case 0xEC: case 0xEC:
DEBUG(" scratch rom\n"); DEBUG(" scratch rom\n");
pmc_write(pmc, 0x76, PMC_TIMEOUT); pmc_write(pmc, 0x76);
scratch_trampoline(); scratch_trampoline();
break; break;
} }
@ -118,11 +127,9 @@ void pmc_event(struct Pmc * pmc) {
switch (state) { switch (state) {
case PMC_STATE_ACPI_READ: case PMC_STATE_ACPI_READ:
state = PMC_STATE_DEFAULT; // Send byte from ACPI space
state = PMC_STATE_WRITE;
state_data = acpi_read(data); state_data = acpi_read(data);
pmc_write(pmc, state_data, PMC_TIMEOUT);
// Send SCI for OBF=1
pmc_sci_interrupt();
break; break;
case PMC_STATE_ACPI_WRITE: case PMC_STATE_ACPI_WRITE:
state = PMC_STATE_ACPI_WRITE_ADDR; state = PMC_STATE_ACPI_WRITE_ADDR;

View File

@ -1,7 +1,7 @@
EC=it5570e EC=it5570e
# Add keymap to src # Add keymap to src
KEYMAP?=default KEYMAP?=jeremy
SRC+=$(BOARD_DIR)/keymap/$(KEYMAP).c SRC+=$(BOARD_DIR)/keymap/$(KEYMAP).c
# Set log level # Set log level

View File

@ -10,10 +10,9 @@ void pmc_init(void) {
*(PMC_2.control) = 0x41; *(PMC_2.control) = 0x41;
} }
#define PMC_TIMEOUT 10000
enum PmcState { enum PmcState {
PMC_STATE_DEFAULT, PMC_STATE_DEFAULT,
PMC_STATE_WRITE,
PMC_STATE_ACPI_READ, PMC_STATE_ACPI_READ,
PMC_STATE_ACPI_WRITE, PMC_STATE_ACPI_WRITE,
PMC_STATE_ACPI_WRITE_ADDR, PMC_STATE_ACPI_WRITE_ADDR,
@ -58,6 +57,18 @@ void pmc_event(struct Pmc * pmc) {
uint8_t burst_timeout; uint8_t burst_timeout;
for (burst_timeout = 1; burst_timeout > 0; burst_timeout--) { for (burst_timeout = 1; burst_timeout > 0; burst_timeout--) {
uint8_t sts = pmc_status(pmc); uint8_t sts = pmc_status(pmc);
if (!(sts & PMC_STS_OBF)) {
switch (state) {
case PMC_STATE_WRITE:
DEBUG("pmc write: %02X\n", state_data);
state = PMC_STATE_DEFAULT;
pmc_write(pmc, state_data);
// Send SCI for OBF=1
pmc_sci_interrupt();
break;
}
}
if (sts & PMC_STS_IBF) { if (sts & PMC_STS_IBF) {
uint8_t data = pmc_read(pmc); uint8_t data = pmc_read(pmc);
if (sts & PMC_STS_CMD) { if (sts & PMC_STS_CMD) {
@ -82,9 +93,8 @@ void pmc_event(struct Pmc * pmc) {
// Set burst bit // Set burst bit
pmc_set_status(pmc, sts | (1 << 4)); pmc_set_status(pmc, sts | (1 << 4));
// Send acknowledgement byte // Send acknowledgement byte
pmc_write(pmc, 0x90, PMC_TIMEOUT); state = PMC_STATE_WRITE;
// Send SCI for OBF=1 state_data = 0x90;
pmc_sci_interrupt();
break; break;
case 0x83: case 0x83:
DEBUG(" burst disable\n"); DEBUG(" burst disable\n");
@ -100,16 +110,15 @@ void pmc_event(struct Pmc * pmc) {
// Clear SCI pending bit // Clear SCI pending bit
pmc_set_status(pmc, sts & ~(1 << 5)); pmc_set_status(pmc, sts & ~(1 << 5));
// Send SCI queue // Send SCI queue
pmc_write(pmc, pmc_sci_queue, PMC_TIMEOUT); state = PMC_STATE_WRITE;
state_data = pmc_sci_queue;
// Clear SCI queue // Clear SCI queue
pmc_sci_queue = 0; pmc_sci_queue = 0;
// Send SCI for OBF=1
pmc_sci_interrupt();
break; break;
case 0xEC: case 0xEC:
DEBUG(" scratch rom\n"); DEBUG(" scratch rom\n");
pmc_write(pmc, 0x76, PMC_TIMEOUT); pmc_write(pmc, 0x76);
scratch_trampoline(); scratch_trampoline();
break; break;
} }
@ -118,11 +127,9 @@ void pmc_event(struct Pmc * pmc) {
switch (state) { switch (state) {
case PMC_STATE_ACPI_READ: case PMC_STATE_ACPI_READ:
state = PMC_STATE_DEFAULT; // Send byte from ACPI space
state = PMC_STATE_WRITE;
state_data = acpi_read(data); state_data = acpi_read(data);
pmc_write(pmc, state_data, PMC_TIMEOUT);
// Send SCI for OBF=1
pmc_sci_interrupt();
break; break;
case PMC_STATE_ACPI_WRITE: case PMC_STATE_ACPI_WRITE:
state = PMC_STATE_ACPI_WRITE_ADDR; state = PMC_STATE_ACPI_WRITE_ADDR;

View File

@ -28,7 +28,7 @@ extern struct Pmc __code PMC_5;
uint8_t pmc_status(struct Pmc * pmc); uint8_t pmc_status(struct Pmc * pmc);
void pmc_set_status(struct Pmc * pmc, uint8_t status); void pmc_set_status(struct Pmc * pmc, uint8_t status);
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); void 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;

View File

@ -25,16 +25,6 @@ uint8_t pmc_read(struct Pmc * pmc) {
return *(pmc->data_in); return *(pmc->data_in);
} }
static bool pmc_wait(struct Pmc * pmc, int timeout) { void pmc_write(struct Pmc * pmc, uint8_t data) {
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;
} }

View File

@ -28,7 +28,7 @@ extern struct Pmc __code PMC_5;
uint8_t pmc_status(struct Pmc * pmc); uint8_t pmc_status(struct Pmc * pmc);
void pmc_set_status(struct Pmc * pmc, uint8_t status); void pmc_set_status(struct Pmc * pmc, uint8_t status);
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); void 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;

View File

@ -25,16 +25,6 @@ uint8_t pmc_read(struct Pmc * pmc) {
return *(pmc->data_in); return *(pmc->data_in);
} }
static bool pmc_wait(struct Pmc * pmc, int timeout) { void pmc_write(struct Pmc * pmc, uint8_t data) {
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;
} }