[arch][or1k] get working after SMP changes

This commit is contained in:
M1cha
2015-07-02 07:55:20 +02:00
committed by Travis Geiselbrecht
parent caec70a21b
commit 8e0afb2b5e
7 changed files with 128 additions and 12 deletions

View File

@@ -27,20 +27,12 @@ enum handler_return platform_tick(void);
void or1k_irq(void)
{
inc_critical_section();
if (platform_irq() == INT_RESCHEDULE)
thread_preempt();
dec_critical_section();
}
void or1k_tick(void)
{
inc_critical_section();
if (platform_tick() == INT_RESCHEDULE)
thread_preempt();
dec_critical_section();
}

View File

@@ -55,7 +55,6 @@ static void dump_fault_frame(struct or1k_iframe *frame)
static void exception_die(struct or1k_iframe *frame, const char *msg)
{
inc_critical_section();
dprintf(CRITICAL, msg);
dump_fault_frame(frame);

View File

@@ -42,6 +42,13 @@ static inline void arch_disable_ints(void)
mtspr(OR1K_SPR_SYS_SR_ADDR, sr);
}
static inline bool arch_ints_disabled(void)
{
uint32_t sr = mfspr(OR1K_SPR_SYS_SR_ADDR);
return !(sr & (OR1K_SPR_SYS_SR_IEE_MASK | OR1K_SPR_SYS_SR_TEE_MASK));
}
static inline int atomic_add(volatile int *ptr, int val)
{
return __atomic_fetch_add(ptr, val, __ATOMIC_RELAXED);
@@ -93,4 +100,9 @@ static inline void set_current_thread(struct thread *t)
}
static inline uint32_t arch_cycle_count(void) { return 0; }
static inline uint arch_curr_cpu_num(void)
{
return 0;
}
#endif // !ASSEMBLY

View File

@@ -0,0 +1,92 @@
/*
* Copyright (c) 2015 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#pragma once
#include <arch/ops.h>
#include <stdbool.h>
#if WITH_SMP
#error microblaze does not support SMP
#endif
#define SPIN_LOCK_INITIAL_VALUE (0)
typedef unsigned int spin_lock_t;
typedef unsigned int spin_lock_saved_state_t;
typedef unsigned int spin_lock_save_flags_t;
static inline void arch_spin_lock(spin_lock_t *lock)
{
*lock = 1;
}
static inline int arch_spin_trylock(spin_lock_t *lock)
{
return 0;
}
static inline void arch_spin_unlock(spin_lock_t *lock)
{
*lock = 0;
}
static inline void arch_spin_lock_init(spin_lock_t *lock)
{
*lock = SPIN_LOCK_INITIAL_VALUE;
}
static inline bool arch_spin_lock_held(spin_lock_t *lock)
{
return *lock != 0;
}
/* default arm flag is to just disable plain irqs */
#define ARCH_DEFAULT_SPIN_LOCK_FLAG_INTERRUPTS 0
enum {
/* private */
SPIN_LOCK_STATE_RESTORE_IRQ = 1,
};
static inline void
arch_interrupt_save(spin_lock_saved_state_t *statep, spin_lock_save_flags_t flags)
{
spin_lock_saved_state_t state = 0;
if (!arch_ints_disabled()) {
state |= SPIN_LOCK_STATE_RESTORE_IRQ;
arch_disable_ints();
}
*statep = state;
}
static inline void
arch_interrupt_restore(spin_lock_saved_state_t old_state, spin_lock_save_flags_t flags)
{
if (old_state & SPIN_LOCK_STATE_RESTORE_IRQ)
arch_enable_ints();
}

View File

@@ -15,6 +15,9 @@ MODULE_SRCS += \
$(LOCAL_DIR)/mmu.c \
$(LOCAL_DIR)/faults.c
GLOBAL_DEFINES += \
SMP_MAX_CPUS=1
# set the default toolchain to or1k elf and set a #define
ifndef TOOLCHAIN_PREFIX
TOOLCHAIN_PREFIX := or1k-elf-

View File

@@ -44,7 +44,8 @@ static void initial_thread_func(void)
#endif
/* exit the implicit critical section we're within */
exit_critical_section();
spin_unlock(&thread_lock);
arch_enable_ints();
int ret = ct->entry(ct->arg);
@@ -74,3 +75,11 @@ void arch_context_switch(thread_t *oldthread, thread_t *newthread)
or1k_context_switch(&oldthread->arch.cs_frame, &newthread->arch.cs_frame);
}
void arch_dump_thread(thread_t *t)
{
if (t->state != THREAD_RUNNING) {
dprintf(INFO, "\tarch: ");
dprintf(INFO, "sp 0x%x\n", t->arch.cs_frame.r1);
}
}

View File

@@ -27,6 +27,13 @@
#include <platform/pic.h>
#include <arch/or1k.h>
static spin_lock_t gicd_lock;
#if WITH_LIB_SM
#define GICD_LOCK_FLAGS SPIN_LOCK_FLAG_IRQ_FIQ
#else
#define GICD_LOCK_FLAGS SPIN_LOCK_FLAG_INTERRUPTS
#endif
struct int_handler_struct {
int_handler handler;
void *arg;
@@ -36,15 +43,17 @@ static struct int_handler_struct int_handler_table[MAX_INT];
void register_int_handler(unsigned int vector, int_handler handler, void *arg)
{
spin_lock_saved_state_t state;
if (vector >= MAX_INT)
panic("%s: vector out of range %d\n", __FUNCTION__, vector);
enter_critical_section();
spin_lock_save(&gicd_lock, &state, GICD_LOCK_FLAGS);
int_handler_table[vector].handler = handler;
int_handler_table[vector].arg = arg;
exit_critical_section();
spin_unlock_restore(&gicd_lock, state, GICD_LOCK_FLAGS);
}
status_t mask_interrupt(unsigned int vector)