Merge pull request #2664 from utzig/kinetis-trng-refactor

Updates to the kinetis TRNG driver
diff --git a/.travis.yml b/.travis.yml
index 6d692ce..7c0eb21 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -196,7 +196,8 @@
   # might have extra dependencies hard to provide, non-common toolchains, etc
   # NOTE: "native" is here to avoid having to install gcc-multilib
   - export IGNORED_BSPS="ci40 embarc_emsk hifive1 native-armv7 native-mips
-                         pic32mx470_6lp_clicker pic32mz2048_wi-fire sensorhub
+                         pic32mx470_6lp_clicker pic32mz2048_wi-fire
+                         olimex-pic32-emz64 olimex-pic32-hmz144
                          native dialog_cmac"
   - |
     if [ "${TEST}" == "STYLE" ]; then
diff --git a/compiler/xc32/compiler.yml b/compiler/xc32/compiler.yml
index 326bb1d..61263d8 100644
--- a/compiler/xc32/compiler.yml
+++ b/compiler/xc32/compiler.yml
@@ -19,18 +19,19 @@
 
 compiler.path.cc: "xc32-gcc"
 compiler.path.as: "xc32-gcc"
+compiler.path.cpp: "xc32-g++"
 compiler.path.archive: "xc32-ar"
 compiler.path.objdump: "xc32-objdump"
 compiler.path.objsize: "xc32-size"
 compiler.path.objcopy: "xc32-objcopy"
 
-compiler.flags.base: [-std=gnu11, -msmart-io=0, -fno-common]
+compiler.flags.base: [-std=gnu11, -fno-common, -mnewlib-libc, -ffunction-sections, -fdata-sections]
 compiler.flags.default: [compiler.flags.base, -O2, -g3]
-compiler.flags.optimized: [compiler.flags.base, -Os, -g3]
-compiler.flags.debug: [compiler.flags.base, -g3]
+compiler.flags.optimized: [compiler.flags.base, -O2, -g3]
+compiler.flags.debug: [compiler.flags.base, -Og, -g3]
 
 compiler.as.flags: [-x, assembler-with-cpp]
 
-compiler.ld.flags: -nostartfiles -nostdlib -static-libgcc -lgcc
+compiler.ld.flags: -nostartfiles -nostdlib -static-libgcc -lgcc -lm -lc-newlib -Wl,--gc-sections
 compiler.ld.resolve_circular_deps: true
 compiler.ld.mapfile: true
diff --git a/hw/bsp/olimex-pic32-emz64/bsp.yml b/hw/bsp/olimex-pic32-emz64/bsp.yml
new file mode 100644
index 0000000..cd9a3d9
--- /dev/null
+++ b/hw/bsp/olimex-pic32-emz64/bsp.yml
@@ -0,0 +1,64 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+bsp.name: "PIC32-EMZ64"
+bsp.url: https://www.olimex.com/Products/PIC/Development/PIC32-EMZ64/open-source-hardware
+bsp.maker: "Olimex"
+
+bsp.arch: pic32
+bsp.compiler: "@apache-mynewt-core/compiler/xc32"
+bsp.downloadscript: "hw/bsp/olimex-pic32-emz64/download.sh"
+bsp.debugscript: "hw/bsp/olimex-pic32-emz64/debug.sh"
+bsp.linkerscript:
+    - "@apache-mynewt-core/hw/mcu/microchip/pic32mz/p32mz_app.ld"
+
+bsp.linkerscript.BOOT_LOADER.OVERWRITE:
+    - "@apache-mynewt-core/hw/mcu/microchip/pic32mz/p32mz_boot.ld"
+
+bsp.flash_map:
+    areas:
+        # System areas.
+        FLASH_AREA_BOOTLOADER:
+            device: 0
+            offset: 0x1FC00000
+            size: 64kB
+        FLASH_AREA_IMAGE_0:
+            device: 0
+            offset: 0x1D000000
+            size: 192kB
+        FLASH_AREA_IMAGE_1:
+            device: 0
+            offset: 0x1D030000
+            size: 192kB
+        FLASH_AREA_IMAGE_SCRATCH:
+            device: 0
+            offset: 0x1D060000
+            size: 16kB
+
+        # User areas.
+        FLASH_AREA_REBOOT_LOG:
+            user_id: 0
+            device: 1
+            offset: 0x00000000
+            size: 64kB
+        FLASH_AREA_NFFS:
+            user_id: 1
+            device: 1
+            offset: 0x00010000
+            size: 32kB
diff --git a/hw/bsp/olimex-pic32-emz64/download.sh b/hw/bsp/olimex-pic32-emz64/download.sh
new file mode 100644
index 0000000..358f287
--- /dev/null
+++ b/hw/bsp/olimex-pic32-emz64/download.sh
@@ -0,0 +1,54 @@
+#!/bin/sh
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# Called with following variables set:
+#  - CORE_PATH is absolute path to @apache-mynewt-core
+#  - BSP_PATH is absolute path to hw/bsp/bsp_name
+#  - BIN_BASENAME is the path to prefix to target binary,
+#    .elf appended to name is the ELF file
+#  - IMAGE_SLOT is the image slot to download to (for non-mfg-image, non-boot)
+#  - FEATURES holds the target features string
+#  - EXTRA_JTAG_CMD holds extra parameters to pass to jtag software
+#  - MFG_IMAGE is "1" if this is a manufacturing image
+#  - FLASH_OFFSET contains the flash offset to download to
+#  - BOOT_LOADER is set if downloading a bootloader
+
+if [ "${HWTOOL}" = "pickit3" ]; then
+  . $CORE_PATH/hw/scripts/mplab_mdb.sh
+
+  export DEVICE=PIC32MZ2048EFH064
+
+  mdb_load
+
+else
+
+  echo "r" > script
+  echo "h" >> script
+  if [ "$BOOT_LOADER" -o "$MYNEWT_VAL_MCU_NO_BOOTLOADER_BUILD" == "1" ]; then
+    xc32-objcopy -O ihex ${BIN_BASENAME}.elf ${BIN_BASENAME}.hex
+    echo "loadfile ${BIN_BASENAME}.hex" >> script
+  else
+    cp ${BIN_BASENAME}.img ${BIN_BASENAME}.bin
+    echo "loadfile ${BIN_BASENAME}.bin 0x1d000000" >> script
+  fi
+  echo "r" >> script
+  echo "g" >> script
+  echo "q" >> script
+
+  JLink${COMSPEC:+.}Exe  -AutoConnect 1 -Device PIC32MZ2048EFH064 -If ICSP -speed 12000 -CommandFile script
+fi
diff --git a/hw/bsp/olimex-pic32-emz64/include/bsp/bsp.h b/hw/bsp/olimex-pic32-emz64/include/bsp/bsp.h
new file mode 100644
index 0000000..8f22cd3
--- /dev/null
+++ b/hw/bsp/olimex-pic32-emz64/include/bsp/bsp.h
@@ -0,0 +1,67 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#ifndef H_BSP_H
+#define H_BSP_H
+
+#include <inttypes.h>
+#include <xc.h>
+#include <mcu/mcu.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Define special stackos sections */
+#define sec_data_core   __attribute__((section(".data.core")))
+#define sec_bss_core    __attribute__((section(".bss.core")))
+#define sec_bss_nz_core __attribute__((section(".bss.core.nz")))
+
+/* More convenient section placement macros. */
+#define bssnz_t         sec_bss_nz_core
+
+extern uint8_t _ram_start;
+
+#define RAM_SIZE        (512 * 1024)
+
+/* LED pins */
+#define LED_1           MCU_GPIO_PORTB(8)
+#define LED_2           MCU_GPIO_PORTB(9)
+#define LED_3           MCU_GPIO_PORTB(10)
+#define LED_BLINK_PIN   LED_2
+
+/* Buttons */
+#define BUTTON_1        MCU_GPIO_PORTB(12)
+#define BUTTON_2        MCU_GPIO_PORTB(13)
+#define BUTTON_3        MCU_GPIO_PORTB(14)
+
+/* UART */
+#define UART_CNT        (6)
+
+/* SPI */
+#define SPI_CNT         (6)
+
+/* I2C */
+#define I2C_CNT         (5)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* H_BSP_H */
diff --git a/hw/bsp/olimex-pic32-emz64/p32mz_app_mem.ld b/hw/bsp/olimex-pic32-emz64/p32mz_app_mem.ld
new file mode 100644
index 0000000..5a21eb6
--- /dev/null
+++ b/hw/bsp/olimex-pic32-emz64/p32mz_app_mem.ld
@@ -0,0 +1,13 @@
+
+/*
+ * Part of the MEMORY section that defines application memory size.
+ * This file is included by MCU linker script.
+ * this file does not have whole MEMORY section to make it clear
+ * what are differences between MCUs (Flash size and RAM), config
+ * sections are same.
+ */
+
+  /* Program leave space for image header ~192KB */
+  kseg0_program_mem     (rx)  : ORIGIN = 0x9D000020, LENGTH = 0x2FFE0
+  /* Cachable RAM 512KB */
+  kseg0_data_mem       (w!x)  : ORIGIN = 0x80000000, LENGTH = 0x80000
diff --git a/hw/bsp/olimex-pic32-emz64/pkg.yml b/hw/bsp/olimex-pic32-emz64/pkg.yml
new file mode 100644
index 0000000..8d17af1
--- /dev/null
+++ b/hw/bsp/olimex-pic32-emz64/pkg.yml
@@ -0,0 +1,38 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+pkg.name: hw/bsp/olimex-pic32-emz64
+pkg.type: bsp
+pkg.description: BSP definition for the Olimex PIC32-EMZ64 board.
+pkg.author: "Apache Mynewt <dev@mynewt.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+    - pic32
+    - microchip
+
+pkg.cflags:
+    - -mprocessor=32MZ2048EFH064
+    - -G6
+pkg.lflags:
+    - "-L@apache-mynewt-core/hw/bsp/olimex-pic32-emz64"
+
+pkg.deps:
+    - "@apache-mynewt-core/hw/mcu/microchip/pic32mz"
+    - "@apache-mynewt-core/libc/baselibc"
+    - "@apache-mynewt-core/hw/drivers/flash/spiflash"
diff --git a/hw/bsp/olimex-pic32-emz64/src/hal_bsp.c b/hw/bsp/olimex-pic32-emz64/src/hal_bsp.c
new file mode 100644
index 0000000..414ab31
--- /dev/null
+++ b/hw/bsp/olimex-pic32-emz64/src/hal_bsp.c
@@ -0,0 +1,154 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#include <assert.h>
+
+#include "os/mynewt.h"
+
+#include <bsp/bsp.h>
+#include <hal/hal_bsp.h>
+#include <mcu/mips_bsp.h>
+#include <mcu/mips_hal.h>
+#include <mcu/pic32mz_periph.h>
+#include <string.h>
+#include <xc.h>
+
+#if MYNEWT_VAL(SPIFLASH)
+#include <spiflash/spiflash.h>
+#endif
+
+#if MYNEWT_VAL(BOOT_LOADER) || MYNEWT_VAL(MCU_NO_BOOTLOADER_BUILD)
+/* JTAG on, WDT off */
+#pragma config FDMTEN=0, FSOSCEN=0, DMTCNT=1
+#pragma config DEBUG=ON
+#pragma config JTAGEN=OFF
+#pragma config FSLEEP=OFF
+#pragma config TRCEN=OFF
+#pragma config ICESEL=ICS_PGx2
+
+#if MYNEWT_VAL(CLOCK_FREQ) == 8000000
+#pragma config POSCMOD = OFF
+#pragma config FNOSC = FRCDIV
+#pragma config FPLLICLK=0
+#else
+#pragma config POSCMOD = EC
+#if MYNEWT_VAL(CLOCK_FREQ) == 24000000
+#pragma config FNOSC = POSC
+/* 24MHz posc input -> 50mhz*/
+#pragma config FPLLICLK=0
+#elif MYNEWT_VAL(CLOCK_FREQ) == 50000000
+#pragma config FNOSC = SPLL
+/* 24MHz posc input to pll, div by 3 -> 8, multiply by 50 -> 400, div by 8 -> 50mhz*/
+#pragma config FPLLICLK=0, FPLLIDIV=DIV_3, FPLLRNG=RANGE_5_10_MHZ, FPLLMULT=MUL_50, FPLLODIV=DIV_8
+#elif MYNEWT_VAL(CLOCK_FREQ) == 100000000
+#pragma config FNOSC = SPLL
+/* 24MHz posc input to pll, div by 3, multiply by 50, div by 4 -> 100mhz*/
+#pragma config FPLLICLK=0, FPLLIDIV=DIV_3, FPLLRNG=RANGE_5_10_MHZ, FPLLMULT=MUL_50, FPLLODIV=DIV_4
+#elif MYNEWT_VAL(CLOCK_FREQ) == 200000000
+#pragma config FNOSC = SPLL
+/* 24MHz posc input to pll, div by 3, multiply by 50, div by 2 -> 200mhz*/
+#pragma config FPLLICLK=0, FPLLIDIV=DIV_3, FPLLRNG=RANGE_5_10_MHZ, FPLLMULT=MUL_50, FPLLODIV=DIV_2
+#else
+#error Clock requency not supported
+#endif
+#endif
+/* USB off */
+#pragma config FUSBIDIO=0
+/*
+ * Watchdog in non-window mode, watchdog disabled during flash programming,
+ * period: 32s
+ */
+#pragma config WINDIS=1, WDTSPGM=1, WDTPS=15
+
+#endif
+
+#if MYNEWT_VAL(SPIFLASH)
+#if MYNEWT_VAL(BUS_DRIVER_PRESENT)
+struct bus_spi_node_cfg flash_spi_cfg = {
+    .node_cfg.bus_name = MYNEWT_VAL(BSP_FLASH_SPI_BUS),
+    .pin_cs = MYNEWT_VAL(SPIFLASH_SPI_CS_PIN),
+    .mode = BUS_SPI_MODE_3,
+    .data_order = HAL_SPI_MSB_FIRST,
+    .freq = MYNEWT_VAL(SPIFLASH_BAUDRATE),
+};
+#endif
+#endif
+
+static const struct hal_flash *flash_devs[] = {
+    [0] = &pic32mz_flash_dev,
+#if MYNEWT_VAL(SPIFLASH)
+    [1] = &spiflash_dev.hal,
+#endif
+};
+
+const struct hal_flash *
+hal_bsp_flash_dev(uint8_t id)
+{
+    if (id >= ARRAY_SIZE(flash_devs)) {
+        return NULL;
+    }
+
+    return flash_devs[id];
+}
+
+void
+hal_bsp_init(void)
+{
+    pic32mz_periph_create();
+#if MYNEWT_VAL(SPIFLASH) && MYNEWT_VAL(BUS_DRIVER_PRESENT)
+    rc = spiflash_create_spi_dev(&spiflash_dev.dev,
+                                 MYNEWT_VAL(BSP_FLASH_SPI_NAME), &flash_spi_cfg);
+    assert(rc == 0);
+#endif
+}
+
+void
+hal_bsp_deinit(void)
+{
+    IEC0 = 0;
+    IEC1 = 0;
+    IEC2 = 0;
+    IEC3 = 0;
+    IEC4 = 0;
+    IEC5 = 0;
+    IEC6 = 0;
+    IFS0 = 0;
+    IFS1 = 0;
+    IFS2 = 0;
+    IFS3 = 0;
+    IFS4 = 0;
+    IFS5 = 0;
+    IFS6 = 0;
+}
+
+int
+hal_bsp_hw_id_len(void)
+{
+    return sizeof(DEVID);
+}
+
+int
+hal_bsp_hw_id(uint8_t *id, int max_len)
+{
+    if (max_len > sizeof(DEVID)) {
+        max_len = sizeof(DEVID);
+    }
+
+    memcpy(id, (const void *)&DEVID, max_len);
+    return max_len;
+}
diff --git a/hw/bsp/olimex-pic32-emz64/syscfg.yml b/hw/bsp/olimex-pic32-emz64/syscfg.yml
new file mode 100644
index 0000000..eafd62c
--- /dev/null
+++ b/hw/bsp/olimex-pic32-emz64/syscfg.yml
@@ -0,0 +1,49 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+syscfg.defs:
+    HARDFLOAT:
+        description: 'Whether to enable UART0 FPU context switch'
+        value:  1
+
+    CLOCK_FREQ:
+        description: 'System clock frequency, defined in hal_bsp.c'
+        value:  200000000
+        range: 8000000, 24000000, 50000000, 100000000, 200000000
+
+syscfg.vals:
+    TIMER_0: 1
+    I2C_3: 1
+    I2C_3_FREQ_KHZ: 400
+    I2C_4: 1
+    I2C_4_FREQ_KHZ: 400
+    UART_3: 1
+    UART_3_PIN_TX: MCU_GPIO_PORTD(4)
+    UART_3_PIN_RX: MCU_GPIO_PORTD(0)
+    SPI_3_MASTER: 1
+    SPI_3_MASTER_PIN_MOSI: MCU_GPIO_PORTD(5)
+    SPI_3_MASTER_PIN_MISO: MCU_GPIO_PORTD(11)
+    CONSOLE_UART_DEV: '"uart3"'
+
+    SYSTEM_CLOCK_SRC: POSC_PLL
+    SYSTEM_CLOCK_OSC_FREQ: 24000000
+    SYSTEM_CLOCK_PLLIDIV: 3
+    SYSTEM_CLOCK_PLLRANGE: 1
+    SYSTEM_CLOCK_PLLMULT: 50
+    SYSTEM_CLOCK_PLLODIV: 2
diff --git a/hw/bsp/olimex-pic32-hmz144/bsp.yml b/hw/bsp/olimex-pic32-hmz144/bsp.yml
new file mode 100644
index 0000000..8f92ee3
--- /dev/null
+++ b/hw/bsp/olimex-pic32-hmz144/bsp.yml
@@ -0,0 +1,64 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+bsp.name: "PIC32-HMZ144"
+bsp.url: https://www.olimex.com/Products/PIC/Development/PIC32-HMZ144/open-source-hardware
+bsp.maker: "Olimex"
+
+bsp.arch: pic32
+bsp.compiler: "@apache-mynewt-core/compiler/xc32"
+bsp.downloadscript: "hw/bsp/olimex-pic32-hmz144/download.sh"
+bsp.debugscript: "hw/bsp/olimex-pic32-hmz144/debug.sh"
+bsp.linkerscript:
+    - "@apache-mynewt-core/hw/mcu/microchip/pic32mz/p32mz_app.ld"
+
+bsp.linkerscript.BOOT_LOADER.OVERWRITE:
+    - "@apache-mynewt-core/hw/mcu/microchip/pic32mz/p32mz_boot.ld"
+
+bsp.flash_map:
+    areas:
+        # System areas.
+        FLASH_AREA_BOOTLOADER:
+            device: 0
+            offset: 0x1FC00000
+            size: 64kB
+        FLASH_AREA_IMAGE_0:
+            device: 0
+            offset: 0x1D000000
+            size: 192kB
+        FLASH_AREA_IMAGE_1:
+            device: 0
+            offset: 0x1D030000
+            size: 192kB
+        FLASH_AREA_IMAGE_SCRATCH:
+            device: 0
+            offset: 0x1D060000
+            size: 16kB
+
+        # User areas.
+        FLASH_AREA_REBOOT_LOG:
+            user_id: 0
+            device: 1
+            offset: 0x00000000
+            size: 64kB
+        FLASH_AREA_NFFS:
+            user_id: 1
+            device: 1
+            offset: 0x00010000
+            size: 32kB
diff --git a/hw/bsp/olimex-pic32-hmz144/download.sh b/hw/bsp/olimex-pic32-hmz144/download.sh
new file mode 100644
index 0000000..e077259
--- /dev/null
+++ b/hw/bsp/olimex-pic32-hmz144/download.sh
@@ -0,0 +1,49 @@
+#!/bin/sh
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# Called with following variables set:
+#  - CORE_PATH is absolute path to @apache-mynewt-core
+#  - BSP_PATH is absolute path to hw/bsp/bsp_name
+#  - BIN_BASENAME is the path to prefix to target binary,
+#    .elf appended to name is the ELF file
+#  - IMAGE_SLOT is the image slot to download to (for non-mfg-image, non-boot)
+#  - FEATURES holds the target features string
+#  - EXTRA_JTAG_CMD holds extra parameters to pass to jtag software
+#  - MFG_IMAGE is "1" if this is a manufacturing image
+#  - FLASH_OFFSET contains the flash offset to download to
+#  - BOOT_LOADER is set if downloading a bootloader
+
+if [ "${HWTOOL}" = "pickit3" ]; then
+  echo "pickit3 not supported yet"
+else
+
+  echo "r" > script
+  echo "h" >> script
+  if [ "$BOOT_LOADER" -o "$MYNEWT_VAL_MCU_NO_BOOTLOADER_BUILD" == "1" ]; then
+    xc32-objcopy -O ihex ${BIN_BASENAME}.elf ${BIN_BASENAME}.hex
+    echo "loadfile ${BIN_BASENAME}.hex" >> script
+  else
+    cp ${BIN_BASENAME}.img ${BIN_BASENAME}.bin
+    echo "loadfile ${BIN_BASENAME}.bin 0x1d000000" >> script
+  fi
+  echo "r" >> script
+  echo "g" >> script
+  echo "q" >> script
+
+  JLink${COMSPEC:+.}Exe  -AutoConnect 1 -Device PIC32MZ2048EFM144 -If ICSP -speed 12000 -CommandFile script
+fi
diff --git a/hw/bsp/olimex-pic32-hmz144/include/bsp/bsp.h b/hw/bsp/olimex-pic32-hmz144/include/bsp/bsp.h
new file mode 100644
index 0000000..9876981
--- /dev/null
+++ b/hw/bsp/olimex-pic32-hmz144/include/bsp/bsp.h
@@ -0,0 +1,63 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#ifndef H_BSP_H
+#define H_BSP_H
+
+#include <inttypes.h>
+#include <xc.h>
+#include <mcu/mcu.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Define special stackos sections */
+#define sec_data_core   __attribute__((section(".data.core")))
+#define sec_bss_core    __attribute__((section(".bss.core")))
+#define sec_bss_nz_core __attribute__((section(".bss.core.nz")))
+
+/* More convenient section placement macros. */
+#define bssnz_t         sec_bss_nz_core
+
+extern uint8_t _ram_start;
+
+#define RAM_SIZE        (512 * 1024)
+
+/* LED pins */
+#define LED_1           MCU_GPIO_PORTH(2)
+#define LED_BLINK_PIN   LED_1
+
+/* Buttons */
+#define BUTTON_1        MCU_GPIO_PORTB(12)
+
+/* UART */
+#define UART_CNT        (6)
+
+/* SPI */
+#define SPI_CNT         (6)
+
+/* I2C */
+#define I2C_CNT         (5)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* H_BSP_H */
diff --git a/hw/bsp/olimex-pic32-hmz144/p32mz_app_mem.ld b/hw/bsp/olimex-pic32-hmz144/p32mz_app_mem.ld
new file mode 100644
index 0000000..5a21eb6
--- /dev/null
+++ b/hw/bsp/olimex-pic32-hmz144/p32mz_app_mem.ld
@@ -0,0 +1,13 @@
+
+/*
+ * Part of the MEMORY section that defines application memory size.
+ * This file is included by MCU linker script.
+ * this file does not have whole MEMORY section to make it clear
+ * what are differences between MCUs (Flash size and RAM), config
+ * sections are same.
+ */
+
+  /* Program leave space for image header ~192KB */
+  kseg0_program_mem     (rx)  : ORIGIN = 0x9D000020, LENGTH = 0x2FFE0
+  /* Cachable RAM 512KB */
+  kseg0_data_mem       (w!x)  : ORIGIN = 0x80000000, LENGTH = 0x80000
diff --git a/hw/bsp/olimex-pic32-hmz144/pkg.yml b/hw/bsp/olimex-pic32-hmz144/pkg.yml
new file mode 100644
index 0000000..84e21c9
--- /dev/null
+++ b/hw/bsp/olimex-pic32-hmz144/pkg.yml
@@ -0,0 +1,38 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+pkg.name: hw/bsp/olimex-pic32-hmz144
+pkg.type: bsp
+pkg.description: BSP definition for the Olimex PIC32-HMZ144 board.
+pkg.author: "Apache Mynewt <dev@mynewt.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+    - pic32
+    - microchip
+
+pkg.cflags:
+    - -mprocessor=32MZ2048EFM144
+    - -G6
+pkg.lflags:
+    - "-L@apache-mynewt-core/hw/bsp/olimex-pic32-hmz144"
+
+pkg.deps:
+    - "@apache-mynewt-core/hw/mcu/microchip/pic32mz"
+    - "@apache-mynewt-core/libc/baselibc"
+    - "@apache-mynewt-core/hw/drivers/flash/spiflash"
diff --git a/hw/bsp/olimex-pic32-hmz144/src/hal_bsp.c b/hw/bsp/olimex-pic32-hmz144/src/hal_bsp.c
new file mode 100644
index 0000000..1628c71
--- /dev/null
+++ b/hw/bsp/olimex-pic32-hmz144/src/hal_bsp.c
@@ -0,0 +1,154 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#include <assert.h>
+
+#include "os/mynewt.h"
+
+#include <bsp/bsp.h>
+#include <hal/hal_bsp.h>
+#include <mcu/mips_bsp.h>
+#include <mcu/mips_hal.h>
+#include <mcu/pic32mz_periph.h>
+#include <string.h>
+#include <xc.h>
+
+#if MYNEWT_VAL(SPIFLASH)
+#include <spiflash/spiflash.h>
+#endif
+
+#if MYNEWT_VAL(BOOT_LOADER) || MYNEWT_VAL(MCU_NO_BOOTLOADER_BUILD)
+/* JTAG on, WDT off */
+#pragma config FDMTEN=0, FSOSCEN=0, DMTCNT=1
+#pragma config DEBUG=ON
+#pragma config JTAGEN=OFF
+#pragma config FSLEEP=OFF
+#pragma config TRCEN=OFF
+#pragma config ICESEL=ICS_PGx2
+
+#if MYNEWT_VAL(CLOCK_FREQ) == 8000000
+#pragma config POSCMOD = OFF
+#pragma config FNOSC = FRCDIV
+#pragma config FPLLICLK=0
+#else
+#pragma config POSCMOD = HS
+#if MYNEWT_VAL(CLOCK_FREQ) == 24000000
+#pragma config FNOSC = POSC
+/* 24MHz posc input -> 50mhz*/
+#pragma config FPLLICLK=0
+#elif MYNEWT_VAL(CLOCK_FREQ) == 50000000
+#pragma config FNOSC = SPLL
+/* 24MHz posc input to pll, div by 3 -> 8, multiply by 50 -> 400, div by 8 -> 50mhz*/
+#pragma config FPLLICLK=0, FPLLIDIV=DIV_3, FPLLRNG=RANGE_5_10_MHZ, FPLLMULT=MUL_50, FPLLODIV=DIV_8
+#elif MYNEWT_VAL(CLOCK_FREQ) == 100000000
+#pragma config FNOSC = SPLL
+/* 24MHz posc input to pll, div by 3, multiply by 50, div by 4 -> 100mhz*/
+#pragma config FPLLICLK=0, FPLLIDIV=DIV_3, FPLLRNG=RANGE_5_10_MHZ, FPLLMULT=MUL_50, FPLLODIV=DIV_4
+#elif MYNEWT_VAL(CLOCK_FREQ) == 200000000
+#pragma config FNOSC = SPLL
+/* 24MHz posc input to pll, div by 3, multiply by 50, div by 2 -> 200mhz*/
+#pragma config FPLLICLK=0, FPLLIDIV=DIV_3, FPLLRNG=RANGE_5_10_MHZ, FPLLMULT=MUL_50, FPLLODIV=DIV_2
+#else
+#error Clock requency not supported
+#endif
+#endif
+/* USB off */
+#pragma config FUSBIDIO=0
+/*
+ * Watchdog in non-window mode, watchdog disabled during flash programming,
+ * period: 32s
+ */
+#pragma config WINDIS=1, WDTSPGM=1, WDTPS=15
+
+#endif
+
+#if MYNEWT_VAL(SPIFLASH)
+#if MYNEWT_VAL(BUS_DRIVER_PRESENT)
+struct bus_spi_node_cfg flash_spi_cfg = {
+    .node_cfg.bus_name = MYNEWT_VAL(BSP_FLASH_SPI_BUS),
+    .pin_cs = MYNEWT_VAL(SPIFLASH_SPI_CS_PIN),
+    .mode = BUS_SPI_MODE_3,
+    .data_order = HAL_SPI_MSB_FIRST,
+    .freq = MYNEWT_VAL(SPIFLASH_BAUDRATE),
+};
+#endif
+#endif
+
+static const struct hal_flash *flash_devs[] = {
+    [0] = &pic32mz_flash_dev,
+#if MYNEWT_VAL(SPIFLASH)
+    [1] = &spiflash_dev.hal,
+#endif
+};
+
+const struct hal_flash *
+hal_bsp_flash_dev(uint8_t id)
+{
+    if (id >= ARRAY_SIZE(flash_devs)) {
+        return NULL;
+    }
+
+    return flash_devs[id];
+}
+
+void
+hal_bsp_init(void)
+{
+    pic32mz_periph_create();
+#if MYNEWT_VAL(SPIFLASH) && MYNEWT_VAL(BUS_DRIVER_PRESENT)
+    rc = spiflash_create_spi_dev(&spiflash_dev.dev,
+                                 MYNEWT_VAL(BSP_FLASH_SPI_NAME), &flash_spi_cfg);
+    assert(rc == 0);
+#endif
+}
+
+void
+hal_bsp_deinit(void)
+{
+    IEC0 = 0;
+    IEC1 = 0;
+    IEC2 = 0;
+    IEC3 = 0;
+    IEC4 = 0;
+    IEC5 = 0;
+    IEC6 = 0;
+    IFS0 = 0;
+    IFS1 = 0;
+    IFS2 = 0;
+    IFS3 = 0;
+    IFS4 = 0;
+    IFS5 = 0;
+    IFS6 = 0;
+}
+
+int
+hal_bsp_hw_id_len(void)
+{
+    return sizeof(DEVID);
+}
+
+int
+hal_bsp_hw_id(uint8_t *id, int max_len)
+{
+    if (max_len > sizeof(DEVID)) {
+        max_len = sizeof(DEVID);
+    }
+
+    memcpy(id, (const void *)&DEVID, max_len);
+    return max_len;
+}
diff --git a/hw/bsp/olimex-pic32-hmz144/syscfg.yml b/hw/bsp/olimex-pic32-hmz144/syscfg.yml
new file mode 100644
index 0000000..7a307c9
--- /dev/null
+++ b/hw/bsp/olimex-pic32-hmz144/syscfg.yml
@@ -0,0 +1,54 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+syscfg.defs:
+    HARDFLOAT:
+        description: 'Whether to enable UART0 FPU context switch'
+        value:  1
+
+    CLOCK_FREQ:
+        description: 'System clock frequency, defined in hal_bsp.c'
+        value:  200000000
+        range: 8000000, 24000000, 50000000, 100000000, 200000000
+
+syscfg.vals:
+    TIMER_0: 1
+
+    # UART_1 available on UEXT header
+    UART_1: 1
+    UART_1_PIN_TX: MCU_GPIO_PORTE(8)
+    UART_1_PIN_RX: MCU_GPIO_PORTE(9)
+
+    # I2C_1 available on UEXT header
+    I2C_1: 1
+    I2C_1_FREQ_KHZ: 400
+
+    # SPI_0 available on UEXT header
+    SPI_0_MASTER: 1
+    SPI_0_MASTER_PIN_MOSI: MCU_GPIO_PORTD(15)
+    SPI_0_MASTER_PIN_MISO: MCU_GPIO_PORTD(14)
+
+    CONSOLE_UART_DEV: '"uart1"'
+
+    CLOCK_FREQ: 200000000
+    SYSTEM_CLOCK_SRC: POSC_PLL
+    SYSTEM_CLOCK_PLLIDIV: 3
+    SYSTEM_CLOCK_PLLRANGE: 1
+    SYSTEM_CLOCK_PLLMULT: 50
+    SYSTEM_CLOCK_PLLODIV: 2
diff --git a/hw/mcu/microchip/pic32mz/include/mcu/mcu.h b/hw/mcu/microchip/pic32mz/include/mcu/mcu.h
new file mode 100644
index 0000000..edf0988
--- /dev/null
+++ b/hw/mcu/microchip/pic32mz/include/mcu/mcu.h
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef __MCU_MCU_H_
+#define __MCU_MCU_H_
+
+#include <xc.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MCU_GPIO_PORTA(pin)	((0 * 16) + (pin & 0xF))
+#define MCU_GPIO_PORTB(pin)	((1 * 16) + (pin & 0xF))
+#define MCU_GPIO_PORTC(pin)	((2 * 16) + (pin & 0xF))
+#define MCU_GPIO_PORTD(pin)	((3 * 16) + (pin & 0xF))
+#define MCU_GPIO_PORTE(pin)	((4 * 16) + (pin & 0xF))
+#define MCU_GPIO_PORTF(pin)	((5 * 16) + (pin & 0xF))
+#define MCU_GPIO_PORTG(pin)	((6 * 16) + (pin & 0xF))
+#define MCU_GPIO_PORTH(pin)	((7 * 16) + (pin & 0xF))
+#define MCU_GPIO_PORTJ(pin)	((8 * 16) + (pin & 0xF))
+#define MCU_GPIO_PORTK(pin)	((9 * 16) + (pin & 0xF))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MCU_MCU_H_ */
diff --git a/hw/mcu/microchip/pic32mz/include/mcu/mips_bsp.h b/hw/mcu/microchip/pic32mz/include/mcu/mips_bsp.h
new file mode 100644
index 0000000..2995f98
--- /dev/null
+++ b/hw/mcu/microchip/pic32mz/include/mcu/mips_bsp.h
@@ -0,0 +1,24 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#ifndef H_MIPS_BSP_
+#define H_MIPS_BSP_
+
+extern const struct hal_flash pic32mz_flash_dev;
+
+#endif /* H_MIPS_BSP_ */
diff --git a/hw/mcu/microchip/pic32mz/include/mcu/mips_hal.h b/hw/mcu/microchip/pic32mz/include/mcu/mips_hal.h
new file mode 100644
index 0000000..d3ad03c
--- /dev/null
+++ b/hw/mcu/microchip/pic32mz/include/mcu/mips_hal.h
@@ -0,0 +1,63 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/* This file defines the HAL implementations within this MCU */
+
+#ifndef MIPS_HAL_H
+#define MIPS_HAL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PIN_UNUSED 0xFF
+
+/* I/O pins for UART */
+struct mips_uart_cfg {
+    uint8_t tx;
+    uint8_t rx;
+    uint8_t rts;
+    uint8_t cts;
+};
+
+/* I/O pins for SPI, SS pin is not handled by the driver */
+struct mips_spi_cfg {
+    uint8_t mosi;
+    uint8_t miso;
+    uint8_t sck;
+};
+
+/* I/O pins for I2C, also set frequency */
+struct mips_i2c_cfg {
+    uint8_t scl;
+    uint8_t sda;
+    uint32_t frequency;
+};
+
+/* Helper functions to enable/disable interrupts. */
+#define __HAL_DISABLE_INTERRUPTS(__os_sr) do {__os_sr = __builtin_get_isr_state(); \
+        __builtin_disable_interrupts();} while(0)
+
+#define __HAL_ENABLE_INTERRUPTS(__os_sr) __builtin_set_isr_state(__os_sr)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MIPS_HAL_H */
diff --git a/hw/mcu/microchip/pic32mz/include/mcu/pic32.h b/hw/mcu/microchip/pic32mz/include/mcu/pic32.h
new file mode 100644
index 0000000..893d2d8
--- /dev/null
+++ b/hw/mcu/microchip/pic32mz/include/mcu/pic32.h
@@ -0,0 +1,31 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef __MCU_PIC32_H__
+#define __MCU_PIC32_H__
+
+extern uint32_t SystemCoreClock;
+
+static inline void __attribute__((always_inline))
+hal_debug_break(void)
+{
+    __asm__ volatile (" sdbbp 0");
+}
+
+#endif /* __MCU_PIC32_H__ */
diff --git a/hw/mcu/microchip/pic32mz/include/mcu/pic32mz_periph.h b/hw/mcu/microchip/pic32mz/include/mcu/pic32mz_periph.h
new file mode 100644
index 0000000..2666cb5
--- /dev/null
+++ b/hw/mcu/microchip/pic32mz/include/mcu/pic32mz_periph.h
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef __MCU_PIC32MZ_PERIPH_H_
+#define __MCU_PIC32MZ_PERIPH_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void pic32mz_periph_create(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MCU_PIC32MZ_PERIPH_H_ */
diff --git a/hw/mcu/microchip/pic32mz/include/mcu/pps.h b/hw/mcu/microchip/pic32mz/include/mcu/pps.h
new file mode 100644
index 0000000..68d6905
--- /dev/null
+++ b/hw/mcu/microchip/pic32mz/include/mcu/pps.h
@@ -0,0 +1,161 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/* This file defines the Peripheral Pin Select module within this MCU */
+
+#ifndef __MCU_PPS_H__
+#define __MCU_PPS_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NO_CONNECT      (0)
+
+/* Input */
+#define INT3_IN_FUNC            (0)
+#define T2CK_IN_FUNC            (1)
+#define T6CK_IN_FUNC            (2)
+#define IC3_IN_FUNC             (3)
+#define IC7_IN_FUNC             (4)
+#define U1RX_IN_FUNC            (5)
+#define U2CTS_IN_FUNC           (6)
+#define U5RX_IN_FUNC            (7)
+#define U6CTS_IN_FUNC           (8)
+#define SDI1_IN_FUNC            (9)
+#define SDI3_IN_FUNC            (10)
+#define SDI5_IN_FUNC            (11)
+#define SS6_IN_FUNC             (12)
+#define REFCLKI1_IN_FUNC        (13)
+
+#define INT4_IN_FUNC            (16 + 0)
+#define T5CK_IN_FUNC            (16 + 1)
+#define T7CK_IN_FUNC            (16 + 2)
+#define IC4_IN_FUNC             (16 + 3)
+#define IC8_IN_FUNC             (16 + 4)
+#define U3RX_IN_FUNC            (16 + 5)
+#define U4CTS_IN_FUNC           (16 + 6)
+#define SDI2_IN_FUNC            (16 + 7)
+#define SDI4_IN_FUNC            (16 + 8)
+#define REFCLKI4_IN_FUNC        (16 + 10)
+
+#define INT2_IN_FUNC            (32 + 0)
+#define T3CK_IN_FUNC            (32 + 1)
+#define T8CK_IN_FUNC            (32 + 2)
+#define IC2_IN_FUNC             (32 + 3)
+#define IC5_IN_FUNC             (32 + 4)
+#define IC9_IN_FUNC             (32 + 5)
+#define U1CTS_IN_FUNC           (32 + 6)
+#define U2RX_IN_FUNC            (32 + 7)
+#define U5CTS_IN_FUNC           (32 + 8)
+#define SS1_IN_FUNC             (32 + 9)
+#define SS3_IN_FUNC             (32 + 10)
+#define SS4_IN_FUNC             (32 + 11)
+#define SS5_IN_FUNC             (32 + 12)
+
+#define INT1_IN_FUNC            (48 + 0)
+#define T4CK_IN_FUNC            (48 + 1)
+#define T9CK_IN_FUNC            (48 + 2)
+#define IC1_IN_FUNC             (48 + 3)
+#define IC6_IN_FUNC             (48 + 4)
+#define U3CTS_IN_FUNC           (48 + 5)
+#define U4RX_IN_FUNC            (48 + 6)
+#define U6RX_IN_FUNC            (48 + 7)
+#define SS2_IN_FUNC             (48 + 8)
+#define SDI6_IN_FUNC            (48 + 9)
+#define OCFA_IN_FUNC            (48 + 10)
+#define REFCLKI3_IN_FUNC        (48 + 11)
+
+
+/* Output */
+#define U3TX_OUT_FUNC           (0b0001)
+#define U4RTS_OUT_FUNC          (0b0010)
+#define SDO1_OUT_FUNC           (0b0101)
+#define SDO2_OUT_FUNC           (0b0110)
+#define SDO3_OUT_FUNC           (0b0111)
+#define SDO5_OUT_FUNC           (0b1001)
+#define SS6_OUT_FUNC            (0b1010)
+#define OC3_OUT_FUNC            (0b1011)
+#define OC6_OUT_FUNC            (0b1100)
+#define REFCLKO4_OUT_FUNC       (0b1101)
+#define C2OUT_OUT_FUNC          (0b1110)
+
+#define U1TX_OUT_FUNC           (0b0001)
+#define U2RTS_OUT_FUNC          (0b0010)
+#define U5TX_OUT_FUNC           (0b0011)
+#define U6RTS_OUT_FUNC          (0b0100)
+#define SDO1_OUT_FUNC           (0b0101)
+#define SDO2_OUT_FUNC           (0b0110)
+#define SDO3_OUT_FUNC           (0b0111)
+#define SDO4_OUT_FUNC           (0b1000)
+#define SDO5_OUT_FUNC           (0b1001)
+#define OC4_OUT_FUNC            (0b1011)
+#define OC7_OUT_FUNC            (0b1100)
+#define REFCLKO1_OUT_FUNC       (0b1111)
+
+#define U3RTS_OUT_FUNC          (0b0001)
+#define U4TX_OUT_FUNC           (0b0010)
+#define U6TX_OUT_FUNC           (0b0100)
+#define SS1_OUT_FUNC            (0b0101)
+#define SS3_OUT_FUNC            (0b0111)
+#define SS4_OUT_FUNC            (0b1000)
+#define SS5_OUT_FUNC            (0b1001)
+#define SDO6_OUT_FUNC           (0b1010)
+#define OC5_OUT_FUNC            (0b1011)
+#define OC8_OUT_FUNC            (0b1100)
+#define C1OUT_OUT_FUNC          (0b1110)
+#define REFCLKO3_OUT_FUNC       (0b1111)
+
+#define U1RTS_OUT_FUNC          (0b0001)
+#define U2TX_OUT_FUNC           (0b0010)
+#define U5RTS_OUT_FUNC          (0b0011)
+#define U6TX_OUT_FUNC           (0b0100)
+#define SS2_OUT_FUNC            (0b0110)
+#define SDO4_OUT_FUNC           (0b1000)
+#define SDO6_OUT_FUNC           (0b1010)
+#define OC2_OUT_FUNC            (0b1011)
+#define OC1_OUT_FUNC            (0b1100)
+#define OC9_OUT_FUNC            (0b1101)
+
+
+/**
+ * @brief Configure pin as a peripheral output
+ *
+ * @param pin
+ * @param func
+ * @return 0 if successful, -1 otherwise
+ */
+int pps_configure_output(uint8_t pin, uint8_t func);
+
+/**
+ * @brief Configure pin as a peripheral input
+ *
+ * @param pin
+ * @param func
+ * @return 0 if successful, -1 otherwise
+ */
+int pps_configure_input(uint8_t pin, uint8_t func);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MCU_PPS_H__ */
diff --git a/hw/mcu/microchip/pic32mz/p32mz_app.ld b/hw/mcu/microchip/pic32mz/p32mz_app.ld
new file mode 100644
index 0000000..3e951ff
--- /dev/null
+++ b/hw/mcu/microchip/pic32mz/p32mz_app.ld
@@ -0,0 +1,1844 @@
+/*--------------------------------------------------------------------------
+ * MPLAB XC Compiler -  PIC32MZ2048EFH064 linker script
+ * Build date : Jul 28 2020
+ * 
+ * Copyright (c) 2020, Microchip Technology Inc. and its subsidiaries ("Microchip")
+ * All rights reserved.
+ * 
+ * This software is developed by Microchip Technology Inc. and its
+ * subsidiaries ("Microchip").
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are 
+ * met:
+ * 
+ * 1.      Redistributions of source code must retain the above copyright
+ *         notice, this list of conditions and the following disclaimer.
+ * 2.      Redistributions in binary form must reproduce the above 
+ *         copyright notice, this list of conditions and the following 
+ *         disclaimer in the documentation and/or other materials provided 
+ *         with the distribution. Publication is not required when this file 
+ *         is used in an embedded application.
+ * 3.      Microchip's name may not be used to endorse or promote products
+ *         derived from this software without specific prior written 
+ *         permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY MICROCHIP "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL MICROCHIP BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING BUT NOT LIMITED TO
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWSOEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 
+ */
+
+/* Default linker script, for normal executables */
+
+/*  NOTE: This single-file linker script replaces the two-file system used
+ *  for older PIC32 devices. 
+ */
+
+OUTPUT_FORMAT("elf32-tradlittlemips")
+OUTPUT_ARCH(pic32mx)
+ENTRY(_reset)
+/*
+ * Provide for a minimum stack and heap size
+ * - _min_stack_size - represents the minimum space that must be made
+ *                     available for the stack.  Can be overridden from
+ *                     the command line using the linker's --defsym option.
+ * - _min_heap_size  - represents the minimum space that must be made
+ *                     available for the heap.  Must be specified on
+ *                     the command line using the linker's --defsym option.
+ */
+PROVIDE(_min_stack_size = 0x400) ;
+/* Mynewt compute heap size differently then default xc compiler wants */
+_min_heap_size = 0x0;
+
+/*************************************************************************
+ * Legacy processor-specific object file.  Contains SFR definitions.
+ * The SFR definitions are now provided in a processor-specific *.S
+ * assembly source file rather than the processor.o file. Use the new
+ * .S file rather than this processor.o file for new projects. MPLAB XC32
+ * v2.10 and later will automatically link the new .S file.
+ *************************************************************************/
+#if defined(__XC32_VERSION__) && (__XC32_VERSION__ < 2100)
+OPTIONAL("processor.o")
+#endif
+
+/*************************************************************************
+ * Vector-offset initialization
+ *************************************************************************/
+OPTIONAL("vector_offset_init.o")
+
+/*************************************************************************
+ * Symbols used for interrupt-vector table generation
+ * To override the defaults, define the _ebase_address symbol using
+ * the --defsym linker opt as shown in this example:
+ *   xc32-gcc src.c -Wl,--defsym=_ebase_address=0x9D001000
+ *************************************************************************/
+PROVIDE(_vector_spacing = 0x0001);
+PROVIDE(_ebase_address = 0x9D001000);
+
+/*************************************************************************
+ * Memory Address Equates
+ * _RESET_ADDR                    -- Reset Vector or entry point
+ * _BEV_EXCPT_ADDR                -- Boot exception Vector
+ * _DBG_EXCPT_ADDR                -- In-circuit Debugging Exception Vector
+ * _SIMPLE_TLB_REFILL_EXCPT_ADDR  -- Simple TLB-Refill Exception Vector
+ * _CACHE_ERR_EXCPT_ADDR          -- Cache-error Exception Vector
+ * _GEN_EXCPT_ADDR                -- General Exception Vector
+ *************************************************************************/
+_RESET_ADDR                    = 0x9D000020;
+_BEV_EXCPT_ADDR                = 0xBFC00380;
+_DBG_EXCPT_ADDR                = 0xBFC00480;
+_SIMPLE_TLB_REFILL_EXCPT_ADDR  = _ebase_address + 0;
+_CACHE_ERR_EXCPT_ADDR          = _ebase_address + 0x100;
+_GEN_EXCPT_ADDR                = _ebase_address + 0x180;
+
+/*************************************************************************
+ * Memory Regions
+ *
+ * Memory regions without attributes cannot be used for orphaned sections.
+ * Only sections specifically assigned to these regions can be allocated
+ * into these regions.
+ *
+ * The Debug exception vector is located at 0x9FC00480.
+ *
+ * The config_<address> sections are used to locate the config words at
+ * their absolute addresses.
+ *************************************************************************/
+
+
+MEMORY
+{
+  kseg1_boot_mem              : ORIGIN = 0x9FC00000, LENGTH = 0x480
+  kseg1_boot_mem_4B0          : ORIGIN = 0xBFC004B0, LENGTH = 0xA50
+  INCLUDE p32mz_app_mem.ld
+  config_BFC0FF40             : ORIGIN = 0xBFC0FF40, LENGTH = 0x4
+  config_BFC0FF44             : ORIGIN = 0xBFC0FF44, LENGTH = 0x4
+  config_BFC0FF48             : ORIGIN = 0xBFC0FF48, LENGTH = 0x4
+  config_BFC0FF4C             : ORIGIN = 0xBFC0FF4C, LENGTH = 0x4
+  config_BFC0FF50             : ORIGIN = 0xBFC0FF50, LENGTH = 0x4
+  config_BFC0FF54             : ORIGIN = 0xBFC0FF54, LENGTH = 0x4
+  config_BFC0FF58             : ORIGIN = 0xBFC0FF58, LENGTH = 0x4
+  config_BFC0FF5C             : ORIGIN = 0xBFC0FF5C, LENGTH = 0x4
+  config_BFC0FF60             : ORIGIN = 0xBFC0FF60, LENGTH = 0x4
+  config_BFC0FF64             : ORIGIN = 0xBFC0FF64, LENGTH = 0x4
+  config_BFC0FF68             : ORIGIN = 0xBFC0FF68, LENGTH = 0x4
+  config_BFC0FF6C             : ORIGIN = 0xBFC0FF6C, LENGTH = 0x4
+  config_BFC0FF70             : ORIGIN = 0xBFC0FF70, LENGTH = 0x4
+  config_BFC0FF74             : ORIGIN = 0xBFC0FF74, LENGTH = 0x4
+  config_BFC0FF78             : ORIGIN = 0xBFC0FF78, LENGTH = 0x4
+  config_BFC0FF7C             : ORIGIN = 0xBFC0FF7C, LENGTH = 0x4
+  config_BFC0FFC0             : ORIGIN = 0xBFC0FFC0, LENGTH = 0x4
+  config_BFC0FFC4             : ORIGIN = 0xBFC0FFC4, LENGTH = 0x4
+  config_BFC0FFC8             : ORIGIN = 0xBFC0FFC8, LENGTH = 0x4
+  config_BFC0FFCC             : ORIGIN = 0xBFC0FFCC, LENGTH = 0x4
+  config_BFC0FFD0             : ORIGIN = 0xBFC0FFD0, LENGTH = 0x4
+  config_BFC0FFD4             : ORIGIN = 0xBFC0FFD4, LENGTH = 0x4
+  config_BFC0FFD8             : ORIGIN = 0xBFC0FFD8, LENGTH = 0x4
+  config_BFC0FFDC             : ORIGIN = 0xBFC0FFDC, LENGTH = 0x4
+  config_BFC0FFE0             : ORIGIN = 0xBFC0FFE0, LENGTH = 0x4
+  config_BFC0FFE4             : ORIGIN = 0xBFC0FFE4, LENGTH = 0x4
+  config_BFC0FFE8             : ORIGIN = 0xBFC0FFE8, LENGTH = 0x4
+  config_BFC0FFEC             : ORIGIN = 0xBFC0FFEC, LENGTH = 0x4
+  config_BFC0FFF0             : ORIGIN = 0xBFC0FFF0, LENGTH = 0x4
+  config_BFC0FFF4             : ORIGIN = 0xBFC0FFF4, LENGTH = 0x4
+  config_BFC0FFF8             : ORIGIN = 0xBFC0FFF8, LENGTH = 0x4
+  config_BFC0FFFC             : ORIGIN = 0xBFC0FFFC, LENGTH = 0x4
+  lowerbootaliaslastpage      : ORIGIN = 0xBFC10000, LENGTH = 0x4000
+  upperbootalias              : ORIGIN = 0xBFC20000, LENGTH = 0xFF00
+  config_BFC2FF40             : ORIGIN = 0xBFC2FF40, LENGTH = 0x4
+  config_BFC2FF44             : ORIGIN = 0xBFC2FF44, LENGTH = 0x4
+  config_BFC2FF48             : ORIGIN = 0xBFC2FF48, LENGTH = 0x4
+  config_BFC2FF4C             : ORIGIN = 0xBFC2FF4C, LENGTH = 0x4
+  config_BFC2FF50             : ORIGIN = 0xBFC2FF50, LENGTH = 0x4
+  config_BFC2FF54             : ORIGIN = 0xBFC2FF54, LENGTH = 0x4
+  config_BFC2FF58             : ORIGIN = 0xBFC2FF58, LENGTH = 0x4
+  config_BFC2FF5C             : ORIGIN = 0xBFC2FF5C, LENGTH = 0x4
+  config_BFC2FF60             : ORIGIN = 0xBFC2FF60, LENGTH = 0x4
+  config_BFC2FF64             : ORIGIN = 0xBFC2FF64, LENGTH = 0x4
+  config_BFC2FF68             : ORIGIN = 0xBFC2FF68, LENGTH = 0x4
+  config_BFC2FF6C             : ORIGIN = 0xBFC2FF6C, LENGTH = 0x4
+  config_BFC2FF70             : ORIGIN = 0xBFC2FF70, LENGTH = 0x4
+  config_BFC2FF74             : ORIGIN = 0xBFC2FF74, LENGTH = 0x4
+  config_BFC2FF78             : ORIGIN = 0xBFC2FF78, LENGTH = 0x4
+  config_BFC2FF7C             : ORIGIN = 0xBFC2FF7C, LENGTH = 0x4
+  config_BFC2FFC0             : ORIGIN = 0xBFC2FFC0, LENGTH = 0x4
+  config_BFC2FFC4             : ORIGIN = 0xBFC2FFC4, LENGTH = 0x4
+  config_BFC2FFC8             : ORIGIN = 0xBFC2FFC8, LENGTH = 0x4
+  config_BFC2FFCC             : ORIGIN = 0xBFC2FFCC, LENGTH = 0x4
+  config_BFC2FFD0             : ORIGIN = 0xBFC2FFD0, LENGTH = 0x4
+  config_BFC2FFD4             : ORIGIN = 0xBFC2FFD4, LENGTH = 0x4
+  config_BFC2FFD8             : ORIGIN = 0xBFC2FFD8, LENGTH = 0x4
+  config_BFC2FFDC             : ORIGIN = 0xBFC2FFDC, LENGTH = 0x4
+  config_BFC2FFE0             : ORIGIN = 0xBFC2FFE0, LENGTH = 0x4
+  config_BFC2FFE4             : ORIGIN = 0xBFC2FFE4, LENGTH = 0x4
+  config_BFC2FFE8             : ORIGIN = 0xBFC2FFE8, LENGTH = 0x4
+  config_BFC2FFEC             : ORIGIN = 0xBFC2FFEC, LENGTH = 0x4
+  config_BFC2FFF0             : ORIGIN = 0xBFC2FFF0, LENGTH = 0x4
+  config_BFC2FFF4             : ORIGIN = 0xBFC2FFF4, LENGTH = 0x4
+  config_BFC2FFF8             : ORIGIN = 0xBFC2FFF8, LENGTH = 0x4
+  config_BFC2FFFC             : ORIGIN = 0xBFC2FFFC, LENGTH = 0x4
+  upperbootaliaslastpage      : ORIGIN = 0xBFC30000, LENGTH = 0x4000
+  boot1                       : ORIGIN = 0xBFC40000, LENGTH = 0xFF00
+  config_BFC4FF40             : ORIGIN = 0xBFC4FF40, LENGTH = 0x4
+  config_BFC4FF44             : ORIGIN = 0xBFC4FF44, LENGTH = 0x4
+  config_BFC4FF48             : ORIGIN = 0xBFC4FF48, LENGTH = 0x4
+  config_BFC4FF4C             : ORIGIN = 0xBFC4FF4C, LENGTH = 0x4
+  config_BFC4FF50             : ORIGIN = 0xBFC4FF50, LENGTH = 0x4
+  config_BFC4FF54             : ORIGIN = 0xBFC4FF54, LENGTH = 0x4
+  config_BFC4FF58             : ORIGIN = 0xBFC4FF58, LENGTH = 0x4
+  config_BFC4FF5C             : ORIGIN = 0xBFC4FF5C, LENGTH = 0x4
+  config_BFC4FF60             : ORIGIN = 0xBFC4FF60, LENGTH = 0x4
+  config_BFC4FF64             : ORIGIN = 0xBFC4FF64, LENGTH = 0x4
+  config_BFC4FF68             : ORIGIN = 0xBFC4FF68, LENGTH = 0x4
+  config_BFC4FF6C             : ORIGIN = 0xBFC4FF6C, LENGTH = 0x4
+  config_BFC4FF70             : ORIGIN = 0xBFC4FF70, LENGTH = 0x4
+  config_BFC4FF74             : ORIGIN = 0xBFC4FF74, LENGTH = 0x4
+  config_BFC4FF78             : ORIGIN = 0xBFC4FF78, LENGTH = 0x4
+  config_BFC4FF7C             : ORIGIN = 0xBFC4FF7C, LENGTH = 0x4
+  config_BFC4FFC0             : ORIGIN = 0xBFC4FFC0, LENGTH = 0x4
+  config_BFC4FFC4             : ORIGIN = 0xBFC4FFC4, LENGTH = 0x4
+  config_BFC4FFC8             : ORIGIN = 0xBFC4FFC8, LENGTH = 0x4
+  config_BFC4FFCC             : ORIGIN = 0xBFC4FFCC, LENGTH = 0x4
+  config_BFC4FFD0             : ORIGIN = 0xBFC4FFD0, LENGTH = 0x4
+  config_BFC4FFD4             : ORIGIN = 0xBFC4FFD4, LENGTH = 0x4
+  config_BFC4FFD8             : ORIGIN = 0xBFC4FFD8, LENGTH = 0x4
+  config_BFC4FFDC             : ORIGIN = 0xBFC4FFDC, LENGTH = 0x4
+  config_BFC4FFE0             : ORIGIN = 0xBFC4FFE0, LENGTH = 0x4
+  config_BFC4FFE4             : ORIGIN = 0xBFC4FFE4, LENGTH = 0x4
+  config_BFC4FFE8             : ORIGIN = 0xBFC4FFE8, LENGTH = 0x4
+  config_BFC4FFEC             : ORIGIN = 0xBFC4FFEC, LENGTH = 0x4
+  config_BFC4FFF0             : ORIGIN = 0xBFC4FFF0, LENGTH = 0x4
+  config_BFC4FFF4             : ORIGIN = 0xBFC4FFF4, LENGTH = 0x4
+  config_BFC4FFF8             : ORIGIN = 0xBFC4FFF8, LENGTH = 0x4
+  config_BFC4FFFC             : ORIGIN = 0xBFC4FFFC, LENGTH = 0x4
+  boot1lastpage               : ORIGIN = 0xBFC50000, LENGTH = 0x4000
+  config_BFC54000             : ORIGIN = 0xBFC54000, LENGTH = 0x4
+  config_BFC54004             : ORIGIN = 0xBFC54004, LENGTH = 0x4
+  config_BFC54008             : ORIGIN = 0xBFC54008, LENGTH = 0x4
+  config_BFC5400C             : ORIGIN = 0xBFC5400C, LENGTH = 0x4
+  config_BFC54010             : ORIGIN = 0xBFC54010, LENGTH = 0x4
+  config_BFC5401C             : ORIGIN = 0xBFC5401C, LENGTH = 0x4
+  config_BFC54020             : ORIGIN = 0xBFC54020, LENGTH = 0x4
+  config_BFC54024             : ORIGIN = 0xBFC54024, LENGTH = 0x4
+  boot2                       : ORIGIN = 0xBFC60000, LENGTH = 0xFF00
+  config_BFC6FF40             : ORIGIN = 0xBFC6FF40, LENGTH = 0x4
+  config_BFC6FF44             : ORIGIN = 0xBFC6FF44, LENGTH = 0x4
+  config_BFC6FF48             : ORIGIN = 0xBFC6FF48, LENGTH = 0x4
+  config_BFC6FF4C             : ORIGIN = 0xBFC6FF4C, LENGTH = 0x4
+  config_BFC6FF50             : ORIGIN = 0xBFC6FF50, LENGTH = 0x4
+  config_BFC6FF54             : ORIGIN = 0xBFC6FF54, LENGTH = 0x4
+  config_BFC6FF58             : ORIGIN = 0xBFC6FF58, LENGTH = 0x4
+  config_BFC6FF5C             : ORIGIN = 0xBFC6FF5C, LENGTH = 0x4
+  config_BFC6FF60             : ORIGIN = 0xBFC6FF60, LENGTH = 0x4
+  config_BFC6FF64             : ORIGIN = 0xBFC6FF64, LENGTH = 0x4
+  config_BFC6FF68             : ORIGIN = 0xBFC6FF68, LENGTH = 0x4
+  config_BFC6FF6C             : ORIGIN = 0xBFC6FF6C, LENGTH = 0x4
+  config_BFC6FF70             : ORIGIN = 0xBFC6FF70, LENGTH = 0x4
+  config_BFC6FF74             : ORIGIN = 0xBFC6FF74, LENGTH = 0x4
+  config_BFC6FF78             : ORIGIN = 0xBFC6FF78, LENGTH = 0x4
+  config_BFC6FF7C             : ORIGIN = 0xBFC6FF7C, LENGTH = 0x4
+  config_BFC6FFC0             : ORIGIN = 0xBFC6FFC0, LENGTH = 0x4
+  config_BFC6FFC4             : ORIGIN = 0xBFC6FFC4, LENGTH = 0x4
+  config_BFC6FFC8             : ORIGIN = 0xBFC6FFC8, LENGTH = 0x4
+  config_BFC6FFCC             : ORIGIN = 0xBFC6FFCC, LENGTH = 0x4
+  config_BFC6FFD0             : ORIGIN = 0xBFC6FFD0, LENGTH = 0x4
+  config_BFC6FFD4             : ORIGIN = 0xBFC6FFD4, LENGTH = 0x4
+  config_BFC6FFD8             : ORIGIN = 0xBFC6FFD8, LENGTH = 0x4
+  config_BFC6FFDC             : ORIGIN = 0xBFC6FFDC, LENGTH = 0x4
+  config_BFC6FFE0             : ORIGIN = 0xBFC6FFE0, LENGTH = 0x4
+  config_BFC6FFE4             : ORIGIN = 0xBFC6FFE4, LENGTH = 0x4
+  config_BFC6FFE8             : ORIGIN = 0xBFC6FFE8, LENGTH = 0x4
+  config_BFC6FFEC             : ORIGIN = 0xBFC6FFEC, LENGTH = 0x4
+  config_BFC6FFF0             : ORIGIN = 0xBFC6FFF0, LENGTH = 0x4
+  config_BFC6FFF4             : ORIGIN = 0xBFC6FFF4, LENGTH = 0x4
+  config_BFC6FFF8             : ORIGIN = 0xBFC6FFF8, LENGTH = 0x4
+  config_BFC6FFFC             : ORIGIN = 0xBFC6FFFC, LENGTH = 0x4
+  boot2lastpage               : ORIGIN = 0xBFC70000, LENGTH = 0x4000
+  sfrs                        : ORIGIN = 0xBF800000, LENGTH = 0x100000
+  configsfrs_BFC0FF40         : ORIGIN = 0xBFC0FF40, LENGTH = 0x40
+  configsfrs_BFC0FFC0         : ORIGIN = 0xBFC0FFC0, LENGTH = 0x40
+  configsfrs_BFC2FF40         : ORIGIN = 0xBFC2FF40, LENGTH = 0x40
+  configsfrs_BFC2FFC0         : ORIGIN = 0xBFC2FFC0, LENGTH = 0x40
+  configsfrs_BFC4FF40         : ORIGIN = 0xBFC4FF40, LENGTH = 0x40
+  configsfrs_BFC4FFC0         : ORIGIN = 0xBFC4FFC0, LENGTH = 0x40
+  configsfrs_BFC54000         : ORIGIN = 0xBFC54000, LENGTH = 0x20
+  configsfrs_BFC6FF40         : ORIGIN = 0xBFC6FF40, LENGTH = 0x40
+  configsfrs_BFC6FFC0         : ORIGIN = 0xBFC6FFC0, LENGTH = 0x40
+}
+
+/*************************************************************************
+ * Configuration-word sections. Map the config-pragma input sections to
+ * absolute-address output sections.
+ *************************************************************************/
+SECTIONS
+{
+  .config_BFC0FF40 : {
+    KEEP(*(.config_BFC0FF40))
+  } > config_BFC0FF40
+  .config_BFC0FF44 : {
+    KEEP(*(.config_BFC0FF44))
+  } > config_BFC0FF44
+  .config_BFC0FF48 : {
+    KEEP(*(.config_BFC0FF48))
+  } > config_BFC0FF48
+  .config_BFC0FF4C : {
+    KEEP(*(.config_BFC0FF4C))
+  } > config_BFC0FF4C
+  .config_BFC0FF50 : {
+    KEEP(*(.config_BFC0FF50))
+  } > config_BFC0FF50
+  .config_BFC0FF54 : {
+    KEEP(*(.config_BFC0FF54))
+  } > config_BFC0FF54
+  .config_BFC0FF58 : {
+    KEEP(*(.config_BFC0FF58))
+  } > config_BFC0FF58
+  .config_BFC0FF5C : {
+    KEEP(*(.config_BFC0FF5C))
+  } > config_BFC0FF5C
+  .config_BFC0FF60 : {
+    KEEP(*(.config_BFC0FF60))
+  } > config_BFC0FF60
+  .config_BFC0FF64 : {
+    KEEP(*(.config_BFC0FF64))
+  } > config_BFC0FF64
+  .config_BFC0FF68 : {
+    KEEP(*(.config_BFC0FF68))
+  } > config_BFC0FF68
+  .config_BFC0FF6C : {
+    KEEP(*(.config_BFC0FF6C))
+  } > config_BFC0FF6C
+  .config_BFC0FF70 : {
+    KEEP(*(.config_BFC0FF70))
+  } > config_BFC0FF70
+  .config_BFC0FF74 : {
+    KEEP(*(.config_BFC0FF74))
+  } > config_BFC0FF74
+  .config_BFC0FF78 : {
+    KEEP(*(.config_BFC0FF78))
+  } > config_BFC0FF78
+  .config_BFC0FF7C : {
+    KEEP(*(.config_BFC0FF7C))
+  } > config_BFC0FF7C
+  .config_BFC0FFC0 : {
+    KEEP(*(.config_BFC0FFC0))
+  } > config_BFC0FFC0
+  .config_BFC0FFC4 : {
+    KEEP(*(.config_BFC0FFC4))
+  } > config_BFC0FFC4
+  .config_BFC0FFC8 : {
+    KEEP(*(.config_BFC0FFC8))
+  } > config_BFC0FFC8
+  .config_BFC0FFCC : {
+    KEEP(*(.config_BFC0FFCC))
+  } > config_BFC0FFCC
+  .config_BFC0FFD0 : {
+    KEEP(*(.config_BFC0FFD0))
+  } > config_BFC0FFD0
+  .config_BFC0FFD4 : {
+    KEEP(*(.config_BFC0FFD4))
+  } > config_BFC0FFD4
+  .config_BFC0FFD8 : {
+    KEEP(*(.config_BFC0FFD8))
+  } > config_BFC0FFD8
+  .config_BFC0FFDC : {
+    KEEP(*(.config_BFC0FFDC))
+  } > config_BFC0FFDC
+  .config_BFC0FFE0 : {
+    KEEP(*(.config_BFC0FFE0))
+  } > config_BFC0FFE0
+  .config_BFC0FFE4 : {
+    KEEP(*(.config_BFC0FFE4))
+  } > config_BFC0FFE4
+  .config_BFC0FFE8 : {
+    KEEP(*(.config_BFC0FFE8))
+  } > config_BFC0FFE8
+  .config_BFC0FFEC : {
+    KEEP(*(.config_BFC0FFEC))
+  } > config_BFC0FFEC
+  .config_BFC0FFF0 : {
+    KEEP(*(.config_BFC0FFF0))
+  } > config_BFC0FFF0
+  .config_BFC0FFF4 : {
+    KEEP(*(.config_BFC0FFF4))
+  } > config_BFC0FFF4
+  .config_BFC0FFF8 : {
+    KEEP(*(.config_BFC0FFF8))
+  } > config_BFC0FFF8
+  .config_BFC0FFFC : {
+    KEEP(*(.config_BFC0FFFC))
+  } > config_BFC0FFFC
+  .config_BFC2FF40 : {
+    KEEP(*(.config_BFC2FF40))
+  } > config_BFC2FF40
+  .config_BFC2FF44 : {
+    KEEP(*(.config_BFC2FF44))
+  } > config_BFC2FF44
+  .config_BFC2FF48 : {
+    KEEP(*(.config_BFC2FF48))
+  } > config_BFC2FF48
+  .config_BFC2FF4C : {
+    KEEP(*(.config_BFC2FF4C))
+  } > config_BFC2FF4C
+  .config_BFC2FF50 : {
+    KEEP(*(.config_BFC2FF50))
+  } > config_BFC2FF50
+  .config_BFC2FF54 : {
+    KEEP(*(.config_BFC2FF54))
+  } > config_BFC2FF54
+  .config_BFC2FF58 : {
+    KEEP(*(.config_BFC2FF58))
+  } > config_BFC2FF58
+  .config_BFC2FF5C : {
+    KEEP(*(.config_BFC2FF5C))
+  } > config_BFC2FF5C
+  .config_BFC2FF60 : {
+    KEEP(*(.config_BFC2FF60))
+  } > config_BFC2FF60
+  .config_BFC2FF64 : {
+    KEEP(*(.config_BFC2FF64))
+  } > config_BFC2FF64
+  .config_BFC2FF68 : {
+    KEEP(*(.config_BFC2FF68))
+  } > config_BFC2FF68
+  .config_BFC2FF6C : {
+    KEEP(*(.config_BFC2FF6C))
+  } > config_BFC2FF6C
+  .config_BFC2FF70 : {
+    KEEP(*(.config_BFC2FF70))
+  } > config_BFC2FF70
+  .config_BFC2FF74 : {
+    KEEP(*(.config_BFC2FF74))
+  } > config_BFC2FF74
+  .config_BFC2FF78 : {
+    KEEP(*(.config_BFC2FF78))
+  } > config_BFC2FF78
+  .config_BFC2FF7C : {
+    KEEP(*(.config_BFC2FF7C))
+  } > config_BFC2FF7C
+  .config_BFC2FFC0 : {
+    KEEP(*(.config_BFC2FFC0))
+  } > config_BFC2FFC0
+  .config_BFC2FFC4 : {
+    KEEP(*(.config_BFC2FFC4))
+  } > config_BFC2FFC4
+  .config_BFC2FFC8 : {
+    KEEP(*(.config_BFC2FFC8))
+  } > config_BFC2FFC8
+  .config_BFC2FFCC : {
+    KEEP(*(.config_BFC2FFCC))
+  } > config_BFC2FFCC
+  .config_BFC2FFD0 : {
+    KEEP(*(.config_BFC2FFD0))
+  } > config_BFC2FFD0
+  .config_BFC2FFD4 : {
+    KEEP(*(.config_BFC2FFD4))
+  } > config_BFC2FFD4
+  .config_BFC2FFD8 : {
+    KEEP(*(.config_BFC2FFD8))
+  } > config_BFC2FFD8
+  .config_BFC2FFDC : {
+    KEEP(*(.config_BFC2FFDC))
+  } > config_BFC2FFDC
+  .config_BFC2FFE0 : {
+    KEEP(*(.config_BFC2FFE0))
+  } > config_BFC2FFE0
+  .config_BFC2FFE4 : {
+    KEEP(*(.config_BFC2FFE4))
+  } > config_BFC2FFE4
+  .config_BFC2FFE8 : {
+    KEEP(*(.config_BFC2FFE8))
+  } > config_BFC2FFE8
+  .config_BFC2FFEC : {
+    KEEP(*(.config_BFC2FFEC))
+  } > config_BFC2FFEC
+  .config_BFC2FFF0 : {
+    KEEP(*(.config_BFC2FFF0))
+  } > config_BFC2FFF0
+  .config_BFC2FFF4 : {
+    KEEP(*(.config_BFC2FFF4))
+  } > config_BFC2FFF4
+  .config_BFC2FFF8 : {
+    KEEP(*(.config_BFC2FFF8))
+  } > config_BFC2FFF8
+  .config_BFC2FFFC : {
+    KEEP(*(.config_BFC2FFFC))
+  } > config_BFC2FFFC
+  .config_BFC4FF40 : {
+    KEEP(*(.config_BFC4FF40))
+  } > config_BFC4FF40
+  .config_BFC4FF44 : {
+    KEEP(*(.config_BFC4FF44))
+  } > config_BFC4FF44
+  .config_BFC4FF48 : {
+    KEEP(*(.config_BFC4FF48))
+  } > config_BFC4FF48
+  .config_BFC4FF4C : {
+    KEEP(*(.config_BFC4FF4C))
+  } > config_BFC4FF4C
+  .config_BFC4FF50 : {
+    KEEP(*(.config_BFC4FF50))
+  } > config_BFC4FF50
+  .config_BFC4FF54 : {
+    KEEP(*(.config_BFC4FF54))
+  } > config_BFC4FF54
+  .config_BFC4FF58 : {
+    KEEP(*(.config_BFC4FF58))
+  } > config_BFC4FF58
+  .config_BFC4FF5C : {
+    KEEP(*(.config_BFC4FF5C))
+  } > config_BFC4FF5C
+  .config_BFC4FF60 : {
+    KEEP(*(.config_BFC4FF60))
+  } > config_BFC4FF60
+  .config_BFC4FF64 : {
+    KEEP(*(.config_BFC4FF64))
+  } > config_BFC4FF64
+  .config_BFC4FF68 : {
+    KEEP(*(.config_BFC4FF68))
+  } > config_BFC4FF68
+  .config_BFC4FF6C : {
+    KEEP(*(.config_BFC4FF6C))
+  } > config_BFC4FF6C
+  .config_BFC4FF70 : {
+    KEEP(*(.config_BFC4FF70))
+  } > config_BFC4FF70
+  .config_BFC4FF74 : {
+    KEEP(*(.config_BFC4FF74))
+  } > config_BFC4FF74
+  .config_BFC4FF78 : {
+    KEEP(*(.config_BFC4FF78))
+  } > config_BFC4FF78
+  .config_BFC4FF7C : {
+    KEEP(*(.config_BFC4FF7C))
+  } > config_BFC4FF7C
+  .config_BFC4FFC0 : {
+    KEEP(*(.config_BFC4FFC0))
+  } > config_BFC4FFC0
+  .config_BFC4FFC4 : {
+    KEEP(*(.config_BFC4FFC4))
+  } > config_BFC4FFC4
+  .config_BFC4FFC8 : {
+    KEEP(*(.config_BFC4FFC8))
+  } > config_BFC4FFC8
+  .config_BFC4FFCC : {
+    KEEP(*(.config_BFC4FFCC))
+  } > config_BFC4FFCC
+  .config_BFC4FFD0 : {
+    KEEP(*(.config_BFC4FFD0))
+  } > config_BFC4FFD0
+  .config_BFC4FFD4 : {
+    KEEP(*(.config_BFC4FFD4))
+  } > config_BFC4FFD4
+  .config_BFC4FFD8 : {
+    KEEP(*(.config_BFC4FFD8))
+  } > config_BFC4FFD8
+  .config_BFC4FFDC : {
+    KEEP(*(.config_BFC4FFDC))
+  } > config_BFC4FFDC
+  .config_BFC4FFE0 : {
+    KEEP(*(.config_BFC4FFE0))
+  } > config_BFC4FFE0
+  .config_BFC4FFE4 : {
+    KEEP(*(.config_BFC4FFE4))
+  } > config_BFC4FFE4
+  .config_BFC4FFE8 : {
+    KEEP(*(.config_BFC4FFE8))
+  } > config_BFC4FFE8
+  .config_BFC4FFEC : {
+    KEEP(*(.config_BFC4FFEC))
+  } > config_BFC4FFEC
+  .config_BFC4FFF0 : {
+    KEEP(*(.config_BFC4FFF0))
+  } > config_BFC4FFF0
+  .config_BFC4FFF4 : {
+    KEEP(*(.config_BFC4FFF4))
+  } > config_BFC4FFF4
+  .config_BFC4FFF8 : {
+    KEEP(*(.config_BFC4FFF8))
+  } > config_BFC4FFF8
+  .config_BFC4FFFC : {
+    KEEP(*(.config_BFC4FFFC))
+  } > config_BFC4FFFC
+  .config_BFC54000 : {
+    KEEP(*(.config_BFC54000))
+  } > config_BFC54000
+  .config_BFC54004 : {
+    KEEP(*(.config_BFC54004))
+  } > config_BFC54004
+  .config_BFC54008 : {
+    KEEP(*(.config_BFC54008))
+  } > config_BFC54008
+  .config_BFC5400C : {
+    KEEP(*(.config_BFC5400C))
+  } > config_BFC5400C
+  .config_BFC54010 : {
+    KEEP(*(.config_BFC54010))
+  } > config_BFC54010
+  .config_BFC5401C : {
+    KEEP(*(.config_BFC5401C))
+  } > config_BFC5401C
+  .config_BFC54020 : {
+    KEEP(*(.config_BFC54020))
+  } > config_BFC54020
+  .config_BFC54024 : {
+    KEEP(*(.config_BFC54024))
+  } > config_BFC54024
+  .config_BFC6FF40 : {
+    KEEP(*(.config_BFC6FF40))
+  } > config_BFC6FF40
+  .config_BFC6FF44 : {
+    KEEP(*(.config_BFC6FF44))
+  } > config_BFC6FF44
+  .config_BFC6FF48 : {
+    KEEP(*(.config_BFC6FF48))
+  } > config_BFC6FF48
+  .config_BFC6FF4C : {
+    KEEP(*(.config_BFC6FF4C))
+  } > config_BFC6FF4C
+  .config_BFC6FF50 : {
+    KEEP(*(.config_BFC6FF50))
+  } > config_BFC6FF50
+  .config_BFC6FF54 : {
+    KEEP(*(.config_BFC6FF54))
+  } > config_BFC6FF54
+  .config_BFC6FF58 : {
+    KEEP(*(.config_BFC6FF58))
+  } > config_BFC6FF58
+  .config_BFC6FF5C : {
+    KEEP(*(.config_BFC6FF5C))
+  } > config_BFC6FF5C
+  .config_BFC6FF60 : {
+    KEEP(*(.config_BFC6FF60))
+  } > config_BFC6FF60
+  .config_BFC6FF64 : {
+    KEEP(*(.config_BFC6FF64))
+  } > config_BFC6FF64
+  .config_BFC6FF68 : {
+    KEEP(*(.config_BFC6FF68))
+  } > config_BFC6FF68
+  .config_BFC6FF6C : {
+    KEEP(*(.config_BFC6FF6C))
+  } > config_BFC6FF6C
+  .config_BFC6FF70 : {
+    KEEP(*(.config_BFC6FF70))
+  } > config_BFC6FF70
+  .config_BFC6FF74 : {
+    KEEP(*(.config_BFC6FF74))
+  } > config_BFC6FF74
+  .config_BFC6FF78 : {
+    KEEP(*(.config_BFC6FF78))
+  } > config_BFC6FF78
+  .config_BFC6FF7C : {
+    KEEP(*(.config_BFC6FF7C))
+  } > config_BFC6FF7C
+  .config_BFC6FFC0 : {
+    KEEP(*(.config_BFC6FFC0))
+  } > config_BFC6FFC0
+  .config_BFC6FFC4 : {
+    KEEP(*(.config_BFC6FFC4))
+  } > config_BFC6FFC4
+  .config_BFC6FFC8 : {
+    KEEP(*(.config_BFC6FFC8))
+  } > config_BFC6FFC8
+  .config_BFC6FFCC : {
+    KEEP(*(.config_BFC6FFCC))
+  } > config_BFC6FFCC
+  .config_BFC6FFD0 : {
+    KEEP(*(.config_BFC6FFD0))
+  } > config_BFC6FFD0
+  .config_BFC6FFD4 : {
+    KEEP(*(.config_BFC6FFD4))
+  } > config_BFC6FFD4
+  .config_BFC6FFD8 : {
+    KEEP(*(.config_BFC6FFD8))
+  } > config_BFC6FFD8
+  .config_BFC6FFDC : {
+    KEEP(*(.config_BFC6FFDC))
+  } > config_BFC6FFDC
+  .config_BFC6FFE0 : {
+    KEEP(*(.config_BFC6FFE0))
+  } > config_BFC6FFE0
+  .config_BFC6FFE4 : {
+    KEEP(*(.config_BFC6FFE4))
+  } > config_BFC6FFE4
+  .config_BFC6FFE8 : {
+    KEEP(*(.config_BFC6FFE8))
+  } > config_BFC6FFE8
+  .config_BFC6FFEC : {
+    KEEP(*(.config_BFC6FFEC))
+  } > config_BFC6FFEC
+  .config_BFC6FFF0 : {
+    KEEP(*(.config_BFC6FFF0))
+  } > config_BFC6FFF0
+  .config_BFC6FFF4 : {
+    KEEP(*(.config_BFC6FFF4))
+  } > config_BFC6FFF4
+  .config_BFC6FFF8 : {
+    KEEP(*(.config_BFC6FFF8))
+  } > config_BFC6FFF8
+  .config_BFC6FFFC : {
+    KEEP(*(.config_BFC6FFFC))
+  } > config_BFC6FFFC
+}
+SECTIONS
+{
+  .boot_reset :
+  {
+    KEEP(*(.boot_reset))
+  } > kseg1_boot_mem
+  /* Boot Sections */
+  .reset :
+  {
+    _app_reset = .;
+    KEEP(*(.reset))
+    KEEP(*(.reset.startup))
+  } > kseg0_program_mem
+  .bev_excpt /*_BEV_EXCPT_ADDR*/ :
+  {
+    KEEP(*(.bev_handler))
+    . = ALIGN(4096);
+  } > kseg0_program_mem
+  .simple_tlb_refill_excpt _SIMPLE_TLB_REFILL_EXCPT_ADDR :
+  {
+    KEEP(*(.simple_tlb_refill_vector))
+  } > kseg0_program_mem
+  .cache_err_excpt _CACHE_ERR_EXCPT_ADDR :
+  {
+    KEEP(*(.cache_err_vector))
+  } > kseg0_program_mem
+  .app_excpt _GEN_EXCPT_ADDR :
+  {
+    KEEP(*(.gen_handler))
+  } > kseg0_program_mem
+
+  /* Interrupt vector table with vector offsets */
+  .vectors _ebase_address + 0x200 :
+  {
+    /*  Symbol __vector_offset_n points to .vector_n if it exists,
+     *  otherwise points to the default handler. The
+     *  vector_offset_init.o module then provides a .data section
+     *  containing values used to initialize the vector-offset SFRs
+     *  in the crt0 startup code.
+     */
+    . = ALIGN(4) ;
+    __vector_offset_0 = (DEFINED(__vector_dispatch_0) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_0))
+    . = ALIGN(4) ;
+    __vector_offset_1 = (DEFINED(__vector_dispatch_1) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_1))
+    . = ALIGN(4) ;
+    __vector_offset_2 = (DEFINED(__vector_dispatch_2) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_2))
+    . = ALIGN(4) ;
+    __vector_offset_3 = (DEFINED(__vector_dispatch_3) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_3))
+    . = ALIGN(4) ;
+    __vector_offset_4 = (DEFINED(__vector_dispatch_4) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_4))
+    . = ALIGN(4) ;
+    __vector_offset_5 = (DEFINED(__vector_dispatch_5) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_5))
+    . = ALIGN(4) ;
+    __vector_offset_6 = (DEFINED(__vector_dispatch_6) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_6))
+    . = ALIGN(4) ;
+    __vector_offset_7 = (DEFINED(__vector_dispatch_7) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_7))
+    . = ALIGN(4) ;
+    __vector_offset_8 = (DEFINED(__vector_dispatch_8) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_8))
+    . = ALIGN(4) ;
+    __vector_offset_9 = (DEFINED(__vector_dispatch_9) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_9))
+    . = ALIGN(4) ;
+    __vector_offset_10 = (DEFINED(__vector_dispatch_10) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_10))
+    . = ALIGN(4) ;
+    __vector_offset_11 = (DEFINED(__vector_dispatch_11) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_11))
+    . = ALIGN(4) ;
+    __vector_offset_12 = (DEFINED(__vector_dispatch_12) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_12))
+    . = ALIGN(4) ;
+    __vector_offset_13 = (DEFINED(__vector_dispatch_13) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_13))
+    . = ALIGN(4) ;
+    __vector_offset_14 = (DEFINED(__vector_dispatch_14) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_14))
+    . = ALIGN(4) ;
+    __vector_offset_15 = (DEFINED(__vector_dispatch_15) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_15))
+    . = ALIGN(4) ;
+    __vector_offset_16 = (DEFINED(__vector_dispatch_16) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_16))
+    . = ALIGN(4) ;
+    __vector_offset_17 = (DEFINED(__vector_dispatch_17) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_17))
+    . = ALIGN(4) ;
+    __vector_offset_18 = (DEFINED(__vector_dispatch_18) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_18))
+    . = ALIGN(4) ;
+    __vector_offset_19 = (DEFINED(__vector_dispatch_19) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_19))
+    . = ALIGN(4) ;
+    __vector_offset_20 = (DEFINED(__vector_dispatch_20) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_20))
+    . = ALIGN(4) ;
+    __vector_offset_21 = (DEFINED(__vector_dispatch_21) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_21))
+    . = ALIGN(4) ;
+    __vector_offset_22 = (DEFINED(__vector_dispatch_22) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_22))
+    . = ALIGN(4) ;
+    __vector_offset_23 = (DEFINED(__vector_dispatch_23) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_23))
+    . = ALIGN(4) ;
+    __vector_offset_24 = (DEFINED(__vector_dispatch_24) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_24))
+    . = ALIGN(4) ;
+    __vector_offset_25 = (DEFINED(__vector_dispatch_25) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_25))
+    . = ALIGN(4) ;
+    __vector_offset_26 = (DEFINED(__vector_dispatch_26) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_26))
+    . = ALIGN(4) ;
+    __vector_offset_27 = (DEFINED(__vector_dispatch_27) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_27))
+    . = ALIGN(4) ;
+    __vector_offset_28 = (DEFINED(__vector_dispatch_28) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_28))
+    . = ALIGN(4) ;
+    __vector_offset_29 = (DEFINED(__vector_dispatch_29) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_29))
+    . = ALIGN(4) ;
+    __vector_offset_30 = (DEFINED(__vector_dispatch_30) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_30))
+    . = ALIGN(4) ;
+    __vector_offset_31 = (DEFINED(__vector_dispatch_31) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_31))
+    . = ALIGN(4) ;
+    __vector_offset_32 = (DEFINED(__vector_dispatch_32) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_32))
+    . = ALIGN(4) ;
+    __vector_offset_33 = (DEFINED(__vector_dispatch_33) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_33))
+    . = ALIGN(4) ;
+    __vector_offset_34 = (DEFINED(__vector_dispatch_34) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_34))
+    . = ALIGN(4) ;
+    __vector_offset_35 = (DEFINED(__vector_dispatch_35) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_35))
+    . = ALIGN(4) ;
+    __vector_offset_36 = (DEFINED(__vector_dispatch_36) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_36))
+    . = ALIGN(4) ;
+    __vector_offset_37 = (DEFINED(__vector_dispatch_37) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_37))
+    . = ALIGN(4) ;
+    __vector_offset_38 = (DEFINED(__vector_dispatch_38) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_38))
+    . = ALIGN(4) ;
+    __vector_offset_39 = (DEFINED(__vector_dispatch_39) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_39))
+    . = ALIGN(4) ;
+    __vector_offset_40 = (DEFINED(__vector_dispatch_40) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_40))
+    . = ALIGN(4) ;
+    __vector_offset_41 = (DEFINED(__vector_dispatch_41) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_41))
+    . = ALIGN(4) ;
+    __vector_offset_42 = (DEFINED(__vector_dispatch_42) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_42))
+    . = ALIGN(4) ;
+    __vector_offset_43 = (DEFINED(__vector_dispatch_43) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_43))
+    . = ALIGN(4) ;
+    __vector_offset_44 = (DEFINED(__vector_dispatch_44) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_44))
+    . = ALIGN(4) ;
+    __vector_offset_45 = (DEFINED(__vector_dispatch_45) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_45))
+    . = ALIGN(4) ;
+    __vector_offset_46 = (DEFINED(__vector_dispatch_46) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_46))
+    . = ALIGN(4) ;
+    __vector_offset_47 = (DEFINED(__vector_dispatch_47) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_47))
+    . = ALIGN(4) ;
+    __vector_offset_48 = (DEFINED(__vector_dispatch_48) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_48))
+    . = ALIGN(4) ;
+    __vector_offset_49 = (DEFINED(__vector_dispatch_49) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_49))
+    . = ALIGN(4) ;
+    __vector_offset_50 = (DEFINED(__vector_dispatch_50) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_50))
+    . = ALIGN(4) ;
+    __vector_offset_51 = (DEFINED(__vector_dispatch_51) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_51))
+    . = ALIGN(4) ;
+    __vector_offset_52 = (DEFINED(__vector_dispatch_52) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_52))
+    . = ALIGN(4) ;
+    __vector_offset_53 = (DEFINED(__vector_dispatch_53) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_53))
+    . = ALIGN(4) ;
+    __vector_offset_54 = (DEFINED(__vector_dispatch_54) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_54))
+    . = ALIGN(4) ;
+    __vector_offset_55 = (DEFINED(__vector_dispatch_55) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_55))
+    . = ALIGN(4) ;
+    __vector_offset_56 = (DEFINED(__vector_dispatch_56) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_56))
+    . = ALIGN(4) ;
+    __vector_offset_57 = (DEFINED(__vector_dispatch_57) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_57))
+    . = ALIGN(4) ;
+    __vector_offset_58 = (DEFINED(__vector_dispatch_58) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_58))
+    . = ALIGN(4) ;
+    __vector_offset_59 = (DEFINED(__vector_dispatch_59) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_59))
+    . = ALIGN(4) ;
+    __vector_offset_60 = (DEFINED(__vector_dispatch_60) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_60))
+    . = ALIGN(4) ;
+    __vector_offset_61 = (DEFINED(__vector_dispatch_61) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_61))
+    . = ALIGN(4) ;
+    __vector_offset_62 = (DEFINED(__vector_dispatch_62) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_62))
+    . = ALIGN(4) ;
+    __vector_offset_63 = (DEFINED(__vector_dispatch_63) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_63))
+    . = ALIGN(4) ;
+    __vector_offset_64 = (DEFINED(__vector_dispatch_64) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_64))
+    . = ALIGN(4) ;
+    __vector_offset_65 = (DEFINED(__vector_dispatch_65) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_65))
+    . = ALIGN(4) ;
+    __vector_offset_66 = (DEFINED(__vector_dispatch_66) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_66))
+    . = ALIGN(4) ;
+    __vector_offset_67 = (DEFINED(__vector_dispatch_67) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_67))
+    . = ALIGN(4) ;
+    __vector_offset_68 = (DEFINED(__vector_dispatch_68) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_68))
+    . = ALIGN(4) ;
+    __vector_offset_69 = (DEFINED(__vector_dispatch_69) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_69))
+    . = ALIGN(4) ;
+    __vector_offset_70 = (DEFINED(__vector_dispatch_70) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_70))
+    . = ALIGN(4) ;
+    __vector_offset_71 = (DEFINED(__vector_dispatch_71) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_71))
+    . = ALIGN(4) ;
+    __vector_offset_72 = (DEFINED(__vector_dispatch_72) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_72))
+    . = ALIGN(4) ;
+    __vector_offset_73 = (DEFINED(__vector_dispatch_73) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_73))
+    . = ALIGN(4) ;
+    __vector_offset_74 = (DEFINED(__vector_dispatch_74) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_74))
+    . = ALIGN(4) ;
+    __vector_offset_75 = (DEFINED(__vector_dispatch_75) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_75))
+    . = ALIGN(4) ;
+    __vector_offset_76 = (DEFINED(__vector_dispatch_76) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_76))
+    . = ALIGN(4) ;
+    __vector_offset_77 = (DEFINED(__vector_dispatch_77) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_77))
+    . = ALIGN(4) ;
+    __vector_offset_78 = (DEFINED(__vector_dispatch_78) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_78))
+    . = ALIGN(4) ;
+    __vector_offset_79 = (DEFINED(__vector_dispatch_79) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_79))
+    . = ALIGN(4) ;
+    __vector_offset_80 = (DEFINED(__vector_dispatch_80) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_80))
+    . = ALIGN(4) ;
+    __vector_offset_81 = (DEFINED(__vector_dispatch_81) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_81))
+    . = ALIGN(4) ;
+    __vector_offset_82 = (DEFINED(__vector_dispatch_82) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_82))
+    . = ALIGN(4) ;
+    __vector_offset_83 = (DEFINED(__vector_dispatch_83) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_83))
+    . = ALIGN(4) ;
+    __vector_offset_84 = (DEFINED(__vector_dispatch_84) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_84))
+    . = ALIGN(4) ;
+    __vector_offset_85 = (DEFINED(__vector_dispatch_85) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_85))
+    . = ALIGN(4) ;
+    __vector_offset_86 = (DEFINED(__vector_dispatch_86) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_86))
+    . = ALIGN(4) ;
+    __vector_offset_87 = (DEFINED(__vector_dispatch_87) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_87))
+    . = ALIGN(4) ;
+    __vector_offset_88 = (DEFINED(__vector_dispatch_88) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_88))
+    . = ALIGN(4) ;
+    __vector_offset_89 = (DEFINED(__vector_dispatch_89) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_89))
+    . = ALIGN(4) ;
+    __vector_offset_90 = (DEFINED(__vector_dispatch_90) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_90))
+    . = ALIGN(4) ;
+    __vector_offset_91 = (DEFINED(__vector_dispatch_91) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_91))
+    . = ALIGN(4) ;
+    __vector_offset_92 = (DEFINED(__vector_dispatch_92) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_92))
+    . = ALIGN(4) ;
+    __vector_offset_93 = (DEFINED(__vector_dispatch_93) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_93))
+    . = ALIGN(4) ;
+    __vector_offset_94 = (DEFINED(__vector_dispatch_94) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_94))
+    . = ALIGN(4) ;
+    __vector_offset_95 = (DEFINED(__vector_dispatch_95) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_95))
+    . = ALIGN(4) ;
+    __vector_offset_96 = (DEFINED(__vector_dispatch_96) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_96))
+    . = ALIGN(4) ;
+    __vector_offset_97 = (DEFINED(__vector_dispatch_97) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_97))
+    . = ALIGN(4) ;
+    __vector_offset_98 = (DEFINED(__vector_dispatch_98) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_98))
+    . = ALIGN(4) ;
+    __vector_offset_99 = (DEFINED(__vector_dispatch_99) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_99))
+    . = ALIGN(4) ;
+    __vector_offset_100 = (DEFINED(__vector_dispatch_100) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_100))
+    . = ALIGN(4) ;
+    __vector_offset_101 = (DEFINED(__vector_dispatch_101) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_101))
+    . = ALIGN(4) ;
+    __vector_offset_102 = (DEFINED(__vector_dispatch_102) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_102))
+    . = ALIGN(4) ;
+    __vector_offset_103 = (DEFINED(__vector_dispatch_103) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_103))
+    . = ALIGN(4) ;
+    __vector_offset_104 = (DEFINED(__vector_dispatch_104) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_104))
+    . = ALIGN(4) ;
+    __vector_offset_105 = (DEFINED(__vector_dispatch_105) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_105))
+    . = ALIGN(4) ;
+    __vector_offset_106 = (DEFINED(__vector_dispatch_106) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_106))
+    . = ALIGN(4) ;
+    __vector_offset_107 = (DEFINED(__vector_dispatch_107) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_107))
+    . = ALIGN(4) ;
+    __vector_offset_108 = (DEFINED(__vector_dispatch_108) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_108))
+    . = ALIGN(4) ;
+    __vector_offset_109 = (DEFINED(__vector_dispatch_109) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_109))
+    . = ALIGN(4) ;
+    __vector_offset_110 = (DEFINED(__vector_dispatch_110) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_110))
+    . = ALIGN(4) ;
+    __vector_offset_111 = (DEFINED(__vector_dispatch_111) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_111))
+    . = ALIGN(4) ;
+    __vector_offset_112 = (DEFINED(__vector_dispatch_112) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_112))
+    . = ALIGN(4) ;
+    __vector_offset_113 = (DEFINED(__vector_dispatch_113) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_113))
+    . = ALIGN(4) ;
+    __vector_offset_114 = (DEFINED(__vector_dispatch_114) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_114))
+    . = ALIGN(4) ;
+    __vector_offset_115 = (DEFINED(__vector_dispatch_115) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_115))
+    . = ALIGN(4) ;
+    __vector_offset_116 = (DEFINED(__vector_dispatch_116) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_116))
+    . = ALIGN(4) ;
+    __vector_offset_117 = (DEFINED(__vector_dispatch_117) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_117))
+    . = ALIGN(4) ;
+    __vector_offset_118 = (DEFINED(__vector_dispatch_118) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_118))
+    . = ALIGN(4) ;
+    __vector_offset_119 = (DEFINED(__vector_dispatch_119) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_119))
+    . = ALIGN(4) ;
+    __vector_offset_120 = (DEFINED(__vector_dispatch_120) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_120))
+    . = ALIGN(4) ;
+    __vector_offset_121 = (DEFINED(__vector_dispatch_121) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_121))
+    . = ALIGN(4) ;
+    __vector_offset_122 = (DEFINED(__vector_dispatch_122) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_122))
+    . = ALIGN(4) ;
+    __vector_offset_123 = (DEFINED(__vector_dispatch_123) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_123))
+    . = ALIGN(4) ;
+    __vector_offset_124 = (DEFINED(__vector_dispatch_124) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_124))
+    . = ALIGN(4) ;
+    __vector_offset_125 = (DEFINED(__vector_dispatch_125) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_125))
+    . = ALIGN(4) ;
+    __vector_offset_126 = (DEFINED(__vector_dispatch_126) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_126))
+    . = ALIGN(4) ;
+    __vector_offset_127 = (DEFINED(__vector_dispatch_127) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_127))
+    . = ALIGN(4) ;
+    __vector_offset_128 = (DEFINED(__vector_dispatch_128) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_128))
+    . = ALIGN(4) ;
+    __vector_offset_129 = (DEFINED(__vector_dispatch_129) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_129))
+    . = ALIGN(4) ;
+    __vector_offset_130 = (DEFINED(__vector_dispatch_130) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_130))
+    . = ALIGN(4) ;
+    __vector_offset_131 = (DEFINED(__vector_dispatch_131) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_131))
+    . = ALIGN(4) ;
+    __vector_offset_132 = (DEFINED(__vector_dispatch_132) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_132))
+    . = ALIGN(4) ;
+    __vector_offset_133 = (DEFINED(__vector_dispatch_133) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_133))
+    . = ALIGN(4) ;
+    __vector_offset_134 = (DEFINED(__vector_dispatch_134) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_134))
+    . = ALIGN(4) ;
+    __vector_offset_135 = (DEFINED(__vector_dispatch_135) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_135))
+    . = ALIGN(4) ;
+    __vector_offset_136 = (DEFINED(__vector_dispatch_136) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_136))
+    . = ALIGN(4) ;
+    __vector_offset_137 = (DEFINED(__vector_dispatch_137) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_137))
+    . = ALIGN(4) ;
+    __vector_offset_138 = (DEFINED(__vector_dispatch_138) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_138))
+    . = ALIGN(4) ;
+    __vector_offset_139 = (DEFINED(__vector_dispatch_139) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_139))
+    . = ALIGN(4) ;
+    __vector_offset_140 = (DEFINED(__vector_dispatch_140) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_140))
+    . = ALIGN(4) ;
+    __vector_offset_141 = (DEFINED(__vector_dispatch_141) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_141))
+    . = ALIGN(4) ;
+    __vector_offset_142 = (DEFINED(__vector_dispatch_142) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_142))
+    . = ALIGN(4) ;
+    __vector_offset_143 = (DEFINED(__vector_dispatch_143) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_143))
+    . = ALIGN(4) ;
+    __vector_offset_144 = (DEFINED(__vector_dispatch_144) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_144))
+    . = ALIGN(4) ;
+    __vector_offset_145 = (DEFINED(__vector_dispatch_145) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_145))
+    . = ALIGN(4) ;
+    __vector_offset_146 = (DEFINED(__vector_dispatch_146) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_146))
+    . = ALIGN(4) ;
+    __vector_offset_147 = (DEFINED(__vector_dispatch_147) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_147))
+    . = ALIGN(4) ;
+    __vector_offset_148 = (DEFINED(__vector_dispatch_148) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_148))
+    . = ALIGN(4) ;
+    __vector_offset_149 = (DEFINED(__vector_dispatch_149) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_149))
+    . = ALIGN(4) ;
+    __vector_offset_150 = (DEFINED(__vector_dispatch_150) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_150))
+    . = ALIGN(4) ;
+    __vector_offset_151 = (DEFINED(__vector_dispatch_151) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_151))
+    . = ALIGN(4) ;
+    __vector_offset_152 = (DEFINED(__vector_dispatch_152) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_152))
+    . = ALIGN(4) ;
+    __vector_offset_153 = (DEFINED(__vector_dispatch_153) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_153))
+    . = ALIGN(4) ;
+    __vector_offset_154 = (DEFINED(__vector_dispatch_154) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_154))
+    . = ALIGN(4) ;
+    __vector_offset_155 = (DEFINED(__vector_dispatch_155) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_155))
+    . = ALIGN(4) ;
+    __vector_offset_156 = (DEFINED(__vector_dispatch_156) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_156))
+    . = ALIGN(4) ;
+    __vector_offset_157 = (DEFINED(__vector_dispatch_157) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_157))
+    . = ALIGN(4) ;
+    __vector_offset_158 = (DEFINED(__vector_dispatch_158) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_158))
+    . = ALIGN(4) ;
+    __vector_offset_159 = (DEFINED(__vector_dispatch_159) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_159))
+    . = ALIGN(4) ;
+    __vector_offset_160 = (DEFINED(__vector_dispatch_160) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_160))
+    . = ALIGN(4) ;
+    __vector_offset_161 = (DEFINED(__vector_dispatch_161) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_161))
+    . = ALIGN(4) ;
+    __vector_offset_162 = (DEFINED(__vector_dispatch_162) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_162))
+    . = ALIGN(4) ;
+    __vector_offset_163 = (DEFINED(__vector_dispatch_163) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_163))
+    . = ALIGN(4) ;
+    __vector_offset_164 = (DEFINED(__vector_dispatch_164) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_164))
+    . = ALIGN(4) ;
+    __vector_offset_165 = (DEFINED(__vector_dispatch_165) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_165))
+    . = ALIGN(4) ;
+    __vector_offset_166 = (DEFINED(__vector_dispatch_166) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_166))
+    . = ALIGN(4) ;
+    __vector_offset_167 = (DEFINED(__vector_dispatch_167) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_167))
+    . = ALIGN(4) ;
+    __vector_offset_168 = (DEFINED(__vector_dispatch_168) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_168))
+    . = ALIGN(4) ;
+    __vector_offset_169 = (DEFINED(__vector_dispatch_169) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_169))
+    . = ALIGN(4) ;
+    __vector_offset_170 = (DEFINED(__vector_dispatch_170) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_170))
+    . = ALIGN(4) ;
+    __vector_offset_171 = (DEFINED(__vector_dispatch_171) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_171))
+    . = ALIGN(4) ;
+    __vector_offset_172 = (DEFINED(__vector_dispatch_172) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_172))
+    . = ALIGN(4) ;
+    __vector_offset_173 = (DEFINED(__vector_dispatch_173) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_173))
+    . = ALIGN(4) ;
+    __vector_offset_174 = (DEFINED(__vector_dispatch_174) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_174))
+    . = ALIGN(4) ;
+    __vector_offset_175 = (DEFINED(__vector_dispatch_175) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_175))
+    . = ALIGN(4) ;
+    __vector_offset_176 = (DEFINED(__vector_dispatch_176) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_176))
+    . = ALIGN(4) ;
+    __vector_offset_177 = (DEFINED(__vector_dispatch_177) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_177))
+    . = ALIGN(4) ;
+    __vector_offset_178 = (DEFINED(__vector_dispatch_178) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_178))
+    . = ALIGN(4) ;
+    __vector_offset_179 = (DEFINED(__vector_dispatch_179) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_179))
+    . = ALIGN(4) ;
+    __vector_offset_180 = (DEFINED(__vector_dispatch_180) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_180))
+    . = ALIGN(4) ;
+    __vector_offset_181 = (DEFINED(__vector_dispatch_181) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_181))
+    . = ALIGN(4) ;
+    __vector_offset_182 = (DEFINED(__vector_dispatch_182) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_182))
+    . = ALIGN(4) ;
+    __vector_offset_183 = (DEFINED(__vector_dispatch_183) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_183))
+    . = ALIGN(4) ;
+    __vector_offset_184 = (DEFINED(__vector_dispatch_184) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_184))
+    . = ALIGN(4) ;
+    __vector_offset_185 = (DEFINED(__vector_dispatch_185) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_185))
+    . = ALIGN(4) ;
+    __vector_offset_186 = (DEFINED(__vector_dispatch_186) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_186))
+    . = ALIGN(4) ;
+    __vector_offset_187 = (DEFINED(__vector_dispatch_187) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_187))
+    . = ALIGN(4) ;
+    __vector_offset_188 = (DEFINED(__vector_dispatch_188) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_188))
+    . = ALIGN(4) ;
+    __vector_offset_189 = (DEFINED(__vector_dispatch_189) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_189))
+    . = ALIGN(4) ;
+    __vector_offset_190 = (DEFINED(__vector_dispatch_190) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_190))
+    . = ALIGN(4) ;
+    __vector_offset_191 = (DEFINED(__vector_dispatch_191) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_191))
+    . = ALIGN(4) ;
+    __vector_offset_192 = (DEFINED(__vector_dispatch_192) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_192))
+    . = ALIGN(4) ;
+    __vector_offset_193 = (DEFINED(__vector_dispatch_193) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_193))
+    . = ALIGN(4) ;
+    __vector_offset_194 = (DEFINED(__vector_dispatch_194) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_194))
+    . = ALIGN(4) ;
+    __vector_offset_195 = (DEFINED(__vector_dispatch_195) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_195))
+    . = ALIGN(4) ;
+    __vector_offset_196 = (DEFINED(__vector_dispatch_196) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_196))
+    . = ALIGN(4) ;
+    __vector_offset_197 = (DEFINED(__vector_dispatch_197) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_197))
+    . = ALIGN(4) ;
+    __vector_offset_198 = (DEFINED(__vector_dispatch_198) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_198))
+    . = ALIGN(4) ;
+    __vector_offset_199 = (DEFINED(__vector_dispatch_199) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_199))
+    . = ALIGN(4) ;
+    __vector_offset_200 = (DEFINED(__vector_dispatch_200) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_200))
+    . = ALIGN(4) ;
+    __vector_offset_201 = (DEFINED(__vector_dispatch_201) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_201))
+    . = ALIGN(4) ;
+    __vector_offset_202 = (DEFINED(__vector_dispatch_202) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_202))
+    . = ALIGN(4) ;
+    __vector_offset_203 = (DEFINED(__vector_dispatch_203) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_203))
+    . = ALIGN(4) ;
+    __vector_offset_204 = (DEFINED(__vector_dispatch_204) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_204))
+    . = ALIGN(4) ;
+    __vector_offset_205 = (DEFINED(__vector_dispatch_205) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_205))
+    . = ALIGN(4) ;
+    __vector_offset_206 = (DEFINED(__vector_dispatch_206) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_206))
+    . = ALIGN(4) ;
+    __vector_offset_207 = (DEFINED(__vector_dispatch_207) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_207))
+    . = ALIGN(4) ;
+    __vector_offset_208 = (DEFINED(__vector_dispatch_208) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_208))
+    . = ALIGN(4) ;
+    __vector_offset_209 = (DEFINED(__vector_dispatch_209) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_209))
+    . = ALIGN(4) ;
+    __vector_offset_210 = (DEFINED(__vector_dispatch_210) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_210))
+    . = ALIGN(4) ;
+    __vector_offset_211 = (DEFINED(__vector_dispatch_211) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_211))
+    . = ALIGN(4) ;
+    __vector_offset_212 = (DEFINED(__vector_dispatch_212) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_212))
+    . = ALIGN(4) ;
+    __vector_offset_213 = (DEFINED(__vector_dispatch_213) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_213))
+    . = ALIGN(4) ;
+    __vector_offset_214 = (DEFINED(__vector_dispatch_214) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_214))
+    . = ALIGN(4) ;
+    __vector_offset_215 = (DEFINED(__vector_dispatch_215) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_215))
+    . = ALIGN(4) ;
+    __vector_offset_216 = (DEFINED(__vector_dispatch_216) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_216))
+    . = ALIGN(4) ;
+    __vector_offset_217 = (DEFINED(__vector_dispatch_217) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_217))
+    . = ALIGN(4) ;
+    __vector_offset_218 = (DEFINED(__vector_dispatch_218) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_218))
+    . = ALIGN(4) ;
+    __vector_offset_219 = (DEFINED(__vector_dispatch_219) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_219))
+    . = ALIGN(4) ;
+    __vector_offset_220 = (DEFINED(__vector_dispatch_220) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_220))
+    . = ALIGN(4) ;
+    __vector_offset_221 = (DEFINED(__vector_dispatch_221) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_221))
+    . = ALIGN(4) ;
+    __vector_offset_222 = (DEFINED(__vector_dispatch_222) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_222))
+    . = ALIGN(4) ;
+    __vector_offset_223 = (DEFINED(__vector_dispatch_223) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_223))
+    . = ALIGN(4) ;
+    __vector_offset_224 = (DEFINED(__vector_dispatch_224) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_224))
+    . = ALIGN(4) ;
+    __vector_offset_225 = (DEFINED(__vector_dispatch_225) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_225))
+    . = ALIGN(4) ;
+    __vector_offset_226 = (DEFINED(__vector_dispatch_226) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_226))
+    . = ALIGN(4) ;
+    __vector_offset_227 = (DEFINED(__vector_dispatch_227) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_227))
+    . = ALIGN(4) ;
+    __vector_offset_228 = (DEFINED(__vector_dispatch_228) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_228))
+    . = ALIGN(4) ;
+    __vector_offset_229 = (DEFINED(__vector_dispatch_229) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_229))
+    . = ALIGN(4) ;
+    __vector_offset_230 = (DEFINED(__vector_dispatch_230) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_230))
+    . = ALIGN(4) ;
+    __vector_offset_231 = (DEFINED(__vector_dispatch_231) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_231))
+    . = ALIGN(4) ;
+    __vector_offset_232 = (DEFINED(__vector_dispatch_232) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_232))
+    . = ALIGN(4) ;
+    __vector_offset_233 = (DEFINED(__vector_dispatch_233) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_233))
+    . = ALIGN(4) ;
+    __vector_offset_234 = (DEFINED(__vector_dispatch_234) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_234))
+    . = ALIGN(4) ;
+    __vector_offset_235 = (DEFINED(__vector_dispatch_235) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_235))
+    . = ALIGN(4) ;
+    __vector_offset_236 = (DEFINED(__vector_dispatch_236) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_236))
+    . = ALIGN(4) ;
+    __vector_offset_237 = (DEFINED(__vector_dispatch_237) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_237))
+    . = ALIGN(4) ;
+    __vector_offset_238 = (DEFINED(__vector_dispatch_238) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_238))
+    . = ALIGN(4) ;
+    __vector_offset_239 = (DEFINED(__vector_dispatch_239) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_239))
+    . = ALIGN(4) ;
+    __vector_offset_240 = (DEFINED(__vector_dispatch_240) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_240))
+    . = ALIGN(4) ;
+    __vector_offset_241 = (DEFINED(__vector_dispatch_241) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_241))
+    . = ALIGN(4) ;
+    __vector_offset_242 = (DEFINED(__vector_dispatch_242) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_242))
+    . = ALIGN(4) ;
+    __vector_offset_243 = (DEFINED(__vector_dispatch_243) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_243))
+    . = ALIGN(4) ;
+    __vector_offset_244 = (DEFINED(__vector_dispatch_244) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_244))
+    . = ALIGN(4) ;
+    __vector_offset_245 = (DEFINED(__vector_dispatch_245) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_245))
+    . = ALIGN(4) ;
+    __vector_offset_246 = (DEFINED(__vector_dispatch_246) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_246))
+    . = ALIGN(4) ;
+    __vector_offset_247 = (DEFINED(__vector_dispatch_247) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_247))
+    . = ALIGN(4) ;
+    __vector_offset_248 = (DEFINED(__vector_dispatch_248) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_248))
+    . = ALIGN(4) ;
+    __vector_offset_249 = (DEFINED(__vector_dispatch_249) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_249))
+    . = ALIGN(4) ;
+    __vector_offset_250 = (DEFINED(__vector_dispatch_250) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_250))
+    . = ALIGN(4) ;
+    __vector_offset_251 = (DEFINED(__vector_dispatch_251) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_251))
+    . = ALIGN(4) ;
+    __vector_offset_252 = (DEFINED(__vector_dispatch_252) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_252))
+    . = ALIGN(4) ;
+    __vector_offset_253 = (DEFINED(__vector_dispatch_253) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_253))
+    . = ALIGN(4) ;
+    __vector_offset_254 = (DEFINED(__vector_dispatch_254) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_254))
+    . = ALIGN(4) ;
+    __vector_offset_255 = (DEFINED(__vector_dispatch_255) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_255))
+    /* Default interrupt handler */
+    . = ALIGN(4) ;
+    __vector_offset_default = . - _ebase_address;
+    KEEP(*(.vector_default))
+  } > kseg0_program_mem
+
+  /*  The startup code is in the .reset.startup section.
+   *  Keep this here for backwards compatibility with older
+   *  C32 v1.xx releases.
+   */
+  .startup :
+  {
+    KEEP(*(.startup))
+  } > kseg0_program_mem
+
+  /* Code Sections - Note that input sections *(.text) and *(.text.*)
+   * are not mapped here. The best-fit allocator locates them,
+   * so that .text may flow around absolute sections as needed.
+   */
+  .text :
+  {
+    *(.stub .gnu.linkonce.t.*)
+    KEEP (*(.text.*personality*))
+    *(.mips16.fn.*)
+    *(.mips16.call.*)
+    *(.gnu.warning)
+    . = ALIGN(4) ;
+  } >kseg0_program_mem
+  /* Global-namespace object initialization */
+  .init   :
+  {
+    KEEP (*crti.o(.init))
+    KEEP (*crtbegin.o(.init))
+    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o *crtn.o ).init))
+    KEEP (*crtend.o(.init))
+    KEEP (*crtn.o(.init))
+    . = ALIGN(4) ;
+  } >kseg0_program_mem
+  .fini   :
+  {
+    KEEP (*(.fini))
+    . = ALIGN(4) ;
+  } >kseg0_program_mem
+  .preinit_array   :
+  {
+    PROVIDE_HIDDEN (__preinit_array_start = .);
+    KEEP (*(.preinit_array))
+    PROVIDE_HIDDEN (__preinit_array_end = .);
+    . = ALIGN(4) ;
+  } >kseg0_program_mem
+  .init_array   :
+  {
+    PROVIDE_HIDDEN (__init_array_start = .);
+    KEEP (*(SORT(.init_array.*)))
+    KEEP (*(.init_array))
+    PROVIDE_HIDDEN (__init_array_end_ = .);
+    . = ALIGN(4) ;
+  } >kseg0_program_mem
+  .ctors   :
+  {
+    /* XC32 uses crtbegin.o to find the start of
+       the constructors, so we make sure it is
+       first.  Because this is a wildcard, it
+       doesn't matter if the user does not
+       actually link against crtbegin.o; the
+       linker won't look for a file to match a
+       wildcard.  The wildcard also means that it
+       doesn't matter which directory crtbegin.o
+       is in.  */
+    KEEP (*crtbegin.o(.ctors))
+    KEEP (*crtbegin?.o(.ctors))
+    /* We don't want to include the .ctor section from
+       the crtend.o file until after the sorted ctors.
+       The .ctor section from the crtend file contains the
+       end of ctors marker and it must be last */
+    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
+    KEEP (*(SORT(.ctors.*)))
+    KEEP (*(.ctors))
+    PROVIDE_HIDDEN (__init_array_end = .);
+    . = ALIGN(4) ;
+  } >kseg0_program_mem
+  .fini_array   :
+  {
+    PROVIDE_HIDDEN (__fini_array_start = .);
+    KEEP (*(SORT(.fini_array.*)))
+    KEEP (*(.fini_array))
+    PROVIDE_HIDDEN (__fini_array_end = .);
+    . = ALIGN(4) ;
+  } >kseg0_program_mem
+  .dtors   :
+  {
+    KEEP (*crtbegin.o(.dtors))
+    KEEP (*crtbegin?.o(.dtors))
+    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
+    KEEP (*(SORT(.dtors.*)))
+    KEEP (*(.dtors))
+    . = ALIGN(4) ;
+  } >kseg0_program_mem
+  /* Read-only sections */
+  .rodata   :
+  {
+    *( .gnu.linkonce.r.*)
+    *(.rodata1)
+    . = ALIGN(4) ;
+  } >kseg0_program_mem
+  /*
+   * Small initialized constant global and static data can be placed in the
+   * .sdata2 section.  This is different from .sdata, which contains small
+   * initialized non-constant global and static data.
+   */
+  .sdata2 ALIGN(4) :
+  {
+    *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+    . = ALIGN(4) ;
+  } >kseg0_program_mem
+  /*
+   * Uninitialized constant global and static data (i.e., variables which will
+   * always be zero).  Again, this is different from .sbss, which contains
+   * small non-initialized, non-constant global and static data.
+   */
+  .sbss2 ALIGN(4) :
+  {
+    *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*)
+    . = ALIGN(4) ;
+  } >kseg0_program_mem
+  .eh_frame_hdr   :
+  {
+    *(.eh_frame_hdr)
+  } >kseg0_program_mem
+    . = ALIGN(4) ;
+  .eh_frame   : ONLY_IF_RO
+  {
+    KEEP (*(.eh_frame))
+  } >kseg0_program_mem
+    . = ALIGN(4) ;
+  .gcc_except_table   : ONLY_IF_RO
+  {
+    *(.gcc_except_table .gcc_except_table.*)
+  } >kseg0_program_mem
+    . = ALIGN(4) ;
+  .dbg_data (NOLOAD) :
+  {
+    . += (DEFINED (_DEBUGGER) ? 0x200 : 0x0);
+    /* Additional data memory required for DSPr2 registers */
+    . += (DEFINED (_DEBUGGER) ? 0x80 : 0x0);
+    /* Additional data memory required for FPU64 registers */
+    . += (DEFINED (_DEBUGGER) ? 0x100 : 0x0);
+  } >kseg0_data_mem
+  .jcr   :
+  {
+    KEEP (*(.jcr))
+    . = ALIGN(4) ;
+  } >kseg0_data_mem
+  .eh_frame    : ONLY_IF_RW
+  {
+    KEEP (*(.eh_frame))
+  } >kseg0_data_mem
+    . = ALIGN(4) ;
+  .gcc_except_table    : ONLY_IF_RW
+  {
+    *(.gcc_except_table .gcc_except_table.*)
+  } >kseg0_data_mem
+    . = ALIGN(4) ;
+  /* Persistent data - Use the new C 'persistent' attribute instead. */
+  .persist   :
+  {
+    _persist_begin = .;
+    *(.persist .persist.*)
+    . = ALIGN(4) ;
+    _persist_end = .;
+  } >kseg0_data_mem
+  /*
+   *  Note that input sections named .data* are not mapped here.
+   *  The best-fit allocator locates them, so that they may flow
+   *  around absolute sections as needed.
+   */
+  .data   :
+  {
+    *( .gnu.linkonce.d.*)
+    SORT(CONSTRUCTORS)
+    *(.data1)
+    *(.data .data.*)
+    . = ALIGN(4) ;
+  } >kseg0_data_mem
+  . = .;
+  _gp = ALIGN(16) + 0x7ff0;
+  .got ALIGN(4) :
+  {
+    *(.got.plt) *(.got)
+    . = ALIGN(4) ;
+  } >kseg0_data_mem /* AT>kseg0_program_mem */
+  /*
+   * Note that 'small' data sections are still mapped in the linker
+   * script. This ensures that they are grouped together for
+   * gp-relative addressing. Absolute sections are allocated after
+   * the 'small' data sections so small data cannot flow around them.
+   */
+  /*
+   * We want the small data sections together, so single-instruction offsets
+   * can access them all, and initialized data all before uninitialized, so
+   * we can shorten the on-disk segment size.
+   */
+  .sdata ALIGN(4) :
+  {
+    _sdata_begin = . ;
+    *(.sdata .sdata.* .gnu.linkonce.s.*)
+    . = ALIGN(4) ;
+    _sdata_end = . ;
+  } >kseg0_data_mem
+  .lit8           :
+  {
+    *(.lit8)
+  } >kseg0_data_mem
+  .lit4           :
+  {
+    *(.lit4)
+  } >kseg0_data_mem
+  . = ALIGN (4) ;
+  _data_end = . ;
+  _bss_begin = . ;
+  .sbss ALIGN(4) :
+  {
+    _sbss_begin = . ;
+    *(.dynsbss)
+    *(.sbss .sbss.* .gnu.linkonce.sb.*)
+    *(.scommon)
+    _sbss_end = . ;
+    . = ALIGN(4) ;
+  } >kseg0_data_mem
+  /*
+   *  Align here to ensure that the .bss section occupies space up to
+   *  _end.  Align after .bss to ensure correct alignment even if the
+   *  .bss section disappears because there are no input sections.
+   *
+   *  Note that input sections named .bss* are no longer mapped here.
+   *  The best-fit allocator locates them, so that they may flow
+   *  around absolute sections as needed.
+   *
+   */
+  .bss     :
+  {
+    *(.dynbss)
+    *(COMMON)
+    *(.bss.*)
+   /* Align here to ensure that the .bss section occupies space up to
+      _end.  Align after .bss to ensure correct alignment even if the
+      .bss section disappears because there are no input sections. */
+   . = ALIGN(. != 0 ? 4 : 1);
+  } >kseg0_data_mem
+  . = ALIGN(4) ;
+  _end = . ;
+  _bss_end = . ;
+
+  /* Heap starts after BSS */
+  . = ALIGN(8);
+  __HeapBase = .;
+
+ /* .stack_dummy section doesn't contains any symbols. It is only
+  * used for linker to calculate size of stack sections, and assign
+  * values to stack symbols later */
+ .stack_dummy (COPY):
+  {
+      KEEP(*(.stack*))
+  } >kseg0_data_mem
+
+  _ram_start = ORIGIN(kseg0_data_mem);
+
+  /* Set stack top to end of RAM, and stack limit move down by
+   * size of stack_dummy section */
+  __StackTop = ORIGIN(kseg0_data_mem) + LENGTH(kseg0_data_mem) - 8;
+  __StackLimit = __StackTop - SIZEOF(.stack_dummy);
+  PROVIDE(__stack = __StackTop);
+  PROVIDE(_stack = __StackTop);
+
+  /* Top of head is the bottom of the stack */
+  __HeapLimit = __StackLimit;
+
+  /* Check if data + heap + stack exceeds kseg0_data_mem limit */
+  ASSERT(__HeapBase <= __HeapLimit, "region kseg0_data_mem overflowed with stack")
+
+    /* The .pdr section belongs in the absolute section */
+    /DISCARD/ : { *(.pdr) }
+  .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
+  .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
+  .mdebug.abi32 0 : { KEEP(*(.mdebug.abi32)) }
+  .mdebug.abiN32 0 : { KEEP(*(.mdebug.abiN32)) }
+  .mdebug.abi64 0 : { KEEP(*(.mdebug.abi64)) }
+  .mdebug.abiO64 0 : { KEEP(*(.mdebug.abiO64)) }
+  .mdebug.eabi32 0 : { KEEP(*(.mdebug.eabi32)) }
+  .mdebug.eabi64 0 : { KEEP(*(.mdebug.eabi64)) }
+  .gcc_compiled_long32 : { KEEP(*(.gcc_compiled_long32)) }
+  .gcc_compiled_long64 : { KEEP(*(.gcc_compiled_long64)) }
+  /* Stabs debugging sections.  */
+  .stab          0 : { *(.stab) }
+  .stabstr       0 : { *(.stabstr) }
+  .stab.excl     0 : { *(.stab.excl) }
+  .stab.exclstr  0 : { *(.stab.exclstr) }
+  .stab.index    0 : { *(.stab.index) }
+  .stab.indexstr 0 : { *(.stab.indexstr) }
+  .comment       0 : { *(.comment) }
+  /* DWARF debug sections used by MPLAB X for source-level debugging. 
+     Symbols in the DWARF debugging sections are relative to the beginning
+     of the section so we begin them at 0.  */
+  /* DWARF 1 */
+  .debug          0 : { *.elf(.debug) *(.debug) }
+  .line           0 : { *.elf(.line) *(.line) }
+  /* GNU DWARF 1 extensions */
+  .debug_srcinfo  0 : { *.elf(.debug_srcinfo) *(.debug_srcinfo) }
+  .debug_sfnames  0 : { *.elf(.debug_sfnames) *(.debug_sfnames) }
+  /* DWARF 1.1 and DWARF 2 */
+  .debug_aranges  0 : { *.elf(.debug_aranges) *(.debug_aranges) }
+  .debug_pubnames 0 : { *.elf(.debug_pubnames) *(.debug_pubnames) }
+  /* DWARF 2 */
+  .debug_info     0 : { *.elf(.debug_info .gnu.linkonce.wi.*) *(.debug_info .gnu.linkonce.wi.*) }
+  .debug_abbrev   0 : { *.elf(.debug_abbrev) *(.debug_abbrev) }
+  .debug_line     0 : { *.elf(.debug_line) *(.debug_line) }
+  .debug_frame    0 : { *.elf(.debug_frame) *(.debug_frame) }
+  .debug_str      0 : { *.elf(.debug_str) *(.debug_str) }
+  .debug_loc      0 : { *.elf(.debug_loc) *(.debug_loc) }
+  .debug_macinfo  0 : { *.elf(.debug_macinfo) *(.debug_macinfo) }
+  /* SGI/MIPS DWARF 2 extensions */
+  .debug_weaknames 0 : { *.elf(.debug_weaknames) *(.debug_weaknames) }
+  .debug_funcnames 0 : { *.elf(.debug_funcnames) *(.debug_funcnames) }
+  .debug_typenames 0 : { *.elf(.debug_typenames) *(.debug_typenames) }
+  .debug_varnames  0 : { *.elf(.debug_varnames) *(.debug_varnames) }
+  .debug_pubtypes 0 : { *.elf(.debug_pubtypes) *(.debug_pubtypes) }
+  .debug_ranges   0 : { *.elf(.debug_ranges) *(.debug_ranges) }
+  /DISCARD/ : { *(.rel.dyn) }
+  .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
+  /DISCARD/ : { *(.note.GNU-stack) }
+  /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) *(.discard) }
+}
+
+/*************************************************************************
+ *                    L1 Cache initialization symbols
+ *************************************************************************/
+/*
+ *  Provide virtual addresses for cache initialization
+ *  These symbols are used by the pic32_init_cache.o module to set up
+ *  the cache at startup.
+ */
+EXTERN  (__pic32_init_cache_program_base_addr)
+PROVIDE (__pic32_init_cache_program_base_addr = 0x9D000000) ;
+EXTERN  (__pic32_init_cache_data_base_addr)
+PROVIDE (__pic32_init_cache_data_base_addr = 0x80000000) ;
+
diff --git a/hw/mcu/microchip/pic32mz/p32mz_boot.ld b/hw/mcu/microchip/pic32mz/p32mz_boot.ld
new file mode 100644
index 0000000..b1f8655
--- /dev/null
+++ b/hw/mcu/microchip/pic32mz/p32mz_boot.ld
@@ -0,0 +1,1963 @@
+/*--------------------------------------------------------------------------
+ * MPLAB XC Compiler -  PIC32MZ2048EFH064 linker script
+ * Build date : Jul 28 2020
+ * 
+ * Copyright (c) 2020, Microchip Technology Inc. and its subsidiaries ("Microchip")
+ * All rights reserved.
+ * 
+ * This software is developed by Microchip Technology Inc. and its
+ * subsidiaries ("Microchip").
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are 
+ * met:
+ * 
+ * 1.      Redistributions of source code must retain the above copyright
+ *         notice, this list of conditions and the following disclaimer.
+ * 2.      Redistributions in binary form must reproduce the above 
+ *         copyright notice, this list of conditions and the following 
+ *         disclaimer in the documentation and/or other materials provided 
+ *         with the distribution. Publication is not required when this file 
+ *         is used in an embedded application.
+ * 3.      Microchip's name may not be used to endorse or promote products
+ *         derived from this software without specific prior written 
+ *         permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY MICROCHIP "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL MICROCHIP BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING BUT NOT LIMITED TO
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWSOEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 
+ */
+
+/* Default linker script, for normal executables */
+
+/*  NOTE: This single-file linker script replaces the two-file system used
+ *  for older PIC32 devices. 
+ */
+
+OUTPUT_FORMAT("elf32-tradlittlemips")
+OUTPUT_ARCH(pic32mx)
+ENTRY(_reset)
+/*
+ * Provide for a minimum stack and heap size
+ * - _min_stack_size - represents the minimum space that must be made
+ *                     available for the stack.  Can be overridden from
+ *                     the command line using the linker's --defsym option.
+ * - _min_heap_size  - represents the minimum space that must be made
+ *                     available for the heap.  Must be specified on
+ *                     the command line using the linker's --defsym option.
+ */
+PROVIDE(_min_stack_size = 0x400) ;
+/* Mynewt compute heap size differently then default xc compiler wants */
+_min_heap_size = 0x0;
+
+/*************************************************************************
+ * Legacy processor-specific object file.  Contains SFR definitions.
+ * The SFR definitions are now provided in a processor-specific *.S
+ * assembly source file rather than the processor.o file. Use the new
+ * .S file rather than this processor.o file for new projects. MPLAB XC32
+ * v2.10 and later will automatically link the new .S file.
+ *************************************************************************/
+#if defined(__XC32_VERSION__) && (__XC32_VERSION__ < 2100)
+OPTIONAL("processor.o")
+#endif
+
+/*************************************************************************
+ * Vector-offset initialization
+ *************************************************************************/
+OPTIONAL("vector_offset_init.o")
+
+/*************************************************************************
+ * Symbols used for interrupt-vector table generation
+ * To override the defaults, define the _ebase_address symbol using
+ * the --defsym linker opt as shown in this example:
+ *   xc32-gcc src.c -Wl,--defsym=_ebase_address=0x9D001000
+ *************************************************************************/
+PROVIDE(_vector_spacing = 0x0001);
+PROVIDE(_ebase_address = 0x9FC01000);
+
+/*************************************************************************
+ * Memory Address Equates
+ * _RESET_ADDR                    -- Reset Vector or entry point
+ * _BEV_EXCPT_ADDR                -- Boot exception Vector
+ * _DBG_EXCPT_ADDR                -- In-circuit Debugging Exception Vector
+ * _SIMPLE_TLB_REFILL_EXCPT_ADDR  -- Simple TLB-Refill Exception Vector
+ * _CACHE_ERR_EXCPT_ADDR          -- Cache-error Exception Vector
+ * _GEN_EXCPT_ADDR                -- General Exception Vector
+ *************************************************************************/
+_RESET_ADDR                    = 0xBFC00000;
+_BEV_EXCPT_ADDR                = 0xBFC00380;
+_DBG_EXCPT_ADDR                = 0xBFC00480;
+_SIMPLE_TLB_REFILL_EXCPT_ADDR  = _ebase_address + 0;
+_CACHE_ERR_EXCPT_ADDR          = _ebase_address + 0x100;
+_GEN_EXCPT_ADDR                = _ebase_address + 0x180;
+
+/*************************************************************************
+ * Memory Regions
+ *
+ * Memory regions without attributes cannot be used for orphaned sections.
+ * Only sections specifically assigned to these regions can be allocated
+ * into these regions.
+ *
+ * The Debug exception vector is located at 0x9FC00480.
+ *
+ * The config_<address> sections are used to locate the config words at
+ * their absolute addresses.
+ *************************************************************************/
+
+
+MEMORY
+{
+  kseg0_program_mem     (rx)  : ORIGIN = 0x9FC01000, LENGTH = 0xF000
+  kseg0_boot_mem              : ORIGIN = 0x9FC004B0, LENGTH = 0x0
+  kseg1_boot_mem              : ORIGIN = 0xBFC00000, LENGTH = 0x480
+  kseg1_boot_mem_4B0          : ORIGIN = 0xBFC004B0, LENGTH = 0x0A50
+  config_BFC0FF40             : ORIGIN = 0xBFC0FF40, LENGTH = 0x4
+  config_BFC0FF44             : ORIGIN = 0xBFC0FF44, LENGTH = 0x4
+  config_BFC0FF48             : ORIGIN = 0xBFC0FF48, LENGTH = 0x4
+  config_BFC0FF4C             : ORIGIN = 0xBFC0FF4C, LENGTH = 0x4
+  config_BFC0FF50             : ORIGIN = 0xBFC0FF50, LENGTH = 0x4
+  config_BFC0FF54             : ORIGIN = 0xBFC0FF54, LENGTH = 0x4
+  config_BFC0FF58             : ORIGIN = 0xBFC0FF58, LENGTH = 0x4
+  config_BFC0FF5C             : ORIGIN = 0xBFC0FF5C, LENGTH = 0x4
+  config_BFC0FF60             : ORIGIN = 0xBFC0FF60, LENGTH = 0x4
+  config_BFC0FF64             : ORIGIN = 0xBFC0FF64, LENGTH = 0x4
+  config_BFC0FF68             : ORIGIN = 0xBFC0FF68, LENGTH = 0x4
+  config_BFC0FF6C             : ORIGIN = 0xBFC0FF6C, LENGTH = 0x4
+  config_BFC0FF70             : ORIGIN = 0xBFC0FF70, LENGTH = 0x4
+  config_BFC0FF74             : ORIGIN = 0xBFC0FF74, LENGTH = 0x4
+  config_BFC0FF78             : ORIGIN = 0xBFC0FF78, LENGTH = 0x4
+  config_BFC0FF7C             : ORIGIN = 0xBFC0FF7C, LENGTH = 0x4
+  config_BFC0FFC0             : ORIGIN = 0xBFC0FFC0, LENGTH = 0x4
+  config_BFC0FFC4             : ORIGIN = 0xBFC0FFC4, LENGTH = 0x4
+  config_BFC0FFC8             : ORIGIN = 0xBFC0FFC8, LENGTH = 0x4
+  config_BFC0FFCC             : ORIGIN = 0xBFC0FFCC, LENGTH = 0x4
+  config_BFC0FFD0             : ORIGIN = 0xBFC0FFD0, LENGTH = 0x4
+  config_BFC0FFD4             : ORIGIN = 0xBFC0FFD4, LENGTH = 0x4
+  config_BFC0FFD8             : ORIGIN = 0xBFC0FFD8, LENGTH = 0x4
+  config_BFC0FFDC             : ORIGIN = 0xBFC0FFDC, LENGTH = 0x4
+  config_BFC0FFE0             : ORIGIN = 0xBFC0FFE0, LENGTH = 0x4
+  config_BFC0FFE4             : ORIGIN = 0xBFC0FFE4, LENGTH = 0x4
+  config_BFC0FFE8             : ORIGIN = 0xBFC0FFE8, LENGTH = 0x4
+  config_BFC0FFEC             : ORIGIN = 0xBFC0FFEC, LENGTH = 0x4
+  config_BFC0FFF0             : ORIGIN = 0xBFC0FFF0, LENGTH = 0x4
+  config_BFC0FFF4             : ORIGIN = 0xBFC0FFF4, LENGTH = 0x4
+  config_BFC0FFF8             : ORIGIN = 0xBFC0FFF8, LENGTH = 0x4
+  config_BFC0FFFC             : ORIGIN = 0xBFC0FFFC, LENGTH = 0x4
+  lowerbootaliaslastpage      : ORIGIN = 0xBFC10000, LENGTH = 0x4000
+  upperbootalias              : ORIGIN = 0xBFC20000, LENGTH = 0xFF00
+  config_BFC2FF40             : ORIGIN = 0xBFC2FF40, LENGTH = 0x4
+  config_BFC2FF44             : ORIGIN = 0xBFC2FF44, LENGTH = 0x4
+  config_BFC2FF48             : ORIGIN = 0xBFC2FF48, LENGTH = 0x4
+  config_BFC2FF4C             : ORIGIN = 0xBFC2FF4C, LENGTH = 0x4
+  config_BFC2FF50             : ORIGIN = 0xBFC2FF50, LENGTH = 0x4
+  config_BFC2FF54             : ORIGIN = 0xBFC2FF54, LENGTH = 0x4
+  config_BFC2FF58             : ORIGIN = 0xBFC2FF58, LENGTH = 0x4
+  config_BFC2FF5C             : ORIGIN = 0xBFC2FF5C, LENGTH = 0x4
+  config_BFC2FF60             : ORIGIN = 0xBFC2FF60, LENGTH = 0x4
+  config_BFC2FF64             : ORIGIN = 0xBFC2FF64, LENGTH = 0x4
+  config_BFC2FF68             : ORIGIN = 0xBFC2FF68, LENGTH = 0x4
+  config_BFC2FF6C             : ORIGIN = 0xBFC2FF6C, LENGTH = 0x4
+  config_BFC2FF70             : ORIGIN = 0xBFC2FF70, LENGTH = 0x4
+  config_BFC2FF74             : ORIGIN = 0xBFC2FF74, LENGTH = 0x4
+  config_BFC2FF78             : ORIGIN = 0xBFC2FF78, LENGTH = 0x4
+  config_BFC2FF7C             : ORIGIN = 0xBFC2FF7C, LENGTH = 0x4
+  config_BFC2FFC0             : ORIGIN = 0xBFC2FFC0, LENGTH = 0x4
+  config_BFC2FFC4             : ORIGIN = 0xBFC2FFC4, LENGTH = 0x4
+  config_BFC2FFC8             : ORIGIN = 0xBFC2FFC8, LENGTH = 0x4
+  config_BFC2FFCC             : ORIGIN = 0xBFC2FFCC, LENGTH = 0x4
+  config_BFC2FFD0             : ORIGIN = 0xBFC2FFD0, LENGTH = 0x4
+  config_BFC2FFD4             : ORIGIN = 0xBFC2FFD4, LENGTH = 0x4
+  config_BFC2FFD8             : ORIGIN = 0xBFC2FFD8, LENGTH = 0x4
+  config_BFC2FFDC             : ORIGIN = 0xBFC2FFDC, LENGTH = 0x4
+  config_BFC2FFE0             : ORIGIN = 0xBFC2FFE0, LENGTH = 0x4
+  config_BFC2FFE4             : ORIGIN = 0xBFC2FFE4, LENGTH = 0x4
+  config_BFC2FFE8             : ORIGIN = 0xBFC2FFE8, LENGTH = 0x4
+  config_BFC2FFEC             : ORIGIN = 0xBFC2FFEC, LENGTH = 0x4
+  config_BFC2FFF0             : ORIGIN = 0xBFC2FFF0, LENGTH = 0x4
+  config_BFC2FFF4             : ORIGIN = 0xBFC2FFF4, LENGTH = 0x4
+  config_BFC2FFF8             : ORIGIN = 0xBFC2FFF8, LENGTH = 0x4
+  config_BFC2FFFC             : ORIGIN = 0xBFC2FFFC, LENGTH = 0x4
+  upperbootaliaslastpage      : ORIGIN = 0xBFC30000, LENGTH = 0x4000
+  boot1                       : ORIGIN = 0xBFC40000, LENGTH = 0xFF00
+  config_BFC4FF40             : ORIGIN = 0xBFC4FF40, LENGTH = 0x4
+  config_BFC4FF44             : ORIGIN = 0xBFC4FF44, LENGTH = 0x4
+  config_BFC4FF48             : ORIGIN = 0xBFC4FF48, LENGTH = 0x4
+  config_BFC4FF4C             : ORIGIN = 0xBFC4FF4C, LENGTH = 0x4
+  config_BFC4FF50             : ORIGIN = 0xBFC4FF50, LENGTH = 0x4
+  config_BFC4FF54             : ORIGIN = 0xBFC4FF54, LENGTH = 0x4
+  config_BFC4FF58             : ORIGIN = 0xBFC4FF58, LENGTH = 0x4
+  config_BFC4FF5C             : ORIGIN = 0xBFC4FF5C, LENGTH = 0x4
+  config_BFC4FF60             : ORIGIN = 0xBFC4FF60, LENGTH = 0x4
+  config_BFC4FF64             : ORIGIN = 0xBFC4FF64, LENGTH = 0x4
+  config_BFC4FF68             : ORIGIN = 0xBFC4FF68, LENGTH = 0x4
+  config_BFC4FF6C             : ORIGIN = 0xBFC4FF6C, LENGTH = 0x4
+  config_BFC4FF70             : ORIGIN = 0xBFC4FF70, LENGTH = 0x4
+  config_BFC4FF74             : ORIGIN = 0xBFC4FF74, LENGTH = 0x4
+  config_BFC4FF78             : ORIGIN = 0xBFC4FF78, LENGTH = 0x4
+  config_BFC4FF7C             : ORIGIN = 0xBFC4FF7C, LENGTH = 0x4
+  config_BFC4FFC0             : ORIGIN = 0xBFC4FFC0, LENGTH = 0x4
+  config_BFC4FFC4             : ORIGIN = 0xBFC4FFC4, LENGTH = 0x4
+  config_BFC4FFC8             : ORIGIN = 0xBFC4FFC8, LENGTH = 0x4
+  config_BFC4FFCC             : ORIGIN = 0xBFC4FFCC, LENGTH = 0x4
+  config_BFC4FFD0             : ORIGIN = 0xBFC4FFD0, LENGTH = 0x4
+  config_BFC4FFD4             : ORIGIN = 0xBFC4FFD4, LENGTH = 0x4
+  config_BFC4FFD8             : ORIGIN = 0xBFC4FFD8, LENGTH = 0x4
+  config_BFC4FFDC             : ORIGIN = 0xBFC4FFDC, LENGTH = 0x4
+  config_BFC4FFE0             : ORIGIN = 0xBFC4FFE0, LENGTH = 0x4
+  config_BFC4FFE4             : ORIGIN = 0xBFC4FFE4, LENGTH = 0x4
+  config_BFC4FFE8             : ORIGIN = 0xBFC4FFE8, LENGTH = 0x4
+  config_BFC4FFEC             : ORIGIN = 0xBFC4FFEC, LENGTH = 0x4
+  config_BFC4FFF0             : ORIGIN = 0xBFC4FFF0, LENGTH = 0x4
+  config_BFC4FFF4             : ORIGIN = 0xBFC4FFF4, LENGTH = 0x4
+  config_BFC4FFF8             : ORIGIN = 0xBFC4FFF8, LENGTH = 0x4
+  config_BFC4FFFC             : ORIGIN = 0xBFC4FFFC, LENGTH = 0x4
+  boot1lastpage               : ORIGIN = 0xBFC50000, LENGTH = 0x4000
+  config_BFC54000             : ORIGIN = 0xBFC54000, LENGTH = 0x4
+  config_BFC54004             : ORIGIN = 0xBFC54004, LENGTH = 0x4
+  config_BFC54008             : ORIGIN = 0xBFC54008, LENGTH = 0x4
+  config_BFC5400C             : ORIGIN = 0xBFC5400C, LENGTH = 0x4
+  config_BFC54010             : ORIGIN = 0xBFC54010, LENGTH = 0x4
+  config_BFC5401C             : ORIGIN = 0xBFC5401C, LENGTH = 0x4
+  config_BFC54020             : ORIGIN = 0xBFC54020, LENGTH = 0x4
+  config_BFC54024             : ORIGIN = 0xBFC54024, LENGTH = 0x4
+  boot2                       : ORIGIN = 0xBFC60000, LENGTH = 0xFF00
+  config_BFC6FF40             : ORIGIN = 0xBFC6FF40, LENGTH = 0x4
+  config_BFC6FF44             : ORIGIN = 0xBFC6FF44, LENGTH = 0x4
+  config_BFC6FF48             : ORIGIN = 0xBFC6FF48, LENGTH = 0x4
+  config_BFC6FF4C             : ORIGIN = 0xBFC6FF4C, LENGTH = 0x4
+  config_BFC6FF50             : ORIGIN = 0xBFC6FF50, LENGTH = 0x4
+  config_BFC6FF54             : ORIGIN = 0xBFC6FF54, LENGTH = 0x4
+  config_BFC6FF58             : ORIGIN = 0xBFC6FF58, LENGTH = 0x4
+  config_BFC6FF5C             : ORIGIN = 0xBFC6FF5C, LENGTH = 0x4
+  config_BFC6FF60             : ORIGIN = 0xBFC6FF60, LENGTH = 0x4
+  config_BFC6FF64             : ORIGIN = 0xBFC6FF64, LENGTH = 0x4
+  config_BFC6FF68             : ORIGIN = 0xBFC6FF68, LENGTH = 0x4
+  config_BFC6FF6C             : ORIGIN = 0xBFC6FF6C, LENGTH = 0x4
+  config_BFC6FF70             : ORIGIN = 0xBFC6FF70, LENGTH = 0x4
+  config_BFC6FF74             : ORIGIN = 0xBFC6FF74, LENGTH = 0x4
+  config_BFC6FF78             : ORIGIN = 0xBFC6FF78, LENGTH = 0x4
+  config_BFC6FF7C             : ORIGIN = 0xBFC6FF7C, LENGTH = 0x4
+  config_BFC6FFC0             : ORIGIN = 0xBFC6FFC0, LENGTH = 0x4
+  config_BFC6FFC4             : ORIGIN = 0xBFC6FFC4, LENGTH = 0x4
+  config_BFC6FFC8             : ORIGIN = 0xBFC6FFC8, LENGTH = 0x4
+  config_BFC6FFCC             : ORIGIN = 0xBFC6FFCC, LENGTH = 0x4
+  config_BFC6FFD0             : ORIGIN = 0xBFC6FFD0, LENGTH = 0x4
+  config_BFC6FFD4             : ORIGIN = 0xBFC6FFD4, LENGTH = 0x4
+  config_BFC6FFD8             : ORIGIN = 0xBFC6FFD8, LENGTH = 0x4
+  config_BFC6FFDC             : ORIGIN = 0xBFC6FFDC, LENGTH = 0x4
+  config_BFC6FFE0             : ORIGIN = 0xBFC6FFE0, LENGTH = 0x4
+  config_BFC6FFE4             : ORIGIN = 0xBFC6FFE4, LENGTH = 0x4
+  config_BFC6FFE8             : ORIGIN = 0xBFC6FFE8, LENGTH = 0x4
+  config_BFC6FFEC             : ORIGIN = 0xBFC6FFEC, LENGTH = 0x4
+  config_BFC6FFF0             : ORIGIN = 0xBFC6FFF0, LENGTH = 0x4
+  config_BFC6FFF4             : ORIGIN = 0xBFC6FFF4, LENGTH = 0x4
+  config_BFC6FFF8             : ORIGIN = 0xBFC6FFF8, LENGTH = 0x4
+  config_BFC6FFFC             : ORIGIN = 0xBFC6FFFC, LENGTH = 0x4
+  boot2lastpage               : ORIGIN = 0xBFC70000, LENGTH = 0x4000
+  kseg0_data_mem       (w!x)  : ORIGIN = 0x80000000, LENGTH = 0x80000
+  sfrs                        : ORIGIN = 0xBF800000, LENGTH = 0x100000
+  configsfrs_BFC0FF40         : ORIGIN = 0xBFC0FF40, LENGTH = 0x40
+  configsfrs_BFC0FFC0         : ORIGIN = 0xBFC0FFC0, LENGTH = 0x40
+  configsfrs_BFC2FF40         : ORIGIN = 0xBFC2FF40, LENGTH = 0x40
+  configsfrs_BFC2FFC0         : ORIGIN = 0xBFC2FFC0, LENGTH = 0x40
+  configsfrs_BFC4FF40         : ORIGIN = 0xBFC4FF40, LENGTH = 0x40
+  configsfrs_BFC4FFC0         : ORIGIN = 0xBFC4FFC0, LENGTH = 0x40
+  configsfrs_BFC54000         : ORIGIN = 0xBFC54000, LENGTH = 0x20
+  configsfrs_BFC6FF40         : ORIGIN = 0xBFC6FF40, LENGTH = 0x40
+  configsfrs_BFC6FFC0         : ORIGIN = 0xBFC6FFC0, LENGTH = 0x40
+  kseg2_sqi_data_mem          : ORIGIN = 0xD0000000, LENGTH = 0x4000000
+  kseg3_sqi_data_mem          : ORIGIN = 0xF0000000, LENGTH = 0x4000000
+}
+
+/*************************************************************************
+ * Configuration-word sections. Map the config-pragma input sections to
+ * absolute-address output sections.
+ *************************************************************************/
+SECTIONS
+{
+  .config_BFC0FF40 : {
+    KEEP(*(.config_BFC0FF40))
+  } > config_BFC0FF40
+  .config_BFC0FF44 : {
+    KEEP(*(.config_BFC0FF44))
+  } > config_BFC0FF44
+  .config_BFC0FF48 : {
+    KEEP(*(.config_BFC0FF48))
+  } > config_BFC0FF48
+  .config_BFC0FF4C : {
+    KEEP(*(.config_BFC0FF4C))
+  } > config_BFC0FF4C
+  .config_BFC0FF50 : {
+    KEEP(*(.config_BFC0FF50))
+  } > config_BFC0FF50
+  .config_BFC0FF54 : {
+    KEEP(*(.config_BFC0FF54))
+  } > config_BFC0FF54
+  .config_BFC0FF58 : {
+    KEEP(*(.config_BFC0FF58))
+  } > config_BFC0FF58
+  .config_BFC0FF5C : {
+    KEEP(*(.config_BFC0FF5C))
+  } > config_BFC0FF5C
+  .config_BFC0FF60 : {
+    KEEP(*(.config_BFC0FF60))
+  } > config_BFC0FF60
+  .config_BFC0FF64 : {
+    KEEP(*(.config_BFC0FF64))
+  } > config_BFC0FF64
+  .config_BFC0FF68 : {
+    KEEP(*(.config_BFC0FF68))
+  } > config_BFC0FF68
+  .config_BFC0FF6C : {
+    KEEP(*(.config_BFC0FF6C))
+  } > config_BFC0FF6C
+  .config_BFC0FF70 : {
+    KEEP(*(.config_BFC0FF70))
+  } > config_BFC0FF70
+  .config_BFC0FF74 : {
+    KEEP(*(.config_BFC0FF74))
+  } > config_BFC0FF74
+  .config_BFC0FF78 : {
+    KEEP(*(.config_BFC0FF78))
+  } > config_BFC0FF78
+  .config_BFC0FF7C : {
+    KEEP(*(.config_BFC0FF7C))
+  } > config_BFC0FF7C
+  .config_BFC0FFC0 : {
+    KEEP(*(.config_BFC0FFC0))
+  } > config_BFC0FFC0
+  .config_BFC0FFC4 : {
+    KEEP(*(.config_BFC0FFC4))
+  } > config_BFC0FFC4
+  .config_BFC0FFC8 : {
+    KEEP(*(.config_BFC0FFC8))
+  } > config_BFC0FFC8
+  .config_BFC0FFCC : {
+    KEEP(*(.config_BFC0FFCC))
+  } > config_BFC0FFCC
+  .config_BFC0FFD0 : {
+    KEEP(*(.config_BFC0FFD0))
+  } > config_BFC0FFD0
+  .config_BFC0FFD4 : {
+    KEEP(*(.config_BFC0FFD4))
+  } > config_BFC0FFD4
+  .config_BFC0FFD8 : {
+    KEEP(*(.config_BFC0FFD8))
+  } > config_BFC0FFD8
+  .config_BFC0FFDC : {
+    KEEP(*(.config_BFC0FFDC))
+  } > config_BFC0FFDC
+  .config_BFC0FFE0 : {
+    KEEP(*(.config_BFC0FFE0))
+  } > config_BFC0FFE0
+  .config_BFC0FFE4 : {
+    KEEP(*(.config_BFC0FFE4))
+  } > config_BFC0FFE4
+  .config_BFC0FFE8 : {
+    KEEP(*(.config_BFC0FFE8))
+  } > config_BFC0FFE8
+  .config_BFC0FFEC : {
+    KEEP(*(.config_BFC0FFEC))
+  } > config_BFC0FFEC
+  .config_BFC0FFF0 : {
+    KEEP(*(.config_BFC0FFF0))
+  } > config_BFC0FFF0
+  .config_BFC0FFF4 : {
+    KEEP(*(.config_BFC0FFF4))
+  } > config_BFC0FFF4
+  .config_BFC0FFF8 : {
+    KEEP(*(.config_BFC0FFF8))
+  } > config_BFC0FFF8
+  .config_BFC0FFFC : {
+    KEEP(*(.config_BFC0FFFC))
+  } > config_BFC0FFFC
+  .config_BFC2FF40 : {
+    KEEP(*(.config_BFC2FF40))
+  } > config_BFC2FF40
+  .config_BFC2FF44 : {
+    KEEP(*(.config_BFC2FF44))
+  } > config_BFC2FF44
+  .config_BFC2FF48 : {
+    KEEP(*(.config_BFC2FF48))
+  } > config_BFC2FF48
+  .config_BFC2FF4C : {
+    KEEP(*(.config_BFC2FF4C))
+  } > config_BFC2FF4C
+  .config_BFC2FF50 : {
+    KEEP(*(.config_BFC2FF50))
+  } > config_BFC2FF50
+  .config_BFC2FF54 : {
+    KEEP(*(.config_BFC2FF54))
+  } > config_BFC2FF54
+  .config_BFC2FF58 : {
+    KEEP(*(.config_BFC2FF58))
+  } > config_BFC2FF58
+  .config_BFC2FF5C : {
+    KEEP(*(.config_BFC2FF5C))
+  } > config_BFC2FF5C
+  .config_BFC2FF60 : {
+    KEEP(*(.config_BFC2FF60))
+  } > config_BFC2FF60
+  .config_BFC2FF64 : {
+    KEEP(*(.config_BFC2FF64))
+  } > config_BFC2FF64
+  .config_BFC2FF68 : {
+    KEEP(*(.config_BFC2FF68))
+  } > config_BFC2FF68
+  .config_BFC2FF6C : {
+    KEEP(*(.config_BFC2FF6C))
+  } > config_BFC2FF6C
+  .config_BFC2FF70 : {
+    KEEP(*(.config_BFC2FF70))
+  } > config_BFC2FF70
+  .config_BFC2FF74 : {
+    KEEP(*(.config_BFC2FF74))
+  } > config_BFC2FF74
+  .config_BFC2FF78 : {
+    KEEP(*(.config_BFC2FF78))
+  } > config_BFC2FF78
+  .config_BFC2FF7C : {
+    KEEP(*(.config_BFC2FF7C))
+  } > config_BFC2FF7C
+  .config_BFC2FFC0 : {
+    KEEP(*(.config_BFC2FFC0))
+  } > config_BFC2FFC0
+  .config_BFC2FFC4 : {
+    KEEP(*(.config_BFC2FFC4))
+  } > config_BFC2FFC4
+  .config_BFC2FFC8 : {
+    KEEP(*(.config_BFC2FFC8))
+  } > config_BFC2FFC8
+  .config_BFC2FFCC : {
+    KEEP(*(.config_BFC2FFCC))
+  } > config_BFC2FFCC
+  .config_BFC2FFD0 : {
+    KEEP(*(.config_BFC2FFD0))
+  } > config_BFC2FFD0
+  .config_BFC2FFD4 : {
+    KEEP(*(.config_BFC2FFD4))
+  } > config_BFC2FFD4
+  .config_BFC2FFD8 : {
+    KEEP(*(.config_BFC2FFD8))
+  } > config_BFC2FFD8
+  .config_BFC2FFDC : {
+    KEEP(*(.config_BFC2FFDC))
+  } > config_BFC2FFDC
+  .config_BFC2FFE0 : {
+    KEEP(*(.config_BFC2FFE0))
+  } > config_BFC2FFE0
+  .config_BFC2FFE4 : {
+    KEEP(*(.config_BFC2FFE4))
+  } > config_BFC2FFE4
+  .config_BFC2FFE8 : {
+    KEEP(*(.config_BFC2FFE8))
+  } > config_BFC2FFE8
+  .config_BFC2FFEC : {
+    KEEP(*(.config_BFC2FFEC))
+  } > config_BFC2FFEC
+  .config_BFC2FFF0 : {
+    KEEP(*(.config_BFC2FFF0))
+  } > config_BFC2FFF0
+  .config_BFC2FFF4 : {
+    KEEP(*(.config_BFC2FFF4))
+  } > config_BFC2FFF4
+  .config_BFC2FFF8 : {
+    KEEP(*(.config_BFC2FFF8))
+  } > config_BFC2FFF8
+  .config_BFC2FFFC : {
+    KEEP(*(.config_BFC2FFFC))
+  } > config_BFC2FFFC
+  .config_BFC4FF40 : {
+    KEEP(*(.config_BFC4FF40))
+  } > config_BFC4FF40
+  .config_BFC4FF44 : {
+    KEEP(*(.config_BFC4FF44))
+  } > config_BFC4FF44
+  .config_BFC4FF48 : {
+    KEEP(*(.config_BFC4FF48))
+  } > config_BFC4FF48
+  .config_BFC4FF4C : {
+    KEEP(*(.config_BFC4FF4C))
+  } > config_BFC4FF4C
+  .config_BFC4FF50 : {
+    KEEP(*(.config_BFC4FF50))
+  } > config_BFC4FF50
+  .config_BFC4FF54 : {
+    KEEP(*(.config_BFC4FF54))
+  } > config_BFC4FF54
+  .config_BFC4FF58 : {
+    KEEP(*(.config_BFC4FF58))
+  } > config_BFC4FF58
+  .config_BFC4FF5C : {
+    KEEP(*(.config_BFC4FF5C))
+  } > config_BFC4FF5C
+  .config_BFC4FF60 : {
+    KEEP(*(.config_BFC4FF60))
+  } > config_BFC4FF60
+  .config_BFC4FF64 : {
+    KEEP(*(.config_BFC4FF64))
+  } > config_BFC4FF64
+  .config_BFC4FF68 : {
+    KEEP(*(.config_BFC4FF68))
+  } > config_BFC4FF68
+  .config_BFC4FF6C : {
+    KEEP(*(.config_BFC4FF6C))
+  } > config_BFC4FF6C
+  .config_BFC4FF70 : {
+    KEEP(*(.config_BFC4FF70))
+  } > config_BFC4FF70
+  .config_BFC4FF74 : {
+    KEEP(*(.config_BFC4FF74))
+  } > config_BFC4FF74
+  .config_BFC4FF78 : {
+    KEEP(*(.config_BFC4FF78))
+  } > config_BFC4FF78
+  .config_BFC4FF7C : {
+    KEEP(*(.config_BFC4FF7C))
+  } > config_BFC4FF7C
+  .config_BFC4FFC0 : {
+    KEEP(*(.config_BFC4FFC0))
+  } > config_BFC4FFC0
+  .config_BFC4FFC4 : {
+    KEEP(*(.config_BFC4FFC4))
+  } > config_BFC4FFC4
+  .config_BFC4FFC8 : {
+    KEEP(*(.config_BFC4FFC8))
+  } > config_BFC4FFC8
+  .config_BFC4FFCC : {
+    KEEP(*(.config_BFC4FFCC))
+  } > config_BFC4FFCC
+  .config_BFC4FFD0 : {
+    KEEP(*(.config_BFC4FFD0))
+  } > config_BFC4FFD0
+  .config_BFC4FFD4 : {
+    KEEP(*(.config_BFC4FFD4))
+  } > config_BFC4FFD4
+  .config_BFC4FFD8 : {
+    KEEP(*(.config_BFC4FFD8))
+  } > config_BFC4FFD8
+  .config_BFC4FFDC : {
+    KEEP(*(.config_BFC4FFDC))
+  } > config_BFC4FFDC
+  .config_BFC4FFE0 : {
+    KEEP(*(.config_BFC4FFE0))
+  } > config_BFC4FFE0
+  .config_BFC4FFE4 : {
+    KEEP(*(.config_BFC4FFE4))
+  } > config_BFC4FFE4
+  .config_BFC4FFE8 : {
+    KEEP(*(.config_BFC4FFE8))
+  } > config_BFC4FFE8
+  .config_BFC4FFEC : {
+    KEEP(*(.config_BFC4FFEC))
+  } > config_BFC4FFEC
+  .config_BFC4FFF0 : {
+    KEEP(*(.config_BFC4FFF0))
+  } > config_BFC4FFF0
+  .config_BFC4FFF4 : {
+    KEEP(*(.config_BFC4FFF4))
+  } > config_BFC4FFF4
+  .config_BFC4FFF8 : {
+    KEEP(*(.config_BFC4FFF8))
+  } > config_BFC4FFF8
+  .config_BFC4FFFC : {
+    KEEP(*(.config_BFC4FFFC))
+  } > config_BFC4FFFC
+  .config_BFC54000 : {
+    KEEP(*(.config_BFC54000))
+  } > config_BFC54000
+  .config_BFC54004 : {
+    KEEP(*(.config_BFC54004))
+  } > config_BFC54004
+  .config_BFC54008 : {
+    KEEP(*(.config_BFC54008))
+  } > config_BFC54008
+  .config_BFC5400C : {
+    KEEP(*(.config_BFC5400C))
+  } > config_BFC5400C
+  .config_BFC54010 : {
+    KEEP(*(.config_BFC54010))
+  } > config_BFC54010
+  .config_BFC5401C : {
+    KEEP(*(.config_BFC5401C))
+  } > config_BFC5401C
+  .config_BFC54020 : {
+    KEEP(*(.config_BFC54020))
+  } > config_BFC54020
+  .config_BFC54024 : {
+    KEEP(*(.config_BFC54024))
+  } > config_BFC54024
+  .config_BFC6FF40 : {
+    KEEP(*(.config_BFC6FF40))
+  } > config_BFC6FF40
+  .config_BFC6FF44 : {
+    KEEP(*(.config_BFC6FF44))
+  } > config_BFC6FF44
+  .config_BFC6FF48 : {
+    KEEP(*(.config_BFC6FF48))
+  } > config_BFC6FF48
+  .config_BFC6FF4C : {
+    KEEP(*(.config_BFC6FF4C))
+  } > config_BFC6FF4C
+  .config_BFC6FF50 : {
+    KEEP(*(.config_BFC6FF50))
+  } > config_BFC6FF50
+  .config_BFC6FF54 : {
+    KEEP(*(.config_BFC6FF54))
+  } > config_BFC6FF54
+  .config_BFC6FF58 : {
+    KEEP(*(.config_BFC6FF58))
+  } > config_BFC6FF58
+  .config_BFC6FF5C : {
+    KEEP(*(.config_BFC6FF5C))
+  } > config_BFC6FF5C
+  .config_BFC6FF60 : {
+    KEEP(*(.config_BFC6FF60))
+  } > config_BFC6FF60
+  .config_BFC6FF64 : {
+    KEEP(*(.config_BFC6FF64))
+  } > config_BFC6FF64
+  .config_BFC6FF68 : {
+    KEEP(*(.config_BFC6FF68))
+  } > config_BFC6FF68
+  .config_BFC6FF6C : {
+    KEEP(*(.config_BFC6FF6C))
+  } > config_BFC6FF6C
+  .config_BFC6FF70 : {
+    KEEP(*(.config_BFC6FF70))
+  } > config_BFC6FF70
+  .config_BFC6FF74 : {
+    KEEP(*(.config_BFC6FF74))
+  } > config_BFC6FF74
+  .config_BFC6FF78 : {
+    KEEP(*(.config_BFC6FF78))
+  } > config_BFC6FF78
+  .config_BFC6FF7C : {
+    KEEP(*(.config_BFC6FF7C))
+  } > config_BFC6FF7C
+  .config_BFC6FFC0 : {
+    KEEP(*(.config_BFC6FFC0))
+  } > config_BFC6FFC0
+  .config_BFC6FFC4 : {
+    KEEP(*(.config_BFC6FFC4))
+  } > config_BFC6FFC4
+  .config_BFC6FFC8 : {
+    KEEP(*(.config_BFC6FFC8))
+  } > config_BFC6FFC8
+  .config_BFC6FFCC : {
+    KEEP(*(.config_BFC6FFCC))
+  } > config_BFC6FFCC
+  .config_BFC6FFD0 : {
+    KEEP(*(.config_BFC6FFD0))
+  } > config_BFC6FFD0
+  .config_BFC6FFD4 : {
+    KEEP(*(.config_BFC6FFD4))
+  } > config_BFC6FFD4
+  .config_BFC6FFD8 : {
+    KEEP(*(.config_BFC6FFD8))
+  } > config_BFC6FFD8
+  .config_BFC6FFDC : {
+    KEEP(*(.config_BFC6FFDC))
+  } > config_BFC6FFDC
+  .config_BFC6FFE0 : {
+    KEEP(*(.config_BFC6FFE0))
+  } > config_BFC6FFE0
+  .config_BFC6FFE4 : {
+    KEEP(*(.config_BFC6FFE4))
+  } > config_BFC6FFE4
+  .config_BFC6FFE8 : {
+    KEEP(*(.config_BFC6FFE8))
+  } > config_BFC6FFE8
+  .config_BFC6FFEC : {
+    KEEP(*(.config_BFC6FFEC))
+  } > config_BFC6FFEC
+  .config_BFC6FFF0 : {
+    KEEP(*(.config_BFC6FFF0))
+  } > config_BFC6FFF0
+  .config_BFC6FFF4 : {
+    KEEP(*(.config_BFC6FFF4))
+  } > config_BFC6FFF4
+  .config_BFC6FFF8 : {
+    KEEP(*(.config_BFC6FFF8))
+  } > config_BFC6FFF8
+  .config_BFC6FFFC : {
+    KEEP(*(.config_BFC6FFFC))
+  } > config_BFC6FFFC
+}
+SECTIONS
+{
+  /* Boot Sections */
+  .reset _RESET_ADDR :
+  {
+    KEEP(*(.reset))
+    KEEP(*(.reset.startup))
+  } > kseg1_boot_mem
+  .bev_excpt _BEV_EXCPT_ADDR :
+  {
+    KEEP(*(.bev_handler))
+  } > kseg1_boot_mem
+  .cache_init :
+  {
+    *(.cache_init)
+    *(.cache_init.*)
+  } > kseg1_boot_mem_4B0
+
+  .simple_tlb_refill_excpt _SIMPLE_TLB_REFILL_EXCPT_ADDR :
+  {
+    KEEP(*(.simple_tlb_refill_vector))
+  } > kseg0_program_mem
+  .cache_err_excpt _CACHE_ERR_EXCPT_ADDR :
+  {
+    KEEP(*(.cache_err_vector))
+  } > kseg0_program_mem
+  .app_excpt _GEN_EXCPT_ADDR :
+  {
+    KEEP(*(.gen_handler))
+  } > kseg0_program_mem
+
+  /* Interrupt vector table with vector offsets */
+  .vectors _ebase_address + 0x200 :
+  {
+    /*  Symbol __vector_offset_n points to .vector_n if it exists, 
+     *  otherwise points to the default handler. The
+     *  vector_offset_init.o module then provides a .data section
+     *  containing values used to initialize the vector-offset SFRs
+     *  in the crt0 startup code.
+     */
+    . = ALIGN(4) ;
+    __vector_offset_0 = (DEFINED(__vector_dispatch_0) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_0))
+    . = ALIGN(4) ;
+    __vector_offset_1 = (DEFINED(__vector_dispatch_1) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_1))
+    . = ALIGN(4) ;
+    __vector_offset_2 = (DEFINED(__vector_dispatch_2) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_2))
+    . = ALIGN(4) ;
+    __vector_offset_3 = (DEFINED(__vector_dispatch_3) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_3))
+    . = ALIGN(4) ;
+    __vector_offset_4 = (DEFINED(__vector_dispatch_4) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_4))
+    . = ALIGN(4) ;
+    __vector_offset_5 = (DEFINED(__vector_dispatch_5) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_5))
+    . = ALIGN(4) ;
+    __vector_offset_6 = (DEFINED(__vector_dispatch_6) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_6))
+    . = ALIGN(4) ;
+    __vector_offset_7 = (DEFINED(__vector_dispatch_7) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_7))
+    . = ALIGN(4) ;
+    __vector_offset_8 = (DEFINED(__vector_dispatch_8) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_8))
+    . = ALIGN(4) ;
+    __vector_offset_9 = (DEFINED(__vector_dispatch_9) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_9))
+    . = ALIGN(4) ;
+    __vector_offset_10 = (DEFINED(__vector_dispatch_10) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_10))
+    . = ALIGN(4) ;
+    __vector_offset_11 = (DEFINED(__vector_dispatch_11) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_11))
+    . = ALIGN(4) ;
+    __vector_offset_12 = (DEFINED(__vector_dispatch_12) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_12))
+    . = ALIGN(4) ;
+    __vector_offset_13 = (DEFINED(__vector_dispatch_13) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_13))
+    . = ALIGN(4) ;
+    __vector_offset_14 = (DEFINED(__vector_dispatch_14) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_14))
+    . = ALIGN(4) ;
+    __vector_offset_15 = (DEFINED(__vector_dispatch_15) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_15))
+    . = ALIGN(4) ;
+    __vector_offset_16 = (DEFINED(__vector_dispatch_16) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_16))
+    . = ALIGN(4) ;
+    __vector_offset_17 = (DEFINED(__vector_dispatch_17) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_17))
+    . = ALIGN(4) ;
+    __vector_offset_18 = (DEFINED(__vector_dispatch_18) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_18))
+    . = ALIGN(4) ;
+    __vector_offset_19 = (DEFINED(__vector_dispatch_19) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_19))
+    . = ALIGN(4) ;
+    __vector_offset_20 = (DEFINED(__vector_dispatch_20) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_20))
+    . = ALIGN(4) ;
+    __vector_offset_21 = (DEFINED(__vector_dispatch_21) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_21))
+    . = ALIGN(4) ;
+    __vector_offset_22 = (DEFINED(__vector_dispatch_22) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_22))
+    . = ALIGN(4) ;
+    __vector_offset_23 = (DEFINED(__vector_dispatch_23) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_23))
+    . = ALIGN(4) ;
+    __vector_offset_24 = (DEFINED(__vector_dispatch_24) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_24))
+    . = ALIGN(4) ;
+    __vector_offset_25 = (DEFINED(__vector_dispatch_25) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_25))
+    . = ALIGN(4) ;
+    __vector_offset_26 = (DEFINED(__vector_dispatch_26) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_26))
+    . = ALIGN(4) ;
+    __vector_offset_27 = (DEFINED(__vector_dispatch_27) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_27))
+    . = ALIGN(4) ;
+    __vector_offset_28 = (DEFINED(__vector_dispatch_28) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_28))
+    . = ALIGN(4) ;
+    __vector_offset_29 = (DEFINED(__vector_dispatch_29) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_29))
+    . = ALIGN(4) ;
+    __vector_offset_30 = (DEFINED(__vector_dispatch_30) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_30))
+    . = ALIGN(4) ;
+    __vector_offset_31 = (DEFINED(__vector_dispatch_31) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_31))
+    . = ALIGN(4) ;
+    __vector_offset_32 = (DEFINED(__vector_dispatch_32) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_32))
+    . = ALIGN(4) ;
+    __vector_offset_33 = (DEFINED(__vector_dispatch_33) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_33))
+    . = ALIGN(4) ;
+    __vector_offset_34 = (DEFINED(__vector_dispatch_34) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_34))
+    . = ALIGN(4) ;
+    __vector_offset_35 = (DEFINED(__vector_dispatch_35) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_35))
+    . = ALIGN(4) ;
+    __vector_offset_36 = (DEFINED(__vector_dispatch_36) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_36))
+    . = ALIGN(4) ;
+    __vector_offset_37 = (DEFINED(__vector_dispatch_37) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_37))
+    . = ALIGN(4) ;
+    __vector_offset_38 = (DEFINED(__vector_dispatch_38) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_38))
+    . = ALIGN(4) ;
+    __vector_offset_39 = (DEFINED(__vector_dispatch_39) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_39))
+    . = ALIGN(4) ;
+    __vector_offset_40 = (DEFINED(__vector_dispatch_40) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_40))
+    . = ALIGN(4) ;
+    __vector_offset_41 = (DEFINED(__vector_dispatch_41) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_41))
+    . = ALIGN(4) ;
+    __vector_offset_42 = (DEFINED(__vector_dispatch_42) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_42))
+    . = ALIGN(4) ;
+    __vector_offset_43 = (DEFINED(__vector_dispatch_43) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_43))
+    . = ALIGN(4) ;
+    __vector_offset_44 = (DEFINED(__vector_dispatch_44) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_44))
+    . = ALIGN(4) ;
+    __vector_offset_45 = (DEFINED(__vector_dispatch_45) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_45))
+    . = ALIGN(4) ;
+    __vector_offset_46 = (DEFINED(__vector_dispatch_46) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_46))
+    . = ALIGN(4) ;
+    __vector_offset_47 = (DEFINED(__vector_dispatch_47) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_47))
+    . = ALIGN(4) ;
+    __vector_offset_48 = (DEFINED(__vector_dispatch_48) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_48))
+    . = ALIGN(4) ;
+    __vector_offset_49 = (DEFINED(__vector_dispatch_49) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_49))
+    . = ALIGN(4) ;
+    __vector_offset_50 = (DEFINED(__vector_dispatch_50) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_50))
+    . = ALIGN(4) ;
+    __vector_offset_51 = (DEFINED(__vector_dispatch_51) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_51))
+    . = ALIGN(4) ;
+    __vector_offset_52 = (DEFINED(__vector_dispatch_52) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_52))
+    . = ALIGN(4) ;
+    __vector_offset_53 = (DEFINED(__vector_dispatch_53) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_53))
+    . = ALIGN(4) ;
+    __vector_offset_54 = (DEFINED(__vector_dispatch_54) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_54))
+    . = ALIGN(4) ;
+    __vector_offset_55 = (DEFINED(__vector_dispatch_55) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_55))
+    . = ALIGN(4) ;
+    __vector_offset_56 = (DEFINED(__vector_dispatch_56) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_56))
+    . = ALIGN(4) ;
+    __vector_offset_57 = (DEFINED(__vector_dispatch_57) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_57))
+    . = ALIGN(4) ;
+    __vector_offset_58 = (DEFINED(__vector_dispatch_58) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_58))
+    . = ALIGN(4) ;
+    __vector_offset_59 = (DEFINED(__vector_dispatch_59) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_59))
+    . = ALIGN(4) ;
+    __vector_offset_60 = (DEFINED(__vector_dispatch_60) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_60))
+    . = ALIGN(4) ;
+    __vector_offset_61 = (DEFINED(__vector_dispatch_61) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_61))
+    . = ALIGN(4) ;
+    __vector_offset_62 = (DEFINED(__vector_dispatch_62) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_62))
+    . = ALIGN(4) ;
+    __vector_offset_63 = (DEFINED(__vector_dispatch_63) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_63))
+    . = ALIGN(4) ;
+    __vector_offset_64 = (DEFINED(__vector_dispatch_64) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_64))
+    . = ALIGN(4) ;
+    __vector_offset_65 = (DEFINED(__vector_dispatch_65) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_65))
+    . = ALIGN(4) ;
+    __vector_offset_66 = (DEFINED(__vector_dispatch_66) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_66))
+    . = ALIGN(4) ;
+    __vector_offset_67 = (DEFINED(__vector_dispatch_67) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_67))
+    . = ALIGN(4) ;
+    __vector_offset_68 = (DEFINED(__vector_dispatch_68) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_68))
+    . = ALIGN(4) ;
+    __vector_offset_69 = (DEFINED(__vector_dispatch_69) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_69))
+    . = ALIGN(4) ;
+    __vector_offset_70 = (DEFINED(__vector_dispatch_70) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_70))
+    . = ALIGN(4) ;
+    __vector_offset_71 = (DEFINED(__vector_dispatch_71) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_71))
+    . = ALIGN(4) ;
+    __vector_offset_72 = (DEFINED(__vector_dispatch_72) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_72))
+    . = ALIGN(4) ;
+    __vector_offset_73 = (DEFINED(__vector_dispatch_73) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_73))
+    . = ALIGN(4) ;
+    __vector_offset_74 = (DEFINED(__vector_dispatch_74) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_74))
+    . = ALIGN(4) ;
+    __vector_offset_75 = (DEFINED(__vector_dispatch_75) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_75))
+    . = ALIGN(4) ;
+    __vector_offset_76 = (DEFINED(__vector_dispatch_76) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_76))
+    . = ALIGN(4) ;
+    __vector_offset_77 = (DEFINED(__vector_dispatch_77) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_77))
+    . = ALIGN(4) ;
+    __vector_offset_78 = (DEFINED(__vector_dispatch_78) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_78))
+    . = ALIGN(4) ;
+    __vector_offset_79 = (DEFINED(__vector_dispatch_79) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_79))
+    . = ALIGN(4) ;
+    __vector_offset_80 = (DEFINED(__vector_dispatch_80) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_80))
+    . = ALIGN(4) ;
+    __vector_offset_81 = (DEFINED(__vector_dispatch_81) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_81))
+    . = ALIGN(4) ;
+    __vector_offset_82 = (DEFINED(__vector_dispatch_82) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_82))
+    . = ALIGN(4) ;
+    __vector_offset_83 = (DEFINED(__vector_dispatch_83) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_83))
+    . = ALIGN(4) ;
+    __vector_offset_84 = (DEFINED(__vector_dispatch_84) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_84))
+    . = ALIGN(4) ;
+    __vector_offset_85 = (DEFINED(__vector_dispatch_85) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_85))
+    . = ALIGN(4) ;
+    __vector_offset_86 = (DEFINED(__vector_dispatch_86) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_86))
+    . = ALIGN(4) ;
+    __vector_offset_87 = (DEFINED(__vector_dispatch_87) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_87))
+    . = ALIGN(4) ;
+    __vector_offset_88 = (DEFINED(__vector_dispatch_88) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_88))
+    . = ALIGN(4) ;
+    __vector_offset_89 = (DEFINED(__vector_dispatch_89) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_89))
+    . = ALIGN(4) ;
+    __vector_offset_90 = (DEFINED(__vector_dispatch_90) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_90))
+    . = ALIGN(4) ;
+    __vector_offset_91 = (DEFINED(__vector_dispatch_91) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_91))
+    . = ALIGN(4) ;
+    __vector_offset_92 = (DEFINED(__vector_dispatch_92) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_92))
+    . = ALIGN(4) ;
+    __vector_offset_93 = (DEFINED(__vector_dispatch_93) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_93))
+    . = ALIGN(4) ;
+    __vector_offset_94 = (DEFINED(__vector_dispatch_94) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_94))
+    . = ALIGN(4) ;
+    __vector_offset_95 = (DEFINED(__vector_dispatch_95) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_95))
+    . = ALIGN(4) ;
+    __vector_offset_96 = (DEFINED(__vector_dispatch_96) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_96))
+    . = ALIGN(4) ;
+    __vector_offset_97 = (DEFINED(__vector_dispatch_97) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_97))
+    . = ALIGN(4) ;
+    __vector_offset_98 = (DEFINED(__vector_dispatch_98) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_98))
+    . = ALIGN(4) ;
+    __vector_offset_99 = (DEFINED(__vector_dispatch_99) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_99))
+    . = ALIGN(4) ;
+    __vector_offset_100 = (DEFINED(__vector_dispatch_100) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_100))
+    . = ALIGN(4) ;
+    __vector_offset_101 = (DEFINED(__vector_dispatch_101) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_101))
+    . = ALIGN(4) ;
+    __vector_offset_102 = (DEFINED(__vector_dispatch_102) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_102))
+    . = ALIGN(4) ;
+    __vector_offset_103 = (DEFINED(__vector_dispatch_103) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_103))
+    . = ALIGN(4) ;
+    __vector_offset_104 = (DEFINED(__vector_dispatch_104) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_104))
+    . = ALIGN(4) ;
+    __vector_offset_105 = (DEFINED(__vector_dispatch_105) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_105))
+    . = ALIGN(4) ;
+    __vector_offset_106 = (DEFINED(__vector_dispatch_106) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_106))
+    . = ALIGN(4) ;
+    __vector_offset_107 = (DEFINED(__vector_dispatch_107) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_107))
+    . = ALIGN(4) ;
+    __vector_offset_108 = (DEFINED(__vector_dispatch_108) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_108))
+    . = ALIGN(4) ;
+    __vector_offset_109 = (DEFINED(__vector_dispatch_109) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_109))
+    . = ALIGN(4) ;
+    __vector_offset_110 = (DEFINED(__vector_dispatch_110) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_110))
+    . = ALIGN(4) ;
+    __vector_offset_111 = (DEFINED(__vector_dispatch_111) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_111))
+    . = ALIGN(4) ;
+    __vector_offset_112 = (DEFINED(__vector_dispatch_112) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_112))
+    . = ALIGN(4) ;
+    __vector_offset_113 = (DEFINED(__vector_dispatch_113) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_113))
+    . = ALIGN(4) ;
+    __vector_offset_114 = (DEFINED(__vector_dispatch_114) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_114))
+    . = ALIGN(4) ;
+    __vector_offset_115 = (DEFINED(__vector_dispatch_115) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_115))
+    . = ALIGN(4) ;
+    __vector_offset_116 = (DEFINED(__vector_dispatch_116) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_116))
+    . = ALIGN(4) ;
+    __vector_offset_117 = (DEFINED(__vector_dispatch_117) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_117))
+    . = ALIGN(4) ;
+    __vector_offset_118 = (DEFINED(__vector_dispatch_118) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_118))
+    . = ALIGN(4) ;
+    __vector_offset_119 = (DEFINED(__vector_dispatch_119) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_119))
+    . = ALIGN(4) ;
+    __vector_offset_120 = (DEFINED(__vector_dispatch_120) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_120))
+    . = ALIGN(4) ;
+    __vector_offset_121 = (DEFINED(__vector_dispatch_121) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_121))
+    . = ALIGN(4) ;
+    __vector_offset_122 = (DEFINED(__vector_dispatch_122) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_122))
+    . = ALIGN(4) ;
+    __vector_offset_123 = (DEFINED(__vector_dispatch_123) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_123))
+    . = ALIGN(4) ;
+    __vector_offset_124 = (DEFINED(__vector_dispatch_124) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_124))
+    . = ALIGN(4) ;
+    __vector_offset_125 = (DEFINED(__vector_dispatch_125) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_125))
+    . = ALIGN(4) ;
+    __vector_offset_126 = (DEFINED(__vector_dispatch_126) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_126))
+    . = ALIGN(4) ;
+    __vector_offset_127 = (DEFINED(__vector_dispatch_127) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_127))
+    . = ALIGN(4) ;
+    __vector_offset_128 = (DEFINED(__vector_dispatch_128) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_128))
+    . = ALIGN(4) ;
+    __vector_offset_129 = (DEFINED(__vector_dispatch_129) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_129))
+    . = ALIGN(4) ;
+    __vector_offset_130 = (DEFINED(__vector_dispatch_130) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_130))
+    . = ALIGN(4) ;
+    __vector_offset_131 = (DEFINED(__vector_dispatch_131) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_131))
+    . = ALIGN(4) ;
+    __vector_offset_132 = (DEFINED(__vector_dispatch_132) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_132))
+    . = ALIGN(4) ;
+    __vector_offset_133 = (DEFINED(__vector_dispatch_133) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_133))
+    . = ALIGN(4) ;
+    __vector_offset_134 = (DEFINED(__vector_dispatch_134) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_134))
+    . = ALIGN(4) ;
+    __vector_offset_135 = (DEFINED(__vector_dispatch_135) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_135))
+    . = ALIGN(4) ;
+    __vector_offset_136 = (DEFINED(__vector_dispatch_136) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_136))
+    . = ALIGN(4) ;
+    __vector_offset_137 = (DEFINED(__vector_dispatch_137) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_137))
+    . = ALIGN(4) ;
+    __vector_offset_138 = (DEFINED(__vector_dispatch_138) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_138))
+    . = ALIGN(4) ;
+    __vector_offset_139 = (DEFINED(__vector_dispatch_139) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_139))
+    . = ALIGN(4) ;
+    __vector_offset_140 = (DEFINED(__vector_dispatch_140) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_140))
+    . = ALIGN(4) ;
+    __vector_offset_141 = (DEFINED(__vector_dispatch_141) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_141))
+    . = ALIGN(4) ;
+    __vector_offset_142 = (DEFINED(__vector_dispatch_142) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_142))
+    . = ALIGN(4) ;
+    __vector_offset_143 = (DEFINED(__vector_dispatch_143) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_143))
+    . = ALIGN(4) ;
+    __vector_offset_144 = (DEFINED(__vector_dispatch_144) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_144))
+    . = ALIGN(4) ;
+    __vector_offset_145 = (DEFINED(__vector_dispatch_145) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_145))
+    . = ALIGN(4) ;
+    __vector_offset_146 = (DEFINED(__vector_dispatch_146) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_146))
+    . = ALIGN(4) ;
+    __vector_offset_147 = (DEFINED(__vector_dispatch_147) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_147))
+    . = ALIGN(4) ;
+    __vector_offset_148 = (DEFINED(__vector_dispatch_148) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_148))
+    . = ALIGN(4) ;
+    __vector_offset_149 = (DEFINED(__vector_dispatch_149) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_149))
+    . = ALIGN(4) ;
+    __vector_offset_150 = (DEFINED(__vector_dispatch_150) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_150))
+    . = ALIGN(4) ;
+    __vector_offset_151 = (DEFINED(__vector_dispatch_151) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_151))
+    . = ALIGN(4) ;
+    __vector_offset_152 = (DEFINED(__vector_dispatch_152) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_152))
+    . = ALIGN(4) ;
+    __vector_offset_153 = (DEFINED(__vector_dispatch_153) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_153))
+    . = ALIGN(4) ;
+    __vector_offset_154 = (DEFINED(__vector_dispatch_154) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_154))
+    . = ALIGN(4) ;
+    __vector_offset_155 = (DEFINED(__vector_dispatch_155) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_155))
+    . = ALIGN(4) ;
+    __vector_offset_156 = (DEFINED(__vector_dispatch_156) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_156))
+    . = ALIGN(4) ;
+    __vector_offset_157 = (DEFINED(__vector_dispatch_157) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_157))
+    . = ALIGN(4) ;
+    __vector_offset_158 = (DEFINED(__vector_dispatch_158) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_158))
+    . = ALIGN(4) ;
+    __vector_offset_159 = (DEFINED(__vector_dispatch_159) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_159))
+    . = ALIGN(4) ;
+    __vector_offset_160 = (DEFINED(__vector_dispatch_160) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_160))
+    . = ALIGN(4) ;
+    __vector_offset_161 = (DEFINED(__vector_dispatch_161) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_161))
+    . = ALIGN(4) ;
+    __vector_offset_162 = (DEFINED(__vector_dispatch_162) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_162))
+    . = ALIGN(4) ;
+    __vector_offset_163 = (DEFINED(__vector_dispatch_163) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_163))
+    . = ALIGN(4) ;
+    __vector_offset_164 = (DEFINED(__vector_dispatch_164) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_164))
+    . = ALIGN(4) ;
+    __vector_offset_165 = (DEFINED(__vector_dispatch_165) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_165))
+    . = ALIGN(4) ;
+    __vector_offset_166 = (DEFINED(__vector_dispatch_166) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_166))
+    . = ALIGN(4) ;
+    __vector_offset_167 = (DEFINED(__vector_dispatch_167) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_167))
+    . = ALIGN(4) ;
+    __vector_offset_168 = (DEFINED(__vector_dispatch_168) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_168))
+    . = ALIGN(4) ;
+    __vector_offset_169 = (DEFINED(__vector_dispatch_169) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_169))
+    . = ALIGN(4) ;
+    __vector_offset_170 = (DEFINED(__vector_dispatch_170) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_170))
+    . = ALIGN(4) ;
+    __vector_offset_171 = (DEFINED(__vector_dispatch_171) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_171))
+    . = ALIGN(4) ;
+    __vector_offset_172 = (DEFINED(__vector_dispatch_172) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_172))
+    . = ALIGN(4) ;
+    __vector_offset_173 = (DEFINED(__vector_dispatch_173) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_173))
+    . = ALIGN(4) ;
+    __vector_offset_174 = (DEFINED(__vector_dispatch_174) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_174))
+    . = ALIGN(4) ;
+    __vector_offset_175 = (DEFINED(__vector_dispatch_175) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_175))
+    . = ALIGN(4) ;
+    __vector_offset_176 = (DEFINED(__vector_dispatch_176) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_176))
+    . = ALIGN(4) ;
+    __vector_offset_177 = (DEFINED(__vector_dispatch_177) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_177))
+    . = ALIGN(4) ;
+    __vector_offset_178 = (DEFINED(__vector_dispatch_178) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_178))
+    . = ALIGN(4) ;
+    __vector_offset_179 = (DEFINED(__vector_dispatch_179) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_179))
+    . = ALIGN(4) ;
+    __vector_offset_180 = (DEFINED(__vector_dispatch_180) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_180))
+    . = ALIGN(4) ;
+    __vector_offset_181 = (DEFINED(__vector_dispatch_181) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_181))
+    . = ALIGN(4) ;
+    __vector_offset_182 = (DEFINED(__vector_dispatch_182) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_182))
+    . = ALIGN(4) ;
+    __vector_offset_183 = (DEFINED(__vector_dispatch_183) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_183))
+    . = ALIGN(4) ;
+    __vector_offset_184 = (DEFINED(__vector_dispatch_184) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_184))
+    . = ALIGN(4) ;
+    __vector_offset_185 = (DEFINED(__vector_dispatch_185) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_185))
+    . = ALIGN(4) ;
+    __vector_offset_186 = (DEFINED(__vector_dispatch_186) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_186))
+    . = ALIGN(4) ;
+    __vector_offset_187 = (DEFINED(__vector_dispatch_187) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_187))
+    . = ALIGN(4) ;
+    __vector_offset_188 = (DEFINED(__vector_dispatch_188) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_188))
+    . = ALIGN(4) ;
+    __vector_offset_189 = (DEFINED(__vector_dispatch_189) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_189))
+    . = ALIGN(4) ;
+    __vector_offset_190 = (DEFINED(__vector_dispatch_190) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_190))
+    . = ALIGN(4) ;
+    __vector_offset_191 = (DEFINED(__vector_dispatch_191) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_191))
+    . = ALIGN(4) ;
+    __vector_offset_192 = (DEFINED(__vector_dispatch_192) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_192))
+    . = ALIGN(4) ;
+    __vector_offset_193 = (DEFINED(__vector_dispatch_193) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_193))
+    . = ALIGN(4) ;
+    __vector_offset_194 = (DEFINED(__vector_dispatch_194) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_194))
+    . = ALIGN(4) ;
+    __vector_offset_195 = (DEFINED(__vector_dispatch_195) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_195))
+    . = ALIGN(4) ;
+    __vector_offset_196 = (DEFINED(__vector_dispatch_196) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_196))
+    . = ALIGN(4) ;
+    __vector_offset_197 = (DEFINED(__vector_dispatch_197) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_197))
+    . = ALIGN(4) ;
+    __vector_offset_198 = (DEFINED(__vector_dispatch_198) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_198))
+    . = ALIGN(4) ;
+    __vector_offset_199 = (DEFINED(__vector_dispatch_199) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_199))
+    . = ALIGN(4) ;
+    __vector_offset_200 = (DEFINED(__vector_dispatch_200) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_200))
+    . = ALIGN(4) ;
+    __vector_offset_201 = (DEFINED(__vector_dispatch_201) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_201))
+    . = ALIGN(4) ;
+    __vector_offset_202 = (DEFINED(__vector_dispatch_202) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_202))
+    . = ALIGN(4) ;
+    __vector_offset_203 = (DEFINED(__vector_dispatch_203) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_203))
+    . = ALIGN(4) ;
+    __vector_offset_204 = (DEFINED(__vector_dispatch_204) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_204))
+    . = ALIGN(4) ;
+    __vector_offset_205 = (DEFINED(__vector_dispatch_205) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_205))
+    . = ALIGN(4) ;
+    __vector_offset_206 = (DEFINED(__vector_dispatch_206) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_206))
+    . = ALIGN(4) ;
+    __vector_offset_207 = (DEFINED(__vector_dispatch_207) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_207))
+    . = ALIGN(4) ;
+    __vector_offset_208 = (DEFINED(__vector_dispatch_208) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_208))
+    . = ALIGN(4) ;
+    __vector_offset_209 = (DEFINED(__vector_dispatch_209) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_209))
+    . = ALIGN(4) ;
+    __vector_offset_210 = (DEFINED(__vector_dispatch_210) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_210))
+    . = ALIGN(4) ;
+    __vector_offset_211 = (DEFINED(__vector_dispatch_211) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_211))
+    . = ALIGN(4) ;
+    __vector_offset_212 = (DEFINED(__vector_dispatch_212) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_212))
+    . = ALIGN(4) ;
+    __vector_offset_213 = (DEFINED(__vector_dispatch_213) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_213))
+    . = ALIGN(4) ;
+    __vector_offset_214 = (DEFINED(__vector_dispatch_214) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_214))
+    . = ALIGN(4) ;
+    __vector_offset_215 = (DEFINED(__vector_dispatch_215) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_215))
+    . = ALIGN(4) ;
+    __vector_offset_216 = (DEFINED(__vector_dispatch_216) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_216))
+    . = ALIGN(4) ;
+    __vector_offset_217 = (DEFINED(__vector_dispatch_217) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_217))
+    . = ALIGN(4) ;
+    __vector_offset_218 = (DEFINED(__vector_dispatch_218) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_218))
+    . = ALIGN(4) ;
+    __vector_offset_219 = (DEFINED(__vector_dispatch_219) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_219))
+    . = ALIGN(4) ;
+    __vector_offset_220 = (DEFINED(__vector_dispatch_220) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_220))
+    . = ALIGN(4) ;
+    __vector_offset_221 = (DEFINED(__vector_dispatch_221) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_221))
+    . = ALIGN(4) ;
+    __vector_offset_222 = (DEFINED(__vector_dispatch_222) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_222))
+    . = ALIGN(4) ;
+    __vector_offset_223 = (DEFINED(__vector_dispatch_223) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_223))
+    . = ALIGN(4) ;
+    __vector_offset_224 = (DEFINED(__vector_dispatch_224) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_224))
+    . = ALIGN(4) ;
+    __vector_offset_225 = (DEFINED(__vector_dispatch_225) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_225))
+    . = ALIGN(4) ;
+    __vector_offset_226 = (DEFINED(__vector_dispatch_226) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_226))
+    . = ALIGN(4) ;
+    __vector_offset_227 = (DEFINED(__vector_dispatch_227) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_227))
+    . = ALIGN(4) ;
+    __vector_offset_228 = (DEFINED(__vector_dispatch_228) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_228))
+    . = ALIGN(4) ;
+    __vector_offset_229 = (DEFINED(__vector_dispatch_229) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_229))
+    . = ALIGN(4) ;
+    __vector_offset_230 = (DEFINED(__vector_dispatch_230) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_230))
+    . = ALIGN(4) ;
+    __vector_offset_231 = (DEFINED(__vector_dispatch_231) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_231))
+    . = ALIGN(4) ;
+    __vector_offset_232 = (DEFINED(__vector_dispatch_232) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_232))
+    . = ALIGN(4) ;
+    __vector_offset_233 = (DEFINED(__vector_dispatch_233) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_233))
+    . = ALIGN(4) ;
+    __vector_offset_234 = (DEFINED(__vector_dispatch_234) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_234))
+    . = ALIGN(4) ;
+    __vector_offset_235 = (DEFINED(__vector_dispatch_235) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_235))
+    . = ALIGN(4) ;
+    __vector_offset_236 = (DEFINED(__vector_dispatch_236) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_236))
+    . = ALIGN(4) ;
+    __vector_offset_237 = (DEFINED(__vector_dispatch_237) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_237))
+    . = ALIGN(4) ;
+    __vector_offset_238 = (DEFINED(__vector_dispatch_238) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_238))
+    . = ALIGN(4) ;
+    __vector_offset_239 = (DEFINED(__vector_dispatch_239) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_239))
+    . = ALIGN(4) ;
+    __vector_offset_240 = (DEFINED(__vector_dispatch_240) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_240))
+    . = ALIGN(4) ;
+    __vector_offset_241 = (DEFINED(__vector_dispatch_241) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_241))
+    . = ALIGN(4) ;
+    __vector_offset_242 = (DEFINED(__vector_dispatch_242) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_242))
+    . = ALIGN(4) ;
+    __vector_offset_243 = (DEFINED(__vector_dispatch_243) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_243))
+    . = ALIGN(4) ;
+    __vector_offset_244 = (DEFINED(__vector_dispatch_244) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_244))
+    . = ALIGN(4) ;
+    __vector_offset_245 = (DEFINED(__vector_dispatch_245) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_245))
+    . = ALIGN(4) ;
+    __vector_offset_246 = (DEFINED(__vector_dispatch_246) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_246))
+    . = ALIGN(4) ;
+    __vector_offset_247 = (DEFINED(__vector_dispatch_247) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_247))
+    . = ALIGN(4) ;
+    __vector_offset_248 = (DEFINED(__vector_dispatch_248) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_248))
+    . = ALIGN(4) ;
+    __vector_offset_249 = (DEFINED(__vector_dispatch_249) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_249))
+    . = ALIGN(4) ;
+    __vector_offset_250 = (DEFINED(__vector_dispatch_250) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_250))
+    . = ALIGN(4) ;
+    __vector_offset_251 = (DEFINED(__vector_dispatch_251) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_251))
+    . = ALIGN(4) ;
+    __vector_offset_252 = (DEFINED(__vector_dispatch_252) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_252))
+    . = ALIGN(4) ;
+    __vector_offset_253 = (DEFINED(__vector_dispatch_253) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_253))
+    . = ALIGN(4) ;
+    __vector_offset_254 = (DEFINED(__vector_dispatch_254) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_254))
+    . = ALIGN(4) ;
+    __vector_offset_255 = (DEFINED(__vector_dispatch_255) ? (. - _ebase_address) : __vector_offset_default);
+    KEEP(*(.vector_255))
+    /* Default interrupt handler */
+    . = ALIGN(4) ;
+    __vector_offset_default = . - _ebase_address;
+    KEEP(*(.vector_default))
+  } > kseg0_program_mem
+
+  /*  The startup code is in the .reset.startup section.
+   *  Keep this here for backwards compatibility with older
+   *  C32 v1.xx releases.
+   */
+  .startup ORIGIN(kseg0_boot_mem) :
+  {
+    KEEP(*(.startup))
+  } > kseg0_boot_mem
+
+  /* Code Sections - Note that input sections *(.text) and *(.text.*)
+   * are not mapped here. The best-fit allocator locates them,
+   * so that .text may flow around absolute sections as needed.
+   */
+  .text :
+  {
+    *(.stub .gnu.linkonce.t.*)
+    KEEP (*(.text.*personality*))
+    *(.mips16.fn.*)
+    *(.mips16.call.*)
+    *(.gnu.warning)
+    . = ALIGN(4) ;
+  } >kseg0_program_mem
+  /* Global-namespace object initialization */
+  .init   :
+  {
+    KEEP (*crti.o(.init))
+    KEEP (*crtbegin.o(.init))
+    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o *crtn.o ).init))
+    KEEP (*crtend.o(.init))
+    KEEP (*crtn.o(.init))
+    . = ALIGN(4) ;
+  } >kseg0_program_mem
+  .fini   :
+  {
+    KEEP (*(.fini))
+    . = ALIGN(4) ;
+  } >kseg0_program_mem
+  .preinit_array   :
+  {
+    PROVIDE_HIDDEN (__preinit_array_start = .);
+    KEEP (*(.preinit_array))
+    PROVIDE_HIDDEN (__preinit_array_end = .);
+    . = ALIGN(4) ;
+  } >kseg0_program_mem
+  .init_array   :
+  {
+    PROVIDE_HIDDEN (__init_array_start = .);
+    KEEP (*(SORT(.init_array.*)))
+    KEEP (*(.init_array))
+    PROVIDE_HIDDEN (__init_array_end_ = .);
+    . = ALIGN(4) ;
+  } >kseg0_program_mem
+  .ctors   :
+  {
+    /* XC32 uses crtbegin.o to find the start of
+       the constructors, so we make sure it is
+       first.  Because this is a wildcard, it
+       doesn't matter if the user does not
+       actually link against crtbegin.o; the
+       linker won't look for a file to match a
+       wildcard.  The wildcard also means that it
+       doesn't matter which directory crtbegin.o
+       is in.  */
+    KEEP (*crtbegin.o(.ctors))
+    KEEP (*crtbegin?.o(.ctors))
+    /* We don't want to include the .ctor section from
+       the crtend.o file until after the sorted ctors.
+       The .ctor section from the crtend file contains the
+       end of ctors marker and it must be last */
+    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
+    KEEP (*(SORT(.ctors.*)))
+    KEEP (*(.ctors))
+    PROVIDE_HIDDEN (__init_array_end = .);
+    . = ALIGN(4) ;
+  } >kseg0_program_mem
+  .fini_array   :
+  {
+    PROVIDE_HIDDEN (__fini_array_start = .);
+    KEEP (*(SORT(.fini_array.*)))
+    KEEP (*(.fini_array))
+    PROVIDE_HIDDEN (__fini_array_end = .);
+    . = ALIGN(4) ;
+  } >kseg0_program_mem
+  .dtors   :
+  {
+    KEEP (*crtbegin.o(.dtors))
+    KEEP (*crtbegin?.o(.dtors))
+    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
+    KEEP (*(SORT(.dtors.*)))
+    KEEP (*(.dtors))
+    . = ALIGN(4) ;
+  } >kseg0_program_mem
+  /* Read-only sections */
+  .rodata   :
+  {
+    *( .gnu.linkonce.r.*)
+    *(.rodata1)
+    . = ALIGN(4) ;
+  } >kseg0_program_mem
+  /*
+   * Small initialized constant global and static data can be placed in the
+   * .sdata2 section.  This is different from .sdata, which contains small
+   * initialized non-constant global and static data.
+   */
+  .sdata2 ALIGN(4) :
+  {
+    *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+    *(.data.memset_func.memset_func)
+    . = ALIGN(4) ;
+  } >kseg0_program_mem
+  /*
+   * Uninitialized constant global and static data (i.e., variables which will
+   * always be zero).  Again, this is different from .sbss, which contains
+   * small non-initialized, non-constant global and static data.
+   */
+  .sbss2 ALIGN(4) :
+  {
+    *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*)
+    . = ALIGN(4) ;
+  } >kseg0_program_mem
+  .eh_frame_hdr   :
+  {
+    *(.eh_frame_hdr)
+  } >kseg0_program_mem
+    . = ALIGN(4) ;
+  .eh_frame   : ONLY_IF_RO
+  {
+    KEEP (*(.eh_frame))
+  } >kseg0_program_mem
+    . = ALIGN(4) ;
+  .gcc_except_table   : ONLY_IF_RO
+  {
+    *(.gcc_except_table .gcc_except_table.*)
+  } >kseg0_program_mem
+    . = ALIGN(4) ;
+  .dbg_data (NOLOAD) :
+  {
+    . += (DEFINED (_DEBUGGER) ? 0x200 : 0x0);
+    /* Additional data memory required for DSPr2 registers */
+    . += (DEFINED (_DEBUGGER) ? 0x80 : 0x0);
+    /* Additional data memory required for FPU64 registers */
+    . += (DEFINED (_DEBUGGER) ? 0x100 : 0x0);
+  } >kseg0_data_mem
+  .jcr   :
+  {
+    KEEP (*(.jcr))
+    . = ALIGN(4) ;
+  } >kseg0_data_mem
+  .eh_frame    : ONLY_IF_RW
+  {
+    KEEP (*(.eh_frame))
+  } >kseg0_data_mem
+    . = ALIGN(4) ;
+  .gcc_except_table    : ONLY_IF_RW
+  {
+    *(.gcc_except_table .gcc_except_table.*)
+  } >kseg0_data_mem
+    . = ALIGN(4) ;
+  /* Persistent data - Use the new C 'persistent' attribute instead. */
+  .persist   :
+  {
+    _persist_begin = .;
+    *(.persist .persist.*)
+    . = ALIGN(4) ;
+    _persist_end = .;
+  } >kseg0_data_mem
+  /*
+   *  Note that input sections named .data* are not mapped here.
+   *  The best-fit allocator locates them, so that they may flow
+   *  around absolute sections as needed.
+   */
+  .data   :
+  {
+    *( .gnu.linkonce.d.*)
+    SORT(CONSTRUCTORS)
+    *(.data1)
+    *(.data .data.*)
+    . = ALIGN(4) ;
+  } >kseg0_data_mem
+  . = .;
+  _gp = ALIGN(16) + 0x7ff0;
+  .got ALIGN(4) :
+  {
+    *(.got.plt) *(.got)
+    . = ALIGN(4) ;
+  } >kseg0_data_mem /* AT>kseg0_program_mem */
+  /*
+   * Note that 'small' data sections are still mapped in the linker
+   * script. This ensures that they are grouped together for
+   * gp-relative addressing. Absolute sections are allocated after
+   * the 'small' data sections so small data cannot flow around them.
+   */
+  /*
+   * We want the small data sections together, so single-instruction offsets
+   * can access them all, and initialized data all before uninitialized, so
+   * we can shorten the on-disk segment size.
+   */
+  .sdata ALIGN(4) :
+  {
+    _sdata_begin = . ;
+    *(.sdata .sdata.* .gnu.linkonce.s.*)
+    . = ALIGN(4) ;
+    _sdata_end = . ;
+  } >kseg0_data_mem
+  .lit8           :
+  {
+    *(.lit8)
+  } >kseg0_data_mem
+  .lit4           :
+  {
+    *(.lit4)
+  } >kseg0_data_mem
+  . = ALIGN (4) ;
+  _data_end = . ;
+  _bss_begin = . ;
+  .sbss ALIGN(4) :
+  {
+    _sbss_begin = . ;
+    *(.dynsbss)
+    *(.sbss .sbss.* .gnu.linkonce.sb.*)
+    *(.scommon)
+    _sbss_end = . ;
+    . = ALIGN(4) ;
+  } >kseg0_data_mem
+  /*
+   *  Align here to ensure that the .bss section occupies space up to
+   *  _end.  Align after .bss to ensure correct alignment even if the
+   *  .bss section disappears because there are no input sections.
+   *
+   *  Note that input sections named .bss* are no longer mapped here.
+   *  The best-fit allocator locates them, so that they may flow
+   *  around absolute sections as needed.
+   *
+   */
+  .bss     :
+  {
+    *(.dynbss)
+    *(COMMON)
+    *(.bss.*)
+   /* Align here to ensure that the .bss section occupies space up to
+      _end.  Align after .bss to ensure correct alignment even if the
+      .bss section disappears because there are no input sections. */
+   . = ALIGN(. != 0 ? 4 : 1);
+  } >kseg0_data_mem
+  . = ALIGN(4) ;
+  _end = . ;
+  _bss_end = . ;
+
+  /* Heap starts after BSS */
+  . = ALIGN(8);
+  __HeapBase = .;
+
+ /* .stack_dummy section doesn't contains any symbols. It is only
+  * used for linker to calculate size of stack sections, and assign
+  * values to stack symbols later */
+ .stack_dummy (COPY):
+  {
+      KEEP(*(.stack*))
+  } >kseg0_data_mem
+
+  _ram_start = ORIGIN(kseg0_data_mem);
+
+  /* Set stack top to end of RAM, and stack limit move down by
+   * size of stack_dummy section */
+  __StackTop = ORIGIN(kseg0_data_mem) + LENGTH(kseg0_data_mem) - 8;
+  __StackLimit = __StackTop - SIZEOF(.stack_dummy);
+  PROVIDE(__stack = __StackTop);
+  PROVIDE(_stack = __StackTop);
+
+  /* Top of head is the bottom of the stack */
+  __HeapLimit = __StackLimit;
+
+  /* Check if data + heap + stack exceeds kseg0_data_mem limit */
+  ASSERT(__HeapBase <= __HeapLimit, "region kseg0_data_mem overflowed with stack")
+
+    /* The .pdr section belongs in the absolute section */
+    /DISCARD/ : { *(.pdr) }
+  .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
+  .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
+  .mdebug.abi32 0 : { KEEP(*(.mdebug.abi32)) }
+  .mdebug.abiN32 0 : { KEEP(*(.mdebug.abiN32)) }
+  .mdebug.abi64 0 : { KEEP(*(.mdebug.abi64)) }
+  .mdebug.abiO64 0 : { KEEP(*(.mdebug.abiO64)) }
+  .mdebug.eabi32 0 : { KEEP(*(.mdebug.eabi32)) }
+  .mdebug.eabi64 0 : { KEEP(*(.mdebug.eabi64)) }
+  .gcc_compiled_long32 : { KEEP(*(.gcc_compiled_long32)) }
+  .gcc_compiled_long64 : { KEEP(*(.gcc_compiled_long64)) }
+  /* Stabs debugging sections.  */
+  .stab          0 : { *(.stab) }
+  .stabstr       0 : { *(.stabstr) }
+  .stab.excl     0 : { *(.stab.excl) }
+  .stab.exclstr  0 : { *(.stab.exclstr) }
+  .stab.index    0 : { *(.stab.index) }
+  .stab.indexstr 0 : { *(.stab.indexstr) }
+  .comment       0 : { *(.comment) }
+  /* DWARF debug sections used by MPLAB X for source-level debugging. 
+     Symbols in the DWARF debugging sections are relative to the beginning
+     of the section so we begin them at 0.  */
+  /* DWARF 1 */
+  .debug          0 : { *.elf(.debug) *(.debug) }
+  .line           0 : { *.elf(.line) *(.line) }
+  /* GNU DWARF 1 extensions */
+  .debug_srcinfo  0 : { *.elf(.debug_srcinfo) *(.debug_srcinfo) }
+  .debug_sfnames  0 : { *.elf(.debug_sfnames) *(.debug_sfnames) }
+  /* DWARF 1.1 and DWARF 2 */
+  .debug_aranges  0 : { *.elf(.debug_aranges) *(.debug_aranges) }
+  .debug_pubnames 0 : { *.elf(.debug_pubnames) *(.debug_pubnames) }
+  /* DWARF 2 */
+  .debug_info     0 : { *.elf(.debug_info .gnu.linkonce.wi.*) *(.debug_info .gnu.linkonce.wi.*) }
+  .debug_abbrev   0 : { *.elf(.debug_abbrev) *(.debug_abbrev) }
+  .debug_line     0 : { *.elf(.debug_line) *(.debug_line) }
+  .debug_frame    0 : { *.elf(.debug_frame) *(.debug_frame) }
+  .debug_str      0 : { *.elf(.debug_str) *(.debug_str) }
+  .debug_loc      0 : { *.elf(.debug_loc) *(.debug_loc) }
+  .debug_macinfo  0 : { *.elf(.debug_macinfo) *(.debug_macinfo) }
+  /* SGI/MIPS DWARF 2 extensions */
+  .debug_weaknames 0 : { *.elf(.debug_weaknames) *(.debug_weaknames) }
+  .debug_funcnames 0 : { *.elf(.debug_funcnames) *(.debug_funcnames) }
+  .debug_typenames 0 : { *.elf(.debug_typenames) *(.debug_typenames) }
+  .debug_varnames  0 : { *.elf(.debug_varnames) *(.debug_varnames) }
+  .debug_pubtypes 0 : { *.elf(.debug_pubtypes) *(.debug_pubtypes) }
+  .debug_ranges   0 : { *.elf(.debug_ranges) *(.debug_ranges) }
+  /DISCARD/ : { *(.rel.dyn) }
+  .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
+  /DISCARD/ : { *(.note.GNU-stack) }
+  /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) *(.discard) }
+}
+
+/*************************************************************************
+ *                    L1 Cache initialization symbols
+ *************************************************************************/
+/*
+ *  Provide virtual addresses for cache initialization
+ *  These symbols are used by the pic32_init_cache.o module to set up
+ *  the cache at startup.
+ */
+EXTERN  (__pic32_init_cache_program_base_addr)
+PROVIDE (__pic32_init_cache_program_base_addr = 0x9D000000) ;
+EXTERN  (__pic32_init_cache_data_base_addr)
+PROVIDE (__pic32_init_cache_data_base_addr = 0x80000000) ;
+
+/*************************************************************************
+ *   TLB-Based MMU Initialization section for EBI/SQI memory regions
+ *************************************************************************/
+/*
+ *  Provide virtual and physical addresses of the SQI for TLB initialization
+ *  These symbols are used below to create a table, which is in turn used to
+ *  initialize the TLB at startup.
+ */
+EXTERN  (__pic32_init_sqi_kseg2_virtual_base_addr)
+PROVIDE (__pic32_init_sqi_kseg2_virtual_base_addr = 0xD0000000) ;
+EXTERN  (__pic32_init_sqi_kseg2_physical_base_addr)
+PROVIDE (__pic32_init_sqi_kseg2_physical_base_addr = 0x30000000) ;
+EXTERN  (__pic32_init_sqi_kseg2_entrylo0_bitset)
+PROVIDE (__pic32_init_sqi_kseg2_entrylo0_bitset = 0x1F) ;
+
+/*  ENTRYHI = VPN2<31:13> VPN2X<12:11> 0<10:8> ASID<7:0> */
+__pic32_tlb_0_entryhi  = __pic32_init_sqi_kseg2_virtual_base_addr ;
+
+
+/*  Create one page table entry consisting of two 16MB physical pages. 
+ *  ENTRYLO0 = RI<31> XI<30> 0<29:26> PFN<25:6> C<5:3> D<2> V<1> G<0> 
+ *  Shift __pic32_init_sqi_kseg3_physical_base_addr to PFN. 
+ *  Bitwise-OR the other bits of ENTRYLO0.
+ */
+__pic32_tlb_0_entrylo0 = (__pic32_init_sqi_kseg2_physical_base_addr >> 6) | __pic32_init_sqi_kseg2_entrylo0_bitset ;
+
+
+/*  ENTRYLO1 = RI<31> XI<30> 0<29:26> PFN<25:6> C<5:3> D<2> V<1> G<0> */
+__pic32_tlb_0_entrylo1 = __pic32_tlb_0_entrylo0 | ((__pic32_init_sqi_kseg2_physical_base_addr + 0x1000000) >> 6) ;
+
+
+/*  ENTRYHI = VPN2<31:13> VPN2X<12:11> 0<10:8> ASID<7:0> */
+__pic32_tlb_1_entryhi  = __pic32_init_sqi_kseg2_virtual_base_addr + 0x2000000;
+
+
+/*  Create one page table entry consisting of two 16MB physical pages. 
+ *  ENTRYLO0 = RI<31> XI<30> 0<29:26> PFN<25:6> C<5:3> D<2> V<1> G<0> 
+ *  Shift __pic32_init_sqi_kseg3_physical_base_addr to PFN. 
+ *  Bitwise-OR the other bits of ENTRYLO0.
+ */
+__pic32_tlb_1_entrylo0 = ((__pic32_init_sqi_kseg2_physical_base_addr + 0x2000000) >> 6) | __pic32_init_sqi_kseg2_entrylo0_bitset;
+
+
+/*  ENTRYLO1 = RI<31> XI<30> 0<29:26> PFN<25:6> C<5:3> D<2> V<1> G<0> */
+__pic32_tlb_1_entrylo1 = __pic32_tlb_1_entrylo0 | 0x00040000 ;
+
+EXTERN  (__pic32_init_sqi_kseg3_virtual_base_addr)
+PROVIDE (__pic32_init_sqi_kseg3_virtual_base_addr = 0xF0000000) ;
+EXTERN  (__pic32_init_sqi_kseg3_physical_base_addr)
+PROVIDE (__pic32_init_sqi_kseg3_physical_base_addr = 0x30000000) ;
+EXTERN  (__pic32_init_sqi_kseg3_entrylo0_bitset)
+PROVIDE (__pic32_init_sqi_kseg3_entrylo0_bitset = 0x17) ;
+
+/*  ENTRYHI = VPN2<31:13> VPN2X<12:11> 0<10:8> ASID<7:0> */
+__pic32_tlb_2_entryhi  = __pic32_init_sqi_kseg3_virtual_base_addr ;
+
+
+/*  Create one page table entry consisting of two 16MB physical pages. 
+ *  ENTRYLO0 = RI<31> XI<30> 0<29:26> PFN<25:6> C<5:3> D<2> V<1> G<0> 
+ *  Shift __pic32_init_sqi_kseg3_physical_base_addr to PFN. 
+ *  Bitwise-OR the other bits of ENTRYLO0. 
+ */
+__pic32_tlb_2_entrylo0 = (__pic32_init_sqi_kseg3_physical_base_addr >> 6) | __pic32_init_sqi_kseg3_entrylo0_bitset ;
+
+
+/*  ENTRYLO1 = RI<31> XI<30> 0<29:26> PFN<25:6> C<5:3> D<2> V<1> G<0> */
+__pic32_tlb_2_entrylo1 = __pic32_tlb_2_entrylo0 | ((__pic32_init_sqi_kseg3_physical_base_addr + 0x1000000) >> 6) ;
+
+
+/*  ENTRYHI = VPN2<31:13> VPN2X<12:11> 0<10:8> ASID<7:0> */
+__pic32_tlb_3_entryhi  = __pic32_init_sqi_kseg3_virtual_base_addr + 0x2000000;
+
+
+/*  Create one page table entry consisting of two 16MB physical pages. 
+ *  ENTRYLO0 = RI<31> XI<30> 0<29:26> PFN<25:6> C<5:3> D<2> V<1> G<0> 
+ *  Shift __pic32_init_sqi_kseg3_physical_base_addr to PFN. 
+ *  Bitwise-OR the other bits of ENTRYLO0.
+ */
+__pic32_tlb_3_entrylo0 = ((__pic32_init_sqi_kseg3_physical_base_addr + 0x2000000) >> 6) | __pic32_init_sqi_kseg3_entrylo0_bitset;
+
+
+/*  ENTRYLO1 = RI<31> XI<30> 0<29:26> PFN<25:6> C<5:3> D<2> V<1> G<0> */
+__pic32_tlb_3_entrylo1 = __pic32_tlb_3_entrylo0 | 0x00040000 ;
+
+/*
+ *  The default pic32_init_tlb_ebi_sqi.o module, which is
+ *  called by the default C startup code (crt0_<isa>.o),
+ *  uses the table created in the .tlb_init_values output
+ *  section to initialize the Translation Lookaside buffer (TLB)
+ *  of the Memory Management Unit (MMU).
+ */
+SECTIONS
+{
+  .tlb_init_values :
+  {
+    . = ALIGN(4) ;
+    __pic32_tlb_init_values_begin = ABSOLUTE(.);
+    LONG(__pic32_tlb_0_entryhi) ;
+    LONG(__pic32_tlb_0_entrylo0) ;
+    LONG(__pic32_tlb_0_entrylo1) ;
+    LONG(__pic32_tlb_1_entryhi) ;
+    LONG(__pic32_tlb_1_entrylo0) ;
+    LONG(__pic32_tlb_1_entrylo1) ;
+    LONG(__pic32_tlb_2_entryhi) ;
+    LONG(__pic32_tlb_2_entrylo0) ;
+    LONG(__pic32_tlb_2_entrylo1) ;
+    LONG(__pic32_tlb_3_entryhi) ;
+    LONG(__pic32_tlb_3_entrylo0) ;
+    LONG(__pic32_tlb_3_entrylo1) ;
+    __pic32_tlb_init_values_end = ABSOLUTE(.);
+    __pic32_tlb_init_values_count = 4 ;
+  } > kseg1_boot_mem_4B0
+}
+
diff --git a/hw/mcu/microchip/pic32mz/pkg.yml b/hw/mcu/microchip/pic32mz/pkg.yml
new file mode 100644
index 0000000..c505ceb
--- /dev/null
+++ b/hw/mcu/microchip/pic32mz/pkg.yml
@@ -0,0 +1,32 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+pkg.name: hw/mcu/microchip/pic32mz
+pkg.description: MCU definition for Microchip PIC32MZ microcontrollers.
+pkg.author: "Apache Mynewt <dev@mynewt.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+    - pic32
+    - pic32mz
+
+pkg.deps.(UART_0 || UART_1 || UART_2 || UART_3 || UART_4 || UART_5):
+    - "@apache-mynewt-core/hw/drivers/uart/uart_hal"
+
+pkg.deps:
+    - "@apache-mynewt-core/hw/hal"
diff --git a/hw/mcu/microchip/pic32mz/src/hal_flash.c b/hw/mcu/microchip/pic32mz/src/hal_flash.c
new file mode 100644
index 0000000..de15f5a
--- /dev/null
+++ b/hw/mcu/microchip/pic32mz/src/hal_flash.c
@@ -0,0 +1,196 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <xc.h>
+#include <assert.h>
+#include <hal/hal_flash_int.h>
+#include <mcu/mips_hal.h>
+#include <string.h>
+
+#define VIRT_TO_PHY(ADDRESS)   (unsigned int)((int)(ADDRESS) & 0x1FFFFFFF)
+#define PHY_TO_VIRT(ADDRESS)   (unsigned int)((int)(ADDRESS) | 0x80000000)
+#define PIC32MZ_FLASH_SECTOR_SZ     (16 * 1024)
+#define WORD_SIZE           (4)
+#define QUADWORD_SIZE       (4 * WORD_SIZE)
+#define QUADWORD_PROGRAM    (0b0010)
+#define WORD_PROGRAM        (0b0001)
+#define ERASE_PAGE          (0b0100)
+
+static int pic32mz_flash_read(const struct hal_flash *dev, uint32_t address,
+                              void *dst, uint32_t num_bytes);
+static int pic32mz_flash_write(const struct hal_flash *dev, uint32_t address,
+                               const void *src, uint32_t num_bytes);
+static int pic32mz_flash_erase_sector(const struct hal_flash *dev,
+                                      uint32_t sector_address);
+static int pic32mz_flash_sector_info(const struct hal_flash *dev, int idx,
+                                     uint32_t *address, uint32_t *sz);
+static int pic32mz_flash_init(const struct hal_flash *dev);
+
+static const struct hal_flash_funcs pic32mz_flash_funcs = {
+    .hff_read = pic32mz_flash_read,
+    .hff_write = pic32mz_flash_write,
+    .hff_erase_sector = pic32mz_flash_erase_sector,
+    .hff_sector_info = pic32mz_flash_sector_info,
+    .hff_init = pic32mz_flash_init
+};
+
+const struct hal_flash pic32mz_flash_dev = {
+    .hf_itf = &pic32mz_flash_funcs,
+    .hf_base_addr = 0x1D000000,
+    .hf_size = __PIC32_FLASH_SIZE * 1024,
+    .hf_sector_cnt = __PIC32_FLASH_SIZE / 16,
+    .hf_align = 4,     /* num bytes must be a multiple of 4 as writes can only
+                        * be done on word boundary. This also assumes that
+                        * ECC memory is disabled (default on Wi-Fire board).
+                        */
+    .hf_erased_val = 0xff,
+};
+
+static int
+flash_do_op(uint32_t op)
+{
+    uint32_t ctx;
+
+    __HAL_DISABLE_INTERRUPTS(ctx);
+
+    NVMCON = _NVMCON_WREN_MASK | (op & _NVMCON_NVMOP_MASK);
+
+    /*
+     * Disable core timer by setting the DC flag in CP0 Cause register.
+     * If the core timer is not disabled, the kernel would miss the core timer
+     * interrupt while the CPU is stalling.
+     */
+    _CP0_SET_CAUSE(_CP0_GET_CAUSE() | _CP0_CAUSE_DC_MASK);
+
+    NVMKEY = 0x0;
+    NVMKEY = 0xAA996655;
+    NVMKEY = 0x556699AA;
+    NVMCONSET = _NVMCON_WR_MASK;
+
+    while (NVMCON & _NVMCON_WR_MASK) {}
+
+    /* Re-enable core timer  */
+    _CP0_SET_CAUSE(_CP0_GET_CAUSE() & ~_CP0_CAUSE_DC_MASK);
+
+    __HAL_ENABLE_INTERRUPTS(ctx);
+
+    NVMCONCLR = _NVMCON_WREN_MASK;
+
+    return (NVMCON & (_NVMCON_WRERR_MASK | _NVMCON_LVDERR_MASK)) ? -1 : 0;
+}
+
+static int
+pic32mz_flash_read(const struct hal_flash *dev, uint32_t address,
+                   void *dst, uint32_t num_bytes)
+{
+    (void)dev;
+    memcpy(dst, (void *)PHY_TO_VIRT(address), num_bytes);
+    return 0;
+}
+
+static int
+pic32mz_flash_write(const struct hal_flash *dev, uint32_t address,
+                    const void *src, uint32_t num_bytes)
+{
+    (void)dev;
+    const uint32_t *data = (const uint32_t*)src;
+    uint32_t word;
+
+    if (num_bytes & (WORD_SIZE - 1) || (address & 3)) {
+        return -1;
+    }
+
+    /* Write flash by word until the next quadword boundary is reached */
+    while (address & (QUADWORD_SIZE -1) && num_bytes >= WORD_SIZE) {
+        NVMADDR = address;
+        address += WORD_SIZE;
+        NVMDATA0 = *data++;
+
+        if (flash_do_op(WORD_PROGRAM)) {
+            return -1;
+        }
+        num_bytes -= WORD_SIZE;
+    }
+
+    while (num_bytes >= QUADWORD_SIZE) {
+        NVMADDR = address;
+        address += QUADWORD_SIZE;
+
+        NVMDATA0 = data[0];
+        NVMDATA1 = data[1];
+        NVMDATA2 = data[2];
+        NVMDATA3 = data[3];
+        data += 4;
+
+        if (flash_do_op(QUADWORD_PROGRAM)) {
+            return -1;
+        }
+        num_bytes -= QUADWORD_SIZE;
+    }
+
+    while (num_bytes >= WORD_SIZE) {
+        NVMADDR = address;
+        address += WORD_SIZE;
+        NVMDATA0 = *data++;
+
+        if (flash_do_op(WORD_PROGRAM)) {
+            return -1;
+        }
+        num_bytes -= WORD_SIZE;
+    }
+    if (num_bytes > 0) {
+        memcpy(&word, data, num_bytes);
+        pic32mz_flash_read(dev, address + num_bytes, ((uint8_t *)&word) + num_bytes, WORD_SIZE - num_bytes);
+
+        NVMADDR = address;
+        NVMDATA0 = word;
+
+        if (flash_do_op(WORD_PROGRAM)) {
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+static int
+pic32mz_flash_erase_sector(const struct hal_flash *dev,
+                           uint32_t sector_address)
+{
+    (void)dev;
+    NVMADDR = sector_address;
+    return flash_do_op(ERASE_PAGE);
+}
+
+static int
+pic32mz_flash_sector_info(const struct hal_flash *dev, int idx,
+                          uint32_t *address, uint32_t *sz)
+{
+    assert(idx < pic32mz_flash_dev.hf_sector_cnt);
+    *address = pic32mz_flash_dev.hf_base_addr + idx * PIC32MZ_FLASH_SECTOR_SZ;
+    *sz = PIC32MZ_FLASH_SECTOR_SZ;
+    return 0;
+}
+
+static int
+pic32mz_flash_init(const struct hal_flash *dev)
+{
+    (void)dev;
+    return 0;
+}
diff --git a/hw/mcu/microchip/pic32mz/src/hal_gpio.c b/hw/mcu/microchip/pic32mz/src/hal_gpio.c
new file mode 100644
index 0000000..e2b8172
--- /dev/null
+++ b/hw/mcu/microchip/pic32mz/src/hal_gpio.c
@@ -0,0 +1,567 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <xc.h>
+#include <os/mynewt.h>
+#include <hal/hal_gpio.h>
+#include <mcu/mips_hal.h>
+
+#define GPIO_INDEX(pin)     ((pin) & 0x0F)
+#define GPIO_PORT(pin)      (((pin) >> 4) & 0x0F)
+#define GPIO_MASK(pin)      (1 << GPIO_INDEX(pin))
+
+#define LATxCLR(P)      (base_address[P].gpio[0x14 / 0x4])
+#define LATxSET(P)      (base_address[P].gpio[0x18 / 0x4])
+#define LATxINV(P)      (base_address[P].gpio[0x1C / 0x4])
+#define PORTx(P)        (base_address[P].gpio[0x0])
+#define CNPUxCLR(P)     (base_address[P].gpio[0x34 / 0x4])
+#define CNPUxSET(P)     (base_address[P].gpio[0x38 / 0x4])
+#define CNPDxCLR(P)     (base_address[P].gpio[0x44 / 0x4])
+#define CNPDxSET(P)     (base_address[P].gpio[0x48 / 0x4])
+#define ODCxCLR(P)      (base_address[P].gpio[0x24 / 0x4])
+#define CNCONxSET(P)    (base_address[P].gpio[0x58 / 0x4])
+#define CNENxCLR(P)     (base_address[P].gpio[0x64 / 0x4])
+#define CNENxSET(P)     (base_address[P].gpio[0x68 / 0x4])
+#define CNNExCLR(P)     (base_address[P].gpio[0x84 / 0x4])
+#define CNNExSET(P)     (base_address[P].gpio[0x88 / 0x4])
+#define CNFx(P)         (base_address[P].gpio[0x90 / 0x4])
+#define CNFxCLR(P)      (base_address[P].gpio[0x94 / 0x4])
+#define ANSELxCLR(P)    (base_address[P].ansel[0x04 / 0x4])
+#define TRISxCLR(P)     (base_address[P].tris[0x04 / 0x4])
+#define TRISxSET(P)     (base_address[P].tris[0x08 / 0x4])
+
+struct hal_gpio_irq_t {
+    int                    pin;
+    hal_gpio_irq_trig_t    trig;
+    hal_gpio_irq_handler_t handler;
+    void                   *arg;
+};
+
+#define HAL_GPIO_MAX_IRQ    (8)
+static struct hal_gpio_irq_t hal_gpio_irqs[HAL_GPIO_MAX_IRQ];
+
+struct pic32_gpio_t {
+    volatile uint32_t * gpio;
+    volatile uint32_t * ansel;
+    volatile uint32_t * tris;
+};
+
+static uint32_t dummy_reg[2];
+#ifndef ANSELA
+#define ANSELA dummy_reg[0]
+#endif
+#ifndef ANSELC
+#define ANSELC dummy_reg[0]
+#endif
+#ifndef ANSELD
+#define ANSELD dummy_reg[0]
+#endif
+#ifndef ANSELE
+#define ANSELE dummy_reg[0]
+#endif
+#ifndef ANSELF
+#define ANSELF dummy_reg[0]
+#endif
+#ifndef ANSELH
+#define ANSELH dummy_reg[0]
+#endif
+#ifndef ANSELJ
+#define ANSELJ dummy_reg[0]
+#endif
+#ifndef ANSELK
+#define ANSELK dummy_reg[0]
+#endif
+#ifndef _PORTA_BASE_ADDRESS
+#define _PORTA_BASE_ADDRESS dummy_reg
+#endif
+#ifndef _PORTH_BASE_ADDRESS
+#define _PORTH_BASE_ADDRESS dummy_reg
+#endif
+#ifndef _PORTJ_BASE_ADDRESS
+#define _PORTJ_BASE_ADDRESS dummy_reg
+#endif
+#ifndef _PORTK_BASE_ADDRESS
+#define _PORTK_BASE_ADDRESS dummy_reg
+#endif
+#ifndef TRISA
+#define TRISA dummy_reg[0]
+#endif
+#ifndef TRISH
+#define TRISH dummy_reg[0]
+#endif
+#ifndef TRISJ
+#define TRISJ dummy_reg[0]
+#endif
+#ifndef TRISK
+#define TRISK dummy_reg[0]
+#endif
+
+static const struct pic32_gpio_t base_address[] = {
+    {
+        .gpio  = (volatile uint32_t *)_PORTA_BASE_ADDRESS,
+        .ansel = (volatile uint32_t *)&ANSELA,
+        .tris  = (volatile uint32_t *)&TRISA
+    },
+    {
+        .gpio  = (volatile uint32_t *)_PORTB_BASE_ADDRESS,
+        .ansel = (volatile uint32_t *)&ANSELB,
+        .tris  = (volatile uint32_t *)&TRISB
+    },
+    {
+        .gpio  = (volatile uint32_t *)_PORTC_BASE_ADDRESS,
+        .ansel = (volatile uint32_t *)&ANSELC,
+        .tris  = (volatile uint32_t *)&TRISC
+    },
+    {
+        .gpio  = (volatile uint32_t *)_PORTD_BASE_ADDRESS,
+        .ansel = (volatile uint32_t *)&ANSELD,
+        .tris  = (volatile uint32_t *)&TRISD
+    },
+    {
+        .gpio  = (volatile uint32_t *)_PORTE_BASE_ADDRESS,
+        .ansel = (volatile uint32_t *)&ANSELE,
+        .tris  = (volatile uint32_t *)&TRISE
+    },
+    {
+        .gpio  = (volatile uint32_t *)_PORTF_BASE_ADDRESS,
+        .ansel = (volatile uint32_t *)&ANSELF,
+        .tris  = (volatile uint32_t *)&TRISF
+    },
+    {
+        .gpio  = (volatile uint32_t *)_PORTG_BASE_ADDRESS,
+        .ansel = (volatile uint32_t *)&ANSELG,
+        .tris  = (volatile uint32_t *)&TRISG
+    },
+    {
+        .gpio  = (volatile uint32_t *)_PORTH_BASE_ADDRESS,
+        .ansel = (volatile uint32_t *)&ANSELH,
+        .tris  = (volatile uint32_t *)&TRISH
+    },
+    {
+        .gpio  = (volatile uint32_t *)_PORTJ_BASE_ADDRESS,
+        .ansel = (volatile uint32_t *)&ANSELJ,
+        .tris  = (volatile uint32_t *)&TRISJ
+    },
+    {
+        .gpio  = (volatile uint32_t *)_PORTK_BASE_ADDRESS,
+        .ansel = (volatile uint32_t *)&ANSELK,
+        .tris  = (volatile uint32_t *)&TRISK
+    },
+};
+
+static uint8_t
+hal_gpio_find_pin(int pin)
+{
+    uint8_t index = 0;
+
+    while (index < HAL_GPIO_MAX_IRQ) {
+        if (hal_gpio_irqs[index].pin == pin) {
+            break;
+        }
+
+        ++index;
+    }
+
+    return index;
+}
+
+static uint8_t
+hal_gpio_find_empty_slot(void)
+{
+    uint8_t index = 0;
+
+    while (index < HAL_GPIO_MAX_IRQ) {
+        if (hal_gpio_irqs[index].handler == NULL) {
+            break;
+        }
+
+        ++index;
+    }
+
+    return index;
+}
+
+static void
+hal_gpio_handle_isr(uint32_t port)
+{
+    uint32_t mask, val;
+    uint8_t index;
+
+    for (index = 0; index < HAL_GPIO_MAX_IRQ; ++index) {
+
+        if (hal_gpio_irqs[index].handler == NULL) {
+            continue;
+        }
+        if (GPIO_PORT(hal_gpio_irqs[index].pin) != port) {
+            continue;
+        }
+
+        mask = GPIO_MASK(hal_gpio_irqs[index].pin);
+        if (CNFx(port) & mask != mask) {
+            continue;
+        }
+
+        val = PORTx(port) & mask;
+        if ((val && (hal_gpio_irqs[index].trig & HAL_GPIO_TRIG_RISING)) ||
+            (!val && (hal_gpio_irqs[index].trig & HAL_GPIO_TRIG_FALLING))) {
+            hal_gpio_irqs[index].handler(hal_gpio_irqs[index].arg);
+        }
+        CNFxCLR(port) = mask;
+    }
+}
+
+#ifdef _PORTA
+void
+__attribute__((interrupt(IPL1AUTO), vector(_CHANGE_NOTICE_A_VECTOR)))
+hal_gpio_porta_isr(void)
+{
+    hal_gpio_handle_isr(0);
+    IFS3CLR = _IFS3_CNAIF_MASK;
+}
+#endif
+
+void
+__attribute__((interrupt(IPL1AUTO), vector(_CHANGE_NOTICE_B_VECTOR)))
+hal_gpio_portb_isr(void)
+{
+    hal_gpio_handle_isr(1);
+    IFS3CLR = _IFS3_CNBIF_MASK;
+}
+
+void
+__attribute__((interrupt(IPL1AUTO), vector(_CHANGE_NOTICE_C_VECTOR)))
+hal_gpio_portc_isr(void)
+{
+    hal_gpio_handle_isr(2);
+    IFS3CLR = _IFS3_CNCIF_MASK;
+}
+
+void
+__attribute__((interrupt(IPL1AUTO), vector(_CHANGE_NOTICE_D_VECTOR)))
+hal_gpio_portd_isr(void)
+{
+    hal_gpio_handle_isr(3);
+    IFS3CLR = _IFS3_CNDIF_MASK;
+}
+
+void
+__attribute__((interrupt(IPL1AUTO), vector(_CHANGE_NOTICE_E_VECTOR)))
+hal_gpio_porte_isr(void)
+{
+    hal_gpio_handle_isr(4);
+    IFS3CLR = _IFS3_CNEIF_MASK;
+}
+
+void
+__attribute__((interrupt(IPL1AUTO), vector(_CHANGE_NOTICE_F_VECTOR)))
+hal_gpio_portf_isr(void)
+{
+    hal_gpio_handle_isr(5);
+    IFS3CLR = _IFS3_CNFIF_MASK;
+}
+
+void
+__attribute__((interrupt(IPL1AUTO), vector(_CHANGE_NOTICE_G_VECTOR)))
+hal_gpio_portg_isr(void)
+{
+    hal_gpio_handle_isr(6);
+    IFS3CLR = _IFS3_CNGIF_MASK;
+}
+
+int
+hal_gpio_init_in(int pin, hal_gpio_pull_t pull)
+{
+    uint32_t port = GPIO_PORT(pin);
+    uint32_t mask = GPIO_MASK(pin);
+
+    /* Configure pin as digital */
+    ANSELxCLR(port) = mask;
+
+    ODCxCLR(port) = mask;
+
+    switch (pull) {
+    case HAL_GPIO_PULL_NONE:
+        CNPUxCLR(port) = mask;
+        CNPDxCLR(port) = mask;
+        break;
+
+    case HAL_GPIO_PULL_DOWN:
+        CNPUxCLR(port) = mask;
+        CNPDxSET(port) = mask;
+        break;
+
+    case HAL_GPIO_PULL_UP:
+        CNPUxSET(port) = mask;
+        CNPDxCLR(port) = mask;
+        break;
+
+    default:
+        return -1;
+    }
+
+    /* Configure pin direction as input */
+    TRISxSET(port) = mask;
+
+    return 0;
+}
+
+int
+hal_gpio_init_out(int pin, int val)
+{
+    uint32_t port = GPIO_PORT(pin);
+    uint32_t mask = GPIO_MASK(pin);
+
+    /* Configure pin as digital */
+    ANSELxCLR(port) = mask;
+
+    /* Disable pull-up, pull-down and open drain */
+    CNPUxCLR(port) = mask;
+    CNPDxCLR(port) = mask;
+    ODCxCLR(port) = mask;
+
+    if (val) {
+        LATxSET(port) = mask;
+    } else {
+        LATxCLR(port) = mask;
+    }
+
+    /* Configure pin direction as output */
+    TRISxCLR(port) = mask;
+
+    return 0;
+}
+
+void
+hal_gpio_write(int pin, int val)
+{
+    uint32_t port = GPIO_PORT(pin);
+    uint32_t mask = GPIO_MASK(pin);
+
+    if (val) {
+        LATxSET(port) = mask;
+    } else {
+        LATxCLR(port) = mask;
+    }
+}
+
+int
+hal_gpio_read(int pin)
+{
+    uint32_t port = GPIO_PORT(pin);
+    uint32_t mask = GPIO_MASK(pin);
+
+    return !!(PORTx(port) & mask);
+}
+
+int
+hal_gpio_toggle(int pin)
+{
+    uint32_t port = GPIO_PORT(pin);
+    uint32_t mask = GPIO_MASK(pin);
+
+    LATxINV(port) = mask;
+
+    /*
+     * One instruction cycle is required between a write and a read
+     * operation on the same port.
+     */
+    asm volatile ("nop");
+
+    return !!(PORTx(port) & mask);
+}
+
+int
+hal_gpio_irq_init(int pin, hal_gpio_irq_handler_t handler, void *arg,
+                  hal_gpio_irq_trig_t trig, hal_gpio_pull_t pull)
+{
+    uint32_t port = GPIO_PORT(pin);
+    uint32_t mask = GPIO_MASK(pin);
+    uint32_t ctx;
+    int ret;
+    uint8_t index;
+
+    /* HAL_GPIO_TRIG_LOW and HAL_GPIO_TRIG_HIGH are not supported */
+    if (trig == HAL_GPIO_TRIG_LOW ||
+        trig == HAL_GPIO_TRIG_HIGH ||
+        trig == HAL_GPIO_TRIG_NONE) {
+        return -1;
+    }
+
+    /* Remove any existing irq handler attached to the pin */
+    hal_gpio_irq_release(pin);
+    hal_gpio_irq_disable(pin);
+
+    index = hal_gpio_find_empty_slot();
+    if (index == HAL_GPIO_MAX_IRQ) {
+        return -1;
+    }
+
+    ret = hal_gpio_init_in(pin, pull);
+    if (ret < 0) {
+        return ret;
+    }
+
+    __HAL_DISABLE_INTERRUPTS(ctx);
+    hal_gpio_irqs[index].arg = arg;
+    hal_gpio_irqs[index].pin = pin;
+    hal_gpio_irqs[index].trig = trig;
+    hal_gpio_irqs[index].handler = handler;
+    __HAL_ENABLE_INTERRUPTS(ctx);
+
+    return 0;
+}
+
+void
+hal_gpio_irq_release(int pin)
+{
+    uint32_t ctx;
+    uint8_t index = hal_gpio_find_pin(pin);
+    if (index == HAL_GPIO_MAX_IRQ) {
+        return;
+    }
+
+    __HAL_DISABLE_INTERRUPTS(ctx);
+    hal_gpio_irqs[index].handler = NULL;
+    __HAL_ENABLE_INTERRUPTS(ctx);
+}
+
+void
+hal_gpio_irq_enable(int pin)
+{
+    uint32_t port, mask, ctx;
+
+    uint8_t index = hal_gpio_find_pin(pin);
+    if (index == HAL_GPIO_MAX_IRQ)
+        return;
+
+    port = GPIO_PORT(pin);
+    mask = GPIO_MASK(pin);
+
+    __HAL_DISABLE_INTERRUPTS(ctx);
+
+    /* Enable Change Notice module for the port */
+    CNCONxSET(port) = _CNCONB_ON_MASK | _CNCONB_EDGEDETECT_MASK;
+
+    switch (hal_gpio_irqs[index].trig) {
+    case HAL_GPIO_TRIG_RISING:
+        CNENxSET(port) = mask;
+        break;
+    case HAL_GPIO_TRIG_FALLING:
+        CNNExSET(port) = mask;
+        break;
+    case HAL_GPIO_TRIG_BOTH:
+        CNENxSET(port) = mask;
+        CNNExSET(port) = mask;
+        break;
+    default:
+        break;
+    }
+
+    /* Set interrupt priority */
+    switch (port) {
+#if defined(_PORTA)
+    case 0:
+        IPC29CLR = (_IPC29_CNAIP_MASK | _IPC29_CNAIS_MASK);
+        IPC29 |= 1 << _IPC29_CNAIP_POSITION;
+        break;
+#endif
+    case 1:
+        IPC29CLR = (_IPC29_CNBIP_MASK | _IPC29_CNBIS_MASK);
+        IPC29 |= 1 << _IPC29_CNBIP_POSITION;
+        break;
+    case 2:
+        IPC30CLR = (_IPC30_CNCIP_MASK | _IPC30_CNCIS_MASK);
+        IPC30 |= 1 << _IPC30_CNCIP_POSITION;
+        break;
+    case 3:
+        IPC30CLR = (_IPC30_CNDIP_MASK | _IPC30_CNDIS_MASK);
+        IPC30 |= 1 << _IPC30_CNDIP_POSITION;
+        break;
+    case 4:
+        IPC30CLR = (_IPC30_CNEIP_MASK | _IPC30_CNEIS_MASK);
+        IPC30 |= 1 << _IPC30_CNEIP_POSITION;
+        break;
+    case 5:
+        IPC30CLR = (_IPC30_CNFIP_MASK | _IPC30_CNFIS_MASK);
+        IPC30 |= 1 << _IPC30_CNFIP_POSITION;
+        break;
+    case 6:
+        IPC31CLR = (_IPC31_CNGIP_MASK | _IPC31_CNGIS_MASK);
+        IPC31 |= 1 << _IPC31_CNGIP_POSITION;
+        break;
+#ifdef _PORTH
+    case 7:
+        IPC31CLR = (_IPC31_CNHIP_MASK | _IPC31_CNHIS_MASK);
+        IPC31 |= 1 << _IPC31_CNHIP_POSITION;
+        break;
+#endif
+    }
+
+    /* Clear interrupt flag and enable Change Notice interrupt */
+    switch (port) {
+#ifdef _PORTA
+    case 0:
+        IFS3CLR = _IFS3_CNAIF_MASK;
+        IEC3SET = _IEC3_CNAIE_MASK;
+        break;
+#endif
+    case 1:
+        IFS3CLR = _IFS3_CNBIF_MASK;
+        IEC3SET = _IEC3_CNBIE_MASK;
+        break;
+    case 2:
+        IFS3CLR = _IFS3_CNCIF_MASK;
+        IEC3SET = _IEC3_CNCIE_MASK;
+        break;
+    case 3:
+        IFS3CLR = _IFS3_CNDIF_MASK;
+        IEC3SET = _IEC3_CNDIE_MASK;
+        break;
+    case 4:
+        IFS3CLR = _IFS3_CNEIF_MASK;
+        IEC3SET = _IEC3_CNEIE_MASK;
+        break;
+    case 5:
+        IFS3CLR = _IFS3_CNFIF_MASK;
+        IEC3SET = _IEC3_CNFIE_MASK;
+        break;
+    case 6:
+        IFS3CLR = _IFS3_CNGIF_MASK;
+        IEC3SET = _IEC3_CNGIE_MASK;
+        break;
+#ifdef _PORTH
+    case 7:
+        IFS3CLR = _IFS3_CNHIF_MASK;
+        IEC3SET = _IEC3_CNHIE_MASK;
+        break;
+#endif
+    }
+
+    __HAL_ENABLE_INTERRUPTS(ctx);
+}
+
+void
+hal_gpio_irq_disable(int pin)
+{
+    uint32_t port = GPIO_PORT(pin);
+    uint32_t mask = GPIO_MASK(pin);
+
+    CNENxCLR(port) = mask;
+    CNNExCLR(port) = mask;
+}
diff --git a/hw/mcu/microchip/pic32mz/src/hal_i2c.c b/hw/mcu/microchip/pic32mz/src/hal_i2c.c
new file mode 100644
index 0000000..654f973
--- /dev/null
+++ b/hw/mcu/microchip/pic32mz/src/hal_i2c.c
@@ -0,0 +1,278 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <xc.h>
+#include <os/mynewt.h>
+#include <bsp/bsp.h>
+#include <hal/hal_gpio.h>
+#include <hal/hal_i2c.h>
+#include <mcu/mips_hal.h>
+
+#define I2CxCON(I)              (base_address[I][0x00 / 0x04])
+#define I2CxCONCLR(I)           (base_address[I][0x04 / 0x04])
+#define I2CxCONSET(I)           (base_address[I][0x08 / 0x04])
+#define I2CxSTAT(I)             (base_address[I][0x10 / 0x04])
+#define I2CxBRG(I)              (base_address[I][0x40 / 0x04])
+#define I2CxTRN(I)              (base_address[I][0x50 / 0x04])
+#define I2CxRCV(I)              (base_address[I][0x60 / 0x04])
+#define WRITE_MODE              (0)
+#define READ_MODE               (1)
+#define PULSE_GOBBLER_DELAY     (104)   /* In nanoseconds */
+
+static volatile uint32_t *base_address[I2C_CNT] = {
+    (volatile uint32_t *)_I2C1_BASE_ADDRESS,
+#ifdef _I2C2_BASE_ADDRESS
+    (volatile uint32_t *)_I2C2_BASE_ADDRESS,
+#else
+    NULL,
+#endif
+    (volatile uint32_t *)_I2C3_BASE_ADDRESS,
+    (volatile uint32_t *)_I2C4_BASE_ADDRESS,
+    (volatile uint32_t *)_I2C5_BASE_ADDRESS
+};
+
+static int
+send_byte(uint8_t i2c_num, uint8_t data, uint32_t deadline)
+{
+    I2CxTRN(i2c_num) = data;
+
+    while (I2CxSTAT(i2c_num) & _I2C1STAT_TRSTAT_MASK) {
+        if (os_time_get() > deadline) {
+            return 0;
+        }
+    }
+
+    if (I2CxSTAT(i2c_num) & _I2C1STAT_ACKSTAT_MASK) {   /* NACK received */
+        return 0;
+    }
+
+    return 1;
+}
+
+static int
+receive_byte(uint8_t i2c_num, uint8_t *data, uint8_t nak, uint32_t deadline)
+{
+    I2CxCONSET(i2c_num) = _I2C1CON_RCEN_MASK;
+
+    /* Wait for some data in RX FIFO */
+    while (!(I2CxSTAT(i2c_num) & _I2C1STAT_RBF_MASK)) {
+        if (os_time_get() > deadline) {
+            return 0;
+        }
+    }
+
+    /* Send ACK/NAK */
+    if (nak) {
+        I2CxCONSET(i2c_num) = _I2C1CON_ACKDT_MASK;
+    } else {
+        I2CxCONCLR(i2c_num) = _I2C1CON_ACKDT_MASK;
+    }
+
+    I2CxCONSET(i2c_num) = _I2C1CON_ACKEN_MASK;
+    while (I2CxCON(i2c_num) & _I2C1CON_ACKEN_MASK) {
+        if (os_time_get() > deadline) {
+            return 0;
+        }
+    }
+
+    *data = I2CxRCV(i2c_num);
+    return 1;
+}
+
+static int
+send_address(uint8_t i2c_num, uint8_t address, uint8_t read_byte,
+             uint32_t deadline)
+{
+    return send_byte(i2c_num, (address << 1) | (read_byte & 0x1), deadline);
+}
+
+static int
+send_start(uint8_t i2c_num, uint32_t deadline)
+{
+    I2CxCONSET(i2c_num) = _I2C1CON_SEN_MASK;
+    while (I2CxCON(i2c_num) & _I2C1CON_SEN_MASK) {
+        if (os_time_get() > deadline) {
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+static int
+send_stop(uint8_t i2c_num, uint32_t deadline)
+{
+    I2CxCONSET(i2c_num) = _I2C1CON_PEN_MASK;
+    while (I2CxCON(i2c_num) & _I2C1CON_PEN_MASK) {
+        if (os_time_get() > deadline) {
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+static uint32_t
+hal_i2c_get_peripheral_clock(void)
+{
+    return SystemCoreClock / ((PB2DIV & _PB2DIV_PBDIV_MASK) + 1);
+}
+
+int
+hal_i2c_init(uint8_t i2c_num, void *cfg)
+{
+    struct mips_i2c_cfg *config;
+    uint64_t baudrate;
+
+    if (cfg == NULL) {
+        return -1;
+    }
+
+    config = (struct mips_i2c_cfg *)cfg;
+
+    /* Configure SCL and SDA as digital output */
+    if (hal_gpio_init_out(config->scl, 1) ||
+        hal_gpio_init_out(config->sda, 1)) {
+        return -1;
+    }
+
+    I2CxCON(i2c_num) = 0;
+
+    /*
+     * From PIC32 family reference manual,
+     * Section 24. Inter-Integrated Circuit, Equation 24-1:
+     *
+     *               10^9
+     *              -------  - PGD
+     *              2*Fsck
+     * baudrate = ----------------- * Pbclk - 2
+     *                10^9
+     */
+    baudrate =
+        (1000 * 1000 * 1000) / (2 * config->frequency) - PULSE_GOBBLER_DELAY;
+    baudrate *= hal_i2c_get_peripheral_clock();
+    baudrate /= (1000 * 1000 * 1000);
+    baudrate -= 2;
+
+    /* I2CxBRG must not be set to 0 or 1 */
+    if (baudrate == 0 || baudrate == 1)
+        return -2;
+
+    I2CxBRG(i2c_num) = baudrate;
+    I2CxCONSET(i2c_num) = _I2C1CON_SMEN_MASK;
+    I2CxCONSET(i2c_num) = _I2C1CON_ON_MASK;
+
+    return 0;
+}
+
+int
+hal_i2c_master_write(uint8_t i2c_num, struct hal_i2c_master_data *pdata,
+                     uint32_t timeout, uint8_t last_op)
+{
+    uint16_t byte_sent_count = 0;
+    int ret = 0;
+    uint32_t deadline = os_time_get() + timeout;
+
+    if (send_start(i2c_num, deadline)) {
+        ret = -1;
+        goto hal_i2c_master_write_stop;
+    }
+
+    if (send_address(i2c_num, pdata->address, WRITE_MODE, deadline) != 1) {
+        ret = -1;
+        goto hal_i2c_master_write_stop;
+    }
+
+    while (byte_sent_count < pdata->len) {
+        if (send_byte(i2c_num, pdata->buffer[byte_sent_count],
+                      deadline) != 1) {
+            ret = -1;
+            goto hal_i2c_master_write_stop;
+        }
+        ++byte_sent_count;
+    }
+
+    if (!last_op) {
+        return ret;
+    }
+
+hal_i2c_master_write_stop:
+    if (send_stop(i2c_num, deadline)) {
+        ret = -1;
+    }
+
+    return ret;
+}
+
+int
+hal_i2c_master_read(uint8_t i2c_num, struct hal_i2c_master_data *pdata,
+                    uint32_t timeout, uint8_t last_op)
+{
+    int ret = 0;
+    uint16_t byte_received_count = 0;
+    uint32_t deadline = os_time_get() + timeout;
+
+    if (i2c_num >= I2C_CNT) {
+        return -1;
+    }
+
+    if (send_start(i2c_num, deadline)) {
+        ret = -1;
+        goto hal_i2c_master_read_stop;
+    }
+
+    if (send_address(i2c_num, pdata->address, READ_MODE, deadline) != 1) {
+        ret = -1;
+        goto hal_i2c_master_read_stop;
+    }
+
+    while (byte_received_count < pdata->len) {
+        if (receive_byte(i2c_num, &pdata->buffer[byte_received_count],
+                         (byte_received_count + 1) == pdata->len,
+                         deadline) != 1) {
+            ret = -1;
+            goto hal_i2c_master_read_stop;
+        }
+        ++byte_received_count;
+    }
+
+    if (!last_op) {
+        return ret;
+    }
+
+hal_i2c_master_read_stop:
+    if (send_stop(i2c_num, deadline)) {
+        ret = -1;
+    }
+
+    return ret;
+}
+
+int
+hal_i2c_master_probe(uint8_t i2c_num, uint8_t address,
+                     uint32_t timeout)
+{
+    struct hal_i2c_master_data data;
+
+    data.address = address;
+    data.buffer = NULL;
+    data.len = 0;
+
+    return hal_i2c_master_write(i2c_num, &data, timeout, 1);
+}
diff --git a/hw/mcu/microchip/pic32mz/src/hal_os_tick.c b/hw/mcu/microchip/pic32mz/src/hal_os_tick.c
new file mode 100644
index 0000000..dcf2d54
--- /dev/null
+++ b/hw/mcu/microchip/pic32mz/src/hal_os_tick.c
@@ -0,0 +1,39 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <assert.h>
+#include <os/mynewt.h>
+#include <hal/hal_os_tick.h>
+#include <mcu/mcu.h>
+
+/*
+ * XXX implement tickless mode.
+ */
+void
+os_tick_idle(os_time_t ticks)
+{
+    OS_ASSERT_CRITICAL();
+
+    _wait();
+}
+
+void
+os_tick_init(uint32_t os_ticks_per_sec, int prio)
+{
+}
diff --git a/hw/mcu/microchip/pic32mz/src/hal_reset_cause.c b/hw/mcu/microchip/pic32mz/src/hal_reset_cause.c
new file mode 100644
index 0000000..802de33
--- /dev/null
+++ b/hw/mcu/microchip/pic32mz/src/hal_reset_cause.c
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <xc.h>
+#include <hal/hal_system.h>
+
+enum hal_reset_reason
+hal_reset_cause(void)
+{
+    static enum hal_reset_reason reason;
+
+    if (reason) {
+        return reason;
+    }
+
+    if (RCON & _RCON_WDTO_MASK) {
+        reason = HAL_RESET_WATCHDOG;
+    } else if (RCON & _RCON_SWR_MASK) {
+        reason = HAL_RESET_SOFT;
+    } else if (RCON & _RCON_EXTR_MASK) {
+        reason = HAL_RESET_PIN;
+    } else if (RCON & _RCON_POR_MASK) {
+        reason = HAL_RESET_POR;
+    } else if (RCON & _RCON_BOR_MASK) {
+        reason = HAL_RESET_BROWNOUT;
+    }
+
+    RCONCLR = _RCON_EXTR_MASK | _RCON_SWR_MASK | _RCON_WDTO_MASK |
+              _RCON_BOR_MASK | _RCON_POR_MASK;
+
+    return reason;
+}
diff --git a/hw/mcu/microchip/pic32mz/src/hal_spi.c b/hw/mcu/microchip/pic32mz/src/hal_spi.c
new file mode 100644
index 0000000..16ccada
--- /dev/null
+++ b/hw/mcu/microchip/pic32mz/src/hal_spi.c
@@ -0,0 +1,707 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <xc.h>
+#include <os/mynewt.h>
+#include <bsp/bsp.h>
+#include <hal/hal_gpio.h>
+#include <hal/hal_spi.h>
+#include <mcu/mcu.h>
+#include <mcu/mips_hal.h>
+#include <mcu/pps.h>
+
+#define SPIxCON(P)          (base_address[P][0x0 / 0x4])
+#define SPIxCONCLR(P)       (base_address[P][0x4 / 0x4])
+#define SPIxCONSET(P)       (base_address[P][0x8 / 0x4])
+#define SPIxSTAT(P)         (base_address[P][0x10 / 0x4])
+#define SPIxSTATCLR(P)      (base_address[P][0x14 / 0x4])
+#define SPIxBUF(P)          (base_address[P][0x20 / 0x4])
+#define SPIxBRG(P)          (base_address[P][0x30 / 0x4])
+#define SPIxCON2(P)         (base_address[P][0x40 / 0x4])
+
+static volatile uint32_t * base_address[SPI_CNT] = {
+    (volatile uint32_t *)_SPI1_BASE_ADDRESS,
+    (volatile uint32_t *)_SPI2_BASE_ADDRESS,
+    (volatile uint32_t *)_SPI3_BASE_ADDRESS,
+    (volatile uint32_t *)_SPI4_BASE_ADDRESS,
+#ifdef _SPI5
+    (volatile uint32_t *)_SPI5_BASE_ADDRESS,
+#endif
+#ifdef _SPI6
+    (volatile uint32_t *)_SPI6_BASE_ADDRESS,
+#endif
+};
+
+struct hal_spi {
+    bool                      slave;
+    uint8_t                   *txbuf;
+    uint8_t                   *rxbuf;
+    int                       len;
+    int                       txcnt;
+    int                       rxcnt;
+    hal_spi_txrx_cb           callback;
+    void                      *arg;
+    const struct mips_spi_cfg *pins;
+    uint32_t                  con;
+    uint32_t                  brg;
+};
+
+static struct hal_spi spis[SPI_CNT];
+
+static void
+hal_spi_power_up(int spi_num)
+{
+    uint32_t mask = 0;
+
+    switch (spi_num) {
+#if MYNEWT_VAL(SPI_0_MASTER)
+    case 0:
+        mask = _PMD5_SPI1MD_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(SPI_1_MASTER)
+    case 1:
+        mask = _PMD5_SPI2MD_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(SPI_2_MASTER)
+    case 2:
+        mask = _PMD5_SPI3MD_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(SPI_3_MASTER)
+    case 3:
+        mask = _PMD5_SPI4MD_MASK;
+        break;
+#endif
+#if defined(_SPI5) && MYNEWT_VAL(SPI_4_MASTER)
+    case 4:
+        mask = _PMD5_SPI5MD_MASK;
+        break;
+#endif
+#if defined(_SPI6) && MYNEWT_VAL(SPI_5_MASTER)
+    case 5:
+        mask = _PMD5_SPI6MD_MASK;
+        break;
+#endif
+    }
+
+    if (!(PMD5 & mask)) {
+        return;
+    }
+
+    PMD5CLR = mask;
+
+    /* It appeared that powering down the SPI module also clears SPIxBRG and SPIxCON */
+    SPIxBRG(spi_num) = spis[spi_num].brg;
+    SPIxCON(spi_num) = spis[spi_num].con;
+}
+
+static void
+hal_spi_power_down(int spi_num)
+{
+    /* It appeared that powering down the SPI module also clears SPIxBRG and SPIxCON */
+    spis[spi_num].brg = SPIxBRG(spi_num);
+    spis[spi_num].con = SPIxCON(spi_num);
+
+    switch (spi_num) {
+#if MYNEWT_VAL(SPI_0_MASTER)
+    case 0:
+        PMD5SET = _PMD5_SPI1MD_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(SPI_1_MASTER)
+    case 1:
+        PMD5SET = _PMD5_SPI2MD_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(SPI_2_MASTER)
+    case 2:
+        PMD5SET = _PMD5_SPI3MD_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(SPI_3_MASTER)
+    case 3:
+        PMD5SET = _PMD5_SPI4MD_MASK;
+        break;
+#endif
+#if defined(_SPI5) && MYNEWT_VAL(SPI_4_MASTER)
+    case 4:
+        PMD5SET = _PMD5_SPI5MD_MASK;
+        break;
+#endif
+#if defined(_SPI6) && MYNEWT_VAL(SPI_5_MASTER)
+    case 5:
+        PMD5SET = _PMD5_SPI6MD_MASK;
+        break;
+#endif
+    }
+}
+
+static int
+hal_spi_config_master(int spi_num, struct hal_spi_settings *psettings)
+{
+    uint32_t pbclk;
+
+    /*
+     * Make sure that the SPI module is not powered down.
+     * If the module is powered down, one cannot write to registers.
+     */
+    hal_spi_power_up(spi_num);
+
+    SPIxCON(spi_num) = 0;
+    SPIxCON2(spi_num) = 0;
+
+    /* Clear RX FIFO */
+    while (!(SPIxSTAT(spi_num) & _SPI1STAT_SPITBE_MASK)) {
+        (void)SPIxBUF(spi_num);
+    }
+
+    /* The SPI module only supports MSB first */
+    if (psettings->data_order == HAL_SPI_LSB_FIRST) {
+        return -1;
+    }
+
+    /* Only 8-bit word size is supported */
+    if (psettings->word_size != HAL_SPI_WORD_SIZE_8BIT) {
+        return -1;
+    }
+
+    switch (psettings->data_mode) {
+    case HAL_SPI_MODE0:
+        SPIxCONCLR(spi_num) = _SPI1CON_CKP_MASK;
+        SPIxCONSET(spi_num) = _SPI1CON_CKE_MASK;
+        break;
+    case HAL_SPI_MODE1:
+        SPIxCONCLR(spi_num) = _SPI1CON_CKP_MASK | _SPI1CON_CKE_MASK;
+        break;
+    case HAL_SPI_MODE2:
+        SPIxCONSET(spi_num) = _SPI1CON_CKP_MASK | _SPI1CON_CKE_MASK;
+        break;
+    case HAL_SPI_MODE3:
+        SPIxCONCLR(spi_num) = _SPI1CON_CKE_MASK;
+        SPIxCONSET(spi_num) = _SPI1CON_CKP_MASK;
+        break;
+    default:
+        return -1;
+    }
+
+    /*
+     * From equation 23-1 of Section 23 of PIC32 FRM:
+     *
+     *                 Fpb2
+     * Fsck =  -------------------
+     *          2 * (SPIxBRG + 1)
+     */
+    pbclk = SystemCoreClock / ((PB2DIV & _PB2DIV_PBDIV_MASK) + 1);
+    SPIxBRG(spi_num) = (pbclk / (2 * psettings->baudrate * 1000)) - 1;
+
+    SPIxSTATCLR(spi_num) = _SPI1STAT_SPIROV_MASK;
+    SPIxCONSET(spi_num) = _SPI1CON_ENHBUF_MASK | _SPI1CON_MSTEN_MASK;
+
+    return 0;
+}
+
+static int
+hal_spi_config_pins(int spi_num, uint8_t mode)
+{
+    int ret = 0;
+
+    if (hal_gpio_init_out(spis[spi_num].pins->mosi, 0) ||
+        hal_gpio_init_out(spis[spi_num].pins->sck, 1) ||
+        hal_gpio_init_in(spis[spi_num].pins->miso, HAL_GPIO_PULL_NONE)) {
+        return -1;
+    }
+
+    /*
+     * To avoid any glitches when turning off and on module, the SCK pin must
+     * be set to the correct value depending on the mode.
+     */
+    switch (mode) {
+    case HAL_SPI_MODE0:
+    case HAL_SPI_MODE1:
+        hal_gpio_write(spis[spi_num].pins->sck, 0);
+        break;
+    case HAL_SPI_MODE2:
+    case HAL_SPI_MODE3:
+        hal_gpio_write(spis[spi_num].pins->sck, 1);
+        break;
+    }
+
+    switch (spi_num) {
+#if MYNEWT_VAL(SPI_0_MASTER)
+    case 0:
+        ret += pps_configure_output(spis[spi_num].pins->mosi, SDO1_OUT_FUNC);
+        ret += pps_configure_input(spis[spi_num].pins->miso, SDI1_IN_FUNC);
+        break;
+#endif
+#if MYNEWT_VAL(SPI_1_MASTER)
+    case 1:
+        ret += pps_configure_output(spis[spi_num].pins->mosi, SDO2_OUT_FUNC);
+        ret += pps_configure_input(spis[spi_num].pins->miso, SDI2_IN_FUNC);
+        break;
+#endif
+#if MYNEWT_VAL(SPI_2_MASTER)
+    case 2:
+        ret += pps_configure_output(spis[spi_num].pins->mosi, SDO3_OUT_FUNC);
+        ret += pps_configure_input(spis[spi_num].pins->miso, SDI3_IN_FUNC);
+        break;
+#endif
+#if MYNEWT_VAL(SPI_3_MASTER)
+    case 3:
+        ret += pps_configure_output(spis[spi_num].pins->mosi, SDO4_OUT_FUNC);
+        ret += pps_configure_input(spis[spi_num].pins->miso, SDI4_IN_FUNC);
+        break;
+#endif
+#if defined(_SPI5) && MYNEWT_VAL(SPI_4_MASTER)
+    case 4:
+        ret += pps_configure_output(spis[spi_num].pins->mosi,
+                                    SDO5_OUT_FUNC);
+        ret += pps_configure_input(spis[spi_num].pins->miso,
+                                   SDI5_IN_FUNC);
+        break;
+#endif
+#if defined(_SPI6) && MYNEWT_VAL(SPI_5_MASTER)
+    case 5:
+        ret += pps_configure_output(spis[spi_num].pins->mosi,
+                                    SDO6_OUT_FUNC);
+        ret += pps_configure_input(spis[spi_num].pins->miso,
+                                   SDI6_IN_FUNC);
+        break;
+#endif
+    }
+
+    return ret;
+}
+
+static void
+hal_spi_enable_int(int spi_num)
+{
+    switch (spi_num) {
+#if MYNEWT_VAL(SPI_0_MASTER)
+    case 0:
+        IFS3CLR = _IFS3_SPI1TXIF_MASK;
+        IEC3SET = _IEC3_SPI1TXIE_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(SPI_1_MASTER)
+    case 1:
+        IFS4CLR = _IFS4_SPI2TXIF_MASK;
+        IEC4SET = _IEC4_SPI2TXIE_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(SPI_2_MASTER)
+    case 2:
+        IFS4CLR = _IFS4_SPI3TXIF_MASK;
+        IEC4SET = _IEC4_SPI3TXIE_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(SPI_3_MASTER)
+    case 3:
+        IFS5CLR = _IFS5_SPI4TXIF_MASK;
+        IEC5SET = _IEC5_SPI4TXIE_MASK;
+        break;
+#endif
+#if defined(_SPI5) && MYNEWT_VAL(SPI_4_MASTER)
+    case 4:
+        IFS5CLR = _IFS5_SPI5TXIF_MASK;
+        IEC5SET = _IEC5_SPI5TXIE_MASK;
+        break;
+#endif
+#if defined(_SPI6) && MYNEWT_VAL(SPI_5_MASTER)
+    case 5:
+        IFS5CLR = _IFS5_SPI6TX_MASK;
+        IEC5SET = _IEC5_SPI6TXIE_MASK;
+        break;
+#endif
+    }
+}
+
+static void
+hal_spi_disable_int(int spi_num)
+{
+    switch (spi_num) {
+#if MYNEWT_VAL(SPI_0_MASTER)
+    case 0:
+        IFS3CLR = _IFS3_SPI1TXIF_MASK;
+        IEC3CLR = _IEC3_SPI1TXIE_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(SPI_1_MASTER)
+    case 1:
+        IFS4CLR = _IFS4_SPI2TXIF_MASK;
+        IEC4CLR = _IEC4_SPI2TXIE_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(SPI_2_MASTER)
+    case 2:
+        IFS4CLR = _IFS4_SPI3TXIF_MASK;
+        IEC4CLR = _IEC4_SPI3TXIE_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(SPI_3_MASTER)
+    case 3:
+        IFS5CLR = _IFS5_SPI4TXIF_MASK;
+        IEC5CLR = _IEC5_SPI4TXIE_MASK;
+        break;
+#endif
+#if defined(_SPI5) && MYNEWT_VAL(SPI_4_MASTER)
+    case 4:
+        IFS5CLR = _IFS5_SPI5TXIF_MASK;
+        IEC5CLR = _IEC5_SPI5TXIE_MASK;
+        break;
+#endif
+#if defined(_SPI6) && MYNEWT_VAL(SPI_5_MASTER)
+    case 5:
+        IFS5CLR = _IFS5_SPI6TX_MASK;
+        IEC5CLR = _IEC5_SPI6TXIE_MASK;
+        break;
+#endif
+    }
+}
+
+static void
+hal_spi_handle_isr(int spi_num)
+{
+    uint32_t rxdata;
+
+    /* Read everything in RX FIFO */
+    while (!(SPIxSTAT(spi_num) & _SPI1STAT_SPIRBE_MASK)) {
+        rxdata = SPIxBUF(spi_num);
+        if (spis[spi_num].rxbuf && spis[spi_num].rxcnt) {
+            *spis[spi_num].rxbuf++ = rxdata;
+            --spis[spi_num].rxcnt;
+        }
+    }
+
+    if (spis[spi_num].txcnt == 0 && spis[spi_num].rxcnt == 0) {
+        spis[spi_num].txbuf = NULL;
+        spis[spi_num].rxbuf = NULL;
+
+        if (spis[spi_num].callback) {
+            spis[spi_num].callback(spis[spi_num].arg, spis[spi_num].len);
+        }
+        hal_spi_disable_int(spi_num);
+    }
+
+
+    /* Fill TX FIFO */
+    while (spis[spi_num].txcnt &&
+           !(SPIxSTAT(spi_num) & _SPI1STAT_SPITBF_MASK)) {
+        SPIxBUF(spi_num) = *spis[spi_num].txbuf++;
+        --spis[spi_num].txcnt;
+    }
+}
+
+#if MYNEWT_VAL(SPI_0_MASTER)
+void
+__attribute__((interrupt(IPL2AUTO), vector(_SPI1_TX_VECTOR)))
+hal_spi1_isr(void)
+{
+    hal_spi_handle_isr(0);
+    IFS3CLR = _IFS3_SPI1TXIF_MASK;
+}
+#endif
+
+#if MYNEWT_VAL(SPI_1_MASTER)
+void
+__attribute__((interrupt(IPL2AUTO), vector(_SPI2_TX_VECTOR)))
+hal_spi2_isr(void)
+{
+    hal_spi_handle_isr(1);
+    IFS4CLR = _IFS4_SPI2TXIF_MASK;
+}
+#endif
+
+#if MYNEWT_VAL(SPI_2_MASTER)
+void
+__attribute__((interrupt(IPL2AUTO), vector(_SPI3_TX_VECTOR)))
+hal_spi3_isr(void)
+{
+    hal_spi_handle_isr(2);
+    IFS4CLR = _IFS4_SPI3TXIF_MASK;
+}
+
+#endif
+
+#if MYNEWT_VAL(SPI_3_MASTER)
+void
+__attribute__((interrupt(IPL2AUTO), vector(_SPI4_TX_VECTOR)))
+hal_spi4_isr(void)
+{
+    hal_spi_handle_isr(3);
+    IFS5CLR = _IFS5_SPI4TXIF_MASK;
+}
+#endif
+
+#if defined(_SPI5) && MYNEWT_VAL(SPI_4_MASTER)
+void
+__attribute__((interrupt(IPL2AUTO), vector(_SPI5_TX_VECTOR)))
+hal_spi5_isr(void)
+{
+    hal_spi_handle_isr(4);
+    IFS5CLR = _IFS5_SPI5TXIF_MASK;
+}
+#endif
+
+#if defined(_SPI6) && MYNEWT_VAL(SPI_5_MASTER)
+void
+__attribute__((interrupt(IPL2AUTO), vector(_SPI6_TX_VECTOR)))
+hal_spi6_isr(void)
+{
+    hal_spi_handle_isr(5);
+    IFS5CLR = _IFS5_SPI6TX_MASK;
+}
+#endif
+
+int
+hal_spi_init(int spi_num, void *cfg, uint8_t spi_type)
+{
+    if (spi_type != HAL_SPI_TYPE_MASTER &&
+        spi_type != HAL_SPI_TYPE_SLAVE) {
+        return -1;
+    }
+
+    spis[spi_num].slave = spi_type;
+    spis[spi_num].pins = cfg;
+
+    return 0;
+}
+
+int
+hal_spi_config(int spi_num, struct hal_spi_settings *psettings)
+{
+    /* Slave mode not supported */
+    if (spis[spi_num].slave) {
+        return -1;
+    }
+
+    /* Configure pins */
+    if (spis[spi_num].pins) {
+        if (hal_spi_config_pins(spi_num, psettings->data_mode)) {
+            return -1;
+        }
+    }
+
+    return hal_spi_config_master(spi_num, psettings);
+}
+
+int
+hal_spi_set_txrx_cb(int spi_num, hal_spi_txrx_cb txrx_cb, void *arg)
+{
+    if (SPIxCON(spi_num) & _SPI1CON_ON_MASK) {
+        return -1;
+    }
+
+    spis[spi_num].callback = txrx_cb;
+    spis[spi_num].arg = arg;
+    return 0;
+}
+
+int
+hal_spi_enable(int spi_num)
+{
+    hal_spi_power_up(spi_num);
+    SPIxCONSET(spi_num) = _SPI1CON_ON_MASK;
+
+    return 0;
+}
+
+int
+hal_spi_disable(int spi_num)
+{
+    /*
+     * Disabling SPI clears the FIFO, so this makes sure that everything was
+     * sent before disabling the module.
+     */
+    while (!(SPIxSTAT(spi_num) & _SPI1STAT_SPITBE_MASK)) {
+    }
+
+    SPIxCONCLR(spi_num) = _SPI1CON_ON_MASK;
+    hal_spi_power_down(spi_num);
+
+    return 0;
+}
+
+uint16_t
+hal_spi_tx_val(int spi_num, uint16_t val)
+{
+    if (spis[spi_num].slave) {
+        return 0xFFFF;
+    }
+
+    /* Wait until there is some space in TX FIFO */
+    while (SPIxSTAT(spi_num) & _SPI1STAT_SPITBF_MASK) {
+    }
+
+    SPIxBUF(spi_num) = val;
+
+    /* Wait until RX FIFO is not empty */
+    while (SPIxSTAT(spi_num) & _SPI1STAT_SPIRBE_MASK) {
+    }
+
+    return SPIxBUF(spi_num);
+}
+
+int
+hal_spi_txrx(int spi_num, void *txbuf, void *rxbuf, int cnt)
+{
+    uint8_t rdata;
+    uint8_t *tx = (uint8_t *)txbuf;
+    uint8_t *rx = (uint8_t *)rxbuf;
+
+    /* Slave mode not supported */
+    if (spis[spi_num].slave) {
+        return -1;
+    }
+
+    while (cnt--) {
+        if (tx) {
+            /* Wait until there is some space in TX FIFO */
+            while (SPIxSTAT(spi_num) & _SPI1STAT_SPITBF_MASK) {
+            }
+
+            SPIxBUF(spi_num) = *tx++;
+        }
+
+        /* Wait until RX FIFO is not empty */
+        while (SPIxSTAT(spi_num) & _SPI1STAT_SPIRBE_MASK) {
+        }
+
+        /* Always read RX FIFO to avoid overrun */
+        rdata = SPIxBUF(spi_num);
+
+        if (rx) {
+            *rx++ = rdata;
+        }
+    }
+
+    return 0;
+}
+
+int
+hal_spi_txrx_noblock(int spi_num, void *txbuf, void *rxbuf, int cnt)
+{
+    uint32_t ctx;
+
+    /* Slave mode not supported */
+    if (spis[spi_num].slave) {
+        return -1;
+    }
+
+    if (txbuf == NULL) {
+        return -1;
+    }
+
+    /* Check if a transfer is pending */
+    if (spis[spi_num].rxbuf != NULL || spis[spi_num].txbuf != NULL) {
+        return -1;
+    }
+
+    spis[spi_num].txbuf = txbuf;
+    spis[spi_num].rxbuf = rxbuf;
+    spis[spi_num].txcnt = cnt;
+    spis[spi_num].rxcnt = cnt;
+    spis[spi_num].len = cnt;
+
+    /* Configure SPIxTXIF to trigger when TX FIFO is empty */
+    SPIxCONCLR(spi_num) = _SPI1CON_STXISEL_MASK;
+    SPIxCONSET(spi_num) = 0b01 << _SPI1CON_STXISEL_POSITION;
+
+    /* Set interrupt priority */
+    switch (spi_num) {
+#if MYNEWT_VAL(SPI_0_MASTER)
+    case 0:
+        IPC27CLR = _IPC27_SPI1TXIS_MASK | _IPC27_SPI1TXIP_MASK;
+        IPC27SET = 2 << _IPC27_SPI1TXIP_POSITION;
+        break;
+#endif
+#if MYNEWT_VAL(SPI_1_MASTER)
+    case 1:
+        IPC36CLR = _IPC36_SPI2TXIS_MASK | _IPC36_SPI2TXIP_MASK;
+        IPC36SET = 2 << _IPC36_SPI2TXIP_POSITION;
+        break;
+#endif
+#if MYNEWT_VAL(SPI_2_MASTER)
+    case 2:
+        IPC39CLR = _IPC39_SPI3TXIS_MASK | _IPC39_SPI3TXIP_MASK;
+        IPC39SET = 2 << _IPC39_SPI3TXIP_POSITION;
+        break;
+#endif
+#if MYNEWT_VAL(SPI_3_MASTER)
+    case 3:
+        IPC41CLR = _IPC41_SPI4TXIS_MASK | _IPC41_SPI4TXIP_MASK;
+        IPC41SET = 2 << _IPC41_SPI4TXIP_POSITION;
+        break;
+#endif
+#if defined(_SPI5) && MYNEWT_VAL(SPI_4_MASTER)
+    case 4:
+        IPC44CLR = _IPC44_SPI5TXIS_MASK | _IPC44_SPI5TXIP_MASK;
+        IPC44SET = 2 << _IPC44_SPI5TXIP_POSITION;
+        break;
+#endif
+#if defined(_SPI6) && MYNEWT_VAL(SPI_5_MASTER)
+    case 5:
+        IPC46CLR = _IPC46_SPI6TXIS_MASK | _IPC46_SPI6TXIP_MASK;
+        IPC46SET = 2 << _IPC46_SPI6TXIP_POSITION;
+        break;
+#endif
+    }
+
+    /* Enable interrupt */
+    hal_spi_enable_int(spi_num);
+
+    return 0;
+}
+
+int
+hal_spi_slave_set_def_tx_val(int spi_num, uint16_t val)
+{
+    /* Slave mode not supported */
+    return -1;
+}
+
+int
+hal_spi_abort(int spi_num)
+{
+    /* Cannot abort transfer if spi is not enabled */
+    if (!(SPIxCON(spi_num) & _SPI1CON_ON_MASK)) {
+        return -1;
+    }
+
+    hal_spi_disable_int(spi_num);
+    spis[spi_num].txbuf = NULL;
+    spis[spi_num].rxbuf = NULL;
+    spis[spi_num].txcnt = 0;
+    spis[spi_num].rxcnt = 0;
+    spis[spi_num].len = 0;
+
+    /* Make sure that we finished transmitting current byte before turning off module */
+    while (!(SPIxSTAT(spi_num) & _SPI1STAT_SRMT_MASK)) {
+    }
+
+    /* Clear TX and RX FIFO by turning off and on module */
+    SPIxCONCLR(spi_num) = _SPI1CON_ON_MASK;
+    asm volatile ("nop");
+    SPIxCONSET(spi_num) = _SPI1CON_ON_MASK;
+
+    return 0;
+}
diff --git a/hw/mcu/microchip/pic32mz/src/hal_system.c b/hw/mcu/microchip/pic32mz/src/hal_system.c
new file mode 100644
index 0000000..50b1fcd
--- /dev/null
+++ b/hw/mcu/microchip/pic32mz/src/hal_system.c
@@ -0,0 +1,52 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <syscfg/syscfg.h>
+#include <hal/hal_system.h>
+
+#include <xc.h>
+
+void
+hal_system_reset(void)
+{
+
+#if MYNEWT_VAL(HAL_SYSTEM_RESET_CB)
+    hal_system_reset_cb();
+#endif
+
+    /* Unlock sequence */
+    SYSKEY = 0x00000000;
+    SYSKEY = 0xAA996655;
+    SYSKEY = 0x556699AA;
+
+    /* Enable Software reset */
+    RSWRSTSET = _RSWRST_SWRST_MASK;
+
+    /* Dummy read of RSWRST register to trigger reset */
+    RSWRST;
+
+    while (1) {
+    }
+}
+
+int
+hal_debugger_connected(void)
+{
+    return 1;
+}
diff --git a/hw/mcu/microchip/pic32mz/src/hal_system_start.c b/hw/mcu/microchip/pic32mz/src/hal_system_start.c
new file mode 100644
index 0000000..588fb01
--- /dev/null
+++ b/hw/mcu/microchip/pic32mz/src/hal_system_start.c
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <assert.h>
+
+#define PHY_TO_VIRT(address)   (unsigned int)((int)(address) | 0x80000000)
+
+void
+hal_system_start(void *img_start)
+{
+    void (*app_reset)(void) = (void (*)(void))PHY_TO_VIRT(img_start);
+
+    app_reset();
+    while (1);
+}
+
+void
+hal_system_restart(void *img_start)
+{
+    hal_system_restart(img_start);
+}
+
diff --git a/hw/mcu/microchip/pic32mz/src/hal_timer.c b/hw/mcu/microchip/pic32mz/src/hal_timer.c
new file mode 100644
index 0000000..45b95ce
--- /dev/null
+++ b/hw/mcu/microchip/pic32mz/src/hal_timer.c
@@ -0,0 +1,599 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <os/mynewt.h>
+#include <xc.h>
+#include <mcu/pic32.h>
+#include <hal/hal_timer.h>
+#include <mcu/mips_hal.h>
+
+#define PIC32MZ_TIMER_COUNT         (8)
+#define PIC32MZ_PRESCALER_COUNT     (8)
+
+#define TxCON(T)        (base_address[T][0x0 / 0x4])
+#define TxCONCLR(T)     (base_address[T][0x4 / 0x4])
+#define TxCONSET(T)     (base_address[T][0x8 / 0x4])
+#define TMRx(T)         (base_address[T][0x10 / 0x4])
+#define PRx(T)          (base_address[T][0x20 / 0x4])
+
+static volatile uint32_t * base_address[PIC32MZ_TIMER_COUNT] = {
+    (volatile uint32_t *)_TMR2_BASE_ADDRESS,
+    (volatile uint32_t *)_TMR3_BASE_ADDRESS,
+    (volatile uint32_t *)_TMR4_BASE_ADDRESS,
+    (volatile uint32_t *)_TMR5_BASE_ADDRESS,
+    (volatile uint32_t *)_TMR6_BASE_ADDRESS,
+    (volatile uint32_t *)_TMR7_BASE_ADDRESS,
+    (volatile uint32_t *)_TMR8_BASE_ADDRESS,
+    (volatile uint32_t *)_TMR9_BASE_ADDRESS
+};
+
+static uint32_t timer_prescalers[PIC32MZ_PRESCALER_COUNT] =
+    {1, 2, 4, 8, 16, 32, 64, 256};
+
+struct pic32_timer {
+    uint32_t index;
+    uint32_t counter;
+    uint32_t frequency;     /* Holds the true frequency of the timer */
+    TAILQ_HEAD(hal_timer_qhead, hal_timer) hal_timer_queue;
+};
+static struct pic32_timer timers[PIC32MZ_TIMER_COUNT];
+
+
+static inline uint32_t
+hal_timer_get_prescaler(int timer_num)
+{
+    uint32_t index =
+        (TxCON(timer_num) & _T2CON_TCKPS_MASK) >> _T2CON_TCKPS_POSITION;
+    return timer_prescalers[index];
+}
+
+static inline uint32_t
+hal_timer_get_peripheral_base_clock(void)
+{
+    return SystemCoreClock / ((PB3DIV & _PB3DIV_PBDIV_MASK) + 1);
+}
+
+static void
+hal_timer_enable_int(int timer_num)
+{
+    switch (timer_num) {
+#if MYNEWT_VAL(TIMER_0)
+    case 0:
+        IPC2CLR = _IPC2_T2IP_MASK | _IPC2_T2IS_MASK;
+        IPC2SET = 3 << _IPC2_T2IP_POSITION;
+        IFS0CLR = _IFS0_T2IF_MASK;
+        IEC0SET = _IEC0_T2IE_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(TIMER_1)
+    case 1:
+        IPC3CLR = _IPC3_T3IP_MASK | _IPC3_T3IS_MASK;
+        IPC3SET = 3 << _IPC3_T3IP_POSITION;
+        IFS0CLR = _IFS0_T3IF_MASK;
+        IEC0SET = _IEC0_T3IE_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(TIMER_2)
+    case 2:
+        IPC4CLR = _IPC4_T4IP_MASK | _IPC4_T4IS_MASK;
+        IPC4SET = 3 << _IPC4_T4IP_POSITION;
+        IFS0CLR = _IFS0_T4IF_MASK;
+        IEC0SET = _IEC0_T4IE_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(TIMER_3)
+    case 3:
+        IPC6CLR = _IPC6_T5IP_MASK | _IPC6_T5IS_MASK;
+        IPC6SET = 3 << _IPC6_T5IP_POSITION;
+        IFS0CLR = _IFS0_T5IF_MASK;
+        IEC0SET = _IEC0_T5IE_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(TIMER_4)
+    case 4:
+        IPC7CLR = _IPC7_T6IP_MASK | _IPC7_T6IS_MASK;
+        IPC7SET = 3 << _IPC7_T6IP_POSITION;
+        IFS0CLR = _IFS0_T6IF_MASK;
+        IEC0SET = _IEC0_T6IE_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(TIMER_5)
+    case 5:
+        IPC8CLR = _IPC8_T7IP_MASK | _IPC8_T7IS_MASK;
+        IPC8SET = 3 << _IPC8_T7IP_POSITION;
+        IFS1CLR = _IFS1_T7IF_MASK;
+        IEC1SET = _IEC1_T7IE_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(TIMER_6)
+    case 6:
+        IPC9CLR = _IPC9_T8IP_MASK | _IPC9_T8IS_MASK;
+        IPC9SET = 3 << _IPC9_T8IP_POSITION;
+        IFS1CLR = _IFS1_T8IF_MASK;
+        IEC1SET = _IEC1_T8IE_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(TIMER_7)
+    case 7:
+        IPC10CLR = _IPC10_T9IP_MASK | _IPC10_T9IS_MASK;
+        IPC10SET = 3 << _IPC10_T9IP_POSITION;
+        IFS1CLR = _IFS1_T9IF_MASK;
+        IEC1SET = _IEC1_T9IE_MASK;
+        break;
+#endif
+    }
+}
+
+static void
+hal_timer_disable_int(int timer_num)
+{
+    switch (timer_num) {
+#if MYNEWT_VAL(TIMER_0)
+    case 0:
+        IEC0CLR = _IEC0_T2IE_MASK;
+        IFS0CLR = _IFS0_T2IF_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(TIMER_1)
+    case 1:
+        IEC0CLR = _IEC0_T3IE_MASK;
+        IFS0CLR = _IFS0_T3IF_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(TIMER_2)
+    case 2:
+        IEC0CLR = _IEC0_T4IE_MASK;
+        IFS0CLR = _IFS0_T4IF_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(TIMER_3)
+    case 3:
+        IEC0CLR = _IEC0_T5IE_MASK;
+        IFS0CLR = _IFS0_T5IF_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(TIMER_4)
+    case 4:
+        IEC0CLR = _IEC0_T6IE_MASK;
+        IFS0CLR = _IFS0_T6IF_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(TIMER_5)
+    case 5:
+        IEC1CLR = _IEC1_T7IE_MASK;
+        IFS1CLR = _IFS1_T7IF_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(TIMER_6)
+    case 6:
+        IEC1CLR = _IEC1_T8IE_MASK;
+        IFS1CLR = _IFS1_T8IF_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(TIMER_7)
+    case 7:
+        IEC1CLR = _IEC1_T9IE_MASK;
+        IFS1CLR = _IFS1_T9IF_MASK;
+        break;
+#endif
+    }
+}
+
+static void
+update_period_register(int timer_num)
+{
+    struct hal_timer *first;
+    uint32_t ticks;
+    uint32_t delta;
+
+    if (TAILQ_EMPTY(&timers[timer_num].hal_timer_queue)) {
+        PRx(timer_num) = UINT16_MAX;
+    } else {
+        first = TAILQ_FIRST(&timers[timer_num].hal_timer_queue);
+        ticks = hal_timer_read(timer_num);
+
+        if (ticks >= first->expiry) {
+            /*
+             * Create a timer interrupt immediately. This case must never
+             * execute inside the interrupt handler (otherwise we would skip
+             * the interrupt).
+             */
+            PRx(timer_num) = TMRx(timer_num) + 1;
+        } else {
+            delta = ticks - first->expiry;
+            if (delta > UINT16_MAX)
+                delta = UINT16_MAX;
+
+            PRx(timer_num) = delta;
+        }
+    }
+}
+
+static inline void
+update_counter(int timer_num)
+{
+    timers[timer_num].counter += PRx(timer_num);
+}
+
+static void
+handle_timer_list(int timer_num)
+{
+    uint32_t current_tick = hal_timer_read(timer_num);
+    struct hal_timer *entry;
+
+    while ((entry = TAILQ_FIRST(&timers[timer_num].hal_timer_queue)) !=
+           NULL) {
+        if (entry->expiry <= current_tick) {
+            TAILQ_REMOVE(&timers[timer_num].hal_timer_queue, entry, link);
+            entry->link.tqe_prev = NULL;
+            entry->link.tqe_next = NULL;
+            entry->cb_func(entry->cb_arg);
+        } else {
+            break;
+        }
+    }
+
+    /*
+     * Even if the list is left unchanged, the period register still needs to
+     * be computed again to ensure that the first callback in the list will
+     * be called on time.
+     */
+    update_period_register(timer_num);
+}
+
+#if MYNEWT_VAL(TIMER_0)
+void
+__attribute__((interrupt(IPL3AUTO), vector(_TIMER_2_VECTOR)))
+timer2_isr(void)
+{
+    update_counter(0);
+    handle_timer_list(0);
+
+    IFS0CLR = _IFS0_T2IF_MASK;
+}
+#endif
+
+#if MYNEWT_VAL(TIMER_1)
+void
+__attribute__((interrupt(IPL3AUTO), vector(_TIMER_3_VECTOR)))
+timer3_isr(void)
+{
+    update_counter(1);
+    handle_timer_list(1);
+
+    IFS0CLR = _IFS0_T3IF_MASK;
+}
+#endif
+
+#if MYNEWT_VAL(TIMER_2)
+void
+__attribute__((interrupt(IPL3AUTO), vector(_TIMER_4_VECTOR)))
+timer4_isr(void)
+{
+    update_counter(2);
+    handle_timer_list(2);
+
+    IFS0CLR = _IFS0_T4IF_MASK;
+}
+#endif
+
+#if MYNEWT_VAL(TIMER_3)
+void
+__attribute__((interrupt(IPL3AUTO), vector(_TIMER_5_VECTOR)))
+timer5_isr(void)
+{
+    update_counter(3);
+    handle_timer_list(3);
+
+    IFS0CLR = _IFS0_T5IF_MASK;
+}
+#endif
+
+#if MYNEWT_VAL(TIMER_4)
+void
+__attribute__((interrupt(IPL3AUTO), vector(_TIMER_6_VECTOR)))
+timer6_isr(void)
+{
+    update_counter(4);
+    handle_timer_list(4);
+
+    IFS0CLR = _IFS0_T6IF_MASK;
+}
+#endif
+
+#if MYNEWT_VAL(TIMER_5)
+void
+__attribute__((interrupt(IPL3AUTO), vector(_TIMER_7_VECTOR)))
+timer7_isr(void)
+{
+    update_counter(5);
+    handle_timer_list(5);
+
+    IFS1CLR = _IFS1_T7IF_MASK;
+}
+#endif
+
+#if MYNEWT_VAL(TIMER_6)
+void
+__attribute__((interrupt(IPL3AUTO), vector(_TIMER_8_VECTOR)))
+timer8_isr(void)
+{
+    update_counter(6);
+    handle_timer_list(6);
+
+    IFS1CLR = _IFS1_T8IF_MASK;
+}
+#endif
+
+#if MYNEWT_VAL(TIMER_7)
+void
+__attribute__((interrupt(IPL3AUTO), vector(_TIMER_9_VECTOR)))
+timer9_isr(void)
+{
+    update_counter(7);
+    handle_timer_list(7);
+
+    IFS1CLR = _IFS1_T9IF_MASK;
+}
+#endif
+
+int
+hal_timer_init(int timer_num, void *cfg)
+{
+    if (timer_num >= PIC32MZ_TIMER_COUNT) {
+        return -1;
+    }
+
+    TxCON(timer_num) = 0;
+    timers[timer_num].index = timer_num;
+    timers[timer_num].counter = 0;
+
+    hal_timer_enable_int(timer_num);
+
+    return 0;
+}
+
+int
+hal_timer_deinit(int timer_num)
+{
+    struct hal_timer *timer;
+
+    if (timer_num >= PIC32MZ_TIMER_COUNT) {
+        return -1;
+    }
+
+    TxCON(timer_num) = 0;
+    hal_timer_disable_int(timer_num);
+    while ((timer = TAILQ_FIRST(&timers[timer_num].hal_timer_queue)) !=
+           NULL) {
+        TAILQ_REMOVE(&timers[timer_num].hal_timer_queue, timer, link);
+    }
+
+    return 0;
+}
+
+int
+hal_timer_config(int timer_num, uint32_t freq_hz)
+{
+    int i;
+    uint32_t ideal_prescaler;
+    uint32_t min_delta;
+    uint32_t max_delta;
+
+    if (timer_num >= PIC32MZ_TIMER_COUNT) {
+        return -1;
+    }
+
+    if (freq_hz == 0) {
+        return -1;
+    }
+
+    ideal_prescaler = hal_timer_get_peripheral_base_clock() / freq_hz;
+    if (ideal_prescaler > 256) {
+        return -1;
+    }
+
+    if (ideal_prescaler == 1) {
+        i = 0;
+    } else {
+        /* Find closest prescaler */
+        for (i = 1; i < PIC32MZ_PRESCALER_COUNT; ++i) {
+            if (ideal_prescaler <= timer_prescalers[i]) {
+                min_delta = ideal_prescaler - timer_prescalers[i - 1];
+                max_delta = timer_prescalers[i] - ideal_prescaler;
+                if (min_delta < max_delta) {
+                    i -= 1;
+                }
+                break;
+            }
+        }
+    }
+
+    TxCON(timer_num) = 0;
+
+    TxCONCLR(timer_num) = _T2CON_TCKPS_MASK;
+    TxCONSET(timer_num) = (i << _T2CON_TCKPS_POSITION) & _T2CON_TCKPS_MASK;
+
+    /* Set PR to its maximum value to minimize timer interrupts */
+    PRx(timer_num) = UINT16_MAX;
+    TMRx(timer_num) = 0;
+
+    timers[timer_num].frequency = hal_timer_get_peripheral_base_clock() /
+                                  timer_prescalers[i];
+
+    /* Start timer */
+    TxCONSET(timer_num) = _T2CON_TON_MASK;
+
+    return 0;
+}
+
+uint32_t
+hal_timer_get_resolution(int timer_num)
+{
+    if (timer_num >= PIC32MZ_TIMER_COUNT) {
+        return 0;
+    }
+
+    return 1000000000 / timers[timer_num].frequency;
+}
+
+uint32_t
+hal_timer_read(int timer_num)
+{
+    uint32_t tmr, counter, ctx;
+
+    if (timer_num >= PIC32MZ_TIMER_COUNT) {
+        return 0;
+    }
+
+    __HAL_DISABLE_INTERRUPTS(ctx);
+
+    tmr = TMRx(timer_num);
+    counter = timers[timer_num].counter;
+
+    __HAL_ENABLE_INTERRUPTS(ctx);
+
+    return tmr + counter;
+}
+
+int
+hal_timer_delay(int timer_num, uint32_t ticks)
+{
+    uint32_t until;
+
+    if (timer_num >= PIC32MZ_TIMER_COUNT) {
+        return -1;
+    }
+
+    until = hal_timer_read(timer_num) + ticks;
+    while ((int32_t)(hal_timer_read(timer_num) - until) <= 0) {
+    }
+
+    return 0;
+}
+
+int
+hal_timer_set_cb(int timer_num, struct hal_timer *timer, hal_timer_cb cb_func,
+                 void *arg)
+{
+    if (timer_num >= PIC32MZ_TIMER_COUNT) {
+        return -1;
+    }
+
+    memset(timer, 0, sizeof(struct hal_timer));
+    timer->bsp_timer = &timers[timer_num];
+    timer->cb_func = cb_func;
+    timer->cb_arg = arg;
+
+    return 0;
+}
+
+int
+hal_timer_start(struct hal_timer *timer, uint32_t ticks)
+{
+    uint32_t tick;
+    struct pic32_timer *bsp_timer;
+
+    if (timer == NULL || ticks == 0) {
+        return -1;
+    }
+
+    bsp_timer = (struct pic32_timer *)(timer->bsp_timer);
+    if (bsp_timer == NULL) {
+        return -1;
+    }
+
+    tick = hal_timer_read(bsp_timer->index) + ticks;
+    return hal_timer_start_at(timer, tick);
+}
+
+int
+hal_timer_start_at(struct hal_timer *timer, uint32_t tick)
+{
+    os_sr_t ctx;
+    struct pic32_timer *bsp_timer;
+    struct hal_timer *entry;
+
+    if ((timer == NULL) || (timer->link.tqe_prev != NULL) ||
+        (timer->cb_func == NULL)) {
+        return -1;
+    }
+
+    bsp_timer = (struct pic32_timer *)timer->bsp_timer;
+    if (bsp_timer == NULL) {
+        return -1;
+    }
+
+    timer->expiry = tick;
+
+    __HAL_DISABLE_INTERRUPTS(ctx);
+
+    /* Add to callback queue, order using expiry tick in increasing order */
+    if (TAILQ_EMPTY(&bsp_timer->hal_timer_queue)) {
+        TAILQ_INSERT_HEAD(&bsp_timer->hal_timer_queue, timer, link);
+    } else {
+        TAILQ_FOREACH(entry, &bsp_timer->hal_timer_queue, link) {
+            if ((int32_t)(timer->expiry - entry->expiry) < 0) {
+                TAILQ_INSERT_BEFORE(entry, timer, link);
+                break;
+            }
+        }
+        if (!entry) {
+            TAILQ_INSERT_TAIL(&bsp_timer->hal_timer_queue, timer, link);
+        }
+    }
+
+    update_period_register(bsp_timer->index);
+
+    __HAL_ENABLE_INTERRUPTS(ctx);
+
+    return 0;
+}
+
+int
+hal_timer_stop(struct hal_timer *timer)
+{
+    os_sr_t ctx;
+    struct pic32_timer *bsp_timer;
+
+    if (timer == NULL) {
+        return -1;
+    }
+
+    bsp_timer = (struct pic32_timer *)timer->bsp_timer;
+    if (bsp_timer == NULL) {
+        return -1;
+    }
+
+    __HAL_DISABLE_INTERRUPTS(ctx);
+
+    if (timer->link.tqe_prev != NULL) {
+        TAILQ_REMOVE(&bsp_timer->hal_timer_queue, timer, link);
+        timer->link.tqe_prev = NULL;
+        timer->link.tqe_next = NULL;
+    }
+
+    update_period_register(bsp_timer->index);
+
+    __HAL_ENABLE_INTERRUPTS(ctx);
+
+    return 0;
+}
diff --git a/hw/mcu/microchip/pic32mz/src/hal_uart.c b/hw/mcu/microchip/pic32mz/src/hal_uart.c
new file mode 100644
index 0000000..99fee93
--- /dev/null
+++ b/hw/mcu/microchip/pic32mz/src/hal_uart.c
@@ -0,0 +1,736 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <os/mynewt.h>
+#include <bsp/bsp.h>
+#include <hal/hal_gpio.h>
+#include <hal/hal_uart.h>
+#include <mcu/pps.h>
+#include <mcu/pic32.h>
+#include <mcu/mips_hal.h>
+
+#include <xc.h>
+
+#define UxMODE(U)           (base_address[U][0x0 / 0x4])
+#define UxMODESET(U)        (base_address[U][0x8 / 0x4])
+#define UxSTA(U)            (base_address[U][0x10 / 0x4])
+#define UxTXREG(U)          (base_address[U][0x20 / 0x4])
+#define UxRXREG(U)          (base_address[U][0x30 / 0x4])
+#define UxBRG(U)            (base_address[U][0x40 / 0x4])
+
+static volatile uint32_t* base_address[UART_CNT] = {
+    (volatile uint32_t *)_UART1_BASE_ADDRESS,
+    (volatile uint32_t *)_UART2_BASE_ADDRESS,
+    (volatile uint32_t *)_UART3_BASE_ADDRESS,
+    (volatile uint32_t *)_UART4_BASE_ADDRESS,
+    (volatile uint32_t *)_UART5_BASE_ADDRESS,
+    (volatile uint32_t *)_UART6_BASE_ADDRESS
+};
+
+struct hal_uart {
+    volatile uint8_t u_rx_stall:1;
+    volatile uint8_t u_rx_data;
+    hal_uart_rx_char u_rx_func;
+    hal_uart_tx_char u_tx_func;
+    hal_uart_tx_done u_tx_done;
+    void *u_func_arg;
+    const struct mips_uart_cfg *u_pins;
+};
+static struct hal_uart uarts[UART_CNT];
+
+int
+hal_uart_init_cbs(int port, hal_uart_tx_char tx_func, hal_uart_tx_done tx_done,
+                  hal_uart_rx_char rx_func, void *arg)
+{
+    uarts[port].u_rx_func = rx_func;
+    uarts[port].u_tx_func = tx_func;
+    uarts[port].u_tx_done = tx_done;
+    uarts[port].u_func_arg = arg;
+    return 0;
+}
+
+static void
+uart_disable_tx_int(int port)
+{
+    switch (port) {
+#if MYNEWT_VAL(UART_0)
+    case 0:
+        IEC3CLR = _IEC3_U1TXIE_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(UART_1)
+    case 1:
+        IEC4CLR = _IEC4_U2TXIE_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(UART_2)
+    case 2:
+        IEC4CLR = _IEC4_U3TXIE_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(UART_3)
+    case 3:
+        IEC5CLR = _IEC5_U4TXIE_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(UART_4)
+    case 4:
+        IEC5CLR = _IEC5_U5TXIE_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(UART_5)
+    case 5:
+        IEC5CLR = _IEC5_U6TXIE_MASK;
+        break;
+#endif
+    }
+}
+
+static void
+uart_enable_tx_int(int port)
+{
+    switch (port) {
+#if MYNEWT_VAL(UART_0)
+    case 0:
+        IEC3SET = _IEC3_U1TXIE_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(UART_1)
+    case 1:
+        IEC4SET = _IEC4_U2TXIE_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(UART_2)
+    case 2:
+        IEC4SET = _IEC4_U3TXIE_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(UART_3)
+    case 3:
+        IEC5SET = _IEC5_U4TXIE_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(UART_4)
+    case 4:
+        IEC5SET = _IEC5_U5TXIE_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(UART_5)
+    case 5:
+        IEC5SET = _IEC5_U6TXIE_MASK;
+        break;
+#endif
+    }
+}
+
+static void
+uart_disable_rx_int(int port)
+{
+    switch (port) {
+#if MYNEWT_VAL(UART_0)
+    case 0:
+        IEC3CLR = _IEC3_U1RXIE_MASK | _IEC3_U1EIE_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(UART_1)
+    case 1:
+        IEC4CLR = _IEC4_U2RXIE_MASK | _IEC4_U2EIE_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(UART_2)
+    case 2:
+        IEC4CLR = _IEC4_U3RXIE_MASK | _IEC4_U3EIE_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(UART_3)
+    case 3:
+        IEC5CLR = _IEC5_U4RXIE_MASK | _IEC5_U4EIE_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(UART_4)
+    case 4:
+        IEC5CLR = _IEC5_U5RXIE_MASK | _IEC5_U5EIE_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(UART_5)
+    case 5:
+        IEC5CLR = _IEC5_U6RXIE_MASK | _IEC5_U6EIE_MASK;
+        break;
+#endif
+    }
+}
+
+static void
+uart_enable_rx_int(int port)
+{
+    switch (port) {
+#if MYNEWT_VAL(UART_0)
+        case 0:
+        IEC3SET = _IEC3_U1RXIE_MASK | _IEC3_U1EIE_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(UART_1)
+        case 1:
+        IEC4SET = _IEC4_U2RXIE_MASK | _IEC4_U2EIE_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(UART_2)
+        case 2:
+        IEC4SET = _IEC4_U3RXIE_MASK | _IEC4_U3EIE_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(UART_3)
+    case 3:
+        IEC5SET = _IEC5_U4RXIE_MASK | _IEC5_U4EIE_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(UART_4)
+        case 4:
+        IEC5SET = _IEC5_U5RXIE_MASK | _IEC5_U5EIE_MASK;
+        break;
+#endif
+#if MYNEWT_VAL(UART_5)
+        case 5:
+        IEC5SET = _IEC5_U6RXIE_MASK | _IEC5_U6EIE_MASK;
+        break;
+#endif
+    }
+}
+
+uint32_t rx_times[256];
+uint8_t rx_times_ix;
+
+static void
+uart_receive_ready(int port)
+{
+    int c;
+
+    rx_times[++rx_times_ix] = _CP0_GET_COUNT();
+    while (UxSTA(port) & _U1STA_URXDA_MASK) {
+        uarts[port].u_rx_data = UxRXREG(port);
+
+        c = uarts[port].u_rx_func(uarts[port].u_func_arg,
+                                  uarts[port].u_rx_data);
+        if (c < 0) {
+            uart_disable_rx_int(port);
+            uarts[port].u_rx_stall = 1;
+            break;
+        }
+    }
+}
+
+static void
+uart_transmit_ready(int port)
+{
+    int c;
+
+    while (!(UxSTA(port) & _U1STA_UTXBF_MASK)) {
+        c = uarts[port].u_tx_func(uarts[port].u_func_arg);
+        if (c < 0) {
+            uart_disable_tx_int(port);
+
+            /* call tx done cb */
+            if (uarts[port].u_tx_done) {
+                uarts[port].u_tx_done(uarts[port].u_func_arg);
+            }
+            break;
+        }
+
+        UxTXREG(port) = (uint32_t)c & 0xff;
+    }
+}
+
+#if MYNEWT_VAL(UART_0)
+void
+__attribute__((interrupt(IPL1AUTO), vector(_UART1_FAULT_VECTOR), no_fpu)) uart_1_fault_isr(void)
+{
+    IFS3CLR = _IFS3_U1EIF_MASK;
+}
+
+void
+__attribute__((interrupt(IPL2AUTO), vector(_UART1_RX_VECTOR), no_fpu)) uart_1_rx_isr(void)
+{
+    uart_receive_ready(0);
+    IFS3CLR = _IFS3_U1RXIF_MASK;
+}
+
+void
+__attribute__((interrupt(IPL2AUTO), vector(_UART1_TX_VECTOR), no_fpu)) uart_1_tx_isr(void)
+{
+    uart_transmit_ready(0);
+    IFS3CLR = _IFS3_U1TXIF_MASK;
+}
+#endif
+
+#if MYNEWT_VAL(UART_1)
+void
+__attribute__((interrupt(IPL2AUTO), vector(_UART2_FAULT_VECTOR), no_fpu)) uart_2_fault_isr(void)
+{
+    IFS4CLR = _IFS4_U2EIF_MASK;
+}
+
+void
+__attribute__((interrupt(IPL1AUTO), vector(_UART2_RX_VECTOR), no_fpu)) uart_2_rx_isr(void)
+{
+    uart_receive_ready(1);
+    IFS4CLR = _IFS4_U2RXIF_MASK;
+}
+
+void
+__attribute__((interrupt(IPL2AUTO), vector(_UART2_TX_VECTOR), no_fpu)) uart_2_tx_isr(void)
+{
+    uart_transmit_ready(1);
+    IFS4CLR = _IFS4_U2TXIF_MASK;
+}
+#endif
+
+#if MYNEWT_VAL(UART_2)
+void
+__attribute__((interrupt(IPL2AUTO), vector(_UART3_FAULT_VECTOR), no_fpu)) uart_3_fault_isr(void)
+{
+    IFS4CLR = _IFS4_U3EIF_MASK;
+}
+
+void
+__attribute__((interrupt(IPL1AUTO), vector(_UART3_RX_VECTOR), no_fpu)) uart_3_rx_isr(void)
+{
+    uart_receive_ready(2);
+    IFS4CLR = _IFS4_U3RXIF_MASK;
+}
+
+void
+__attribute__((interrupt(IPL2AUTO), vector(_UART3_TX_VECTOR), no_fpu)) uart_3_tx_isr(void)
+{
+    uart_transmit_ready(2);
+    IFS4CLR = _IFS4_U3TXIF_MASK;
+}
+#endif
+
+#if MYNEWT_VAL(UART_3)
+void
+__attribute__((interrupt(IPL2AUTO), vector(_UART4_FAULT_VECTOR), no_fpu)) uart_4_fault_isr(void)
+{
+    IFS5CLR = _IFS5_U4EIF_MASK;
+}
+
+void
+__attribute__((interrupt(IPL1AUTO), vector(_UART4_RX_VECTOR), no_fpu)) uart_4_rx_isr(void)
+{
+    uart_receive_ready(3);
+    IFS5CLR = _IFS5_U4RXIF_MASK;
+}
+
+void
+__attribute__((interrupt(IPL2AUTO), vector(_UART4_TX_VECTOR), no_fpu)) uart_4_tx_isr(void)
+{
+    uart_transmit_ready(3);
+    IFS5CLR = _IFS5_U4TXIF_MASK;
+}
+#endif
+
+#if MYNEWT_VAL(UART_4)
+void
+__attribute__((interrupt(IPL2AUTO), vector(_UART5_FAULT_VECTOR), no_fpu)) uart_5_fault_isr(void)
+{
+    IFS5CLR = _IFS5_U5EIF_MASK;
+}
+
+void
+__attribute__((interrupt(IPL1AUTO), vector(_UART5_RX_VECTOR), no_fpu)) uart_5_rx_isr(void)
+{
+    uart_receive_ready(4);
+    IFS5CLR = _IFS5_U5RXIF_MASK;
+}
+
+void
+__attribute__((interrupt(IPL2AUTO), vector(_UART5_TX_VECTOR), no_fpu)) uart_5_tx_isr(void)
+{
+    uart_transmit_ready(4);
+    IFS5CLR = _IFS5_U5TXIF_MASK;
+}
+#endif
+
+#if MYNEWT_VAL(UART_5)
+void
+__attribute__((interrupt(IPL2AUTO), vector(_UART6_FAULT_VECTOR), no_fpu)) uart_6_fault_isr(void)
+{
+    IFS5CLR = _IFS5_U6EIF_MASK;
+}
+
+void
+__attribute__((interrupt(IPL1AUTO), vector(_UART6_RX_VECTOR), no_fpu)) uart_6_rx_isr(void)
+{
+    uart_receive_ready(5);
+    IFS5CLR = _IFS5_U6RXIF_MASK;
+}
+
+void
+__attribute__((interrupt(IPL2AUTO), vector(_UART6_TX_VECTOR), no_fpu)) uart_6_tx_isr(void)
+{
+    uart_transmit_ready(5);
+    IFS5CLR = _IFS5_U6TXIF_MASK;
+}
+#endif
+
+void
+hal_uart_start_rx(int port)
+{
+    uint32_t sr;
+    int c;
+
+    if (uarts[port].u_rx_stall) {
+        /* recover saved data */
+        __HAL_DISABLE_INTERRUPTS(sr);
+        c = uarts[port].u_rx_func(uarts[port].u_func_arg,
+                                  uarts[port].u_rx_data);
+        if (c >= 0) {
+            uarts[port].u_rx_stall = 0;
+            uart_enable_rx_int(port);
+        }
+        __HAL_ENABLE_INTERRUPTS(sr);
+    }
+}
+
+void
+hal_uart_start_tx(int port)
+{
+    uart_enable_tx_int(port);
+}
+
+void
+hal_uart_blocking_tx(int port, uint8_t data)
+{
+    /* wait for transmit holding register to be empty */
+    while (!(UxSTA(port) & _U1STA_TRMT_MASK)) {
+    }
+
+    UxTXREG(port) = data;
+}
+
+int
+hal_uart_init(int port, void *arg)
+{
+    if (port >= UART_CNT) {
+        return -1;
+    }
+
+    uarts[port].u_pins = arg;
+
+    return 0;
+}
+
+int
+hal_uart_config(int port, int32_t baudrate, uint8_t databits, uint8_t stopbits,
+                enum hal_uart_parity parity, enum hal_uart_flow_ctl flow_ctl)
+{
+    uint16_t divisor;
+    uint32_t peripheral_clk = SystemCoreClock / ((PB2DIV & _PB2DIV_PBDIV_MASK) + 1);
+    int ret;
+    uint16_t mode;
+
+    /* check input */
+    if ((databits < 8) || (databits > 9) || (stopbits < 1) || (stopbits > 2)) {
+        return -1;
+    }
+
+    mode = _U1MODE_BRGH_MASK | (stopbits >> 1);
+    if (flow_ctl == HAL_UART_FLOW_CTL_RTS_CTS) {
+        assert(uarts[port].u_pins->rts != PIN_UNUSED);
+        mode |= ((uarts[port].u_pins->cts != PIN_UNUSED) ? 2 : 1) << _U1MODE_UEN0_POSITION;
+    }
+    uarts[port].u_rx_stall = 0;
+
+    switch (parity) {
+    case HAL_UART_PARITY_NONE:
+        if (databits == 9) {
+            mode |= _U1MODE_PDSEL_MASK;
+        }
+        break;
+    case HAL_UART_PARITY_ODD:
+        if (databits == 9) { /* PIC does not do 9 bit data + parity. */
+            return -1;
+        }
+        mode |= _U1MODE_PDSEL1_MASK;
+        break;
+    case HAL_UART_PARITY_EVEN:
+        if (databits == 9) {
+           return -1;
+        }
+        mode |= _U1MODE_PDSEL0_MASK;
+        break;
+    default:
+        return -1;
+    }
+
+    /* Configure TX/RX pins */
+    if (uarts[port].u_pins) {
+        ret = 0;
+        switch (port) {
+#if MYNEWT_VAL(UART_0)
+        case 0:
+            ret += pps_configure_output(uarts[port].u_pins->tx, U1TX_OUT_FUNC);
+            ret += pps_configure_input(uarts[port].u_pins->rx, U1RX_IN_FUNC);
+            if (flow_ctl == HAL_UART_FLOW_CTL_RTS_CTS) {
+                ret += pps_configure_output(uarts[port].u_pins->rts, U1RTS_OUT_FUNC);
+                if (uarts[port].u_pins->cts != PIN_UNUSED) {
+                    ret += pps_configure_input(uarts[port].u_pins->cts, U1CTS_IN_FUNC);
+                }
+            }
+            break;
+#endif
+#if MYNEWT_VAL(UART_1)
+        case 1:
+            ret += pps_configure_output(uarts[port].u_pins->tx, U2TX_OUT_FUNC);
+            ret += pps_configure_input(uarts[port].u_pins->rx, U2RX_IN_FUNC);
+            if (flow_ctl == HAL_UART_FLOW_CTL_RTS_CTS) {
+                ret += pps_configure_output(uarts[port].u_pins->rts, U2RTS_OUT_FUNC);
+                if (uarts[port].u_pins->cts != PIN_UNUSED) {
+                    ret += pps_configure_input(uarts[port].u_pins->cts, U2CTS_IN_FUNC);
+                }
+            }
+            break;
+#endif
+#if MYNEWT_VAL(UART_2)
+        case 2:
+            ret += pps_configure_output(uarts[port].u_pins->tx, U3TX_OUT_FUNC);
+            ret += pps_configure_input(uarts[port].u_pins->rx, U3RX_IN_FUNC);
+            if (flow_ctl == HAL_UART_FLOW_CTL_RTS_CTS) {
+                ret += pps_configure_output(uarts[port].u_pins->rts, U3RTS_OUT_FUNC);
+                if (uarts[port].u_pins->cts != PIN_UNUSED) {
+                    ret += pps_configure_input(uarts[port].u_pins->cts, U3CTS_IN_FUNC);
+                }
+            }
+            break;
+#endif
+#if MYNEWT_VAL(UART_3)
+        case 3:
+            ret += pps_configure_output(uarts[port].u_pins->tx, U4TX_OUT_FUNC);
+            ret += pps_configure_input(uarts[port].u_pins->rx, U4RX_IN_FUNC);
+            if (flow_ctl == HAL_UART_FLOW_CTL_RTS_CTS) {
+                ret += pps_configure_output(uarts[port].u_pins->rts, U4RTS_OUT_FUNC);
+                if (uarts[port].u_pins->cts != PIN_UNUSED) {
+                    ret += pps_configure_input(uarts[port].u_pins->cts, U4CTS_IN_FUNC);
+                }
+            }
+            break;
+#endif
+#if MYNEWT_VAL(UART_4)
+        case 4:
+            ret += pps_configure_output(uarts[port].u_pins->tx, U5TX_OUT_FUNC);
+            ret += pps_configure_input(uarts[port].u_pins->rx, U5RX_IN_FUNC);
+            if (flow_ctl == HAL_UART_FLOW_CTL_RTS_CTS) {
+                ret += pps_configure_output(uarts[port].u_pins->rts, U5RTS_OUT_FUNC);
+                if (uarts[port].u_pins->cts != PIN_UNUSED) {
+                    ret += pps_configure_input(uarts[port].u_pins->cts, U5CTS_IN_FUNC);
+                }
+            }
+            break;
+#endif
+#if MYNEWT_VAL(UART_5)
+        case 5:
+            ret += pps_configure_output(uarts[port].u_pins->tx, U6TX_OUT_FUNC);
+            ret += pps_configure_input(uarts[port].u_pins->rx, U6RX_IN_FUNC);
+            if (flow_ctl == HAL_UART_FLOW_CTL_RTS_CTS) {
+                ret += pps_configure_output(uarts[port].u_pins->rts, U6RTS_OUT_FUNC);
+                if (uarts[port].u_pins->cts != PIN_UNUSED) {
+                    ret += pps_configure_input(uarts[port].u_pins->cts, U6CTS_IN_FUNC);
+                }
+            }
+            break;
+#endif
+        default:
+            return -1;
+        }
+        if (ret) {
+            return -1;
+        }
+    }
+
+    /* Set pin as digital input to clear ANSEL bit if any */
+    hal_gpio_init_in(uarts[port].u_pins->rx, HAL_GPIO_PULL_NONE);
+
+    divisor = peripheral_clk / (4 * baudrate) - 1;
+
+    /* disable */
+    UxMODE(port) = 0;
+    _nop();
+    UxBRG(port) = divisor;
+    UxMODE(port) = mode;
+    UxSTA(port) = _U1STA_URXEN_MASK | _U1STA_UTXEN_MASK;
+
+    switch (port) {
+#if MYNEWT_VAL(UART_0)
+    case 0:
+        /* clear RX interrupt flag */
+        IFS3CLR = _IFS3_U1RXIF_MASK;
+
+        /* enable RX interrupt */
+        IEC3SET = _IEC3_U1RXIE_MASK;
+
+        /* set rx interrupt priority */
+        IPC28CLR = _IPC28_U1RXIP_MASK;
+        IPC28SET = (1 << _IPC28_U1RXIP_POSITION); /* priority 1 */
+        /* set rx interrupt subpriority */
+        IPC28CLR = _IPC28_U1RXIS_MASK;
+        IPC28SET = (0 << _IPC28_U1RXIS_POSITION); /* subpriority 0 */
+
+        /* set tx interrupt priority */
+        IPC28CLR = _IPC28_U1TXIP_MASK;
+        IPC28SET = (1 << _IPC28_U1TXIP_POSITION); /* priority 1 */
+        /* set tx interrupt subpriority */
+        IPC28CLR = _IPC28_U1TXIS_MASK;
+        IPC28SET = (0 << _IPC28_U1TXIS_POSITION); /* subpriority 0 */
+        break;
+#endif
+#if MYNEWT_VAL(UART_1)
+    case 1:
+        /* clear RX interrupt flag */
+        IFS4CLR = _IFS4_U2RXIF_MASK;
+
+        /* enable RX interrupt */
+        IEC4SET = _IEC4_U2RXIE_MASK;
+
+        /* set rx interrupt priority */
+        IPC36CLR = _IPC36_U2RXIP_MASK;
+        IPC36SET = (1 << _IPC36_U2RXIP_POSITION); /* priority 1 */
+        /* set rx interrupt subpriority */
+        IPC36CLR = _IPC36_U2RXIS_MASK;
+        IPC36SET = (0 << _IPC36_U2RXIS_POSITION); /* subpriority 0 */
+
+        /* set tx interrupt priority */
+        IPC36CLR = _IPC36_U2TXIP_MASK;
+        IPC36SET = (1 << _IPC36_U2TXIP_POSITION); /* priority 1 */
+        /* set tx interrupt subpriority */
+        IPC36CLR = _IPC36_U2TXIS_MASK;
+        IPC36SET = (0 << _IPC36_U2TXIS_POSITION); /* subpriority 0 */
+        break;
+#endif
+#if MYNEWT_VAL(UART_2)
+    case 2:
+        /* clear RX interrupt flag */
+        IFS4CLR = _IFS4_U3RXIF_MASK;
+
+        /* enable RX interrupt */
+        IEC4SET = _IEC4_U3RXIE_MASK;
+
+        /* set rx interrupt priority */
+        IPC39CLR = _IPC39_U3RXIP_MASK;
+        IPC39SET = (1 << _IPC39_U3RXIP_POSITION); /* priority 1 */
+        /* set rx interrupt subpriority */
+        IPC39CLR = _IPC39_U3RXIS_MASK;
+        IPC39SET = (0 << _IPC39_U3RXIS_POSITION); /* subpriority 0 */
+
+        /* set tx interrupt priority */
+        IPC39CLR = _IPC39_U3TXIP_MASK;
+        IPC39SET = (1 << _IPC39_U3TXIP_POSITION); /* priority 1 */
+        /* set tx interrupt subpriority */
+        IPC39CLR = _IPC39_U3TXIS_MASK;
+        IPC39SET = (0 << _IPC39_U3TXIS_POSITION); /* subpriority 0 */
+        break;
+#endif
+#if MYNEWT_VAL(UART_3)
+    case 3:
+        /* clear RX interrupt flag */
+        IFS5CLR = _IFS5_U4RXIF_MASK;
+
+        /* enable RX interrupt */
+        IEC5SET = _IEC5_U4RXIE_MASK;
+
+        /* set rx interrupt priority */
+        IPC42CLR = _IPC42_U4RXIP_MASK;
+        IPC42SET = (1 << _IPC42_U4RXIP_POSITION); /* priority 1 */
+        /* set rx interrupt subpriority */
+        IPC42CLR = _IPC42_U4RXIS_MASK;
+        IPC42SET = (0 << _IPC42_U4RXIS_POSITION); /* subpriority 0 */
+
+        /* set tx interrupt priority */
+        IPC43CLR = _IPC43_U4TXIP_MASK;
+        IPC43SET = (1 << _IPC43_U4TXIP_POSITION); /* priority 1 */
+        /* set tx interrupt subpriority */
+        IPC43CLR = _IPC43_U4TXIS_MASK;
+        IPC43SET = (0 << _IPC43_U4TXIS_POSITION); /* subpriority 0 */
+        break;
+#endif
+#if MYNEWT_VAL(UART_4)
+    case 4:
+        /* clear RX interrupt flag */
+        IFS5CLR = _IFS5_U5RXIF_MASK;
+
+        /* enable RX interrupt */
+        IEC5SET = _IEC5_U5RXIE_MASK;
+
+        /* set rx interrupt priority */
+        IPC45CLR = _IPC45_U5RXIP_MASK;
+        IPC45SET = (1 << _IPC45_U5RXIP_POSITION); /* priority 1 */
+        /* set rx interrupt subpriority */
+        IPC45CLR = _IPC45_U5RXIS_MASK;
+        IPC45SET = (0 << _IPC45_U5RXIS_POSITION); /* subpriority 0 */
+
+        /* set tx interrupt priority */
+        IPC45CLR = _IPC45_U5TXIP_MASK;
+        IPC45SET = (1 << _IPC45_U5TXIP_POSITION); /* priority 1 */
+        /* set tx interrupt subpriority */
+        IPC45CLR = _IPC45_U5TXIS_MASK;
+        IPC45SET = (0 << _IPC45_U5TXIS_POSITION); /* subpriority 0 */
+        break;
+#endif
+#if MYNEWT_VAL(UART_5)
+    case 5:
+        /* clear RX interrupt flag */
+        IFS5CLR = _IFS5_U6RXIF_MASK;
+
+        /* enable RX interrupt */
+        IEC5SET = _IEC5_U6RXIE_MASK;
+
+        /* set rx interrupt priority */
+        IPC47CLR = _IPC47_U6RXIP_MASK;
+        IPC47SET = (1 << _IPC47_U6RXIP_POSITION); /* priority 1 */
+        /* set rx interrupt subpriority */
+        IPC47CLR = _IPC47_U6RXIS_MASK;
+        IPC47SET = (0 << _IPC47_U6RXIS_POSITION); /* subpriority 0 */
+
+        /* set tx interrupt priority */
+        IPC47CLR = _IPC47_U6TXIP_MASK;
+        IPC47SET = (1 << _IPC47_U6TXIP_POSITION); /* priority 1 */
+        /* set tx interrupt subpriority */
+        IPC47CLR = _IPC47_U6TXIS_MASK;
+        IPC47SET = (0 << _IPC47_U6TXIS_POSITION); /* subpriority 0 */
+        break;
+#endif
+    }
+
+    UxMODESET(port) = _U1MODE_ON_MASK;
+
+    return 0;
+}
+
+int
+hal_uart_close(int port)
+{
+    if (port >= UART_CNT) {
+        return -1;
+    }
+
+    UxMODE(port) = 0;
+    uart_disable_rx_int(port);
+
+    return 0;
+}
diff --git a/hw/mcu/microchip/pic32mz/src/hal_watchdog.c b/hw/mcu/microchip/pic32mz/src/hal_watchdog.c
new file mode 100644
index 0000000..ab875df
--- /dev/null
+++ b/hw/mcu/microchip/pic32mz/src/hal_watchdog.c
@@ -0,0 +1,47 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <xc.h>
+#include <hal/hal_watchdog.h>
+
+int
+hal_watchdog_init(uint32_t expire_msecs)
+{
+    /*
+     * Cannot change watchdog prescaler at runtime.
+     * Only check if the watchdog timer is greater than expire_msecs.
+     */
+    uint32_t wdt_period = 1;
+    wdt_period <<= (WDTCON & _WDTCON_RUNDIV_MASK) >> _WDTCON_RUNDIV_POSITION;
+
+    return wdt_period < expire_msecs ? -1 : 0;
+}
+
+void
+hal_watchdog_enable(void)
+{
+    WDTCONSET = _WDTCON_ON_MASK;
+}
+
+void
+hal_watchdog_tickle(void)
+{
+    volatile uint16_t *wdtclrkey = (volatile uint16_t *)&WDTCON + 1;
+    *wdtclrkey = 0x5743;
+}
diff --git a/hw/mcu/microchip/pic32mz/src/pic32mz_periph.c b/hw/mcu/microchip/pic32mz/src/pic32mz_periph.c
new file mode 100644
index 0000000..5baf166
--- /dev/null
+++ b/hw/mcu/microchip/pic32mz/src/pic32mz_periph.c
@@ -0,0 +1,382 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <assert.h>
+
+#include <os/mynewt.h>
+
+#include <hal/hal_bsp.h>
+#include <hal/hal_i2c.h>
+#include <hal/hal_timer.h>
+#include <hal/hal_spi.h>
+#include <uart/uart.h>
+#include <mcu/mips_bsp.h>
+#include <mcu/mips_hal.h>
+#include <uart_hal/uart_hal.h>
+#include <bsp/bsp.h>
+
+static struct uart_dev uart_0_dev;
+static struct uart_dev uart_1_dev;
+static struct uart_dev uart_2_dev;
+static struct uart_dev uart_3_dev;
+static struct uart_dev uart_4_dev;
+static struct uart_dev uart_5_dev;
+
+static const struct mips_uart_cfg uart_0_cfg = {
+    .tx = MYNEWT_VAL(UART_0_PIN_TX),
+    .rx = MYNEWT_VAL(UART_0_PIN_RX),
+    .rts = MYNEWT_VAL(UART_0_PIN_RTS),
+    .cts = MYNEWT_VAL(UART_0_PIN_CTS),
+};
+
+static const struct mips_uart_cfg uart_1_cfg = {
+    .tx = MYNEWT_VAL(UART_1_PIN_TX),
+    .rx = MYNEWT_VAL(UART_1_PIN_RX),
+    .rts = MYNEWT_VAL(UART_1_PIN_RTS),
+    .cts = MYNEWT_VAL(UART_1_PIN_CTS),
+};
+
+static const struct mips_uart_cfg uart_2_cfg = {
+    .tx = MYNEWT_VAL(UART_2_PIN_TX),
+    .rx = MYNEWT_VAL(UART_2_PIN_RX),
+    .rts = MYNEWT_VAL(UART_2_PIN_RTS),
+    .cts = MYNEWT_VAL(UART_2_PIN_CTS),
+};
+
+static const struct mips_uart_cfg uart_3_cfg = {
+    .tx = MYNEWT_VAL(UART_3_PIN_TX),
+    .rx = MYNEWT_VAL(UART_3_PIN_RX),
+    .rts = MYNEWT_VAL(UART_3_PIN_RTS),
+    .cts = MYNEWT_VAL(UART_3_PIN_CTS),
+};
+
+static const struct mips_uart_cfg uart_4_cfg = {
+    .tx = MYNEWT_VAL(UART_4_PIN_TX),
+    .rx = MYNEWT_VAL(UART_4_PIN_RX),
+    .rts = MYNEWT_VAL(UART_4_PIN_RTS),
+    .cts = MYNEWT_VAL(UART_4_PIN_CTS),
+};
+
+static const struct mips_uart_cfg uart_5_cfg = {
+    .tx = MYNEWT_VAL(UART_5_PIN_TX),
+    .rx = MYNEWT_VAL(UART_5_PIN_RX),
+    .rts = MYNEWT_VAL(UART_5_PIN_RTS),
+    .cts = MYNEWT_VAL(UART_5_PIN_CTS),
+};
+
+/*
+ * SPI_0
+ *   SCK1  -> RD1
+ */
+static const struct mips_spi_cfg spi_0_cfg = {
+    .mosi = MYNEWT_VAL(SPI_0_MASTER_PIN_MOSI),
+    .miso = MYNEWT_VAL(SPI_0_MASTER_PIN_MISO),
+    .sck = MCU_GPIO_PORTD(1),
+};
+
+/*
+ * SPI_1
+ *   SCK2  -> RG6
+ */
+static const struct mips_spi_cfg spi_1_cfg = {
+    .mosi = MYNEWT_VAL(SPI_1_MASTER_PIN_MOSI),
+    .miso = MYNEWT_VAL(SPI_1_MASTER_PIN_MISO),
+    .sck = MCU_GPIO_PORTG(6),
+};
+
+/*
+ * SPI_2
+ *   SCK3  -> B14
+ */
+static const struct mips_spi_cfg spi_2_cfg = {
+    .mosi = MYNEWT_VAL(SPI_2_MASTER_PIN_MOSI),
+    .miso = MYNEWT_VAL(SPI_2_MASTER_PIN_MISO),
+    .sck = MCU_GPIO_PORTB(14),
+};
+
+/*
+ * SPI_3
+ *   SCK4  -> RD10
+ */
+static const struct mips_spi_cfg spi_3_cfg = {
+    .mosi = MYNEWT_VAL(SPI_3_MASTER_PIN_MOSI),
+    .miso = MYNEWT_VAL(SPI_3_MASTER_PIN_MISO),
+    .sck = MCU_GPIO_PORTD(10),
+};
+
+#ifdef _SPI5_BASE_ADDRESS
+/*
+ * SPI_4
+ *   SCK5  -> RF13
+ */
+static const struct mips_spi_cfg spi_4_cfg = {
+    .mosi = MYNEWT_VAL(SPI_4_MASTER_PIN_MOSI),
+    .miso = MYNEWT_VAL(SPI_4_MASTER_PIN_MISO),
+    .sck = MCU_GPIO_PORTF(13),
+};
+#endif
+
+#ifdef _SPI6_BASE_ADDRESS
+/*
+ * SPI_5
+ *   SCK6  -> RD15
+ */
+static const struct mips_spi_cfg spi_5_cfg = {
+    .mosi = MYNEWT_VAL(SPI_5_MASTER_PIN_MOSI),
+    .miso = MYNEWT_VAL(SPI_5_MASTER_PIN_MISO),
+    .sck = MCU_GPIO_PORTD(15),
+};
+#endif
+
+/*
+ * I2C_0 -> I2C1
+ *   SCL1 -> RA14 (D10 for 64 pin packges)
+ *   SDA1 -> RA15 (D9 for 64 pin packges)
+ */
+static const struct mips_i2c_cfg i2c_0_cfg = {
+#if __PIC32_PIN_COUNT > 64
+    .scl = MCU_GPIO_PORTA(14),
+    .sda = MCU_GPIO_PORTA(15),
+#else
+    .scl = MCU_GPIO_PORTD(10),
+    .sda = MCU_GPIO_PORTD(9),
+#endif
+    .frequency = MYNEWT_VAL(I2C_0_FREQ_KHZ) * 1000,
+};
+
+#ifdef _I2C2_BASE_ADDRESS
+/*
+ * I2C_1 -> I2C2
+ *   SCL2 -> RA2
+ *   SDA2 -> RA3
+ */
+static const struct mips_i2c_cfg i2c_1_cfg = {
+    .scl = MCU_GPIO_PORTA(2),
+    .sda = MCU_GPIO_PORTA(3),
+    .frequency = MYNEWT_VAL(I2C_1_FREQ_KHZ) * 1000,
+};
+#endif
+
+/*
+ * I2C_2 -> I2C3
+ *   SCL3 -> RF8 (D3 for 64 pin packges)
+ *   SDA3 -> RF2 (D2 for 64 pin packges)
+ */
+static const struct mips_i2c_cfg i2c_2_cfg = {
+#if __PIC32_PIN_COUNT > 64
+    .scl = MCU_GPIO_PORTF(8),
+    .sda = MCU_GPIO_PORTF(2),
+#else
+    .scl = MCU_GPIO_PORTD(3),
+    .sda = MCU_GPIO_PORTD(2),
+#endif
+    .frequency = MYNEWT_VAL(I2C_2_FREQ_KHZ) * 1000,
+};
+
+/*
+ * I2C_3 -> I2C4
+ *   SCL4 -> RG8
+ *   SDA4 -> RG7
+ */
+static const struct mips_i2c_cfg i2c_3_cfg = {
+    .scl = MCU_GPIO_PORTG(8),
+    .sda = MCU_GPIO_PORTG(7),
+    .frequency = MYNEWT_VAL(I2C_3_FREQ_KHZ) * 1000,
+};
+
+/*
+ * I2C_4 -> I2C5
+ *   SCL5 -> RF5
+ *   SDA5 -> RF4
+ */
+static const struct mips_i2c_cfg i2c_4_cfg = {
+    .scl = MCU_GPIO_PORTF(5),
+    .sda = MCU_GPIO_PORTF(4),
+    .frequency = MYNEWT_VAL(I2C_4_FREQ_KHZ) * 1000,
+};
+
+static void
+pic32mz_periph_create_timer_devs(void)
+{
+    int rc;
+
+    if (MYNEWT_VAL(TIMER_0)) {
+        rc = hal_timer_init(0, NULL);
+        assert(rc == 0);
+    }
+
+    if (MYNEWT_VAL(TIMER_1)) {
+        rc = hal_timer_init(1, NULL);
+        assert(rc == 0);
+    }
+
+    if (MYNEWT_VAL(TIMER_2)) {
+        rc = hal_timer_init(2, NULL);
+        assert(rc == 0);
+    }
+
+    if (MYNEWT_VAL(TIMER_3)) {
+        rc = hal_timer_init(3, NULL);
+        assert(rc == 0);
+    }
+
+    if (MYNEWT_VAL(TIMER_4)) {
+        rc = hal_timer_init(4, NULL);
+        assert(rc == 0);
+    }
+
+    if (MYNEWT_VAL(TIMER_5)) {
+        rc = hal_timer_init(5, NULL);
+        assert(rc == 0);
+    }
+
+    if (MYNEWT_VAL(TIMER_6)) {
+        rc = hal_timer_init(6, NULL);
+        assert(rc == 0);
+    }
+
+    if (MYNEWT_VAL(TIMER_7)) {
+        rc = hal_timer_init(7, NULL);
+        assert(rc == 0);
+    }
+
+#if MYNEWT_VAL(OS_CPUTIME_TIMER_NUM) >= 0
+    rc = os_cputime_init(MYNEWT_VAL(OS_CPUTIME_FREQ));
+    assert(rc == 0);
+#endif
+}
+
+static void
+pic32mz_periph_create_uart_devs(void)
+{
+    int rc;
+
+    if (MYNEWT_VAL(UART_0)) {
+        rc = os_dev_create((struct os_dev *)&uart_0_dev, "uart0",
+                           OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&uart_0_cfg);
+        assert(rc == 0);
+    }
+
+    if (MYNEWT_VAL(UART_1)) {
+        rc = os_dev_create((struct os_dev *)&uart_1_dev, "uart1",
+                           OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&uart_1_cfg);
+        assert(rc == 0);
+    }
+
+    if (MYNEWT_VAL(UART_2)) {
+        rc = os_dev_create((struct os_dev *)&uart_2_dev, "uart2",
+                           OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&uart_2_cfg);
+        assert(rc == 0);
+    }
+
+    if (MYNEWT_VAL(UART_3)) {
+        rc = os_dev_create((struct os_dev *)&uart_3_dev, "uart3",
+                           OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&uart_3_cfg);
+        assert(rc == 0);
+    }
+
+    if (MYNEWT_VAL(UART_4)) {
+        rc = os_dev_create((struct os_dev *)&uart_4_dev, "uart4",
+                           OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&uart_4_cfg);
+        assert(rc == 0);
+    }
+
+    if (MYNEWT_VAL(UART_5)) {
+        rc = os_dev_create((struct os_dev *)&uart_5_dev, "uart5",
+                           OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&uart_5_cfg);
+        assert(rc == 0);
+    }
+}
+
+static void
+pic32mz_periph_spi_devs(void)
+{
+    int rc;
+
+    if (MYNEWT_VAL(SPI_0_MASTER)) {
+        rc = hal_spi_init(0, (void *)&spi_0_cfg, HAL_SPI_TYPE_MASTER);
+        assert(rc == 0);
+    }
+    if (MYNEWT_VAL(SPI_1_MASTER)) {
+        rc = hal_spi_init(1, (void *)&spi_1_cfg, HAL_SPI_TYPE_MASTER);
+        assert(rc == 0);
+    }
+    if (MYNEWT_VAL(SPI_2_MASTER)) {
+        rc = hal_spi_init(2, (void *)&spi_2_cfg, HAL_SPI_TYPE_MASTER);
+        assert(rc == 0);
+    }
+    if (MYNEWT_VAL(SPI_3_MASTER)) {
+        rc = hal_spi_init(3, (void *)&spi_3_cfg, HAL_SPI_TYPE_MASTER);
+        assert(rc == 0);
+    }
+#ifdef _SPI5_BASE_ADDRESS
+    if (MYNEWT_VAL(SPI_4_MASTER)) {
+        rc = hal_spi_init(4, (void *)&spi_4_cfg, HAL_SPI_TYPE_MASTER);
+        assert(rc == 0);
+    }
+#endif
+#ifdef _SPI6_BASE_ADDRESS
+    if (MYNEWT_VAL(SPI_5_MASTER)) {
+        rc = hal_spi_init(5, (void *)&spi_5_cfg, HAL_SPI_TYPE_MASTER);
+        assert(rc == 0);
+    }
+#endif
+}
+
+static void
+pic32mz_periph_i2c_devs(void)
+{
+    int rc;
+
+    if (MYNEWT_VAL(I2C_0)) {
+        rc = hal_i2c_init(0, (void *)&i2c_0_cfg);
+        assert(rc == 0);
+    }
+
+#ifdef _I2C2_BASE_ADDRESS
+    if (MYNEWT_VAL(I2C_1)) {
+        rc = hal_i2c_init(1, (void *)&i2c_1_cfg);
+        assert(rc == 0);
+    }
+#endif
+
+    if (MYNEWT_VAL(I2C_2)) {
+        rc = hal_i2c_init(2, (void *)&i2c_2_cfg);
+        assert(rc == 0);
+    }
+
+    if (MYNEWT_VAL(I2C_3)) {
+        rc = hal_i2c_init(3, (void *)&i2c_3_cfg);
+        assert(rc == 0);
+    }
+
+    if (MYNEWT_VAL(I2C_4)) {
+        rc = hal_i2c_init(4, (void *)&i2c_3_cfg);
+        assert(rc == 0);
+    }
+}
+
+void
+pic32mz_periph_create(void)
+{
+    pic32mz_periph_create_timer_devs();
+    pic32mz_periph_create_uart_devs();
+    pic32mz_periph_spi_devs();
+    pic32mz_periph_i2c_devs();
+}
diff --git a/hw/mcu/microchip/pic32mz/src/pps.c b/hw/mcu/microchip/pic32mz/src/pps.c
new file mode 100644
index 0000000..b2fa49e
--- /dev/null
+++ b/hw/mcu/microchip/pic32mz/src/pps.c
@@ -0,0 +1,224 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <xc.h>
+#include <mcu/mcu.h>
+#include <mcu/pps.h>
+
+#define MCU_GPIO_UNDEF                  (0xFF)
+#define PPS_BASE_ADDRESS                (0xBF801500)
+
+static volatile uint32_t *const input_regs[4][16] = {
+    {
+        &INT3R,
+        &T2CKR,
+        &T6CKR,
+        &IC3R,
+        &IC7R,
+        &U1RXR,
+        &U2CTSR,
+        &U5RXR,
+        &U6CTSR,
+        &SDI1R,
+        &SDI3R,
+#ifdef SDI5R
+        &SDI5R,
+#else
+        NULL,
+#endif
+#ifdef SS6R
+        &SS6R,
+#else
+        NULL,
+#endif
+        &REFCLKI1R
+    },
+    {
+        &INT4R,
+        &T5CKR,
+        &T7CKR,
+        &IC4R,
+        &IC8R,
+        &U3RXR,
+        &U4CTSR,
+        &SDI2R,
+        &SDI4R,
+        NULL,
+        &REFCLKI4R
+    },
+    {
+        &INT2R,
+        &T3CKR,
+        &T8CKR,
+        &IC2R,
+        &IC5R,
+        &IC9R,
+        &U1CTSR,
+        &U2RXR,
+        &U5CTSR,
+        &SS1R,
+        &SS3R,
+        &SS4R,
+#ifdef SS5R
+        &SS5R,
+#else
+        NULL,
+#endif
+#ifdef C2RXR
+        &C2RXR,
+#else
+        NULL,
+#endif
+    },
+    {
+        &INT1R,
+        &T4CKR,
+        &T9CKR,
+        &IC1R,
+        &IC6R,
+        &U3CTSR,
+        &U4RXR,
+        &U6RXR,
+        &SS2R,
+#ifdef SDI6R
+        &SDI6R,
+#else
+        NULL,
+#endif
+        &OCFAR,
+        &REFCLKI3R
+    }
+};
+
+static const uint8_t input_pins[4][16] = {
+    {
+        MCU_GPIO_PORTD(2),
+        MCU_GPIO_PORTG(8),
+        MCU_GPIO_PORTF(4),
+        MCU_GPIO_PORTD(10),
+        MCU_GPIO_PORTF(1),
+        MCU_GPIO_PORTB(9),
+        MCU_GPIO_PORTB(10),
+        MCU_GPIO_PORTC(14),
+        MCU_GPIO_PORTB(5),
+        MCU_GPIO_UNDEF,
+        MCU_GPIO_PORTC(1),
+        MCU_GPIO_PORTD(14),
+        MCU_GPIO_PORTG(1),
+        MCU_GPIO_PORTA(14),
+        MCU_GPIO_PORTD(6),
+        MCU_GPIO_UNDEF
+    },
+    {
+        MCU_GPIO_PORTD(3),
+        MCU_GPIO_PORTG(7),
+        MCU_GPIO_PORTF(5),
+        MCU_GPIO_PORTD(11),
+        MCU_GPIO_PORTF(0),
+        MCU_GPIO_PORTB(1),
+        MCU_GPIO_PORTE(5),
+        MCU_GPIO_PORTC(13),
+        MCU_GPIO_PORTB(3),
+        MCU_GPIO_UNDEF,
+        MCU_GPIO_PORTC(4),
+        MCU_GPIO_PORTD(15),
+        MCU_GPIO_PORTG(0),
+        MCU_GPIO_PORTA(15),
+        MCU_GPIO_PORTD(7),
+        MCU_GPIO_UNDEF
+    },
+    {
+        MCU_GPIO_PORTD(9),
+        MCU_GPIO_PORTG(6),
+        MCU_GPIO_PORTB(8),
+        MCU_GPIO_PORTB(15),
+        MCU_GPIO_PORTD(4),
+        MCU_GPIO_PORTB(0),
+        MCU_GPIO_PORTE(3),
+        MCU_GPIO_PORTB(7),
+        MCU_GPIO_UNDEF,
+        MCU_GPIO_PORTF(12),
+        MCU_GPIO_PORTD(12),
+        MCU_GPIO_PORTF(8),
+        MCU_GPIO_PORTC(3),
+        MCU_GPIO_PORTE(9),
+        MCU_GPIO_UNDEF,
+        MCU_GPIO_UNDEF
+    },
+    {
+        MCU_GPIO_PORTD(1),
+        MCU_GPIO_PORTG(9),
+        MCU_GPIO_PORTB(14),
+        MCU_GPIO_PORTD(0),
+        MCU_GPIO_UNDEF,
+        MCU_GPIO_PORTB(6),
+        MCU_GPIO_PORTD(5),
+        MCU_GPIO_PORTB(2),
+        MCU_GPIO_PORTF(3),
+        MCU_GPIO_PORTF(13),
+        MCU_GPIO_UNDEF,
+        MCU_GPIO_PORTF(2),
+        MCU_GPIO_PORTC(2),
+        MCU_GPIO_PORTE(8),
+        MCU_GPIO_UNDEF,
+        MCU_GPIO_UNDEF
+    }
+};
+
+int
+pps_configure_output(uint8_t pin, uint8_t func)
+{
+    volatile uint32_t *ptr = (volatile uint32_t *)PPS_BASE_ADDRESS;
+
+    if (func >= 16) {
+        return -1;
+    }
+
+    ptr[pin] = func;
+    return 0;
+}
+
+
+int
+pps_configure_input(uint8_t pin, uint8_t func)
+{
+    uint8_t index = func >> 4;
+    uint8_t val;
+
+    if (index > 3) {
+        return -1;
+    }
+
+    func &= 0xF;
+    if (input_regs[index][func] == NULL) {
+        return -1;
+    }
+
+    for (val = 0; val < 16; ++val) {
+        if (input_pins[index][val] == pin) {
+            break;
+        }
+    }
+    if (val == 16) {
+        return -1;
+    }
+
+    *input_regs[index][func] = val;
+    return 0;
+}
diff --git a/hw/mcu/microchip/pic32mz/src/system_pic32.c b/hw/mcu/microchip/pic32mz/src/system_pic32.c
new file mode 100644
index 0000000..2f6e181
--- /dev/null
+++ b/hw/mcu/microchip/pic32mz/src/system_pic32.c
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <assert.h>
+#include <stdint.h>
+
+#include <os/mynewt.h>
+
+#include <hal/hal_bsp.h>
+#include <bsp/bsp.h>
+
+static inline int PLL_ODIV(int n)
+{
+    if (n == 2) {
+        return 1;
+    } else if (n == 4) {
+        return 2;
+    } else if (n == 8) {
+        return 3;
+    } else if (n == 16) {
+        return 4;
+    } else {
+        return 5;
+    }
+}
+
+uint32_t SystemCoreClock;
+
+void
+SystemClock_Config(void)
+{
+    /* unlock system for clock configuration */
+    SYSKEY = 0x00000000;
+    SYSKEY = 0xAA996655;
+    SYSKEY = 0x556699AA;
+
+#if (MYNEWT_VAL(SYSTEM_CLOCK_FPLLIDIV))
+    fpllidiv = MYNEWT_VAL(SYSTEM_CLOCK_FPLLIDIV);
+#endif
+
+#if MYNEWT_VAL_CHOICE(SYSTEM_CLOCK_SRC, POSC) ||\
+    MYNEWT_VAL_CHOICE(SYSTEM_CLOCK_SRC, POSC_PLL)
+#if MYNEWT_VAL(SYSTEM_CLOCK_OSC_FREQ)
+    OSCCON = (OSCCON & ~_OSCCON_NOSC_MASK) | (2 << _OSCCON_NOSC_POSITION) | _OSCCON_OSWEN_MASK;
+    SystemCoreClock = MYNEWT_VAL(SYSTEM_CLOCK_OSC_FREQ);
+#else
+#error When POSC is selected OSC_FREQ must also be specified
+#endif
+#endif
+
+#if MYNEWT_VAL_CHOICE(SYSTEM_CLOCK_SRC, FRC_DIV)
+    OSCCON = (OSCCON & ~(_OSCCON_NOSC_MASK | _OSCCON_FRCDIV_MASK)) | _OSCCON_OSWEN_MASK |
+        ((MYNEWT_VAL(SYSTEM_CLOCK_FRC_DIV) - 1) << _OSCCON_FRCDIV_POSITION);
+    SystemCoreClock = 8000000 / MYNEWT_VAL(SYSTEM_CLOCK_FRC_DIV);
+#elif MYNEWT_VAL_CHOICE(SYSTEM_CLOCK_SRC, POSC)
+    OSCCON = (OSCCON & ~_OSCCON_NOSC_MASK) | (2 << _OSCCON_NOSC_POSITION) | _OSCCON_OSWEN_MASK;
+    SystemCoreClock = MYNEWT_VAL(SYSTEM_CLOCK_OSC_FREQ);
+#elif MYNEWT_VAL(SYSTEM_CLOCK_SRC) == MYNEWT_VAL_CHOICE(SYSTEM_CLOCK_SRC, FRC_PLL)
+    /* Running on PLL now, switch to FRC */
+    if ((OSCCON & _OSCCON_COSC_MASK) == (1 << _OSCCON_COSC_POSITION)) {
+        OSCCON = (OSCCON & ~(_OSCCON_CLKLOCK_MASK | _OSCCON_NOSC_MASK | _OSCCON_FRCDIV_MASK)) | _OSCCON_OSWEN_MASK;
+        while (OSCCON & _OSCCON_COSC_MASK) ;
+    }
+    SPLLCON = (PLL_ODIV(MYNEWT_VAL(SYSTEM_CLOCK_PLLODIV))) << _SPLLCON_PLLODIV_POSITION |
+        (MYNEWT_VAL(SYSTEM_CLOCK_PLLMULT) - 1) << _SPLLCON_PLLMULT_POSITION |
+        (MYNEWT_VAL(SYSTEM_CLOCK_PLLIDIV) - 1) << _SPLLCON_PLLIDIV_POSITION |
+        _SPLLCON_PLLICLK_MASK |
+        (MYNEWT_VAL(SYSTEM_CLOCK_PLLRANGE)) << _SPLLCON_PLLRANGE_POSITION;
+    OSCCON = (OSCCON & ~_OSCCON_NOSC_MASK) | (1 << _OSCCON_NOSC_POSITION) | _OSCCON_OSWEN_MASK;
+    SystemCoreClock = 8000000 / MYNEWT_VAL(SYSTEM_CLOCK_PLLIDIV) *
+        MYNEWT_VAL(SYSTEM_CLOCK_PLLMULT) / MYNEWT_VAL(SYSTEM_CLOCK_PLLODIV);
+
+#elif MYNEWT_VAL(SYSTEM_CLOCK_SRC) == MYNEWT_VAL_CHOICE(SYSTEM_CLOCK_SRC, POSC_PLL)
+    /* Running on PLL now, switch to FRC */
+    if ((OSCCON & _OSCCON_COSC_MASK) == (1 << _OSCCON_COSC_POSITION)) {
+        OSCCON = (OSCCON & ~(_OSCCON_CLKLOCK_MASK | _OSCCON_NOSC_MASK | _OSCCON_FRCDIV_MASK)) | _OSCCON_OSWEN_MASK;
+        while (OSCCON & _OSCCON_COSC_MASK) ;
+    }
+    SPLLCON = (PLL_ODIV(MYNEWT_VAL(SYSTEM_CLOCK_PLLODIV))) << _SPLLCON_PLLODIV_POSITION |
+        (MYNEWT_VAL(SYSTEM_CLOCK_PLLMULT) - 1) << _SPLLCON_PLLMULT_POSITION |
+        (MYNEWT_VAL(SYSTEM_CLOCK_PLLIDIV) - 1) << _SPLLCON_PLLIDIV_POSITION |
+        (MYNEWT_VAL(SYSTEM_CLOCK_PLLRANGE)) << _SPLLCON_PLLRANGE_POSITION;
+    OSCCON = (OSCCON & ~_OSCCON_NOSC_MASK) | (1 << _OSCCON_NOSC_POSITION) | _OSCCON_OSWEN_MASK;
+    SystemCoreClock = MYNEWT_VAL(SYSTEM_CLOCK_OSC_FREQ) / MYNEWT_VAL(SYSTEM_CLOCK_PLLIDIV) *
+        MYNEWT_VAL(SYSTEM_CLOCK_PLLMULT) / MYNEWT_VAL(SYSTEM_CLOCK_PLLODIV);
+#endif
+    /* Lock system since done with clock configuration */
+    SYSKEY = 0x33333333;
+}
+
+void
+SystemInit(void)
+{
+    /* Configure System Clock */
+    SystemClock_Config();
+}
diff --git a/hw/mcu/microchip/pic32mz/syscfg.yml b/hw/mcu/microchip/pic32mz/syscfg.yml
new file mode 100644
index 0000000..c70a30f
--- /dev/null
+++ b/hw/mcu/microchip/pic32mz/syscfg.yml
@@ -0,0 +1,280 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+syscfg.defs:
+    MCU_FLASH_MIN_WRITE_SIZE:
+        description: >
+            Specifies the required alignment for internal flash writes.
+            Used internally by the newt tool.
+        value: 4
+    I2C_0:
+        description: 'I2C interface 0'
+        value:  0
+    I2C_0_FREQ_KHZ:
+        description: 'Frequency in khz for I2C_0 bus'
+        value:  100
+    I2C_1:
+        description: 'I2C interface 1'
+        value:  0
+    I2C_1_FREQ_KHZ:
+        description: 'Frequency in khz for I2C_0 bus'
+        value:  100
+    I2C_2:
+        description: 'I2C interface 2'
+        value:  0
+    I2C_2_FREQ_KHZ:
+        description: 'Frequency in khz for I2C_0 bus'
+        value:  100
+    I2C_3:
+        description: 'I2C interface 3'
+        value:  0
+    I2C_3_FREQ_KHZ:
+        description: 'Frequency in khz for I2C_0 bus'
+        value:  100
+    I2C_4:
+        description: 'I2C interface 4'
+        value:  0
+    I2C_4_FREQ_KHZ:
+        description: 'Frequency in khz for I2C_0 bus'
+        value:  100
+
+    SPI_0_MASTER:
+        description: 'SPI 0 master'
+        value:  0
+    SPI_0_MASTER_PIN_MOSI:
+        description: 'MOSI pin for SPI_0_MASTER'
+        value: 0xFF
+    SPI_0_MASTER_PIN_MISO:
+        description: 'MOSI pin for SPI_0_MASTER'
+        value: 0xFF
+    SPI_1_MASTER:
+        description: 'SPI 1 master'
+        value:  0
+    SPI_1_MASTER_PIN_MOSI:
+        description: 'MOSI pin for SPI_1_MASTER'
+        value: 0xFF
+    SPI_1_MASTER_PIN_MISO:
+        description: 'MOSI pin for SPI_1_MASTER'
+        value: 0xFF
+    SPI_2_MASTER:
+        description: 'SPI 2 master'
+        value:  0
+    SPI_2_MASTER_PIN_MOSI:
+        description: 'MOSI pin for SPI_2_MASTER'
+        value: 0xFF
+    SPI_2_MASTER_PIN_MISO:
+        description: 'MOSI pin for SPI_2_MASTER'
+        value: 0xFF
+    SPI_3_MASTER:
+        description: 'SPI 3 master'
+        value:  0
+    SPI_3_MASTER_PIN_MOSI:
+        description: 'MOSI pin for SPI_3_MASTER'
+        value: 0xFF
+    SPI_3_MASTER_PIN_MISO:
+        description: 'MOSI pin for SPI_3_MASTER'
+        value: 0xFF
+    SPI_4_MASTER:
+        description: 'SPI 4 master'
+        value:  0
+    SPI_4_MASTER_PIN_MOSI:
+        description: 'MOSI pin for SPI_4_MASTER'
+        value: 0xFF
+    SPI_4_MASTER_PIN_MISO:
+        description: 'MOSI pin for SPI_4_MASTER'
+        value: 0xFF
+    SPI_5_MASTER:
+        description: 'SPI 5 master'
+        value:  0
+    SPI_5_MASTER_PIN_MOSI:
+        description: 'MOSI pin for SPI_5_MASTER'
+        value: 0xFF
+    SPI_5_MASTER_PIN_MISO:
+        description: 'MOSI pin for SPI_5_MASTER'
+        value: 0xFF
+
+    UART_0:
+        description: Enable UART_0 (Datasheet peripheral name UART1)
+        value: 0
+    UART_0_PIN_TX:
+        description: 'TX pin for UART_0'
+        value: 0xFF
+    UART_0_PIN_RX:
+        description: 'RX pin for UART_0'
+        value: 0xFF
+    UART_0_PIN_RTS:
+        description: 'RTS pin for UART_0'
+        value: 0xFF
+    UART_0_PIN_CTS:
+        description: 'CTS pin for UART_0'
+        value: 0xFF
+
+    UART_1:
+        description: Enable UART_1 (Datasheet peripheral name UART2)
+        value: 0
+    UART_1_PIN_TX:
+        description: 'TX pin for UART_1'
+        value: 0xFF
+    UART_1_PIN_RX:
+        description: 'RX pin for UART_1'
+        value: 0xFF
+    UART_1_PIN_RTS:
+        description: 'RTS pin for UART_1'
+        value: 0xFF
+    UART_1_PIN_CTS:
+        description: 'CTS pin for UART_1'
+        value: 0xFF
+
+    UART_2:
+        description: Enable UART_2 (Datasheet peripheral name UART3)
+        value: 0
+    UART_2_PIN_TX:
+        description: 'TX pin for UART_2'
+        value: 0xFF
+    UART_2_PIN_RX:
+        description: 'RX pin for UART_2'
+        value: 0xFF
+    UART_2_PIN_RTS:
+        description: 'RTS pin for UART_2'
+        value: 0xFF
+    UART_2_PIN_CTS:
+        description: 'CTS pin for UART_2'
+        value: 0xFF
+
+    UART_3:
+        description: Enable UART_4 (Datasheet peripheral name UART4)
+        value: 0
+    UART_3_PIN_TX:
+        description: 'TX pin for UART_3'
+        value: 0xFF
+    UART_3_PIN_RX:
+        description: 'RX pin for UART_3'
+        value: 0xFF
+    UART_3_PIN_RTS:
+        description: 'RTS pin for UART_3'
+        value: 0xFF
+    UART_3_PIN_CTS:
+        description: 'CTS pin for UART_3'
+        value: 0xFF
+
+    UART_4:
+        description: Enable UART_4 (Datasheet peripheral name UART5)
+        value: 0
+    UART_4_PIN_TX:
+        description: 'TX pin for UART_4'
+        value: 0xFF
+    UART_4_PIN_RX:
+        description: 'RX pin for UART_4'
+        value: 0xFF
+    UART_4_PIN_RTS:
+        description: 'RTS pin for UART_4'
+        value: 0xFF
+    UART_4_PIN_CTS:
+        description: 'CTS pin for UART_4'
+        value: 0xFF
+
+    UART_5:
+        description: Enable UART_5 (Datasheet peripheral name UART6)
+        value: 0
+    UART_5_PIN_TX:
+        description: 'TX pin for UART_5'
+        value: 0xFF
+    UART_5_PIN_RX:
+        description: 'RX pin for UART_5'
+        value: 0xFF
+    UART_5_PIN_RTS:
+        description: 'RTS pin for UART_5'
+        value: 0xFF
+    UART_5_PIN_CTS:
+        description: 'CTS pin for UART_5'
+        value: 0xFF
+
+    TIMER_0:
+        description: "Whether to enable Timer 0"
+        value:  1
+
+    TIMER_1:
+        description: "Whether to enable Timer 1"
+        value:  0
+
+    TIMER_2:
+        description: "Whether to enable Timer 2"
+        value:  0
+
+    TIMER_3:
+        description: "Whether to enable Timer 3"
+        value:  0
+
+    TIMER_4:
+        description: "Whether to enable Timer 4"
+        value:  0
+
+    TIMER_5:
+        description: "Whether to enable Timer 5"
+        value:  0
+
+    TIMER_6:
+        description: "Whether to enable Timer 6"
+        value:  0
+
+    TIMER_7:
+        description: "Whether to enable Timer 7"
+        value:  0
+
+    SYSTEM_CLOCK_OSC_FREQ:
+        descriprion: HS Oscilator/External clock freqency.
+        value:
+    SYSTEM_CLOCK_SRC:
+        description: >
+            Select system clock source, that will affect both CONFIG registers
+            and startup code.
+        value:
+        choices:
+            - FRC_DIV
+            - FRC_PLL
+            - POSC
+            - POSC_PLL
+    SYSTEM_CLOCK_FRC_DIV:
+        description: FRCDIV value
+        range: 1,2,4,6,8,16,32,64,256
+        value: 1
+    SYSTEM_CLOCK_PLLIDIV:
+        description:
+        range: 1..8
+        value:
+    SYSTEM_CLOCK_PLLRANGE:
+        description:
+        range: 1..5
+        value:
+    SYSTEM_CLOCK_PLLMULT:
+        description:
+        range: 1..128
+        value:
+    SYSTEM_CLOCK_PLLODIV:
+        description:
+        range: 2,4,8,16,32
+        value:
+
+    MCU_NO_BOOTLOADER_BUILD:
+        description: >
+            Set this value to 1 when building elf files that are not
+            converted to img files.
+        value: 0
+
+syscfg.vals:
+    OS_TICKS_PER_SEC: 1000
diff --git a/kernel/os/include/os/arch/pic32/os/os_arch.h b/kernel/os/include/os/arch/pic32/os/os_arch.h
index 98684ee..7b78d61 100644
--- a/kernel/os/include/os/arch/pic32/os/os_arch.h
+++ b/kernel/os/include/os/arch/pic32/os/os_arch.h
@@ -32,7 +32,7 @@
 
 /* Stack sizes for common OS tasks */
 #define OS_SANITY_STACK_SIZE (64)
-#define OS_IDLE_STACK_SIZE (256)
+#define OS_IDLE_STACK_SIZE (400)
 
 #define OS_ENTER_CRITICAL(__os_sr)                  \
         do {                                        \
diff --git a/kernel/os/src/arch/pic32/asm/ctx.S b/kernel/os/src/arch/pic32/asm/ctx.S
index 53043fc..4299680 100644
--- a/kernel/os/src/arch/pic32/asm/ctx.S
+++ b/kernel/os/src/arch/pic32/asm/ctx.S
@@ -25,7 +25,7 @@
 
 #define CTX_ALIGNED_SIZE ((((CTX_SIZE - 1) / OS_STACK_ALIGNMENT) + 1) * \
     OS_STACK_ALIGNMENT)
-#define CTX_OFFS(r) (((r) * 4) - CTX_ALIGNED_SIZE)
+#define CTX_OFFS(r) (((r) * 4))
 
 #if (__mips_isa_rev < 6)
     #define CTX_SIZE (36 * 4)
@@ -44,9 +44,7 @@
 
 .macro _gpctx_save
     .set push
-    .set noat
-    sw      $1, CTX_REG(1)(sp)
-    .set at
+    # at already pushed
     sw      v0, CTX_REG(2)(sp)
     sw      v1, CTX_REG(3)(sp)
     sw      a0, CTX_REG(4)(sp)
@@ -71,39 +69,43 @@
     sw      s7, CTX_REG(23)(sp)
     sw      t8, CTX_REG(24)(sp)
     sw      t9, CTX_REG(25)(sp)
-    sw      k0, CTX_REG(26)(sp)
-    sw      k1, CTX_REG(27)(sp)
+    # k0 already pushed
+    # k1 already pushed
     sw      gp, CTX_REG(28)(sp)
-    # don't bother saving sp
-    sw      fp, CTX_REG(29)(sp)
-    sw      ra, CTX_REG(30)(sp)
+    # save ra in place on sp
+    sw      ra, CTX_REG(29)(sp)
+    sw      fp, CTX_REG(30)(sp)
 
 #if (__mips_isa_rev < 6)
-	mfhi   k0
-    sw	   k0, CTX_HI(sp)
-	mflo   k0
-	sw     k0, CTX_LO(sp)
+    mfhi    k0
+    sw      k0, CTX_HI(sp)
+    mflo    k0
+    sw      k0, CTX_LO(sp)
 #endif
 
     # cp0
     mfc0    k0, _CP0_EPC
-    sw	    k0, CTX_EPC(sp)
+    sw      k0, CTX_EPC(sp)
     mfc0    k0, _CP0_BADVADDR
-	sw	    k0, CTX_BADVADDR(sp)
-    mfc0	k0, _CP0_STATUS
-    # disable co-precessor 1
-    li	    k1, ~_CP0_STATUS_CU1_MASK
-    and	    k0, k0, k1
-	sw	    k0, CTX_STATUS(sp)
+    sw      k0, CTX_BADVADDR(sp)
     mfc0    k0, _CP0_CAUSE
     sw      k0, CTX_CAUSE(sp)
+
+    mfc0    k0, _CP0_STATUS
+    # disable co-precessor 1 on return from context switch
+    ins     k0, $0, _CP0_STATUS_CU1_POSITION, _CP0_STATUS_CU1_LENGTH
+    sw      k0, CTX_STATUS(sp)
+    # enable interrupts with higher priority
+    ins     k0, $0, _CP0_STATUS_EXL_POSITION, _CP0_STATUS_EXL_LENGTH
+    ori     k0, k0, 1 << _CP0_STATUS_IPL_POSITION
+    mtc0    k0, _CP0_STATUS
     .set pop
 .endm
 
 .macro _gpctx_load
     .set push
     .set noat
-    lw     $1, CTX_REG(1)(sp)
+    # at restored at the end of contex switch
     lw     v0, CTX_REG(2)(sp)
     lw     v1, CTX_REG(3)(sp)
     lw     a0, CTX_REG(4)(sp)
@@ -128,31 +130,29 @@
     lw     s7, CTX_REG(23)(sp)
     lw     t8, CTX_REG(24)(sp)
     lw     t9, CTX_REG(25)(sp)
-    # restore k0 last
-    lw     k1, CTX_REG(27)(sp)
+    # restore k0 later
+    # restore k1 later
     lw     gp, CTX_REG(28)(sp)
-    # sp already restored
-    lw     fp, CTX_REG(29)(sp)
-    lw     ra, CTX_REG(30)(sp)
+    # sp already restored ra in place of sp
+    lw     ra, CTX_REG(29)(sp)
+    lw     fp, CTX_REG(30)(sp)
 
     di
 
 #if (__mips_isa_rev < 6)
-    lw	   k0, CTX_HI(sp)
-    mthi   k0
-    lw	   k0, CTX_LO(sp)
-    mtlo   k0
+    lw      k0, CTX_HI(sp)
+    mthi    k0
+    lw      k0, CTX_LO(sp)
+    mtlo    k0
 #endif
 
     # cp0
-    lw     k0, CTX_EPC(sp)
-    mtc0   k0, _CP0_EPC
-    # STATUS here will have EXL set
-    lw     k0, CTX_STATUS(sp)
-    mtc0   k0, _CP0_STATUS
+    lw      k0, CTX_EPC(sp)
+    mtc0    k0, _CP0_EPC
+    # STATUS here will have EXL set and EI cleared
+    lw      k0, CTX_STATUS(sp)
+    mtc0    k0, _CP0_STATUS
     ehb
-    # restore k0
-    lw     k0, CTX_REG(26)(sp)
     .set pop
 .endm
 
@@ -170,45 +170,45 @@
 #define TASK_STACK_SIZE     (8)
 
 .macro _fpctx_save
-    sdc1	$f0, CTX_FP_REG(0)(k0)
-    sdc1	$f2, CTX_FP_REG(2)(k0)
-    sdc1	$f4, CTX_FP_REG(4)(k0)
-    sdc1	$f6, CTX_FP_REG(6)(k0)
-    sdc1	$f8, CTX_FP_REG(8)(k0)
-    sdc1	$f10, CTX_FP_REG(10)(k0)
-    sdc1	$f12, CTX_FP_REG(12)(k0)
-    sdc1	$f14, CTX_FP_REG(14)(k0)
-    sdc1	$f16, CTX_FP_REG(16)(k0)
-    sdc1	$f18, CTX_FP_REG(18)(k0)
-    sdc1	$f20, CTX_FP_REG(20)(k0)
-    sdc1	$f22, CTX_FP_REG(22)(k0)
-    sdc1	$f24, CTX_FP_REG(24)(k0)
-    sdc1	$f26, CTX_FP_REG(26)(k0)
-    sdc1	$f28, CTX_FP_REG(28)(k0)
-    sdc1	$f30, CTX_FP_REG(30)(k0)
-    cfc1	k1, $31
-    sw	    k1, CTX_FP_FCSR(k0)
+    sdc1    $f0, CTX_FP_REG(0)(k0)
+    sdc1    $f2, CTX_FP_REG(2)(k0)
+    sdc1    $f4, CTX_FP_REG(4)(k0)
+    sdc1    $f6, CTX_FP_REG(6)(k0)
+    sdc1    $f8, CTX_FP_REG(8)(k0)
+    sdc1    $f10, CTX_FP_REG(10)(k0)
+    sdc1    $f12, CTX_FP_REG(12)(k0)
+    sdc1    $f14, CTX_FP_REG(14)(k0)
+    sdc1    $f16, CTX_FP_REG(16)(k0)
+    sdc1    $f18, CTX_FP_REG(18)(k0)
+    sdc1    $f20, CTX_FP_REG(20)(k0)
+    sdc1    $f22, CTX_FP_REG(22)(k0)
+    sdc1    $f24, CTX_FP_REG(24)(k0)
+    sdc1    $f26, CTX_FP_REG(26)(k0)
+    sdc1    $f28, CTX_FP_REG(28)(k0)
+    sdc1    $f30, CTX_FP_REG(30)(k0)
+    cfc1    k1, $31
+    sw      k1, CTX_FP_FCSR(k0)
 .endm
 
 .macro _fpctx_load
-    ldc1	$f0, CTX_FP_REG(0)(k0)
-    ldc1	$f2, CTX_FP_REG(2)(k0)
-    ldc1	$f4, CTX_FP_REG(4)(k0)
-    ldc1	$f6, CTX_FP_REG(6)(k0)
-    ldc1	$f8, CTX_FP_REG(8)(k0)
-    ldc1	$f10, CTX_FP_REG(10)(k0)
-    ldc1	$f12, CTX_FP_REG(12)(k0)
-    ldc1	$f14, CTX_FP_REG(14)(k0)
-    ldc1	$f16, CTX_FP_REG(16)(k0)
-    ldc1	$f18, CTX_FP_REG(18)(k0)
-    ldc1	$f20, CTX_FP_REG(20)(k0)
-    ldc1	$f22, CTX_FP_REG(22)(k0)
-    ldc1	$f24, CTX_FP_REG(24)(k0)
-    ldc1	$f26, CTX_FP_REG(26)(k0)
-    ldc1	$f28, CTX_FP_REG(28)(k0)
-    ldc1	$f30, CTX_FP_REG(30)(k0)
+    ldc1    $f0, CTX_FP_REG(0)(k0)
+    ldc1    $f2, CTX_FP_REG(2)(k0)
+    ldc1    $f4, CTX_FP_REG(4)(k0)
+    ldc1    $f6, CTX_FP_REG(6)(k0)
+    ldc1    $f8, CTX_FP_REG(8)(k0)
+    ldc1    $f10, CTX_FP_REG(10)(k0)
+    ldc1    $f12, CTX_FP_REG(12)(k0)
+    ldc1    $f14, CTX_FP_REG(14)(k0)
+    ldc1    $f16, CTX_FP_REG(16)(k0)
+    ldc1    $f18, CTX_FP_REG(18)(k0)
+    ldc1    $f20, CTX_FP_REG(20)(k0)
+    ldc1    $f22, CTX_FP_REG(22)(k0)
+    ldc1    $f24, CTX_FP_REG(24)(k0)
+    ldc1    $f26, CTX_FP_REG(26)(k0)
+    ldc1    $f28, CTX_FP_REG(28)(k0)
+    ldc1    $f30, CTX_FP_REG(30)(k0)
     lw      k0, CTX_FP_FCSR(k0)
-    ctc1	k0, $31
+    ctc1    k0, $31
 .endm
 #endif
 
@@ -234,8 +234,8 @@
 
     # enable co-precessor 1
     mfc0    k0, _CP0_STATUS
-    li	    k1, _CP0_STATUS_CU1_MASK
-    or	    k0, k0, k1
+    li      k1, _CP0_STATUS_CU1_MASK
+    or      k0, k0, k1
     mtc0    k0, _CP0_STATUS
 
     lw      k1, g_current_task          # get current task
@@ -275,24 +275,37 @@
 .ent isr_sw0
 isr_sw0:
     .set noat
-    rdpgpr  sp, sp
 
+    addiu   sp, sp, -(CTX_SIZE)
     # context switch
-    _gpctx_save                         # save the context
+    sw      k0, CTX_REG(26)(sp)
+    sw      k1, CTX_REG(27)(sp)
+    sw      $1, CTX_REG(1)(sp)
     .set at
-    lw      k0, g_current_task          # get current task
-    beqz    k0, 1f                      # if there is a current task
-    sw      sp, 0(k0)                   # update stored sp
-1:
+
     li      k0, _IFS0_CS0IF_MASK        # clear sw interrupt
     sw      k0, IFS0CLR
 
-    lw      k0, g_os_run_list           # get new task
-    sw      k0, g_current_task          # g_current_task = g_os_run_list
+    lw      k0, g_current_task          # get current task
+    lw      k1, g_os_run_list           # get high prio task to k1
+    beq     k0, k1, same_task_no_switch
+    beqz    k0, no_save_needed          # no current task so far
+    sw      sp, 0(k0)                   # update stored sp
+    _gpctx_save
 
-    lw      sp, 0(k0)                   # restore sp
+    .set at
+no_save_needed:
+
+    sw      k1, g_current_task          # g_current_task = g_os_run_list
+
+    lw      sp, 0(k1)                   # restore sp
     .set noat
     _gpctx_load                         # load the context
-    wrpgpr  sp, sp
+same_task_no_switch:
+    lw      $1, CTX_REG(1)(sp)
+    lw      k0, CTX_REG(26)(sp)
+    lw      k1, CTX_REG(27)(sp)
+    addiu   sp, sp, CTX_SIZE
+
     eret
 .end isr_sw0
diff --git a/kernel/os/src/arch/pic32/os_arch_pic32.c b/kernel/os/src/arch/pic32/os_arch_pic32.c
index 4e371c1..eda2512 100644
--- a/kernel/os/src/arch/pic32/os_arch_pic32.c
+++ b/kernel/os/src/arch/pic32/os_arch_pic32.c
@@ -138,6 +138,8 @@
 os_arch_task_stack_init(struct os_task *t, os_stack_t *stack_top, int size)
 {
     int ctx_space = os_bytes_to_stack_aligned_words(sizeof(struct ctx));
+    struct ctx *ctx;
+    int i;
 #if MYNEWT_VAL(HARDFLOAT)
     /* If stack does not have space for the FPU context, assume the
     thread won't use it. */
@@ -157,18 +159,18 @@
     stack_top -= 4;
 #endif
 
-    os_stack_t *s = stack_top - ctx_space;
+    ctx = ((struct ctx *)stack_top) - 1;
 
-    struct ctx ctx;
-    ctx.regs[3] = (uint32_t)t->t_arg;
-    ctx.regs[27] = get_global_pointer();
-    ctx.status = (_CP0_GET_STATUS() & ~_CP0_STATUS_CU1_MASK) | _CP0_STATUS_IE_MASK | _CP0_STATUS_EXL_MASK;
-    ctx.cause = _CP0_GET_CAUSE();
-    ctx.epc = (uint32_t)t->t_func;
-    /* copy struct onto the stack */
-    memcpy(s, &ctx, sizeof(ctx));
+    for (i = 0; i < 30; ++i) {
+        ctx->regs[i] = 0;
+    }
+    ctx->regs[3] = (uint32_t)t->t_arg;
+    ctx->regs[27] = get_global_pointer();
+    ctx->status = (_CP0_GET_STATUS() & ~_CP0_STATUS_CU1_MASK) | _CP0_STATUS_IE_MASK | _CP0_STATUS_EXL_MASK;
+    ctx->cause = _CP0_GET_CAUSE();
+    ctx->epc = (uint32_t)t->t_func;
 
-    return stack_top;
+    return ctx->regs;
 }
 
 void
@@ -194,6 +196,9 @@
         /* vector spacing 0x20  */
         _CP0_SET_INTCTL(_CP0_GET_INTCTL() | (1 << _CP0_INTCTL_VS_POSITION));
 
+        /* Stop core timer while debugger stops */
+        _CP0_BIC_DEBUG(_CP0_DEBUG_COUNTDM_MASK);
+
         /* enable core timer interrupt */
         IEC0SET = _IEC0_CTIE_MASK;
         /* set interrupt priority */
diff --git a/kernel/os/src/arch/pic32/startup/crt0.S b/kernel/os/src/arch/pic32/startup/crt0.S
index e338046..ac30225 100644
--- a/kernel/os/src/arch/pic32/startup/crt0.S
+++ b/kernel/os/src/arch/pic32/startup/crt0.S
@@ -47,6 +47,7 @@
 
 #include "xc.h"
 #include <cp0defs.h>
+#include <syscfg/syscfg.h>
 
 #ifdef __LIBBUILD__
    # Replace the standard debugging information with a simple filename. This
@@ -571,6 +572,13 @@
         .align 2
         .ent _main_entry
 _main_entry:
+#if MYNEWT_VAL_HAL_SBRK
+        la a0,  __HeapBase
+        la a1,  __HeapLimit
+        la t0,  _sbrkInit
+        jalr    t0
+        nop
+#endif
 
 #if defined(CPP_INIT)
         .weak _init
@@ -584,6 +592,9 @@
         nop
 2:
 #endif
+        la      t0, SystemInit
+        jalr    t0
+
         and     a0,a0,0
         and     a1,a1,0
 
@@ -621,3 +632,13 @@
 
         .globl __crt0_exit
         .end _main_entry
+
+        .section .text.SystemInit,code
+        .align 2
+        .weak SystemInit
+        .ent SystemInit
+SystemInit:
+        jr   ra
+        nop
+
+        .end SystemInit
diff --git a/repository.yml b/repository.yml
index d88c444..aa77325 100644
--- a/repository.yml
+++ b/repository.yml
@@ -110,8 +110,9 @@
 
     mcuboot:
         type: github
-        user: JuulLabs-OSS
+        user: mcu-tools
         repo: mcuboot
+        branch: main
         vers:
             master: 0-dev
             mynewt_1_7_0_tag: 1.3.1