--- /dev/null
+/*
+ * arch/powerpc/boot/ugecon.c
+ *
+ * USB Gecko bootwrapper console.
+ * Copyright (C) 2008-2009 The GameCube Linux Team
+ * Copyright (C) 2008,2009 Albert Herranz
+ *
+ * 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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ */
+
+#include <stddef.h>
+#include "stdio.h"
+#include "types.h"
+#include "io.h"
+#include "ops.h"
+
+
+#define EXI_CLK_32MHZ           5
+
+#define EXI_CSR                 0x00
+#define   EXI_CSR_CLKMASK       (0x7<<4)
+#define     EXI_CSR_CLK_32MHZ   (EXI_CLK_32MHZ<<4)
+#define   EXI_CSR_CSMASK        (0x7<<7)
+#define     EXI_CSR_CS_0        (0x1<<7)  /* Chip Select 001 */
+
+#define EXI_CR                  0x0c
+#define   EXI_CR_TSTART         (1<<0)
+#define   EXI_CR_WRITE         (1<<2)
+#define   EXI_CR_READ_WRITE     (2<<2)
+#define   EXI_CR_TLEN(len)      (((len)-1)<<4)
+
+#define EXI_DATA                0x10
+
+
+/* virtual address base for input/output, retrieved from device tree */
+static void *ug_io_base;
+
+
+static u32 ug_io_transaction(u32 in)
+{
+       u32 *csr_reg = ug_io_base + EXI_CSR;
+       u32 *data_reg = ug_io_base + EXI_DATA;
+       u32 *cr_reg = ug_io_base + EXI_CR;
+       u32 csr, data, cr;
+
+       /* select */
+       csr = EXI_CSR_CLK_32MHZ | EXI_CSR_CS_0;
+       out_be32(csr_reg, csr);
+
+       /* read/write */
+       data = in;
+       out_be32(data_reg, data);
+       cr = EXI_CR_TLEN(2) | EXI_CR_READ_WRITE | EXI_CR_TSTART;
+       out_be32(cr_reg, cr);
+
+       while (in_be32(cr_reg) & EXI_CR_TSTART)
+               barrier();
+
+       /* deselect */
+       out_be32(csr_reg, 0);
+
+       data = in_be32(data_reg);
+       return data;
+}
+
+static int ug_is_txfifo_ready(void)
+{
+       return ug_io_transaction(0xc0000000) & 0x04000000;
+}
+
+static void ug_raw_putc(char ch)
+{
+       ug_io_transaction(0xb0000000 | (ch << 20));
+}
+
+static void ug_putc(char ch)
+{
+       int count = 16;
+
+       if (!ug_io_base)
+               return;
+
+       while (!ug_is_txfifo_ready() && count--)
+               barrier();
+       if (count)
+               ug_raw_putc(ch);
+}
+
+void ug_console_write(const char *buf, int len)
+{
+       char *b = (char *)buf;
+
+       while (len--) {
+               if (*b == '\n')
+                       ug_putc('\r');
+               ug_putc(*b++);
+       }
+}
+
+static int ug_is_adapter_present(void)
+{
+       if (!ug_io_base)
+               return 0;
+       return ug_io_transaction(0x90000000) == 0x04700000;
+}
+
+static void *ug_grab_exi_io_base(void)
+{
+       u32 v;
+       void *devp;
+
+       devp = find_node_by_compatible(NULL, "nintendo,flipper-exi");
+       if (devp == NULL)
+               goto err_out;
+       if (getprop(devp, "virtual-reg", &v, sizeof(v)) != sizeof(v))
+               goto err_out;
+
+       return (void *)v;
+
+err_out:
+       return NULL;
+}
+
+void *ug_probe(void)
+{
+       void *exi_io_base;
+       int i;
+
+       exi_io_base = ug_grab_exi_io_base();
+       if (!exi_io_base)
+               return NULL;
+
+       /* look for a usbgecko on memcard slots A and B */
+       for (i = 0; i < 2; i++) {
+               ug_io_base = exi_io_base + 0x14 * i;
+               if (ug_is_adapter_present())
+                       break;
+       }
+       if (i == 2)
+               ug_io_base = NULL;
+       return ug_io_base;
+}
+
 
--- /dev/null
+/*
+ * arch/powerpc/boot/ugecon.h
+ *
+ * USB Gecko early bootwrapper console.
+ * Copyright (C) 2008-2009 The GameCube Linux Team
+ * Copyright (C) 2008,2009 Albert Herranz
+ *
+ * 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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ */
+
+#ifndef __UGECON_H
+#define __UGECON_H
+
+extern void *ug_probe(void);
+
+extern void ug_putc(char ch);
+extern void ug_console_write(const char *buf, int len);
+
+#endif /* __UGECON_H */
+