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