This commit is contained in:
Calascibetta Romain 2024-12-23 01:46:17 +01:00
parent e7ccf2e72a
commit 40cc5affc0
45 changed files with 1591 additions and 129 deletions

View file

@ -50,7 +50,8 @@ LDFLAGS += -nostdlib -static -Wl,--no-warn-rwx-segments \
-Wl,--start-group -L . -lgilbraltar -L nolibc -lnolibc -L openlibm -lopenlibm -lgcc -Wl,--end-group
SRCS= kernel.c timer.c led.c interrupt_handler.c exception_handler.c \
mbox.c clock.c crt.c serial.c log.c
mbox.c clock.c crt.c serial.c log.c power.c tag.c coherent_page.c dtb.c \
synchronize.c spinlock.c memory.c pager.c translation_table.c
ASMS= startup.S exception_stub.S
@ -116,5 +117,5 @@ test02.img: libgilbraltar.a nolibc/libnolibc.a openlibm/libopenlibm.a test/test0
test03.img: libgilbraltar.a nolibc/libnolibc.a openlibm/libopenlibm.a test/test03.o
@echo "LD ${@:img=elf}"
@$(LD) test/${@:img=o} -o ${@:img=elf} $(LDFLAGS) -Wl,-T gilbraltar.ld
@$(LD) test/${@:img=o} -o ${@:img=elf} $(LDFLAGS) -Wl,-Map ${@:img=map} -Wl,-T gilbraltar.ld
@$(OBJCOPY) ${@:img=elf} -O binary $@

44
clock.c
View file

@ -1,41 +1,31 @@
#include <mem.h>
#include <assert.h>
#include <log.h>
#include <mbox.h>
#include <mem.h>
#include <tag.h>
#define PROPTAG_GET_CLOCK_RATE 0x00030002
#define PROPTAG_GET_CLOCK_RATE 0x00030002
#define PROPTAG_GET_CLOCK_RATE_MEASURED 0x00030047
uint32_t gilbraltar_get_clock(uint32_t cid) {
uint32_t proptag0[] __attribute__ ((aligned(16))) =
{
8.4,
CODE_REQUEST,
PROPTAG_GET_CLOCK_RATE,
4*4,
1*4,
cid,
0,
PROPTAG_END
};
uint32_t gilbraltar_get_rate_of_clock(uint32_t cid) {
uint32_t proptag0[] __attribute__((aligned(16))) = {
8 * 4, CODE_REQUEST, PROPTAG_GET_CLOCK_RATE, 2 * 4, 1 * 4, cid,
0, PROPTAG_END};
gilbraltar_mbox_write_read((uintptr_t) &proptag0);
for (int i = 0; i < sizeof(proptag0) / 4; i++)
gilbraltar_log(DEBUG, "%08lx[%d]: %04x\r\n", (uintptr_t)proptag0, i,
proptag0[i]);
assert(gilbraltar_mbox_write_read((uintptr_t)&proptag0));
if (proptag0[6] != 0)
return proptag0[6];
uint32_t proptag1[] __attribute__ ((aligned(16))) =
{
8*4,
CODE_REQUEST,
PROPTAG_GET_CLOCK_RATE_MEASURED,
4*4,
1*4,
cid,
0,
PROPTAG_END
};
uint32_t proptag1[] __attribute__((aligned(16))) = {
8 * 4, CODE_REQUEST, PROPTAG_GET_CLOCK_RATE_MEASURED, 2 * 4, 1 * 4, cid,
0, PROPTAG_END};
gilbraltar_mbox_write_read((uintptr_t) &proptag1);
assert(gilbraltar_mbox_write_read((uintptr_t)&proptag1));
return proptag1[6];
}

13
coherent_page.c Normal file
View file

@ -0,0 +1,13 @@
#include <coherent_page.h>
#include <stdlib.h>
uintptr_t get_coherent_page(enum coherent_page slot) {
switch (slot) {
case PROP_MAILBOX:
return (MEM_COHERENT_REGION);
case GPIO_VIRTBUF:
return (MEM_COHERENT_REGION + PAGE_SIZE);
}
abort();
}

6
crt.c
View file

@ -34,11 +34,13 @@ uintptr_t SSP_GUARD_SYMBOL = 0x00deadbeef0d0a00;
* message and abort, taking care to make minimal use of the stack.
*/
static const char stack_chk_fail_message[] =
"ABORT: Stack corruption detected\n";
"ABORT: Stack corruption detected\r\n";
extern void uart_puts(const char *str);
extern void gilbraltar_serial_puts(const char *str);
__attribute__((noreturn)) void SSP_FAIL_SYMBOL(void) {
gilbraltar_serial_puts(stack_chk_fail_message);
for (;;)
;
}

48
dtb.c Normal file
View file

@ -0,0 +1,48 @@
#include <endian.h>
#include <log.h>
#include <stdbool.h>
#include <stdint.h>
#define ARM_DTB_PTR32 0x000000f8
struct __attribute__((packed)) header {
uint32_t magic;
#define DTB_MAGIC 0xd00dfeed
uint32_t total_size;
#define DTB_MAX_SIZE 0x100000
uint32_t off_dt_strt;
uint32_t off_dt_strs;
uint32_t off_mem_rsvmap;
uint32_t version;
#define DTB_VERSION 17
uint32_t last_comp_version;
#define DTB_LAST_COMP_VERSION 16
uint32_t boot_cpuid_phys;
uint32_t size_dt_strs;
uint32_t size_dt_strt;
};
static const struct header *hdr = 0;
bool gilbraltar_dtb_init(void) {
uint32_t *volatile ptr = (uint32_t *volatile)ARM_DTB_PTR32;
const void *dtb = (const void *)(uintptr_t)*ptr;
hdr = (const struct header *)dtb;
if (be32toh(hdr->magic) != DTB_MAGIC ||
be32toh(hdr->last_comp_version) != DTB_LAST_COMP_VERSION)
return false;
uint32_t total_size = be32toh(hdr->total_size);
if (total_size < sizeof(struct header) || total_size > DTB_MAX_SIZE)
return false;
gilbraltar_log(INFO, " dtb magic : %04x\r\n", be32toh(hdr->magic));
gilbraltar_log(INFO, "dtb version : %d\r\n", be32toh(hdr->last_comp_version));
gilbraltar_log(INFO, " dtb size : %d byte(s)\r\n",
be32toh(hdr->total_size));
return true;
}

View file

@ -1,6 +1,31 @@
#include <exception_handler.h>
#include <log.h>
#include <synchronize.h>
static const char *names[] = {"Unexpected exception", "Synchronous exception",
"System error"};
void gilbraltar_exception_handler(uint64_t exn, struct frame *frame) {
enable_fiqs();
uint64_t sp = frame->sp_el0;
if ((frame->spsr_el1 & 0xf) == 0x05)
sp = frame->sp_el1;
uint64_t ec = (frame->esr_el1 >> 26) & 0x3f;
uint64_t iss = frame->esr_el1 & 0x1ffffff;
uint64_t far = 0;
if ((0x20 <= ec && ec <= 0x25) || (0x34 <= ec && ec <= 0x35))
far = frame->far_el1;
gilbraltar_log(ERROR,
"%s (pc: 0x%lx, ec: 0x%lx, iss: 0x%lx, far: 0x%lx, sp: 0x%lx, "
"lr: 0x%lx, spsr: 0x%lx)\r\n",
names[exn], frame->elr_el1, ec, iss, far, sp, frame->x30,
frame->spsr_el1);
while (1)
__asm__ __volatile("wfi");
}

View file

@ -10,14 +10,26 @@
#define ARM_SYSTIMER_CHI (ARM_SYSTIMER_BASE + 0x08)
// Interrupt Controller
#define ARM_IC_BASE (ARM_IO_BASE + 0xb000)
#define ARM_IC_BASE (ARM_IO_BASE + 0xb000)
#define ARM_IC_FIQ_CONTROL (ARM_IO_BASE + 0x20c)
// General Purpose I/O #2
#define ARM_GPIO2_BASE (ARM_IO_BASE + 0x1517c00)
#define ARM_GPIO2_BASE (ARM_IO_BASE + 0x1517c00)
#define ARM_GPIO2_DATA0 (ARM_GPIO2_BASE + 0x04)
#define ARM_GPIO2_DATA0 (ARM_GPIO2_BASE + 0x04)
#define ARM_GPIO2_IODIR0 (ARM_GPIO2_BASE + 0x08)
// Power Manager
#define ARM_PM_BASE (ARM_IO_BASE + 0x1200000)
#define ARM_PM_RSTC (ARM_PM_BASE + 0x1c)
#define ARM_PM_RSTS (ARM_PM_BASE + 0x20)
#define ARM_PM_WDOG (ARM_PM_BASE + 0x24)
#define ARM_PM_PADS0 (ARM_PM_BASE + 0x2c)
#define ARM_PM_PADS1 (ARM_PM_BASE + 0x30)
#define ARM_PM_PADS2 (ARM_PM_BASE + 0x34)
#define ARM_PM_PASSWD (0x5a << 24)
#endif

8
include/board.h Normal file
View file

@ -0,0 +1,8 @@
#ifndef __GILBRALTAR_BOARD__
#define __GILBRALTAR_BOARD__
#include <stdint.h>
uint32_t gilbraltar_get_board(void);
#endif

View file

@ -1,6 +1,8 @@
#ifndef __GILBRALTAR_CLOCK__
#define __GILBRALTAR_CLOCK__
uint32_t gilbraltar_get_clock(uint32_t);
#include <stdint.h>
uint32_t gilbraltar_get_rate_of_clock(uint32_t);
#endif

12
include/coherent_page.h Normal file
View file

@ -0,0 +1,12 @@
#ifndef __GILBRALTAR_COHERENT_PAGE__
#define __GILBRALTAR_COHERENT_PAGE__
#include <stdbool.h>
#include <stdint.h>
#include <sysconfig.h>
enum coherent_page { PROP_MAILBOX = 0, GPIO_VIRTBUF };
uintptr_t get_coherent_page(enum coherent_page);
#endif

13
include/cpu_aarch64.h Normal file
View file

@ -0,0 +1,13 @@
#ifndef __GILBRALTAR_CPU_AARCH64__
#define __GILBRALTAR_CPU_AARCH64__
#include <stdint.h>
static inline uint64_t cpu_cntpct(void) {
uint64_t val;
__asm__ __volatile("mrs %0, cntpct_el0" : "=r"(val)::);
return (val);
}
#endif

11
include/crt.h Normal file
View file

@ -0,0 +1,11 @@
#include <stdint.h>
extern uintptr_t SSP_GUARD_SYMBOL;
#include <cpu_aarch64.h>
#define READ_CPU_TICKS cpu_cntpct
__attribute__((always_inline)) static inline void crt_init_ssp(void) {
SSP_GUARD_SYMBOL = READ_CPU_TICKS() + (READ_CPU_TICKS() << 32UL);
SSP_GUARD_SYMBOL &= ~(uintptr_t)0xff00;
}

8
include/dtb.h Normal file
View file

@ -0,0 +1,8 @@
#ifndef __GILBRALTAR_DTB__
#define __GILBRALTAR_DTB__
#include <stdbool.h>
bool gilbraltar_dtb_init(void);
#endif

View file

@ -3,28 +3,15 @@
#include <stdint.h>
struct frame {
uint32_t sp_irq;
uint32_t lr_irq;
uint32_t sp_fiq;
uint32_t lr_fiq;
uint32_t r0;
uint32_t r1;
uint32_t r2;
uint32_t r3;
uint32_t r4;
uint32_t r5;
uint32_t r6;
uint32_t r7;
uint32_t r8;
uint32_t r9;
uint32_t r10;
uint32_t r11;
uint32_t r12;
uint32_t sp;
uint32_t lr;
uint32_t spsr;
uint32_t pc;
struct __attribute__((packed)) frame {
uint64_t esr_el1;
uint64_t spsr_el1;
uint64_t x30;
uint64_t elr_el1;
uint64_t sp_el0;
uint64_t sp_el1;
uint64_t far_el1;
uint64_t unused;
};
void gilbraltar_exception_handler(uint64_t, struct frame *);

View file

@ -1,19 +1,14 @@
#ifndef __GILBRALTAR_LOG__
#define __GILBRALTAR_LOG__
#include <stdint.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
enum log_level {
ERROR= 0,
WARN,
INFO,
DEBUG
};
enum log_level { ERROR = 0, WARN, INFO, DEBUG };
size_t gilbraltar_log(enum log_level, const char *fmt, ...)
__attribute__((format (printf, 2, 3)));
__attribute__((format(printf, 2, 3)));
void gilbraltar_log_set(enum log_level);
#endif

View file

@ -4,15 +4,15 @@
#include <bcm.h>
#include <stdint.h>
#define MAILBOX_BASE (ARM_IO_BASE + 0x13880)
#define MAILBOX_BASE (ARM_IO_BASE + 0x13880)
#define MAILBOX0_READ (MAILBOX_BASE + 0x00)
#define MAILBOX0_READ (MAILBOX_BASE + 0x00)
#define MAILBOX0_STATUS (MAILBOX_BASE + 0x18)
#define MAILBOX1_WRITE (MAILBOX_BASE + 0x20)
#define MAILBOX1_WRITE (MAILBOX_BASE + 0x20)
#define MAILBOX1_STATUS (MAILBOX_BASE + 0x38)
#define MAILBOX_STATUS_EMPTY 0x40000000
#define MAILBOX_STATUS_FULL 0x80000000
#define MAILBOX_STATUS_FULL 0x80000000
#define BCM_MAILBOX_PROP_OUT 8

View file

@ -20,4 +20,8 @@ static inline void write32(uintptr_t addr, uint32_t v) {
*(uint32_t volatile *)addr = v;
}
#define data_sync_barrier() __asm__ __volatile("dsb sy" ::: "memory")
#define data_mem_barrier() __asm__ __volatile("dmb sy" ::: "memory")
#define instruction_sync_barrier() __asm__ __volatile("isb" ::: "memory")
#endif

6
include/memory.h Normal file
View file

@ -0,0 +1,6 @@
#ifndef __GILBRALTAR_MEMORY__
#define __GILBRALTAR_MEMORY__
void gilbraltar_memory_init(void);
#endif

View file

@ -13,19 +13,18 @@
#define GIGABYTE 0x40000000UL
#endif
#define CORES 4 // must be a power of 2
#define MEM_SIZE (512 * MEGABYTE) // default size
#define GPU_MEM_SIZE (64 * MEGABYTE) // set in config.txt
#define ARM_MEM_SIZE (MEM_SIZE - GPU_MEM_SIZE) // normally overwritten
#define PAGE_SIZE 0x10000 // page size used by us
#define PAGE_SHIFT 16
#define PAGE_MASK ~(0xffff)
#define CORES 4 // must be a power of 2
#define MEM_SIZE (512 * MEGABYTE) // default size
#define GPU_MEM_SIZE (64 * MEGABYTE) // set in config.txt
#define ARM_MEM_SIZE (MEM_SIZE - GPU_MEM_SIZE) // normally overwritten
#define PAGE_SIZE 0x10000LL // page size used by us
#define PAGE_SHIFT 16
#define EXCEPTION_STACK_SIZE 0x8000
#define PAGE_RESERVE (16 * MEGABYTE)
#define PAGE_RESERVE (16 * MEGABYTE)
// Kernel
#define MEM_KERNEL_START 0x80000 // main code starts here
#define MEM_KERNEL_END (MEM_KERNEL_START + KERNEL_MAX_SIZE)
#define MEM_KERNEL_END (MEM_KERNEL_START + KERNEL_MAX_SIZE)
#define MEM_KERNEL_STACK (MEM_KERNEL_END + KERNEL_STACK_SIZE) // expands down
#define MEM_EXCEPTION_STACK \
@ -38,20 +37,26 @@
((MEM_EXCEPTION_STACK_END + 2 * MEGABYTE) & ~(MEGABYTE - 1))
// Heap
#define MEM_HEAP_START GIGABYTE
#define MEM_HEAP_END (8 * GIGABYTE - 1)
#define MEM_HEAP_START (MEM_COHERENT_REGION + 4 * MEGABYTE)
// IRQ & FIC stacks
#define MEM_ABORT_STACK (MEM_KERNEL_STACK + KERNEL_STACK_SIZE * (CORES - 1))
#define MEM_IRQ_STACK (MEM_EXCEPTION_STACK_END + EXCEPTION_STACK_SIZE)
#define MEM_IRQ_STACK (MEM_EXCEPTION_STACK_END + EXCEPTION_STACK_SIZE)
#define MEM_FIQ_STACK \
(MEM_IRQ_STACK + EXCEPTION_STACK_SIZE * (CORES - 1) + EXCEPTION_STACK_SIZE)
// Page table
#define MEM_PAGE_TABLE1 \
(MEM_FIQ_STACK + EXCEPTION_STACK_SIZE * (CORES - 1))
#define MEM_PAGE_TABLE1 (MEM_FIQ_STACK + EXCEPTION_STACK_SIZE * (CORES - 1))
#define PAGE_TABLE1_SIZE 0x4000
#define MEM_PAGE_TABLE1_END (MEM_PAGE_TABLE1 + PAGE_TABLE1_SIZE)
#define MEM_PAGE_TABLE1_END (MEM_PAGE_TABLE1 + PAGE_TABLE1_SIZE)
// I/O memory regions of RaspBerry Pi 5
#define MEM_IOMEM_AXI_START 0x1000000000UL // AXI peripherals
#define MEM_IOMEM_AXI_END 0x101fffffffUL
#define MEM_IOMEM_SOC_START 0x1060000000UL // SoC peripherals
#define MEM_IOMEM_SOC_END 0x107fffffffUL
#define MEM_IOMEM_PCIE_START 0x1f00000000UL // PCI Bus 0000:01
#define MEM_IOMEM_PCIE_END 0x1f1fffffffUL
#endif

12
include/pager.h Normal file
View file

@ -0,0 +1,12 @@
#ifndef __GILBRALTAR_PAGER__
#define __GILBRALTAR_PAGER__
#include <stddef.h>
#include <stdint.h>
void gilbraltar_pager_init(uintptr_t, size_t);
size_t gilbraltar_pager_free_space(void);
void *gilbraltar_palloc(void);
void gilbraltar_pager_free(void *);
#endif

7
include/power.h Normal file
View file

@ -0,0 +1,7 @@
#ifndef __GILBRALTAR_POWER__
#define __GILBRALTAR_POWER__
void reboot(void);
void poweroff(void);
#endif

View file

@ -2,22 +2,22 @@
#define __GILBRALTAR_SERIAL__
#include <bcm.h>
#include <stdint.h>
#include <stddef.h>
#include <stdint.h>
#define ARM_UART0_BASE (ARM_IO_BASE + 0x1001000)
#define ARM_UART0_DR (ARM_UART0_BASE + 0x00)
#define ARM_UART0_FR (ARM_UART0_BASE + 0x18)
#define ARM_UART0_DR (ARM_UART0_BASE + 0x00)
#define ARM_UART0_FR (ARM_UART0_BASE + 0x18)
#define ARM_UART0_IBRD (ARM_UART0_BASE + 0x24)
#define ARM_UART0_FBRD (ARM_UART0_BASE + 0x28)
#define ARM_UART0_LCRH (ARM_UART0_BASE + 0x2c)
#define ARM_UART0_CR (ARM_UART0_BASE + 0x30)
#define ARM_UART0_CR (ARM_UART0_BASE + 0x30)
#define ARM_UART0_IFLS (ARM_UART0_BASE + 0x34)
#define ARM_UART0_IMSC (ARM_UART0_BASE + 0x38)
#define ARM_UART0_RIS (ARM_UART0_BASE + 0x3c)
#define ARM_UART0_MIS (ARM_UART0_BASE + 0x40)
#define ARM_UART0_ICR (ARM_UART0_BASE + 0x44)
#define ARM_UART0_RIS (ARM_UART0_BASE + 0x3c)
#define ARM_UART0_MIS (ARM_UART0_BASE + 0x40)
#define ARM_UART0_ICR (ARM_UART0_BASE + 0x44)
void gilbraltar_serial_init(void);
void gilbraltar_serial_send(uint8_t);

11
include/spinlock.h Normal file
View file

@ -0,0 +1,11 @@
#ifndef __GILBRALTAR_SPINLOCK__
#define __GILBRALTAR_SPINLOCK__
#include <stdint.h>
#include <synchronize.h>
void gilbraltar_spinlock_init(void);
void gilbraltar_spinlock_acquire(enum level, uint32_t *);
void gilbraltar_spinlock_release(enum level, uint32_t *);
#endif

14
include/synchronize.h Normal file
View file

@ -0,0 +1,14 @@
#ifndef __GILBRALTAR_SYNCHRONIZE__
#define __GILBRALTAR_SYNCHRONIZE__
#define enable_fiqs() __asm__ __volatile("msr DAIFClr, #1")
#define disable_fiqs() __asm__ __volatile("msr DAIFSet, #1")
#define enable_irqs() __asm__ __volatile("msr DAIFClr, #2")
#define disable_irqs() __asm__ __volatile("msr DAIFSet, #2")
enum level { TASK, IRQ, FIQ };
void gilbraltar_enter_critical(enum level);
void gilbraltar_leave_critical(void);
#endif

View file

@ -8,7 +8,7 @@
* value. This value must be a multiple of 16 KByte.
*/
#ifndef KERNEL_MAX_SIZE
#define KERNEL_MAX_SIZE (6 * MEGABYTE)
#define KERNEL_MAX_SIZE (2 * MEGABYTE)
#endif
/* KERNEL_STACK_SIZE is the size of the stack set on startup for the main

View file

@ -1,10 +1,16 @@
#ifndef __GILBRALTAR_TAG__
#define __GILBRALTAR_TAG__
#define CODE_REQUEST 0x00000000
#include <stdbool.h>
#include <stddef.h>
#define CODE_REQUEST 0x00000000
#define CODE_RESPONSE_SUCCESS 0x80000000
#define CODE_RESPONSE_FAILURE 0x80000001
#define PROPTAG_END 0x00000000
#define PROPTAG_END 0x00000000
bool gilbraltar_get_tags(void *, size_t);
bool gilbraltar_get_tag(uint32_t, void *, size_t, size_t);
#endif

112
include/translation_table.h Normal file
View file

@ -0,0 +1,112 @@
#ifndef __GILBRALTAR_TRANSITION_TABLE__
#define __GILBRALTAR_TRANSITION_TABLE__
#include <stddef.h>
#include <stdint.h>
#define ARMV8MMU_TABLE_ENTRIES 8192
// index into MAIR_EL1 register
#define ATTR_INDX_NORMAL 0
#define ATTR_INDX_DEVICE 1
#define ATTR_INDX_COHERENT 2
// Level 2
struct __attribute__((packed)) TARMV8MMU_LEVEL2_TABLE_DESCRIPTOR {
uint64_t value11 : 2, // set to 3
ignored1 : 14, // set to 0
table_addr : 32, // table base [47:16]
reserved0 : 4, // set to 0
ignored2 : 7, // set to 0
pxn_table : 1, // set to 0
uxn_table : 1, // set to 0
ap_table : 2,
#define AP_TABLE_ALL_ACCESS 0
ns_table : 1 // RES0, set to 0
;
};
#define ARMV8MMUL2TABLEADDR(addr) (((addr) >> 16) & 0xffffffff)
#define ARMV8MMUL2TABLEPTR(table) ((void *)((table) << 16))
struct __attribute__((packed)) TARMV8MMU_LEVEL2_BLOCK_DESCRIPTOR {
uint64_t value01 : 2, // set to 1
// lower attributes : 10,
attr_indx : 3, // [2:0], see MAIR_EL1
ns : 1, // RES0, set to 0
ap : 2, // [2:1]
#define ATTR_IB_AP_RW_EL1 0
#define ATTR_IB_AP_RW_ALL 1
#define ATTR_IB_AP_RO_EL1 2
#define ATTR_IB_AP_RO_ALL 3
sh : 2, // [1:0]
#define ATTR_IB_SH_NON_SHAREABLE 0
#define ATTR_IB_SH_OUTER_SHAREABLE 2
#define ATTR_IB_SH_INNER_SHAREABLE 3
af : 1, // set to 1, will fault otherwise
ng : 1, // set to 0
reserved0_1 : 17, // set to 0
output_addr : 19, // [47:29]
reserved0_2 : 4, // set to 0
// upper attributes : 12
continuous : 1, // set to 0
pxn : 1, // set to 0, 1 for device memory
uxn : 1, // set to 1
ignored : 9 // set to 0
;
};
#define ARMV8MMU_LEVEL2_BLOCK_SIZE (512 * MEGABYTE)
#define ARMV8MMUL2BLOCKADDR(addr) (((addr) >> 29) & 0x7ffff)
#define ARMV8MMUL2BLOCKPTR(block) ((void *)((table) << 29))
struct __attribute__((packed)) TARMV8MMU_LEVEL2_INVALID_DESCRIPTOR {
uint64_t value0 : 1, // set to 0
ignored : 63;
};
union __attribute__((packed)) TARMV8MMU_LEVEL2_DESCRIPTOR {
struct TARMV8MMU_LEVEL2_TABLE_DESCRIPTOR table;
struct TARMV8MMU_LEVEL2_BLOCK_DESCRIPTOR block;
struct TARMV8MMU_LEVEL2_INVALID_DESCRIPTOR invalid;
};
// Level 3
struct __attribute__((packed)) TARMV8MMU_LEVEL3_PAGE_DESCRIPTOR {
uint64_t value11 : 2, // set to 3
// lower attributes : 10,
attr_indx : 3, // [2:0], see MAIR_EL1
ns : 1, // RES0, set to 0
ap : 2, // [2:1]
sh : 2, // [1:0]
af : 1, // set to 1, will fault otherwise
ng : 1, // set to 0
reserved0_1 : 4, // set to 0
output_addr : 32, // [47:16]
reserved0_2 : 4, // set to 0
// upper attributes : 12
continuous : 1, // set to 0
pxn : 1, // set to 0, 1 for device memory
uxn : 1, // set to 1
ignored : 9 // set to 0
;
};
#define ARMV8MMU_LEVEL3_PAGE_SIZE 0x10000
#define ARMV8MMUL3PAGEADDR(addr) (((addr) >> 16) & 0xffffffff)
#define ARMV8MMUL3PAGEPTR(page) ((void *)((page) << 16))
struct __attribute__((packed)) TARMV8MMU_LEVEL3_INVALID_DESCRIPTOR {
uint64_t value0 : 1, // set to 0
ignored : 63;
};
union __attribute__((packed)) TARMV8MMU_LEVEL3_DESCRIPTOR {
struct TARMV8MMU_LEVEL3_PAGE_DESCRIPTOR page;
struct TARMV8MMU_LEVEL3_INVALID_DESCRIPTOR invalid;
};
void gilbraltar_translation_table_init(size_t);
uintptr_t gilbraltar_translation_table_base(void);
#endif

View file

@ -1,4 +1,8 @@
#include <log.h>
void gilbraltar_interrupt_handler(void) {
gilbraltar_log(DEBUG, "Interruption.\r\n");
while (1)
__asm__ __volatile("wfi");
}

View file

@ -1,3 +1,78 @@
extern void main(void);
#include <crt.h>
#include <dtb.h>
#include <log.h>
#include <mem.h>
#include <memory.h>
#include <power.h>
#include <serial.h>
#include <stdlib.h>
#include <string.h>
#include <synchronize.h>
#include <tag.h>
void gilbraltar_sysinit(void) { main(); }
extern int main(int, char *const *);
extern char __bss_start;
extern char _etext[];
extern char _end[];
#define PROPTAG_GET_COMMAND_LINE 0x00050001
struct __attribute__((packed)) command_line {
uint32_t id;
uint32_t value_len;
uint32_t param_len;
uint8_t str[2048];
};
static size_t split(char *src, char *dst[], size_t len) {
int i = 0;
char *rem = src;
while (rem != NULL && *rem != '\0' && i < len) {
char *e = strstr(rem, " ");
dst[i++] = rem;
if (e != NULL) {
*e = '\0';
while (*(++e) == ' ')
;
}
rem = e;
}
return (i);
}
void gilbraltar_sysinit(void) {
enable_fiqs();
enable_irqs();
memset(&__bss_start, 0, (uintptr_t)_end - (uintptr_t)__bss_start);
crt_init_ssp();
gilbraltar_serial_init();
gilbraltar_memory_init();
struct command_line p;
char *cmdline[64] = {NULL};
size_t ac = 1;
cmdline[0] = "gilbraltar";
if (!gilbraltar_get_tag(PROPTAG_GET_COMMAND_LINE, &p, sizeof(p), 2048)) {
gilbraltar_log(ERROR, "Impossible to retrieve cmdline.txt.\r\n");
ac = 1;
} else if (p.param_len >= sizeof(p.str)) {
gilbraltar_log(ERROR, "cmdline.txt too long.\r\n");
ac = 1;
} else {
p.str[p.param_len] = '\0';
ac = split((char *)p.str, cmdline + 1, 62);
}
gilbraltar_dtb_init();
int ret = main(ac + 1, cmdline);
gilbraltar_log(DEBUG, "End of program: %3d.", ret);
if (ret == 0)
poweroff();
}

8
log.c
View file

@ -1,8 +1,8 @@
#include <log.h>
#include <serial.h>
#include <stdio.h>
#include <log.h>
static enum log_level actual_level = INFO;
static enum log_level actual_level = DEBUG;
size_t gilbraltar_log(enum log_level level, const char *fmt, ...) {
if (actual_level < level)
@ -27,6 +27,4 @@ size_t gilbraltar_log(enum log_level level, const char *fmt, ...) {
}
}
void gilbraltar_log_set(enum log_level level) {
actual_level = level;
}
void gilbraltar_log_set(enum log_level level) { actual_level = level; }

13
mbox.c
View file

@ -1,18 +1,23 @@
#include <mem.h>
#include <assert.h>
#include <mbox.h>
#include <mem.h>
uint32_t gilbraltar_mbox_write_read(uintptr_t dma) {
assert((dma & 3) == 0); // [dma] must be aligned to 32-bit
dma |= 0xc0000000U;
while (read32(MAILBOX1_STATUS) & MAILBOX_STATUS_FULL);
while (read32(MAILBOX1_STATUS) & MAILBOX_STATUS_FULL)
;
write32(MAILBOX1_WRITE, BCM_MAILBOX_PROP_OUT | dma);
uint32_t result;
do {
while (read32(MAILBOX0_STATUS) & MAILBOX_STATUS_EMPTY);
while (read32(MAILBOX0_STATUS) & MAILBOX_STATUS_EMPTY)
;
result = read32(MAILBOX0_READ);
} while ((result & 0xf) != BCM_MAILBOX_PROP_OUT);
return (result & ~0xf);
return ((result & ~0xf) & 0x3fffffff);
}

97
memory.c Normal file
View file

@ -0,0 +1,97 @@
#include <log.h>
#include <mem.h>
#include <pager.h>
#include <stdint.h>
#include <sysconfig.h>
#include <tag.h>
#include <translation_table.h>
// 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");
}
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_log(INFO, " pager @ 0x%08lx - 0x%08lx\r\n",
MEM_HEAP_START + rsv, MEM_HEAP_START + rsv + PAGE_RESERVE);
gilbraltar_translation_table_init(ARM_MEM_SIZE);
enable_mmu();
instruction_sync_barrier();
}

View file

@ -13,6 +13,6 @@ void _assert_fail(const char *file, const char *line, const char *e)
puts(line);
puts(": Assertion `");
puts(e);
puts("' failed\n");
puts("' failed\r\n");
abort();
}

View file

@ -1,17 +1,17 @@
#include <string.h>
#include <unistd.h>
extern void solo5_console_write(const char *, size_t);
extern void gilbraltar_serial_write(const char *, size_t);
int puts(const char *s)
{
size_t len = strlen(s);
solo5_console_write(s, len);
gilbraltar_serial_write(s, len);
return (int)(len); // We should never have a string length above MAX_INT, do we?
}
int putchar(int chr)
{
solo5_console_write((char *) &chr, 1);
gilbraltar_serial_write((char *) &chr, 1);
return (1);
}

View file

@ -201,6 +201,8 @@ static const double zero= 0.00000000000000000000e+00;
return -y;
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
OLM_DLLEXPORT double
__ieee754_lgamma_r(double x, int *signgamp)
@ -296,3 +298,5 @@ __ieee754_lgamma_r(double x, int *signgamp)
if(hx<0) r = nadj - r;
return r;
}
#pragma GCC diagnostic pop

View file

@ -134,6 +134,8 @@ static const float zero= 0.0000000000e+00;
return -y;
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
OLM_DLLEXPORT float
__ieee754_lgammaf_r(float x, int *signgamp)
@ -229,3 +231,5 @@ __ieee754_lgammaf_r(float x, int *signgamp)
if(hx<0) r = nadj - r;
return r;
}
#pragma GCC diagnostic pop

64
pager.c Normal file
View file

@ -0,0 +1,64 @@
#include <assert.h>
#include <log.h>
#include <spinlock.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <sysconfig.h>
#define FREE_PAGE_MAGIC 0x50474d43
#define PAGE_MASK (PAGE_SIZE - 1)
struct free_page {
uint32_t magic;
struct free_page *next;
};
static uint8_t *pager_next = 0;
static uint8_t *pager_limit = 0;
static struct free_page *free_list = 0;
static uint32_t spinlock = 0;
void gilbraltar_pager_init(uintptr_t base, size_t size) {
pager_next = (uint8_t *)((base + PAGE_SIZE - 1) & ~PAGE_MASK);
pager_limit = (uint8_t *)((base + size) & ~PAGE_MASK);
}
size_t gilbraltar_pager_free_space(void) { return (pager_limit - pager_next); }
void *gilbraltar_palloc(void) {
assert(pager_next != 0);
gilbraltar_spinlock_acquire(IRQ, &spinlock);
gilbraltar_log(DEBUG, "Allocate a new page (actual: %08lx)\r\n",
(uintptr_t)pager_next);
struct free_page *free_page;
if ((free_page = free_list) != 0) {
assert(free_page->magic == FREE_PAGE_MAGIC);
free_list = free_page->next;
free_page->magic = 0;
} else {
free_page = (struct free_page *)pager_next;
pager_next += PAGE_SIZE;
if (pager_next > pager_limit) {
gilbraltar_spinlock_release(IRQ, &spinlock);
gilbraltar_log(ERROR, "Out of page.\r\n");
abort();
}
}
gilbraltar_log(DEBUG, "New page @ %08lx.\r\n", (uintptr_t)free_page);
gilbraltar_spinlock_release(IRQ, &spinlock);
return (free_page);
}
void gilbraltar_pager_free(void *page) {
struct free_page *free_page = (struct free_page *)page;
gilbraltar_spinlock_acquire(IRQ, &spinlock);
free_page->magic = FREE_PAGE_MAGIC;
free_page->next = free_list;
free_list = free_page;
gilbraltar_spinlock_release(IRQ, &spinlock);
}

21
power.c Normal file
View file

@ -0,0 +1,21 @@
#include <bcm.h>
#include <mem.h>
#define PM_RSTC_WRCFG_FULL_RESET 0x20
void reboot(void) {
write32(ARM_PM_WDOG, ARM_PM_PASSWD | 1);
write32(ARM_PM_RSTC, ARM_PM_PASSWD | PM_RSTC_WRCFG_FULL_RESET);
for (;;)
; // wait for reset
}
void poweroff(void) {
__asm__ __volatile("mov x0, %0\n"
"smc #0\n" ::"r"(0x84000008UL) // function code SYSTEM_OFF
);
for (;;)
;
}

View file

@ -1,12 +1,11 @@
#include <stdio.h>
#include <stdarg.h>
#include <stdio.h>
int printf(const char *restrict fmt, ...)
{
int ret;
va_list ap;
va_start(ap, fmt);
ret = vfprintf(stdout, fmt, ap);
va_end(ap);
return ret;
int printf(const char *restrict fmt, ...) {
int ret;
va_list ap;
va_start(ap, fmt);
ret = vfprintf(stdout, fmt, ap);
va_end(ap);
return ret;
}

View file

@ -1,12 +1,45 @@
#include <serial.h>
#include <assert.h>
#include <clock.h>
#include <mem.h>
#include <serial.h>
#include <spinlock.h>
#include <stdbool.h>
#include <stdlib.h>
#include <timer.h>
#define DEFAULT_BAUDRATE 115200
#define SERIAL_BUF_SIZE 0x1000
#define SERIAL_BUF_MASK (SERIAL_BUF_SIZE - 1)
/* NOTE(dinosaure): [serial.c] is usable only **after** the initialization of
* the .bss section:
* memset (&__bss_start, 0, (uintptr_t) _end - (uintptr_t) __bss_start);
*
* TODO(dinosaure): we should probably initialize .bss in [startup.S]
*/
static bool initialized = false;
static uint8_t tx_buf[SERIAL_BUF_SIZE] = {0};
static uint8_t tx_rd = 0;
static uint8_t tx_wr = 0;
// static uint32_t spinlock = 0;
static void flush_tx_buf(void) {
assert(initialized);
while (tx_rd != tx_wr) {
if (!(read32(ARM_UART0_FR) & 0x20)) {
write32(ARM_UART0_DR, tx_buf[tx_rd++]);
tx_rd &= SERIAL_BUF_MASK;
}
}
}
void gilbraltar_serial_init(void) {
if (initialized)
return;
uint32_t baudrate = DEFAULT_BAUDRATE;
uint32_t clock_rate = gilbraltar_get_clock(2);
uint32_t clock_rate = gilbraltar_get_rate_of_clock(2); // UART clock
uint32_t baud16 = baudrate * 16;
uint32_t int_div = clock_rate / baud16;
uint32_t fract_div_2 = (clock_rate % baud16) * 8 / baudrate;
@ -18,30 +51,46 @@ void gilbraltar_serial_init(void) {
write32(ARM_UART0_FBRD, fract_div);
write32(ARM_UART0_LCRH, (1 << 4) | (3 << 5));
write32(ARM_UART0_CR, (1 << 0) | (1 << 8) | (1 << 9));
initialized = true;
flush_tx_buf();
}
void gilbraltar_serial_send(uint8_t chr) {
while (1)
if (!(read32(ARM_UART0_FR) & 0x20)) break;
if (initialized) {
while (1)
if (!(read32(ARM_UART0_FR) & 0x20))
break;
write32(ARM_UART0_DR, chr);
write32(ARM_UART0_DR, chr);
} else {
// gilbraltar_spinlock_acquire(IRQ, &spinlock);
if (((tx_wr + 1) & SERIAL_BUF_MASK) != tx_rd) {
tx_buf[tx_wr++] = chr;
tx_wr &= SERIAL_BUF_MASK;
}
// gilbraltar_spinlock_release(IRQ, &spinlock);
}
}
uint8_t gilbraltar_serial_recv(void) {
while (1)
if (!(read32(ARM_UART0_FR) & 0x10)) break;
if (!(read32(ARM_UART0_FR) & 0x10))
break;
return (read32(ARM_UART0_DR) & 0xff);
}
void gilbraltar_serial_puts(const char *str) {
while (*str) gilbraltar_serial_send(*str++);
while (*str)
gilbraltar_serial_send(*str++);
}
void gilbraltar_serial_putchar(int chr) {
gilbraltar_serial_send(chr & 0xff);
}
void gilbraltar_serial_putchar(int chr) { gilbraltar_serial_send(chr & 0xff); }
void gilbraltar_serial_write(const char *str, size_t len) {
while (len--) gilbraltar_serial_send(*str++);
while (len--)
gilbraltar_serial_send(*str++);
}

45
spinlock.c Normal file
View file

@ -0,0 +1,45 @@
#include <log.h>
#include <stdbool.h>
#include <stdint.h>
#include <synchronize.h>
static bool enabled = false;
void gilbraltar_spinlock_init(void) { enabled = true; }
void gilbraltar_spinlock_acquire(enum level level, uint32_t *s) {
if (level >= IRQ)
gilbraltar_enter_critical(level);
if (enabled) {
gilbraltar_log(DEBUG, "Acquire %08lx.\r\n", (uintptr_t)s);
__asm__ __volatile("mov x1, %0\n"
"mov w2, #1\n"
"prfm pstl1keep, [x1]\n"
"sevl\n"
"1: wfe\n"
"ldaxr w3, [x1]\n"
"cbnz w3, 1b\n"
"stxr w3, w2, [x1]\n"
"cbnz w3, 1b\n"
:
: "r"((uintptr_t)&s[0])
: "x1", "x2", "x3");
gilbraltar_log(DEBUG, "%08lx acquired.\r\n", (uintptr_t)s);
}
}
void gilbraltar_spinlock_release(enum level level, uint32_t *s) {
if (enabled) {
__asm__ __volatile("mov x1, %0\n"
"stlr wzr, [x1]\n"
:
: "r"((uintptr_t)&s[0])
: "x1");
}
if (level >= IRQ)
gilbraltar_leave_critical();
}

58
synchronize.c Normal file
View file

@ -0,0 +1,58 @@
#include <assert.h>
#include <log.h>
#include <mem.h>
#include <stdint.h>
#include <synchronize.h>
#include <sysconfig.h>
#define MAX_CRITICAL_LEVEL 20
static volatile unsigned int critical_level[CORES] = {0};
static volatile uint64_t store[CORES][MAX_CRITICAL_LEVEL];
/* This function can be used to disable IRQ and/or FIQ interrupts for the
* current core.
*/
void gilbraltar_enter_critical(enum level level) {
assert(level == IRQ || level == FIQ);
uint64_t mpidr;
__asm__ __volatile("mrs %0, mpidr_el1" : "=r"(mpidr));
mpidr >>= 8;
unsigned int core = mpidr & (CORES - 1);
uint64_t flags;
__asm__ __volatile("mrs %0, daif" : "=r"(flags));
// if we are already on FIQ, we must not go back to IRQ here
assert(level == FIQ || !(flags & 0x40));
gilbraltar_log(DEBUG, "Disable IRQs and FIQs for %02x, flags:%08lx.\r\n",
core, flags);
__asm__ __volatile("msr DAIFSet, #3"); // disable both IRQ and FIQ
store[core][critical_level[core]++] = flags;
// if we want the IRQ level, keep the FIQ level
if (level == IRQ)
enable_fiqs();
data_mem_barrier();
gilbraltar_log(DEBUG, "Critical zone.\r\n");
}
void gilbraltar_leave_critical() {
uint64_t mpidr;
__asm__ __volatile("mrs %0, mpidr_el1" : "=r"(mpidr));
mpidr >>= 8;
unsigned int core = mpidr & (CORES - 1);
data_mem_barrier();
disable_fiqs();
assert(critical_level[core] > 0);
uint64_t flags = store[core][--critical_level[core]];
gilbraltar_log(DEBUG, "Re-enable flags %08lx for %02x.\r\n", flags, core);
// re-set old flags
__asm__ __volatile("msr daif, %0" ::"r"(flags));
}

68
tag.c Normal file
View file

@ -0,0 +1,68 @@
#include <assert.h>
#include <coherent_page.h>
#include <log.h>
#include <mbox.h>
#include <mem.h>
#include <stdbool.h>
#include <string.h>
#include <tag.h>
struct __attribute__((packed)) property_buf {
uint32_t size;
uint32_t code;
uint8_t tags[0];
};
struct __attribute__((packed)) property_tag {
uint32_t id;
uint32_t value_len;
uint32_t param_len;
};
bool gilbraltar_get_tags(void *tags, size_t len) {
struct property_buf *buf =
(struct property_buf *)get_coherent_page(PROP_MAILBOX);
uintptr_t dma = (uintptr_t)buf;
uint32_t *top = (uint32_t *)(buf->tags + len);
assert((((uintptr_t)buf) & (16 - 1)) == 0);
assert(len >= sizeof(struct property_tag) + sizeof(uint32_t));
uint32_t size = sizeof(struct property_buf) + len + sizeof(uint32_t);
assert((size & 3) == 0);
buf->size = size;
buf->code = CODE_REQUEST;
memcpy(buf->tags, tags, len);
*top = PROPTAG_END;
data_sync_barrier();
if (gilbraltar_mbox_write_read(dma) != dma)
return false;
data_mem_barrier();
if (buf->code != CODE_RESPONSE_SUCCESS)
return false;
memcpy(tags, buf->tags, len);
return true;
}
#define VALUE_LENGTH_RESPONSE (1 << 31)
bool gilbraltar_get_tag(uint32_t tag, void *buf, size_t len, size_t param_len) {
struct property_tag *hdr = buf;
hdr->id = tag;
hdr->value_len = len - sizeof(struct property_tag);
hdr->param_len = param_len & ~VALUE_LENGTH_RESPONSE;
if (!gilbraltar_get_tags(buf, len))
return false;
hdr->param_len &= ~VALUE_LENGTH_RESPONSE;
if (hdr->param_len == 0)
return false;
return true;
}

574
test03.map Normal file
View file

@ -0,0 +1,574 @@
Archive member included to satisfy reference by file (symbol)
./libgilbraltar.a(log.o) test/test03.o (gilbraltar_log)
./libgilbraltar.a(startup.o) (_start)
./libgilbraltar.a(exception_stub.o)
./libgilbraltar.a(startup.o) (VectorTable)
./libgilbraltar.a(kernel.o) ./libgilbraltar.a(startup.o) (gilbraltar_sysinit)
./libgilbraltar.a(interrupt_handler.o)
./libgilbraltar.a(exception_stub.o) (gilbraltar_interrupt_handler)
./libgilbraltar.a(exception_handler.o)
./libgilbraltar.a(exception_stub.o) (gilbraltar_exception_handler)
./libgilbraltar.a(crt.o) ./libgilbraltar.a(log.o) (__stack_chk_guard)
./libgilbraltar.a(serial.o) ./libgilbraltar.a(kernel.o) (gilbraltar_serial_init)
./libgilbraltar.a(power.o) ./libgilbraltar.a(kernel.o) (poweroff)
./libgilbraltar.a(tag.o) ./libgilbraltar.a(kernel.o) (gilbraltar_get_tag)
./libgilbraltar.a(coherent_page.o)
./libgilbraltar.a(tag.o) (get_coherent_page)
./libgilbraltar.a(dtb.o) ./libgilbraltar.a(kernel.o) (gilbraltar_dtb_init)
./libgilbraltar.a(memory.o) ./libgilbraltar.a(kernel.o) (gilbraltar_memory_init)
./libgilbraltar.a(pager.o) ./libgilbraltar.a(memory.o) (gilbraltar_pager_init)
./libgilbraltar.a(translation_table.o)
./libgilbraltar.a(memory.o) (gilbraltar_translation_table_base)
./libgilbraltar.a(mbox.o) ./libgilbraltar.a(tag.o) (gilbraltar_mbox_write_read)
./libgilbraltar.a(clock.o) ./libgilbraltar.a(serial.o) (gilbraltar_get_rate_of_clock)
./libgilbraltar.a(spinlock.o)
./libgilbraltar.a(pager.o) (gilbraltar_spinlock_acquire)
./libgilbraltar.a(synchronize.o)
./libgilbraltar.a(spinlock.o) (gilbraltar_enter_critical)
nolibc/libnolibc.a(assert.o) ./libgilbraltar.a(serial.o) (_assert_fail)
nolibc/libnolibc.a(memcpy.o) ./libgilbraltar.a(tag.o) (memcpy)
nolibc/libnolibc.a(memset.o) ./libgilbraltar.a(kernel.o) (memset)
nolibc/libnolibc.a(strstr.o) ./libgilbraltar.a(kernel.o) (strstr)
nolibc/libnolibc.a(puts.o) nolibc/libnolibc.a(assert.o) (puts)
nolibc/libnolibc.a(vsnprintf.o)
./libgilbraltar.a(log.o) (vsnprintf)
nolibc/libnolibc.a(sysdeps.o)
./libgilbraltar.a(coherent_page.o) (abort)
nolibc/libnolibc.a(memchr.o) nolibc/libnolibc.a(strstr.o) (memchr)
nolibc/libnolibc.a(memcmp.o) nolibc/libnolibc.a(strstr.o) (memcmp)
nolibc/libnolibc.a(strlen.o) nolibc/libnolibc.a(puts.o) (strlen)
nolibc/libnolibc.a(strchr.o) nolibc/libnolibc.a(strstr.o) (strchr)
nolibc/libnolibc.a(strchrnul.o)
nolibc/libnolibc.a(strchr.o) (__strchrnul)
nolibc/libnolibc.a(vfprintf.o)
nolibc/libnolibc.a(vsnprintf.o) (vfprintf)
nolibc/libnolibc.a(ctype.o) nolibc/libnolibc.a(vfprintf.o) (isdigit)
nolibc/libnolibc.a(stubs.o) nolibc/libnolibc.a(vfprintf.o) (strerror)
nolibc/libnolibc.a(printf.o) nolibc/libnolibc.a(stubs.o) (printf)
openlibm/libopenlibm.a(s_frexp.c.o)
nolibc/libnolibc.a(vfprintf.o) (frexp)
openlibm/libopenlibm.a(s_isfinite.c.o)
nolibc/libnolibc.a(vfprintf.o) (__isfinite)
openlibm/libopenlibm.a(s_signbit.c.o)
nolibc/libnolibc.a(vfprintf.o) (__signbit)
/usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(extenddftf2.o)
nolibc/libnolibc.a(vfprintf.o) (__extenddftf2)
/usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(trunctfdf2.o)
nolibc/libnolibc.a(vfprintf.o) (__trunctfdf2)
/usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(sfp-exceptions.o)
/usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(extenddftf2.o) (__sfp_handle_exceptions)
There are no discarded input sections
Memory Configuration
Name Origin Length Attributes
*default* 0x0000000000000000 0xffffffffffffffff
Linker script and memory map
LOAD test/test03.o
Address of section .init set to 0x80000
START GROUP
LOAD ./libgilbraltar.a
LOAD nolibc/libnolibc.a
LOAD openlibm/libopenlibm.a
LOAD /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a
END GROUP
.init 0x0000000000080000 0xa8
*(.init)
.init 0x0000000000080000 0xa8 ./libgilbraltar.a(startup.o)
0x0000000000080000 _start
.text 0x0000000000080800 0x7960
*(.text*)
.text 0x0000000000080800 0x7c test/test03.o
0x0000000000080800 main
.text 0x000000000008087c 0x1b0 ./libgilbraltar.a(log.o)
0x000000000008087c gilbraltar_log
0x0000000000080a08 gilbraltar_log_set
.text 0x0000000000080a2c 0x0 ./libgilbraltar.a(startup.o)
*fill* 0x0000000000080a2c 0x5d4
.text 0x0000000000081000 0x9d8 ./libgilbraltar.a(exception_stub.o)
0x0000000000081000 VectorTable
0x0000000000081784 unexpected_stub
0x00000000000817bc synchronous_stub
0x00000000000817f4 system_error_stub
0x000000000008182c IRQ_stub
0x00000000000818dc FIQ_stub
0x0000000000081988 SMC_stub
.text 0x00000000000819d8 0x2dc ./libgilbraltar.a(kernel.o)
0x0000000000081ac0 gilbraltar_sysinit
.text 0x0000000000081cb4 0x28 ./libgilbraltar.a(interrupt_handler.o)
0x0000000000081cb4 gilbraltar_interrupt_handler
0x0000000000081cd4 gilbraltar_secure_monitor_handler
.text 0x0000000000081cdc 0x400 ./libgilbraltar.a(exception_handler.o)
0x0000000000081cdc gilbraltar_exception_handler
.text 0x00000000000820dc 0x1c ./libgilbraltar.a(crt.o)
0x00000000000820dc __stack_chk_fail
.text 0x00000000000820f8 0x440 ./libgilbraltar.a(serial.o)
0x0000000000082224 gilbraltar_serial_init
0x0000000000082354 gilbraltar_serial_send
0x000000000008243c gilbraltar_serial_recv
0x0000000000082484 gilbraltar_serial_puts
0x00000000000824c8 gilbraltar_serial_putchar
0x00000000000824ec gilbraltar_serial_write
.text 0x0000000000082538 0x7c ./libgilbraltar.a(power.o)
0x000000000008255c reboot
0x000000000008259c poweroff
.text 0x00000000000825b4 0x5ac ./libgilbraltar.a(tag.o)
0x00000000000825b4 gilbraltar_get_tags
0x0000000000082810 gilbraltar_get_tag
.text 0x0000000000082b60 0x44 ./libgilbraltar.a(coherent_page.o)
0x0000000000082b60 get_coherent_page
.text 0x0000000000082ba4 0x20c ./libgilbraltar.a(dtb.o)
0x0000000000082ba4 gilbraltar_dtb_init
.text 0x0000000000082db0 0x104 ./libgilbraltar.a(memory.o)
0x0000000000082e50 gilbraltar_memory_init
.text 0x0000000000082eb4 0x268 ./libgilbraltar.a(pager.o)
0x0000000000082eb4 gilbraltar_pager_init
0x0000000000082f0c gilbraltar_pager_free_space
0x0000000000082f2c gilbraltar_palloc
0x00000000000830a8 gilbraltar_pager_free
.text 0x000000000008311c 0x554 ./libgilbraltar.a(translation_table.o)
0x00000000000833d8 gilbraltar_translation_table_base
0x00000000000833e8 gilbraltar_translation_table_init
.text 0x0000000000083670 0x10c ./libgilbraltar.a(mbox.o)
0x00000000000836ac gilbraltar_mbox_write_read
.text 0x000000000008377c 0x184 ./libgilbraltar.a(clock.o)
0x000000000008377c gilbraltar_get_rate_of_clock
.text 0x0000000000083900 0x108 ./libgilbraltar.a(spinlock.o)
0x0000000000083900 gilbraltar_spinlock_init
0x0000000000083918 gilbraltar_spinlock_acquire
0x00000000000839b8 gilbraltar_spinlock_release
.text 0x0000000000083a08 0x21c ./libgilbraltar.a(synchronize.o)
0x0000000000083a08 gilbraltar_enter_critical
0x0000000000083b44 gilbraltar_leave_critical
*fill* 0x0000000000083c24 0x1c
.text 0x0000000000083c40 0x50 nolibc/libnolibc.a(assert.o)
0x0000000000083c40 _assert_fail
*fill* 0x0000000000083c90 0x10
.text 0x0000000000083ca0 0x3e0 nolibc/libnolibc.a(memcpy.o)
0x0000000000083ca0 memcpy
.text 0x0000000000084080 0xe0 nolibc/libnolibc.a(memset.o)
0x0000000000084080 memset
.text 0x0000000000084160 0x584 nolibc/libnolibc.a(strstr.o)
0x0000000000084520 strstr
*fill* 0x00000000000846e4 0x1c
.text 0x0000000000084700 0x64 nolibc/libnolibc.a(puts.o)
0x0000000000084700 puts
0x0000000000084740 putchar
*fill* 0x0000000000084764 0x1c
.text 0x0000000000084780 0x14c nolibc/libnolibc.a(vsnprintf.o)
0x00000000000847d0 vsnprintf
*fill* 0x00000000000848cc 0x14
.text 0x00000000000848e0 0xbc nolibc/libnolibc.a(sysdeps.o)
0x000000000008490c write
0x0000000000084960 exit
0x0000000000084968 abort
0x0000000000084988 __getauxval
*fill* 0x000000000008499c 0x4
.text 0x00000000000849a0 0xbc nolibc/libnolibc.a(memchr.o)
0x00000000000849a0 memchr
*fill* 0x0000000000084a5c 0x4
.text 0x0000000000084a60 0x38 nolibc/libnolibc.a(memcmp.o)
0x0000000000084a60 memcmp
*fill* 0x0000000000084a98 0x8
.text 0x0000000000084aa0 0x78 nolibc/libnolibc.a(strlen.o)
0x0000000000084aa0 strlen
*fill* 0x0000000000084b18 0x8
.text 0x0000000000084b20 0x2c nolibc/libnolibc.a(strchr.o)
0x0000000000084b20 strchr
*fill* 0x0000000000084b4c 0x14
.text 0x0000000000084b60 0xd8 nolibc/libnolibc.a(strchrnul.o)
0x0000000000084b60 __strchrnul
*fill* 0x0000000000084c38 0x8
.text 0x0000000000084c40 0x1e38 nolibc/libnolibc.a(vfprintf.o)
0x0000000000084f88 printf_core
0x00000000000869c8 vfprintf
*fill* 0x0000000000086a78 0x8
.text 0x0000000000086a80 0x70 nolibc/libnolibc.a(ctype.o)
0x0000000000086a80 isalpha
0x0000000000086aa0 isdigit
0x0000000000086ab0 isprint
0x0000000000086ac0 isspace
0x0000000000086ae0 isupper
*fill* 0x0000000000086af0 0x10
.text 0x0000000000086b00 0xec0 nolibc/libnolibc.a(stubs.o)
0x0000000000086b00 fflush
0x0000000000086b6c rename
0x0000000000086b8c sscanf
0x0000000000086bac fread
0x0000000000086c20 getc
0x0000000000086c90 ungetc
0x0000000000086d00 fwrite
0x0000000000086d70 fputc
0x0000000000086de0 fputs
0x0000000000086e50 putc
0x0000000000086ec0 ferror
0x0000000000086f30 fopen
0x0000000000086fa0 fclose
0x0000000000087010 getenv
0x0000000000087080 secure_getenv
0x00000000000870f0 system
0x0000000000087110 chdir
0x0000000000087180 close
0x00000000000871a0 getcwd
0x00000000000871c0 getpid
0x0000000000087230 getppid
0x00000000000872a0 isatty
0x00000000000872c0 lseek
0x00000000000872e0 read
0x0000000000087300 readlink
0x0000000000087320 unlink
0x0000000000087340 rmdir
0x0000000000087360 ftruncate
0x0000000000087380 execv
0x00000000000873a0 closedir
0x0000000000087410 opendir
0x0000000000087480 readdir
0x00000000000874f0 fcntl
0x0000000000087510 open
0x0000000000087580 setjmp
0x00000000000875a0 signal
0x00000000000875c0 raise
0x00000000000875e0 strerror
0x0000000000087600 stat
0x0000000000087670 mkdir
0x0000000000087690 pthread_join
0x00000000000876a4 pthread_create
0x00000000000876c0 pthread_attr_init
0x00000000000876e0 pthread_cleanup_push
0x0000000000087700 pthread_cleanup_pop
0x0000000000087720 pthread_mutex_lock
0x0000000000087740 pthread_mutex_trylock
0x0000000000087760 pthread_mutex_unlock
0x0000000000087780 pthread_mutex_destroy
0x00000000000877a0 pthread_mutex_init
0x00000000000877c0 pthread_mutexattr_init
0x00000000000877e0 pthread_mutexattr_destroy
0x0000000000087800 pthread_mutexattr_settype
0x0000000000087820 pthread_sigmask
0x0000000000087840 pthread_equal
0x0000000000087860 pthread_condattr_init
0x0000000000087880 pthread_cond_init
0x00000000000878a0 pthread_cond_destroy
0x00000000000878c0 pthread_cond_wait
0x00000000000878e0 pthread_cond_signal
0x0000000000087900 pthread_cond_broadcast
0x0000000000087920 pthread_self
0x0000000000087940 pthread_detach
0x0000000000087960 sigfillset
0x0000000000087980 sigwait
0x00000000000879a0 usleep
.text 0x00000000000879c0 0xbc nolibc/libnolibc.a(printf.o)
0x00000000000879c0 printf
*fill* 0x0000000000087a7c 0x4
.text 0x0000000000087a80 0x78 openlibm/libopenlibm.a(s_frexp.c.o)
0x0000000000087a80 frexp
*fill* 0x0000000000087af8 0x8
.text 0x0000000000087b00 0x64 openlibm/libopenlibm.a(s_isfinite.c.o)
0x0000000000087b00 __isfinite
0x0000000000087b20 __isfinitef
0x0000000000087b40 __isfinitel
*fill* 0x0000000000087b64 0x1c
.text 0x0000000000087b80 0x38 openlibm/libopenlibm.a(s_signbit.c.o)
0x0000000000087b80 __signbit
0x0000000000087b8c __signbitf
0x0000000000087ba0 __signbitl
.text 0x0000000000087bb8 0x0 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(extenddftf2.o)
*fill* 0x0000000000087bb8 0x8
.text.__extenddftf2
0x0000000000087bc0 0x158 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(extenddftf2.o)
0x0000000000087bc0 __extenddftf2
.text 0x0000000000087d18 0x0 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(trunctfdf2.o)
*fill* 0x0000000000087d18 0x8
.text.__trunctfdf2
0x0000000000087d20 0x3c4 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(trunctfdf2.o)
0x0000000000087d20 __trunctfdf2
.text 0x00000000000880e4 0x0 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(sfp-exceptions.o)
*fill* 0x00000000000880e4 0xc
.text.__sfp_handle_exceptions
0x00000000000880f0 0x70 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(sfp-exceptions.o)
0x00000000000880f0 __sfp_handle_exceptions
0x0000000000088160 _etext = .
.iplt 0x0000000000088160 0x0
.iplt 0x0000000000088160 0x0 test/test03.o
.rodata 0x0000000000088160 0xa40
*(.rodata*)
.rodata 0x0000000000088160 0x22 test/test03.o
*fill* 0x0000000000088182 0x6
.rodata 0x0000000000088188 0x6d ./libgilbraltar.a(kernel.o)
*fill* 0x00000000000881f5 0x3
.rodata 0x00000000000881f8 0x10 ./libgilbraltar.a(interrupt_handler.o)
.rodata 0x0000000000088208 0x97 ./libgilbraltar.a(exception_handler.o)
*fill* 0x000000000008829f 0x1
.rodata 0x00000000000882a0 0x23 ./libgilbraltar.a(crt.o)
*fill* 0x00000000000882c3 0x5
.rodata 0x00000000000882c8 0x21 ./libgilbraltar.a(serial.o)
*fill* 0x00000000000882e9 0x7
.rodata 0x00000000000882f0 0x8b ./libgilbraltar.a(tag.o)
*fill* 0x000000000008837b 0x5
.rodata 0x0000000000088380 0x4b ./libgilbraltar.a(dtb.o)
*fill* 0x00000000000883cb 0x5
.rodata 0x00000000000883d0 0x26 ./libgilbraltar.a(memory.o)
*fill* 0x00000000000883f6 0x2
.rodata 0x00000000000883f8 0x9c ./libgilbraltar.a(pager.o)
*fill* 0x0000000000088494 0x4
.rodata 0x0000000000088498 0x28 ./libgilbraltar.a(translation_table.o)
.rodata 0x00000000000884c0 0x1f ./libgilbraltar.a(mbox.o)
*fill* 0x00000000000884df 0x1
.rodata 0x00000000000884e0 0x9b ./libgilbraltar.a(clock.o)
*fill* 0x000000000008857b 0x5
.rodata 0x0000000000088580 0x2a ./libgilbraltar.a(spinlock.o)
*fill* 0x00000000000885aa 0x6
.rodata 0x00000000000885b0 0xf2 ./libgilbraltar.a(synchronize.o)
*fill* 0x00000000000886a2 0x6
.rodata.str1.8
0x00000000000886a8 0x297 nolibc/libnolibc.a(assert.o)
0x23 (size before relaxing)
.rodata.str1.8
0x000000000008893f 0xa nolibc/libnolibc.a(sysdeps.o)
*fill* 0x000000000008893f 0x1
.rodata 0x0000000000088940 0x260 nolibc/libnolibc.a(vfprintf.o)
.rodata.str1.8
0x0000000000088ba0 0x52 nolibc/libnolibc.a(vfprintf.o)
.rodata.str1.8
0x0000000000088ba0 0x207 nolibc/libnolibc.a(stubs.o)
.rela.dyn 0x0000000000088ba0 0x0
.rela.iplt 0x0000000000088ba0 0x0 test/test03.o
.rela.text 0x0000000000088ba0 0x0 test/test03.o
.ARM.exidx 0x0000000000088ba0 0x0
0x0000000000088ba0 __exidx_start = .
*(.ARM.exidx*)
0x0000000000088ba0 __exidx_end = .
.eh_frame
*(.eh_frame*)
.data 0x0000000000088ba0 0xc4
*(.data*)
.data 0x0000000000088ba0 0x0 test/test03.o
.data 0x0000000000088ba0 0x4 ./libgilbraltar.a(log.o)
.data 0x0000000000088ba4 0x0 ./libgilbraltar.a(startup.o)
*fill* 0x0000000000088ba4 0x4
.data 0x0000000000088ba8 0x20 ./libgilbraltar.a(exception_stub.o)
0x0000000000088ba8 FIQ_data
0x0000000000088bc0 IRQ_return_address
.data 0x0000000000088bc8 0x0 ./libgilbraltar.a(kernel.o)
.data 0x0000000000088bc8 0x0 ./libgilbraltar.a(interrupt_handler.o)
.data 0x0000000000088bc8 0x18 ./libgilbraltar.a(exception_handler.o)
.data 0x0000000000088be0 0x8 ./libgilbraltar.a(crt.o)
0x0000000000088be0 __stack_chk_guard
.data 0x0000000000088be8 0x0 ./libgilbraltar.a(serial.o)
.data 0x0000000000088be8 0x0 ./libgilbraltar.a(power.o)
.data 0x0000000000088be8 0x0 ./libgilbraltar.a(tag.o)
.data 0x0000000000088be8 0x0 ./libgilbraltar.a(coherent_page.o)
.data 0x0000000000088be8 0x0 ./libgilbraltar.a(dtb.o)
.data 0x0000000000088be8 0x0 ./libgilbraltar.a(memory.o)
.data 0x0000000000088be8 0x0 ./libgilbraltar.a(pager.o)
.data 0x0000000000088be8 0x0 ./libgilbraltar.a(translation_table.o)
.data 0x0000000000088be8 0x0 ./libgilbraltar.a(mbox.o)
.data 0x0000000000088be8 0x0 ./libgilbraltar.a(clock.o)
.data 0x0000000000088be8 0x0 ./libgilbraltar.a(spinlock.o)
.data 0x0000000000088be8 0x0 ./libgilbraltar.a(synchronize.o)
.data 0x0000000000088be8 0x0 nolibc/libnolibc.a(assert.o)
.data 0x0000000000088be8 0x0 nolibc/libnolibc.a(memcpy.o)
.data 0x0000000000088be8 0x0 nolibc/libnolibc.a(memset.o)
.data 0x0000000000088be8 0x0 nolibc/libnolibc.a(strstr.o)
.data 0x0000000000088be8 0x0 nolibc/libnolibc.a(puts.o)
.data 0x0000000000088be8 0x0 nolibc/libnolibc.a(vsnprintf.o)
.data 0x0000000000088be8 0x28 nolibc/libnolibc.a(sysdeps.o)
0x0000000000088be8 stdout
0x0000000000088bf0 stderr
.data 0x0000000000088c10 0x0 nolibc/libnolibc.a(memchr.o)
.data 0x0000000000088c10 0x0 nolibc/libnolibc.a(memcmp.o)
.data 0x0000000000088c10 0x0 nolibc/libnolibc.a(strlen.o)
.data 0x0000000000088c10 0x0 nolibc/libnolibc.a(strchr.o)
.data 0x0000000000088c10 0x0 nolibc/libnolibc.a(strchrnul.o)
.data 0x0000000000088c10 0x0 nolibc/libnolibc.a(vfprintf.o)
.data 0x0000000000088c10 0x0 nolibc/libnolibc.a(ctype.o)
.data 0x0000000000088c10 0x54 nolibc/libnolibc.a(stubs.o)
.data 0x0000000000088c64 0x0 nolibc/libnolibc.a(printf.o)
.data 0x0000000000088c64 0x0 openlibm/libopenlibm.a(s_frexp.c.o)
.data 0x0000000000088c64 0x0 openlibm/libopenlibm.a(s_isfinite.c.o)
.data 0x0000000000088c64 0x0 openlibm/libopenlibm.a(s_signbit.c.o)
.data 0x0000000000088c64 0x0 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(extenddftf2.o)
.data 0x0000000000088c64 0x0 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(trunctfdf2.o)
.data 0x0000000000088c64 0x0 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(sfp-exceptions.o)
.igot.plt 0x0000000000088c68 0x0
.igot.plt 0x0000000000088c68 0x0 test/test03.o
.tdata 0x0000000000088c64 0x0
0x0000000000088c64 _stdata = .
*(.tdata)
0x0000000000088c64 _edata = .
.tbss
*(.tbss)
.bss 0x0000000000088c70 0x1364
0x0000000000088c70 __bss_start = .
*(.bss*)
.bss 0x0000000000088c70 0x0 test/test03.o
.bss 0x0000000000088c70 0x0 ./libgilbraltar.a(log.o)
.bss 0x0000000000088c70 0x0 ./libgilbraltar.a(startup.o)
.bss 0x0000000000088c70 0x80 ./libgilbraltar.a(exception_stub.o)
.bss 0x0000000000088cf0 0x0 ./libgilbraltar.a(kernel.o)
.bss 0x0000000000088cf0 0x0 ./libgilbraltar.a(interrupt_handler.o)
.bss 0x0000000000088cf0 0x0 ./libgilbraltar.a(exception_handler.o)
.bss 0x0000000000088cf0 0x0 ./libgilbraltar.a(crt.o)
.bss 0x0000000000088cf0 0x100a ./libgilbraltar.a(serial.o)
.bss 0x0000000000089cfa 0x0 ./libgilbraltar.a(power.o)
.bss 0x0000000000089cfa 0x0 ./libgilbraltar.a(tag.o)
.bss 0x0000000000089cfa 0x0 ./libgilbraltar.a(coherent_page.o)
*fill* 0x0000000000089cfa 0x6
.bss 0x0000000000089d00 0x8 ./libgilbraltar.a(dtb.o)
.bss 0x0000000000089d08 0x0 ./libgilbraltar.a(memory.o)
.bss 0x0000000000089d08 0x1c ./libgilbraltar.a(pager.o)
*fill* 0x0000000000089d24 0x4
.bss 0x0000000000089d28 0x10 ./libgilbraltar.a(translation_table.o)
.bss 0x0000000000089d38 0x0 ./libgilbraltar.a(mbox.o)
.bss 0x0000000000089d38 0x0 ./libgilbraltar.a(clock.o)
.bss 0x0000000000089d38 0x1 ./libgilbraltar.a(spinlock.o)
*fill* 0x0000000000089d39 0x7
.bss 0x0000000000089d40 0x290 ./libgilbraltar.a(synchronize.o)
.bss 0x0000000000089fd0 0x0 nolibc/libnolibc.a(assert.o)
.bss 0x0000000000089fd0 0x0 nolibc/libnolibc.a(memcpy.o)
.bss 0x0000000000089fd0 0x0 nolibc/libnolibc.a(memset.o)
.bss 0x0000000000089fd0 0x0 nolibc/libnolibc.a(strstr.o)
.bss 0x0000000000089fd0 0x0 nolibc/libnolibc.a(puts.o)
.bss 0x0000000000089fd0 0x0 nolibc/libnolibc.a(vsnprintf.o)
.bss 0x0000000000089fd0 0x4 nolibc/libnolibc.a(sysdeps.o)
0x0000000000089fd0 errno
.bss 0x0000000000089fd4 0x0 nolibc/libnolibc.a(memchr.o)
.bss 0x0000000000089fd4 0x0 nolibc/libnolibc.a(memcmp.o)
.bss 0x0000000000089fd4 0x0 nolibc/libnolibc.a(strlen.o)
.bss 0x0000000000089fd4 0x0 nolibc/libnolibc.a(strchr.o)
.bss 0x0000000000089fd4 0x0 nolibc/libnolibc.a(strchrnul.o)
.bss 0x0000000000089fd4 0x0 nolibc/libnolibc.a(vfprintf.o)
.bss 0x0000000000089fd4 0x0 nolibc/libnolibc.a(ctype.o)
.bss 0x0000000000089fd4 0x0 nolibc/libnolibc.a(stubs.o)
.bss 0x0000000000089fd4 0x0 nolibc/libnolibc.a(printf.o)
.bss 0x0000000000089fd4 0x0 openlibm/libopenlibm.a(s_frexp.c.o)
.bss 0x0000000000089fd4 0x0 openlibm/libopenlibm.a(s_isfinite.c.o)
.bss 0x0000000000089fd4 0x0 openlibm/libopenlibm.a(s_signbit.c.o)
.bss 0x0000000000089fd4 0x0 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(extenddftf2.o)
.bss 0x0000000000089fd4 0x0 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(trunctfdf2.o)
.bss 0x0000000000089fd4 0x0 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(sfp-exceptions.o)
*(COMMON)
0x0000000000089fd4 _end = .
OUTPUT(test03.elf elf64-littleaarch64)
LOAD linker stubs
.comment 0x0000000000000000 0x45
.comment 0x0000000000000000 0x45 test/test03.o
0x46 (size before relaxing)
.comment 0x0000000000000045 0x46 ./libgilbraltar.a(log.o)
.comment 0x0000000000000045 0x46 ./libgilbraltar.a(kernel.o)
.comment 0x0000000000000045 0x46 ./libgilbraltar.a(interrupt_handler.o)
.comment 0x0000000000000045 0x46 ./libgilbraltar.a(exception_handler.o)
.comment 0x0000000000000045 0x46 ./libgilbraltar.a(crt.o)
.comment 0x0000000000000045 0x46 ./libgilbraltar.a(serial.o)
.comment 0x0000000000000045 0x46 ./libgilbraltar.a(power.o)
.comment 0x0000000000000045 0x46 ./libgilbraltar.a(tag.o)
.comment 0x0000000000000045 0x46 ./libgilbraltar.a(coherent_page.o)
.comment 0x0000000000000045 0x46 ./libgilbraltar.a(dtb.o)
.comment 0x0000000000000045 0x46 ./libgilbraltar.a(memory.o)
.comment 0x0000000000000045 0x46 ./libgilbraltar.a(pager.o)
.comment 0x0000000000000045 0x46 ./libgilbraltar.a(translation_table.o)
.comment 0x0000000000000045 0x46 ./libgilbraltar.a(mbox.o)
.comment 0x0000000000000045 0x46 ./libgilbraltar.a(clock.o)
.comment 0x0000000000000045 0x46 ./libgilbraltar.a(spinlock.o)
.comment 0x0000000000000045 0x46 ./libgilbraltar.a(synchronize.o)
.comment 0x0000000000000045 0x46 nolibc/libnolibc.a(assert.o)
.comment 0x0000000000000045 0x46 nolibc/libnolibc.a(memcpy.o)
.comment 0x0000000000000045 0x46 nolibc/libnolibc.a(memset.o)
.comment 0x0000000000000045 0x46 nolibc/libnolibc.a(strstr.o)
.comment 0x0000000000000045 0x46 nolibc/libnolibc.a(puts.o)
.comment 0x0000000000000045 0x46 nolibc/libnolibc.a(vsnprintf.o)
.comment 0x0000000000000045 0x46 nolibc/libnolibc.a(sysdeps.o)
.comment 0x0000000000000045 0x46 nolibc/libnolibc.a(memchr.o)
.comment 0x0000000000000045 0x46 nolibc/libnolibc.a(memcmp.o)
.comment 0x0000000000000045 0x46 nolibc/libnolibc.a(strlen.o)
.comment 0x0000000000000045 0x46 nolibc/libnolibc.a(strchr.o)
.comment 0x0000000000000045 0x46 nolibc/libnolibc.a(strchrnul.o)
.comment 0x0000000000000045 0x46 nolibc/libnolibc.a(vfprintf.o)
.comment 0x0000000000000045 0x46 nolibc/libnolibc.a(ctype.o)
.comment 0x0000000000000045 0x46 nolibc/libnolibc.a(stubs.o)
.comment 0x0000000000000045 0x46 nolibc/libnolibc.a(printf.o)
.comment 0x0000000000000045 0x46 openlibm/libopenlibm.a(s_frexp.c.o)
.comment 0x0000000000000045 0x46 openlibm/libopenlibm.a(s_isfinite.c.o)
.comment 0x0000000000000045 0x46 openlibm/libopenlibm.a(s_signbit.c.o)
.comment 0x0000000000000045 0x46 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(extenddftf2.o)
.comment 0x0000000000000045 0x46 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(trunctfdf2.o)
.comment 0x0000000000000045 0x46 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(sfp-exceptions.o)
.debug_info 0x0000000000000000 0x76a
.debug_info 0x0000000000000000 0x2ef /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(extenddftf2.o)
.debug_info 0x00000000000002ef 0x39e /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(trunctfdf2.o)
.debug_info 0x000000000000068d 0xdd /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(sfp-exceptions.o)
.debug_abbrev 0x0000000000000000 0x35e
.debug_abbrev 0x0000000000000000 0x159 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(extenddftf2.o)
.debug_abbrev 0x0000000000000159 0x183 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(trunctfdf2.o)
.debug_abbrev 0x00000000000002dc 0x82 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(sfp-exceptions.o)
.debug_loclists
0x0000000000000000 0xacb
.debug_loclists
0x0000000000000000 0x451 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(extenddftf2.o)
.debug_loclists
0x0000000000000451 0x653 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(trunctfdf2.o)
.debug_loclists
0x0000000000000aa4 0x27 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(sfp-exceptions.o)
.debug_aranges 0x0000000000000000 0x90
.debug_aranges
0x0000000000000000 0x30 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(extenddftf2.o)
.debug_aranges
0x0000000000000030 0x30 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(trunctfdf2.o)
.debug_aranges
0x0000000000000060 0x30 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(sfp-exceptions.o)
.debug_rnglists
0x0000000000000000 0x1d6
.debug_rnglists
0x0000000000000000 0x84 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(extenddftf2.o)
.debug_rnglists
0x0000000000000084 0x13b /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(trunctfdf2.o)
.debug_rnglists
0x00000000000001bf 0x17 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(sfp-exceptions.o)
.debug_line 0x0000000000000000 0xb07
.debug_line 0x0000000000000000 0x276 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(extenddftf2.o)
.debug_line 0x0000000000000276 0x7f9 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(trunctfdf2.o)
.debug_line 0x0000000000000a6f 0x98 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(sfp-exceptions.o)
.debug_str 0x0000000000000000 0x294
.debug_str 0x0000000000000000 0x294 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(extenddftf2.o)
0x1f3 (size before relaxing)
.debug_str 0x0000000000000294 0x252 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(trunctfdf2.o)
.debug_str 0x0000000000000294 0x11c /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(sfp-exceptions.o)
.debug_line_str
0x0000000000000000 0x213
.debug_line_str
0x0000000000000000 0x213 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(extenddftf2.o)
0x19c (size before relaxing)
.debug_line_str
0x0000000000000213 0x199 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(trunctfdf2.o)
.debug_line_str
0x0000000000000213 0x193 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(sfp-exceptions.o)
.debug_frame 0x0000000000000000 0xb0
.debug_frame 0x0000000000000000 0x38 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(extenddftf2.o)
.debug_frame 0x0000000000000038 0x50 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(trunctfdf2.o)
.debug_frame 0x0000000000000088 0x28 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(sfp-exceptions.o)

93
translation_table.c Normal file
View file

@ -0,0 +1,93 @@
#include <log.h>
#include <mem.h>
#include <pager.h>
#include <string.h>
#include <sysconfig.h>
#include <translation_table.h>
#define LEVEL2_TABLE_ENTRIES 256
static union TARMV8MMU_LEVEL2_DESCRIPTOR *l2_table;
static size_t mem = 0;
extern uint8_t _etext;
static union TARMV8MMU_LEVEL3_DESCRIPTOR *
new_level_l3_table(uintptr_t base_addr) {
union TARMV8MMU_LEVEL3_DESCRIPTOR *l3_table =
(union TARMV8MMU_LEVEL3_DESCRIPTOR *)gilbraltar_palloc();
for (unsigned page = 0; page < ARMV8MMU_TABLE_ENTRIES; page++) {
struct TARMV8MMU_LEVEL3_PAGE_DESCRIPTOR *desc = &l3_table[page].page;
desc->value11 = 3;
desc->attr_indx = ATTR_INDX_NORMAL;
desc->ns = 0;
desc->ap = ATTR_IB_AP_RW_EL1;
desc->sh = ATTR_IB_SH_INNER_SHAREABLE;
desc->af = 1;
desc->ng = 0;
desc->reserved0_1 = 0;
desc->output_addr = ARMV8MMUL3PAGEADDR(base_addr);
desc->reserved0_2 = 0;
desc->continuous = 0;
desc->pxn = 0;
desc->uxn = 1;
desc->ignored = 0;
if (base_addr >= (uint64_t)&_etext) {
desc->pxn = 1;
if ((base_addr >= mem && base_addr < GIGABYTE) ||
base_addr > (8 * GIGABYTE - 1)) {
desc->attr_indx = ATTR_INDX_DEVICE;
desc->sh = ATTR_IB_SH_OUTER_SHAREABLE;
} else if (base_addr >= MEM_COHERENT_REGION &&
base_addr < MEM_HEAP_START) {
desc->attr_indx = ATTR_INDX_COHERENT;
desc->sh = ATTR_IB_SH_OUTER_SHAREABLE;
}
}
base_addr += ARMV8MMU_LEVEL3_PAGE_SIZE;
}
return (l3_table);
}
uintptr_t gilbraltar_translation_table_base(void) {
return ((uintptr_t)l2_table);
}
void gilbraltar_translation_table_init(size_t size) {
l2_table = (union TARMV8MMU_LEVEL2_DESCRIPTOR *)gilbraltar_palloc();
gilbraltar_log(INFO, "L2 table allocated.\r\n");
memset(l2_table, 0, PAGE_SIZE);
for (unsigned entry = 0; entry < LEVEL2_TABLE_ENTRIES; entry++) {
uint64_t base_addr =
(uint64_t)entry * ARMV8MMU_TABLE_ENTRIES * ARMV8MMU_LEVEL3_PAGE_SIZE;
if (base_addr >= 8 * GIGABYTE &&
!(MEM_IOMEM_AXI_START <= base_addr && base_addr <= MEM_IOMEM_AXI_END) &&
!(MEM_IOMEM_SOC_START <= base_addr && base_addr <= MEM_IOMEM_SOC_END) &&
!(MEM_IOMEM_PCIE_START <= base_addr && base_addr <= MEM_IOMEM_PCIE_END))
continue; // as far as we can
gilbraltar_log(INFO, "New L3 table.\r\n");
union TARMV8MMU_LEVEL3_DESCRIPTOR *l3_table = new_level_l3_table(base_addr);
struct TARMV8MMU_LEVEL2_TABLE_DESCRIPTOR *desc = &l2_table[entry].table;
desc->value11 = 3;
desc->ignored1 = 0;
desc->table_addr = ARMV8MMUL2TABLEADDR((uint64_t)l3_table);
desc->reserved0 = 0;
desc->ignored2 = 0;
desc->pxn_table = 0;
desc->uxn_table = 0;
desc->ap_table = AP_TABLE_ALL_ACCESS;
desc->ns_table = 0;
}
data_sync_barrier();
}