// Copyright 2016 The Fuchsia Authors
// Copyright (c) 2013-2015 Travis Geiselbrecht
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT

/*
 * Main entry point to the OS. Initializes modules in order and creates
 * the default thread.
 */
#include "lk/main.h"

#include <arch.h>
#include <debug.h>
#include <lib/counters.h>
#include <lib/debuglog.h>
#include <lib/heap.h>
#include <platform.h>
#include <string.h>
#include <target.h>
#include <zircon/compiler.h>

#include <kernel/init.h>
#include <kernel/mutex.h>
#include <kernel/percpu.h>
#include <kernel/thread.h>
#include <lk/init.h>
#include <vm/init.h>
#include <vm/vm.h>

extern void (*const __init_array_start[])();
extern void (*const __init_array_end[])();

static uint secondary_idle_thread_count;

static int bootstrap2(void* arg);

KCOUNTER(timeline_threading, "boot.timeline.threading")
KCOUNTER(timeline_init, "boot.timeline.init")

static void call_constructors() {
  for (void (*const* a)() = __init_array_start; a != __init_array_end; a++)
    (*a)();
}

// called from arch code
void lk_main() {
  // serial prints to console based on compile time switch
  dlog_bypass_init_early();

  // get us into some sort of thread context
  thread_init_early();

  // deal with any static constructors
  call_constructors();

  // early arch stuff
  lk_primary_cpu_init_level(LK_INIT_LEVEL_EARLIEST, LK_INIT_LEVEL_ARCH_EARLY - 1);
  arch_early_init();

  // do any super early platform initialization
  lk_primary_cpu_init_level(LK_INIT_LEVEL_ARCH_EARLY, LK_INIT_LEVEL_PLATFORM_EARLY - 1);
  platform_early_init();

  // do any super early target initialization
  lk_primary_cpu_init_level(LK_INIT_LEVEL_PLATFORM_EARLY, LK_INIT_LEVEL_TARGET_EARLY - 1);
  target_early_init();

  dprintf(INFO, "\nwelcome to Zircon\n\n");

  dprintf(INFO, "KASLR: .text section at %p\n", __code_start);

  lk_primary_cpu_init_level(LK_INIT_LEVEL_TARGET_EARLY, LK_INIT_LEVEL_VM_PREHEAP - 1);
  dprintf(SPEW, "initializing vm pre-heap\n");
  vm_init_preheap();

  // bring up the kernel heap
  lk_primary_cpu_init_level(LK_INIT_LEVEL_VM_PREHEAP, LK_INIT_LEVEL_HEAP - 1);
  dprintf(SPEW, "initializing heap\n");
  heap_init();

  lk_primary_cpu_init_level(LK_INIT_LEVEL_HEAP, LK_INIT_LEVEL_VM - 1);
  dprintf(SPEW, "initializing vm\n");
  vm_init();

  // initialize the kernel
  lk_primary_cpu_init_level(LK_INIT_LEVEL_VM, LK_INIT_LEVEL_KERNEL - 1);
  dprintf(SPEW, "initializing kernel\n");
  kernel_init();

  lk_primary_cpu_init_level(LK_INIT_LEVEL_KERNEL, LK_INIT_LEVEL_THREADING - 1);

  // create a thread to complete system initialization
  dprintf(SPEW, "creating bootstrap completion thread\n");
  Thread* t = Thread::Create("bootstrap2", &bootstrap2, NULL, DEFAULT_PRIORITY);
  t->Detach();
  t->Resume();

  // become the idle thread and enable interrupts to start the scheduler
  Thread::Current::BecomeIdle();
}

static int bootstrap2(void*) {
  timeline_threading.Set(current_ticks());

  dprintf(SPEW, "top of bootstrap2()\n");

  lk_primary_cpu_init_level(LK_INIT_LEVEL_THREADING, LK_INIT_LEVEL_ARCH - 1);
  arch_init();

  // initialize the rest of the platform
  dprintf(SPEW, "initializing platform\n");
  lk_primary_cpu_init_level(LK_INIT_LEVEL_ARCH, LK_INIT_LEVEL_PLATFORM - 1);
  platform_init();

  // late CPU initialization, after platform is available
  arch_cpu_late_init();

  // initialize the target
  dprintf(SPEW, "initializing target\n");
  lk_primary_cpu_init_level(LK_INIT_LEVEL_PLATFORM, LK_INIT_LEVEL_TARGET - 1);
  target_init();

  dprintf(SPEW, "moving to last init level\n");
  lk_primary_cpu_init_level(LK_INIT_LEVEL_TARGET, LK_INIT_LEVEL_LAST);

  timeline_init.Set(current_ticks());
  return 0;
}

void lk_secondary_cpu_entry() {
  uint cpu = arch_curr_cpu_num();

  if (cpu > secondary_idle_thread_count) {
    dprintf(CRITICAL,
            "Invalid secondary cpu num %u, SMP_MAX_CPUS %d, secondary_idle_thread_count %u\n", cpu,
            SMP_MAX_CPUS, secondary_idle_thread_count);
    return;
  }

  // late CPU initialization for secondary CPUs
  arch_cpu_late_init();

  // secondary cpu initialize from threading level up. 0 to threading was handled in arch
  lk_init_level(LK_INIT_FLAG_SECONDARY_CPUS, LK_INIT_LEVEL_THREADING, LK_INIT_LEVEL_LAST);

  dprintf(SPEW, "entering scheduler on cpu %u\n", cpu);
  thread_secondary_cpu_entry();
}

void lk_init_secondary_cpus(uint secondary_cpu_count) {
  if (secondary_cpu_count >= SMP_MAX_CPUS) {
    dprintf(CRITICAL, "Invalid secondary_cpu_count %u, SMP_MAX_CPUS %d\n", secondary_cpu_count,
            SMP_MAX_CPUS);
    secondary_cpu_count = SMP_MAX_CPUS - 1;
  }
  for (uint i = 0; i < secondary_cpu_count; i++) {
    Thread* t = Thread::CreateIdleThread(i + 1);
    if (!t) {
      dprintf(CRITICAL, "could not allocate idle thread %u\n", i + 1);
      secondary_idle_thread_count = i;
      break;
    }
  }
  secondary_idle_thread_count = secondary_cpu_count;
}
