diff options
Diffstat (limited to 'tools/src/main.c')
| -rw-r--r-- | tools/src/main.c | 205 |
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"); +} |
