[arch][openrisc] fix up and get the OpenRISC port working again
Previous to now it had always relied on a custom patched gcc and a custom sim. In the interim since the initial port went in some time in 2015 GCC and QEMU have both officially picked up support for the architecture and the machine that was emulated in the previous emultor. Using gcc 10.2 fix up the build and get it basically working. Timers seem to not be working right but it's probably fairly easy to fix.
This commit is contained in:
@@ -31,6 +31,8 @@ static inline bool arch_ints_disabled(void) {
|
||||
return !(sr & (OR1K_SPR_SYS_SR_IEE_MASK | OR1K_SPR_SYS_SR_TEE_MASK));
|
||||
}
|
||||
|
||||
// Using builtin atomics
|
||||
#if 0
|
||||
static inline int atomic_add(volatile int *ptr, int val) {
|
||||
return __atomic_fetch_add(ptr, val, __ATOMIC_RELAXED);
|
||||
}
|
||||
@@ -62,6 +64,7 @@ static inline int atomic_cmpxchg(volatile int *ptr, int oldval, int newval) {
|
||||
|
||||
return oldval;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* use a global pointer to store the current_thread */
|
||||
extern struct thread *_current_thread;
|
||||
|
||||
20
arch/or1k/include/arch/aspace.h
Normal file
20
arch/or1k/include/arch/aspace.h
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Travis Geiselbrecht
|
||||
*
|
||||
* Use of this source code is governed by a MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <lk/compiler.h>
|
||||
|
||||
__BEGIN_CDECLS
|
||||
|
||||
struct arch_aspace {
|
||||
// nothing for now, does not support address spaces other than the kernel
|
||||
};
|
||||
|
||||
__END_CDECLS
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <lk/trace.h>
|
||||
#include <lk/debug.h>
|
||||
#include <lk/err.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <arch/mmu.h>
|
||||
#include <arch/or1k.h>
|
||||
@@ -38,10 +39,13 @@ void or1k_invalidate_tlb(vaddr_t vaddr, uint count) {
|
||||
switch (num_dtlb_ways) {
|
||||
case 4:
|
||||
mtspr_off(0, OR1K_SPR_DMMU_DTLBW_MR_ADDR(3, offs), 0);
|
||||
// fallthrough
|
||||
case 3:
|
||||
mtspr_off(0, OR1K_SPR_DMMU_DTLBW_MR_ADDR(2, offs), 0);
|
||||
// fallthrough
|
||||
case 2:
|
||||
mtspr_off(0, OR1K_SPR_DMMU_DTLBW_MR_ADDR(1, offs), 0);
|
||||
// fallthrough
|
||||
case 1:
|
||||
mtspr_off(0, OR1K_SPR_DMMU_DTLBW_MR_ADDR(0, offs), 0);
|
||||
}
|
||||
@@ -50,10 +54,13 @@ void or1k_invalidate_tlb(vaddr_t vaddr, uint count) {
|
||||
switch (num_itlb_ways) {
|
||||
case 4:
|
||||
mtspr_off(0, OR1K_SPR_IMMU_ITLBW_MR_ADDR(3, offs), 0);
|
||||
// fallthrough
|
||||
case 3:
|
||||
mtspr_off(0, OR1K_SPR_IMMU_ITLBW_MR_ADDR(2, offs), 0);
|
||||
// fallthrough
|
||||
case 2:
|
||||
mtspr_off(0, OR1K_SPR_IMMU_ITLBW_MR_ADDR(1, offs), 0);
|
||||
// fallthrough
|
||||
case 1:
|
||||
mtspr_off(0, OR1K_SPR_IMMU_ITLBW_MR_ADDR(0, offs), 0);
|
||||
}
|
||||
@@ -61,7 +68,7 @@ void or1k_invalidate_tlb(vaddr_t vaddr, uint count) {
|
||||
}
|
||||
}
|
||||
|
||||
status_t arch_mmu_query(vaddr_t vaddr, paddr_t *paddr, uint *flags) {
|
||||
status_t arch_mmu_query(arch_aspace_t *aspace, vaddr_t vaddr, paddr_t *paddr, uint *flags) {
|
||||
uint index = vaddr / SECTION_SIZE;
|
||||
uint32_t pte = or1k_kernel_translation_table[index];
|
||||
uint32_t vmask = SECTION_SIZE-1;
|
||||
@@ -95,8 +102,8 @@ status_t arch_mmu_query(vaddr_t vaddr, paddr_t *paddr, uint *flags) {
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
int arch_mmu_unmap(vaddr_t vaddr, uint count) {
|
||||
LTRACEF("vaddr = 0x%x, count = %d\n", vaddr, count);
|
||||
int arch_mmu_unmap(arch_aspace_t *aspace, vaddr_t vaddr, uint count) {
|
||||
LTRACEF("vaddr = 0x%lx, count = %d\n", vaddr, count);
|
||||
|
||||
if (!IS_PAGE_ALIGNED(vaddr))
|
||||
return ERR_INVALID_ARGS;
|
||||
@@ -124,12 +131,12 @@ int arch_mmu_unmap(vaddr_t vaddr, uint count) {
|
||||
return unmapped;
|
||||
}
|
||||
|
||||
int arch_mmu_map(vaddr_t vaddr, paddr_t paddr, uint count, uint flags) {
|
||||
int arch_mmu_map(arch_aspace_t *aspace, vaddr_t vaddr, paddr_t paddr, uint count, uint flags) {
|
||||
uint l1_index;
|
||||
uint32_t pte;
|
||||
uint32_t arch_flags = 0;
|
||||
|
||||
LTRACEF("vaddr = 0x%x, paddr = 0x%x, count = %d, flags = 0x%x\n", vaddr, paddr, count, flags);
|
||||
LTRACEF("vaddr = 0x%lx, paddr = 0x%lx, count = %d, flags = 0x%x\n", vaddr, paddr, count, flags);
|
||||
|
||||
if (!IS_PAGE_ALIGNED(vaddr) || !IS_PAGE_ALIGNED(paddr))
|
||||
return ERR_INVALID_ARGS;
|
||||
@@ -174,14 +181,14 @@ int arch_mmu_map(vaddr_t vaddr, paddr_t paddr, uint count, uint flags) {
|
||||
}
|
||||
|
||||
memset(l2_table, 0, PAGE_SIZE);
|
||||
paddr_t l2_pa = kvaddr_to_paddr(l2_table);
|
||||
paddr_t l2_pa = vaddr_to_paddr(l2_table);
|
||||
LTRACEF("allocated pagetable at %p, pa 0x%lx\n", l2_table, l2_pa);
|
||||
or1k_kernel_translation_table[l1_index] = l2_pa | arch_flags | OR1K_MMU_PG_PRESENT;
|
||||
}
|
||||
|
||||
uint l2_index = (vaddr % SECTION_SIZE) / PAGE_SIZE;
|
||||
|
||||
LTRACEF("l2_index = 0x%x, vaddr = 0x%x, paddr = 0x%x\n", l2_index, vaddr, paddr);
|
||||
LTRACEF("l2_index = 0x%x, vaddr = 0x%lx, paddr = 0x%lx\n", l2_index, vaddr, paddr);
|
||||
l2_table[l2_index] = paddr | arch_flags | OR1K_MMU_PG_PRESENT | OR1K_MMU_PG_L;
|
||||
|
||||
count--;
|
||||
@@ -193,4 +200,49 @@ int arch_mmu_map(vaddr_t vaddr, paddr_t paddr, uint count, uint flags) {
|
||||
return mapped;
|
||||
}
|
||||
|
||||
// initialize per address space
|
||||
status_t arch_mmu_init_aspace(arch_aspace_t *aspace, vaddr_t base, size_t size, uint flags) {
|
||||
LTRACEF("aspace %p, base %#lx, size %#zx, flags %#x\n", aspace, base, size, flags);
|
||||
|
||||
DEBUG_ASSERT(aspace);
|
||||
|
||||
// validate that the base + size is sane and doesn't wrap
|
||||
DEBUG_ASSERT(size > PAGE_SIZE);
|
||||
DEBUG_ASSERT(base + size - 1 > base);
|
||||
|
||||
#if 0
|
||||
aspace->flags = flags;
|
||||
if (flags & ARCH_ASPACE_FLAG_KERNEL) {
|
||||
// at the moment we can only deal with address spaces as globally defined
|
||||
DEBUG_ASSERT(base == KERNEL_ASPACE_BASE);
|
||||
DEBUG_ASSERT(size == KERNEL_ASPACE_SIZE);
|
||||
|
||||
aspace->base = base;
|
||||
aspace->size = size;
|
||||
aspace->pt_virt = kernel_pgtable;
|
||||
aspace->pt_phys = kernel_pgtable_phys;
|
||||
} else {
|
||||
PANIC_UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
LTRACEF("pt phys %#lx, pt virt %p\n", aspace->pt_phys, aspace->pt_virt);
|
||||
#endif
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
status_t arch_mmu_destroy_aspace(arch_aspace_t *aspace) {
|
||||
LTRACEF("aspace %p\n", aspace);
|
||||
|
||||
PANIC_UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
// load a new user address space context.
|
||||
// aspace argument NULL should load kernel-only context
|
||||
void arch_mmu_context_switch(arch_aspace_t *aspace) {
|
||||
LTRACEF("aspace %p\n", aspace);
|
||||
|
||||
PANIC_UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
#endif /* WITH_KERNEL_VM */
|
||||
|
||||
@@ -23,7 +23,7 @@ static uint32_t timer_freq;
|
||||
static volatile uint64_t ticks = 0;
|
||||
|
||||
status_t platform_set_periodic_timer(platform_timer_callback callback, void *arg, lk_time_t interval) {
|
||||
LTRACEF("cb %p, arg %p, interval %ld\n", callback, arg, interval);
|
||||
LTRACEF("cb %p, arg %p, interval %u\n", callback, arg, interval);
|
||||
|
||||
uint32_t ttmr = (uint64_t)timer_freq * interval / 1000;
|
||||
LTRACEF("count 0x%x\n", ttmr);
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
$DIR/make-parallel or1ksim &&
|
||||
or1k-elf-sim -f platform/or1ksim/or1ksim.cfg build-or1ksim/lk.elf $@
|
||||
"$DIR"/make-parallel or1ksim
|
||||
|
||||
qemu-system-or1k -nographic -M or1k-sim -cpu any \
|
||||
-kernel build-or1ksim/lk.elf $@
|
||||
|
||||
#or1k-elf-sim -f platform/or1ksim/or1ksim.cfg build-or1ksim/lk.elf $@
|
||||
|
||||
Reference in New Issue
Block a user