Add timeout for kbc and pmc writes

This commit is contained in:
Jeremy Soller
2019-11-08 13:40:10 -07:00
parent 4269b25ecf
commit 1f87adb1fc
7 changed files with 61 additions and 36 deletions

View File

@ -1,6 +1,7 @@
#ifndef _EC_KBC_H
#define _EC_KBC_H
#include <stdbool.h>
#include <stdint.h>
void kbc_init(void);
@ -28,8 +29,8 @@ extern struct Kbc __code KBC;
uint8_t kbc_status(struct Kbc * kbc);
uint8_t kbc_read(struct Kbc * kbc);
void kbc_keyboard(struct Kbc * kbc, uint8_t data);
void kbc_mouse(struct Kbc * kbc, uint8_t data);
bool kbc_keyboard(struct Kbc * kbc, uint8_t data, int timeout);
bool kbc_mouse(struct Kbc * kbc, uint8_t data, int timeout);
volatile uint8_t __xdata __at(0x1300) KBHICR;
volatile uint8_t __xdata __at(0x1302) KBIRQR;

View File

@ -1,6 +1,7 @@
#ifndef _EC_PMC_H
#define _EC_PMC_H
#include <stdbool.h>
#include <stdint.h>
struct Pmc {
@ -23,7 +24,7 @@ extern struct Pmc __code PMC_2;
uint8_t pmc_status(struct Pmc * pmc);
uint8_t pmc_read(struct Pmc * pmc);
void pmc_write(struct Pmc * pmc, uint8_t data);
bool pmc_write(struct Pmc * pmc, uint8_t data, int timeout);
void pmc_event(struct Pmc * pmc);

View File

@ -17,14 +17,23 @@ uint8_t kbc_read(struct Kbc * kbc) {
return *(kbc->data_in);
}
void kbc_keyboard(struct Kbc * kbc, uint8_t data) {
//TODO: use timeout
while (kbc_status(kbc) & KBC_STS_OBF) {}
*(kbc->keyboard_out) = data;
static bool kbc_wait(struct Kbc * kbc, int timeout) {
while (kbc_status(kbc) & KBC_STS_OBF) {
if (timeout == 0) return false;
timeout -= 1;
}
return true;
}
void kbc_mouse(struct Kbc * kbc, uint8_t data) {
//TODO: use timeout
while (kbc_status(kbc) & KBC_STS_OBF) {}
*(kbc->mouse_out) = data;
bool kbc_keyboard(struct Kbc * kbc, uint8_t data, int timeout) {
if (!kbc_wait(kbc, timeout)) return false;
*(kbc->keyboard_out) = data;
return true;
}
bool kbc_mouse(struct Kbc * kbc, uint8_t data, int timeout) {
if (!kbc_wait(kbc, timeout)) return false;
*(kbc->mouse_out) = data;
return true;
}

View File

@ -21,12 +21,22 @@ uint8_t pmc_read(struct Pmc * pmc) {
return *(pmc->data_in);
}
void pmc_write(struct Pmc * pmc, uint8_t data) {
//TODO: use timeout
while (pmc_status(pmc) & PMC_STS_OBF) {}
*(pmc->data_out) = data;
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;
*(pmc->data_out) = data;
return true;
}
#define PMC_TIMEOUT 1000
enum PmcState {
PMC_STATE_DEFAULT,
PMC_STATE_ACPI_READ,
@ -55,7 +65,7 @@ void pmc_event(struct Pmc * pmc) {
case 0x82:
printf(" burst enable\n");
// TODO: figure out what burst is
pmc_write(pmc, 0x90);
pmc_write(pmc, 0x90, PMC_TIMEOUT);
break;
case 0x83:
printf(" burst disable\n");
@ -64,7 +74,7 @@ void pmc_event(struct Pmc * pmc) {
case 0x84:
printf(" SCI queue\n");
// TODO: queue is always empty
pmc_write(pmc, 0);
pmc_write(pmc, 0, PMC_TIMEOUT);
break;
}
} else {
@ -74,7 +84,7 @@ void pmc_event(struct Pmc * pmc) {
case PMC_STATE_ACPI_READ:
state = PMC_STATE_DEFAULT;
uint8_t value = acpi_read(data);
pmc_write(pmc, value);
pmc_write(pmc, value, PMC_TIMEOUT);
break;
case PMC_STATE_ACPI_WRITE:
state = PMC_STATE_ACPI_WRITE_ADDR;