// Copyright 2021 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_LEVEL PW_CPU_EXCEPTION_CORTEX_M_LOG_LEVEL

#include "pw_cpu_exception_cortex_m/snapshot.h"

#include "pw_cpu_exception/support.h"
#include "pw_cpu_exception_cortex_m/proto_dump.h"
#include "pw_cpu_exception_cortex_m_private/config.h"
#include "pw_cpu_exception_cortex_m_private/cortex_m_constants.h"
#include "pw_cpu_exception_cortex_m_protos/cpu_state.pwpb.h"
#include "pw_log/log.h"
#include "pw_protobuf/encoder.h"
#include "pw_status/status.h"
#include "pw_thread/snapshot.h"
#include "pw_thread_protos/thread.pwpb.h"

namespace pw::cpu_exception::cortex_m {
namespace {

constexpr char kMainStackHandlerModeName[] = "Main Stack (Handler Mode)";
constexpr char kMainStackThreadModeName[] = "Main Stack (Thread Mode)";

enum class ProcessorMode {
  kHandlerMode,
  kThreadMode,
};

Status CaptureMainStack(
    ProcessorMode mode,
    uintptr_t stack_low_addr,
    uintptr_t stack_high_addr,
    uintptr_t stack_pointer,
    thread::SnapshotThreadInfo::StreamEncoder& snapshot_encoder,
    thread::ProcessThreadStackCallback& thread_stack_callback) {
  thread::Thread::StreamEncoder encoder = snapshot_encoder.GetThreadsEncoder();

  const char* thread_name;
  thread::ThreadState::Enum thread_state;
  if (mode == ProcessorMode::kHandlerMode) {
    thread_name = kMainStackHandlerModeName;
    PW_LOG_DEBUG("Capturing thread info for Main Stack (Handler Mode)");
    thread_state = thread::ThreadState::Enum::INTERRUPT_HANDLER;
    PW_LOG_DEBUG("Thread state: INTERRUPT_HANDLER");
  } else {  // mode == ProcessorMode::kThreadMode
    thread_name = kMainStackHandlerModeName;
    PW_LOG_DEBUG("Capturing thread info for Main Stack (Thread Mode)");
    thread_state = thread::ThreadState::Enum::RUNNING;
    PW_LOG_DEBUG("Thread state: RUNNING");
  }
  encoder.WriteState(thread_state);
  encoder.WriteName(std::as_bytes(std::span(std::string_view(thread_name))));

  const thread::StackContext thread_ctx = {
      .thread_name = thread_name,
      .stack_low_addr = stack_low_addr,
      .stack_high_addr = stack_high_addr,
      .stack_pointer = stack_pointer,
      .stack_pointer_est_peak = std::nullopt,
  };
  return thread::SnapshotStack(thread_ctx, encoder, thread_stack_callback);
}

}  // namespace

Status SnapshotCpuState(
    const pw_cpu_exception_State& cpu_state,
    SnapshotCpuStateOverlay::StreamEncoder& snapshot_encoder) {
  LogCpuState(cpu_state);
  {
    ArmV7mCpuState::StreamEncoder cpu_state_encoder =
        snapshot_encoder.GetArmv7mCpuStateEncoder();
    DumpCpuStateProto(cpu_state_encoder, cpu_state);
  }
  return snapshot_encoder.status();
}

Status SnapshotMainStackThread(
    uintptr_t stack_low_addr,
    uintptr_t stack_high_addr,
    thread::SnapshotThreadInfo::StreamEncoder& encoder,
    thread::ProcessThreadStackCallback& thread_stack_callback) {
  uintptr_t stack_pointer;
  asm volatile("mrs %0, msp\n" : "=r"(stack_pointer));

  // First check if we're in Handler mode, AKA handling exceptions/interrupts.
  //
  // Handler mode vs thread mode can be determined via IPSR, bits 8:0 of xPSR.
  // In thread mode the value is 0, in handler mode the value is non-zero.
  uint32_t xpsr;
  asm volatile("mrs %0, xpsr\n" : "=r"(xpsr));
  if ((xpsr & kXpsrIpsrMask) != 0) {
    return CaptureMainStack(ProcessorMode::kHandlerMode,
                            stack_low_addr,
                            stack_high_addr,
                            stack_pointer,
                            encoder,
                            thread_stack_callback);
  }

  // It looks like we're in Thread mode which means we need to check whether
  // or not we are executing off the main stack currently.
  //
  // See ARMv7-M Architecture Reference Manual Section B1.4.4 for the control
  // register values, in particular the SPSEL bit while in Thread mode which
  // is 0 while running off the main stack and 1 while running off the proces
  // stack.
  uint32_t control;
  asm volatile("mrs %0, control\n" : "=r"(control));
  if ((control & kControlThreadModeStackMask) != 0) {
    return OkStatus();  // Main stack is not currently active.
  }

  // We're running off the main stack in Thread mode.
  return CaptureMainStack(ProcessorMode::kThreadMode,
                          stack_low_addr,
                          stack_high_addr,
                          stack_pointer,
                          encoder,
                          thread_stack_callback);
}

Status SnapshotMainStackThread(
    const pw_cpu_exception_State& cpu_state,
    uintptr_t stack_low_addr,
    uintptr_t stack_high_addr,
    thread::SnapshotThreadInfo::StreamEncoder& encoder,
    thread::ProcessThreadStackCallback& thread_stack_callback) {
  const uint32_t exc_return = cpu_state.extended.exc_return;

  // See ARMv7-M Architecture Reference Manual Section B1.5.8 for the exception
  // return values, in particular bits 0:3.
  // Bits 0:3 of EXC_RETURN:
  // 0b0001 - 0x1 Handler mode Main
  // 0b1001 - 0x9 Thread mode Main
  // 0b1101 - 0xD Thread mode Process

  // First check whether the CPU state shows the main stack was active.
  if ((exc_return & kExcReturnStackMask) != 0) {
    return OkStatus();  // Main stack is not currently active.
  }
  const uintptr_t stack_pointer = cpu_state.extended.msp;

  // Second, check if we're in Handler mode, AKA handling exceptions/interrupts.
  const ProcessorMode mode = ((exc_return & kExcReturnModeMask) == 0)
                                 ? ProcessorMode::kHandlerMode
                                 : ProcessorMode::kThreadMode;

  return CaptureMainStack(mode,
                          stack_low_addr,
                          stack_high_addr,
                          stack_pointer,
                          encoder,
                          thread_stack_callback);
}

}  // namespace pw::cpu_exception::cortex_m
