it8xxx2: generalize ILM support
Executing code out of RAM on IT8xxx2 requires that the relevant addresses be mapped onto the CPU's instruction memory bus, referred to by ITE documentation as Instruction Local Memory (ILM). ILM mappings configure blocks of RAM to be used for accesses to chosen addresses when performing instruction fetch, instead of the memory that would normally be accessed at that address. ILM must be used for some chip features (particularly Flash self-programming, to execute from RAM while writing to Flash), and has historically been configured in the Flash driver. The RAM for that was hard-coded as a single 4k block in the linker script. Configuring ILM in the flash driver is confusing because it is used by other SoC code as well, currently in code that cannot depend on the Flash being functional or in hand-selected functions that seem performance-critical. This change moves ILM configuration to a new driver and dynamically allocates RAM to ILM in the linker script, allowing software use of the entire 64k RAM depending on configuration. This makes ILM configuration more discoverable and makes it much easier to correctly support the CODE_DATA_RELOCATION feature on this SoC. Signed-off-by: Peter Marheine <pmarheine@chromium.org>
This commit is contained in:
parent
1b931af0ff
commit
d4549ed808
15 changed files with 656 additions and 106 deletions
|
@ -7,16 +7,8 @@ config SOC_FLASH_ITE_IT8XXX2
|
|||
bool "ITE IT8XXX2 flash driver"
|
||||
default y
|
||||
depends on DT_HAS_ITE_IT8XXX2_FLASH_CONTROLLER_ENABLED
|
||||
select SOC_FLASH_RAMCODE_SECTION
|
||||
select SOC_IT8XXX2_USE_ILM
|
||||
help
|
||||
The flash driver includes support for read, write and
|
||||
erase flash operations. It also supports protection.
|
||||
The it8xxx2 flash size is 1M byte.
|
||||
|
||||
config SOC_FLASH_RAMCODE_SECTION
|
||||
bool
|
||||
depends on SOC_FLASH_ITE_IT8XXX2
|
||||
help
|
||||
Enable this config to map the __ram_code section
|
||||
operations of flash(flash_it8xxx2_erase,
|
||||
flash_it8xxx2_write, flash_it8xxx2_read) to RAM.
|
||||
|
|
|
@ -10,31 +10,26 @@
|
|||
#define FLASH_WRITE_BLK_SZ DT_PROP(SOC_NV_FLASH_NODE, write_block_size)
|
||||
#define FLASH_ERASE_BLK_SZ DT_PROP(SOC_NV_FLASH_NODE, erase_block_size)
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/drivers/flash.h>
|
||||
#include <zephyr/init.h>
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/linker/linker-defs.h>
|
||||
|
||||
#include <ilm.h>
|
||||
#include <soc.h>
|
||||
#include <string.h>
|
||||
|
||||
#define LOG_LEVEL CONFIG_FLASH_LOG_LEVEL
|
||||
#include <zephyr/logging/log.h>
|
||||
LOG_MODULE_REGISTER(flash_ite_it8xxx2);
|
||||
|
||||
/* RAM code start address */
|
||||
extern char _ram_code_start[];
|
||||
#define FLASH_RAMCODE_START ((uint32_t)&_ram_code_start)
|
||||
#define FLASH_RAMCODE_START_BIT19 BIT(19)
|
||||
/* RAM code section */
|
||||
#define __ram_code __attribute__((section(".__ram_code")))
|
||||
|
||||
#define FLASH_IT8XXX2_REG_BASE \
|
||||
((struct flash_it8xxx2_regs *)DT_INST_REG_ADDR(0))
|
||||
|
||||
struct flash_it8xxx2_dev_data {
|
||||
struct k_sem sem;
|
||||
int flash_static_cache_enabled;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -48,8 +43,6 @@ struct flash_it8xxx2_dev_data {
|
|||
#define CHIP_FLASH_SIZE_BYTES DT_REG_SIZE(DT_NODELABEL(flash0))
|
||||
/* protect bank size */
|
||||
#define CHIP_FLASH_BANK_SIZE 0x00001000
|
||||
/* base+0000h~base+0FFF */
|
||||
#define CHIP_RAMCODE_BASE 0x80100000
|
||||
|
||||
/*
|
||||
* This is the block size of the ILM on the it8xxx2 chip.
|
||||
|
@ -98,7 +91,7 @@ static const struct flash_parameters flash_it8xxx2_parameters = {
|
|||
.erase_value = 0xff,
|
||||
};
|
||||
|
||||
void __ram_code ramcode_reset_i_cache(void)
|
||||
void __soc_ram_code ramcode_reset_i_cache(void)
|
||||
{
|
||||
/* I-Cache tag sram reset */
|
||||
IT83XX_GCTRL_MCCR |= IT83XX_GCTRL_ICACHE_RESET;
|
||||
|
@ -109,7 +102,7 @@ void __ram_code ramcode_reset_i_cache(void)
|
|||
__asm__ volatile ("fence.i" ::: "memory");
|
||||
}
|
||||
|
||||
void __ram_code ramcode_flash_follow_mode(void)
|
||||
void __soc_ram_code ramcode_flash_follow_mode(void)
|
||||
{
|
||||
struct flash_it8xxx2_regs *const flash_regs = FLASH_IT8XXX2_REG_BASE;
|
||||
/*
|
||||
|
@ -130,7 +123,7 @@ void __ram_code ramcode_flash_follow_mode(void)
|
|||
flash_regs->SMFI_ECINDDR = 0x00;
|
||||
}
|
||||
|
||||
void __ram_code ramcode_flash_follow_mode_exit(void)
|
||||
void __soc_ram_code ramcode_flash_follow_mode_exit(void)
|
||||
{
|
||||
struct flash_it8xxx2_regs *const flash_regs = FLASH_IT8XXX2_REG_BASE;
|
||||
|
||||
|
@ -139,7 +132,7 @@ void __ram_code ramcode_flash_follow_mode_exit(void)
|
|||
flash_regs->SMFI_ECINDAR2 = 0x00;
|
||||
}
|
||||
|
||||
void __ram_code ramcode_flash_fsce_high(void)
|
||||
void __soc_ram_code ramcode_flash_fsce_high(void)
|
||||
{
|
||||
struct flash_it8xxx2_regs *const flash_regs = FLASH_IT8XXX2_REG_BASE;
|
||||
|
||||
|
@ -162,7 +155,7 @@ void __ram_code ramcode_flash_fsce_high(void)
|
|||
flash_regs->SMFI_ECINDDR = 0x00;
|
||||
}
|
||||
|
||||
void __ram_code ramcode_flash_write_dat(uint8_t wdata)
|
||||
void __soc_ram_code ramcode_flash_write_dat(uint8_t wdata)
|
||||
{
|
||||
struct flash_it8xxx2_regs *const flash_regs = FLASH_IT8XXX2_REG_BASE;
|
||||
|
||||
|
@ -170,9 +163,8 @@ void __ram_code ramcode_flash_write_dat(uint8_t wdata)
|
|||
flash_regs->SMFI_ECINDDR = wdata;
|
||||
}
|
||||
|
||||
void __ram_code ramcode_flash_transaction(int wlen, uint8_t *wbuf, int rlen,
|
||||
uint8_t *rbuf,
|
||||
enum flash_transaction_cmd cmd_end)
|
||||
void __soc_ram_code ramcode_flash_transaction(int wlen, uint8_t *wbuf, int rlen, uint8_t *rbuf,
|
||||
enum flash_transaction_cmd cmd_end)
|
||||
{
|
||||
struct flash_it8xxx2_regs *const flash_regs = FLASH_IT8XXX2_REG_BASE;
|
||||
int i;
|
||||
|
@ -193,8 +185,8 @@ void __ram_code ramcode_flash_transaction(int wlen, uint8_t *wbuf, int rlen,
|
|||
}
|
||||
}
|
||||
|
||||
void __ram_code ramcode_flash_cmd_read_status(enum flash_status_mask mask,
|
||||
enum flash_status_mask target)
|
||||
void __soc_ram_code ramcode_flash_cmd_read_status(enum flash_status_mask mask,
|
||||
enum flash_status_mask target)
|
||||
{
|
||||
struct flash_it8xxx2_regs *const flash_regs = FLASH_IT8XXX2_REG_BASE;
|
||||
uint8_t cmd_rs[] = {FLASH_CMD_RS};
|
||||
|
@ -218,7 +210,7 @@ void __ram_code ramcode_flash_cmd_read_status(enum flash_status_mask mask,
|
|||
ramcode_flash_fsce_high();
|
||||
}
|
||||
|
||||
void __ram_code ramcode_flash_cmd_write_enable(void)
|
||||
void __soc_ram_code ramcode_flash_cmd_write_enable(void)
|
||||
{
|
||||
uint8_t cmd_we[] = {FLASH_CMD_WREN};
|
||||
|
||||
|
@ -232,7 +224,7 @@ void __ram_code ramcode_flash_cmd_write_enable(void)
|
|||
ramcode_flash_follow_mode_exit();
|
||||
}
|
||||
|
||||
void __ram_code ramcode_flash_cmd_write_disable(void)
|
||||
void __soc_ram_code ramcode_flash_cmd_write_disable(void)
|
||||
{
|
||||
uint8_t cmd_wd[] = {FLASH_CMD_WRDI};
|
||||
|
||||
|
@ -246,21 +238,21 @@ void __ram_code ramcode_flash_cmd_write_disable(void)
|
|||
ramcode_flash_follow_mode_exit();
|
||||
}
|
||||
|
||||
int __ram_code ramcode_flash_verify(int addr, int size, const char *data)
|
||||
int __soc_ram_code ramcode_flash_verify(int addr, int size, const char *data)
|
||||
{
|
||||
int i;
|
||||
uint8_t *wbuf = (uint8_t *)data;
|
||||
uint8_t *flash = (uint8_t *)addr;
|
||||
|
||||
/* verify for erase */
|
||||
if (data == NULL) {
|
||||
/* verify for erase */
|
||||
for (i = 0; i < size; i++) {
|
||||
if (flash[i] != 0xFF) {
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
/* verify for write */
|
||||
} else {
|
||||
/* verify for write */
|
||||
for (i = 0; i < size; i++) {
|
||||
if (flash[i] != wbuf[i]) {
|
||||
return -EINVAL;
|
||||
|
@ -271,7 +263,7 @@ int __ram_code ramcode_flash_verify(int addr, int size, const char *data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void __ram_code ramcode_flash_cmd_write(int addr, int wlen, uint8_t *wbuf)
|
||||
void __soc_ram_code ramcode_flash_cmd_write(int addr, int wlen, uint8_t *wbuf)
|
||||
{
|
||||
int i;
|
||||
uint8_t flash_write[] = {FLASH_CMD_WRITE, ((addr >> 16) & 0xFF),
|
||||
|
@ -315,14 +307,14 @@ void __ram_code ramcode_flash_cmd_write(int addr, int wlen, uint8_t *wbuf)
|
|||
ramcode_flash_follow_mode_exit();
|
||||
}
|
||||
|
||||
void __ram_code ramcode_flash_write(int addr, int wlen, const char *wbuf)
|
||||
void __soc_ram_code ramcode_flash_write(int addr, int wlen, const char *wbuf)
|
||||
{
|
||||
ramcode_flash_cmd_write_enable();
|
||||
ramcode_flash_cmd_write(addr, wlen, (uint8_t *)wbuf);
|
||||
ramcode_flash_cmd_write_disable();
|
||||
}
|
||||
|
||||
void __ram_code ramcode_flash_cmd_erase(int addr, int cmd)
|
||||
void __soc_ram_code ramcode_flash_cmd_erase(int addr, int cmd)
|
||||
{
|
||||
uint8_t cmd_erase[] = {cmd, ((addr >> 16) & 0xFF),
|
||||
((addr >> 8) & 0xFF), (addr & 0xFF)};
|
||||
|
@ -337,7 +329,7 @@ void __ram_code ramcode_flash_cmd_erase(int addr, int cmd)
|
|||
ramcode_flash_follow_mode_exit();
|
||||
}
|
||||
|
||||
void __ram_code ramcode_flash_erase(int addr, int cmd)
|
||||
void __soc_ram_code ramcode_flash_erase(int addr, int cmd)
|
||||
{
|
||||
ramcode_flash_cmd_write_enable();
|
||||
ramcode_flash_cmd_erase(addr, cmd);
|
||||
|
@ -345,8 +337,8 @@ void __ram_code ramcode_flash_erase(int addr, int cmd)
|
|||
}
|
||||
|
||||
/* Read data from flash */
|
||||
static int __ram_code flash_it8xxx2_read(const struct device *dev, off_t offset,
|
||||
void *data, size_t len)
|
||||
static int __soc_ram_code flash_it8xxx2_read(const struct device *dev, off_t offset, void *data,
|
||||
size_t len)
|
||||
{
|
||||
struct flash_it8xxx2_regs *const flash_regs = FLASH_IT8XXX2_REG_BASE;
|
||||
uint8_t *data_t = data;
|
||||
|
@ -371,8 +363,8 @@ static int __ram_code flash_it8xxx2_read(const struct device *dev, off_t offset,
|
|||
}
|
||||
|
||||
/* Write data to the flash, page by page */
|
||||
static int __ram_code flash_it8xxx2_write(const struct device *dev, off_t offset,
|
||||
const void *src_data, size_t len)
|
||||
static int __soc_ram_code flash_it8xxx2_write(const struct device *dev, off_t offset,
|
||||
const void *src_data, size_t len)
|
||||
{
|
||||
struct flash_it8xxx2_dev_data *data = dev->data;
|
||||
int ret = -EINVAL;
|
||||
|
@ -388,7 +380,7 @@ static int __ram_code flash_it8xxx2_write(const struct device *dev, off_t offset
|
|||
if ((len % FLASH_WRITE_BLK_SZ) != 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
if (data->flash_static_cache_enabled == 0) {
|
||||
if (!it8xxx2_is_ilm_configured()) {
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
|
@ -414,8 +406,7 @@ static int __ram_code flash_it8xxx2_write(const struct device *dev, off_t offset
|
|||
}
|
||||
|
||||
/* Erase multiple blocks */
|
||||
static int __ram_code flash_it8xxx2_erase(const struct device *dev,
|
||||
off_t offset, size_t len)
|
||||
static int __soc_ram_code flash_it8xxx2_erase(const struct device *dev, off_t offset, size_t len)
|
||||
{
|
||||
struct flash_it8xxx2_dev_data *data = dev->data;
|
||||
int v_size = len, v_addr = offset, ret = -EINVAL;
|
||||
|
@ -431,7 +422,7 @@ static int __ram_code flash_it8xxx2_erase(const struct device *dev,
|
|||
if ((len % FLASH_ERASE_BLK_SZ) != 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
if (data->flash_static_cache_enabled == 0) {
|
||||
if (!it8xxx2_is_ilm_configured()) {
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
|
@ -468,42 +459,6 @@ flash_it8xxx2_get_parameters(const struct device *dev)
|
|||
return &flash_it8xxx2_parameters;
|
||||
}
|
||||
|
||||
static void flash_code_static_cache(const struct device *dev)
|
||||
{
|
||||
struct flash_it8xxx2_regs *const flash_regs = FLASH_IT8XXX2_REG_BASE;
|
||||
struct flash_it8xxx2_dev_data *data = dev->data;
|
||||
unsigned int key;
|
||||
|
||||
/* Make sure no interrupt while enable static cache */
|
||||
key = irq_lock();
|
||||
|
||||
/* invalid static cache first */
|
||||
IT83XX_GCTRL_RVILMCR0 &= ~ILMCR_ILM0_ENABLE;
|
||||
|
||||
flash_regs->SMFI_SCAR0H = IT8XXX2_SMFI_SCAR0H_ENABLE;
|
||||
|
||||
memcpy((void *)CHIP_RAMCODE_BASE, (const void *)FLASH_RAMCODE_START,
|
||||
IT8XXX2_ILM_BLOCK_SIZE);
|
||||
|
||||
/* RISCV ILM 0 Enable */
|
||||
IT83XX_GCTRL_RVILMCR0 |= ILMCR_ILM0_ENABLE;
|
||||
|
||||
/* Enable ILM */
|
||||
flash_regs->SMFI_SCAR0L = FLASH_RAMCODE_START & GENMASK(7, 0);
|
||||
flash_regs->SMFI_SCAR0M = (FLASH_RAMCODE_START >> 8) & GENMASK(7, 0);
|
||||
flash_regs->SMFI_SCAR0H = (FLASH_RAMCODE_START >> 16) & GENMASK(2, 0);
|
||||
|
||||
if (FLASH_RAMCODE_START & FLASH_RAMCODE_START_BIT19) {
|
||||
flash_regs->SMFI_SCAR0H |= IT8XXX2_SMFI_SC0A19;
|
||||
} else {
|
||||
flash_regs->SMFI_SCAR0H &= ~IT8XXX2_SMFI_SC0A19;
|
||||
}
|
||||
|
||||
data->flash_static_cache_enabled = 0x01;
|
||||
|
||||
irq_unlock(key);
|
||||
}
|
||||
|
||||
static int flash_it8xxx2_init(const struct device *dev)
|
||||
{
|
||||
struct flash_it8xxx2_regs *const flash_regs = FLASH_IT8XXX2_REG_BASE;
|
||||
|
@ -522,8 +477,6 @@ static int flash_it8xxx2_init(const struct device *dev)
|
|||
/* Initialize mutex for flash controller */
|
||||
k_sem_init(&data->sem, 1, 1);
|
||||
|
||||
flash_code_static_cache(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <zephyr/irq.h>
|
||||
#include <zephyr/kernel.h>
|
||||
#include <errno.h>
|
||||
#include <ilm.h>
|
||||
#include <soc.h>
|
||||
#include <soc_dt.h>
|
||||
#include <zephyr/dt-bindings/i2c/it8xxx2-i2c.h>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#define ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_ITE_IT8XXX2_H_
|
||||
|
||||
#include <zephyr/dt-bindings/interrupt-controller/ite-intc.h>
|
||||
#include <ilm.h>
|
||||
#include <soc.h>
|
||||
|
||||
#endif /* ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_ITE_IT8XXX2_H_ */
|
||||
|
|
9
dts/bindings/memory-controllers/ite,it8xxx2-ilm.yaml
Normal file
9
dts/bindings/memory-controllers/ite,it8xxx2-ilm.yaml
Normal file
|
@ -0,0 +1,9 @@
|
|||
# Copyright (c) 2022 The ChromiumOS Authors
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: ITE IT8XXX2 Instruction Local Memory
|
||||
compatible: "ite,it8xxx2-ilm"
|
||||
include: base.yaml
|
||||
properties:
|
||||
reg:
|
||||
required: true
|
|
@ -309,9 +309,37 @@
|
|||
};
|
||||
};
|
||||
|
||||
sram0: memory@80101000 {
|
||||
sram0: memory@80100000 {
|
||||
compatible = "mmio-sram";
|
||||
reg = <0x80101000 DT_SIZE_K(56)>;
|
||||
reg = <0x80100000 DT_SIZE_K(60)>;
|
||||
};
|
||||
ilm: ilm@f0205d {
|
||||
compatible = "ite,it8xxx2-ilm";
|
||||
reg = <0xf0205d 3 /* RVILMCR0..2 */
|
||||
0xf01040 3 /* SCAR0 */
|
||||
0xf01043 3
|
||||
0xf01046 3
|
||||
0xf01049 3
|
||||
0xf0104c 3 /* SCAR4 */
|
||||
0xf01081 3 /* SCAR5 */
|
||||
0xf01084 3
|
||||
0xf01087 3
|
||||
0xf0108a 3
|
||||
0xf0108d 3
|
||||
0xf01090 3
|
||||
0xf01093 3
|
||||
0xf01096 3 /* SCAR12 */
|
||||
0xf010b0 3 /* SCAR13 */
|
||||
0xf010b3 3
|
||||
0xf010b6 3
|
||||
0xf010b9 3
|
||||
0xf010bc 3
|
||||
0xf010bf 3
|
||||
0xf010c2 3
|
||||
0xf010c5 3
|
||||
0xf010c8 3
|
||||
0xf010cb 3
|
||||
0xf010ce 3>; /* SCAR23 */
|
||||
};
|
||||
wuc1: wakeup-controller@f01b00 {
|
||||
compatible = "ite,it8xxx2-wuc";
|
||||
|
|
|
@ -145,14 +145,6 @@ SECTIONS
|
|||
*(".text.*")
|
||||
*(.gnu.linkonce.t.*)
|
||||
#include <zephyr/linker/kobject-text.ld>
|
||||
#ifdef CONFIG_SOC_FLASH_RAMCODE_SECTION
|
||||
. = ALIGN(0x1000);
|
||||
_ram_code_start = .;
|
||||
KEEP(*(.__ram_code))
|
||||
__ram_code_size = . - _ram_code_start;
|
||||
ASSERT((__ram_code_size <= 0x1000),
|
||||
"__ram_code_size <= 4k bytes");
|
||||
#endif
|
||||
} GROUP_LINK_IN(ROMABLE_REGION)
|
||||
|
||||
__text_region_end = .;
|
||||
|
|
|
@ -2,6 +2,7 @@ zephyr_sources(
|
|||
soc.c
|
||||
)
|
||||
zephyr_library_sources_ifndef(CONFIG_RISCV_ISA_EXT_M __arithmetic.S)
|
||||
zephyr_sources_ifdef(CONFIG_SOC_IT8XXX2_USE_ILM ilm.c)
|
||||
|
||||
# IMPORTANT:
|
||||
# The h2ram section must be first added to RAM_SECTIONS to avoid gap.
|
||||
|
|
|
@ -79,4 +79,14 @@ config SOC_IT8XXX2_EXT_32K
|
|||
|
||||
endchoice
|
||||
|
||||
config SOC_IT8XXX2_USE_ILM
|
||||
bool
|
||||
default y
|
||||
help
|
||||
If enabled, Instruction Local Memory (ILM) will be configured to execute
|
||||
code placed in the .__ram_code section out of RAM. This consumes RAM in
|
||||
blocks of 4 kilobytes, but performance of code in ILM is much more
|
||||
predictable than executing from Flash directly, and some code (such as code
|
||||
that writes to the internal Flash) must execute out of RAM.
|
||||
|
||||
endif # SOC_IT8XXX2
|
||||
|
|
193
soc/riscv/riscv-ite/it8xxx2/ilm.c
Normal file
193
soc/riscv/riscv-ite/it8xxx2/ilm.c
Normal file
|
@ -0,0 +1,193 @@
|
|||
/*
|
||||
* Copyright 2022 The ChromiumOS Authors.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/devicetree.h>
|
||||
#include <zephyr/irq.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
#include <zephyr/sys/__assert.h>
|
||||
|
||||
LOG_MODULE_REGISTER(soc_it8xxx2_ilm, CONFIG_LOG_DEFAULT_LEVEL);
|
||||
|
||||
/*
|
||||
* Instruction Local Memory (ILM) support for IT8xxx2.
|
||||
*
|
||||
* IT8xxx2 allows 4-kilobyte blocks of RAM be configured individually as either Instruction- or
|
||||
* Data Local Memory (ILM or DLM). Addresses from which instructions will be fetched by the CPU
|
||||
* *must* be in the Flash memory space: it is not permitted to execute from RAM addresses, only
|
||||
* through ILM mappings into RAM.
|
||||
*
|
||||
* When a RAM block is configured as ILM, accesses to addresses matching the corresponding Scratch
|
||||
* SRAM address register (SCARn{H,M,L}) are redirected to the corresponding ILM block in RAM.
|
||||
* If SCAR0 (corresponding to ILM0) has the value 0x8021532 and ILM0 is enabled, then instruction
|
||||
* fetches from the memory range 0x8021532..0x8022532 will be redirected to physical addresses
|
||||
* 0x80100000..0x80101000 (the first 4k block of RAM).
|
||||
*
|
||||
* Instruction fetch from Flash is normally cacheable, but configuring ILM for a region makes that
|
||||
* address range non-cacheable (which is appropriate because Flash has high latency but RAM is
|
||||
* essentially the same speed as cache).
|
||||
*/
|
||||
|
||||
extern const uint8_t __ilm_flash_start[];
|
||||
extern const uint8_t __ilm_flash_end[];
|
||||
extern uint8_t __ilm_ram_start[];
|
||||
extern uint8_t __ilm_ram_end[];
|
||||
|
||||
#define ILM_BLOCK_SIZE 0x1000
|
||||
BUILD_ASSERT((ILM_BLOCK_SIZE & (ILM_BLOCK_SIZE - 1)) == 0, "ILM_BLOCK_SIZE must be a power of two");
|
||||
|
||||
#define FLASH_BASE CONFIG_FLASH_BASE_ADDRESS
|
||||
#define RAM_BASE CONFIG_SRAM_BASE_ADDRESS
|
||||
#define RAM_SIZE CONFIG_SRAM_SIZE
|
||||
|
||||
#define ILM_NODE DT_NODELABEL(ilm)
|
||||
|
||||
#define SCARH_ENABLE BIT(3)
|
||||
#define SCARH_ADDR_BIT19 BIT(7)
|
||||
|
||||
/*
|
||||
* SCAR registers contain 20-bit addresses in three registers, with one set
|
||||
* of SCAR registers for each ILM block that may be configured.
|
||||
*/
|
||||
struct scar_reg {
|
||||
/* Bits 0..7 of address; SCARnL */
|
||||
uint8_t l;
|
||||
/* Bits 8..15 of address; SCARnM */
|
||||
uint8_t m;
|
||||
/* Bits 16..18 and 19 of address, plus the enable bit for the entire SCAR; SCARnH */
|
||||
uint8_t h;
|
||||
};
|
||||
|
||||
struct ilm_config {
|
||||
/* Points to the contiguous set of RVILMCRn registers */
|
||||
volatile uint8_t *ilm_control_regs;
|
||||
volatile struct scar_reg *scar_regs[15];
|
||||
};
|
||||
|
||||
bool it8xxx2_is_ilm_configured(void)
|
||||
{
|
||||
return device_is_ready(DEVICE_DT_GET(ILM_NODE));
|
||||
}
|
||||
|
||||
static bool __maybe_unused is_block_aligned(const void *const p)
|
||||
{
|
||||
return ((uintptr_t)p & (ILM_BLOCK_SIZE - 1)) == 0;
|
||||
}
|
||||
|
||||
static int it8xxx2_configure_ilm_block(const struct ilm_config *const config, void *ram_addr,
|
||||
const void *flash_addr, const size_t copy_sz)
|
||||
{
|
||||
if ((uintptr_t)ram_addr < RAM_BASE) {
|
||||
return -EFAULT; /* Not in RAM */
|
||||
}
|
||||
const int dirmap_index = ((uintptr_t)ram_addr - RAM_BASE) / ILM_BLOCK_SIZE;
|
||||
|
||||
if (dirmap_index >= ARRAY_SIZE(config->scar_regs)) {
|
||||
return -EFAULT; /* Past the end of RAM */
|
||||
}
|
||||
BUILD_ASSERT((FLASH_BASE & GENMASK(19, 0)) == 0,
|
||||
"Flash is assumed to be aligned to SCAR register width");
|
||||
if (((uintptr_t)flash_addr - FLASH_BASE) & ~GENMASK(19, 0)) {
|
||||
return -EFAULT; /* Address doesn't fit in the SCAR */
|
||||
}
|
||||
if (!is_block_aligned(flash_addr)) {
|
||||
/* Bits 0..11 of SCAR can be programmed but ILM only works if they're zero */
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
LOG_DBG("Enabling ILM%d %p -> %p, copy %d", dirmap_index, flash_addr, ram_addr, copy_sz);
|
||||
|
||||
volatile uint8_t *const rvilmcr = &config->ilm_control_regs[dirmap_index / 8];
|
||||
volatile struct scar_reg *const scar = config->scar_regs[dirmap_index];
|
||||
const int cr_mask = BIT(dirmap_index % 8);
|
||||
|
||||
int irq_key = irq_lock();
|
||||
|
||||
/* Invalidate any possibly-existing mapping */
|
||||
*rvilmcr &= ~cr_mask;
|
||||
/* Ensure scratch RAM for block data access is enabled */
|
||||
scar->h = SCARH_ENABLE;
|
||||
/* Copy block contents from flash into RAM */
|
||||
memcpy(ram_addr, flash_addr, copy_sz);
|
||||
/* Enable ILM block */
|
||||
*rvilmcr |= cr_mask;
|
||||
/* Program SCAR */
|
||||
scar->l = (uintptr_t)flash_addr & GENMASK(7, 0);
|
||||
scar->m = ((uintptr_t)flash_addr & GENMASK(15, 8)) >> 8;
|
||||
|
||||
uint8_t scarh_value = ((uintptr_t)flash_addr & GENMASK(18, 16)) >> 16;
|
||||
|
||||
if ((uintptr_t)flash_addr & BIT(19)) {
|
||||
scarh_value |= SCARH_ADDR_BIT19;
|
||||
}
|
||||
scar->h = scarh_value;
|
||||
|
||||
irq_unlock(irq_key);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int it8xxx2_ilm_init(const struct device *dev)
|
||||
{
|
||||
/* Invariants enforced by the linker script */
|
||||
__ASSERT(is_block_aligned(__ilm_ram_start),
|
||||
"ILM physical base address (%p) must be 4k-aligned", __ilm_ram_start);
|
||||
__ASSERT(is_block_aligned(__ilm_flash_start),
|
||||
"ILM flash base address (%p) must be 4k-aligned", __ilm_flash_start);
|
||||
__ASSERT_NO_MSG((uintptr_t)__ilm_ram_end >= (uintptr_t)__ilm_ram_start &&
|
||||
(uintptr_t)__ilm_flash_end >= (uintptr_t)__ilm_flash_start);
|
||||
|
||||
LOG_DBG("ILM init %p-%p -> %p-%p", __ilm_flash_start, __ilm_flash_end, __ilm_ram_start,
|
||||
__ilm_ram_end);
|
||||
for (uintptr_t block_base = (uintptr_t)__ilm_ram_start;
|
||||
block_base < (uintptr_t)__ilm_ram_end; block_base += ILM_BLOCK_SIZE) {
|
||||
uintptr_t flash_base =
|
||||
(uintptr_t)__ilm_flash_start + (block_base - (uintptr_t)__ilm_ram_start);
|
||||
/*
|
||||
* Part of the target RAM block might be used for non-code data; avoid overwriting
|
||||
* it by only copying as much data as the ILM flash region contains.
|
||||
*/
|
||||
size_t used_size = MIN((uintptr_t)__ilm_flash_end - flash_base, ILM_BLOCK_SIZE);
|
||||
int rv = it8xxx2_configure_ilm_block(dev->config, (void *)block_base,
|
||||
(const void *)flash_base, used_size);
|
||||
|
||||
if (rv) {
|
||||
LOG_ERR("Unable to configure ILM block %p: %d", (void *)flash_base, rv);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define SCAR_REG(n) (volatile struct scar_reg *)DT_REG_ADDR_BY_IDX(ILM_NODE, n)
|
||||
|
||||
static const struct ilm_config ilm_config = {
|
||||
.ilm_control_regs = (volatile uint8_t *)DT_REG_ADDR_BY_IDX(ILM_NODE, 0),
|
||||
.scar_regs = {
|
||||
SCAR_REG(1),
|
||||
SCAR_REG(2),
|
||||
SCAR_REG(3),
|
||||
SCAR_REG(4),
|
||||
SCAR_REG(5),
|
||||
SCAR_REG(6),
|
||||
SCAR_REG(7),
|
||||
SCAR_REG(8),
|
||||
SCAR_REG(9),
|
||||
SCAR_REG(10),
|
||||
SCAR_REG(11),
|
||||
SCAR_REG(12),
|
||||
SCAR_REG(13),
|
||||
SCAR_REG(14),
|
||||
SCAR_REG(15),
|
||||
}};
|
||||
BUILD_ASSERT(ARRAY_SIZE(ilm_config.scar_regs) * ILM_BLOCK_SIZE == KB(RAM_SIZE),
|
||||
"Wrong number of SCAR registers defined for RAM size");
|
||||
BUILD_ASSERT(ARRAY_SIZE(ilm_config.scar_regs) <= DT_REG_SIZE_BY_IDX(ILM_NODE, 0) * 8,
|
||||
"Size of ILM control register block is too small for number of SCARs");
|
||||
|
||||
DEVICE_DT_DEFINE(ILM_NODE, &it8xxx2_ilm_init, NULL, NULL, &ilm_config, PRE_KERNEL_1, 0, NULL);
|
15
soc/riscv/riscv-ite/it8xxx2/ilm.h
Normal file
15
soc/riscv/riscv-ite/it8xxx2/ilm.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* Copyright 2022 The ChromiumOS Authors.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/* Places code in the section that gets mapped into ILM */
|
||||
#define __soc_ram_code __attribute__((section(".__ram_code")))
|
||||
|
||||
|
||||
#ifndef _ASMLANGUAGE
|
||||
bool it8xxx2_is_ilm_configured(void);
|
||||
#endif
|
|
@ -4,4 +4,368 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/arch/riscv/common/linker.ld>
|
||||
#include <soc.h>
|
||||
#include <zephyr/devicetree.h>
|
||||
|
||||
#include <zephyr/linker/sections.h>
|
||||
#include <zephyr/linker/devicetree_regions.h>
|
||||
|
||||
#include <zephyr/linker/linker-defs.h>
|
||||
#include <zephyr/linker/linker-tool.h>
|
||||
|
||||
#ifdef CONFIG_XIP
|
||||
#define ROMABLE_REGION ROM
|
||||
#else
|
||||
#define ROMABLE_REGION RAM
|
||||
#endif
|
||||
#define RAMABLE_REGION RAM
|
||||
|
||||
#define _EXCEPTION_SECTION_NAME exceptions
|
||||
#define _RESET_SECTION_NAME reset
|
||||
|
||||
#ifdef CONFIG_XIP
|
||||
#if DT_NODE_HAS_COMPAT_STATUS(DT_CHOSEN(zephyr_flash), soc_nv_flash, okay)
|
||||
#ifdef CONFIG_FLASH_LOAD_OFFSET
|
||||
#define ROM_BASE (DT_REG_ADDR(DT_CHOSEN(zephyr_flash)) + \
|
||||
CONFIG_FLASH_LOAD_OFFSET)
|
||||
#else /* !CONFIG_FLASH_LOAD_OFFSET */
|
||||
#define ROM_BASE DT_REG_ADDR(DT_CHOSEN(zephyr_flash))
|
||||
#endif /* CONFIG_FLASH_LOAD_OFFSET */
|
||||
#define ROM_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_flash))
|
||||
#elif DT_NODE_HAS_COMPAT(DT_CHOSEN(zephyr_flash), jedec_spi_nor)
|
||||
/* For jedec,spi-nor we expect the spi controller to memory map the flash
|
||||
* and for that mapping to be the second register property of the spi
|
||||
* controller.
|
||||
*/
|
||||
#define SPI_CTRL DT_PARENT(DT_CHOSEN(zephyr_flash))
|
||||
#define ROM_BASE DT_REG_ADDR_BY_IDX(SPI_CTRL, 1)
|
||||
#define ROM_SIZE DT_REG_SIZE_BY_IDX(SPI_CTRL, 1)
|
||||
#endif
|
||||
#else /* CONFIG_XIP */
|
||||
#define ROM_BASE CONFIG_SRAM_BASE_ADDRESS
|
||||
#define ROM_SIZE KB(CONFIG_SRAM_SIZE)
|
||||
#endif /* CONFIG_XIP */
|
||||
|
||||
#define RAM_BASE CONFIG_SRAM_BASE_ADDRESS
|
||||
#define RAM_SIZE KB(CONFIG_SRAM_SIZE)
|
||||
|
||||
#ifdef CONFIG_RISCV_PMP
|
||||
#define MPU_MIN_SIZE 4
|
||||
#define MPU_MIN_SIZE_ALIGN . = ALIGN(MPU_MIN_SIZE);
|
||||
#if defined(CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT)
|
||||
#define MPU_ALIGN(region_size) \
|
||||
. = ALIGN(MPU_MIN_SIZE); \
|
||||
. = ALIGN( 1 << LOG2CEIL(region_size))
|
||||
#else
|
||||
#define MPU_ALIGN(region_size) \
|
||||
. = ALIGN(MPU_MIN_SIZE)
|
||||
#endif
|
||||
#else
|
||||
#define MPU_MIN_SIZE_ALIGN
|
||||
#define MPU_ALIGN(region_size) . = ALIGN(4)
|
||||
#endif
|
||||
|
||||
MEMORY
|
||||
{
|
||||
#ifdef CONFIG_XIP
|
||||
ROM (rx) : ORIGIN = ROM_BASE, LENGTH = ROM_SIZE
|
||||
#endif
|
||||
RAM (rwx) : ORIGIN = RAM_BASE, LENGTH = RAM_SIZE
|
||||
|
||||
LINKER_DT_REGIONS()
|
||||
|
||||
/* Used by and documented in include/linker/intlist.ld */
|
||||
IDT_LIST (wx) : ORIGIN = 0xFFFFF7FF, LENGTH = 2K
|
||||
}
|
||||
|
||||
ENTRY(CONFIG_KERNEL_ENTRY)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
|
||||
#include <zephyr/linker/rel-sections.ld>
|
||||
|
||||
/*
|
||||
* The .plt and .iplt are here according to
|
||||
* 'riscv32-zephyr-elf-ld --verbose', before text section.
|
||||
*/
|
||||
SECTION_PROLOGUE(.plt,,)
|
||||
{
|
||||
*(.plt)
|
||||
}
|
||||
|
||||
SECTION_PROLOGUE(.iplt,,)
|
||||
{
|
||||
*(.iplt)
|
||||
}
|
||||
|
||||
GROUP_START(ROMABLE_REGION)
|
||||
__rom_region_start = ROM_BASE;
|
||||
|
||||
SECTION_PROLOGUE(rom_start,,)
|
||||
{
|
||||
. = ALIGN(16);
|
||||
/* Located in generated directory. This file is populated by calling
|
||||
* zephyr_linker_sources(ROM_START ...).
|
||||
*/
|
||||
#include <snippets-rom-start.ld>
|
||||
} GROUP_LINK_IN(ROMABLE_REGION)
|
||||
|
||||
#ifdef CONFIG_CODE_DATA_RELOCATION
|
||||
#include <linker_relocate.ld>
|
||||
#endif
|
||||
|
||||
SECTION_PROLOGUE(_RESET_SECTION_NAME,,)
|
||||
{
|
||||
KEEP(*(.reset.*))
|
||||
} GROUP_LINK_IN(ROMABLE_REGION)
|
||||
|
||||
SECTION_PROLOGUE(_EXCEPTION_SECTION_NAME,,)
|
||||
{
|
||||
KEEP(*(".exception.entry.*"))
|
||||
*(".exception.other.*")
|
||||
} GROUP_LINK_IN(ROMABLE_REGION)
|
||||
|
||||
SECTION_PROLOGUE(_TEXT_SECTION_NAME,,)
|
||||
{
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.openocd_debug))
|
||||
KEEP(*(".openocd_debug.*"))
|
||||
|
||||
__text_region_start = .;
|
||||
|
||||
*(.text)
|
||||
*(".text.*")
|
||||
*(.gnu.linkonce.t.*)
|
||||
#include <zephyr/linker/kobject-text.ld>
|
||||
|
||||
/* IT8xxx2 requires memory mappings be configured for execution
|
||||
* out of RAM, which refer to contiguous blocks of RAM. Place
|
||||
* all relevant sections together to minimize RAM waste. */
|
||||
. = ALIGN(0x1000);
|
||||
/* Mapping base address must be 4k-aligned */
|
||||
__ilm_flash_start = .;
|
||||
/* Specially-tagged functions in SoC sources */
|
||||
KEEP(*(.__ram_code))
|
||||
__ilm_flash_end = .;
|
||||
/* ILM mapping is always a multiple of 4k size; ensure following
|
||||
* sections won't incorrectly redirect to RAM. */
|
||||
. = ALIGN(0x1000);
|
||||
|
||||
} GROUP_LINK_IN(ROMABLE_REGION)
|
||||
|
||||
__text_region_end = .;
|
||||
|
||||
__rodata_region_start = .;
|
||||
#include <zephyr/linker/common-rom.ld>
|
||||
#include <zephyr/linker/thread-local-storage.ld>
|
||||
|
||||
SECTION_PROLOGUE(_RODATA_SECTION_NAME,,)
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.srodata)
|
||||
*(".srodata.*")
|
||||
*(.rodata)
|
||||
*(".rodata.*")
|
||||
*(.gnu.linkonce.r.*)
|
||||
*(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
|
||||
|
||||
/* Located in generated directory. This file is populated by the
|
||||
* zephyr_linker_sources() Cmake function.
|
||||
*/
|
||||
#include <snippets-rodata.ld>
|
||||
#include <zephyr/linker/kobject-rom.ld>
|
||||
. = ALIGN(4);
|
||||
} GROUP_LINK_IN(ROMABLE_REGION)
|
||||
|
||||
#include <zephyr/linker/cplusplus-rom.ld>
|
||||
__rodata_region_end = .;
|
||||
|
||||
/* For non-XIP system, __rom_region_end symbol should be set to
|
||||
* the end of common ROMABLE_REGIONs (text and rodata) instead of
|
||||
* the linker script end, so it wouldn't mistakenly contain
|
||||
* RAMABLE_REGION in it.
|
||||
*/
|
||||
#ifndef CONFIG_XIP
|
||||
#ifdef CONFIG_RISCV_PMP
|
||||
SECTION_PROLOGUE(rom_mpu_padding,,)
|
||||
{
|
||||
MPU_ALIGN(__rodata_region_end - __rom_region_start);
|
||||
#ifdef CONFIG_QEMU_TARGET
|
||||
/*
|
||||
* QEMU doesn't vet each instruction fetch individually.
|
||||
* Instead, it grabs a whole page and perform dynamic
|
||||
* transation on it in a batch. It therefore validates
|
||||
* PMP permissions using page-sized and -aligned chunks.
|
||||
*/
|
||||
. = ALIGN(0x1000);
|
||||
#endif
|
||||
} GROUP_LINK_IN(ROMABLE_REGION)
|
||||
#endif /* CONFIG_RISCV_PMP */
|
||||
|
||||
__rom_region_end = .;
|
||||
__rom_region_size = __rom_region_end - __rom_region_start;
|
||||
#endif /* CONFIG_XIP */
|
||||
GROUP_END(ROMABLE_REGION)
|
||||
|
||||
GROUP_START(RAMABLE_REGION)
|
||||
|
||||
. = RAM_BASE;
|
||||
|
||||
/* Claim RAM for ILM mappings; must be 4k-aligned and each mapping is 4k in
|
||||
* size, but mapped regions can still be accessed as data so don't need to be
|
||||
* padded out to 4k size. This doesn't load any sections because code in ILM
|
||||
* is still accessed at its VMA in ROM. */
|
||||
SECTION_PROLOGUE(ilm_ram,(NOLOAD),ALIGN(0x1000))
|
||||
{
|
||||
__ilm_ram_start = .;
|
||||
. += __ilm_flash_end - __ilm_flash_start;
|
||||
__ilm_ram_end = .;
|
||||
} GROUP_LINK_IN(RAMABLE_REGION)
|
||||
|
||||
_image_ram_start = .;
|
||||
/* Located in generated directory. This file is populated by the
|
||||
* zephyr_linker_sources() Cmake function.
|
||||
*/
|
||||
#include <snippets-ram-sections.ld>
|
||||
|
||||
#if defined(CONFIG_USERSPACE)
|
||||
#define APP_SHARED_ALIGN MPU_MIN_SIZE_ALIGN
|
||||
#define SMEM_PARTITION_ALIGN MPU_ALIGN
|
||||
|
||||
#include <app_smem.ld>
|
||||
|
||||
_app_smem_size = _app_smem_end - _app_smem_start;
|
||||
_app_smem_rom_start = LOADADDR(_APP_SMEM_SECTION_NAME);
|
||||
#endif /* CONFIG_USERSPACE */
|
||||
|
||||
SECTION_DATA_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD),)
|
||||
{
|
||||
MPU_MIN_SIZE_ALIGN
|
||||
/*
|
||||
* For performance, BSS section is assumed to be 4 byte aligned and
|
||||
* a multiple of 4 bytes
|
||||
*/
|
||||
. = ALIGN(4);
|
||||
__bss_start = .;
|
||||
__kernel_ram_start = .;
|
||||
*(.sbss)
|
||||
*(".sbss.*")
|
||||
*(.bss)
|
||||
*(".bss.*")
|
||||
COMMON_SYMBOLS
|
||||
|
||||
#ifdef CONFIG_CODE_DATA_RELOCATION
|
||||
#include <linker_sram_bss_relocate.ld>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* As memory is cleared in words only, it is simpler to ensure the BSS
|
||||
* section ends on a 4 byte boundary. This wastes a maximum of 3 bytes.
|
||||
*/
|
||||
__bss_end = ALIGN(4);
|
||||
} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION)
|
||||
|
||||
#include <zephyr/linker/common-noinit.ld>
|
||||
|
||||
SECTION_DATA_PROLOGUE(_DATA_SECTION_NAME,,)
|
||||
{
|
||||
. = ALIGN(4);
|
||||
/* _image_ram_start = .; */
|
||||
__data_region_start = .;
|
||||
__data_start = .;
|
||||
|
||||
*(.data)
|
||||
*(".data.*")
|
||||
|
||||
#ifdef CONFIG_RISCV_GP
|
||||
/*
|
||||
* RISC-V architecture has 12-bit signed immediate offsets in the
|
||||
* instructions. If we can put the most commonly accessed globals
|
||||
* in a special 4K span of memory addressed by the GP register, then
|
||||
* we can access those values in a single instruction, saving both
|
||||
* codespace and runtime.
|
||||
*
|
||||
* Since these immediate offsets are signed, place gp 0x800 past the
|
||||
* beginning of .sdata so that we can use both positive and negative
|
||||
* offsets.
|
||||
*/
|
||||
. = ALIGN(8);
|
||||
PROVIDE (__global_pointer$ = . + 0x800);
|
||||
#endif
|
||||
|
||||
*(.sdata .sdata.* .gnu.linkonce.s.*)
|
||||
|
||||
/* Located in generated directory. This file is populated by the
|
||||
* zephyr_linker_sources() Cmake function.
|
||||
*/
|
||||
#include <snippets-rwdata.ld>
|
||||
|
||||
#ifdef CONFIG_CODE_DATA_RELOCATION
|
||||
#include <linker_sram_data_relocate.ld>
|
||||
#endif
|
||||
|
||||
__data_end = .;
|
||||
|
||||
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
|
||||
__data_size = __data_end - __data_start;
|
||||
__data_load_start = LOADADDR(_DATA_SECTION_NAME);
|
||||
|
||||
__data_region_load_start = LOADADDR(_DATA_SECTION_NAME);
|
||||
|
||||
#include <zephyr/linker/common-ram.ld>
|
||||
#include <zephyr/linker/kobject-data.ld>
|
||||
#include <zephyr/linker/cplusplus-ram.ld>
|
||||
|
||||
/* Located in generated directory. This file is populated by the
|
||||
* zephyr_linker_sources() Cmake function.
|
||||
*/
|
||||
#include <snippets-data-sections.ld>
|
||||
|
||||
__data_region_end = .;
|
||||
|
||||
MPU_MIN_SIZE_ALIGN
|
||||
|
||||
_image_ram_end = .;
|
||||
_end = .; /* end of image */
|
||||
|
||||
__kernel_ram_end = .;
|
||||
__kernel_ram_size = __kernel_ram_end - __kernel_ram_start;
|
||||
|
||||
/* Located in generated directory. This file is populated by the
|
||||
* zephyr_linker_sources() Cmake function.
|
||||
*/
|
||||
#include <snippets-sections.ld>
|
||||
|
||||
GROUP_END(RAMABLE_REGION)
|
||||
|
||||
#include <zephyr/linker/debug-sections.ld>
|
||||
|
||||
/DISCARD/ : { *(.note.GNU-stack) }
|
||||
|
||||
SECTION_PROLOGUE(.riscv.attributes, 0,)
|
||||
{
|
||||
KEEP(*(.riscv.attributes))
|
||||
KEEP(*(.gnu.attributes))
|
||||
}
|
||||
|
||||
/* Sections generated from 'zephyr,memory-region' nodes */
|
||||
LINKER_DT_SECTIONS()
|
||||
|
||||
/* Because ROMABLE_REGION != RAMABLE_REGION in XIP-system, it is valid
|
||||
* to set __rom_region_end symbol at the end of linker script and
|
||||
* doesn't mistakenly contain the RAMABLE_REGION in it.
|
||||
*/
|
||||
#ifdef CONFIG_XIP
|
||||
/* Must be last in romable region */
|
||||
SECTION_PROLOGUE(.last_section,(NOLOAD),)
|
||||
{
|
||||
} GROUP_LINK_IN(ROMABLE_REGION)
|
||||
|
||||
/* To provide the image size as a const expression,
|
||||
* calculate this value here. */
|
||||
__rom_region_end = LOADADDR(.last_section);
|
||||
__rom_region_size = __rom_region_end - __rom_region_start;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/init.h>
|
||||
#include "ilm.h"
|
||||
#include <soc.h>
|
||||
#include "soc_espi.h"
|
||||
#include <zephyr/dt-bindings/interrupt-controller/ite-intc.h>
|
||||
|
|
|
@ -8,8 +8,6 @@
|
|||
*/
|
||||
#include <soc_common.h>
|
||||
|
||||
#define __soc_ram_code __attribute__((section(".__ram_code")))
|
||||
|
||||
/*
|
||||
* This define gets the total number of USBPD ports available on the
|
||||
* ITE EC chip from dtsi (include status disable). Both it81202 and
|
||||
|
|
|
@ -148,14 +148,6 @@ SECTIONS
|
|||
*(".text.*")
|
||||
*(.gnu.linkonce.t.*)
|
||||
#include <zephyr/linker/kobject-text.ld>
|
||||
#ifdef CONFIG_SOC_FLASH_RAMCODE_SECTION
|
||||
. = ALIGN(0x1000);
|
||||
_ram_code_start = .;
|
||||
KEEP(*(.__ram_code))
|
||||
__ram_code_size = . - _ram_code_start;
|
||||
ASSERT((__ram_code_size <= 0x1000),
|
||||
"__ram_code_size <= 4k bytes");
|
||||
#endif
|
||||
} GROUP_LINK_IN(ROMABLE_REGION)
|
||||
|
||||
__text_region_end = .;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue