#include #include #include #include #include #include #include #include #include // System registers #define SCTLR_EL1_WXN (1 << 19) #define SCTLR_EL1_I (1 << 12) #define SCTLR_EL1_C (1 << 2) #define SCTLR_EL1_A (1 << 1) #define SCTLR_EL1_M (1 << 0) #define TCR_EL1_IPS__SHIFT 32 #define TCR_EL1_IPS__MASK (7UL << 32) #define TCR_EL1_IPS_4GB 0UL #define TCR_EL1_IPS_64GB 1UL #define TCR_EL1_IPS_1TB 2UL #define TCR_EL1_EPD1 (1 << 23) #define TCR_EL1_A1 (1 << 22) #define TCR_EL1_TG0__SHIFT 14 #define TCR_EL1_TG0__MASK (3 << 14) #define TCR_EL1_TG0_64KB 1 #define TCR_EL1_SH0__SHIFT 12 #define TCR_EL1_SH0__MASK (3 << 12) #define TCR_EL1_SH0_INNER 3 #define TCR_EL1_ORGN0__SHIFT 10 #define TCR_EL1_ORGN0__MASK (3 << 10) #define TCR_EL1_ORGN0_WR_BACK_ALLOCATE 1 #define TCR_EL1_ORGN0_WR_BACK 3 #define TCR_EL1_IRGN0__SHIFT 8 #define TCR_EL1_IRGN0__MASK (3 << 8) #define TCR_EL1_IRGN0_WR_BACK_ALLOCATE 1 #define TCR_EL1_IRGN0_WR_BACK 3 #define TCR_EL1_EPD0 (1 << 7) #define TCR_EL1_T0SZ__SHIFT 0 #define TCR_EL1_T0SZ__MASK (0x3f << 0) #define TCR_EL1_T0SZ_4GB 32 #define TCR_EL1_T0SZ_64GB 28 #define TCR_EL1_T0SZ_128GB 27 static void enable_mmu(void) { uint64_t mair_el1 = 0xff << ATTR_INDX_NORMAL * 8 // inner/outer write-back non-transient, allocating | 0x04 << ATTR_INDX_DEVICE * 8 // Device-nGnRE | 0x00 << ATTR_INDX_COHERENT * 8; // Device-nGnRnE __asm__ __volatile("msr mair_el1, %0" : : "r"(mair_el1)); __asm__ __volatile("msr ttbr0_el1, %0" : : "r"(gilbraltar_translation_table_base())); uint64_t tcr_el1; __asm__ __volatile("mrs %0, tcr_el1" : "=r"(tcr_el1)); tcr_el1 &= ~(TCR_EL1_IPS__MASK | TCR_EL1_A1 | TCR_EL1_TG0__MASK | TCR_EL1_SH0__MASK | TCR_EL1_ORGN0__MASK | TCR_EL1_IRGN0__MASK | TCR_EL1_EPD0 | TCR_EL1_T0SZ__MASK); tcr_el1 |= TCR_EL1_EPD1 | TCR_EL1_TG0_64KB << TCR_EL1_TG0__SHIFT | TCR_EL1_SH0_INNER << TCR_EL1_SH0__SHIFT | TCR_EL1_ORGN0_WR_BACK_ALLOCATE << TCR_EL1_ORGN0__SHIFT | TCR_EL1_IRGN0_WR_BACK_ALLOCATE << TCR_EL1_IRGN0__SHIFT | TCR_EL1_IPS_1TB << TCR_EL1_IPS__SHIFT | TCR_EL1_T0SZ_128GB << TCR_EL1_T0SZ__SHIFT; __asm__ __volatile("msr tcr_el1, %0" : : "r"(tcr_el1)); uint64_t sctlr_el1; __asm__ __volatile("mrs %0, sctlr_el1" : "=r"(sctlr_el1)); sctlr_el1 &= ~(SCTLR_EL1_WXN | SCTLR_EL1_A); sctlr_el1 |= SCTLR_EL1_I | SCTLR_EL1_C | SCTLR_EL1_M; __asm__ __volatile("msr sctlr_el1, %0" : : "r"(sctlr_el1) : "memory"); } static uintptr_t sbrk_start; static uintptr_t sbrk_end; static uintptr_t sbrk_cur; static uintptr_t sbrk_guard_size; void *sbrk(intptr_t increment) { uintptr_t prev, brk; uintptr_t max = (uintptr_t)&prev - sbrk_guard_size; prev = brk = sbrk_cur; brk += increment; if (brk >= max || brk >= sbrk_end || brk < sbrk_start) return ((void *)(-1)); sbrk_cur = brk; return ((void *)prev); } #define PROPTAG_GET_BOARD_REVISION 0x00010002 struct __attribute__((packed)) board_revision { uint32_t id; uint32_t value_len; uint32_t param_len; uint32_t revision; }; void gilbraltar_memory_init(void) { size_t rsv = ARM_MEM_SIZE - MEM_HEAP_START - PAGE_RESERVE; gilbraltar_pager_init(MEM_HEAP_START + rsv, PAGE_RESERVE); gilbraltar_translation_table_init(ARM_MEM_SIZE); enable_mmu(); instruction_sync_barrier(); struct board_revision b; if (!gilbraltar_get_tag(PROPTAG_GET_BOARD_REVISION, &b, sizeof(b), 4)) { gilbraltar_log(ERROR, "Impossible to retrieve the board revision.\r\n"); abort(); } assert(b.revision & (1 << 23)); // new revision scheme size_t ram_size = 256 << ((b.revision >> 20) & 7); size_t heap_size = (ram_size - 1024) * MEGABYTE; heap_size = (heap_size > (8 * GIGABYTE) - GIGABYTE) ? (8 * GIGABYTE) - GIGABYTE : heap_size; sbrk_guard_size = (heap_size >= MEGABYTE) ? MEGABYTE : (heap_size / 2); sbrk_start = sbrk_cur = GIGABYTE; sbrk_end = GIGABYTE + heap_size; } void gilbraltar_get_heap(uintptr_t *start, uintptr_t *end) { *start = sbrk_start; *end = sbrk_end; } #include #define ABORT_ON_ASSERT_FAILURE 0 #undef WIN32 #define HAVE_MMAP 0 #define HAVE_MREMAP 0 #define MMAP_CLEARS 0 #define NO_MALLOC_STATS 1 #define LACKS_FCNTL_H #define LACKS_SYS_PARAM_H #define LACKS_SYS_MMAN_H #define LACKS_STRINGS_H #define LACKS_SYS_TYPES_H #define LACKS_SCHED_H #define LACKS_TIME_H #define MALLOC_FAILURE_ACTION #define USE_LOCKS 0 // TODO(dinosaure): for multicore. #define STRUCT_MALLINFO_DECLARED 1 #define FOOTERS 1 /* disable null-pointer-arithmetic warning on clang */ #if defined(__clang__) && __clang_major__ >= 6 #pragma clang diagnostic ignored "-Wnull-pointer-arithmetic" #endif /* inline the dlmalloc implementation into this module */ #include "dlmalloc.i"