sparcisr.c 1.37 KB
Newer Older
1 2 3 4 5 6 7 8
/*
 * This file is part of the MicroPython port to LEON platforms
 * Copyright (c) 2017 George Robotics Limited
 */

#include <stdint.h>
#include "leon-common/sparcisr.h"

9 10
#if RTEMS_4_8_EDISOFT

11 12 13 14 15 16 17 18
// This function retrieves the value of the Trap Base Register, to be used
// to install a window flushing trap handler next.
static void TRAP_read_TBR(volatile uint32_t* const tbrPtr) {
    asm("mov %0, %%o1" : : "r" (tbrPtr) : "%o1");
    asm("rd %%tbr, %%o0" : : : "%o0");
    asm("st %o0, [%o1]");
}

19 20 21 22 23 24
// This function installs the "ta 3" ISR which handles window flushing.
// It is only needed for Edisoft RTEMS 4.8 because the trap handler is not
// included in that version, but it is needed by MicroPython to implement
// setjmp/longjmp calls for exception handling.
void sparc_install_ta_3_window_flush_isr(void) {
    extern int sparc_window_flush_trap_handler(void);
25 26 27 28 29
    volatile uint32_t tbr = 0;
    TRAP_read_TBR(&tbr);
    tbr &= 0xfffff000;
    tbr |= 0x830;
    uint32_t *m = (uint32_t*)tbr;
30 31 32 33 34 35
    uint32_t addr = (uint32_t)sparc_window_flush_trap_handler;
    m[0] = 0xa1480000; // rd %psr, %l0
    m[1] = 0x29100000 | (addr >> 10); // sethi %hi(addr), %l4
    m[2] = 0x81c52000 | (addr & 0x3ff); // jmp %l4 + (addr & 0x3ff)
    m[3] = 0xa6102083; // mov 0x83, %l3
}
36 37 38 39 40 41 42 43

#else

// For non-Edisoft builds the "ta 3" ISR is already installed.
void sparc_install_ta_3_window_flush_isr(void) {
}

#endif