summaryrefslogtreecommitdiff
path: root/ports/litex/boards
diff options
context:
space:
mode:
Diffstat (limited to 'ports/litex/boards')
-rw-r--r--ports/litex/boards/board.h45
-rw-r--r--ports/litex/boards/fomu/board.c75
-rw-r--r--ports/litex/boards/fomu/csr.h647
-rw-r--r--ports/litex/boards/fomu/fomu-spi.ld118
-rw-r--r--ports/litex/boards/fomu/generated/soc.h58
-rw-r--r--ports/litex/boards/fomu/mpconfigboard.h37
-rw-r--r--ports/litex/boards/fomu/mpconfigboard.mk20
-rw-r--r--ports/litex/boards/fomu/pins.c9
-rw-r--r--ports/litex/boards/fomu/profiling.gdb.txt16
9 files changed, 1025 insertions, 0 deletions
diff --git a/ports/litex/boards/board.h b/ports/litex/boards/board.h
new file mode 100644
index 000000000..837b37190
--- /dev/null
+++ b/ports/litex/boards/board.h
@@ -0,0 +1,45 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+// This file defines board specific functions.
+
+#ifndef MICROPY_INCLUDED_LITEX_BOARDS_BOARD_H
+#define MICROPY_INCLUDED_LITEX_BOARDS_BOARD_H
+
+#include <stdbool.h>
+
+// Initializes board related state once on start up.
+void board_init(void);
+
+// Returns true if the user initiates safe mode in a board specific way.
+// Also add BOARD_USER_SAFE_MODE in mpconfigboard.h to explain the board specific
+// way.
+bool board_requests_safe_mode(void);
+
+// Reset the state of off MCU components such as neopixels.
+void reset_board(void);
+
+#endif // MICROPY_INCLUDED_LITEX_BOARDS_BOARD_H
diff --git a/ports/litex/boards/fomu/board.c b/ports/litex/boards/fomu/board.c
new file mode 100644
index 000000000..97e1ecadd
--- /dev/null
+++ b/ports/litex/boards/fomu/board.c
@@ -0,0 +1,75 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "boards/board.h"
+#include "mpconfigboard.h"
+#include "csr.h"
+
+// ICE40 LED Driver hard macro.
+// See http://www.latticesemi.com/-/media/LatticeSemi/Documents/ApplicationNotes/IK/ICE40LEDDriverUsageGuide.ashx?document_id=50668
+enum led_registers {
+ LEDDCR0 = 8,
+ LEDDBR = 9,
+ LEDDONR = 10,
+ LEDDOFR = 11,
+ LEDDBCRR = 5,
+ LEDDBCFR = 6,
+ LEDDPWRR = 1,
+ LEDDPWRG = 2,
+ LEDDPWRB = 3,
+};
+
+#define BREATHE_ENABLE (1 << 7)
+#define BREATHE_EDGE_ON (0 << 6)
+#define BREATHE_EDGE_BOTH (1 << 6)
+#define BREATHE_MODE_MODULATE (1 << 5)
+#define BREATHE_RATE(x) ((x & 7) << 0)
+
+// Write a value into the LEDDA_IP register.
+static void ledda_write(uint8_t value, uint8_t addr) {
+ rgb_addr_write(addr);
+ rgb_dat_write(value);
+}
+
+void board_init(void) {
+ uint8_t onrate = 15;
+ uint8_t offrate = 1;
+
+ ledda_write(BREATHE_ENABLE | BREATHE_MODE_MODULATE | BREATHE_RATE(onrate), LEDDBCRR);
+ ledda_write(BREATHE_ENABLE | BREATHE_MODE_MODULATE | BREATHE_RATE(offrate), LEDDBCFR);
+
+ ledda_write(123, LEDDPWRR); // Red
+ ledda_write(3, LEDDPWRG); // Green
+ ledda_write(98, LEDDPWRB); // Blue
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+
+}
diff --git a/ports/litex/boards/fomu/csr.h b/ports/litex/boards/fomu/csr.h
new file mode 100644
index 000000000..bf66fe3a1
--- /dev/null
+++ b/ports/litex/boards/fomu/csr.h
@@ -0,0 +1,647 @@
+//--------------------------------------------------------------------------------
+// Auto-generated by Migen (f4fcd10) & LiteX (de205d4a) on 2019-11-25 14:57:34
+//--------------------------------------------------------------------------------
+#include <generated/soc.h>
+#ifndef __GENERATED_CSR_H
+#define __GENERATED_CSR_H
+#include <stdint.h>
+#ifdef CSR_ACCESSORS_DEFINED
+extern void csr_writeb(uint8_t value, unsigned long addr);
+extern uint8_t csr_readb(unsigned long addr);
+extern void csr_writew(uint16_t value, unsigned long addr);
+extern uint16_t csr_readw(unsigned long addr);
+extern void csr_writel(uint32_t value, unsigned long addr);
+extern uint32_t csr_readl(unsigned long addr);
+#else /* ! CSR_ACCESSORS_DEFINED */
+#include <hw/common.h>
+#endif /* ! CSR_ACCESSORS_DEFINED */
+
+/* ctrl */
+#define CSR_CTRL_BASE 0xe0000000L
+#define CSR_CTRL_RESET_ADDR 0xe0000000L
+#define CSR_CTRL_RESET_SIZE 1
+static inline unsigned char ctrl_reset_read(void) {
+ unsigned char r = csr_readl(0xe0000000L);
+ return r;
+}
+static inline void ctrl_reset_write(unsigned char value) {
+ csr_writel(value, 0xe0000000L);
+}
+#define CSR_CTRL_SCRATCH_ADDR 0xe0000004L
+#define CSR_CTRL_SCRATCH_SIZE 4
+static inline unsigned int ctrl_scratch_read(void) {
+ unsigned int r = csr_readl(0xe0000004L);
+ r <<= 8;
+ r |= csr_readl(0xe0000008L);
+ r <<= 8;
+ r |= csr_readl(0xe000000cL);
+ r <<= 8;
+ r |= csr_readl(0xe0000010L);
+ return r;
+}
+static inline void ctrl_scratch_write(unsigned int value) {
+ csr_writel(value >> 24, 0xe0000004L);
+ csr_writel(value >> 16, 0xe0000008L);
+ csr_writel(value >> 8, 0xe000000cL);
+ csr_writel(value, 0xe0000010L);
+}
+#define CSR_CTRL_BUS_ERRORS_ADDR 0xe0000014L
+#define CSR_CTRL_BUS_ERRORS_SIZE 4
+static inline unsigned int ctrl_bus_errors_read(void) {
+ unsigned int r = csr_readl(0xe0000014L);
+ r <<= 8;
+ r |= csr_readl(0xe0000018L);
+ r <<= 8;
+ r |= csr_readl(0xe000001cL);
+ r <<= 8;
+ r |= csr_readl(0xe0000020L);
+ return r;
+}
+
+/* lxspi */
+#define CSR_LXSPI_BASE 0xe0007800L
+#define CSR_LXSPI_BITBANG_ADDR 0xe0007800L
+#define CSR_LXSPI_BITBANG_SIZE 1
+static inline unsigned char lxspi_bitbang_read(void) {
+ unsigned char r = csr_readl(0xe0007800L);
+ return r;
+}
+static inline void lxspi_bitbang_write(unsigned char value) {
+ csr_writel(value, 0xe0007800L);
+}
+#define CSR_LXSPI_BITBANG_MOSI_OFFSET 0
+#define CSR_LXSPI_BITBANG_MOSI_SIZE 1
+#define CSR_LXSPI_BITBANG_CLK_OFFSET 1
+#define CSR_LXSPI_BITBANG_CLK_SIZE 1
+#define CSR_LXSPI_BITBANG_CS_N_OFFSET 2
+#define CSR_LXSPI_BITBANG_CS_N_SIZE 1
+#define CSR_LXSPI_BITBANG_DIR_OFFSET 3
+#define CSR_LXSPI_BITBANG_DIR_SIZE 1
+#define CSR_LXSPI_MISO_ADDR 0xe0007804L
+#define CSR_LXSPI_MISO_SIZE 1
+static inline unsigned char lxspi_miso_read(void) {
+ unsigned char r = csr_readl(0xe0007804L);
+ return r;
+}
+#define CSR_LXSPI_BITBANG_EN_ADDR 0xe0007808L
+#define CSR_LXSPI_BITBANG_EN_SIZE 1
+static inline unsigned char lxspi_bitbang_en_read(void) {
+ unsigned char r = csr_readl(0xe0007808L);
+ return r;
+}
+static inline void lxspi_bitbang_en_write(unsigned char value) {
+ csr_writel(value, 0xe0007808L);
+}
+
+/* messible */
+#define CSR_MESSIBLE_BASE 0xe0008000L
+#define CSR_MESSIBLE_IN_ADDR 0xe0008000L
+#define CSR_MESSIBLE_IN_SIZE 1
+static inline unsigned char messible_in_read(void) {
+ unsigned char r = csr_readl(0xe0008000L);
+ return r;
+}
+static inline void messible_in_write(unsigned char value) {
+ csr_writel(value, 0xe0008000L);
+}
+#define CSR_MESSIBLE_OUT_ADDR 0xe0008004L
+#define CSR_MESSIBLE_OUT_SIZE 1
+static inline unsigned char messible_out_read(void) {
+ unsigned char r = csr_readl(0xe0008004L);
+ return r;
+}
+#define CSR_MESSIBLE_STATUS_ADDR 0xe0008008L
+#define CSR_MESSIBLE_STATUS_SIZE 1
+static inline unsigned char messible_status_read(void) {
+ unsigned char r = csr_readl(0xe0008008L);
+ return r;
+}
+#define CSR_MESSIBLE_STATUS_FULL_OFFSET 0
+#define CSR_MESSIBLE_STATUS_FULL_SIZE 1
+#define CSR_MESSIBLE_STATUS_HAVE_OFFSET 1
+#define CSR_MESSIBLE_STATUS_HAVE_SIZE 1
+
+/* reboot */
+#define CSR_REBOOT_BASE 0xe0006000L
+#define CSR_REBOOT_CTRL_ADDR 0xe0006000L
+#define CSR_REBOOT_CTRL_SIZE 1
+static inline unsigned char reboot_ctrl_read(void) {
+ unsigned char r = csr_readl(0xe0006000L);
+ return r;
+}
+static inline void reboot_ctrl_write(unsigned char value) {
+ csr_writel(value, 0xe0006000L);
+}
+#define CSR_REBOOT_CTRL_IMAGE_OFFSET 0
+#define CSR_REBOOT_CTRL_IMAGE_SIZE 2
+#define CSR_REBOOT_CTRL_KEY_OFFSET 2
+#define CSR_REBOOT_CTRL_KEY_SIZE 6
+#define CSR_REBOOT_ADDR_ADDR 0xe0006004L
+#define CSR_REBOOT_ADDR_SIZE 4
+static inline unsigned int reboot_addr_read(void) {
+ unsigned int r = csr_readl(0xe0006004L);
+ r <<= 8;
+ r |= csr_readl(0xe0006008L);
+ r <<= 8;
+ r |= csr_readl(0xe000600cL);
+ r <<= 8;
+ r |= csr_readl(0xe0006010L);
+ return r;
+}
+static inline void reboot_addr_write(unsigned int value) {
+ csr_writel(value >> 24, 0xe0006004L);
+ csr_writel(value >> 16, 0xe0006008L);
+ csr_writel(value >> 8, 0xe000600cL);
+ csr_writel(value, 0xe0006010L);
+}
+
+/* rgb */
+#define CSR_RGB_BASE 0xe0006800L
+#define CSR_RGB_DAT_ADDR 0xe0006800L
+#define CSR_RGB_DAT_SIZE 1
+static inline unsigned char rgb_dat_read(void) {
+ unsigned char r = csr_readl(0xe0006800L);
+ return r;
+}
+static inline void rgb_dat_write(unsigned char value) {
+ csr_writel(value, 0xe0006800L);
+}
+#define CSR_RGB_ADDR_ADDR 0xe0006804L
+#define CSR_RGB_ADDR_SIZE 1
+static inline unsigned char rgb_addr_read(void) {
+ unsigned char r = csr_readl(0xe0006804L);
+ return r;
+}
+static inline void rgb_addr_write(unsigned char value) {
+ csr_writel(value, 0xe0006804L);
+}
+#define CSR_RGB_CTRL_ADDR 0xe0006808L
+#define CSR_RGB_CTRL_SIZE 1
+static inline unsigned char rgb_ctrl_read(void) {
+ unsigned char r = csr_readl(0xe0006808L);
+ return r;
+}
+static inline void rgb_ctrl_write(unsigned char value) {
+ csr_writel(value, 0xe0006808L);
+}
+#define CSR_RGB_CTRL_EXE_OFFSET 0
+#define CSR_RGB_CTRL_EXE_SIZE 1
+#define CSR_RGB_CTRL_CURREN_OFFSET 1
+#define CSR_RGB_CTRL_CURREN_SIZE 1
+#define CSR_RGB_CTRL_RGBLEDEN_OFFSET 2
+#define CSR_RGB_CTRL_RGBLEDEN_SIZE 1
+#define CSR_RGB_CTRL_RRAW_OFFSET 3
+#define CSR_RGB_CTRL_RRAW_SIZE 1
+#define CSR_RGB_CTRL_GRAW_OFFSET 4
+#define CSR_RGB_CTRL_GRAW_SIZE 1
+#define CSR_RGB_CTRL_BRAW_OFFSET 5
+#define CSR_RGB_CTRL_BRAW_SIZE 1
+#define CSR_RGB_RAW_ADDR 0xe000680cL
+#define CSR_RGB_RAW_SIZE 1
+static inline unsigned char rgb_raw_read(void) {
+ unsigned char r = csr_readl(0xe000680cL);
+ return r;
+}
+static inline void rgb_raw_write(unsigned char value) {
+ csr_writel(value, 0xe000680cL);
+}
+#define CSR_RGB_RAW_R_OFFSET 0
+#define CSR_RGB_RAW_R_SIZE 1
+#define CSR_RGB_RAW_G_OFFSET 1
+#define CSR_RGB_RAW_G_SIZE 1
+#define CSR_RGB_RAW_B_OFFSET 2
+#define CSR_RGB_RAW_B_SIZE 1
+
+/* timer0 */
+#define CSR_TIMER0_BASE 0xe0002800L
+#define CSR_TIMER0_LOAD_ADDR 0xe0002800L
+#define CSR_TIMER0_LOAD_SIZE 4
+static inline unsigned int timer0_load_read(void) {
+ unsigned int r = csr_readl(0xe0002800L);
+ r <<= 8;
+ r |= csr_readl(0xe0002804L);
+ r <<= 8;
+ r |= csr_readl(0xe0002808L);
+ r <<= 8;
+ r |= csr_readl(0xe000280cL);
+ return r;
+}
+static inline void timer0_load_write(unsigned int value) {
+ csr_writel(value >> 24, 0xe0002800L);
+ csr_writel(value >> 16, 0xe0002804L);
+ csr_writel(value >> 8, 0xe0002808L);
+ csr_writel(value, 0xe000280cL);
+}
+#define CSR_TIMER0_RELOAD_ADDR 0xe0002810L
+#define CSR_TIMER0_RELOAD_SIZE 4
+static inline unsigned int timer0_reload_read(void) {
+ unsigned int r = csr_readl(0xe0002810L);
+ r <<= 8;
+ r |= csr_readl(0xe0002814L);
+ r <<= 8;
+ r |= csr_readl(0xe0002818L);
+ r <<= 8;
+ r |= csr_readl(0xe000281cL);
+ return r;
+}
+static inline void timer0_reload_write(unsigned int value) {
+ csr_writel(value >> 24, 0xe0002810L);
+ csr_writel(value >> 16, 0xe0002814L);
+ csr_writel(value >> 8, 0xe0002818L);
+ csr_writel(value, 0xe000281cL);
+}
+#define CSR_TIMER0_EN_ADDR 0xe0002820L
+#define CSR_TIMER0_EN_SIZE 1
+static inline unsigned char timer0_en_read(void) {
+ unsigned char r = csr_readl(0xe0002820L);
+ return r;
+}
+static inline void timer0_en_write(unsigned char value) {
+ csr_writel(value, 0xe0002820L);
+}
+#define CSR_TIMER0_UPDATE_VALUE_ADDR 0xe0002824L
+#define CSR_TIMER0_UPDATE_VALUE_SIZE 1
+static inline unsigned char timer0_update_value_read(void) {
+ unsigned char r = csr_readl(0xe0002824L);
+ return r;
+}
+static inline void timer0_update_value_write(unsigned char value) {
+ csr_writel(value, 0xe0002824L);
+}
+#define CSR_TIMER0_VALUE_ADDR 0xe0002828L
+#define CSR_TIMER0_VALUE_SIZE 4
+static inline unsigned int timer0_value_read(void) {
+ unsigned int r = csr_readl(0xe0002828L);
+ r <<= 8;
+ r |= csr_readl(0xe000282cL);
+ r <<= 8;
+ r |= csr_readl(0xe0002830L);
+ r <<= 8;
+ r |= csr_readl(0xe0002834L);
+ return r;
+}
+#define CSR_TIMER0_EV_STATUS_ADDR 0xe0002838L
+#define CSR_TIMER0_EV_STATUS_SIZE 1
+static inline unsigned char timer0_ev_status_read(void) {
+ unsigned char r = csr_readl(0xe0002838L);
+ return r;
+}
+static inline void timer0_ev_status_write(unsigned char value) {
+ csr_writel(value, 0xe0002838L);
+}
+#define CSR_TIMER0_EV_PENDING_ADDR 0xe000283cL
+#define CSR_TIMER0_EV_PENDING_SIZE 1
+static inline unsigned char timer0_ev_pending_read(void) {
+ unsigned char r = csr_readl(0xe000283cL);
+ return r;
+}
+static inline void timer0_ev_pending_write(unsigned char value) {
+ csr_writel(value, 0xe000283cL);
+}
+#define CSR_TIMER0_EV_ENABLE_ADDR 0xe0002840L
+#define CSR_TIMER0_EV_ENABLE_SIZE 1
+static inline unsigned char timer0_ev_enable_read(void) {
+ unsigned char r = csr_readl(0xe0002840L);
+ return r;
+}
+static inline void timer0_ev_enable_write(unsigned char value) {
+ csr_writel(value, 0xe0002840L);
+}
+
+/* touch */
+#define CSR_TOUCH_BASE 0xe0005800L
+#define CSR_TOUCH_O_ADDR 0xe0005800L
+#define CSR_TOUCH_O_SIZE 1
+static inline unsigned char touch_o_read(void) {
+ unsigned char r = csr_readl(0xe0005800L);
+ return r;
+}
+static inline void touch_o_write(unsigned char value) {
+ csr_writel(value, 0xe0005800L);
+}
+#define CSR_TOUCH_OE_ADDR 0xe0005804L
+#define CSR_TOUCH_OE_SIZE 1
+static inline unsigned char touch_oe_read(void) {
+ unsigned char r = csr_readl(0xe0005804L);
+ return r;
+}
+static inline void touch_oe_write(unsigned char value) {
+ csr_writel(value, 0xe0005804L);
+}
+#define CSR_TOUCH_I_ADDR 0xe0005808L
+#define CSR_TOUCH_I_SIZE 1
+static inline unsigned char touch_i_read(void) {
+ unsigned char r = csr_readl(0xe0005808L);
+ return r;
+}
+
+/* usb */
+#define CSR_USB_BASE 0xe0004800L
+#define CSR_USB_PULLUP_OUT_ADDR 0xe0004800L
+#define CSR_USB_PULLUP_OUT_SIZE 1
+static inline unsigned char usb_pullup_out_read(void) {
+ unsigned char r = csr_readl(0xe0004800L);
+ return r;
+}
+static inline void usb_pullup_out_write(unsigned char value) {
+ csr_writel(value, 0xe0004800L);
+}
+#define CSR_USB_ADDRESS_ADDR 0xe0004804L
+#define CSR_USB_ADDRESS_SIZE 1
+static inline unsigned char usb_address_read(void) {
+ unsigned char r = csr_readl(0xe0004804L);
+ return r;
+}
+static inline void usb_address_write(unsigned char value) {
+ csr_writel(value, 0xe0004804L);
+}
+#define CSR_USB_ADDRESS_ADDR_OFFSET 0
+#define CSR_USB_ADDRESS_ADDR_SIZE 7
+#define CSR_USB_NEXT_EV_ADDR 0xe0004808L
+#define CSR_USB_NEXT_EV_SIZE 1
+static inline unsigned char usb_next_ev_read(void) {
+ unsigned char r = csr_readl(0xe0004808L);
+ return r;
+}
+#define CSR_USB_NEXT_EV_IN_OFFSET 0
+#define CSR_USB_NEXT_EV_IN_SIZE 1
+#define CSR_USB_NEXT_EV_OUT_OFFSET 1
+#define CSR_USB_NEXT_EV_OUT_SIZE 1
+#define CSR_USB_NEXT_EV_SETUP_OFFSET 2
+#define CSR_USB_NEXT_EV_SETUP_SIZE 1
+#define CSR_USB_NEXT_EV_RESET_OFFSET 3
+#define CSR_USB_NEXT_EV_RESET_SIZE 1
+#define CSR_USB_SETUP_DATA_ADDR 0xe000480cL
+#define CSR_USB_SETUP_DATA_SIZE 1
+static inline unsigned char usb_setup_data_read(void) {
+ unsigned char r = csr_readl(0xe000480cL);
+ return r;
+}
+#define CSR_USB_SETUP_DATA_DATA_OFFSET 0
+#define CSR_USB_SETUP_DATA_DATA_SIZE 8
+#define CSR_USB_SETUP_CTRL_ADDR 0xe0004810L
+#define CSR_USB_SETUP_CTRL_SIZE 1
+static inline unsigned char usb_setup_ctrl_read(void) {
+ unsigned char r = csr_readl(0xe0004810L);
+ return r;
+}
+static inline void usb_setup_ctrl_write(unsigned char value) {
+ csr_writel(value, 0xe0004810L);
+}
+#define CSR_USB_SETUP_CTRL_RESET_OFFSET 5
+#define CSR_USB_SETUP_CTRL_RESET_SIZE 1
+#define CSR_USB_SETUP_STATUS_ADDR 0xe0004814L
+#define CSR_USB_SETUP_STATUS_SIZE 1
+static inline unsigned char usb_setup_status_read(void) {
+ unsigned char r = csr_readl(0xe0004814L);
+ return r;
+}
+#define CSR_USB_SETUP_STATUS_EPNO_OFFSET 0
+#define CSR_USB_SETUP_STATUS_EPNO_SIZE 4
+#define CSR_USB_SETUP_STATUS_HAVE_OFFSET 4
+#define CSR_USB_SETUP_STATUS_HAVE_SIZE 1
+#define CSR_USB_SETUP_STATUS_PEND_OFFSET 5
+#define CSR_USB_SETUP_STATUS_PEND_SIZE 1
+#define CSR_USB_SETUP_STATUS_IS_IN_OFFSET 6
+#define CSR_USB_SETUP_STATUS_IS_IN_SIZE 1
+#define CSR_USB_SETUP_STATUS_DATA_OFFSET 7
+#define CSR_USB_SETUP_STATUS_DATA_SIZE 1
+#define CSR_USB_SETUP_EV_STATUS_ADDR 0xe0004818L
+#define CSR_USB_SETUP_EV_STATUS_SIZE 1
+static inline unsigned char usb_setup_ev_status_read(void) {
+ unsigned char r = csr_readl(0xe0004818L);
+ return r;
+}
+static inline void usb_setup_ev_status_write(unsigned char value) {
+ csr_writel(value, 0xe0004818L);
+}
+#define CSR_USB_SETUP_EV_PENDING_ADDR 0xe000481cL
+#define CSR_USB_SETUP_EV_PENDING_SIZE 1
+static inline unsigned char usb_setup_ev_pending_read(void) {
+ unsigned char r = csr_readl(0xe000481cL);
+ return r;
+}
+static inline void usb_setup_ev_pending_write(unsigned char value) {
+ csr_writel(value, 0xe000481cL);
+}
+#define CSR_USB_SETUP_EV_ENABLE_ADDR 0xe0004820L
+#define CSR_USB_SETUP_EV_ENABLE_SIZE 1
+static inline unsigned char usb_setup_ev_enable_read(void) {
+ unsigned char r = csr_readl(0xe0004820L);
+ return r;
+}
+static inline void usb_setup_ev_enable_write(unsigned char value) {
+ csr_writel(value, 0xe0004820L);
+}
+#define CSR_USB_IN_DATA_ADDR 0xe0004824L
+#define CSR_USB_IN_DATA_SIZE 1
+static inline unsigned char usb_in_data_read(void) {
+ unsigned char r = csr_readl(0xe0004824L);
+ return r;
+}
+static inline void usb_in_data_write(unsigned char value) {
+ csr_writel(value, 0xe0004824L);
+}
+#define CSR_USB_IN_DATA_DATA_OFFSET 0
+#define CSR_USB_IN_DATA_DATA_SIZE 8
+#define CSR_USB_IN_CTRL_ADDR 0xe0004828L
+#define CSR_USB_IN_CTRL_SIZE 1
+static inline unsigned char usb_in_ctrl_read(void) {
+ unsigned char r = csr_readl(0xe0004828L);
+ return r;
+}
+static inline void usb_in_ctrl_write(unsigned char value) {
+ csr_writel(value, 0xe0004828L);
+}
+#define CSR_USB_IN_CTRL_EPNO_OFFSET 0
+#define CSR_USB_IN_CTRL_EPNO_SIZE 4
+#define CSR_USB_IN_CTRL_RESET_OFFSET 5
+#define CSR_USB_IN_CTRL_RESET_SIZE 1
+#define CSR_USB_IN_CTRL_STALL_OFFSET 6
+#define CSR_USB_IN_CTRL_STALL_SIZE 1
+#define CSR_USB_IN_STATUS_ADDR 0xe000482cL
+#define CSR_USB_IN_STATUS_SIZE 1
+static inline unsigned char usb_in_status_read(void) {
+ unsigned char r = csr_readl(0xe000482cL);
+ return r;
+}
+#define CSR_USB_IN_STATUS_IDLE_OFFSET 0
+#define CSR_USB_IN_STATUS_IDLE_SIZE 1
+#define CSR_USB_IN_STATUS_HAVE_OFFSET 4
+#define CSR_USB_IN_STATUS_HAVE_SIZE 1
+#define CSR_USB_IN_STATUS_PEND_OFFSET 5
+#define CSR_USB_IN_STATUS_PEND_SIZE 1
+#define CSR_USB_IN_EV_STATUS_ADDR 0xe0004830L
+#define CSR_USB_IN_EV_STATUS_SIZE 1
+static inline unsigned char usb_in_ev_status_read(void) {
+ unsigned char r = csr_readl(0xe0004830L);
+ return r;
+}
+static inline void usb_in_ev_status_write(unsigned char value) {
+ csr_writel(value, 0xe0004830L);
+}
+#define CSR_USB_IN_EV_PENDING_ADDR 0xe0004834L
+#define CSR_USB_IN_EV_PENDING_SIZE 1
+static inline unsigned char usb_in_ev_pending_read(void) {
+ unsigned char r = csr_readl(0xe0004834L);
+ return r;
+}
+static inline void usb_in_ev_pending_write(unsigned char value) {
+ csr_writel(value, 0xe0004834L);
+}
+#define CSR_USB_IN_EV_ENABLE_ADDR 0xe0004838L
+#define CSR_USB_IN_EV_ENABLE_SIZE 1
+static inline unsigned char usb_in_ev_enable_read(void) {
+ unsigned char r = csr_readl(0xe0004838L);
+ return r;
+}
+static inline void usb_in_ev_enable_write(unsigned char value) {
+ csr_writel(value, 0xe0004838L);
+}
+#define CSR_USB_OUT_DATA_ADDR 0xe000483cL
+#define CSR_USB_OUT_DATA_SIZE 1
+static inline unsigned char usb_out_data_read(void) {
+ unsigned char r = csr_readl(0xe000483cL);
+ return r;
+}
+#define CSR_USB_OUT_DATA_DATA_OFFSET 0
+#define CSR_USB_OUT_DATA_DATA_SIZE 8
+#define CSR_USB_OUT_CTRL_ADDR 0xe0004840L
+#define CSR_USB_OUT_CTRL_SIZE 1
+static inline unsigned char usb_out_ctrl_read(void) {
+ unsigned char r = csr_readl(0xe0004840L);
+ return r;
+}
+static inline void usb_out_ctrl_write(unsigned char value) {
+ csr_writel(value, 0xe0004840L);
+}
+#define CSR_USB_OUT_CTRL_EPNO_OFFSET 0
+#define CSR_USB_OUT_CTRL_EPNO_SIZE 4
+#define CSR_USB_OUT_CTRL_ENABLE_OFFSET 4
+#define CSR_USB_OUT_CTRL_ENABLE_SIZE 1
+#define CSR_USB_OUT_CTRL_RESET_OFFSET 5
+#define CSR_USB_OUT_CTRL_RESET_SIZE 1
+#define CSR_USB_OUT_CTRL_STALL_OFFSET 6
+#define CSR_USB_OUT_CTRL_STALL_SIZE 1
+#define CSR_USB_OUT_STATUS_ADDR 0xe0004844L
+#define CSR_USB_OUT_STATUS_SIZE 1
+static inline unsigned char usb_out_status_read(void) {
+ unsigned char r = csr_readl(0xe0004844L);
+ return r;
+}
+#define CSR_USB_OUT_STATUS_EPNO_OFFSET 0
+#define CSR_USB_OUT_STATUS_EPNO_SIZE 4
+#define CSR_USB_OUT_STATUS_HAVE_OFFSET 4
+#define CSR_USB_OUT_STATUS_HAVE_SIZE 1
+#define CSR_USB_OUT_STATUS_PEND_OFFSET 5
+#define CSR_USB_OUT_STATUS_PEND_SIZE 1
+#define CSR_USB_OUT_EV_STATUS_ADDR 0xe0004848L
+#define CSR_USB_OUT_EV_STATUS_SIZE 1
+static inline unsigned char usb_out_ev_status_read(void) {
+ unsigned char r = csr_readl(0xe0004848L);
+ return r;
+}
+static inline void usb_out_ev_status_write(unsigned char value) {
+ csr_writel(value, 0xe0004848L);
+}
+#define CSR_USB_OUT_EV_PENDING_ADDR 0xe000484cL
+#define CSR_USB_OUT_EV_PENDING_SIZE 1
+static inline unsigned char usb_out_ev_pending_read(void) {
+ unsigned char r = csr_readl(0xe000484cL);
+ return r;
+}
+static inline void usb_out_ev_pending_write(unsigned char value) {
+ csr_writel(value, 0xe000484cL);
+}
+#define CSR_USB_OUT_EV_ENABLE_ADDR 0xe0004850L
+#define CSR_USB_OUT_EV_ENABLE_SIZE 1
+static inline unsigned char usb_out_ev_enable_read(void) {
+ unsigned char r = csr_readl(0xe0004850L);
+ return r;
+}
+static inline void usb_out_ev_enable_write(unsigned char value) {
+ csr_writel(value, 0xe0004850L);
+}
+#define CSR_USB_OUT_ENABLE_STATUS_ADDR 0xe0004854L
+#define CSR_USB_OUT_ENABLE_STATUS_SIZE 1
+static inline unsigned char usb_out_enable_status_read(void) {
+ unsigned char r = csr_readl(0xe0004854L);
+ return r;
+}
+#define CSR_USB_OUT_STALL_STATUS_ADDR 0xe0004858L
+#define CSR_USB_OUT_STALL_STATUS_SIZE 1
+static inline unsigned char usb_out_stall_status_read(void) {
+ unsigned char r = csr_readl(0xe0004858L);
+ return r;
+}
+
+/* version */
+#define CSR_VERSION_BASE 0xe0007000L
+#define CSR_VERSION_MAJOR_ADDR 0xe0007000L
+#define CSR_VERSION_MAJOR_SIZE 1
+static inline unsigned char version_major_read(void) {
+ unsigned char r = csr_readl(0xe0007000L);
+ return r;
+}
+#define CSR_VERSION_MINOR_ADDR 0xe0007004L
+#define CSR_VERSION_MINOR_SIZE 1
+static inline unsigned char version_minor_read(void) {
+ unsigned char r = csr_readl(0xe0007004L);
+ return r;
+}
+#define CSR_VERSION_REVISION_ADDR 0xe0007008L
+#define CSR_VERSION_REVISION_SIZE 1
+static inline unsigned char version_revision_read(void) {
+ unsigned char r = csr_readl(0xe0007008L);
+ return r;
+}
+#define CSR_VERSION_GITREV_ADDR 0xe000700cL
+#define CSR_VERSION_GITREV_SIZE 4
+static inline unsigned int version_gitrev_read(void) {
+ unsigned int r = csr_readl(0xe000700cL);
+ r <<= 8;
+ r |= csr_readl(0xe0007010L);
+ r <<= 8;
+ r |= csr_readl(0xe0007014L);
+ r <<= 8;
+ r |= csr_readl(0xe0007018L);
+ return r;
+}
+#define CSR_VERSION_GITEXTRA_ADDR 0xe000701cL
+#define CSR_VERSION_GITEXTRA_SIZE 2
+static inline unsigned short int version_gitextra_read(void) {
+ unsigned short int r = csr_readl(0xe000701cL);
+ r <<= 8;
+ r |= csr_readl(0xe0007020L);
+ return r;
+}
+#define CSR_VERSION_DIRTY_ADDR 0xe0007024L
+#define CSR_VERSION_DIRTY_SIZE 1
+static inline unsigned char version_dirty_read(void) {
+ unsigned char r = csr_readl(0xe0007024L);
+ return r;
+}
+#define CSR_VERSION_DIRTY_DIRTY_OFFSET 0
+#define CSR_VERSION_DIRTY_DIRTY_SIZE 1
+#define CSR_VERSION_MODEL_ADDR 0xe0007028L
+#define CSR_VERSION_MODEL_SIZE 1
+static inline unsigned char version_model_read(void) {
+ unsigned char r = csr_readl(0xe0007028L);
+ return r;
+}
+#define CSR_VERSION_MODEL_MODEL_OFFSET 0
+#define CSR_VERSION_MODEL_MODEL_SIZE 8
+#define CSR_VERSION_SEED_ADDR 0xe000702cL
+#define CSR_VERSION_SEED_SIZE 4
+static inline unsigned int version_seed_read(void) {
+ unsigned int r = csr_readl(0xe000702cL);
+ r <<= 8;
+ r |= csr_readl(0xe0007030L);
+ r <<= 8;
+ r |= csr_readl(0xe0007034L);
+ r <<= 8;
+ r |= csr_readl(0xe0007038L);
+ return r;
+}
+
+#endif
diff --git a/ports/litex/boards/fomu/fomu-spi.ld b/ports/litex/boards/fomu/fomu-spi.ld
new file mode 100644
index 000000000..b6b00becd
--- /dev/null
+++ b/ports/litex/boards/fomu/fomu-spi.ld
@@ -0,0 +1,118 @@
+/*
+ GNU linker script for Fomu
+*/
+
+ENTRY(_start)
+
+/* Specify the memory areas */
+MEMORY
+{
+ FLASH (rx) : ORIGIN = 0x20040000, LENGTH = 0x100000 /* entire flash, 1 MiB */
+ RAM (xrw) : ORIGIN = 0x10000000, LENGTH = 0x00020000 /* 128 KiB */
+}
+
+/* top end of the stack */
+_estack = ORIGIN(RAM) + LENGTH(RAM);
+
+/* define output sections */
+SECTIONS
+{
+ /* This is the initialized data section
+ The program executes knowing that the data is in the RAM
+ but the loader puts the initial values in the FLASH (inidata).
+ It is one task of the startup to copy the initial values from FLASH to RAM. */
+ .data : AT ( _sidata )
+ {
+ . = ALIGN(4);
+ _sdata = .; /* create a global symbol at data start; used by startup code in order to initialise the .data section in RAM */
+
+ /* These functions must be in RAM for USB to respond in time. */
+ *(.text.timer0_ev_pending_write)
+ *(.text.mp_parse)
+ *(.text.parse_compile_execute)
+ *(.text.cmp_lfn)
+ *(.text.qstr_find_strn)
+ *(.text.dcd_edpt_xfer)
+ *(.text.pop_rule)
+ *(.text.ff_wtoupper)
+ *(.text.dir_find)
+ *(.text.push_rule)
+ *(.text.csr_writel)
+ *(.text.csr_readl)
+ *(.text.autoreload_tick)
+ *(.text.filesystem_tick)
+
+ /* These two functions are called twice as often as any other function */
+ *(.text.mp_map_lookup)
+ *(.text.mp_execute_bytecode) /* Note: this function is 7kb */
+
+ /* These functions are hot, and placing them in ram greatly
+ * improves performance
+ */
+ *(.text.mp_decode_uint_value)
+ *(.text.tud_cdc_n_write_flush)
+ *(.text.mp_load_method_maybe)
+ *(.text.mp_convert_member_lookup)
+ *(.text.irq_getmask)
+ *(.text.irq_setmask)
+ *(.text.tu_edpt_dir)
+ *(.text.tu_fifo_empty)
+ *(.text.irq_pending)
+ *(.text.tud_task)
+ *(.text.usb_background)
+ *(.text._osal_q_lock)
+ *(.text.osal_queue_receive)
+ *(.text.mp_obj_get_type)
+ *(.text.usbd_edpt_busy)
+
+ *(.ramtext) /* .text* sections (code) */
+ *(.ramtext*) /* .text* sections (code) */
+ *(.data) /* .data sections */
+ *(.data*) /* .data* sections */
+ *(.sdata) /* .data sections */
+ *(.sdata*) /* .data* sections */
+
+ . = ALIGN(4);
+ _edata = .; /* define a global symbol at data end; used by startup code in order to initialise the .data section in RAM */
+ } >RAM
+
+ /* The program code and other data goes into FLASH */
+ .text :
+ {
+ . = ALIGN(4);
+ KEEP(*(.text.start)) /* isr vector table */
+ *(.text) /* .text sections (code) */
+ *(.text*) /* .text* sections (code) */
+ *(.rodata) /* .rodata sections (constants, strings, etc.) */
+ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */
+ *(.srodata) /* .rodata sections (constants, strings, etc.) */
+ *(.srodata*) /* .rodata* sections (constants, strings, etc.) */
+
+ . = ALIGN(4);
+ _etext = .; /* define a global symbol at end of code */
+ _sidata = _etext; /* This is used by the startup in order to initialize the .data secion */
+ } >FLASH
+
+ /* Uninitialized data section */
+ .bss :
+ {
+ . = ALIGN(4);
+ _sbss = .; /* define a global symbol at bss start; used by startup code */
+ *(.bss)
+ *(.bss*)
+ *(.sbss)
+ *(.sbss*)
+ *(COMMON)
+
+ . = ALIGN(4);
+ _ebss = .; /* define a global symbol at bss end; used by startup code */
+ } >RAM
+
+
+ /* this is to define the start of the heap, and make sure we have a minimum size */
+ .heap :
+ {
+ . = ALIGN(4);
+ _heap_start = .; /* define a global symbol at heap start */
+ } >RAM
+}
diff --git a/ports/litex/boards/fomu/generated/soc.h b/ports/litex/boards/fomu/generated/soc.h
new file mode 100644
index 000000000..91b2f1a31
--- /dev/null
+++ b/ports/litex/boards/fomu/generated/soc.h
@@ -0,0 +1,58 @@
+//--------------------------------------------------------------------------------
+// Auto-generated by Migen (f4fcd10) & LiteX (de205d4a) on 2019-11-25 15:17:59
+//--------------------------------------------------------------------------------
+#ifndef __GENERATED_SOC_H
+#define __GENERATED_SOC_H
+#define CONFIG_BITSTREAM_SYNC_HEADER1 2123999870
+static inline int config_bitstream_sync_header1_read(void) {
+ return 2123999870;
+}
+#define CONFIG_BITSTREAM_SYNC_HEADER2 2125109630
+static inline int config_bitstream_sync_header2_read(void) {
+ return 2125109630;
+}
+#define CONFIG_CLOCK_FREQUENCY 12000000
+static inline int config_clock_frequency_read(void) {
+ return 12000000;
+}
+#define CONFIG_CPU_RESET_ADDR 0
+static inline int config_cpu_reset_addr_read(void) {
+ return 0;
+}
+#define CONFIG_CPU_TYPE "VEXRISCV"
+static inline const char * config_cpu_type_read(void) {
+ return "VEXRISCV";
+}
+#define CONFIG_CPU_TYPE_VEXRISCV
+#define CONFIG_CPU_VARIANT "MIN"
+static inline const char * config_cpu_variant_read(void) {
+ return "MIN";
+}
+#define CONFIG_CPU_VARIANT_MIN
+#define CONFIG_CSR_ALIGNMENT 32
+static inline int config_csr_alignment_read(void) {
+ return 32;
+}
+#define CONFIG_CSR_DATA_WIDTH 8
+static inline int config_csr_data_width_read(void) {
+ return 8;
+}
+#define CONFIG_FOMU_REV "HACKER"
+static inline const char * config_fomu_rev_read(void) {
+ return "HACKER";
+}
+#define CONFIG_FOMU_REV_HACKER
+#define CONFIG_SHADOW_BASE 2147483648
+static inline int config_shadow_base_read(void) {
+ return 2147483648;
+}
+#define TIMER0_INTERRUPT 2
+static inline int timer0_interrupt_read(void) {
+ return 2;
+}
+#define USB_INTERRUPT 3
+static inline int usb_interrupt_read(void) {
+ return 3;
+}
+
+#endif
diff --git a/ports/litex/boards/fomu/mpconfigboard.h b/ports/litex/boards/fomu/mpconfigboard.h
new file mode 100644
index 000000000..127301eee
--- /dev/null
+++ b/ports/litex/boards/fomu/mpconfigboard.h
@@ -0,0 +1,37 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+//Micropython setup
+
+#define MICROPY_HW_BOARD_NAME "Fomu"
+#define MICROPY_HW_MCU_NAME "VexRiscv"
+
+#define FLASH_SIZE (0x100000)
+#define FLASH_PAGE_SIZE (0x1000)
+#define FLASH_PARTITION_OFFSET_BYTES (1024*1024)
+
+#define AUTORESET_DELAY_MS 500
+#define BOARD_FLASH_SIZE (FLASH_SIZE)
diff --git a/ports/litex/boards/fomu/mpconfigboard.mk b/ports/litex/boards/fomu/mpconfigboard.mk
new file mode 100644
index 000000000..4787803cc
--- /dev/null
+++ b/ports/litex/boards/fomu/mpconfigboard.mk
@@ -0,0 +1,20 @@
+USB_VID = 0x1209
+USB_PID = 0x5BF0
+USB_PRODUCT = "Fomu"
+USB_MANUFACTURER = "Foosn"
+USB_DEVICES = "CDC,MSC,AUDIO,HID"
+
+INTERNAL_FLASH_FILESYSTEM = 1
+LONGINT_IMPL = MPZ
+
+# The default queue depth of 16 overflows on release builds,
+# so increase it to 32.
+CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32
+
+# Fomu only implements rv32i
+CFLAGS += -march=rv32i -mabi=ilp32
+LDFLAGS += -march=rv32i -mabi=ilp32
+
+CIRCUITPY_NEOPIXEL_WRITE = 1
+CIRCUITPY_DIGITALIO = 1
+CIRCUITPY_MICROCONTROLLER = 1
diff --git a/ports/litex/boards/fomu/pins.c b/ports/litex/boards/fomu/pins.c
new file mode 100644
index 000000000..6be495c33
--- /dev/null
+++ b/ports/litex/boards/fomu/pins.c
@@ -0,0 +1,9 @@
+#include "shared-bindings/board/__init__.h"
+
+STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_TOUCH1), MP_ROM_PTR(&pin_TOUCH1) },
+ { MP_ROM_QSTR(MP_QSTR_TOUCH2), MP_ROM_PTR(&pin_TOUCH2) },
+ { MP_ROM_QSTR(MP_QSTR_TOUCH3), MP_ROM_PTR(&pin_TOUCH3) },
+ { MP_ROM_QSTR(MP_QSTR_TOUCH4), MP_ROM_PTR(&pin_TOUCH4) },
+};
+MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table);
diff --git a/ports/litex/boards/fomu/profiling.gdb.txt b/ports/litex/boards/fomu/profiling.gdb.txt
new file mode 100644
index 000000000..28faf45b7
--- /dev/null
+++ b/ports/litex/boards/fomu/profiling.gdb.txt
@@ -0,0 +1,16 @@
+set pagination 0
+set logging file profile.txt
+set logging overwrite
+
+server define poor_profile
+set $total = $arg0
+set $i = 0
+ set logging on
+ while($i<$total)
+ set $i = $i + 1
+ cont
+ p $pc
+ bt
+ end
+ set logging off
+end