diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..84c048a --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/build/ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..026e363 --- /dev/null +++ b/Makefile @@ -0,0 +1,21 @@ +SRC=$(wildcard src/*.c) +INCLUDE=$(wildcard src/include/*.h) +OBJ=$(patsubst src/%.c,build/%.rel,$(SRC)) + +all: build/ec.rom + +clean: + rm -rf build + +build/ec.rom: build/ec.ihx + mkdir -p build + makebin -p < $< > $@ + +build/ec.ihx: $(OBJ) + mkdir -p build + sdcc -mmcs51 -o $@ $< + +build/%.rel: src/%.c $(INCLUDE) + mkdir -p build + cd build && \ + sdcc -mmcs51 -c ../$< diff --git a/README.md b/README.md index d9218bf..0b68afe 100644 --- a/README.md +++ b/README.md @@ -1,2 +1 @@ -# ec -System76 EC (WIP) +# System76 EC (WIP) diff --git a/src/include/gctrl.h b/src/include/gctrl.h new file mode 100644 index 0000000..944c219 --- /dev/null +++ b/src/include/gctrl.h @@ -0,0 +1,8 @@ +#ifndef _GCTRL_H_ +#define _GCTRL_H_ + +__xdata volatile unsigned char __at(0x2006) RSTS; +__xdata volatile unsigned char __at(0x200A) BADRSEL; +__xdata volatile unsigned char __at(0x200D) SPCTRL1; + +#endif // _GCTRL_H_ diff --git a/src/include/gpio.h b/src/include/gpio.h new file mode 100644 index 0000000..a88d621 --- /dev/null +++ b/src/include/gpio.h @@ -0,0 +1,140 @@ +#ifndef _GPIO_H_ +#define _GPIO_H_ + +__xdata volatile unsigned char __at(0x1600) GCR; + +__xdata volatile unsigned char __at(0x1601) GPDRA; +__xdata volatile unsigned char __at(0x1602) GPDRB; +__xdata volatile unsigned char __at(0x1603) GPDRC; +__xdata volatile unsigned char __at(0x1604) GPDRD; +__xdata volatile unsigned char __at(0x1605) GPDRE; +__xdata volatile unsigned char __at(0x1606) GPDRF; +__xdata volatile unsigned char __at(0x1607) GPDRG; +__xdata volatile unsigned char __at(0x1608) GPDRH; +__xdata volatile unsigned char __at(0x1609) GPDRI; +__xdata volatile unsigned char __at(0x160A) GPDRJ; +__xdata volatile unsigned char __at(0x160D) GPDRM; + +__xdata volatile unsigned char __at(0x1661) GPDMRA; +__xdata volatile unsigned char __at(0x1662) GPDMRB; +__xdata volatile unsigned char __at(0x1663) GPDMRC; +__xdata volatile unsigned char __at(0x1664) GPDMRD; +__xdata volatile unsigned char __at(0x1665) GPDMRE; +__xdata volatile unsigned char __at(0x1666) GPDMRF; +__xdata volatile unsigned char __at(0x1667) GPDMRG; +__xdata volatile unsigned char __at(0x1668) GPDMRH; +__xdata volatile unsigned char __at(0x1669) GPDMRI; +__xdata volatile unsigned char __at(0x166A) GPDMRJ; +__xdata volatile unsigned char __at(0x166D) GPDMRM; + +__xdata volatile unsigned char __at(0x1671) GPOTA; +__xdata volatile unsigned char __at(0x1672) GPOTB; +__xdata volatile unsigned char __at(0x1673) GPOTC; +__xdata volatile unsigned char __at(0x1674) GPOTD; +__xdata volatile unsigned char __at(0x1675) GPOTE; +__xdata volatile unsigned char __at(0x1676) GPOTF; +__xdata volatile unsigned char __at(0x1677) GPOTG; +__xdata volatile unsigned char __at(0x1678) GPOTH; +__xdata volatile unsigned char __at(0x1679) GPOTI; +__xdata volatile unsigned char __at(0x167A) GPOTJ; +// GPOTM does not exist + +__xdata volatile unsigned char __at(0x1610) GPCRA0; +__xdata volatile unsigned char __at(0x1611) GPCRA1; +__xdata volatile unsigned char __at(0x1612) GPCRA2; +__xdata volatile unsigned char __at(0x1613) GPCRA3; +__xdata volatile unsigned char __at(0x1614) GPCRA4; +__xdata volatile unsigned char __at(0x1615) GPCRA5; +__xdata volatile unsigned char __at(0x1616) GPCRA6; +__xdata volatile unsigned char __at(0x1617) GPCRA7; + +__xdata volatile unsigned char __at(0x1618) GPCRB0; +__xdata volatile unsigned char __at(0x1619) GPCRB1; +__xdata volatile unsigned char __at(0x161A) GPCRB2; +__xdata volatile unsigned char __at(0x161B) GPCRB3; +__xdata volatile unsigned char __at(0x161C) GPCRB4; +__xdata volatile unsigned char __at(0x161D) GPCRB5; +__xdata volatile unsigned char __at(0x161E) GPCRB6; +__xdata volatile unsigned char __at(0x161F) GPCRB7; + +__xdata volatile unsigned char __at(0x1620) GPCRC0; +__xdata volatile unsigned char __at(0x1621) GPCRC1; +__xdata volatile unsigned char __at(0x1622) GPCRC2; +__xdata volatile unsigned char __at(0x1623) GPCRC3; +__xdata volatile unsigned char __at(0x1624) GPCRC4; +__xdata volatile unsigned char __at(0x1625) GPCRC5; +__xdata volatile unsigned char __at(0x1626) GPCRC6; +__xdata volatile unsigned char __at(0x1627) GPCRC7; + +__xdata volatile unsigned char __at(0x1628) GPCRD0; +__xdata volatile unsigned char __at(0x1629) GPCRD1; +__xdata volatile unsigned char __at(0x162A) GPCRD2; +__xdata volatile unsigned char __at(0x162B) GPCRD3; +__xdata volatile unsigned char __at(0x162C) GPCRD4; +__xdata volatile unsigned char __at(0x162D) GPCRD5; +__xdata volatile unsigned char __at(0x162E) GPCRD6; +__xdata volatile unsigned char __at(0x162F) GPCRD7; + +__xdata volatile unsigned char __at(0x1630) GPCRE0; +__xdata volatile unsigned char __at(0x1631) GPCRE1; +__xdata volatile unsigned char __at(0x1632) GPCRE2; +__xdata volatile unsigned char __at(0x1633) GPCRE3; +__xdata volatile unsigned char __at(0x1634) GPCRE4; +__xdata volatile unsigned char __at(0x1635) GPCRE5; +__xdata volatile unsigned char __at(0x1636) GPCRE6; +__xdata volatile unsigned char __at(0x1637) GPCRE7; + +__xdata volatile unsigned char __at(0x1638) GPCRF0; +__xdata volatile unsigned char __at(0x1639) GPCRF1; +__xdata volatile unsigned char __at(0x163A) GPCRF2; +__xdata volatile unsigned char __at(0x163B) GPCRF3; +__xdata volatile unsigned char __at(0x163C) GPCRF4; +__xdata volatile unsigned char __at(0x163D) GPCRF5; +__xdata volatile unsigned char __at(0x163E) GPCRF6; +__xdata volatile unsigned char __at(0x163F) GPCRF7; + +__xdata volatile unsigned char __at(0x1640) GPCRG0; +__xdata volatile unsigned char __at(0x1641) GPCRG1; +__xdata volatile unsigned char __at(0x1642) GPCRG2; +__xdata volatile unsigned char __at(0x1643) GPCRG3; +__xdata volatile unsigned char __at(0x1644) GPCRG4; +__xdata volatile unsigned char __at(0x1645) GPCRG5; +__xdata volatile unsigned char __at(0x1646) GPCRG6; +__xdata volatile unsigned char __at(0x1647) GPCRG7; + +__xdata volatile unsigned char __at(0x1648) GPCRH0; +__xdata volatile unsigned char __at(0x1649) GPCRH1; +__xdata volatile unsigned char __at(0x164A) GPCRH2; +__xdata volatile unsigned char __at(0x164B) GPCRH3; +__xdata volatile unsigned char __at(0x164C) GPCRH4; +__xdata volatile unsigned char __at(0x164D) GPCRH5; +__xdata volatile unsigned char __at(0x164E) GPCRH6; +__xdata volatile unsigned char __at(0x164F) GPCRH7; + +__xdata volatile unsigned char __at(0x1650) GPCRI0; +__xdata volatile unsigned char __at(0x1651) GPCRI1; +__xdata volatile unsigned char __at(0x1652) GPCRI2; +__xdata volatile unsigned char __at(0x1653) GPCRI3; +__xdata volatile unsigned char __at(0x1654) GPCRI4; +__xdata volatile unsigned char __at(0x1655) GPCRI5; +__xdata volatile unsigned char __at(0x1656) GPCRI6; +__xdata volatile unsigned char __at(0x1657) GPCRI7; + +__xdata volatile unsigned char __at(0x1658) GPCRJ0; +__xdata volatile unsigned char __at(0x1659) GPCRJ1; +__xdata volatile unsigned char __at(0x165A) GPCRJ2; +__xdata volatile unsigned char __at(0x165B) GPCRJ3; +__xdata volatile unsigned char __at(0x165C) GPCRJ4; +__xdata volatile unsigned char __at(0x165D) GPCRJ5; +__xdata volatile unsigned char __at(0x165E) GPCRJ6; +__xdata volatile unsigned char __at(0x165F) GPCRJ7; + +__xdata volatile unsigned char __at(0x16A0) GPCRM0; +__xdata volatile unsigned char __at(0x16A1) GPCRM1; +__xdata volatile unsigned char __at(0x16A2) GPCRM2; +__xdata volatile unsigned char __at(0x16A3) GPCRM3; +__xdata volatile unsigned char __at(0x16A4) GPCRM4; +__xdata volatile unsigned char __at(0x16A5) GPCRM5; +__xdata volatile unsigned char __at(0x16A6) GPCRM6; + +#endif // _GPIO_H_ diff --git a/src/include/kbc.h b/src/include/kbc.h new file mode 100644 index 0000000..f88f9c3 --- /dev/null +++ b/src/include/kbc.h @@ -0,0 +1,11 @@ +#ifndef _KBC_H_ +#define _KBC_H_ + +__xdata volatile unsigned char __at(0x1300) KBHICR; +__xdata volatile unsigned char __at(0x1302) KBIRQR; +__xdata volatile unsigned char __at(0x1304) KBHISR; +__xdata volatile unsigned char __at(0x1306) KBHIKDOR; +__xdata volatile unsigned char __at(0x1308) KBHIMDOR; +__xdata volatile unsigned char __at(0x130A) KBHIDIR; + +#endif // _KBC_H_ diff --git a/src/include/kbscan.h b/src/include/kbscan.h new file mode 100644 index 0000000..82a8964 --- /dev/null +++ b/src/include/kbscan.h @@ -0,0 +1,45 @@ +#ifndef _KBSCAN_H_ +#define _KBSCAN_H_ + +__xdata volatile unsigned char __at(0x1D00) KSOL; +__xdata volatile unsigned char __at(0x1D01) KSOH1; +__xdata volatile unsigned char __at(0x1D02) KSOCTRL; +__xdata volatile unsigned char __at(0x1D03) KSOH2; +__xdata volatile unsigned char __at(0x1D04) KSI; +__xdata volatile unsigned char __at(0x1D05) KSICTRLR; +__xdata volatile unsigned char __at(0x1D06) KSIGCTRL; +__xdata volatile unsigned char __at(0x1D07) KSIGOEN; +__xdata volatile unsigned char __at(0x1D08) KSIGDAT; +__xdata volatile unsigned char __at(0x1D09) KSIGDMRR; +__xdata volatile unsigned char __at(0x1D0A) KSOHGCTRL; +__xdata volatile unsigned char __at(0x1D0B) KSOHGOEN; +__xdata volatile unsigned char __at(0x1D0C) KSOHGDMRR; +__xdata volatile unsigned char __at(0x1D0D) KSOLGCTRL; +__xdata volatile unsigned char __at(0x1D0E) KSOLGOEN; +__xdata volatile unsigned char __at(0x1D0F) KSOLGDMRR; + +__xdata volatile unsigned char __at(0x1D10) KSO0LSDR; +__xdata volatile unsigned char __at(0x1D11) KSO1LSDR; +__xdata volatile unsigned char __at(0x1D12) KSO2LSDR; +__xdata volatile unsigned char __at(0x1D13) KSO3LSDR; +__xdata volatile unsigned char __at(0x1D14) KSO4LSDR; +__xdata volatile unsigned char __at(0x1D15) KSO5LSDR; +__xdata volatile unsigned char __at(0x1D16) KSO6LSDR; +__xdata volatile unsigned char __at(0x1D17) KSO7LSDR; +__xdata volatile unsigned char __at(0x1D18) KSO8LSDR; +__xdata volatile unsigned char __at(0x1D19) KSO9LSDR; +__xdata volatile unsigned char __at(0x1D1A) KSO10LSDR; +__xdata volatile unsigned char __at(0x1D1B) KSO11LSDR; +__xdata volatile unsigned char __at(0x1D1C) KSO12LSDR; +__xdata volatile unsigned char __at(0x1D1D) KSO13LSDR; +__xdata volatile unsigned char __at(0x1D1E) KSO14LSDR; +__xdata volatile unsigned char __at(0x1D1F) KSO15LSDR; +__xdata volatile unsigned char __at(0x1D20) KSO16LSDR; +__xdata volatile unsigned char __at(0x1D21) KSO17LSDR; + +__xdata volatile unsigned char __at(0x1D22) SDC1R; +__xdata volatile unsigned char __at(0x1D23) SDC2R; +__xdata volatile unsigned char __at(0x1D24) SDC3R; +__xdata volatile unsigned char __at(0x1D25) SDSR; + +#endif // _KBSCAN_H_ diff --git a/src/include/pmc.h b/src/include/pmc.h new file mode 100644 index 0000000..ce9cbe5 --- /dev/null +++ b/src/include/pmc.h @@ -0,0 +1,7 @@ +#ifndef _PMC_H_ +#define _PMC_H_ + +__xdata volatile unsigned char __at(0x1506) PM1CTL; +__xdata volatile unsigned char __at(0x1516) PM2CTL; + +#endif // _PMC_H_ diff --git a/src/include/ps2.h b/src/include/ps2.h new file mode 100644 index 0000000..0ffc9e5 --- /dev/null +++ b/src/include/ps2.h @@ -0,0 +1,20 @@ +#ifndef _PS2_H_ +#define _PS2_H_ + +__xdata volatile unsigned char __at(0x1700) PSCTL1; +__xdata volatile unsigned char __at(0x1701) PSCTL2; +__xdata volatile unsigned char __at(0x1702) PSCTL3; + +__xdata volatile unsigned char __at(0x1704) PSINT1; +__xdata volatile unsigned char __at(0x1705) PSINT2; +__xdata volatile unsigned char __at(0x1706) PSINT3; + +__xdata volatile unsigned char __at(0x1708) PSSTS1; +__xdata volatile unsigned char __at(0x1709) PSSTS2; +__xdata volatile unsigned char __at(0x170A) PSSTS3; + +__xdata volatile unsigned char __at(0x170C) PSDAT1; +__xdata volatile unsigned char __at(0x170D) PSDAT2; +__xdata volatile unsigned char __at(0x170E) PSDAT3; + +#endif // _PS2_H_ diff --git a/src/include/signature.h b/src/include/signature.h new file mode 100644 index 0000000..bc976e5 --- /dev/null +++ b/src/include/signature.h @@ -0,0 +1,12 @@ +#ifndef _SIGNATURE_H_ +#define _SIGNATURE_H_ + +static __code char __at(0x40) SIGNATURE[32] = { + 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0x94, + 0x85, 0x12, 0x5A, 0x5A, 0xAA, 0x00, 0x55, 0x55, + + 0x49, 0x54, 0x45, 0x20, 0x54, 0x65, 0x63, 0x68, + 0x2E, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x20, 0x20 +}; + +#endif // _SIGNATURE_H_ diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..f1181a1 --- /dev/null +++ b/src/main.c @@ -0,0 +1,280 @@ +#include "include/signature.h" + +void reset() { + __asm__("ljmp 0"); +} + +#include "include/gpio.h" + +void gpio_init() { + // Enable LPC reset on GPD2 + GCR = 0x04; + + // Set GPIO data + GPDRA = 0; + GPDRB = (1 << 0); + GPDRC = 0; + GPDRD = (1 << 5) | (1 << 4) | (1 << 3); + GPDRE = 0; + GPDRF = (1 << 7) | (1 << 6); + GPDRG = 0; + GPDRH = 0; + GPDRI = 0; + GPDRJ = 0; + + // Set GPIO control + GPCRA0 = 0x80; + GPCRA1 = 0x00; + GPCRA2 = 0x00; + GPCRA3 = 0x80; + GPCRA4 = 0x40; + GPCRA5 = 0x44; + GPCRA6 = 0x44; + GPCRA7 = 0x44; + GPCRB0 = 0x44; + GPCRB1 = 0x44; + GPCRB2 = 0x84; + GPCRB3 = 0x00; + GPCRB4 = 0x00; + GPCRB5 = 0x44; + GPCRB6 = 0x84; + GPCRB7 = 0x80; + GPCRC0 = 0x80; + GPCRC1 = 0x84; + GPCRC2 = 0x84; + GPCRC3 = 0x84; + GPCRC4 = 0x44; + GPCRC5 = 0x44; + GPCRC6 = 0x40; + GPCRC7 = 0x44; + GPCRD0 = 0x84; + GPCRD1 = 0x84; + GPCRD2 = 0x00; + GPCRD3 = 0x80; + GPCRD4 = 0x80; + GPCRD5 = 0x44; + GPCRD6 = 0x80; + GPCRD7 = 0x80; + GPCRE0 = 0x44; + GPCRE1 = 0x44; + GPCRE2 = 0x80; + GPCRE3 = 0x40; + GPCRE4 = 0x42; + GPCRE5 = 0x40; + GPCRE6 = 0x44; + GPCRE7 = 0x44; + GPCRF0 = 0x80; + GPCRF1 = 0x44; + GPCRF2 = 0x84; + GPCRF3 = 0x44; + GPCRF4 = 0x80; + GPCRF5 = 0x80; + GPCRF6 = 0x00; + GPCRF7 = 0x80; + GPCRG0 = 0x44; + GPCRG1 = 0x44; + GPCRG2 = 0x40; + GPCRG3 = 0x00; + GPCRG4 = 0x00; + GPCRG5 = 0x00; + GPCRG6 = 0x44; + GPCRG7 = 0x00; + GPCRH0 = 0x00; + GPCRH1 = 0x80; + GPCRH2 = 0x44; + GPCRH3 = 0x44; + GPCRH4 = 0x80; + GPCRH5 = 0x80; + GPCRH6 = 0x80; + GPCRH7 = 0x80; + GPCRI0 = 0x00; + GPCRI1 = 0x00; + GPCRI2 = 0x80; + GPCRI3 = 0x00; + GPCRI4 = 0x00; + GPCRI5 = 0x80; + GPCRI6 = 0x80; + GPCRI7 = 0x80; + GPCRJ0 = 0x82; + GPCRJ1 = 0x80; + GPCRJ2 = 0x40; + GPCRJ3 = 0x80; + GPCRJ4 = 0x44; + GPCRJ5 = 0x40; + GPCRJ6 = 0x44; + GPCRJ7 = 0x80; +} + +#include "include/gctrl.h" + +void gctrl_init() { + SPCTRL1 = 0x03; + BADRSEL = 0; + RSTS = 0x84; +} + +#include "include/kbc.h" + +void kbc_init() { + KBIRQR = 0; + KBHICR = 0x48; +} + +#include "include/pmc.h" + +void pmc_init() { + PM1CTL = 0x41; + PM2CTL = 0x41; +} + +#include "include/ps2.h" + +void ps2_init() { + PSCTL1 = 0x11; + PSCTL2 = 0x41; + PSCTL3 = 0x41; + PSINT1 = 0x04; + PSINT2 = 0x04; + PSINT3 = 0x04; +} + +#include "include/kbscan.h" + +void kbscan_init() { + KSOCTRL = 0x05; + KSICTRLR = 0x04; + + // Set all outputs to GPIO mode and high + KSOH2 = 0xFF; + KSOH1 = 0xFF; + KSOL = 0xFF; + KSOHGCTRL = 0xFF; + KSOHGOEN = 0xFF; + KSOLGCTRL = 0xFF; + KSOLGOEN = 0xFF; +} + +#include <8051.h> + +void timer_clear(void) { + TR0 = 0; + TF0 = 0; +} + +void timer_mode_1(int value) { + timer_clear(); + TMOD = 0x01; + TH0 = (unsigned char)(value >> 8); + TL0 = (unsigned char)value; + TR0 = 1; +} + +void delay_ms(int ms) { + for (int i = 0; i < ms; i++) { + // One millisecond in ticks is determined as follows: + // 9.2 MHz is the clock rate + // The timer divider is 12 + // The timer rate is 12 / 9.2 MHz = 1.304 us + // The ticks are 1000 ms / (1.304 us) = 766.667 + // 65536 - 766.667 = 64769.33 + timer_mode_1(64769); + while (TF0 == 0) {} + timer_clear(); + } +} + +#include + +struct Pin { + __xdata volatile unsigned char * data; + __xdata volatile unsigned char * mirror; + __xdata volatile unsigned char * control; + unsigned char value; +}; + +#define PIN(BLOCK, NUMBER) { \ + .data = &GPDR ## BLOCK, \ + .mirror = &GPDMR ## BLOCK, \ + .control = &GPCR ## BLOCK ## NUMBER, \ + .value = (1 << NUMBER), \ +} + +bool pin_get(struct Pin * pin) { + if (*(pin->data) & pin->value) { + return true; + } else { + return false; + } +} + +void pin_set(struct Pin * pin, bool value) { + if (value) { + *(pin->data) |= pin->value; + } else { + *(pin->data) &= ~(pin->value); + } +} + +struct Pin LED_BAT_CHG = PIN(A, 5); +struct Pin LED_BAT_FULL = PIN(A, 6); +struct Pin LED_PWR = PIN(A, 7); +struct Pin LED_ACIN = PIN(C, 7); +struct Pin LED_AIRPLANE_N = PIN(G, 6); + +struct Pin PWR_SW = PIN(D, 0); + +void parallel_write(unsigned char value) { + // Make sure clock is high + KSOH1 = 0xFF; + delay_ms(1); + + // Set value + KSOL = value; + delay_ms(1); + + // Set clock low + KSOH1 = 0; + pin_set(&LED_ACIN, true); + delay_ms(1); + + // Set clock high again + pin_set(&LED_ACIN, false); + KSOH1 = 0xFF; +} + +void puts(const char * s) { + char c; + while (c = *(s++)) { + parallel_write((unsigned char)c); + } +} + +void main() { + gpio_init(); + + gctrl_init(); + + kbc_init(); + + pmc_init(); + + kbscan_init(); + + //TODO: INTC, PECI, PWM, SMBUS + + // Set the battery full LED (to know our firmware is loaded) + pin_set(&LED_BAT_CHG, true); + delay_ms(1000); + pin_set(&LED_BAT_FULL, true); + puts("Hello from System76 EC!\n"); + + bool last = false; + for(;;) { + // Check if the power switch goes low + bool new = pin_get(&PWR_SW); + if (!new && last) { + puts("Power Switch\n"); + } + last = new; + } +}