armv8: cpu driver improvements.
authorSimon Gerber <simon.gerber@inf.ethz.ch>
Fri, 19 Jun 2015 13:36:48 +0000 (15:36 +0200)
committerSimon Gerber <simon.gerber@inf.ethz.ch>
Fri, 19 Jun 2015 13:50:14 +0000 (15:50 +0200)
* Set exception vector base register
* Use provided kernel stack
* implement some system register inline assembly
* Clean up arch_init()
* Add prototypes for paging_init() and paging_dump().

Signed-off-by: Simon Gerber <simon.gerber@inf.ethz.ch>

kernel/arch/apm88xxxx/boot.S
kernel/arch/apm88xxxx/init.c
kernel/arch/apm88xxxx/paging.c
kernel/arch/apm88xxxx/uart.c
kernel/arch/armv8/exceptions.S
kernel/arch/armv8/exec.c
kernel/include/arch/armv8/cp15.h [deleted file]
kernel/include/arch/armv8/paging_kernel_arch.h
kernel/include/arch/armv8/sysreg.h [new file with mode: 0644]

index 498e5cd..4e7b737 100644 (file)
@@ -22,7 +22,7 @@
         .text
 
         .globl start, halt, got_base
-        .extern kernel_stack, glbl_core_data
+        .extern glbl_core_data, exception_vectors
 
         // Used to track phys memory allocator limit globally.
         alloc_top .req x11
@@ -45,10 +45,10 @@ start:
         // Register x1 contains a pointer to the UEFI memory map
         //
 
-        //init stack
-        ldr     x15, =kernel_stack
-        mov     sp, x15
-        add     sp, sp, #KERNEL_STACK_SIZE
+        // set exception vectors for EL1 and EL2
+        adrp    x15, exception_vectors
+        msr     vbar_el1, x15
+        msr     vbar_el2, x15
 
         ldr     PIC_REGISTER, got_base
 
@@ -60,8 +60,8 @@ start:
 /**
  * extern "C" void halt(void) __attribute__((noreturn))
  */
-halt:
-        b       .
+halt:   wfi
+        b       halt
 
 /**********************************************************************/
 .ltorg
index c077d3d..63012fe 100644 (file)
@@ -1,60 +1,71 @@
 #include <kernel.h>
 #include <serial.h>
 #include <uefi_mmap.h>
+#include <sysreg.h>
+#include <multiboot.h>
 
-/**
- * \brief Kernel stack.
- *
- * This is the one and only kernel stack for a kernel instance.
+/*
+ * Create kernel page tables (high 256G)
+ * We use GB sections (level 1 entries that point to memory)
  */
-uintptr_t kernel_stack[KERNEL_STACK_SIZE / sizeof(uintptr_t)] __attribute__ ((aligned(16)));
+static void paging_init(void)
+{
+    return;
+}
 
+static void paging_dump(void)
+{
+    lvaddr_t lvl0 = sysreg_read_ttbr0();
+    lvl0 = lvl0;
+}
+
+bool is_bsp = true;
 
 __attribute__((noreturn))
-void arch_init(void *arg1, EFI_MEMORY_DESCRIPTOR *uefi_mmap);
+void arch_init(void *pointer, EFI_MEMORY_DESCRIPTOR *uefi_mmap);
 // Currently
-void arch_init(void *arg1, EFI_MEMORY_DESCRIPTOR *uefi_mmap)
+void arch_init(void *pointer, EFI_MEMORY_DESCRIPTOR *uefi_mmap)
 {
-    // set console port: UART0 is the one that's connected to the DB9
+    // break to attach gdb here
+    __asm volatile ("wfi":::);
+
+    // set both console ports: UART0 is the one that's connected to the DB9
     // connector on the back of the mustang boxes.
     serial_console_port = 0;
+    serial_debug_port   = 0;
 
     // init serial console, skip hwinit, as the port is guaranteed to be
     // initialized by UEFI.
     serial_console_init(false);
 
-    // print something
-    printf("Barrelfish APM88xxxx CPU driver starting at addr 0x%"
-            PRIxLVADDR" on core %"PRIuCOREID" xxxxxxxxxx\n",
-            local_phys_to_mem((lpaddr_t)&kernel_first_byte), my_core_id);
+    if (is_bsp) {
+        printf("ACPI root table (RSDP):  %p\n", pointer);
+        printf("UEFI memory map pointer: %p\n", uefi_mmap);
 
-    printf("ACPI root table (RSDP):  %p\n", arg1);
-    printf("UEFI memory map pointer: %p\n", uefi_mmap);
+        printf("First memory map entry:\n");
+        printf(" Type:      %x\n", uefi_mmap->Type);
+        printf(" PhysStart: 0x%lx\n", uefi_mmap->PhysicalStart);
+        printf(" VirtStart: 0x%lx\n", uefi_mmap->VirtualStart);
+        printf(" #pages:    %lu\n", uefi_mmap->NumberOfPages);
+        printf(" Attrs:     %lx\n", uefi_mmap->Attribute);
 
-    uint32_t *mmap_ptr = (uint32_t *)uefi_mmap;
+        struct multiboot_info *mb = pointer;
+        mb = mb;
 
-    printf("Test 1: %p\n", mmap_ptr);
-    printf("Test 2: %p\n", mmap_ptr+1);
-    printf("Test 3: %p\n", mmap_ptr+2);
-    printf("Test 4: %p\n", mmap_ptr+3);
-    printf("Test 5: %p\n", mmap_ptr+4);
-#if 0
-    for (int i = 0; i < 8; i++) {
-        printf("%016lx: 0x%08x\n", (uint64_t)(mmap_ptr+i), mmap_ptr[i]);
+        // TODO: finish BSP core init
+    } else {
+        // TODO: AP core init
     }
 
-    printf("First memory map entry:\n");
-    printf(" Type:      %x\n", uefi_mmap->Type);
-    printf(" PhysStart: 0x%lx\n", uefi_mmap->PhysicalStart);
-    printf(" VirtStart: 0x%lx\n", uefi_mmap->VirtualStart);
-    printf(" #pages:    %lu\n", uefi_mmap->NumberOfPages);
-    printf(" Attrs:     %lx\n", uefi_mmap->Attribute);
-
-#endif
+    // print something
+    printf("Barrelfish APM88xxxx CPU driver starting at addr 0x%"
+            PRIxLVADDR" on core %"PRIuCOREID"\n",
+            local_phys_to_mem((lpaddr_t)&kernel_first_byte), my_core_id);
 
-    *(uint32_t*)0x1c020000 = 'a';
+    paging_dump();
+    paging_init();
 
     while(1) {
-        __asm volatile ("nop":::);
+        __asm volatile ("wfi":::);
     }
 }
index e853d95..db84c53 100644 (file)
@@ -4,7 +4,6 @@
 
 #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn"
 
-
 void paging_context_switch(lpaddr_t ttbr)
 {
     panic("NYI");
index 1352e4f..b675c4f 100644 (file)
@@ -13,7 +13,8 @@
 // #ports
 #define NUM_PORTS 4
 
-unsigned serial_console_port, serial_debug_port;
+unsigned serial_console_port = 0;
+unsigned serial_debug_port = 0;
 
 // port base addresses for lookup by port no
 static const mackerel_addr_t portbases[NUM_PORTS] =
@@ -23,10 +24,16 @@ static apm88xxxx_pc16550_t ports[NUM_PORTS];
 
 errval_t serial_init(unsigned port, bool initialize_hw)
 {
+    // XXX: remove once we have data section
+    port = 0;
     if (port >= NUM_PORTS) {
         return SYS_ERR_SERIAL_PORT_INVALID;
     }
 
+    if (ports[port].base == portbases[port]) {
+        return SYS_ERR_OK;
+    }
+
     apm88xxxx_pc16550_t *uart = &ports[port];
     apm88xxxx_pc16550_initialize(uart, portbases[port]);
 
@@ -53,6 +60,8 @@ errval_t serial_early_init(unsigned port)
  */
 void serial_putchar(unsigned port, char c)
 {
+    // XXX: remove once we have data section
+    port = 0;
     assert(port < NUM_PORTS);
     assert(ports[port].base != 0);
     // Wait until FIFO can hold more characters
index 7969a35..d80aec4 100644 (file)
 #include <exceptions.h>
 
 // macro for creating table entries that are nicely aligned
-.macro vector_entry label idx
+.macro vector_entry label
 // every entry is at 128 byte boundary
 .align 7
     b   \label
 .endm
 
+// macro for getting current exception level (result in arg)
+.macro get_cur_el reg
+    mrs     \reg, currentel
+    ubfm    \reg, \reg, #2, #3 // extract currentel[3:2]
+.endm
+
 // macro for saving exception frame: needs to match with struct layout in C
 // code
 .macro push_state_to_exn_frame
     stp      x0,  x1, [sp, #-16]!
     // save old SP: 48 + 32 * 8
     add     x1, sp, #288
+    get_cur_el x0
+    cmp     x0, #1
+    b.ne    push_get_el2_state_\@
     // save ELR_EL1
     mrs     x2, elr_el1
     // save SPSR_EL1
     mrs     x3, spsr_el1
+    b       push_el_state_cont_\@
+push_get_el2_state_\@:
+    // save ELR_EL1
+    mrs     x2, elr_el2
+    // save SPSR_EL1
+    mrs     x3, spsr_el2
+push_el_state_cont_\@:
     // store pair of lr and sp just after x29
     stp     x30, x1, [sp, #240]
     // store pair of elr_el1, and spsr_el1 just after sp
 // macro for restoring from exception frame: needs to match with struct layout
 // in C code
 .macro pop_state_from_exn_frame
-    // load elr_el1, spsr_el1
+    // load elr, spsr
     ldp     x21, x22, [sp, #256]
     ldp     x0, x1, [sp], #16
     ldp     x2, x3, [sp], #16
     ldp     x4, x5, [sp], #16
     ldp     x6, x7, [sp], #16
     ldp     x8, x9, [sp], #16
+    get_cur_el x10
+    cmp     x10, #1
+    b.ne    pop_restore_el2_state_\@
     // set elr and spsr
     msr     elr_el1, x21
     msr     spsr_el1, x22
+    b       pop_state_cont_\@
+pop_restore_el2_state_\@:
+    cmp     x10, #2
+    b.ne    halt
+    // set elr and spsr
+    msr     elr_el2, x21
+    msr     spsr_el2, x22
+pop_state_cont_\@:
     ldp      x10, x11, [sp], #16
     ldp      x12, x13, [sp], #16
     ldp      x14, x15, [sp], #16
 .align 12
 exception_vectors:
     // current EL with SP_EL0: NYI/unused
-    vector_entry invalid_handler  0 // sync
-    vector_entry invalid_handler  1 // IRQ/vIRQ
-    vector_entry invalid_handler  2 // FIQ/vFIQ
-    vector_entry invalid_handler  3 // SError/vSError
+    vector_entry invalid_handler    // sync
+    vector_entry invalid_handler    // IRQ/vIRQ
+    vector_entry invalid_handler    // FIQ/vFIQ
+    vector_entry invalid_handler    // SError/vSError
 
     // current EL with SP_ELcur
-    vector_entry sync_handler     4 // sync
-    vector_entry irq_handler      5 // IRQ/vIRQ
-    vector_entry fiq_handler      6 // FIQ/vFIQ
-    vector_entry serror_handler   7 // SError/vSError
+    vector_entry sync_handler       // sync
+    vector_entry irq_handler        // IRQ/vIRQ
+    vector_entry fiq_handler        // FIQ/vFIQ
+    vector_entry serror_handler     // SError/vSError
 
-    // lower EL running AArch64
-    vector_entry invalid_handler  8 // sync
-    vector_entry invalid_handler  9 // IRQ/vIRQ
-    vector_entry invalid_handler 10 // FIQ/vFIQ
-    vector_entry invalid_handler 11 // SError/vSError
+    // lower EL running AArch64: NYI
+    vector_entry invalid_handler    // sync
+    vector_entry invalid_handler    // IRQ/vIRQ
+    vector_entry invalid_handler    // FIQ/vFIQ
+    vector_entry invalid_handler    // SError/vSError
 
     // lower EL running AArch32: unsupported
-    vector_entry invalid_handler 12 // sync
-    vector_entry invalid_handler 13 // IRQ/vIRQ
-    vector_entry invalid_handler 14 // FIQ/vFIQ
-    vector_entry invalid_handler 15 // SError/vSError
+    vector_entry invalid_handler    // sync
+    vector_entry invalid_handler    // IRQ/vIRQ
+    vector_entry invalid_handler    // FIQ/vFIQ
+    vector_entry invalid_handler    // SError/vSError
 
 
 // we are using unsigned bitfield moves (ubfm, C6-789) to extract fields from
@@ -145,16 +172,15 @@ exception_vectors:
 .global invalid_handler
 .type invalid_handler @function
 invalid_handler:
-    mrs x20, elr_el1    // store exception link register to x20
-    mrs x21, spsr_el1   // store saved pstate to x21
-    mrs x22, esr_el1    // store exception syndrome register to x22
+    mrs     x20, elr_el1    // store exception link register to x20
+    mrs     x21, spsr_el1   // store saved pstate to x21
+    mrs     x22, esr_el1    // store exception syndrome register to x22
+
+    ubfm    x23, x22, #ESR_EC_L, #ESR_EC_H
+    ubfm    x24, x22, #ESR_ISS_L, #ESR_ISS_H
 
-    ubfm x23, x22, #ESR_EC_L, #ESR_EC_H
-    ubfm x24, x22, #ESR_ISS_L, #ESR_ISS_H
+    b       halt
 
-    // abort()
-1:  wfi
-    b   1b
 
         //
         // void sync_handler(void)
@@ -166,8 +192,23 @@ invalid_handler:
 sync_handler:
     push_state_to_exn_frame
 
-    // extract exception details from ESR
+    // get current EL
+    get_cur_el x0
+    cmp     x0, #1
+    // != -> check for EL2
+    b.ne    sync_handler_check_el2
+    // == -> extract from  esr_el
+    // extract exception details from ESR_EL1
     mrs     x1, esr_el1
+    b       sync_handler_common
+sync_handler_check_el2:
+    cmp     x0, #2
+    b.ne    halt
+    // == -> use el2 registers
+    // extract exception details from ESR_EL1
+    mrs     x1, esr_el2
+
+sync_handler_common:
     // Exception Class to x2
     ubfm    x2, x1, #ESR_EC_L, #ESR_EC_H
     // Fault to x3
@@ -180,6 +221,7 @@ sync_handler:
     b.eq    handle_pf_abort
     // otherwise, goto unknown_handler(esr)
     b.ne    handle_sync_abort
+    b       sync_handler_epi
 handle_pf_abort:
     // goto invalid_handler if fault == 0
     cbz     x3, invalid_handler
@@ -191,6 +233,7 @@ handle_pf_abort:
     mov     x0, sp
     bl      page_fault
 
+sync_handler_epi:
     pop_state_from_exn_frame
     eret
 
index f42c694..d113b84 100644 (file)
@@ -19,7 +19,7 @@
 #include <arm_hal.h>
 #include <exec.h>
 #include <misc.h>
-#include <cp15.h>   // for invalidating tlb and cache
+#include <sysreg.h>   // for invalidating tlb and cache
 
 //static arch_registers_state_t upcall_state;
 
diff --git a/kernel/include/arch/armv8/cp15.h b/kernel/include/arch/armv8/cp15.h
deleted file mode 100644 (file)
index 705faf8..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (c) 2009 ETH Zurich.
- * All rights reserved.
- *
- * This file is distributed under the terms in the attached LICENSE file.
- * If you do not find this file, copies can be found by writing to:
- * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
- */
-
-#ifndef __CP15_H__
-#define __CP15_H__
-
-/**
- * \brief Read domain access control register
- */
-static inline uint32_t cp15_read_dacr(void)
-{
-    panic("NYI");
-}
-
-/**
- * \brief Read instruction fault status register.
- */
-static inline uint32_t cp15_read_ifsr(void)
-{
-    panic("NYI");
-}
-
-/**
- * \brief Read data fault status register.
- */
-static inline uint32_t cp15_read_dfsr(void)
-{
-    panic("NYI");
-}
-
-/**
- * \brief Read fault address register.
- */
-static inline uint32_t cp15_read_far(void)
-{
-    panic("NYI");
-}
-
-static inline lpaddr_t cp15_read_ttbr0(void)
-{
-    panic("NYI");
-}
-
-static inline lpaddr_t cp15_read_ttbr1(void)
-{
-    panic("NYI");
-}
-
-static inline void cp15_write_ttbr0(lpaddr_t ttbr)
-{
-    panic("NYI");
-}
-
-static inline void cp15_write_ttbr1(lpaddr_t ttbr)
-{
-    panic("NYI");
-}
-
-static inline uint32_t cp15_read_ttbcr(void)
-{
-    panic("NYI");
-}
-
-static inline void cp15_write_ttbcr(uint32_t ttbcr)
-{
-    panic("NYI");
-}
-
-extern void cp15_invalidate_d_cache(void);
-extern void cp15_invalidate_i_and_d_caches(void);
-extern void cp15_invalidate_i_and_d_caches_fast(void);
-extern void cp15_invalidate_tlb_fn(void);
-extern void cp15_enable_mmu(void);
-extern void cp15_enable_alignment(void);
-
-static inline uint32_t cp15_read_cache_status(void){
-    panic("NYI");
-}
-
-
-static inline void cp15_disable_cache(void){
-
-    cp15_invalidate_i_and_d_caches_fast();
-
-    panic("NYI");
-
-    printf("WARNING! Caching has been disabled, configuration is: %"PRIx32"\n", cp15_read_cache_status());
-
-}
-
-static inline void cp15_invalidate_tlb(void)
-{
-    panic("NYI");
-}
-
-static inline uint8_t cp15_get_cpu_id(void) {
-    panic("NYI");
-}
-
-/*
- * Get the configuration base address
- * This is described in the Cortex A9 TRM, 4.2.32
- */
-static inline uint32_t cp15_read_cbar(void)
-{
-    panic("NYI");
-}
-
-#endif // __CP15_H__
index 6e99b0c..f593f2d 100644 (file)
@@ -19,7 +19,7 @@
 #include <capabilities.h>
 #include <barrelfish_kpi/cpu.h>
 #include <barrelfish_kpi/paging_arch.h>
-#include <cp15.h>
+#include <sysreg.h>
 
 /**
  * Setup bootstrap page table with direct and relocated mappings for kernel.
@@ -80,18 +80,18 @@ static inline size_t get_pte_size(void) {
 static inline void do_one_tlb_flush(genvaddr_t vaddr)
 {
     // TODO: figure out selective flushing for ARM
-    cp15_invalidate_tlb();
+    sysreg_invalidate_tlb();
 }
 
 static inline void do_selective_tlb_flush(genvaddr_t vaddr, genvaddr_t vend)
 {
     // TODO: figure out selective flushing for ARM
-    cp15_invalidate_tlb();
+    sysreg_invalidate_tlb();
 }
 
 static inline void do_full_tlb_flush(void)
 {
-    cp15_invalidate_tlb();
+    sysreg_invalidate_tlb();
 }
 
 
diff --git a/kernel/include/arch/armv8/sysreg.h b/kernel/include/arch/armv8/sysreg.h
new file mode 100644 (file)
index 0000000..ad173a1
--- /dev/null
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2015 ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#ifndef __SYSREG_H__
+#define __SYSREG_H__
+
+/**
+ * \brief Read domain access control register
+ */
+static inline uint32_t sysreg_read_dacr(void)
+{
+    panic("NYI");
+}
+
+/**
+ * \brief Read instruction fault status register.
+ */
+static inline uint32_t sysreg_read_ifsr(void)
+{
+    panic("NYI");
+}
+
+/**
+ * \brief Read data fault status register.
+ */
+static inline uint32_t sysreg_read_dfsr(void)
+{
+    panic("NYI");
+}
+
+/**
+ * \brief Read fault address register.
+ */
+static inline uint32_t sysreg_read_far(void)
+{
+    panic("NYI");
+}
+
+static inline uintptr_t get_current_el(void)
+{
+    uintptr_t currentel;
+    __asm volatile ("mrs %[curel], currentel" : [curel] "=r" (currentel));
+    return (currentel >> 2) & 0x3;
+}
+
+static inline lpaddr_t sysreg_read_ttbr0_el1(void)
+{
+    lpaddr_t ttbr0;
+    __asm volatile ("mrs %[ttbr], ttbr0_el1" : [ttbr] "=r" (ttbr0));
+    return ttbr0;
+}
+
+static inline lpaddr_t sysreg_read_ttbr0_el2(void)
+{
+    lpaddr_t ttbr0;
+    __asm volatile ("mrs %[ttbr], ttbr0_el2" : [ttbr] "=r" (ttbr0));
+    return ttbr0;
+}
+
+static inline lpaddr_t sysreg_read_ttbr0(void)
+{
+    uintptr_t currentel = get_current_el();
+    if (currentel == 1) {
+        return sysreg_read_ttbr0_el1();
+    } else if (currentel == 2) {
+        return sysreg_read_ttbr0_el2();
+    }
+    panic("%s: Unsupported EL: %d\n", __FUNCTION__, currentel);
+}
+
+static inline void sysreg_write_ttbr0_el1(lpaddr_t ttbr)
+{
+    __asm volatile ("msr ttbr0_el1, %[ttbr]" : [ttbr] "=r" (ttbr));
+}
+
+static inline void sysreg_write_ttbr0_el2(lpaddr_t ttbr)
+{
+    __asm volatile ("msr ttbr0_el2, %[ttbr]" : [ttbr] "=r" (ttbr));
+}
+
+static inline void sysreg_write_ttbr0(lpaddr_t ttbr)
+{
+    uintptr_t currentel = get_current_el();
+    if (currentel == 1) {
+        sysreg_write_ttbr0_el1(ttbr);
+    } else if (currentel == 2) {
+        sysreg_write_ttbr0_el2(ttbr);
+    }
+    panic("%s: Unsupported EL: %d\n", __FUNCTION__, currentel);
+}
+
+static inline lpaddr_t sysreg_read_ttbr1_el1(void)
+{
+    lpaddr_t ttbr1;
+    __asm volatile ("mrs %[ttbr], ttbr1_el1" : [ttbr] "=r" (ttbr1));
+    return ttbr1;
+}
+
+static inline lpaddr_t sysreg_read_ttbr1_el2(void)
+{
+    lpaddr_t ttbr1;
+    __asm volatile ("mrs %[ttbr], ttbr1_el2" : [ttbr] "=r" (ttbr1));
+    return ttbr1;
+}
+
+static inline lpaddr_t sysreg_read_ttbr1(void)
+{
+    uintptr_t currentel = get_current_el();
+    if (currentel == 1) {
+        return sysreg_read_ttbr1_el1();
+    } else if (currentel == 2) {
+        return sysreg_read_ttbr1_el2();
+    }
+    panic("%s: Unsupported EL: %d\n", __FUNCTION__, currentel);
+}
+
+static inline void sysreg_write_ttbr1_el1(lpaddr_t ttbr)
+{
+    __asm volatile ("msr ttbr1_el1, %[ttbr]" : [ttbr] "=r" (ttbr));
+}
+
+static inline void sysreg_write_ttbr1_el2(lpaddr_t ttbr)
+{
+    __asm volatile ("msr ttbr1_el2, %[ttbr]" : [ttbr] "=r" (ttbr));
+}
+
+static inline lpaddr_t sysreg_write_ttbr1(lpaddr_t ttbr)
+{
+    uintptr_t currentel = get_current_el();
+    if (currentel == 1) {
+        sysreg_write_ttbr1_el1(ttbr);
+    } else if (currentel == 2) {
+        sysreg_write_ttbr1_el2(ttbr);
+    }
+    panic("%s: Unsupported EL: %d\n", __FUNCTION__, currentel);
+}
+
+static inline uint32_t sysreg_read_ttbcr(void)
+{
+    panic("NYI");
+}
+
+static inline void sysreg_write_ttbcr(uint32_t ttbcr)
+{
+    panic("NYI");
+}
+
+static inline uint32_t sysreg_read_cache_status(void){
+    panic("NYI");
+}
+
+
+static inline void sysreg_disable_cache(void){
+
+    panic("NYI");
+
+    printf("WARNING! Caching has been disabled, configuration is: %"PRIx32"\n", sysreg_read_cache_status());
+
+}
+
+static inline void sysreg_invalidate_tlb(void)
+{
+    panic("NYI");
+}
+
+static inline uint8_t sysreg_get_cpu_id(void) {
+    panic("NYI");
+}
+
+/*
+ * Get the configuration base address
+ * This is described in the Cortex A9 TRM, 4.2.32
+ */
+static inline uint32_t sysreg_read_cbar(void)
+{
+    panic("NYI");
+}
+
+#endif // __SYSREG_H__