| /* Copyright lowRISC contributors. */ | 
 | /* Licensed under the Apache License, Version 2.0, see LICENSE for details. */ | 
 | /* SPDX-License-Identifier: Apache-2.0 */ | 
 | <%! | 
 | # TODO(#4709): Remove this function, once the old way of defining memories has been deprecated. | 
 | def memory_to_flags(memory): | 
 |     memory_type = memory["type"] | 
 |     memory_access = memory.get("swaccess", "rw") | 
 |     assert memory_access in ["ro", "rw"] | 
 |  | 
 |     flags_str = "" | 
 |     if memory_access == "ro": | 
 |         flags_str += "r" | 
 |     else: | 
 |         flags_str += "rw" | 
 |  | 
 |     if memory_type in ["rom", "eflash"]: | 
 |         flags_str += "x" | 
 |  | 
 |     return flags_str | 
 |  | 
 | def flags(mem): | 
 |     swaccess = mem["swaccess"] | 
 |     exec = mem["exec"] | 
 |     sw_to_flags = { | 
 |         'rw': 'rw', | 
 |         'ro': 'r' | 
 |     } | 
 |     assert swaccess in sw_to_flags | 
 |  | 
 |     flags_str = sw_to_flags[swaccess] | 
 |     if exec: | 
 |         flags_str += "x" | 
 |  | 
 |     return flags_str | 
 |  | 
 | def get_virtual_memory_size(top): | 
 |     for mod in top["module"]: | 
 |         if "memory" in mod: | 
 |             for _, mem in mod["memory"].items(): | 
 |                 if mem["label"] == "eflash": | 
 |                     return hex(int(mem["size"], 0) // 2) | 
 |     return None | 
 | %>\ | 
 |  | 
 | /** | 
 |  * Partial linker script for chip memory configuration. | 
 |  * rom_ext_virtual and owner_virtual are address windows that provide a fixed translation | 
 |  * address for whichever half of the flash contains the corresponding boot stage. | 
 |  */ | 
 | MEMORY { | 
 | % for m in top["module"]: | 
 |   % if "memory" in m: | 
 |     % for key, mem in m["memory"].items(): | 
 |   ${mem["label"]}(${flags(mem)}) : ORIGIN = ${m["base_addrs"][key]}, LENGTH = ${mem["size"]} | 
 |     % endfor | 
 |   % endif | 
 | % endfor | 
 | % for m in top["memory"]: | 
 |   ${m["name"]}(${memory_to_flags(m)}) : ORIGIN = ${m["base_addr"]}, LENGTH = ${m["size"]} | 
 | % endfor | 
 |   rom_ext_virtual(rx) : ORIGIN = 0x90000000, LENGTH = ${get_virtual_memory_size(top)} | 
 |   owner_virtual(rx) : ORIGIN = 0xa0000000, LENGTH = ${get_virtual_memory_size(top)} | 
 | } | 
 |  | 
 | /** | 
 |  * Stack at the top of the main SRAM. | 
 |  */ | 
 | _stack_size = 16384; | 
 | _stack_end = ORIGIN(ram_main) + LENGTH(ram_main); | 
 | _stack_start = _stack_end - _stack_size; | 
 |  | 
 | /** | 
 |  * Size of the `.static_critical` section at the bottom of the main SRAM (in | 
 |  * bytes). | 
 |  */ | 
 | _static_critical_size = 8132; | 
 |  | 
 | /** | 
 |  * `.chip_info` at the top of ROM. | 
 |  */ | 
 | _chip_info_size = 128; | 
 | _chip_info_end   = ORIGIN(rom) + LENGTH(rom); | 
 | _chip_info_start = _chip_info_end - _chip_info_size; | 
 |  | 
 | /** | 
 |  * Size of the initial ePMP RX region at reset (in bytes). This region must be | 
 |  * large enough to cover the .crt section. | 
 |  * | 
 |  * NOTE: This value must match the size of the RX region in | 
 |  * hw/ip/rv_core_ibex/rtl/ibex_pmp_reset.svh. | 
 |  */ | 
 | _epmp_reset_rx_size = 2048; |