summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorMichael Neuling <mikey@neuling.org>2019-08-22 10:21:48 +1000
committerDamien George <damien.p.george@gmail.com>2019-10-22 22:45:33 +1100
commit079cc940a68b3b3b9d47d4402267393a528a0477 (patch)
treecf124486508818ab74f85625ab973e01a1db4ad4
parent19ca025b45b3160a2ad5a20014cdd7bf0053ff9d (diff)
downloadmicropython-079cc940a68b3b3b9d47d4402267393a528a0477.tar.gz
micropython-079cc940a68b3b3b9d47d4402267393a528a0477.zip
powerpc: Add initial port to bare metal PowerPC arch.
Runs in microwatt (GHDL and FPGA) and qemu. Port done initially by Michael Neuling, with help from Anton Blanchard and Jordan Niethe.
-rw-r--r--.travis.yml9
-rw-r--r--ports/powerpc/Makefile64
-rw-r--r--ports/powerpc/README.md40
-rw-r--r--ports/powerpc/frozentest.mpybin0 -> 196 bytes
-rw-r--r--ports/powerpc/frozentest.py7
-rw-r--r--ports/powerpc/head.S121
-rw-r--r--ports/powerpc/main.c139
-rw-r--r--ports/powerpc/mpconfigport.h123
-rw-r--r--ports/powerpc/mphalport.h45
-rw-r--r--ports/powerpc/powerpc.lds13
-rw-r--r--ports/powerpc/qstrdefsport.h1
-rw-r--r--ports/powerpc/uart_core.c73
-rw-r--r--ports/powerpc/uart_lpc_serial.c111
-rw-r--r--ports/powerpc/uart_lpc_serial.h29
-rw-r--r--ports/powerpc/uart_potato.c121
-rw-r--r--ports/powerpc/uart_potato.h29
-rw-r--r--ports/powerpc/unistd.h36
-rw-r--r--py/nlr.h4
-rw-r--r--py/nlrpowerpc.c121
-rw-r--r--py/py.mk1
20 files changed, 1087 insertions, 0 deletions
diff --git a/.travis.yml b/.travis.yml
index 077fca20af..5923cb2b96 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -232,3 +232,12 @@ jobs:
- sudo apt-get install libnewlib-arm-none-eabi
script:
- make ${MAKEOPTS} -C ports/teensy
+
+ # powerpc port
+ - stage: test
+ env: NAME="powerpc port build"
+ install:
+ - sudo apt-get install gcc-powerpc64le-linux-gnu
+ - sudo apt-get install libc6-dev-ppc64el-cross
+ script:
+ - make ${MAKEOPTS} -C ports/powerpc CROSS_COMPILE=powerpc64le-linux-gnu-
diff --git a/ports/powerpc/Makefile b/ports/powerpc/Makefile
new file mode 100644
index 0000000000..30474df1d1
--- /dev/null
+++ b/ports/powerpc/Makefile
@@ -0,0 +1,64 @@
+include ../../py/mkenv.mk
+
+# qstr definitions (must come before including py.mk)
+QSTR_DEFS = qstrdefsport.h
+
+# include py core make definitions
+include $(TOP)/py/py.mk
+
+ARCH = $(shell uname -m)
+ifneq ("$(ARCH)", "ppc64")
+ifneq ("$(ARCH)", "ppc64le")
+ CROSS_COMPILE = powerpc64le-linux-
+endif
+endif
+
+INC += -I.
+INC += -I$(TOP)
+INC += -I$(BUILD)
+
+CFLAGS = $(INC) -g -Wall -std=c99 $(COPT)
+CFLAGS += -mno-string -mno-multiple -mno-vsx -mno-altivec -nostdlib
+CFLAGS += -mlittle-endian -mstrict-align -msoft-float
+CFLAGS += -Os
+CFLAGS += -fdata-sections -ffunction-sections -fno-stack-protector -ffreestanding
+CFLAGS += -U_FORTIFY_SOURCE
+
+LDFLAGS = -N -T powerpc.lds -nostdlib
+
+LIBS =
+
+SRC_C = \
+ main.c \
+ uart_core.c \
+ uart_potato.c \
+ uart_lpc_serial.c \
+ lib/utils/printf.c \
+ lib/utils/stdout_helpers.c \
+ lib/utils/pyexec.c \
+ lib/libc/string0.c \
+ lib/mp-readline/readline.c \
+ $(BUILD)/_frozen_mpy.c \
+
+OBJ = $(PY_CORE_O)
+OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
+OBJ += $(BUILD)/head.o
+
+all: $(BUILD)/firmware.elf $(BUILD)/firmware.map $(BUILD)/firmware.bin
+
+$(BUILD)/_frozen_mpy.c: frozentest.mpy $(BUILD)/genhdr/qstrdefs.generated.h
+ $(ECHO) "MISC freezing bytecode"
+ $(Q)$(MPY_TOOL) -f -q $(BUILD)/genhdr/qstrdefs.preprocessed.h -mlongint-impl=mpz $< > $@
+
+$(BUILD)/firmware.elf: $(OBJ) powerpc.lds
+ $(ECHO) "LINK $@"
+ $(Q)$(LD) $(LDFLAGS) -o $@ $^ $(LIBS)
+ $(Q)$(SIZE) $@
+
+$(BUILD)/firmware.bin: $(BUILD)/firmware.elf
+ $(Q)$(OBJCOPY) -O binary $^ $(BUILD)/firmware.bin
+
+$(BUILD)/firmware.map: $(BUILD)/firmware.elf
+ $(Q)nm $^ | sort > $(BUILD)/firmware.map
+
+include $(TOP)/py/mkrules.mk
diff --git a/ports/powerpc/README.md b/ports/powerpc/README.md
new file mode 100644
index 0000000000..862bfcd3c5
--- /dev/null
+++ b/ports/powerpc/README.md
@@ -0,0 +1,40 @@
+# The PowerPC port that runs on microwatt and qemu
+
+This port is intended to be a minimal MicroPython port that runs in
+QEMU, microwatt simulator with ghdl or microwatt on Xilinx FPGA with
+potato UART.
+
+## Building
+
+By default the port will be built for the host machine:
+
+ $ make
+
+## Cross compilation for POWERPC
+
+If you need to cross compilers you'll want to grab a powerpc64le
+compiler (not powerpc or powerpc64).
+
+On Ubuntu (18.04) you'll want:
+
+ $ apt install gcc-powerpc64le-linux-gnu
+
+*(Use CROSS_COMPILE=powerpc64le-linux-gnu-)*
+
+If your distro doesn't have cross compilers, you can get cross compilers here:
+- https://toolchains.bootlin.com/
+*(use CROSS_COMPILE=powerpc64le-buildroot-linux-gnu-)*
+
+(Avoid musl libc as it defines __assert_fail() differently to glibc
+which breaks the micropython powerpc code)
+
+Then do:
+
+ $ make CROSS_COMPILE=<compiler prefix>
+
+Building will produce the build/firmware.bin file which can be used
+QEMU or [microwatt](https://github.com/antonblanchard/microwatt).
+
+To run in QEMU use:
+
+ $ ./qemu-system-ppc64 -M powernv -cpu POWER9 -nographic -bios build/firmware.bin
diff --git a/ports/powerpc/frozentest.mpy b/ports/powerpc/frozentest.mpy
new file mode 100644
index 0000000000..8a89194a10
--- /dev/null
+++ b/ports/powerpc/frozentest.mpy
Binary files differ
diff --git a/ports/powerpc/frozentest.py b/ports/powerpc/frozentest.py
new file mode 100644
index 0000000000..0f99b74297
--- /dev/null
+++ b/ports/powerpc/frozentest.py
@@ -0,0 +1,7 @@
+print('uPy')
+print('a long string that is not interned')
+print('a string that has unicode αβγ chars')
+print(b'bytes 1234\x01')
+print(123456789)
+for i in range(4):
+ print(i)
diff --git a/ports/powerpc/head.S b/ports/powerpc/head.S
new file mode 100644
index 0000000000..09aa62e59c
--- /dev/null
+++ b/ports/powerpc/head.S
@@ -0,0 +1,121 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019, Michael Neuling, IBM Corporation.
+ *
+ * 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.
+ */
+
+#define STACK_TOP 0x60000
+
+#define FIXUP_ENDIAN \
+ tdi 0,0,0x48; /* Reverse endian of b . + 8 */ \
+ b 191f; /* Skip trampoline if endian is good */ \
+ .long 0xa600607d; /* mfmsr r11 */ \
+ .long 0x01006b69; /* xori r11,r11,1 */ \
+ .long 0x05009f42; /* bcl 20,31,$+4 */ \
+ .long 0xa602487d; /* mflr r10 */ \
+ .long 0x14004a39; /* addi r10,r10,20 */ \
+ .long 0xa64b5a7d; /* mthsrr0 r10 */ \
+ .long 0xa64b7b7d; /* mthsrr1 r11 */ \
+ .long 0x2402004c; /* hrfid */ \
+ 191:
+
+/* Load an immediate 64-bit value into a register */
+#define LOAD_IMM64(r, e) \
+ lis r,(e)@highest; \
+ ori r,r,(e)@higher; \
+ rldicr r,r, 32, 31; \
+ oris r,r, (e)@h; \
+ ori r,r, (e)@l;
+
+.section ".head","ax"
+
+/*
+ * Microwatt comes in at 0 as little endian so we do not need to worry up
+ * FIXUP_ENDIAN.
+ */
+ . = 0
+ .global _start
+_start:
+ b boot_entry
+
+/* QEMU comes in at 0x10. Put a value in argc/r3 to distingush from
+ * microwatt. */
+ . = 0x10
+ FIXUP_ENDIAN
+ LOAD_IMM64(%r3, 1)
+ b boot_entry
+
+ .global boot_entry
+ boot_entry:
+ /* Save R3 to non-volatile register */
+ mr %r14, %r3
+ restart:
+ /*
+ * setup stack with a safety gap, since we might write to the
+ * previous frame.
+ */
+ LOAD_IMM64(%r1, STACK_TOP - 0x100)
+ LOAD_IMM64(%r12, main)
+ mtctr %r12
+ bctrl
+
+ /* On exit, restart */
+ mr %r3, %r14
+ b restart
+
+#define EXCEPTION(nr) \
+ .= nr; \
+b .
+
+ /* More exception stubs */
+ EXCEPTION(0x300)
+ EXCEPTION(0x380)
+ EXCEPTION(0x400)
+ EXCEPTION(0x480)
+ EXCEPTION(0x500)
+ EXCEPTION(0x600)
+ EXCEPTION(0x700)
+ EXCEPTION(0x800)
+ EXCEPTION(0x900)
+ EXCEPTION(0x980)
+ EXCEPTION(0xa00)
+ EXCEPTION(0xb00)
+ EXCEPTION(0xc00)
+ EXCEPTION(0xd00)
+ EXCEPTION(0xe00)
+ EXCEPTION(0xe20)
+ EXCEPTION(0xe40)
+ EXCEPTION(0xe60)
+ EXCEPTION(0xe80)
+ EXCEPTION(0xf00)
+ EXCEPTION(0xf20)
+ EXCEPTION(0xf40)
+ EXCEPTION(0xf60)
+ EXCEPTION(0xf80)
+ EXCEPTION(0x1000)
+ EXCEPTION(0x1100)
+ EXCEPTION(0x1200)
+ EXCEPTION(0x1300)
+ EXCEPTION(0x1400)
+ EXCEPTION(0x1500)
+ EXCEPTION(0x1600)
diff --git a/ports/powerpc/main.c b/ports/powerpc/main.c
new file mode 100644
index 0000000000..9b164ac18c
--- /dev/null
+++ b/ports/powerpc/main.c
@@ -0,0 +1,139 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019, Michael Neuling, IBM Corporation.
+ *
+ * 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 <stdio.h>
+
+#include "py/compile.h"
+#include "py/runtime.h"
+#include "py/repl.h"
+#include "py/gc.h"
+#include "py/mperrno.h"
+#include "py/stackctrl.h"
+#include "lib/utils/pyexec.h"
+
+void __stack_chk_fail(void);
+void __stack_chk_fail(void) {
+ static bool failed_once;
+
+ if (failed_once) {
+ return;
+ }
+ failed_once = true;
+ printf("Stack corruption detected !\n");
+ assert(0);
+}
+
+/* fill in __assert_fail for libc */
+void __assert_fail(const char *__assertion, const char *__file,
+ unsigned int __line, const char *__function) {
+ printf("Assert at %s:%d:%s() \"%s\" failed\n", __file, __line, __function, __assertion);
+ for (;;) ;
+}
+
+static char *stack_top;
+#if MICROPY_ENABLE_GC
+static char heap[32 * 1024];
+#endif
+
+extern void uart_init_ppc(int qemu);
+
+int main(int argc, char **argv) {
+ int stack_dummy;
+ stack_top = (char*)&stack_dummy;
+
+ // microwatt has argc/r3 = 0 whereas QEMU has r3 set in head.S
+ uart_init_ppc(argc);
+
+ #if MICROPY_ENABLE_PYSTACK
+ static mp_obj_t pystack[1024];
+ mp_pystack_init(pystack, &pystack[1024]);
+ #endif
+
+ #if MICROPY_STACK_CHECK
+ mp_stack_ctrl_init();
+ mp_stack_set_limit(48 * 1024);
+ #endif
+
+ #if MICROPY_ENABLE_GC
+ gc_init(heap, heap + sizeof(heap));
+ #endif
+ mp_init();
+ #if MICROPY_ENABLE_COMPILER
+ #if MICROPY_REPL_EVENT_DRIVEN
+ pyexec_event_repl_init();
+ for (;;) {
+ int c = mp_hal_stdin_rx_chr();
+ if (pyexec_event_repl_process_char(c)) {
+ break;
+ }
+ }
+ #else
+ pyexec_friendly_repl();
+ #endif
+ #else
+ pyexec_frozen_module("frozentest.py");
+ #endif
+ mp_deinit();
+ return 0;
+}
+
+void gc_collect(void) {
+ // WARNING: This gc_collect implementation doesn't try to get root
+ // pointers from CPU registers, and thus may function incorrectly.
+ void *dummy;
+ gc_collect_start();
+ gc_collect_root(&dummy, ((mp_uint_t)stack_top - (mp_uint_t)&dummy) / sizeof(mp_uint_t));
+ gc_collect_end();
+ gc_dump_info();
+}
+
+mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
+ mp_raise_OSError(MP_ENOENT);
+}
+
+mp_import_stat_t mp_import_stat(const char *path) {
+ return MP_IMPORT_STAT_NO_EXIST;
+}
+
+mp_obj_t mp_builtin_open(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) {
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open);
+
+void nlr_jump_fail(void *val) {
+ while (1);
+}
+
+void NORETURN __fatal_error(const char *msg) {
+ while (1);
+}
+
+#ifndef NDEBUG
+void MP_WEAK __assert_func(const char *file, int line, const char *func, const char *expr) {
+ printf("Assertion '%s' failed, at file %s:%d\n", expr, file, line);
+ __fatal_error("Assertion failed");
+}
+#endif
diff --git a/ports/powerpc/mpconfigport.h b/ports/powerpc/mpconfigport.h
new file mode 100644
index 0000000000..93ef699ad9
--- /dev/null
+++ b/ports/powerpc/mpconfigport.h
@@ -0,0 +1,123 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019, Michael Neuling, IBM Corporation.
+ *
+ * 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 <stdint.h>
+
+// options to control how MicroPython is built
+
+// You can disable the built-in MicroPython compiler by setting the following
+// config option to 0. If you do this then you won't get a REPL prompt, but you
+// will still be able to execute pre-compiled scripts, compiled with mpy-cross.
+#define MICROPY_ENABLE_COMPILER (1)
+
+//#define MICROPY_DEBUG_VERBOSE (1)
+
+#define MICROPY_QSTR_BYTES_IN_HASH (1)
+#define MICROPY_QSTR_EXTRA_POOL mp_qstr_frozen_const_pool
+#define MICROPY_ALLOC_PATH_MAX (256)
+#define MICROPY_ALLOC_PARSE_CHUNK_INIT (16)
+#define MICROPY_EMIT_X64 (0)
+#define MICROPY_EMIT_THUMB (0)
+#define MICROPY_EMIT_INLINE_THUMB (0)
+#define MICROPY_COMP_MODULE_CONST (0)
+#define MICROPY_COMP_CONST (0)
+#define MICROPY_COMP_DOUBLE_TUPLE_ASSIGN (0)
+#define MICROPY_COMP_TRIPLE_TUPLE_ASSIGN (0)
+#define MICROPY_MEM_STATS (0)
+#define MICROPY_DEBUG_PRINTERS (1)
+#define MICROPY_ENABLE_GC (1)
+#define MICROPY_STACK_CHECK (1)
+#define MICROPY_GC_ALLOC_THRESHOLD (0)
+#define MICROPY_REPL_EVENT_DRIVEN (0)
+#define MICROPY_HELPER_REPL (1)
+#define MICROPY_HELPER_LEXER_UNIX (0)
+#define MICROPY_ENABLE_SOURCE_LINE (1)
+#define MICROPY_ENABLE_DOC_STRING (0)
+#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_TERSE)
+#define MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG (0)
+#define MICROPY_PY_ASYNC_AWAIT (0)
+#define MICROPY_MODULE_BUILTIN_INIT (1)
+#define MICROPY_PY_BUILTINS_BYTEARRAY (1)
+#define MICROPY_PY_BUILTINS_DICT_FROMKEYS (1)
+#define MICROPY_PY_BUILTINS_MEMORYVIEW (1)
+#define MICROPY_PY_BUILTINS_ENUMERATE (1)
+#define MICROPY_PY_BUILTINS_FILTER (1)
+#define MICROPY_PY_BUILTINS_FROZENSET (1)
+#define MICROPY_PY_BUILTINS_REVERSED (1)
+#define MICROPY_PY_BUILTINS_SET (1)
+#define MICROPY_PY_BUILTINS_SLICE (1)
+#define MICROPY_PY_BUILTINS_PROPERTY (1)
+#define MICROPY_PY_BUILTINS_MIN_MAX (1)
+#define MICROPY_PY_BUILTINS_STR_COUNT (1)
+#define MICROPY_PY_BUILTINS_STR_OP_MODULO (1)
+#define MICROPY_PY_BUILTINS_HELP (1)
+#define MICROPY_PY_BUILTINS_HELP_MODULES (1)
+#define MICROPY_PY___FILE__ (0)
+#define MICROPY_PY_GC (1)
+#define MICROPY_PY_ARRAY (1)
+#define MICROPY_PY_COLLECTIONS (1)
+#define MICROPY_PY_MATH (0)
+#define MICROPY_PY_CMATH (0)
+#define MICROPY_PY_IO (0)
+#define MICROPY_PY_STRUCT (1)
+#define MICROPY_PY_SYS (1)
+#define MICROPY_MODULE_FROZEN_MPY (1)
+#define MICROPY_CPYTHON_COMPAT (0)
+#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ)
+#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_NONE)
+#define MICROPY_ENABLE_PYSTACK (1)
+#define MICROPY_USE_INTERNAL_PRINTF (1)
+
+// type definitions for the specific machine
+
+#define MICROPY_MAKE_POINTER_CALLABLE(p) ((void*)((mp_uint_t)(p) | 1))
+
+// This port is 64-bit
+#define UINT_FMT "%lu"
+#define INT_FMT "%ld"
+typedef signed long mp_int_t; // must be pointer size
+typedef unsigned long mp_uint_t; // must be pointer size
+
+typedef long mp_off_t;
+
+#define MP_PLAT_PRINT_STRN(str, len) mp_hal_stdout_tx_strn_cooked(str, len)
+
+// extra built in names to add to the global namespace
+#define MICROPY_PORT_BUILTINS \
+ { MP_ROM_QSTR(MP_QSTR_open), MP_ROM_PTR(&mp_builtin_open_obj) },
+
+#define MICROPY_HW_BOARD_NAME "bare-metal"
+#define MICROPY_HW_MCU_NAME "POWERPC"
+
+#define MP_STATE_PORT MP_STATE_VM
+
+#define MICROPY_PORT_ROOT_POINTERS \
+ const char *readline_hist[8];
+
+// powerpc64 gcc doesn't seem to define these
+// These are pointers, so make them 64 bit types
+typedef long intptr_t;
+typedef unsigned long uintptr_t;
diff --git a/ports/powerpc/mphalport.h b/ports/powerpc/mphalport.h
new file mode 100644
index 0000000000..c6bf940072
--- /dev/null
+++ b/ports/powerpc/mphalport.h
@@ -0,0 +1,45 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019, Michael Neuling, IBM Corporation.
+ *
+ * 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.
+ */
+
+#define mftb() ({unsigned long rval; \
+ __asm__ volatile("mftb %0" : "=r" (rval)); rval;})
+
+#define TBFREQ 512000000
+
+static inline mp_uint_t mp_hal_ticks_ms(void) {
+ unsigned long tb = mftb();
+
+ return tb * 1000 / TBFREQ;
+}
+
+static inline mp_uint_t mp_hal_ticks_us(void) {
+ unsigned long tb = mftb();
+
+ return tb * 1000000 / TBFREQ;
+}
+
+static inline void mp_hal_set_interrupt_char(char c) {
+}
diff --git a/ports/powerpc/powerpc.lds b/ports/powerpc/powerpc.lds
new file mode 100644
index 0000000000..93bd8a605c
--- /dev/null
+++ b/ports/powerpc/powerpc.lds
@@ -0,0 +1,13 @@
+SECTIONS
+{
+ . = 0;
+ _start = .;
+ .head : {
+ KEEP(*(.head))
+ }
+
+ /* Put this at 0x1700 which is right after our execption
+ * vectors in head.S.
+ */
+ . = 0x1700;
+}
diff --git a/ports/powerpc/qstrdefsport.h b/ports/powerpc/qstrdefsport.h
new file mode 100644
index 0000000000..3ba897069b
--- /dev/null
+++ b/ports/powerpc/qstrdefsport.h
@@ -0,0 +1 @@
+// qstrs specific to this port
diff --git a/ports/powerpc/uart_core.c b/ports/powerpc/uart_core.c
new file mode 100644
index 0000000000..b0dcd031a5
--- /dev/null
+++ b/ports/powerpc/uart_core.c
@@ -0,0 +1,73 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019, Michael Neuling, IBM Corporation.
+ *
+ * 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 <unistd.h>
+#include <stdbool.h>
+
+#include "py/mpconfig.h"
+#include "uart_potato.h"
+#include "uart_lpc_serial.h"
+
+static int lpc_console;
+static int potato_console;
+
+void uart_init_ppc(int lpc) {
+ lpc_console = lpc;
+
+ if (!lpc_console) {
+ potato_console = 1;
+
+ potato_uart_init();
+ } else {
+ lpc_uart_init();
+ }
+}
+
+// Receive single character
+int mp_hal_stdin_rx_chr(void) {
+ unsigned char c = 0;
+ if (lpc_console) {
+ c = lpc_uart_read();
+ } else if (potato_console) {
+ c = potato_uart_read();
+ }
+ return c;
+}
+
+// Send string of given length
+void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) {
+ if (lpc_console) {
+ int i;
+ for (i = 0; i < len; i++) {
+ lpc_uart_write(str[i]);
+ }
+ } else if (potato_console) {
+ int i;
+ for (i = 0; i < len; i++) {
+ potato_uart_write(str[i]);
+ }
+ }
+}
diff --git a/ports/powerpc/uart_lpc_serial.c b/ports/powerpc/uart_lpc_serial.c
new file mode 100644
index 0000000000..51a55cb1e6
--- /dev/null
+++ b/ports/powerpc/uart_lpc_serial.c
@@ -0,0 +1,111 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019, Michael Neuling, IBM Corporation.
+ *
+ * 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 is the LPC serial UART used by POWER9 boxes. This is modelled
+ * in the qemu POWER9 machine.
+ */
+
+#include <unistd.h>
+#include <stdbool.h>
+#include "py/mpconfig.h"
+
+#define PROC_FREQ 50000000
+#define UART_FREQ 115200
+#define UART_BASE 0xc0002000
+#define LPC_UART_BASE 0x60300d00103f8
+
+/* Taken from skiboot */
+#define REG_RBR 0
+#define REG_THR 0
+#define REG_DLL 0
+#define REG_IER 1
+#define REG_DLM 1
+#define REG_FCR 2
+#define REG_IIR 2
+#define REG_LCR 3
+#define REG_MCR 4
+#define REG_LSR 5
+#define REG_MSR 6
+#define REG_SCR 7
+
+#define LSR_DR 0x01 /* Data ready */
+#define LSR_OE 0x02 /* Overrun */
+#define LSR_PE 0x04 /* Parity error */
+#define LSR_FE 0x08 /* Framing error */
+#define LSR_BI 0x10 /* Break */
+#define LSR_THRE 0x20 /* Xmit holding register empty */
+#define LSR_TEMT 0x40 /* Xmitter empty */
+#define LSR_ERR 0x80 /* Error */
+
+#define LCR_DLAB 0x80 /* DLL access */
+
+#define IER_RX 0x01
+#define IER_THRE 0x02
+#define IER_ALL 0x0f
+
+static uint64_t lpc_uart_base;
+
+static void lpc_uart_reg_write(uint64_t offset, uint8_t val) {
+ uint64_t addr;
+
+ addr = lpc_uart_base + offset;
+
+ *(volatile uint8_t *)addr = val;
+}
+
+static uint8_t lpc_uart_reg_read(uint64_t offset) {
+ uint64_t addr;
+ uint8_t val;
+
+ addr = lpc_uart_base + offset;
+
+ val = *(volatile uint8_t *)addr;
+
+ return val;
+}
+
+static int lpc_uart_tx_full(void) {
+ return !(lpc_uart_reg_read(REG_LSR) & LSR_THRE);
+}
+
+static int lpc_uart_rx_empty(void) {
+ return !(lpc_uart_reg_read(REG_LSR) & LSR_DR);
+}
+
+void lpc_uart_init(void) {
+ lpc_uart_base = LPC_UART_BASE;
+}
+
+char lpc_uart_read(void) {
+ while (lpc_uart_rx_empty()) ;
+ return lpc_uart_reg_read(REG_THR);
+}
+
+void lpc_uart_write(char c) {
+ while (lpc_uart_tx_full());
+ lpc_uart_reg_write(REG_RBR, c);
+}
diff --git a/ports/powerpc/uart_lpc_serial.h b/ports/powerpc/uart_lpc_serial.h
new file mode 100644
index 0000000000..d0e35ca32b
--- /dev/null
+++ b/ports/powerpc/uart_lpc_serial.h
@@ -0,0 +1,29 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019, Michael Neuling, IBM Corporation.
+ *
+ * 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.
+ */
+
+void lpc_uart_init(void);
+char lpc_uart_read(void);
+void lpc_uart_write(char c);
diff --git a/ports/powerpc/uart_potato.c b/ports/powerpc/uart_potato.c
new file mode 100644
index 0000000000..18f89d463a
--- /dev/null
+++ b/ports/powerpc/uart_potato.c
@@ -0,0 +1,121 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019, Michael Neuling, IBM Corporation.
+ *
+ * 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 is a driver for the potato UART used by the microwatt core.
+ * The original potato UART came from here
+ * https://github.com/skordal/potato
+ */
+
+#include <unistd.h>
+#include <stdbool.h>
+#include "py/mpconfig.h"
+
+#define PROC_FREQ 50000000
+#define UART_FREQ 115200
+#define POTATO_UART_BASE 0xc0002000
+uint64_t potato_uart_base;
+
+#define POTATO_CONSOLE_TX 0x00
+#define POTATO_CONSOLE_RX 0x08
+#define POTATO_CONSOLE_STATUS 0x10
+#define POTATO_CONSOLE_STATUS_RX_EMPTY 0x01
+#define POTATO_CONSOLE_STATUS_TX_EMPTY 0x02
+#define POTATO_CONSOLE_STATUS_RX_FULL 0x04
+#define POTATO_CONSOLE_STATUS_TX_FULL 0x08
+#define POTATO_CONSOLE_CLOCK_DIV 0x18
+#define POTATO_CONSOLE_IRQ_EN 0x20
+
+static uint64_t potato_uart_reg_read(int offset) {
+ uint64_t addr;
+ uint64_t val;
+
+ addr = potato_uart_base + offset;
+
+ val = *(volatile uint64_t *)addr;
+
+ return val;
+}
+
+void potato_uart_reg_write(int offset, uint64_t val) {
+ uint64_t addr;
+
+ addr = potato_uart_base + offset;
+
+ *(volatile uint64_t *)addr = val;
+}
+
+static int potato_uart_rx_empty(void) {
+ uint64_t val;
+
+ val = potato_uart_reg_read(POTATO_CONSOLE_STATUS);
+
+ if (val & POTATO_CONSOLE_STATUS_RX_EMPTY) {
+ return 1;
+ }
+
+ return 0;
+}
+
+static int potato_uart_tx_full(void) {
+ uint64_t val;
+
+ val = potato_uart_reg_read(POTATO_CONSOLE_STATUS);
+
+ if (val & POTATO_CONSOLE_STATUS_TX_FULL) {
+ return 1;
+ }
+
+ return 0;
+}
+
+static unsigned long potato_uart_divisor(unsigned long proc_freq, unsigned long uart_freq) {
+ return proc_freq / (uart_freq * 16) - 1;
+}
+
+void potato_uart_init(void) {
+ potato_uart_base = POTATO_UART_BASE;
+ potato_uart_reg_write(POTATO_CONSOLE_CLOCK_DIV, potato_uart_divisor(PROC_FREQ, UART_FREQ));
+
+}
+
+char potato_uart_read(void) {
+ uint64_t val;
+
+ while (potato_uart_rx_empty());
+ val = potato_uart_reg_read(POTATO_CONSOLE_RX);
+
+ return (char)(val & 0x000000ff);
+}
+
+void potato_uart_write(char c) {
+ uint64_t val;
+
+ val = c;
+
+ while (potato_uart_tx_full());
+ potato_uart_reg_write(POTATO_CONSOLE_TX, val);
+}
diff --git a/ports/powerpc/uart_potato.h b/ports/powerpc/uart_potato.h
new file mode 100644
index 0000000000..d6bd93aa4e
--- /dev/null
+++ b/ports/powerpc/uart_potato.h
@@ -0,0 +1,29 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019, Michael Neuling, IBM Corporation.
+ *
+ * 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.
+ */
+
+void potato_uart_init(void);
+char potato_uart_read(void);
+void potato_uart_write(char c);
diff --git a/ports/powerpc/unistd.h b/ports/powerpc/unistd.h
new file mode 100644
index 0000000000..88e3b27218
--- /dev/null
+++ b/ports/powerpc/unistd.h
@@ -0,0 +1,36 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019, Michael Neuling, IBM Corporation.
+ *
+ * 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.
+ */
+#ifndef MICROPY_INCLUDED_POWERPC_UNISTD_H
+#define MICROPY_INCLUDED_POWERPC_UNISTD_H
+
+// powerpc gcc compiler doesn't seem to have unistd.h file
+
+#define SEEK_SET 0
+#define SEEK_CUR 1
+
+typedef int ssize_t;
+
+#endif // MICROPY_INCLUDED_POWERPC_UNISTD_H
diff --git a/py/nlr.h b/py/nlr.h
index f2453bc460..3be3eb58cc 100644
--- a/py/nlr.h
+++ b/py/nlr.h
@@ -73,6 +73,10 @@
#elif defined(__xtensa__)
#define MICROPY_NLR_XTENSA (1)
#define MICROPY_NLR_NUM_REGS (MICROPY_NLR_NUM_REGS_XTENSA)
+#elif defined(__powerpc__)
+ #define MICROPY_NLR_POWERPC (1)
+ // this could be less but using 128 for safety
+ #define MICROPY_NLR_NUM_REGS (128)
#else
#define MICROPY_NLR_SETJMP (1)
//#warning "No native NLR support for this arch, using setjmp implementation"
diff --git a/py/nlrpowerpc.c b/py/nlrpowerpc.c
new file mode 100644
index 0000000000..b403823813
--- /dev/null
+++ b/py/nlrpowerpc.c
@@ -0,0 +1,121 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019, Michael Neuling, IBM Corporation.
+ *
+ * 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 "py/mpstate.h"
+
+#if MICROPY_NLR_POWERPC
+
+#undef nlr_push
+
+// Saving all ABI non-vol registers here
+
+unsigned int nlr_push(nlr_buf_t *nlr) {
+
+ __asm__ volatile(
+ "li 4, 0x4eed ; " // Store canary
+ "std 4, 0x00(%0) ;"
+ "std 0, 0x08(%0) ;"
+ "std 1, 0x10(%0) ;"
+ "std 2, 0x18(%0) ;"
+ "std 14, 0x20(%0) ;"
+ "std 15, 0x28(%0) ;"
+ "std 16, 0x30(%0) ;"
+ "std 17, 0x38(%0) ;"
+ "std 18, 0x40(%0) ;"
+ "std 19, 0x48(%0) ;"
+ "std 20, 0x50(%0) ;"
+ "std 21, 0x58(%0) ;"
+ "std 22, 0x60(%0) ;"
+ "std 23, 0x68(%0) ;"
+ "std 24, 0x70(%0) ;"
+ "std 25, 0x78(%0) ;"
+ "std 26, 0x80(%0) ;"
+ "std 27, 0x88(%0) ;"
+ "std 28, 0x90(%0) ;"
+ "std 29, 0x98(%0) ;"
+ "std 30, 0xA0(%0) ;"
+ "std 31, 0xA8(%0) ;"
+
+ "mfcr 4 ; "
+ "std 4, 0xB0(%0) ;"
+ "mflr 4 ;"
+ "std 4, 0xB8(%0) ;"
+ "li 4, nlr_push_tail@l ;"
+ "oris 4, 4, nlr_push_tail@h ;"
+ "mtctr 4 ;"
+ "mr 3, %1 ; "
+ "bctr ;"
+ :
+ : "r"(&nlr->regs), "r"(nlr)
+ :
+ );
+
+ return 0;
+}
+
+NORETURN void nlr_jump(void *val) {
+ MP_NLR_JUMP_HEAD(val, top)
+
+ __asm__ volatile(
+ "ld 3, 0x0(%0) ;"
+ "cmpdi 3, 0x4eed ; " // Check canary
+ "bne . ; "
+ "ld 0, 0x08(%0) ;"
+ "ld 1, 0x10(%0) ;"
+ "ld 2, 0x18(%0) ;"
+ "ld 14, 0x20(%0) ;"
+ "ld 15, 0x28(%0) ;"
+ "ld 16, 0x30(%0) ;"
+ "ld 17, 0x38(%0) ;"
+ "ld 18, 0x40(%0) ;"
+ "ld 19, 0x48(%0) ;"
+ "ld 20, 0x50(%0) ;"
+ "ld 21, 0x58(%0) ;"
+ "ld 22, 0x60(%0) ;"
+ "ld 23, 0x68(%0) ;"
+ "ld 24, 0x70(%0) ;"
+ "ld 25, 0x78(%0) ;"
+ "ld 26, 0x80(%0) ;"
+ "ld 27, 0x88(%0) ;"
+ "ld 28, 0x90(%0) ;"
+ "ld 29, 0x98(%0) ;"
+ "ld 30, 0xA0(%0) ;"
+ "ld 31, 0xA8(%0) ;"
+ "ld 3, 0xB0(%0) ;"
+ "mtcr 3 ;"
+ "ld 3, 0xB8(%0) ;"
+ "mtlr 3 ; "
+ "li 3, 1;"
+ "blr ;"
+ :
+ : "r"(&top->regs)
+ :
+ );
+
+ MP_UNREACHABLE;
+}
+
+#endif // MICROPY_NLR_POWERPC
diff --git a/py/py.mk b/py/py.mk
index 514a0e405a..d7021d3268 100644
--- a/py/py.mk
+++ b/py/py.mk
@@ -46,6 +46,7 @@ PY_CORE_O_BASENAME = $(addprefix py/,\
nlrx86.o \
nlrx64.o \
nlrthumb.o \
+ nlrpowerpc.o \
nlrxtensa.o \
nlrsetjmp.o \
malloc.o \