targets: Ambiq Apollo4 support

Adds a new Ambiq Apollo4 target that uses Ambiq Suite SDK
HAL and FreeRTOS.

Change-Id: Ie5788d2eba7b55b4423dd4c8ca9402f55362e33d
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/129490
Commit-Queue: Viktor Elizarov <elizarovv@google.com>
Presubmit-Verified: CQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Armando Montanez <amontanez@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index 9c26edd..14af529 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -24,6 +24,7 @@
 import("$dir_pw_perf_test/perf_test.gni")
 import("$dir_pw_rpc/config.gni")
 import("$dir_pw_rust/rust.gni")
+import("$dir_pw_third_party/ambiq/ambiq.gni")
 import("$dir_pw_third_party/mcuxpresso/mcuxpresso.gni")
 import("$dir_pw_toolchain/c_optimization.gni")
 import("$dir_pw_toolchain/generate_toolchain.gni")
@@ -228,6 +229,12 @@
   }
 }
 
+if (dir_pw_third_party_ambiq_SDK != "") {
+  _build_pigweed_default_at_all_optimization_levels("apollo4") {
+    toolchain_prefix = "$dir_pigweed/targets/apollo4:apollo4_"
+  }
+}
+
 _build_pigweed_default_at_all_optimization_levels("stm32f429i") {
   toolchain_prefix = "$dir_pigweed/targets/stm32f429i_disc1:stm32f429i_disc1_"
 }
diff --git a/PIGWEED_MODULES b/PIGWEED_MODULES
index 7f0e2ed..da2656e 100644
--- a/PIGWEED_MODULES
+++ b/PIGWEED_MODULES
@@ -108,6 +108,7 @@
 pw_sync_threadx
 pw_sync_zephyr
 pw_sys_io
+pw_sys_io_ambiq_sdk
 pw_sys_io_arduino
 pw_sys_io_baremetal_lm3s6965evb
 pw_sys_io_baremetal_stm32f429
diff --git a/docs/BUILD.gn b/docs/BUILD.gn
index f645421..8397fbf 100644
--- a/docs/BUILD.gn
+++ b/docs/BUILD.gn
@@ -79,6 +79,8 @@
 group("target_docs") {
   deps = [
     "$dir_pigweed/targets/android:target_docs",
+    "$dir_pigweed/targets/apollo4:target_docs",
+    "$dir_pigweed/targets/apollo4_pw_system:target_docs",
     "$dir_pigweed/targets/arduino:target_docs",
     "$dir_pigweed/targets/docs:target_docs",
     "$dir_pigweed/targets/emcraft_sf2_som:docs",
diff --git a/pw_build/generated_pigweed_modules_lists.gni b/pw_build/generated_pigweed_modules_lists.gni
index c9ebaab..2e03dae 100644
--- a/pw_build/generated_pigweed_modules_lists.gni
+++ b/pw_build/generated_pigweed_modules_lists.gni
@@ -145,6 +145,7 @@
   dir_pw_sync_threadx = get_path_info("../pw_sync_threadx", "abspath")
   dir_pw_sync_zephyr = get_path_info("../pw_sync_zephyr", "abspath")
   dir_pw_sys_io = get_path_info("../pw_sys_io", "abspath")
+  dir_pw_sys_io_ambiq_sdk = get_path_info("../pw_sys_io_ambiq_sdk", "abspath")
   dir_pw_sys_io_arduino = get_path_info("../pw_sys_io_arduino", "abspath")
   dir_pw_sys_io_baremetal_lm3s6965evb =
       get_path_info("../pw_sys_io_baremetal_lm3s6965evb", "abspath")
@@ -300,6 +301,7 @@
     dir_pw_sync_threadx,
     dir_pw_sync_zephyr,
     dir_pw_sys_io,
+    dir_pw_sys_io_ambiq_sdk,
     dir_pw_sys_io_arduino,
     dir_pw_sys_io_baremetal_lm3s6965evb,
     dir_pw_sys_io_baremetal_stm32f429,
@@ -447,6 +449,7 @@
     "$dir_pw_sync_threadx:tests",
     "$dir_pw_sync_zephyr:tests",
     "$dir_pw_sys_io:tests",
+    "$dir_pw_sys_io_ambiq_sdk:tests",
     "$dir_pw_sys_io_arduino:tests",
     "$dir_pw_sys_io_baremetal_lm3s6965evb:tests",
     "$dir_pw_sys_io_baremetal_stm32f429:tests",
@@ -594,6 +597,7 @@
     "$dir_pw_sync_threadx:docs",
     "$dir_pw_sync_zephyr:docs",
     "$dir_pw_sys_io:docs",
+    "$dir_pw_sys_io_ambiq_sdk:docs",
     "$dir_pw_sys_io_arduino:docs",
     "$dir_pw_sys_io_baremetal_lm3s6965evb:docs",
     "$dir_pw_sys_io_baremetal_stm32f429:docs",
diff --git a/pw_sys_io_ambiq_sdk/BUILD.bazel b/pw_sys_io_ambiq_sdk/BUILD.bazel
new file mode 100644
index 0000000..bd423e1
--- /dev/null
+++ b/pw_sys_io_ambiq_sdk/BUILD.bazel
@@ -0,0 +1,39 @@
+# Copyright 2020 The Pigweed Authors
+#
+# Licensed 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
+#
+#     https://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.
+
+load(
+    "//pw_build:pigweed.bzl",
+    "pw_cc_library",
+)
+
+package(default_visibility = ["//visibility:public"])
+
+licenses(["notice"])
+
+constraint_value(
+    name = "backend",
+    constraint_setting = "//pw_sys_io:backend_constraint_setting",
+)
+
+pw_cc_library(
+    name = "pw_sys_ambiq_sdk",
+    srcs = ["sys_io.cc"],
+    hdrs = ["public/pw_sys_io_ambiq_sdk/init.h"],
+    tags = ["manual"],
+    deps = [
+        "//pw_boot_cortex_m:armv7m",
+        "//pw_preprocessor",
+        "//pw_sys_io:facade",
+    ],
+)
diff --git a/pw_sys_io_ambiq_sdk/BUILD.gn b/pw_sys_io_ambiq_sdk/BUILD.gn
new file mode 100644
index 0000000..1f286a7
--- /dev/null
+++ b/pw_sys_io_ambiq_sdk/BUILD.gn
@@ -0,0 +1,44 @@
+# Copyright 2020 The Pigweed Authors
+#
+# Licensed 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
+#
+#     https://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.
+
+import("//build_overrides/pigweed.gni")
+
+import("$dir_pw_build/target_types.gni")
+import("$dir_pw_docgen/docs.gni")
+import("$dir_pw_third_party/ambiq/ambiq.gni")
+import("$dir_pw_unit_test/test.gni")
+
+config("default_config") {
+  include_dirs = [ "public" ]
+}
+
+pw_source_set("pw_sys_io_ambiq_sdk") {
+  public_configs = [ ":default_config" ]
+  public = [ "public/pw_sys_io_ambiq_sdk/init.h" ]
+  public_deps = [ "$dir_pw_preprocessor" ]
+
+  deps = [
+    "$dir_pw_sys_io:default_putget_bytes",
+    "$dir_pw_sys_io:facade",
+    "$dir_pw_third_party/ambiq:sdk",
+  ]
+  sources = [ "sys_io.cc" ]
+}
+
+pw_test_group("tests") {
+}
+
+pw_doc_group("docs") {
+  sources = [ "docs.rst" ]
+}
diff --git a/pw_sys_io_ambiq_sdk/docs.rst b/pw_sys_io_ambiq_sdk/docs.rst
new file mode 100644
index 0000000..ae7c065
--- /dev/null
+++ b/pw_sys_io_ambiq_sdk/docs.rst
@@ -0,0 +1,24 @@
+.. _module-pw_sys_io_ambiq_sdk:
+
+===============================
+pw_sys_io_ambiq_sdk
+===============================
+
+``pw_sys_io_ambiq_sdk`` implements the ``pw_sys_io`` facade over UART using the
+Ambiq Suite SDK HAL.
+
+The UART baud rate is fixed at 115200 (8N1).
+
+Setup
+=====
+This module requires relatively minimal setup:
+
+  1. Write code against the ``pw_sys_io`` facade.
+  2. Specify the ``dir_pw_sys_io_backend`` GN global variable to point to this
+     backend.
+  3. Call ``pw_sys_io_Init()`` during init so the UART is properly initialized
+     and configured.
+
+The UART peripheral and the GPIO pins are defined in the ``am_bsp.h`` file. Make sure
+that the build argument ``pw_third_party_ambiq_PRODUCT`` is set correctly so that
+the correct bsp header file is included.
diff --git a/pw_sys_io_ambiq_sdk/public/pw_sys_io_ambiq_sdk/init.h b/pw_sys_io_ambiq_sdk/public/pw_sys_io_ambiq_sdk/init.h
new file mode 100644
index 0000000..d4262c5
--- /dev/null
+++ b/pw_sys_io_ambiq_sdk/public/pw_sys_io_ambiq_sdk/init.h
@@ -0,0 +1,23 @@
+// Copyright 2020 The Pigweed Authors
+//
+// Licensed 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
+//
+//     https://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.
+#pragma once
+
+#include "pw_preprocessor/util.h"
+
+PW_EXTERN_C_START
+
+// The actual implement of PreMainInit() in sys_io_BACKEND.
+void pw_sys_io_Init();
+
+PW_EXTERN_C_END
diff --git a/pw_sys_io_ambiq_sdk/sys_io.cc b/pw_sys_io_ambiq_sdk/sys_io.cc
new file mode 100644
index 0000000..5e19f1f
--- /dev/null
+++ b/pw_sys_io_ambiq_sdk/sys_io.cc
@@ -0,0 +1,138 @@
+// Copyright 2020 The Pigweed Authors
+//
+// Licensed 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
+//
+//     https://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 "pw_sys_io/sys_io.h"
+
+#include <cinttypes>
+
+#include "am_bsp.h"
+#include "am_mcu_apollo.h"
+#include "pw_preprocessor/compiler.h"
+
+namespace {
+void* hal_uart_handle{};
+}  // namespace
+
+PW_EXTERN_C void pw_sys_io_Init() {
+  // Use baud rate of 115200 (8N1).
+  static constexpr am_hal_uart_config_t kUartConfig = {
+      .ui32BaudRate = 115200,
+      .eDataBits = AM_HAL_UART_DATA_BITS_8,
+      .eParity = AM_HAL_UART_PARITY_NONE,
+      .eStopBits = AM_HAL_UART_ONE_STOP_BIT,
+      .eFlowControl = AM_HAL_UART_FLOW_CTRL_NONE,
+      .eTXFifoLevel = AM_HAL_UART_FIFO_LEVEL_16,
+      .eRXFifoLevel = AM_HAL_UART_FIFO_LEVEL_16,
+  };
+
+  // Initialize the UART peripheral.
+  am_hal_uart_initialize(AM_BSP_UART_PRINT_INST, &hal_uart_handle);
+
+  // Change the power state of the UART peripheral.
+  am_hal_uart_power_control(hal_uart_handle, AM_HAL_SYSCTRL_WAKE, false);
+
+  // Configure UART (baudrate etc.).
+  am_hal_uart_configure(hal_uart_handle, &kUartConfig);
+
+  // Enable the UART TX and RX GPIO's.
+  am_hal_gpio_pinconfig(AM_BSP_GPIO_COM_UART_TX, g_AM_BSP_GPIO_COM_UART_TX);
+  am_hal_gpio_pinconfig(AM_BSP_GPIO_COM_UART_RX, g_AM_BSP_GPIO_COM_UART_RX);
+}
+
+namespace pw::sys_io {
+
+// Wait for a byte to read on UART0. This blocks until a byte is read. This is
+// extremely inefficient as it requires the target to burn CPU cycles polling to
+// see if a byte is ready yet.
+Status ReadByte(std::byte* dest) {
+  while (true) {
+    if (TryReadByte(dest).ok()) {
+      return OkStatus();
+    }
+  }
+}
+
+Status TryReadByte(std::byte* dest) {
+  am_hal_uart_transfer_t transaction{};
+  uint32_t bytes_read{};
+
+  // Configure UART transaction for the read operation.
+  transaction.eType = AM_HAL_UART_BLOCKING_READ;
+  transaction.pui8Data = reinterpret_cast<uint8_t*>(dest);
+  transaction.ui32NumBytes = 1;
+  transaction.ui32TimeoutMs = AM_HAL_UART_WAIT_FOREVER;
+  transaction.pui32BytesTransferred = &bytes_read;
+
+  // Do read data over UART.
+  if (am_hal_uart_transfer(hal_uart_handle, &transaction) !=
+      AM_HAL_STATUS_SUCCESS) {
+    return Status::ResourceExhausted();
+  }
+
+  if (bytes_read != 1u) {
+    return Status::DataLoss();
+  }
+
+  return OkStatus();
+}
+
+Status WriteByte(std::byte b) {
+  am_hal_uart_transfer_t transaction{};
+  uint32_t chars_written{};
+
+  // Configure UART transaction for the write operation.
+  transaction.eType = AM_HAL_UART_BLOCKING_WRITE;
+  transaction.pui8Data =
+      const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(&b));
+  transaction.ui32NumBytes = 1;
+  transaction.ui32TimeoutMs = AM_HAL_UART_WAIT_FOREVER;
+  transaction.pui32BytesTransferred = &chars_written;
+
+  // Do write data over UART.
+  if (am_hal_uart_transfer(hal_uart_handle, &transaction) !=
+      AM_HAL_STATUS_SUCCESS) {
+    return Status::ResourceExhausted();
+  }
+
+  if (chars_written != 1) {
+    return Status::DataLoss();
+  }
+
+  return OkStatus();
+}
+
+// Writes a string using pw::sys_io, and add newline characters at the end.
+StatusWithSize WriteLine(const std::string_view& s) {
+  StatusWithSize result = WriteBytes(as_bytes(span(s)));
+  if (!result.ok()) {
+    return result;
+  }
+
+  size_t chars_written = result.size();
+  if (chars_written != s.size()) {
+    return StatusWithSize::DataLoss(chars_written);
+  }
+
+  // Write trailing newline.
+  result = WriteBytes(as_bytes(span("\r\n", 2)));
+  chars_written += result.size();
+
+  if (result.size() != 2) {
+    return StatusWithSize::DataLoss(chars_written);
+  }
+
+  return StatusWithSize(chars_written);
+}
+
+}  // namespace pw::sys_io
diff --git a/pw_system/BUILD.gn b/pw_system/BUILD.gn
index 8cb2d67..e20c9f8 100644
--- a/pw_system/BUILD.gn
+++ b/pw_system/BUILD.gn
@@ -14,6 +14,7 @@
 
 import("//build_overrides/pigweed.gni")
 
+import("$dir_pigweed/third_party/ambiq/ambiq.gni")
 import("$dir_pigweed/third_party/freertos/freertos.gni")
 import("$dir_pigweed/third_party/nanopb/nanopb.gni")
 import("$dir_pigweed/third_party/pico_sdk/pi_pico.gni")
@@ -255,6 +256,12 @@
       ":system_example($dir_pigweed/targets/rp2040_pw_system:rp2040_pw_system.size_optimized)",
     ]
   }
+  if (dir_pw_third_party_ambiq_SDK != "" && dir_pw_third_party_freertos != "") {
+    deps += [
+      ":system_example($dir_pigweed/targets/apollo4_pw_system:apollo4_pw_system.debug)",
+      ":system_example($dir_pigweed/targets/apollo4_pw_system:apollo4_pw_system.size_optimized)",
+    ]
+  }
 }
 
 pw_doc_group("docs") {
diff --git a/targets/apollo4/BUILD.bazel b/targets/apollo4/BUILD.bazel
new file mode 100644
index 0000000..5f65670
--- /dev/null
+++ b/targets/apollo4/BUILD.bazel
@@ -0,0 +1,27 @@
+# Copyright 2023 The Pigweed Authors
+#
+# Licensed 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
+#
+#     https://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.
+
+package(default_visibility = ["//visibility:public"])
+
+licenses(["notice"])
+
+# This is just a stub to silence warnings saying that files are
+# missing from the bazel build.
+filegroup(
+    name = "apollo4_files",
+    srcs = [
+        "boot.cc",
+        "vector_table.c",
+    ],
+)
diff --git a/targets/apollo4/BUILD.gn b/targets/apollo4/BUILD.gn
new file mode 100644
index 0000000..fada563
--- /dev/null
+++ b/targets/apollo4/BUILD.gn
@@ -0,0 +1,107 @@
+# Copyright 2023 The Pigweed Authors
+#
+# Licensed 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
+#
+#     https://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.
+
+import("//build_overrides/pigweed.gni")
+
+import("$dir_pigweed/third_party/ambiq/ambiq.gni")
+import("$dir_pw_build/error.gni")
+import("$dir_pw_build/linker_script.gni")
+import("$dir_pw_build/target_types.gni")
+import("$dir_pw_cpu_exception/backend.gni")
+import("$dir_pw_docgen/docs.gni")
+import("$dir_pw_malloc/backend.gni")
+import("$dir_pw_system/backend.gni")
+import("$dir_pw_toolchain/generate_toolchain.gni")
+import("target_toolchains.gni")
+
+generate_toolchains("target_toolchains") {
+  toolchains = pw_target_toolchain_apollo4_list
+}
+
+pw_build_assert("check_ambiq_product_defined") {
+  condition = pw_third_party_ambiq_PRODUCT == "apollo4p" ||
+              pw_third_party_ambiq_PRODUCT == "apollo4b"
+  message = "Build argument pw_third_party_ambiq_PRODUCT must be one of " +
+            "the following values: 'apollo4p' or 'apollo4b'."
+  visibility = [ ":*" ]
+}
+
+config("disable_warnings") {
+  cflags = [ "-Wno-undef" ]
+  visibility = [ ":*" ]
+}
+
+config("pw_malloc_active") {
+  if (pw_malloc_BACKEND != "") {
+    defines = [ "PW_MALLOC_ACTIVE=1" ]
+  } else {
+    defines = [ "PW_MALLOC_ACTIVE=0" ]
+  }
+}
+
+config("pw_system_active") {
+  if (pw_system_TARGET_HOOKS_BACKEND != "") {
+    ldflags = [
+      "-Wl,--defsym=SysTick_Handler=xPortSysTickHandler",
+      "-Wl,--defsym=PendSV_Handler=xPortPendSVHandler",
+      "-Wl,--defsym=SVC_Handler=vPortSVCHandler",
+    ]
+  }
+}
+
+config("pw_cpu_exception_active") {
+  if (pw_cpu_exception_ENTRY_BACKEND != "") {
+    ldflags = [
+      "-Wl,--defsym=HardFault_Handler=pw_cpu_exception_Entry",
+      "-Wl,--defsym=MemManage_Handler=pw_cpu_exception_Entry",
+      "-Wl,--defsym=BusFault_Handler=pw_cpu_exception_Entry",
+      "-Wl,--defsym=UsageFault_Handler=pw_cpu_exception_Entry",
+      "-Wl,--defsym=NMI_Handler=pw_cpu_exception_Entry",
+    ]
+  }
+}
+
+if (current_toolchain != default_toolchain) {
+  pw_source_set("boot") {
+    public_configs = [ ":pw_malloc_active" ]
+
+    all_dependent_configs = [
+      ":pw_system_active",
+      ":pw_cpu_exception_active",
+    ]
+
+    public_deps = [ "$dir_pw_third_party/ambiq:sdk" ]
+
+    deps = [
+      ":check_ambiq_product_defined",
+      "$dir_pw_boot",
+      "$dir_pw_boot_cortex_m",
+      "$dir_pw_preprocessor",
+      "$dir_pw_sys_io_ambiq_sdk",
+    ]
+
+    if (pw_malloc_BACKEND != "") {
+      deps += [ "$dir_pw_malloc" ]
+    }
+
+    sources = [
+      "boot.cc",
+      "vector_table.c",
+    ]
+  }
+}
+
+pw_doc_group("target_docs") {
+  sources = [ "target_docs.rst" ]
+}
diff --git a/targets/apollo4/OWNERS b/targets/apollo4/OWNERS
new file mode 100644
index 0000000..0eb639f
--- /dev/null
+++ b/targets/apollo4/OWNERS
@@ -0,0 +1 @@
+elizarovv@google.com
diff --git a/targets/apollo4/apollo4_executable.gni b/targets/apollo4/apollo4_executable.gni
new file mode 100644
index 0000000..49878f2
--- /dev/null
+++ b/targets/apollo4/apollo4_executable.gni
@@ -0,0 +1,33 @@
+# Copyright 2023 The Pigweed Authors
+#
+# Licensed 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
+#
+#     https://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.
+
+import("//build_overrides/pigweed.gni")
+import("$dir_pw_malloc/backend.gni")
+
+# Executable wrapper that includes some baremetal startup code.
+template("apollo4_executable") {
+  target("executable", target_name) {
+    forward_variables_from(invoker, "*")
+    if (!defined(deps)) {
+      deps = []
+    }
+    deps += [ "$dir_pigweed/targets/apollo4:boot" ]
+    if (pw_malloc_BACKEND != "") {
+      if (!defined(configs)) {
+        configs = []
+      }
+      configs += [ "$dir_pw_malloc:pw_malloc_wrapper_config" ]
+    }
+  }
+}
diff --git a/targets/apollo4/boot.cc b/targets/apollo4/boot.cc
new file mode 100644
index 0000000..5072f69
--- /dev/null
+++ b/targets/apollo4/boot.cc
@@ -0,0 +1,37 @@
+// Copyright 2023 The Pigweed Authors
+//
+// Licensed 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
+//
+//     https://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 "pw_boot_cortex_m/boot.h"
+
+#include "pw_malloc/malloc.h"
+#include "pw_sys_io_ambiq_sdk/init.h"
+
+PW_EXTERN_C void pw_boot_PreStaticMemoryInit() {}
+
+PW_EXTERN_C void pw_boot_PreStaticConstructorInit() {
+  if constexpr (PW_MALLOC_ACTIVE == 1) {
+    pw_MallocInit(&pw_boot_heap_low_addr, &pw_boot_heap_high_addr);
+  }
+
+  pw_sys_io_Init();
+}
+
+PW_EXTERN_C void pw_boot_PreMainInit() {}
+
+PW_EXTERN_C PW_NO_RETURN void pw_boot_PostMain() {
+  // In case main() returns, just sit here until the device is reset.
+  while (true) {
+  }
+  PW_UNREACHABLE;
+}
diff --git a/targets/apollo4/target_docs.rst b/targets/apollo4/target_docs.rst
new file mode 100644
index 0000000..35e36c9
--- /dev/null
+++ b/targets/apollo4/target_docs.rst
@@ -0,0 +1,165 @@
+.. _target-apollo4:
+
+===========================
+Ambiq Apollo4
+===========================
+-----
+Setup
+-----
+To use this target, Pigweed must be set up to use the `AmbiqSuite SDK`_ HAL
+for the Apollo4 series which can be downloaded from the Ambiq website.
+
+.. _AmbiqSuite SDK: https://ambiq.com/apollo4-blue-plus
+
+Once the AmbiqSuite SDK package has been downloaded and extracted, the user
+needs to set ``dir_pw_third_party_ambiq_SDK`` build arg to the location of
+extracted directory:
+
+.. code:: sh
+
+  $ gn args out
+
+Then add the following lines to that text file:
+
+.. code::
+
+  # Path to the extracted AmbiqSuite SDK package.
+  dir_pw_third_party_ambiq_SDK = "/path/to/AmbiqSuite_R4.3.0"
+
+Usage
+=====
+The Apollo4 is configured to output logs and test results over the UART to an
+on-board J-Link Debug Probe (Virtual COM Port) at a baud rate of 115200.
+
+Once the AmbiqSuite SDK is configured, the unit tests for the Apollo4 board
+can be build with a command:
+
+.. code:: sh
+
+  ninja -C out apollo4
+
+If using out as a build directory, tests will be located in out/apollo4/obj/[module name]/[test_name].elf.
+
+Flashing using SEGGER's J-Link
+==============================
+Flashing the Apollo4 board can be done using the J-Flash Lite GUI program or from
+a command line using ``JLinkExe`` program. The latter requires a script which
+describes the steps of programming. Here is an example bash script to flash
+an Apollo4 board using ``JLinkExe`` program:
+
+.. code:: sh
+
+  #!/bin/bash
+  function flash_jlink()
+  {
+     local TMP_FLASH_SCRIPT=/tmp/gdb-flash.txt
+
+     cat > $TMP_FLASH_SCRIPT <<- EOF
+        r
+        h
+        loadfile $1
+        r
+        q
+     EOF
+
+     JLinkExe -NoGui 1 -device AMAP42KK-KBR -if SWD -speed 4000 -autoconnect 1 -CommanderScript $TMP_FLASH_SCRIPT
+
+     rm "$TMP_FLASH_SCRIPT"
+  }
+
+  flash_jlink $@
+
+Then call this script:
+
+.. code:: sh
+
+  bash ./flash_amap4.sh ./out/apollo4_debug/obj/pw_log/test/basic_log_test.elf
+
+In this case the basic log test is debugged, but substitute your own ELF file.
+
+Debugging
+=========
+Debugging can be done using the on-board J-Link Debug Probe. First you need to
+start ``JLinkGDBServer`` and connect to the on-board J-Link Debug Probe.
+
+.. code:: sh
+
+  JLinkGDBServer -select USB      \
+            -device AMAP42KK-KBR  \
+            -endian little        \
+            -if SWD               \
+            -speed 4000           \
+            -noir -LocalhostOnly  \
+            -singlerun            \
+            -nogui                \
+            -excdbg               \
+            -rtos GDBServer/RTOSPlugin_FreeRTOS.dylib
+
+The ``-rtos`` option is for `Thread Aware Debugging`_.
+
+.. _Thread Aware Debugging: https://www.segger.com/products/debug-probes/j-link/tools/j-link-gdb-server/thread-aware-debugging/
+
+Then on the second terminal window use ``arm-none-eabi-gdb`` to load an executable
+into the target, debug, and run it.
+
+.. code:: sh
+
+  arm-none-eabi-gdb -q out/apollo4_debug/obj/pw_log/test/basic_log_test.elf
+
+This can be combined with a simple bash script. Here is an example of one:
+
+.. code:: sh
+
+  #!/bin/bash
+
+  function debug_jlink()
+  {
+     local TMP_GDB_SCRIPT=/tmp/gdb-debug.txt
+
+     # Create GDB script.
+
+     cat > $TMP_GDB_SCRIPT <<- EOF
+
+     # Backtrace all threads.
+
+     define btall
+       thread apply all backtrace
+     end
+
+     target remote localhost:2331
+     load
+     monitor reset
+     monitor halt
+     b pw_boot_Entry
+
+     EOF
+
+     # Start GDB server.
+
+     set -m
+     JLinkGDBServer -select USB       \
+                -device AMAP42KK-KBR  \
+                -endian little        \
+                -if SWD               \
+                -speed 4000           \
+                -noir -LocalhostOnly  \
+                -singlerun            \
+                -nogui                \
+                -excdbg               \
+                -rtos GDBServer/RTOSPlugin_FreeRTOS.dylib &
+     set +m
+
+     # Debug program.
+
+     arm-none-eabi-gdb -q $1 -x $TMP_GDB_SCRIPT
+
+     rm "$TMP_GDB_SCRIPT"
+  }
+
+  debug_jlink $@
+
+Then call this script:
+
+.. code:: sh
+
+  bash ./debug_amap4.sh ./out/apollo4_debug/obj/pw_log/test/basic_log_test.elf
diff --git a/targets/apollo4/target_toolchains.gni b/targets/apollo4/target_toolchains.gni
new file mode 100644
index 0000000..e614f71
--- /dev/null
+++ b/targets/apollo4/target_toolchains.gni
@@ -0,0 +1,149 @@
+# Copyright 2023 The Pigweed Authors
+#
+# Licensed 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
+#
+#     https://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.
+
+import("//build_overrides/pigweed.gni")
+
+import("$dir_pw_log/backend.gni")
+import("$dir_pw_toolchain/arm_gcc/toolchains.gni")
+
+_target_config = {
+  pw_third_party_ambiq_PRODUCT = "apollo4p"
+
+  # Use the logging main.
+  pw_unit_test_MAIN = "$dir_pw_unit_test:logging_main"
+
+  # Use ARM Cycle Counts
+  pw_perf_test_TIMER_INTERFACE_BACKEND = "$dir_pw_perf_test:arm_cortex_timer"
+
+  # Configuration options for Pigweed executable targets.
+  pw_build_EXECUTABLE_TARGET_TYPE = "apollo4_executable"
+
+  pw_build_EXECUTABLE_TARGET_TYPE_FILE =
+      get_path_info("apollo4_executable.gni", "abspath")
+
+  # Path to the bloaty config file for the output binaries.
+  pw_bloat_BLOATY_CONFIG = "$dir_pw_boot_cortex_m/bloaty_config.bloaty"
+
+  # Configure backend for assert facade.
+  pw_assert_BACKEND = dir_pw_assert_basic
+
+  pw_boot_BACKEND = "$dir_pw_boot_cortex_m"
+  pw_cpu_exception_ENTRY_BACKEND =
+      "$dir_pw_cpu_exception_cortex_m:cpu_exception"
+  pw_cpu_exception_HANDLER_BACKEND = "$dir_pw_cpu_exception:basic_handler"
+  pw_cpu_exception_SUPPORT_BACKEND = "$dir_pw_cpu_exception_cortex_m:support"
+  pw_sync_INTERRUPT_SPIN_LOCK_BACKEND =
+      "$dir_pw_sync_baremetal:interrupt_spin_lock"
+
+  # Configure backends for pw_sync's facades.
+  pw_sync_MUTEX_BACKEND = "$dir_pw_sync_baremetal:mutex"
+
+  # Configure backend for logging facade.
+  pw_log_BACKEND = "$dir_pw_log_basic"
+
+  # Configure backend for pw_sys_io facade.
+  pw_sys_io_BACKEND = "$dir_pw_sys_io_ambiq_sdk"
+
+  # Configure backend for pw_rpc_system_server.
+  pw_rpc_system_server_BACKEND = "$dir_pw_hdlc:hdlc_sys_io_system_server"
+  pw_rpc_CONFIG = "$dir_pw_rpc:disable_global_mutex"
+
+  pw_malloc_BACKEND = "$dir_pw_malloc_freelist"
+
+  pw_boot_cortex_m_LINK_CONFIG_DEFINES = [
+    "PW_BOOT_VECTOR_TABLE_BEGIN=0x00018000",
+    "PW_BOOT_VECTOR_TABLE_SIZE=512",
+
+    "PW_BOOT_FLASH_BEGIN=0x00018200",
+    "PW_BOOT_FLASH_SIZE=1951K",
+
+    "PW_BOOT_HEAP_SIZE=100K",
+    "PW_BOOT_MIN_STACK_SIZE=1K",
+
+    "PW_BOOT_RAM_BEGIN=0x10000000",
+    "PW_BOOT_RAM_SIZE=1408K",
+  ]
+
+  pw_build_LINK_DEPS = []  # Explicit list overwrite required by GN
+  pw_build_LINK_DEPS = [
+    "$dir_pw_assert:impl",
+    "$dir_pw_log:impl",
+    "$dir_pw_cpu_exception:entry_impl",
+    "$dir_pw_toolchain/arm_gcc:arm_none_eabi_gcc_support",
+  ]
+
+  current_cpu = "arm"
+  current_os = ""
+}
+
+_toolchain_properties = {
+  final_binary_extension = ".elf"
+}
+
+_target_default_configs = [
+  "$dir_pw_build:extra_strict_warnings",
+  "$dir_pw_toolchain/arm_gcc:enable_float_printf",
+]
+
+pw_target_toolchain_apollo4 = {
+  _excluded_members = [
+    "defaults",
+    "name",
+  ]
+
+  debug = {
+    name = "apollo4_debug"
+    _toolchain_base = pw_toolchain_arm_gcc.cortex_m4f_debug
+    forward_variables_from(_toolchain_base, "*", _excluded_members)
+    forward_variables_from(_toolchain_properties, "*")
+    defaults = {
+      forward_variables_from(_toolchain_base.defaults, "*")
+      forward_variables_from(_target_config, "*")
+      default_configs += _target_default_configs
+    }
+  }
+
+  speed_optimized = {
+    name = "apollo4_speed_optimized"
+    _toolchain_base = pw_toolchain_arm_gcc.cortex_m4f_speed_optimized
+    forward_variables_from(_toolchain_base, "*", _excluded_members)
+    forward_variables_from(_toolchain_properties, "*")
+    defaults = {
+      forward_variables_from(_toolchain_base.defaults, "*")
+      forward_variables_from(_target_config, "*")
+      default_configs += _target_default_configs
+    }
+  }
+
+  size_optimized = {
+    name = "apollo4_size_optimized"
+    _toolchain_base = pw_toolchain_arm_gcc.cortex_m4f_size_optimized
+    forward_variables_from(_toolchain_base, "*", _excluded_members)
+    forward_variables_from(_toolchain_properties, "*")
+    defaults = {
+      forward_variables_from(_toolchain_base.defaults, "*")
+      forward_variables_from(_target_config, "*")
+      default_configs += _target_default_configs
+    }
+  }
+}
+
+# This list just contains the members of the above scope for convenience to make
+# it trivial to generate all the toolchains in this file via a
+# `generate_toolchains` target.
+pw_target_toolchain_apollo4_list = [
+  pw_target_toolchain_apollo4.debug,
+  pw_target_toolchain_apollo4.speed_optimized,
+  pw_target_toolchain_apollo4.size_optimized,
+]
diff --git a/targets/apollo4/vector_table.c b/targets/apollo4/vector_table.c
new file mode 100644
index 0000000..a05e153
--- /dev/null
+++ b/targets/apollo4/vector_table.c
@@ -0,0 +1,222 @@
+// Copyright 2023 The Pigweed Authors
+//
+// Licensed 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
+//
+//     https://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 "pw_boot/boot.h"
+#include "pw_boot_cortex_m/boot.h"
+#include "pw_preprocessor/compiler.h"
+
+// Default handler to insert into the ARMv7-M vector table (below).
+// This function exists for convenience. If a device isn't doing what you
+// expect, it might have hit a fault and ended up here.
+static void DefaultFaultHandler(void) {
+  while (true) {
+    // Wait for debugger to attach.
+  }
+}
+
+// This typedef is for convenience when building the vector table. With the
+// exception of SP_main (0th entry in the vector table), all the entries of the
+// vector table are function pointers.
+typedef void (*InterruptHandler)(void);
+
+void SVC_Handler(void) PW_ALIAS(DefaultFaultHandler);
+void PendSV_Handler(void) PW_ALIAS(DefaultFaultHandler);
+void SysTick_Handler(void) PW_ALIAS(DefaultFaultHandler);
+
+void MemManage_Handler(void) PW_ALIAS(DefaultFaultHandler);
+void BusFault_Handler(void) PW_ALIAS(DefaultFaultHandler);
+void UsageFault_Handler(void) PW_ALIAS(DefaultFaultHandler);
+void DebugMon_Handler(void) PW_ALIAS(DefaultFaultHandler);
+
+void am_brownout_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_watchdog_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_rtc_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_vcomp_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_ioslave_ios_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_ioslave_acc_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_iomaster0_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_iomaster1_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_iomaster2_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_iomaster3_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_iomaster4_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_iomaster5_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_iomaster6_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_iomaster7_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_ctimer_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_uart_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_uart1_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_uart2_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_uart3_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_adc_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_mspi0_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_mspi1_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_mspi2_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_clkgen_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_cryptosec_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_sdio_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_usb_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_gpu_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_disp_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_dsi_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_stimer_cmpr0_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_stimer_cmpr1_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_stimer_cmpr2_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_stimer_cmpr3_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_stimer_cmpr4_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_stimer_cmpr5_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_stimer_cmpr6_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_stimer_cmpr7_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_stimerof_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_audadc0_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_dspi2s0_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_dspi2s1_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_dspi2s2_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_dspi2s3_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_pdm0_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_pdm1_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_pdm2_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_pdm3_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_gpio0_001f_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_gpio0_203f_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_gpio0_405f_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_gpio0_607f_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_gpio1_001f_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_gpio1_203f_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_gpio1_405f_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_gpio1_607f_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_timer00_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_timer01_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_timer02_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_timer03_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_timer04_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_timer05_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_timer06_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_timer07_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_timer08_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_timer09_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_timer10_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_timer11_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_timer12_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_timer13_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_timer14_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_timer15_isr(void) PW_ALIAS(DefaultFaultHandler);
+void am_cachecpu_isr(void) PW_ALIAS(DefaultFaultHandler);
+
+PW_KEEP_IN_SECTION(".vector_table")
+const InterruptHandler vector_table[] = {
+    // Cortex-M CPU specific interrupt handlers.
+    (InterruptHandler)(&pw_boot_stack_high_addr),
+    pw_boot_Entry,        // The reset handler
+    DefaultFaultHandler,  // The NMI handler
+    DefaultFaultHandler,  // The hard fault handler
+    DefaultFaultHandler,  // The MemManage_Handler
+    DefaultFaultHandler,  // The BusFault_Handler
+    DefaultFaultHandler,  // The UsageFault_Handler
+    0,                    // Reserved
+    0,                    // Reserved
+    0,                    // Reserved
+    0,                    // Reserved
+    SVC_Handler,          // SVCall handler
+    DefaultFaultHandler,  // Debug monitor handler
+    0,                    // Reserved
+    PendSV_Handler,       // The PendSV handler
+    SysTick_Handler,      // The SysTick handler
+    // Vendor specific peripheral interrupt handlers.
+    am_brownout_isr,      //  0: Brownout (rstgen)
+    am_watchdog_isr,      //  1: Watchdog (WDT)
+    am_rtc_isr,           //  2: RTC
+    am_vcomp_isr,         //  3: Voltage Comparator
+    am_ioslave_ios_isr,   //  4: I/O Responder general
+    am_ioslave_acc_isr,   //  5: I/O Responder access
+    am_iomaster0_isr,     //  6: I/O Controller 0
+    am_iomaster1_isr,     //  7: I/O Controller 1
+    am_iomaster2_isr,     //  8: I/O Controller 2
+    am_iomaster3_isr,     //  9: I/O Controller 3
+    am_iomaster4_isr,     // 10: I/O Controller 4
+    am_iomaster5_isr,     // 11: I/O Controller 5
+    am_iomaster6_isr,     // 12: I/O Controller 6 (I3C/I2C/SPI)
+    am_iomaster7_isr,     // 13: I/O Controller 7 (I3C/I2C/SPI)
+    am_ctimer_isr,        // 14: OR of all timerX interrupts
+    am_uart_isr,          // 15: UART0
+    am_uart1_isr,         // 16: UART1
+    am_uart2_isr,         // 17: UART2
+    am_uart3_isr,         // 18: UART3
+    am_adc_isr,           // 19: ADC
+    am_mspi0_isr,         // 20: MSPI0
+    am_mspi1_isr,         // 21: MSPI1
+    am_mspi2_isr,         // 22: MSPI2
+    am_clkgen_isr,        // 23: ClkGen
+    am_cryptosec_isr,     // 24: Crypto Secure
+    DefaultFaultHandler,  // 25: Reserved
+    am_sdio_isr,          // 26: SDIO
+    am_usb_isr,           // 27: USB
+    am_gpu_isr,           // 28: GPU
+    am_disp_isr,          // 29: DISP
+    am_dsi_isr,           // 30: DSI
+    DefaultFaultHandler,  // 31: Reserved
+    am_stimer_cmpr0_isr,  // 32: System Timer Compare0
+    am_stimer_cmpr1_isr,  // 33: System Timer Compare1
+    am_stimer_cmpr2_isr,  // 34: System Timer Compare2
+    am_stimer_cmpr3_isr,  // 35: System Timer Compare3
+    am_stimer_cmpr4_isr,  // 36: System Timer Compare4
+    am_stimer_cmpr5_isr,  // 37: System Timer Compare5
+    am_stimer_cmpr6_isr,  // 38: System Timer Compare6
+    am_stimer_cmpr7_isr,  // 39: System Timer Compare7
+    am_stimerof_isr,      // 40: System Timer Cap Overflow
+    DefaultFaultHandler,  // 41: Reserved
+    am_audadc0_isr,       // 42: Audio ADC
+    DefaultFaultHandler,  // 43: Reserved
+    am_dspi2s0_isr,       // 44: I2S0
+    am_dspi2s1_isr,       // 45: I2S1
+    am_dspi2s2_isr,       // 46: I2S2
+    am_dspi2s3_isr,       // 47: I2S3
+    am_pdm0_isr,          // 48: PDM0
+    am_pdm1_isr,          // 49: PDM1
+    am_pdm2_isr,          // 50: PDM2
+    am_pdm3_isr,          // 51: PDM3
+    DefaultFaultHandler,  // 52: Reserved
+    DefaultFaultHandler,  // 53: Reserved
+    DefaultFaultHandler,  // 54: Reserved
+    DefaultFaultHandler,  // 55: Reserved
+    am_gpio0_001f_isr,    // 56: GPIO N0 pins  0-31
+    am_gpio0_203f_isr,    // 57: GPIO N0 pins 32-63
+    am_gpio0_405f_isr,    // 58: GPIO N0 pins 64-95
+    am_gpio0_607f_isr,    // 59: GPIO N0 pins 96-104, virtual 105-127
+    am_gpio1_001f_isr,    // 60: GPIO N1 pins  0-31
+    am_gpio1_203f_isr,    // 61: GPIO N1 pins 32-63
+    am_gpio1_405f_isr,    // 62: GPIO N1 pins 64-95
+    am_gpio1_607f_isr,    // 63: GPIO N1 pins 96-104, virtual 105-127
+    DefaultFaultHandler,  // 64: Reserved
+    DefaultFaultHandler,  // 65: Reserved
+    DefaultFaultHandler,  // 66: Reserved
+    am_timer00_isr,       // 67: timer0
+    am_timer01_isr,       // 68: timer1
+    am_timer02_isr,       // 69: timer2
+    am_timer03_isr,       // 70: timer3
+    am_timer04_isr,       // 71: timer4
+    am_timer05_isr,       // 72: timer5
+    am_timer06_isr,       // 73: timer6
+    am_timer07_isr,       // 74: timer7
+    am_timer08_isr,       // 75: timer8
+    am_timer09_isr,       // 76: timer9
+    am_timer10_isr,       // 77: timer10
+    am_timer11_isr,       // 78: timer11
+    am_timer12_isr,       // 79: timer12
+    am_timer13_isr,       // 80: timer13
+    am_timer14_isr,       // 81: timer14
+    am_timer15_isr,       // 82: timer15
+    am_cachecpu_isr       // 83: CPU cache
+};
diff --git a/targets/apollo4_pw_system/BUILD.bazel b/targets/apollo4_pw_system/BUILD.bazel
new file mode 100644
index 0000000..d83f06e
--- /dev/null
+++ b/targets/apollo4_pw_system/BUILD.bazel
@@ -0,0 +1,27 @@
+# Copyright 2023 The Pigweed Authors
+#
+# Licensed 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
+#
+#     https://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.
+
+package(default_visibility = ["//visibility:public"])
+
+licenses(["notice"])
+
+# This is just a stub to silence warnings saying that files are
+# missing from the bazel build.
+filegroup(
+    name = "apollo4_pw_system_files",
+    srcs = [
+        "config/FreeRTOSConfig.h",
+        "main.cc",
+    ],
+)
diff --git a/targets/apollo4_pw_system/BUILD.gn b/targets/apollo4_pw_system/BUILD.gn
new file mode 100644
index 0000000..d37d20a
--- /dev/null
+++ b/targets/apollo4_pw_system/BUILD.gn
@@ -0,0 +1,87 @@
+# Copyright 2023 The Pigweed Authors
+#
+# Licensed 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
+#
+#     https://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.
+
+import("//build_overrides/pigweed.gni")
+
+import("$dir_pw_build/target_types.gni")
+import("$dir_pw_docgen/docs.gni")
+import("$dir_pw_system/system_target.gni")
+
+config("config_includes") {
+  include_dirs = [ "config" ]
+}
+
+if (current_toolchain != default_toolchain) {
+  pw_source_set("main") {
+    deps = [
+      "$dir_pigweed/targets/apollo4:boot",
+      "$dir_pw_system",
+      "$dir_pw_third_party/freertos",
+    ]
+
+    sources = [ "main.cc" ]
+  }
+
+  pw_source_set("apollo4_freertos_config") {
+    public_configs = [ ":config_includes" ]
+    public_deps = [ "$dir_pw_third_party/freertos:config_assert" ]
+    public = [ "config/FreeRTOSConfig.h" ]
+  }
+}
+
+pw_system_target("apollo4_pw_system") {
+  cpu = PW_SYSTEM_CPU.CORTEX_M4F
+  scheduler = PW_SYSTEM_SCHEDULER.FREERTOS
+
+  build_args = {
+    pw_third_party_ambiq_PRODUCT = "apollo4p"
+    pw_log_BACKEND = dir_pw_log_tokenized
+
+    pw_third_party_freertos_CONFIG =
+        "$dir_pigweed/targets/apollo4_pw_system:apollo4_freertos_config"
+    pw_third_party_freertos_PORT = "$dir_pw_third_party/freertos:arm_cm4f"
+    pw_sys_io_BACKEND = "$dir_pw_sys_io_ambiq_sdk"
+    pw_log_BACKEND = "$dir_pw_log_basic"
+    pw_cpu_exception_ENTRY_BACKEND =
+        "$dir_pw_cpu_exception_cortex_m:cpu_exception"
+    pw_cpu_exception_HANDLER_BACKEND = "$dir_pw_cpu_exception:basic_handler"
+    pw_cpu_exception_SUPPORT_BACKEND = "$dir_pw_cpu_exception_cortex_m:support"
+
+    pw_boot_cortex_m_LINK_CONFIG_DEFINES = [
+      "PW_BOOT_VECTOR_TABLE_BEGIN=0x00018000",
+      "PW_BOOT_VECTOR_TABLE_SIZE=512",
+
+      "PW_BOOT_FLASH_BEGIN=0x00018200",
+      "PW_BOOT_FLASH_SIZE=1951K",
+
+      "PW_BOOT_HEAP_SIZE=100K",
+      "PW_BOOT_MIN_STACK_SIZE=1K",
+
+      "PW_BOOT_RAM_BEGIN=0x10000000",
+      "PW_BOOT_RAM_SIZE=1408K",
+    ]
+
+    pw_build_LINK_DEPS += [
+      "$dir_pigweed/targets/apollo4_pw_system:main",
+      "$dir_pw_assert:impl",
+      "$dir_pw_log:impl",
+      "$dir_pw_cpu_exception:entry_impl",
+      "$dir_pw_toolchain/arm_gcc:arm_none_eabi_gcc_support",
+    ]
+  }
+}
+
+pw_doc_group("target_docs") {
+  sources = [ "target_docs.rst" ]
+}
diff --git a/targets/apollo4_pw_system/OWNERS b/targets/apollo4_pw_system/OWNERS
new file mode 100644
index 0000000..0eb639f
--- /dev/null
+++ b/targets/apollo4_pw_system/OWNERS
@@ -0,0 +1 @@
+elizarovv@google.com
diff --git a/targets/apollo4_pw_system/config/FreeRTOSConfig.h b/targets/apollo4_pw_system/config/FreeRTOSConfig.h
new file mode 100644
index 0000000..8ccd4c9
--- /dev/null
+++ b/targets/apollo4_pw_system/config/FreeRTOSConfig.h
@@ -0,0 +1,81 @@
+// Copyright 2023 The Pigweed Authors
+//
+// Licensed 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
+//
+//     https://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.
+#pragma once
+
+#include <stdint.h>
+
+// Externally defined variables that must be forward-declared for FreeRTOS to
+// use them.
+extern uint32_t SystemCoreClock;
+
+// Disable formatting to make it easier to compare with other config files.
+// clang-format off
+
+#define configUSE_PREEMPTION                    1
+#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
+
+#define configSUPPORT_STATIC_ALLOCATION         1
+#define configSUPPORT_DYNAMIC_ALLOCATION        0
+
+#define configCPU_CLOCK_HZ                      SystemCoreClock
+#define configTICK_RATE_HZ                      1000
+#define configMAX_PRIORITIES                    16
+#define configMINIMAL_STACK_SIZE                128
+
+#define configMAX_TASK_NAME_LEN                 16
+#define configUSE_16_BIT_TICKS                  0
+
+#define configUSE_MUTEXES                       1
+#define configUSE_RECURSIVE_MUTEXES             0
+#define configUSE_COUNTING_SEMAPHORES           1
+#define configQUEUE_REGISTRY_SIZE               8
+#define configUSE_QUEUE_SETS                    0
+#define configUSE_NEWLIB_REENTRANT              0
+#define configENABLE_BACKWARD_COMPATIBILITY     0
+#define configRECORD_STACK_HIGH_ADDRESS         1
+
+#define configUSE_IDLE_HOOK                     0
+#define configUSE_TICK_HOOK                     0
+#define configCHECK_FOR_STACK_OVERFLOW          2
+#define configUSE_MALLOC_FAILED_HOOK            1
+
+#define configGENERATE_RUN_TIME_STATS           0
+#define configUSE_TRACE_FACILITY                0
+
+#define configUSE_TIMERS                        1
+#define configTIMER_TASK_PRIORITY               3
+#define configTIMER_QUEUE_LENGTH                10
+#define configTIMER_TASK_STACK_DEPTH            configMINIMAL_STACK_SIZE
+
+#define configKERNEL_INTERRUPT_PRIORITY             (0x7 << 5)
+#define configMAX_SYSCALL_INTERRUPT_PRIORITY        (0x4 << 5)
+#define NVIC_configKERNEL_INTERRUPT_PRIORITY        (0x7)
+#define NVIC_configMAX_SYSCALL_INTERRUPT_PRIORITY   (0x4)
+
+/* Optional functions - most linkers will remove unused functions anyway. */
+#define INCLUDE_vTaskPrioritySet                1
+#define INCLUDE_uxTaskPriorityGet               1
+#define INCLUDE_vTaskDelete                     1
+#define INCLUDE_vTaskSuspend                    1
+#define INCLUDE_xResumeFromISR                  0
+#define INCLUDE_vTaskDelayUntil                 0
+#define INCLUDE_vTaskDelay                      1
+#define INCLUDE_xTaskGetSchedulerState          1
+#define INCLUDE_xTaskGetCurrentTaskHandle       1
+#define INCLUDE_uxTaskGetStackHighWaterMark2    1
+#define INCLUDE_uxTaskGetStackHighWaterMark     1
+
+// Instead of defining configASSERT(), include a header that provides a
+// definition that redirects to pw_assert.
+#include "pw_third_party/freertos/config_assert.h"
diff --git a/targets/apollo4_pw_system/main.cc b/targets/apollo4_pw_system/main.cc
new file mode 100644
index 0000000..35d383f
--- /dev/null
+++ b/targets/apollo4_pw_system/main.cc
@@ -0,0 +1,74 @@
+// Copyright 2023 The Pigweed Authors
+//
+// Licensed 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
+//
+//     https://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.
+
+#define PW_LOG_MODULE_NAME "pw_system"
+
+#include "FreeRTOS.h"
+#include "pw_log/log.h"
+#include "pw_preprocessor/compiler.h"
+#include "pw_string/util.h"
+#include "pw_system/init.h"
+#include "task.h"
+
+// System core clock value definition, usually provided by the CMSIS package.
+uint32_t SystemCoreClock = 96'000'000ul;
+
+namespace {
+
+#if configCHECK_FOR_STACK_OVERFLOW != 0
+std::array<char, configMAX_TASK_NAME_LEN> temp_thread_name_buffer;
+#endif  // configCHECK_FOR_STACK_OVERFLOW
+
+#if configUSE_TIMERS == 1
+std::array<StackType_t, configTIMER_TASK_STACK_DEPTH> freertos_timer_stack;
+StaticTask_t freertos_timer_tcb;
+#endif  // configUSE_TIMERS == 1
+
+std::array<StackType_t, configMINIMAL_STACK_SIZE> freertos_idle_stack;
+StaticTask_t freertos_idle_tcb;
+}  // namespace
+
+#if configCHECK_FOR_STACK_OVERFLOW != 0
+PW_EXTERN_C void vApplicationStackOverflowHook(TaskHandle_t, char* pcTaskName) {
+  pw::string::Copy(pcTaskName, temp_thread_name_buffer);
+  PW_CRASH("Stack OVF for task %s", temp_thread_name_buffer.data());
+}
+#endif  // configCHECK_FOR_STACK_OVERFLOW
+
+#if configUSE_TIMERS == 1
+PW_EXTERN_C void vApplicationGetTimerTaskMemory(
+    StaticTask_t** ppxTimerTaskTCBBuffer,
+    StackType_t** ppxTimerTaskStackBuffer,
+    uint32_t* pulTimerTaskStackSize) {
+  *ppxTimerTaskTCBBuffer = &freertos_timer_tcb;
+  *ppxTimerTaskStackBuffer = freertos_timer_stack.data();
+  *pulTimerTaskStackSize = freertos_timer_stack.size();
+}
+#endif  // configUSE_TIMERS == 1
+
+PW_EXTERN_C void vApplicationGetIdleTaskMemory(
+    StaticTask_t** ppxIdleTaskTCBBuffer,
+    StackType_t** ppxIdleTaskStackBuffer,
+    uint32_t* pulIdleTaskStackSize) {
+  *ppxIdleTaskTCBBuffer = &freertos_idle_tcb;
+  *ppxIdleTaskStackBuffer = freertos_idle_stack.data();
+  *pulIdleTaskStackSize = freertos_idle_stack.size();
+}
+
+int main() {
+  pw::system::Init();
+  vTaskStartScheduler();
+
+  PW_UNREACHABLE;
+}
diff --git a/targets/apollo4_pw_system/target_docs.rst b/targets/apollo4_pw_system/target_docs.rst
new file mode 100644
index 0000000..90f4800
--- /dev/null
+++ b/targets/apollo4_pw_system/target_docs.rst
@@ -0,0 +1,111 @@
+.. _target-apollo4-pw-system:
+
+============================
+Ambiq Apollo4 with pw_system
+============================
+
+.. warning::
+
+  This target is in a very preliminary state and is under active development.
+  This demo gives a preview of the direction we are heading with
+  :ref:`pw_system<module-pw_system>`, but it is not yet ready for production
+  use.
+
+This target configuration uses :ref:`pw_system<module-pw_system>` on top of
+FreeRTOS and the `AmbiqSuite SDK
+<https://ambiq.com/apollo4-blue-plus>`_ HAL.
+
+-----
+Setup
+-----
+To use this target, Pigweed must be set up to use FreeRTOS and the AmbiqSuite
+SDK HAL for the Apollo4 series. The FreeRTOS repository can be downloaded via
+``pw package``, and the `AmbiqSuite SDK`_ can be downloaded from the Ambiq
+website.
+
+.. _AmbiqSuite SDK: https://ambiq.com/apollo4-blue-plus
+
+Once the AmbiqSuite SDK package has been downloaded and extracted, the user
+needs to set ``dir_pw_third_party_ambiq_SDK`` build arg to the location of
+extracted directory:
+
+.. code:: sh
+
+   $ gn args out
+
+Then add the following lines to that text file:
+
+.. code::
+
+   # Path to the extracted AmbiqSuite SDK package.
+   dir_pw_third_party_ambiq_SDK = "/path/to/AmbiqSuite_R4.3.0"
+
+   # Path to the FreeRTOS source directory.
+   dir_pw_third_party_freertos = "/path/to/pigweed/third_party/freertos"
+
+-----------------------------
+Building and Running the Demo
+-----------------------------
+This target has an associated demo application that can be built and then
+flashed to a device with the following commands:
+
+.. code:: sh
+
+   ninja -C out pw_system_demo
+
+.. seealso::
+
+   The :ref:`target-apollo4` for more info on flashing the Apollo4 board.
+
+Once the board has been flashed, you can connect to it and send RPC commands
+via the Pigweed console:
+
+.. code:: sh
+
+   pw-system-console -d /dev/{ttyX} -b 115200 \
+     --proto-globs pw_rpc/echo.proto \
+     --token-databases \
+       out/apollo4_pw_system.size_optimized/obj/pw_system/bin/system_example.elf
+
+Replace ``{ttyX}`` with the appropriate device on your machine. On Linux this
+may look like ``ttyACM0``, and on a Mac it may look like ``cu.usbmodem***``.
+
+When the console opens, try sending an Echo RPC request. You should get back
+the same message you sent to the device.
+
+.. code:: pycon
+
+   >>> device.rpcs.pw.rpc.EchoService.Echo(msg="Hello, Pigweed!")
+   (Status.OK, pw.rpc.EchoMessage(msg='Hello, Pigweed!'))
+
+You can also try out our thread snapshot RPC service, which should return a
+stack usage overview of all running threads on the device in Host Logs.
+
+.. code:: pycon
+
+   >>> device.rpcs.pw.thread.proto.ThreadSnapshotService.GetPeakStackUsage()
+
+Example output:
+
+.. code::
+
+   20220826 09:47:22  INF  PendingRpc(channel=1, method=pw.thread.ThreadSnapshotService.GetPeakStackUsage) completed: Status.OK
+   20220826 09:47:22  INF  Thread State
+   20220826 09:47:22  INF    5 threads running.
+   20220826 09:47:22  INF
+   20220826 09:47:22  INF  Thread (UNKNOWN): IDLE
+   20220826 09:47:22  INF  Est CPU usage: unknown
+   20220826 09:47:22  INF  Stack info
+   20220826 09:47:22  INF    Current usage:   0x20002da0 - 0x???????? (size unknown)
+   20220826 09:47:22  INF    Est peak usage:  390 bytes, 76.77%
+   20220826 09:47:22  INF    Stack limits:    0x20002da0 - 0x20002ba4 (508 bytes)
+   20220826 09:47:22  INF
+   20220826 09:47:22  INF  ...
+
+You are now up and running!
+
+.. seealso::
+
+   The :ref:`module-pw_console`
+   :bdg-ref-primary-line:`module-pw_console-user_guide` for more info on using
+   the the pw_console UI.
diff --git a/third_party/ambiq/BUILD.gn b/third_party/ambiq/BUILD.gn
new file mode 100644
index 0000000..eaaf514
--- /dev/null
+++ b/third_party/ambiq/BUILD.gn
@@ -0,0 +1,216 @@
+# Copyright 2023 The Pigweed Authors
+#
+# Licensed 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
+#
+#     https://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.
+
+import("//build_overrides/pigweed.gni")
+
+import("$dir_pw_build/target_types.gni")
+import("$dir_pw_docgen/docs.gni")
+import("ambiq.gni")
+
+pw_doc_group("docs") {
+  sources = [ "docs.rst" ]
+}
+
+# This file defines a GN source_set for an external installation of Ambiq SDK.
+# To use, checkout the Ambiq Apollo4 SDK source into a directory, then set
+# the build arg dir_pw_third_party_ambiq_SDK to point to that directory. The
+# Ambiq Apollo 4 SDK library will be available in GN
+# at "$dir_pw_third_party/apollo4".
+if (dir_pw_third_party_ambiq_SDK != "") {
+  config("apollo4p_sdk_defines") {
+    defines = [
+      "AM_PART_APOLLO4P=1",
+      "apollo4p_evb=1",
+      "gcc=1",
+      "AM_PACKAGE_BGA=1",
+    ]
+    visibility = [ ":*" ]
+  }
+
+  config("apollo4b_sdk_defines") {
+    defines = [
+      "AM_PART_APOLLO4B=1",
+      "apollo4b_evb=1",
+      "gcc=1",
+      "AM_PACKAGE_BGA=1",
+    ]
+    visibility = [ ":*" ]
+  }
+
+  config("disable_warnings") {
+    cflags = [
+      "-Wno-sign-compare",
+      "-Wno-unused-parameter",
+      "-Wno-cast-qual",
+      "-Wno-shadow",
+      "-Wno-implicit-fallthrough",
+      "-Wno-maybe-uninitialized",
+    ]
+    cflags_c = [ "-Wno-old-style-declaration" ]
+    visibility = [ ":*" ]
+  }
+
+  config("apollo4_include_dirs") {
+    include_dirs = [
+      "$dir_pw_third_party_ambiq_SDK/devices",
+      "$dir_pw_third_party_ambiq_SDK/utils",
+      "$dir_pw_third_party_ambiq_SDK/CMSIS/ARM/Include",
+      "$dir_pw_third_party_ambiq_SDK/CMSIS/AmbiqMicro/Include",
+    ]
+  }
+
+  config("apollo4p_include_dirs") {
+    include_dirs = [
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/mcu",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p",
+      "$dir_pw_third_party_ambiq_SDK/boards/apollo4p_evb/bsp",
+    ]
+  }
+
+  config("apollo4b_include_dirs") {
+    include_dirs = [
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/mcu",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b",
+      "$dir_pw_third_party_ambiq_SDK/boards/apollo4b_evb/bsp",
+    ]
+  }
+
+  pw_source_set("apollo4p") {
+    remove_configs = [ "$dir_pw_build:extra_strict_warnings" ]
+
+    public_configs = [
+      ":disable_warnings",
+      ":apollo4_include_dirs",
+      ":apollo4p_include_dirs",
+      ":apollo4p_sdk_defines",
+    ]
+
+    sources = [
+      "$dir_pw_third_party_ambiq_SDK/boards/apollo4p_evb/bsp/am_bsp.c",
+      "$dir_pw_third_party_ambiq_SDK/boards/apollo4p_evb/bsp/am_bsp_pins.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/am_hal_access.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/am_hal_adc.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/am_hal_audadc.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/am_hal_dcu.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/am_hal_global.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/am_hal_gpio.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/am_hal_i2s.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/am_hal_otp.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/am_hal_pdm.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/am_hal_pin.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/am_hal_pwrctrl.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/am_hal_queue.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/am_hal_security.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/am_hal_stimer.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/am_hal_timer.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/am_hal_usb.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/am_hal_wdt.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/mcu/am_hal_bootrom_helper.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/mcu/am_hal_cachectrl.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/mcu/am_hal_card.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/mcu/am_hal_card_host.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/mcu/am_hal_clkgen.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/mcu/am_hal_cmdq.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/mcu/am_hal_dsi.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/mcu/am_hal_fault.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/mcu/am_hal_interrupt.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/mcu/am_hal_iom.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/mcu/am_hal_ios.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/mcu/am_hal_itm.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/mcu/am_hal_itm.h",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/mcu/am_hal_mcuctrl.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/mcu/am_hal_mpu.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/mcu/am_hal_mram.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/mcu/am_hal_mspi.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/mcu/am_hal_reset.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/mcu/am_hal_rtc.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/mcu/am_hal_sdhc.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/mcu/am_hal_secure_ota.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/mcu/am_hal_sysctrl.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/mcu/am_hal_systick.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/mcu/am_hal_tpiu.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/mcu/am_hal_uart.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4p/hal/mcu/am_hal_utils.c",
+    ]
+  }
+
+  pw_source_set("apollo4b") {
+    remove_configs = [ "$dir_pw_build:extra_strict_warnings" ]
+
+    public_configs = [
+      ":disable_warnings",
+      ":apollo4_include_dirs",
+      ":apollo4b_include_dirs",
+      ":apollo4b_sdk_defines",
+    ]
+
+    sources = [
+      "$dir_pw_third_party_ambiq_SDK/boards/apollo4b_evb/bsp/am_bsp.c",
+      "$dir_pw_third_party_ambiq_SDK/boards/apollo4b_evb/bsp/am_bsp_pins.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/am_hal_access.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/am_hal_adc.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/am_hal_audadc.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/am_hal_dcu.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/am_hal_global.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/am_hal_gpio.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/am_hal_i2s.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/am_hal_otp.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/am_hal_pdm.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/am_hal_pin.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/am_hal_pwrctrl.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/am_hal_queue.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/am_hal_security.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/am_hal_stimer.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/am_hal_timer.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/am_hal_usb.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/am_hal_wdt.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/mcu/am_hal_bootrom_helper.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/mcu/am_hal_cachectrl.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/mcu/am_hal_card.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/mcu/am_hal_card_host.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/mcu/am_hal_clkgen.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/mcu/am_hal_cmdq.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/mcu/am_hal_dsi.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/mcu/am_hal_fault.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/mcu/am_hal_interrupt.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/mcu/am_hal_iom.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/mcu/am_hal_ios.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/mcu/am_hal_itm.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/mcu/am_hal_itm.h",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/mcu/am_hal_mcuctrl.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/mcu/am_hal_mpu.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/mcu/am_hal_mram.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/mcu/am_hal_mspi.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/mcu/am_hal_reset.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/mcu/am_hal_rtc.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/mcu/am_hal_sdhc.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/mcu/am_hal_secure_ota.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/mcu/am_hal_sysctrl.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/mcu/am_hal_systick.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/mcu/am_hal_tpiu.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/mcu/am_hal_uart.c",
+      "$dir_pw_third_party_ambiq_SDK/mcu/apollo4b/hal/mcu/am_hal_utils.c",
+    ]
+  }
+
+  pw_source_set("sdk") {
+    if (pw_third_party_ambiq_PRODUCT == "apollo4p") {
+      public_deps = [ ":apollo4p" ]
+    } else if (pw_third_party_ambiq_PRODUCT == "apollo4b") {
+      public_deps = [ ":apollo4b" ]
+    }
+  }
+}
diff --git a/third_party/ambiq/ambiq.gni b/third_party/ambiq/ambiq.gni
new file mode 100644
index 0000000..c0db57e
--- /dev/null
+++ b/third_party/ambiq/ambiq.gni
@@ -0,0 +1,24 @@
+# Copyright 2023 The Pigweed Authors
+#
+# Licensed 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
+#
+#     https://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.
+import("//build_overrides/pigweed.gni")
+
+declare_args() {
+  # If compiling a project against an Ambiq Apollo SDK, this variable is set to the path to the
+  # Ambiq Suite SDK directory.
+  dir_pw_third_party_ambiq_SDK = ""
+
+  # The Product specified in as much detail as possible.
+  # i.e. "apollo4p", "apollo4b", etc.
+  pw_third_party_ambiq_PRODUCT = ""
+}