uboot/arch/arm/mach-apple/board.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * (C) Copyright 2021 Mark Kettenis <kettenis@openbsd.org>
   4 */
   5
   6#include <common.h>
   7#include <dm.h>
   8#include <dm/uclass-internal.h>
   9#include <efi_loader.h>
  10#include <lmb.h>
  11
  12#include <asm/armv8/mmu.h>
  13#include <asm/global_data.h>
  14#include <asm/io.h>
  15#include <asm/system.h>
  16
  17DECLARE_GLOBAL_DATA_PTR;
  18
  19/* Apple M1/M2 */
  20
  21static struct mm_region t8103_mem_map[] = {
  22        {
  23                /* I/O */
  24                .virt = 0x200000000,
  25                .phys = 0x200000000,
  26                .size = 2UL * SZ_1G,
  27                .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
  28                         PTE_BLOCK_NON_SHARE |
  29                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
  30        }, {
  31                /* I/O */
  32                .virt = 0x380000000,
  33                .phys = 0x380000000,
  34                .size = SZ_1G,
  35                .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
  36                         PTE_BLOCK_NON_SHARE |
  37                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
  38        }, {
  39                /* I/O */
  40                .virt = 0x500000000,
  41                .phys = 0x500000000,
  42                .size = SZ_1G,
  43                .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
  44                         PTE_BLOCK_NON_SHARE |
  45                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
  46        }, {
  47                /* I/O */
  48                .virt = 0x680000000,
  49                .phys = 0x680000000,
  50                .size = SZ_512M,
  51                .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
  52                         PTE_BLOCK_NON_SHARE |
  53                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
  54        }, {
  55                /* PCIE */
  56                .virt = 0x6a0000000,
  57                .phys = 0x6a0000000,
  58                .size = SZ_512M,
  59                .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRE) |
  60                         PTE_BLOCK_INNER_SHARE |
  61                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
  62        }, {
  63                /* PCIE */
  64                .virt = 0x6c0000000,
  65                .phys = 0x6c0000000,
  66                .size = SZ_1G,
  67                .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRE) |
  68                         PTE_BLOCK_INNER_SHARE |
  69                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
  70        }, {
  71                /* RAM */
  72                .virt = 0x800000000,
  73                .phys = 0x800000000,
  74                .size = 8UL * SZ_1G,
  75                .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
  76                         PTE_BLOCK_INNER_SHARE
  77        }, {
  78                /* Framebuffer */
  79                .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL_NC) |
  80                         PTE_BLOCK_INNER_SHARE |
  81                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
  82        }, {
  83                /* List terminator */
  84                0,
  85        }
  86};
  87
  88/* Apple M1 Pro/Max */
  89
  90static struct mm_region t6000_mem_map[] = {
  91        {
  92                /* I/O */
  93                .virt = 0x280000000,
  94                .phys = 0x280000000,
  95                .size = SZ_1G,
  96                .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
  97                         PTE_BLOCK_NON_SHARE |
  98                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
  99        }, {
 100                /* I/O */
 101                .virt = 0x380000000,
 102                .phys = 0x380000000,
 103                .size = SZ_1G,
 104                .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 105                         PTE_BLOCK_NON_SHARE |
 106                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
 107        }, {
 108                /* I/O */
 109                .virt = 0x580000000,
 110                .phys = 0x580000000,
 111                .size = SZ_512M,
 112                .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 113                         PTE_BLOCK_NON_SHARE |
 114                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
 115        }, {
 116                /* PCIE */
 117                .virt = 0x5a0000000,
 118                .phys = 0x5a0000000,
 119                .size = SZ_512M,
 120                .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRE) |
 121                         PTE_BLOCK_INNER_SHARE |
 122                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
 123        }, {
 124                /* PCIE */
 125                .virt = 0x5c0000000,
 126                .phys = 0x5c0000000,
 127                .size = SZ_1G,
 128                .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRE) |
 129                         PTE_BLOCK_INNER_SHARE |
 130                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
 131        }, {
 132                /* I/O */
 133                .virt = 0x700000000,
 134                .phys = 0x700000000,
 135                .size = SZ_1G,
 136                .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 137                         PTE_BLOCK_NON_SHARE |
 138                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
 139        }, {
 140                /* I/O */
 141                .virt = 0xb00000000,
 142                .phys = 0xb00000000,
 143                .size = SZ_1G,
 144                .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 145                         PTE_BLOCK_NON_SHARE |
 146                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
 147        }, {
 148                /* I/O */
 149                .virt = 0xf00000000,
 150                .phys = 0xf00000000,
 151                .size = SZ_1G,
 152                .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 153                         PTE_BLOCK_NON_SHARE |
 154                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
 155        }, {
 156                /* I/O */
 157                .virt = 0x1300000000,
 158                .phys = 0x1300000000,
 159                .size = SZ_1G,
 160                .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 161                         PTE_BLOCK_NON_SHARE |
 162                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
 163        }, {
 164                /* RAM */
 165                .virt = 0x10000000000,
 166                .phys = 0x10000000000,
 167                .size = 16UL * SZ_1G,
 168                .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
 169                         PTE_BLOCK_INNER_SHARE
 170        }, {
 171                /* Framebuffer */
 172                .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL_NC) |
 173                         PTE_BLOCK_INNER_SHARE |
 174                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
 175        }, {
 176                /* List terminator */
 177                0,
 178        }
 179};
 180
 181/* Apple M1 Ultra */
 182
 183static struct mm_region t6002_mem_map[] = {
 184        {
 185                /* I/O */
 186                .virt = 0x280000000,
 187                .phys = 0x280000000,
 188                .size = SZ_1G,
 189                .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 190                         PTE_BLOCK_NON_SHARE |
 191                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
 192        }, {
 193                /* I/O */
 194                .virt = 0x380000000,
 195                .phys = 0x380000000,
 196                .size = SZ_1G,
 197                .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 198                         PTE_BLOCK_NON_SHARE |
 199                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
 200        }, {
 201                /* I/O */
 202                .virt = 0x580000000,
 203                .phys = 0x580000000,
 204                .size = SZ_512M,
 205                .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 206                         PTE_BLOCK_NON_SHARE |
 207                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
 208        }, {
 209                /* PCIE */
 210                .virt = 0x5a0000000,
 211                .phys = 0x5a0000000,
 212                .size = SZ_512M,
 213                .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRE) |
 214                         PTE_BLOCK_INNER_SHARE |
 215                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
 216        }, {
 217                /* PCIE */
 218                .virt = 0x5c0000000,
 219                .phys = 0x5c0000000,
 220                .size = SZ_1G,
 221                .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRE) |
 222                         PTE_BLOCK_INNER_SHARE |
 223                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
 224        }, {
 225                /* I/O */
 226                .virt = 0x700000000,
 227                .phys = 0x700000000,
 228                .size = SZ_1G,
 229                .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 230                         PTE_BLOCK_NON_SHARE |
 231                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
 232        }, {
 233                /* I/O */
 234                .virt = 0xb00000000,
 235                .phys = 0xb00000000,
 236                .size = SZ_1G,
 237                .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 238                         PTE_BLOCK_NON_SHARE |
 239                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
 240        }, {
 241                /* I/O */
 242                .virt = 0xf00000000,
 243                .phys = 0xf00000000,
 244                .size = SZ_1G,
 245                .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 246                         PTE_BLOCK_NON_SHARE |
 247                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
 248        }, {
 249                /* I/O */
 250                .virt = 0x1300000000,
 251                .phys = 0x1300000000,
 252                .size = SZ_1G,
 253                .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 254                         PTE_BLOCK_NON_SHARE |
 255                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
 256        }, {
 257                /* I/O */
 258                .virt = 0x2280000000,
 259                .phys = 0x2280000000,
 260                .size = SZ_1G,
 261                .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 262                         PTE_BLOCK_NON_SHARE |
 263                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
 264        }, {
 265                /* I/O */
 266                .virt = 0x2380000000,
 267                .phys = 0x2380000000,
 268                .size = SZ_1G,
 269                .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 270                         PTE_BLOCK_NON_SHARE |
 271                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
 272        }, {
 273                /* I/O */
 274                .virt = 0x2580000000,
 275                .phys = 0x2580000000,
 276                .size = SZ_512M,
 277                .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 278                         PTE_BLOCK_NON_SHARE |
 279                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
 280        }, {
 281                /* PCIE */
 282                .virt = 0x25a0000000,
 283                .phys = 0x25a0000000,
 284                .size = SZ_512M,
 285                .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRE) |
 286                         PTE_BLOCK_INNER_SHARE |
 287                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
 288        }, {
 289                /* PCIE */
 290                .virt = 0x25c0000000,
 291                .phys = 0x25c0000000,
 292                .size = SZ_1G,
 293                .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRE) |
 294                         PTE_BLOCK_INNER_SHARE |
 295                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
 296        }, {
 297                /* I/O */
 298                .virt = 0x2700000000,
 299                .phys = 0x2700000000,
 300                .size = SZ_1G,
 301                .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 302                         PTE_BLOCK_NON_SHARE |
 303                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
 304        }, {
 305                /* I/O */
 306                .virt = 0x2b00000000,
 307                .phys = 0x2b00000000,
 308                .size = SZ_1G,
 309                .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 310                         PTE_BLOCK_NON_SHARE |
 311                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
 312        }, {
 313                /* I/O */
 314                .virt = 0x2f00000000,
 315                .phys = 0x2f00000000,
 316                .size = SZ_1G,
 317                .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 318                         PTE_BLOCK_NON_SHARE |
 319                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
 320        }, {
 321                /* I/O */
 322                .virt = 0x3300000000,
 323                .phys = 0x3300000000,
 324                .size = SZ_1G,
 325                .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 326                         PTE_BLOCK_NON_SHARE |
 327                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
 328        }, {
 329                /* RAM */
 330                .virt = 0x10000000000,
 331                .phys = 0x10000000000,
 332                .size = 16UL * SZ_1G,
 333                .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
 334                         PTE_BLOCK_INNER_SHARE
 335        }, {
 336                /* Framebuffer */
 337                .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL_NC) |
 338                         PTE_BLOCK_INNER_SHARE |
 339                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
 340        }, {
 341                /* List terminator */
 342                0,
 343        }
 344};
 345
 346struct mm_region *mem_map;
 347
 348int board_init(void)
 349{
 350        return 0;
 351}
 352
 353int dram_init(void)
 354{
 355        return fdtdec_setup_mem_size_base();
 356}
 357
 358int dram_init_banksize(void)
 359{
 360        return fdtdec_setup_memory_banksize();
 361}
 362
 363extern long fw_dtb_pointer;
 364
 365void *board_fdt_blob_setup(int *err)
 366{
 367        /* Return DTB pointer passed by m1n1 */
 368        *err = 0;
 369        return (void *)fw_dtb_pointer;
 370}
 371
 372void build_mem_map(void)
 373{
 374        ofnode node;
 375        fdt_addr_t base;
 376        fdt_size_t size;
 377        int i;
 378
 379        if (of_machine_is_compatible("apple,t8103") ||
 380            of_machine_is_compatible("apple,t8112"))
 381                mem_map = t8103_mem_map;
 382        else if (of_machine_is_compatible("apple,t6000"))
 383                mem_map = t6000_mem_map;
 384        else if (of_machine_is_compatible("apple,t6001"))
 385                mem_map = t6000_mem_map;
 386        else if (of_machine_is_compatible("apple,t6002"))
 387                mem_map = t6002_mem_map;
 388        else
 389                panic("Unsupported SoC\n");
 390
 391        /* Find list terminator. */
 392        for (i = 0; mem_map[i].size || mem_map[i].attrs; i++)
 393                ;
 394
 395        /* Align RAM mapping to page boundaries */
 396        base = gd->bd->bi_dram[0].start;
 397        size = gd->bd->bi_dram[0].size;
 398        size += (base - ALIGN_DOWN(base, SZ_4K));
 399        base = ALIGN_DOWN(base, SZ_4K);
 400        size = ALIGN(size, SZ_4K);
 401
 402        /* Update RAM mapping */
 403        mem_map[i - 2].virt = base;
 404        mem_map[i - 2].phys = base;
 405        mem_map[i - 2].size = size;
 406
 407        node = ofnode_path("/chosen/framebuffer");
 408        if (!ofnode_valid(node))
 409                return;
 410
 411        base = ofnode_get_addr_size(node, "reg", &size);
 412        if (base == FDT_ADDR_T_NONE)
 413                return;
 414
 415        /* Align framebuffer mapping to page boundaries */
 416        size += (base - ALIGN_DOWN(base, SZ_4K));
 417        base = ALIGN_DOWN(base, SZ_4K);
 418        size = ALIGN(size, SZ_4K);
 419
 420        /* Add framebuffer mapping */
 421        mem_map[i - 1].virt = base;
 422        mem_map[i - 1].phys = base;
 423        mem_map[i - 1].size = size;
 424}
 425
 426void enable_caches(void)
 427{
 428        build_mem_map();
 429
 430        icache_enable();
 431        dcache_enable();
 432}
 433
 434u64 get_page_table_size(void)
 435{
 436        return SZ_256K;
 437}
 438
 439#define KERNEL_COMP_SIZE        SZ_128M
 440
 441int board_late_init(void)
 442{
 443        struct lmb lmb;
 444        u32 status = 0;
 445
 446        lmb_init_and_reserve(&lmb, gd->bd, (void *)gd->fdt_blob);
 447
 448        /* somewhat based on the Linux Kernel boot requirements:
 449         * align by 2M and maximal FDT size 2M
 450         */
 451        status |= env_set_hex("loadaddr", lmb_alloc(&lmb, SZ_1G, SZ_2M));
 452        status |= env_set_hex("fdt_addr_r", lmb_alloc(&lmb, SZ_2M, SZ_2M));
 453        status |= env_set_hex("kernel_addr_r", lmb_alloc(&lmb, SZ_128M, SZ_2M));
 454        status |= env_set_hex("ramdisk_addr_r", lmb_alloc(&lmb, SZ_1G, SZ_2M));
 455        status |= env_set_hex("kernel_comp_addr_r",
 456                              lmb_alloc(&lmb, KERNEL_COMP_SIZE, SZ_2M));
 457        status |= env_set_hex("kernel_comp_size", KERNEL_COMP_SIZE);
 458        status |= env_set_hex("scriptaddr", lmb_alloc(&lmb, SZ_4M, SZ_2M));
 459        status |= env_set_hex("pxefile_addr_r", lmb_alloc(&lmb, SZ_4M, SZ_2M));
 460
 461        if (status)
 462                log_warning("late_init: Failed to set run time variables\n");
 463
 464        return 0;
 465}
 466
 467int ft_board_setup(void *blob, struct bd_info *bd)
 468{
 469        struct udevice *dev;
 470        const char *stdoutname;
 471        int node, ret;
 472
 473        /*
 474         * Modify the "stdout-path" property under "/chosen" to point
 475         * at "/chosen/framebuffer if a keyboard is available and
 476         * we're not running under the m1n1 hypervisor.
 477         * Developers can override this behaviour by dropping
 478         * "vidconsole" from the "stdout" environment variable.
 479         */
 480
 481        /* EL1 means we're running under the m1n1 hypervisor. */
 482        if (current_el() == 1)
 483                return 0;
 484
 485        ret = uclass_find_device(UCLASS_KEYBOARD, 0, &dev);
 486        if (ret < 0)
 487                return 0;
 488
 489        stdoutname = env_get("stdout");
 490        if (!stdoutname || !strstr(stdoutname, "vidconsole"))
 491                return 0;
 492
 493        /* Make sure we actually have a framebuffer. */
 494        node = fdt_path_offset(blob, "/chosen/framebuffer");
 495        if (node < 0 || !fdtdec_get_is_enabled(blob, node))
 496                return 0;
 497
 498        node = fdt_path_offset(blob, "/chosen");
 499        if (node < 0)
 500                return 0;
 501        fdt_setprop_string(blob, node, "stdout-path", "/chosen/framebuffer");
 502
 503        return 0;
 504}
 505