/* * main.c - the C entry. console up first, then load the payload and * jump. called from start.S with x0 = whatever the firmware passed. * * the osdev model, arm64: the firmware services do the work, the * kernel goes at a fixed known address, whatever x0 we were handed * goes straight through to the payload. * * Copyright (c) 2026 Bradley Morgan * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include #include #include #define TB_VERSION "0.1" extern int tb_console_init(void); /* * fixed load address, the osdev way. past the bootloader at the * bottom of RAM, the image header decides its final resting place. */ #define TB_LOAD_ADDR 0x40200000 /* the file semihosting serves as the payload */ #define TB_BOOTFILE "Image" extern void __NO_RETURN tb_boot_linux(uintptr_t ep, uintptr_t fw_arg); void tashaboot_main(uintptr_t fw_arg) { struct tb_image img; int ret; if (tb_console_init()) return; dprintf(ALWAYS, "tashaboot " TB_VERSION "\n"); #ifdef TB_ENABLE_MMU { extern int tb_mmu_enable(void); extern int tb_mmu_selftest(void); extern void tb_mmu_disable(void); if (tb_mmu_enable() == 0) { if (tb_mmu_selftest() == 0) dprintf(ALWAYS, "mmu: identity map on\n"); else dprintf(ALWAYS, "mmu: self test failed, " "running unmapped\n"); tb_mmu_disable(); } } #endif ret = tb_load_semihosting(TB_BOOTFILE, TB_LOAD_ADDR, &img); if (ret) { dprintf(ALWAYS, "load failed (%d), halting\n", ret); platform_halt(); } dprintf(ALWAYS, "loaded %llu bytes at %lx, entry %lx\n", (unsigned long long)img.size, img.load, img.ep); dprintf(ALWAYS, "jumping\n"); tb_boot_linux(img.ep, fw_arg); }