1/*
2 * Copyright (c) 2011-2014, Wind River Systems, Inc.
3 * Copyright (c) 2019-2020 Intel Corp.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8/**
9 * @file Directives for linker MEMORY regions for all x86
10 *
11 * By default, the kernel is linked at its physical address and all addresses
12 * are in RAM.
13 *
14 * If CONFIG_XIP is enabled, then another MEMORY region is declared for ROM,
15 * and this is where the Zephyr image is booted from. The linker LMAs and VMAs
16 * are set up, such that read/write data/bss have their VMA addresses
17 * in RAM and are copied from flash at boot. Text/rodata linked in-place in
18 * flash.
19 *
20 * If CONFIG_MMU is enabled, then the ROM region in MEMORY is used to set the
21 * LMA for all sections relative to physical address. The virtual address VMAs
22 * for all sections are relative to the base virtual address for the kernel.
23 * Setting LMAs here helps let QEMU or any other ELF-aware loader know where to
24 * physically load the image.
25 */
26
27#ifndef ARCH_X86_MEMORY_LD
28#define ARCH_X86_MEMORY_LD
29
30#include <zephyr/devicetree.h>
31#include <zephyr/linker/devicetree_regions.h>
32#include <zephyr/kernel/mm.h>
33
34/* Bounds of physical RAM from DTS */
35#define PHYS_RAM_ADDR		DT_REG_ADDR(DT_CHOSEN(zephyr_sram))
36#define PHYS_RAM_SIZE		DT_REG_SIZE(DT_CHOSEN(zephyr_sram))
37
38/* Virtual base address for the kernel; with CONFIG_MMU this is not necessarily
39 * the same as its physical location, although an identity mapping for RAM
40 * is still supported by setting CONFIG_KERNEL_VM_BASE=CONFIG_SRAM_BASE_ADDRESS.
41 */
42#ifdef K_MEM_IS_VM_KERNEL
43#define KERNEL_BASE_ADDR  (CONFIG_KERNEL_VM_BASE + CONFIG_KERNEL_VM_OFFSET)
44#define KERNEL_RAM_SIZE   (CONFIG_KERNEL_VM_SIZE - CONFIG_KERNEL_VM_OFFSET)
45#define PHYS_RAM_AVAIL    (PHYS_RAM_SIZE - CONFIG_SRAM_OFFSET)
46#else
47#define KERNEL_BASE_ADDR  (PHYS_RAM_ADDR + CONFIG_SRAM_OFFSET)
48#define KERNEL_RAM_SIZE   (PHYS_RAM_SIZE - CONFIG_SRAM_OFFSET)
49#endif
50
51/* "kernel RAM" for linker VMA allocations starts at the offset */
52
53#if defined(CONFIG_ROM_END_OFFSET)
54#define ROM_END_OFFSET CONFIG_ROM_END_OFFSET
55#else
56#define ROM_END_OFFSET 0
57#endif
58
59#ifdef CONFIG_XIP
60  /* "ROM" is flash, we leave rodata and text there and just copy in data.
61   * Board-level DTS must specify a flash region that doesn't overlap with
62   * sram0, so that DT_PHYS_LOAD_ADDR is set.
63   */
64  #define FLASH_ROM_SIZE      (DT_REG_SIZE(DT_CHOSEN(zephyr_flash)) - ROM_END_OFFSET)
65  #define PHYS_LOAD_ADDR      DT_REG_ADDR(DT_CHOSEN(zephyr_flash))
66#else
67  /* Physical RAM location where the kernel image is loaded */
68  #define PHYS_LOAD_ADDR      (PHYS_RAM_ADDR + CONFIG_SRAM_OFFSET)
69#endif /* CONFIG_XIP */
70
71#ifdef CONFIG_X86_64
72/* Locore must be addressable by real mode and so cannot extend past 64K.
73 * Skip reserved stuff in the first page
74 */
75#define LOCORE_BASE         0x1000
76#define LOCORE_SIZE         (0x10000 - LOCORE_BASE)
77
78#if PHYS_RAM_ADDR != CONFIG_KERNEL_VM_BASE
79#error Virtual kernel linking is not yet implemented for 64-bit
80#endif
81#endif /* CONFIG_X86_64 */
82
83MEMORY
84    {
85#if defined(CONFIG_XIP)
86    /* Address range where the kernel will be installed on a flash part (XIP),
87     * or copied into physical RAM by a loader (MMU)
88     */
89    ROM (rx)        : ORIGIN = PHYS_LOAD_ADDR, LENGTH = FLASH_ROM_SIZE
90#elif defined(K_MEM_IS_VM_KERNEL)
91    ROM (rx)        : ORIGIN = PHYS_LOAD_ADDR, LENGTH = PHYS_RAM_AVAIL
92#endif
93    /* Linear address range to link the kernel. If non-XIP, everything is
94     * linked in this space. Otherwise, rodata and text are linked at their
95     * physical ROM locations
96     */
97    RAM (wx)        : ORIGIN = KERNEL_BASE_ADDR, LENGTH = KERNEL_RAM_SIZE
98    LINKER_DT_REGIONS()
99
100#ifdef CONFIG_X86_64
101    /* Special low-memory area for bootstrapping other CPUs from real mode */
102    LOCORE (wx)     : ORIGIN = LOCORE_BASE, LENGTH = LOCORE_SIZE
103#else
104    /*
105     * On 32-bit x86, fake memory area for build-time IDT generation data.
106     * 64-bit doesn't use this, interrupts are all managed at runtime.
107     *
108     * It doesn't matter where this region goes as it is stripped from the
109     * final ELF image. The address doesn't even have to be valid on the
110     * target. However, it shouldn't overlap any other regions.
111     */
112
113    IDT_LIST        : ORIGIN = 0xFFFF1000, LENGTH = 2K
114#endif /* !CONFIG_X86_64 */
115    }
116#endif /* ARCH_X86_MEMORY_LD */
117