[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:
Travis Geiselbrecht
2020-10-21 02:19:51 -07:00
parent 917906e4a4
commit 01f9a97dc1
6 changed files with 91 additions and 10 deletions

View File

@@ -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;

View 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

View File

@@ -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 */

View File

@@ -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);

View File

@@ -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 $@