summaryrefslogtreecommitdiff
path: root/tools/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/src/main.c')
-rw-r--r--tools/src/main.c205
1 files changed, 205 insertions, 0 deletions
diff --git a/tools/src/main.c b/tools/src/main.c
new file mode 100644
index 0000000..8d69e03
--- /dev/null
+++ b/tools/src/main.c
@@ -0,0 +1,205 @@
+/* SPDX-License-Identifier: MIT */
+
+#include "../build/build_cfg.h"
+#include "../build/build_tag.h"
+
+#include "../config.h"
+
+#include "adt.h"
+#include "aic.h"
+#include "clk.h"
+#include "cpufreq.h"
+#include "display.h"
+#include "exception.h"
+#include "fb.h"
+#include "firmware.h"
+#include "gxf.h"
+#include "heapblock.h"
+#include "mcc.h"
+#include "memory.h"
+#include "nvme.h"
+#include "payload.h"
+#include "pcie.h"
+#include "pmgr.h"
+#include "sep.h"
+#include "smp.h"
+#include "string.h"
+#include "tunables.h"
+#include "uart.h"
+#include "uartproxy.h"
+#include "usb.h"
+#include "utils.h"
+#include "wdt.h"
+#include "xnuboot.h"
+
+struct vector_args next_stage;
+
+const char version_tag[] = "##m1n1_ver##" BUILD_TAG;
+const char *const m1n1_version = version_tag + 12;
+
+u32 board_id = ~0, chip_id = ~0;
+
+void get_device_info(void)
+{
+ printf("Device info:\n");
+ printf(" Model: %s\n", (const char *)adt_getprop(adt, 0, "model", NULL));
+ printf(" Target: %s\n", (const char *)adt_getprop(adt, 0, "target-type", NULL));
+
+ int chosen = adt_path_offset(adt, "/chosen");
+ if (chosen > 0) {
+ if (ADT_GETPROP(adt, chosen, "board-id", &board_id) < 0)
+ printf("Failed to find board-id\n");
+ if (ADT_GETPROP(adt, chosen, "chip-id", &chip_id) < 0)
+ printf("Failed to find chip-id\n");
+
+ printf(" Board-ID: 0x%x\n", board_id);
+ printf(" Chip-ID: 0x%x\n", chip_id);
+ } else {
+ printf("No chosen node!\n");
+ }
+
+ printf("\n");
+}
+
+void run_actions(void)
+{
+ bool usb_up = false;
+
+#ifndef BRINGUP
+#ifdef EARLY_PROXY_TIMEOUT
+ int node = adt_path_offset(adt, "/chosen/asmb");
+ u64 lp_sip0 = 0;
+
+ if (node >= 0) {
+ ADT_GETPROP(adt, node, "lp-sip0", &lp_sip0);
+ printf("Boot policy: sip0 = %ld\n", lp_sip0);
+ }
+
+ if (!cur_boot_args.video.display && lp_sip0 == 127) {
+ printf("Bringing up USB for early debug...\n");
+
+ usb_init();
+ usb_iodev_init();
+
+ usb_up = true;
+
+ printf("Waiting for proxy connection... ");
+ for (int i = 0; i < EARLY_PROXY_TIMEOUT * 100; i++) {
+ for (int j = 0; j < USB_IODEV_COUNT; j++) {
+ iodev_id_t iodev = IODEV_USB0 + j;
+
+ if (!(iodev_get_usage(iodev) & USAGE_UARTPROXY))
+ continue;
+
+ usb_iodev_vuart_setup(iodev);
+ iodev_handle_events(iodev);
+ if (iodev_can_write(iodev) || iodev_can_write(IODEV_USB_VUART)) {
+ printf(" Connected!\n");
+ uartproxy_run(NULL);
+ return;
+ }
+ }
+
+ mdelay(10);
+ if (i % 100 == 99)
+ printf(".");
+ }
+ printf(" Timed out\n");
+ }
+#endif
+#endif
+
+ printf("Checking for payloads...\n");
+
+ if (payload_run() == 0) {
+ printf("Valid payload found\n");
+ return;
+ }
+
+ fb_set_active(true);
+
+ printf("No valid payload found\n");
+
+#ifndef BRINGUP
+ if (!usb_up) {
+ usb_init();
+ usb_iodev_init();
+ }
+#endif
+
+ printf("Running proxy...\n");
+
+ uartproxy_run(NULL);
+}
+
+void m1n1_main(void)
+{
+ printf("\n\nm1n1 %s\n", m1n1_version);
+ printf("Copyright The Asahi Linux Contributors\n");
+ printf("Licensed under the MIT license\n\n");
+
+ printf("Running in EL%lu\n\n", mrs(CurrentEL) >> 2);
+
+ get_device_info();
+ firmware_init();
+
+ heapblock_init();
+
+#ifndef BRINGUP
+ gxf_init();
+ mcc_init();
+ mmu_init();
+ aic_init();
+#endif
+ wdt_disable();
+#ifndef BRINGUP
+ pmgr_init();
+ tunables_apply_static();
+
+#ifdef USE_FB
+ display_init();
+ // Kick DCP to sleep, so dodgy monitors which cause reconnect cycles don't cause us to lose the
+ // framebuffer.
+ display_shutdown(DCP_SLEEP_IF_EXTERNAL);
+ fb_init(false);
+ fb_display_logo();
+#ifdef FB_SILENT_MODE
+ fb_set_active(!cur_boot_args.video.display);
+#else
+ fb_set_active(true);
+#endif
+#endif
+
+ clk_init();
+ cpufreq_init();
+ sep_init();
+#endif
+
+ printf("Initialization complete.\n");
+
+ run_actions();
+
+ if (!next_stage.entry) {
+ panic("Nothing to do!\n");
+ }
+
+ printf("Preparing to run next stage at %p...\n", next_stage.entry);
+
+ nvme_shutdown();
+ exception_shutdown();
+#ifndef BRINGUP
+ usb_iodev_shutdown();
+ display_shutdown(DCP_SLEEP_IF_EXTERNAL);
+#ifdef USE_FB
+ fb_shutdown(next_stage.restore_logo);
+#endif
+ mmu_shutdown();
+#endif
+
+ printf("Vectoring to next stage...\n");
+
+ next_stage.entry(next_stage.args[0], next_stage.args[1], next_stage.args[2], next_stage.args[3],
+ next_stage.args[4]);
+
+ panic("Next stage returned!\n");
+}