Rudolf Marek ([email protected]) just uploaded a new patch set to gerrit, 
which you can find at http://review.coreboot.org/1096

-gerrit

commit 2eea3421b95a5b1127805ac623ea5a16cfae2e83
Author: Rudolf Marek <[email protected]>
Date:   Tue Jun 5 00:29:45 2012 +0200

    Hack in the target part of serialICE this needs to be done in more sane way.
    
    Just some quick and dirty way of using real serialICE.
    
    Change-Id: I4b39eba9526bdd21e99044bc5f67106176d26e2b
    Signed-off-by: Rudolf Marek <[email protected]>
---
 src/arch/x86/lib/cbfs_and_run.c |    5 +-
 src/lib/Makefile.inc            |    1 +
 src/lib/serialice/serial.c      |  196 ++++++++++++++++++++++++++++++
 src/lib/serialice/serialice.c   |  256 +++++++++++++++++++++++++++++++++++++++
 src/lib/serialice/serialice.h   |   31 +++++
 5 files changed, 487 insertions(+), 2 deletions(-)

diff --git a/src/arch/x86/lib/cbfs_and_run.c b/src/arch/x86/lib/cbfs_and_run.c
index 62b2789..a63e50d 100644
--- a/src/arch/x86/lib/cbfs_and_run.c
+++ b/src/arch/x86/lib/cbfs_and_run.c
@@ -25,7 +25,6 @@
 static void cbfs_and_run_core(const char *filename, unsigned ebp)
 {
        u8 *dst;
-
        timestamp_add_now(TS_START_COPYRAM);
        print_debug("Loading image.\n");
        dst = cbfs_load_stage(filename);
@@ -40,13 +39,15 @@ static void cbfs_and_run_core(const char *filename, 
unsigned ebp)
                :: "a"(ebp), "D"(dst)
        );
 }
-
+void serialice_main(void);
 void __attribute__((regparm(0))) copy_and_run(unsigned cpu_reset)
 {
        // FIXME fix input parameters instead normalizing them here.
        if (cpu_reset == 1) cpu_reset = -1;
        else cpu_reset = 0;
 
+       serialice_main();
+
        cbfs_and_run_core(CONFIG_CBFS_PREFIX "/coreboot_ram", cpu_reset);
 }
 
diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc
index 3bd7f99..e6ae8b6 100644
--- a/src/lib/Makefile.inc
+++ b/src/lib/Makefile.inc
@@ -21,6 +21,7 @@ romstage-$(CONFIG_USBDEBUG) += usbdebug.c
 romstage-$(CONFIG_COLLECT_TIMESTAMPS) += timestamp.c
 romstage-y += compute_ip_checksum.c
 romstage-y += memmove.c
+romstage-y += serialice/serialice.c
 
 ifneq ($(CONFIG_HAVE_ARCH_MEMSET),y)
 ramstage-y += memset.c
diff --git a/src/lib/serialice/serial.c b/src/lib/serialice/serial.c
new file mode 100644
index 0000000..529009c
--- /dev/null
+++ b/src/lib/serialice/serial.c
@@ -0,0 +1,196 @@
+/*
+ * SerialICE 
+ *
+ * Copyright (C) 2009 coresystems GmbH
+ *
+ * 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
+ */
+
+/* Data */
+#define UART_RBR 0x00
+#define UART_TBR 0x00
+
+/* Control */
+#define UART_IER 0x01
+#define UART_IIR 0x02
+#define UART_FCR 0x02
+#define UART_LCR 0x03
+#define UART_MCR 0x04
+#define UART_DLL 0x00
+#define UART_DLM 0x01
+
+/* Status */
+#define UART_LSR 0x05
+#define UART_MSR 0x06
+#define UART_SCR 0x07
+
+/* SIO functions */
+
+static void sio_init(void)
+{
+#if SIO_SPEED > 115200
+       /* "high speed" serial requires special chip setup
+        * (to be done in superio_init), and special divisor
+        * values (implement superio_serial_divisor() for that).
+        * Maybe it requires even more, but so far that seems
+        * to be enough.
+        */
+       int divisor = superio_serial_divisor(SIO_SPEED);
+#else
+       int divisor = 115200 / SIO_SPEED;
+#endif
+       int lcs = 3;
+       outb(0x00, SIO_PORT + UART_IER);
+       outb(0x01, SIO_PORT + UART_FCR);
+       outb(0x03, SIO_PORT + UART_MCR);
+       outb(0x80 | lcs, SIO_PORT + UART_LCR);
+       outb(divisor & 0xff, SIO_PORT + UART_DLL);
+       outb((divisor >> 8) & 0xff, SIO_PORT + UART_DLM);
+       outb(lcs, SIO_PORT + UART_LCR);
+}
+
+static void sio_putc(u8 data)
+{
+       while (!(inb(SIO_PORT + UART_LSR) & 0x20)) ;
+       outb(data, SIO_PORT + UART_TBR);
+       while (!(inb(SIO_PORT + UART_LSR) & 0x40)) ;
+}
+
+static u8 sio_getc(void)
+{
+       u8 val;
+       while (!(inb(SIO_PORT + UART_LSR) & 0x01)) ;
+
+       val = inb(SIO_PORT + UART_RBR);
+
+#if ECHO_MODE
+       sio_putc(val);
+#endif
+       return val;
+}
+
+/* SIO helpers */
+
+static void sio_putstring(const char *string)
+{
+       /* Very simple, no %d, %x etc. */
+       while (*string) {
+               if (*string == '\n')
+                       sio_putc('\r');
+               sio_putc(*string);
+               string++;
+       }
+}
+
+#define sio_put_nibble(nibble) \
+       if (nibble > 9)         \
+               nibble += ('a' - 10);   \
+       else                    \
+               nibble += '0';  \
+       sio_putc(nibble)
+
+static void sio_put8(u8 data)
+{
+       u8 c;
+               
+       c = (data >> 4) & 0xf;
+       sio_put_nibble(c);
+
+       c = data & 0xf;
+       sio_put_nibble(c);
+}
+
+static void sio_put16(u16 data)
+{
+       int i;
+       for (i=12; i >= 0; i -= 4) {
+               u8 c = (data >> i) & 0xf;
+               sio_put_nibble(c);
+       }
+}
+
+static void sio_put32(u32 data)
+{
+       int i;
+       for (i=28; i >= 0; i -= 4) {
+               u8 c = (data >> i) & 0xf;
+               sio_put_nibble(c);
+       }
+}
+
+static u8 sio_get_nibble(void)
+{
+       u8 ret = 0;
+       u8 nibble = sio_getc();
+
+       if (nibble >= '0' && nibble <= '9') {
+               ret = (nibble - '0');
+       } else if (nibble >= 'a' && nibble <= 'f') {
+               ret = (nibble - 'a') + 0xa;
+       } else if (nibble >= 'A' && nibble <= 'F') {
+               ret = (nibble - 'A') + 0xa;
+       } else {
+               sio_putstring("ERROR: parsing number\n");
+       }
+       return ret;
+}
+
+static u8 sio_get8(void)
+{
+       u8 data;
+       data = sio_get_nibble();
+       data = data << 4;
+       data |= sio_get_nibble();
+       return data;
+}
+
+static u16 sio_get16(void)
+{
+       u16 data;
+
+       data = sio_get_nibble();
+       data = data << 4;
+       data |= sio_get_nibble();
+       data = data << 4;
+       data |= sio_get_nibble();
+       data = data << 4;
+       data |= sio_get_nibble();
+
+       return data;
+}
+
+static u32 sio_get32(void)
+{
+       u32 data;
+
+       data = sio_get_nibble();
+       data = data << 4;
+       data |= sio_get_nibble();
+       data = data << 4;
+       data |= sio_get_nibble();
+       data = data << 4;
+       data |= sio_get_nibble();
+       data = data << 4;
+       data |= sio_get_nibble();
+       data = data << 4;
+       data |= sio_get_nibble();
+       data = data << 4;
+       data |= sio_get_nibble();
+       data = data << 4;
+       data |= sio_get_nibble();
+
+       return data;
+}
+
+
diff --git a/src/lib/serialice/serialice.c b/src/lib/serialice/serialice.c
new file mode 100644
index 0000000..0a5a8e0
--- /dev/null
+++ b/src/lib/serialice/serialice.c
@@ -0,0 +1,256 @@
+/*
+ * SerialICE 
+ *
+ * Copyright (C) 2009 coresystems GmbH
+ *
+ * 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
+ */
+
+#include "serialice.h"
+#include <arch/io.h>
+#include <cpu/x86/msr.h>
+#include <arch/cpu.h>
+
+const char boardname[33]="infinite improbability board    ";
+
+
+/* Hardware specific functions */
+
+/* SIO functions */
+#include "serial.c"
+
+/* Accessor functions */
+
+static void serialice_read_memory(void)
+{
+       u8 width;
+       u32 addr;
+
+       // Format:
+       // *rm00000000.w
+       addr = sio_get32();
+       sio_getc();     // skip .
+       width = sio_getc();
+
+       sio_putc('\r'); sio_putc('\n');
+
+       switch (width) {
+       case 'b': sio_put8(read8(addr)); break;
+       case 'w': sio_put16(read16(addr)); break;
+       case 'l': sio_put32(read32(addr)); break;
+       }
+}
+
+static void serialice_write_memory(void)
+{
+       u8 width;
+       u32 addr;
+       u32 data;
+
+       // Format:
+       // *wm00000000.w=0000
+       addr = sio_get32();
+       sio_getc();     // skip .
+       width = sio_getc();
+       sio_getc();     // skip =
+
+       switch (width) {
+       case 'b': data = sio_get8(); write8(addr, (u8)data); break;
+       case 'w': data = sio_get16(); write16(addr, (u16)data); break;
+       case 'l': data = sio_get32(); write32(addr, (u32)data); break;
+       }
+}
+
+static void serialice_read_io(void)
+{
+       u8 width;
+       u16 port;
+
+       // Format:
+       // *ri0000.w
+       port = sio_get16();
+       sio_getc();     // skip .
+       width = sio_getc();
+
+       sio_putc('\r'); sio_putc('\n');
+
+       switch (width) {
+       case 'b': sio_put8(inb(port)); break;
+       case 'w': sio_put16(inw(port)); break;
+       case 'l': sio_put32(inl(port)); break;
+       }
+}
+
+static void serialice_write_io(void)
+{
+       u8 width;
+       u16 port;
+       u32 data;
+
+       // Format:
+       // *wi0000.w=0000
+       port = sio_get16();
+       sio_getc();     // skip .
+       width = sio_getc();
+       sio_getc();     // skip =
+
+       switch (width) {
+       case 'b': data = sio_get8(); outb((u8)data, port); break;
+       case 'w': data = sio_get16(); outw((u16)data, port); break;
+       case 'l': data = sio_get32(); outl((u32)data, port); break;
+       }
+}
+
+static void serialice_read_msr(void)
+{
+       u32 addr, key;
+       msr_t msr;
+
+       // Format:
+       // *rc00000000.9c5a203a
+       addr = sio_get32();
+       sio_getc();        // skip .
+       key = sio_get32(); // key in %edi
+
+       sio_putc('\r'); sio_putc('\n');
+
+       msr = rdmsr(addr);
+       sio_put32(msr.hi);
+       sio_putc('.');
+       sio_put32(msr.lo);
+}
+
+static void serialice_write_msr(void)
+{
+       u32 addr, key;
+       msr_t msr;
+
+       // Format:
+       // *wc00000000.9c5a203a=00000000.00000000
+       addr = sio_get32();
+       sio_getc();     // skip .
+       key = sio_get32(); // read key in %edi
+       sio_getc();     // skip =
+       msr.hi = sio_get32();
+       sio_getc();     // skip .
+       msr.lo = sio_get32();
+
+#ifdef __ROMCC__
+       /* Cheat to avoid register outage */
+       wrmsr(addr, msr, 0x9c5a203a);
+#else
+       wrmsr(addr, msr);
+#endif
+}
+
+static void serialice_cpuinfo(void)
+{
+       u32 eax, ecx;
+       u32 reg32 = 0xdeadbeef;
+
+       // Format:
+       //    --EAX--- --ECX---
+       // *ci00000000.00000000
+       eax = sio_get32();
+       sio_getc(); // skip .
+       ecx = sio_get32();
+
+       sio_putc('\r'); sio_putc('\n');
+
+       /* This code looks quite crappy but this way we don't
+        * have to worry about running out of registers if we
+        * occupy eax, ebx, ecx, edx at the same time 
+        */
+//     reg32 = cpuid_eax(eax, ecx);
+       sio_put32(reg32);
+       sio_putc('.');
+
+//     reg32 = cpuid_ebx(eax, ecx);
+       sio_put32(reg32);
+       sio_putc('.');
+
+//     reg32 = cpuid_ecx(eax, ecx);
+       sio_put32(reg32);
+       sio_putc('.');
+
+//     reg32 = cpuid_edx(eax, ecx);
+       sio_put32(reg32);
+}
+
+static void serialice_mainboard(void)
+{
+       sio_putc('\r'); sio_putc('\n');
+
+       /* must be defined in mainboard/<boardname>.c */
+       sio_putstring(boardname);
+}
+
+static void serialice_version(void)
+{
+       sio_putstring("\nSerialICE v" VERSION " (" __DATE__ ")\n");
+}
+void serialice_main(void);
+
+void serialice_main(void)
+{
+       sio_init();
+       serialice_version();
+
+       while(1) {
+               u16 c;
+               sio_putstring("\n> ");
+
+               c = sio_getc();
+               if (c != '*')
+                       continue;
+
+               c = sio_getc() << 8;
+               c |= sio_getc();
+
+               switch(c) {
+               case (('r' << 8)|'m'): // Read Memory *rm
+                       serialice_read_memory();
+                       break;
+               case (('w' << 8)|'m'): // Write Memory *wm
+                       serialice_write_memory();
+                       break;
+               case (('r' << 8)|'i'): // Read IO *ri
+                       serialice_read_io();
+                       break;
+               case (('w' << 8)|'i'): // Write IO *wi
+                       serialice_write_io();
+                       break;
+               case (('r' << 8)|'c'): // Read CPU MSR *rc
+                       serialice_read_msr();
+                       break;
+               case (('w' << 8)|'c'): // Write CPU MSR *wc
+                       serialice_write_msr();
+                       break;
+               case (('c' << 8)|'i'): // Read CPUID *ci
+                       serialice_cpuinfo();
+                       break;
+               case (('m' << 8)|'b'): // Read mainboard type *mb
+                       serialice_mainboard();
+                       break;
+               case (('v' << 8)|'i'): // Read version info *vi
+                       serialice_version();
+                       break;
+               default:
+                       sio_putstring("ERROR\n");
+                       break;
+               }
+       }
+
+       // Never get here:
+}
diff --git a/src/lib/serialice/serialice.h b/src/lib/serialice/serialice.h
new file mode 100644
index 0000000..1d01849
--- /dev/null
+++ b/src/lib/serialice/serialice.h
@@ -0,0 +1,31 @@
+/*
+ * SerialICE 
+ *
+ * Copyright (C) 2009 coresystems GmbH
+ *
+ * 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
+ */
+
+#ifndef SERIALICE_H
+#define SERIALICE_H
+
+#include "config.h"
+
+#define ECHO_MODE      1
+
+#define VERSION "42"
+#define SIO_SPEED      115200
+#define SIO_PORT       0x3f8
+
+#endif

-- 
coreboot mailing list: [email protected]
http://www.coreboot.org/mailman/listinfo/coreboot

Reply via email to