Idwer Vollering (vidwer@gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/6159
-gerrit
commit 7fc56bf9c0426f04267271b8e57853f95143708c Author: Idwer Vollering vidwer@gmail.com Date: Mon Jun 30 04:00:23 2014 +0200
[3/4] HP DL120G5: BMC code
Change-Id: I39fdac61f3ecab611b737815143caa2e0bea9848 Signed-off-by: Ruud Schramp schramp@holmes.nl Signed-off-by: Idwer Vollering vidwer@gmail.com --- SerialICE/bmc/ipmi.c | 253 +++++++++++++++++++++++++++++++++++++++++++ SerialICE/bmc/ipmi_disable.c | 37 +++++++ 2 files changed, 290 insertions(+)
diff --git a/SerialICE/bmc/ipmi.c b/SerialICE/bmc/ipmi.c new file mode 100644 index 0000000..52f1153 --- /dev/null +++ b/SerialICE/bmc/ipmi.c @@ -0,0 +1,253 @@ +/* + * SerialICE + * + * Copyright (C) 2011 Netherlands Forensic Institute + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * This is an example of lowlevel code for disabeling the BMC serial + * communication. + */ + +#define nftransport 0xc + +#define OBF (1 << 0) +#define IBF (1 << 1) + +#define ipmidata 0xca2 +#define ipmicsr 0xca3 + +#if 0 +static u8 i_n_b_debug(u16 port) +{ + u8 d=inb(port); + outb(d,0x80); + return d; +} + +#define inb i_n_b_debug +#endif + +#if 0 +static char * print_binary(char val) +{ + static char strbuf[20]; + char *dat=strbuf; + unsigned char mask=0x80; + while (mask!=0) { + *dat= (val & mask) ? '1' : '0'; + mask = mask>>1; + dat++; + }; + *dat=0; + return strbuf; +}; +#endif + +static int writestateQ(void) +{ + return ((inb(ipmicsr)>>6)==0x10); +} + +static int readstateQ(void) +{ + return ((inb(ipmicsr)>>6)==0x01); +} + +static int idlestateQ(void) +{ + return ((inb(ipmicsr)>>6)==0x00); +} + +static inline void ibfzero(void) +{ + while(inb(ipmicsr) & IBF) + ; +} +static inline void clearobf(void) +{ + (void) inb(ipmidata); +} + +static inline void waitobf(void) +{ + while((inb(ipmicsr) & OBF) == 0) + ; +} + +/* quite possibly the stupidest interface ever designed. */ +static inline void first_cmd_byte(unsigned char byte) +{ + ibfzero(); + clearobf(); + outb(0x61, ipmicsr); + ibfzero(); + clearobf(); + outb(byte, ipmidata); +} + +static inline void next_cmd_byte(unsigned char byte) +{ + ibfzero(); + clearobf(); + outb(byte, ipmidata); +} + +static inline void last_cmd_byte(unsigned char byte) +{ + ibfzero(); + clearobf(); + outb(0x62, ipmicsr); + + ibfzero(); + clearobf(); + outb(byte, ipmidata); +} + +static inline void getStatus(void ) +{ + do { + ibfzero(); + outb(0x60, ipmicsr); + ibfzero(); + clearobf(); + outb(0, ipmidata); + ibfzero(); + } while (!readstateQ()); + waitobf(); + + int val=inb(ipmidata); + outb(val,ipmidata); + ibfzero(); + waitobf(); + clearobf(); +} + + +static inline void read_response_byte(void) +{ + int val = -1; + if ((inb(ipmicsr)>>6) != 1) //Check state=0x01 (READ); + return; + + ibfzero(); + waitobf(); + val = inb(ipmidata); + outb(0x68, ipmidata); + + /* see if it is done */ + if ((inb(ipmicsr)>>6) != 1){ + /* wait for the dummy read. Which describes this protocol */ + waitobf(); + (void)inb(ipmidata); + } +} + +static inline void ipmidelay(void) +{ + int i; + for(i = 0; i < 10; i++) { + inb(0x80); + } +} + +static void earlydbg(char POST) +{ + outb(POST,0x80); +} + +static inline void ipmi_request(const char *Start, const char *End) +{ + unsigned char c; + /* be safe; make sure it is really ready */ + while ((inb(ipmicsr)>>6)) { //Not IDLE + outb(inb(ipmicsr),0x80); + outb(0x60, ipmicsr); //abort + + }; + + first_cmd_byte(*Start); + ipmidelay(); + Start++; + + while( (int) Start< ((int) End -1)) { + next_cmd_byte(*Start); + ipmidelay(); + Start++; + }; + + last_cmd_byte(*Start); + ipmidelay(); +} + +static void ipmi_transaction(const char *Start, const char *End) +{ + ipmi_request(Start,End); + ibfzero(); + while(readstateQ()) { + char val; + waitobf(); + val=inb(ipmidata); + outb(0x68,ipmidata); + ipmidelay(); + ibfzero(); + }; + if (idlestateQ()) { +// char val; +// waitobf(); +// val = inb(ipmidata); + } else { + getStatus(); + } +} + + + +const char channel_access[]={0x06<<2,0x40,0x04,0x80,0x05}; +const char serialmodem_conf[]={0x0c<<2,0x10,0x04,0x08,0x00,0x0f}; +const char serial_mux1[]={0x0c<<2,0x12,0x04,0x06}; +const char serial_mux2[]={0x0c<<2,0x12,0x04,0x03}; +const char serial_mux3[]={0x0c<<2,0x12,0x04,0x07}; + +static void setup_early_ipmi_serial(void ) +{ +// earlydbg(0x0d); + //set channel access system only +// ipmi_transaction(channel_access,channel_access+sizeof(channel_access)); + while ((inb(ipmicsr)>>6)) { //Not IDLE + outb(inb(ipmicsr),0x80); + outb(0x60, ipmicsr); //abort + getStatus(); + }; + + //Set serial/modem config +// ipmi_transaction(serialmodem_conf,serialmodem_conf+sizeof(serialmodem_conf)); +// earlydbg(result); + + //Set serial mux 1 +// ipmi_transaction(serial_mux1,serial_mux1+sizeof(serial_mux1)); +// earlydbg(result); + + //Set serial mux 2 + ipmi_transaction(serial_mux2,serial_mux2+sizeof(serial_mux2)); + + //Set serial mux 3 +// ipmi_transaction(serial_mux3,serial_mux3+sizeof(serial_mux3)); + + earlydbg(0x0e); + +} + diff --git a/SerialICE/bmc/ipmi_disable.c b/SerialICE/bmc/ipmi_disable.c new file mode 100644 index 0000000..5c70f11 --- /dev/null +++ b/SerialICE/bmc/ipmi_disable.c @@ -0,0 +1,37 @@ +/* + * SerialICE + * + * Copyright (C) 2011 Netherlands Forensic Institute + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * This is an example of lowlevel code for disabeling the BMC serial + * communication. + */ +#include <stdio.h> +#include <sys/io.h> + +#include "ipmi.c" + +int main(int argc, char **argv) +{ + iopl(3); + ioperm(0x80, 0x20 , 1); + earlydbg(0x12); + getStatus(); + setup_early_ipmi_serial(); +}; +