.
This commit is contained in:
parent
e7ccf2e72a
commit
40cc5affc0
45 changed files with 1591 additions and 129 deletions
|
@ -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 $@
|
||||
|
|
42
clock.c
42
clock.c
|
@ -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_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
13
coherent_page.c
Normal 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
6
crt.c
|
@ -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
48
dtb.c
Normal 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;
|
||||
}
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -20,4 +20,16 @@
|
|||
#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
8
include/board.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef __GILBRALTAR_BOARD__
|
||||
#define __GILBRALTAR_BOARD__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
uint32_t gilbraltar_get_board(void);
|
||||
|
||||
#endif
|
|
@ -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
12
include/coherent_page.h
Normal 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
13
include/cpu_aarch64.h
Normal 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
11
include/crt.h
Normal 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
8
include/dtb.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef __GILBRALTAR_DTB__
|
||||
#define __GILBRALTAR_DTB__
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
bool gilbraltar_dtb_init(void);
|
||||
|
||||
#endif
|
|
@ -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 *);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
6
include/memory.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef __GILBRALTAR_MEMORY__
|
||||
#define __GILBRALTAR_MEMORY__
|
||||
|
||||
void gilbraltar_memory_init(void);
|
||||
|
||||
#endif
|
|
@ -17,9 +17,8 @@
|
|||
#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_SIZE 0x10000LL // page size used by us
|
||||
#define PAGE_SHIFT 16
|
||||
#define PAGE_MASK ~(0xffff)
|
||||
#define EXCEPTION_STACK_SIZE 0x8000
|
||||
#define PAGE_RESERVE (16 * MEGABYTE)
|
||||
|
||||
|
@ -38,8 +37,7 @@
|
|||
((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))
|
||||
|
@ -48,10 +46,17 @@
|
|||
(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)
|
||||
|
||||
// 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
12
include/pager.h
Normal 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
7
include/power.h
Normal file
|
@ -0,0 +1,7 @@
|
|||
#ifndef __GILBRALTAR_POWER__
|
||||
#define __GILBRALTAR_POWER__
|
||||
|
||||
void reboot(void);
|
||||
void poweroff(void);
|
||||
|
||||
#endif
|
|
@ -2,8 +2,8 @@
|
|||
#define __GILBRALTAR_SERIAL__
|
||||
|
||||
#include <bcm.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define ARM_UART0_BASE (ARM_IO_BASE + 0x1001000)
|
||||
|
||||
|
|
11
include/spinlock.h
Normal file
11
include/spinlock.h
Normal 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
14
include/synchronize.h
Normal 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
|
|
@ -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
|
||||
|
|
|
@ -1,10 +1,16 @@
|
|||
#ifndef __GILBRALTAR_TAG__
|
||||
#define __GILBRALTAR_TAG__
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#define CODE_REQUEST 0x00000000
|
||||
#define CODE_RESPONSE_SUCCESS 0x80000000
|
||||
#define CODE_RESPONSE_FAILURE 0x80000001
|
||||
|
||||
#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
112
include/translation_table.h
Normal 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
|
|
@ -1,4 +1,8 @@
|
|||
#include <log.h>
|
||||
|
||||
void gilbraltar_interrupt_handler(void) {
|
||||
gilbraltar_log(DEBUG, "Interruption.\r\n");
|
||||
|
||||
while (1)
|
||||
__asm__ __volatile("wfi");
|
||||
}
|
||||
|
|
79
kernel.c
79
kernel.c
|
@ -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
8
log.c
|
@ -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
13
mbox.c
|
@ -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
97
memory.c
Normal 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();
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
64
pager.c
Normal 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
21
power.c
Normal 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 (;;)
|
||||
;
|
||||
}
|
5
printf.c
5
printf.c
|
@ -1,8 +1,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int printf(const char *restrict fmt, ...)
|
||||
{
|
||||
int printf(const char *restrict fmt, ...) {
|
||||
int ret;
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
|
|
67
serial.c
67
serial.c
|
@ -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) {
|
||||
if (initialized) {
|
||||
while (1)
|
||||
if (!(read32(ARM_UART0_FR) & 0x20)) break;
|
||||
if (!(read32(ARM_UART0_FR) & 0x20))
|
||||
break;
|
||||
|
||||
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
45
spinlock.c
Normal 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
58
synchronize.c
Normal 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
68
tag.c
Normal 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
574
test03.map
Normal 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
93
translation_table.c
Normal 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();
|
||||
}
|
Loading…
Reference in a new issue