Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fvp dram1 #1860

Merged
merged 6 commits into from
Oct 12, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions core/arch/arm/arm.mk
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ $(error Error: CFG_CORE_SANITIZE_KADDRESS not compatible with CFG_WITH_PAGER)
endif
endif

ifeq ($(CFG_CORE_LARGE_PHYS_ADDR),y)
$(call force,CFG_WITH_LPAE,y)
endif

ifeq ($(CFG_ARM32_core),y)
# Configration directive related to ARMv7 optee boot arguments.
# CFG_PAGEABLE_ADDR: if defined, forces pageable data physical address.
Expand Down
10 changes: 5 additions & 5 deletions core/arch/arm/include/kernel/linker.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,15 @@ extern const struct core_mmu_phys_mem __end_phys_mem_map_section;
extern const struct core_mmu_phys_mem __start_phys_nsec_ddr_section;
extern const struct core_mmu_phys_mem __end_phys_nsec_ddr_section;

#define VCORE_UNPG_RX_PA ((paddr_t)__vcore_unpg_rx_start)
#define VCORE_UNPG_RX_PA ((unsigned long)__vcore_unpg_rx_start)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As these hold physical addresses/sizes, CFG_CORE_LARGE_PHYS_ADDR=y requires 64bit fields here. Why doesn't paddr_t fit?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Static initialization based on addresses of variables seems to the a bit fragile. As soon as there's a 64-bit type on a 32-bit system involved the compiler tends to complain. unsigned long should be a good enough compromise for all systems.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

#define VCORE_UNPG_RX_SZ ((size_t)__vcore_unpg_rx_size)
#define VCORE_UNPG_RO_PA ((paddr_t)__vcore_unpg_ro_start)
#define VCORE_UNPG_RO_PA ((unsigned long)__vcore_unpg_ro_start)
#define VCORE_UNPG_RO_SZ ((size_t)__vcore_unpg_ro_size)
#define VCORE_UNPG_RW_PA ((paddr_t)__vcore_unpg_rw_start)
#define VCORE_UNPG_RW_PA ((unsigned long)__vcore_unpg_rw_start)
#define VCORE_UNPG_RW_SZ ((size_t)__vcore_unpg_rw_size)
#define VCORE_INIT_RX_PA ((paddr_t)__vcore_init_rx_start)
#define VCORE_INIT_RX_PA ((unsigned long)__vcore_init_rx_start)
#define VCORE_INIT_RX_SZ ((size_t)__vcore_init_rx_size)
#define VCORE_INIT_RO_PA ((paddr_t)__vcore_init_ro_start)
#define VCORE_INIT_RO_PA ((unsigned long)__vcore_init_ro_start)
#define VCORE_INIT_RO_SZ ((size_t)__vcore_init_ro_size)
extern const uint8_t __vcore_unpg_rx_start[];
extern const uint8_t __vcore_unpg_rx_size[];
Expand Down
38 changes: 36 additions & 2 deletions core/arch/arm/include/mm/core_mmu.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,22 +165,56 @@ static inline const char *teecore_memtype_name(enum teecore_memtypes type)
struct core_mmu_phys_mem {
const char *name;
enum teecore_memtypes type;
paddr_t addr;
size_t size;
__extension__ union {
#if __SIZEOF_LONG__ != __SIZEOF_PADDR__
struct {
uint32_t lo_addr;
uint32_t hi_addr;
};
#endif
paddr_t addr;
};
__extension__ union {
#if __SIZEOF_LONG__ != __SIZEOF_PADDR__
struct {
uint32_t lo_size;
uint32_t hi_size;
};
#endif
paddr_size_t size;
};
};

#define __register_memory2(_name, _type, _addr, _size, _section, _id) \
static const struct core_mmu_phys_mem __phys_mem_ ## _id \
__used __section(_section) = \
{ .name = _name, .type = _type, .addr = _addr, .size = _size }

#if __SIZEOF_LONG__ != __SIZEOF_PADDR__
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks strange to have 2 macros register_phys_mem() and register_phys_mem_ul().
Can't use something like:

#if __SIZEOF_LONG__ == __SIZEOF_PADDR__
#define __PHYSMEM_LOC(_addr, _size) \
			.addr = (_addr), .size = (_size),
#else
#define __PHYSMEM_LOC(_addr, _size) \
			.lo_addr = (_addr), .lo_size = (_size),
#endif

#define __register_memory2(_name, _type, _addr, _size, _section, _id) \
	static const struct core_mmu_phys_mem __phys_mem_ ## _id \
		__used __section(_section) = \
 		{ .name = _name, .type = _type, __PHYSMEM_LOC(_addr, _size) },

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need both the normal and the _ul version. The normal is needed when supplying 64-bit addresses from a proper constant, while the _ul version must be used when initializing from variables provided by the link script.

It's not beautiful and have some sharp corners, but I can't find a way around it.

#define __register_memory2_ul(_name, _type, _addr, _size, _section, _id) \
static const struct core_mmu_phys_mem __phys_mem_ ## _id \
__used __section(_section) = \
{ .name = _name, .type = _type, .lo_addr = _addr, \
.lo_size = _size }
#else
#define __register_memory2_ul(_name, _type, _addr, _size, _section, _id) \
__register_memory2(_name, _type, _addr, _size, _section, _id)
#endif

#define __register_memory1(name, type, addr, size, section, id) \
__register_memory2(name, type, addr, size, #section, id)

#define __register_memory1_ul(name, type, addr, size, section, id) \
__register_memory2_ul(name, type, addr, size, #section, id)

#define register_phys_mem(type, addr, size) \
__register_memory1(#addr, (type), (addr), (size), \
phys_mem_map_section, __COUNTER__)

#define register_phys_mem_ul(type, addr, size) \
__register_memory1_ul(#addr, (type), (addr), (size), \
phys_mem_map_section, __COUNTER__)

#define register_sdp_mem(addr, size) \
__register_memory1(#addr, MEM_AREA_SDP_MEM, (addr), (size), \
phys_sdp_mem_section, __COUNTER__)
Expand Down
20 changes: 10 additions & 10 deletions core/arch/arm/mm/core_mmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,12 @@ register_sdp_mem(CFG_TEE_SDP_MEM_BASE, CFG_TEE_SDP_MEM_SIZE);
#endif

#ifdef CFG_CORE_RWDATA_NOEXEC
register_phys_mem(MEM_AREA_TEE_RAM_RX, VCORE_UNPG_RX_PA, VCORE_UNPG_RX_SZ);
register_phys_mem(MEM_AREA_TEE_RAM_RO, VCORE_UNPG_RO_PA, VCORE_UNPG_RO_SZ);
register_phys_mem(MEM_AREA_TEE_RAM_RW, VCORE_UNPG_RW_PA, VCORE_UNPG_RW_SZ);
register_phys_mem_ul(MEM_AREA_TEE_RAM_RX, VCORE_UNPG_RX_PA, VCORE_UNPG_RX_SZ);
register_phys_mem_ul(MEM_AREA_TEE_RAM_RO, VCORE_UNPG_RO_PA, VCORE_UNPG_RO_SZ);
register_phys_mem_ul(MEM_AREA_TEE_RAM_RW, VCORE_UNPG_RW_PA, VCORE_UNPG_RW_SZ);
#ifdef CFG_WITH_PAGER
register_phys_mem(MEM_AREA_TEE_RAM_RX, VCORE_INIT_RX_PA, VCORE_INIT_RX_SZ);
register_phys_mem(MEM_AREA_TEE_RAM_RO, VCORE_INIT_RO_PA, VCORE_INIT_RO_SZ);
register_phys_mem_ul(MEM_AREA_TEE_RAM_RX, VCORE_INIT_RX_PA, VCORE_INIT_RX_SZ);
register_phys_mem_ul(MEM_AREA_TEE_RAM_RO, VCORE_INIT_RO_PA, VCORE_INIT_RO_SZ);
#endif
#else
register_phys_mem(MEM_AREA_TEE_RAM, CFG_TEE_RAM_START, CFG_TEE_RAM_PH_SIZE);
Expand Down Expand Up @@ -269,8 +269,8 @@ static void check_phys_mem_is_outside(struct core_mmu_phys_mem *start,
for (n = 0; n < nelems; n++) {
if (!core_is_buffer_outside(start[n].addr, start[n].size,
map->pa, map->size)) {
EMSG(
"Non-sec mem (%#" PRIxPA ":%#zx) overlaps map (type %d %#" PRIxPA ":%#zx)",
EMSG("Non-sec mem (%#" PRIxPA ":%#" PRIxPASZ
") overlaps map (type %d %#" PRIxPA ":%#zx)",
start[n].addr, start[n].size,
map->type, map->pa, map->size);
panic();
Expand Down Expand Up @@ -508,7 +508,7 @@ static void add_phys_mem(struct tee_mmap_region *memory_map, size_t num_elems,
{
size_t n = 0;
paddr_t pa;
size_t size;
paddr_size_t size;

/*
* If some ranges of memory of the same type do overlap
Expand All @@ -520,7 +520,7 @@ static void add_phys_mem(struct tee_mmap_region *memory_map, size_t num_elems,
* mapped as both secure and non-secure. This will probably not
* happen often in practice.
*/
DMSG("%s type %s 0x%08" PRIxPA " size 0x%08zx",
DMSG("%s type %s 0x%08" PRIxPA " size 0x%08" PRIxPASZ,
mem->name, teecore_memtype_name(mem->type), mem->addr, mem->size);
while (true) {
if (n >= (num_elems - 1)) {
Expand Down Expand Up @@ -1051,7 +1051,7 @@ static void *map_pa2va(struct tee_mmap_region *map, paddr_t pa)
if (!pa_is_in_map(map, pa))
return NULL;

return (void *)(map->va + pa - map->pa);
return (void *)(vaddr_t)(map->va + pa - map->pa);
}

/*
Expand Down
17 changes: 15 additions & 2 deletions core/arch/arm/mm/core_mmu_lpae.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,11 @@
#include <compiler.h>
#include <inttypes.h>
#include <keep.h>
#include <kernel/linker.h>
#include <kernel/misc.h>
#include <kernel/panic.h>
#include <kernel/tlb_helpers.h>
#include <kernel/thread.h>
#include <kernel/tlb_helpers.h>
#include <mm/core_memprot.h>
#include <mm/core_memprot.h>
#include <mm/pgt_cache.h>
Expand Down Expand Up @@ -454,9 +455,21 @@ static unsigned int calc_physical_addr_size_bits(uint64_t max_addr)
return TCR_PS_BITS_4GB;
}

void core_init_mmu_tables(struct tee_mmap_region *mm)
static paddr_t get_nsec_ddr_max_pa(void)
{
paddr_t max_pa = 0;
const struct core_mmu_phys_mem *mem;

for (mem = &__start_phys_nsec_ddr_section;
mem < &__end_phys_nsec_ddr_section; mem++)
max_pa = MAX(max_pa, mem->addr + mem->size);

return max_pa;
}

void core_init_mmu_tables(struct tee_mmap_region *mm)
{
paddr_t max_pa = get_nsec_ddr_max_pa();
uint64_t max_va = 0;
size_t n;

Expand Down
4 changes: 2 additions & 2 deletions core/arch/arm/mm/mobj.c
Original file line number Diff line number Diff line change
Expand Up @@ -496,8 +496,8 @@ static void *mobj_mapped_shm_get_va(struct mobj *mobj, size_t offst)
struct mobj_reg_shm *reg_shm =
to_mobj_reg_shm(mobj_mapped_shm->reg_shm);

return (void *)(tee_mm_get_smem(mobj_mapped_shm->mm_entry) + offst +
reg_shm->page_offset);
return (void *)(vaddr_t)(tee_mm_get_smem(mobj_mapped_shm->mm_entry) +
offst + reg_shm->page_offset);
}

static void mobj_mapped_shm_free(struct mobj *mobj)
Expand Down
6 changes: 4 additions & 2 deletions core/arch/arm/mm/tee_mmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -687,7 +687,8 @@ static TEE_Result tee_mmu_user_va2pa_attr(const struct user_ta_ctx *utc,
if (res != TEE_SUCCESS)
return res;

*pa = (paddr_t)ua - utc->mmu->regions[n].va + p;
*pa = (paddr_t)(vaddr_t)ua -
utc->mmu->regions[n].va + p;
}
if (attr)
*attr = utc->mmu->regions[n].attr;
Expand Down Expand Up @@ -722,7 +723,8 @@ TEE_Result tee_mmu_user_pa2va_helper(const struct user_ta_ctx *utc,

if (core_is_buffer_inside(pa, 1, p,
utc->mmu->regions[n].size)) {
*va = (void *)(pa - p + utc->mmu->regions[n].va);
*va = (void *)(vaddr_t)(pa - p +
utc->mmu->regions[n].va);
return TEE_SUCCESS;
}
}
Expand Down
5 changes: 5 additions & 0 deletions core/arch/arm/plat-vexpress/conf.mk
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,8 @@ CFG_SE_API ?= y
CFG_SE_API_SELF_TEST ?= y
CFG_PCSC_PASSTHRU_READER_DRV ?= y
endif

ifeq ($(PLATFORM_FLAVOR),fvp)
# DRAM1 is defined above 4G
$(call force,CFG_CORE_LARGE_PHYS_ADDR,y)
endif
3 changes: 3 additions & 0 deletions core/arch/arm/plat-vexpress/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ register_phys_mem(MEM_AREA_IO_SEC, SECRAM_BASE, SECRAM_COHERENT_SIZE);
#endif
register_phys_mem(MEM_AREA_IO_SEC, CONSOLE_UART_BASE, PL011_REG_SIZE);
register_nsec_ddr(DRAM0_BASE, DRAM0_SIZE);
#ifdef DRAM1_BASE
register_nsec_ddr(DRAM1_BASE, DRAM1_SIZE);
#endif

const struct thread_handlers *generic_boot_get_handlers(void)
{
Expand Down
3 changes: 3 additions & 0 deletions core/arch/arm/plat-vexpress/platform_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,9 @@
#define DRAM0_BASE 0x80000000
#define DRAM0_SIZE 0x7f000000

#define DRAM1_BASE 0x880000000UL
#define DRAM1_SIZE 0x180000000UL

#define TZCDRAM_BASE 0xff000000
#define TZCDRAM_SIZE 0x01000000

Expand Down
2 changes: 1 addition & 1 deletion core/include/drivers/gic.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ struct gic_data {
* then used by the other functions.
*/

void gic_init(struct gic_data *gd, paddr_t gicc_base, paddr_t gicd_base);
void gic_init(struct gic_data *gd, vaddr_t gicc_base, vaddr_t gicd_base);
/* initial base address only */
void gic_init_base_addr(struct gic_data *gd, vaddr_t gicc_base,
vaddr_t gicd_base);
Expand Down
13 changes: 12 additions & 1 deletion lib/libutils/ext/include/types_ext.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,18 @@ typedef uintptr_t uaddr_t;
typedef uintptr_t vaddr_t;
#define PRIxVA PRIxPTR

#if defined(__ILP32__) && defined(CFG_CORE_LARGE_PHYS_ADDR)
typedef uint64_t paddr_t;
typedef uint64_t paddr_size_t;
#define PRIxPA PRIx64
#define PRIxPASZ PRIx64
#define __SIZEOF_PADDR__ 8
#else
typedef uintptr_t paddr_t;
#define PRIxPA PRIxPTR
typedef uintptr_t paddr_size_t;
#define PRIxPA PRIxPTR
#define PRIxPASZ PRIxPTR
#define __SIZEOF_PADDR__ __SIZEOF_POINTER__
#endif

#endif /* TYPES_EXT_H */
4 changes: 4 additions & 0 deletions mk/config.mk
Original file line number Diff line number Diff line change
Expand Up @@ -270,3 +270,7 @@ CFG_CORE_CLUSTER_SHIFT ?= 2
# report to Normal World that it support dynamic SHM. But, nevertheles it
# will accept dynamic SHM buffers.
CFG_DYN_SHM_CAP ?= y

# Enables support for larger physical addresses, that is, it will define
# paddr_t as a 64-bit type.
CFG_CORE_LARGE_PHYS_ADDR ?= n