Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add gr712rc support - single core #470

Merged
merged 4 commits into from
Nov 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .codespell_ignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
PTD
ptd
1 change: 1 addition & 0 deletions hal/armv7m/arch/pmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#define PGHD_EXEC 0x00
#define PGHD_DEV 0x00
#define PGHD_NOT_CACHED 0x00
#define PGHD_READ 0x00

/* Page flags */
#define PAGE_FREE 0x00000001
Expand Down
1 change: 1 addition & 0 deletions hal/armv8m/arch/pmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#define PGHD_EXEC 0x00u
#define PGHD_DEV 0x00u
#define PGHD_NOT_CACHED 0x00u
#define PGHD_READ 0x00u

/* Page flags */
#define PAGE_FREE 0x00000001u
Expand Down
1 change: 1 addition & 0 deletions hal/ia32/arch/pmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#define PGHD_USER 0x04
#define PGHD_WRITE 0x02
#define PGHD_EXEC 0x00
#define PGHD_READ 0x00
#define PGHD_DEV PGHD_CACHE_UC
#define PGHD_NOT_CACHED PGHD_CACHE_UCM

Expand Down
12 changes: 9 additions & 3 deletions hal/sparcv8leon3/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,14 @@
# Copyright 2022 Phoenix Systems
#

include hal/sparcv8leon3/$(TARGET_SUBFAMILY)/Makefile
include hal/$(TARGET_SUFF)/gaisler/Makefile

CFLAGS += -Ihal/sparcv8leon3 -Ihal/sparcv8leon3/$(TARGET_SUBFAMILY)
CFLAGS := -Ihal/$(TARGET_SUFF) $(CFLAGS)

OBJS += $(addprefix $(PREFIX_O)hal/sparcv8leon3/, cpu.o exceptions.o hal.o interrupts.o pmap.o spinlock.o string.o _init.o _interrupts.o _traps.o)
OBJS += $(addprefix $(PREFIX_O)hal/$(TARGET_SUFF)/, cpu.o hal.o spinlock.o string.o _traps.o)

ifeq ($(findstring -DNOMMU,$(CPPFLAGS)),-DNOMMU)
OBJS += $(addprefix $(PREFIX_O)hal/$(TARGET_SUFF)/, exceptions-nommu.o pmap-nommu.o _interrupts-nommu.o)
else
OBJS += $(addprefix $(PREFIX_O)hal/$(TARGET_SUFF)/, exceptions.o pmap.o srmmu.o _interrupts.o)
endif
286 changes: 286 additions & 0 deletions hal/sparcv8leon3/_interrupts-nommu.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,286 @@
/*
* Phoenix-RTOS
*
* Operating system kernel
*
* Interrupts handlers (NOMMU) for sparcv8leon3
*
* Copyright 2022, 2023 Phoenix Systems
* Author: Lukasz Leczkowski
*
* This file is part of Phoenix-RTOS.
*
* %LICENSE%
*/

#define __ASSEMBLY__

#include <config.h>
#include <arch/cpu.h>

.extern hal_cpuKernelStack

.section ".text"
.align 4

.global _interrupts_dispatch
.type _interrupts_dispatch, #function

/* Interrupt handler
* on entry:
* %l0: psr
* %l1: pc
* %l2: npc
* %l3: irq number
*/
_interrupts_dispatch:
/* %g2, g3 used during manual window overflow */
mov %g2, %l4
mov %g3, %l5

mov %wim, %g2
/* check if we've just overflowed
* window overflow if wim == (1 << CWP)
* wim >> l0[4:0] - shift wim by CWP (lowest 5 bits from psr)
*/
srl %g2, %l0, %g3
cmp %g3, 1

bne irq_wovfl_done
sll %g2, (NWINDOWS - 1), %g3

/* calculate new wim: current %wim in %g2, %g3 is scratch */
srl %g2, 1, %g2

save
wr %g2, %g3, %wim
nop
nop
nop
std %l0, [%sp + 0x00]
std %l2, [%sp + 0x08]
std %l4, [%sp + 0x10]
std %l6, [%sp + 0x18]
std %i0, [%sp + 0x20]
std %i2, [%sp + 0x28]
std %i4, [%sp + 0x30]
std %fp, [%sp + 0x38]
restore

irq_wovfl_done:
/* check if we need to swap to kernel stack
* i.e. when PSR_PS is not set
*/
andcc %l0, PSR_PS, %g0
bnz irq_no_kstack_switch

set hal_cpuKernelStack, %l6
/* Extract CPU ID and add offset */
rd %asr17, %l7
srl %l7, 28, %l7
sll %l7, 2, %l7
ld [%l6 + %l7], %l7
ba irq_kstack_set
sub %l7, 0x50, %sp

irq_no_kstack_switch:
/* we came from kernel, make space for context */
sub %fp, 0x50, %sp

irq_kstack_set:
/* Save context on kernel stack - we have enough space for 1 window.
* Here only a part of thread context is saved,
* all windows are saved only if we're switching context.
*
* Registers saved:
* %sp, %y, %psr, PC, nPC, %g1, %g2 (in %l4), %g3 (in %l5), %g4-%g7, %i0-%i7
*/

st %sp, [%sp + 0x00] /* sp */
rd %y, %g2
st %g2, [%sp + 0x04] /* y */

std %l0, [%sp + 0x08] /* psr, PC */
st %l2, [%sp + 0x10] /* nPC */
st %g1, [%sp + 0x14] /* g1 */
std %l4, [%sp + 0x18] /* g2, g3 */
std %g4, [%sp + 0x20] /* g4, g5 */
std %g6, [%sp + 0x28] /* g6, g7 */

/* input registers here are the outputs of the interrupted window */

std %i0, [%sp + 0x30] /* i0, i1 */
std %i2, [%sp + 0x38] /* i2, i3 */
std %i4, [%sp + 0x40] /* i4, i5 */
std %fp, [%sp + 0x48] /* fp (task's sp), i7 */

mov %sp, %l7
sub %sp, 0x60, %sp

mov %l7, %o1 /* (cpu_context_t *) */

/* enable traps, disable interrupts */
or %l0, (PSR_PIL | PSR_ET), %l0
wr %l0, %psr
nop
nop
nop

/* void interrupts_dispatch(unsigned int irq, cpu_context_t *) */
call interrupts_dispatch
mov %l3, %o0 /* irq */

/* disable traps */
pwr 0, %psr
nop
nop
nop

/* l7 still points to bottom of context */
mov %l7, %sp

/* check if we're going to switch context (sp != *(sp)) */
ld [%sp], %g2
cmp %sp, %g2
be irq_no_switch
nop

/* We're switching, save used register windows on stack
* and load only the window we'll be returning to.
* The rest will be restored on window underflows.
*/

rd %psr, %g3
and %g3, PSR_CWP, %g3

/* Current state of registers:
* %g2 - %sp of new task
* %g3 - CWP
* freely usable: %g4, %g5
*/

/* set bit in register %g3, which corresponds to CWP
* %g3 = 1 << %g3 (CWP)
*/
mov 1, %g4
sll %g4, %g3, %g3

/* save context on stack */
sethi %hi(_interrupts_saveContext), %g5
jmpl %g5 + %lo(_interrupts_saveContext), %g1 /* clobbers %g1, %g3 */
rd %wim, %g4

/* At this point, we've saved all registers that the previous
* task used, and we're ready to switch to the new task.
*
* %g2 points to the new task's context.
*/

mov %g0, %wim /* we don't need it now */
ld [%g2 + 0x08], %g1
nop
andn %g1, PSR_ET, %g1 /* leave traps disabled */

/* Set %psr of the new task.
* This will cause window to be switched
* to the window in interrupt handler.
*/

wr %g1, %psr
/* no delay needed, we're using global registers */

sethi %hi(_interrupts_restoreContext), %g5
jmpl %g5 + %lo(_interrupts_restoreContext), %g1
nop

/* check CWP overflow (same as before) */
and %g2, PSR_CWP, %g2
add %g2, 1, %g2
cmp %g2, NWINDOWS
bne irq_cwp_done
mov 1, %g3

mov 0, %g2

irq_cwp_done:
/* set %wim to 1 << %g2 (CWP + 2) */
sll %g3, %g2, %g2
mov %g2, %wim

/* restore %g1, %g2, %g3 */
ld [%sp + 0x14], %g1

andn %l0, PSR_ET, %l0

ba irq_return
ldd [%sp + 0x18], %g2


irq_no_switch:
/* restore current window */
ld [%sp + 0x04], %g1 /* y */
ldd [%sp + 0x08], %l0 /* psr, PC */
wr %g1, %y
ld [%sp + 0x10], %l2 /* nPC */
ld [%sp + 0x14], %g1
ldd [%sp + 0x18], %g2
ldd [%sp + 0x20], %g4
ldd [%sp + 0x28], %g6

ldd [%sp + 0x30], %i0
ldd [%sp + 0x38], %i2
ldd [%sp + 0x40], %i4
ldd [%sp + 0x48], %fp

/* Check if restore would cause window underflow.
* After restore: CWP = CWP + 1 (mod NWINDOWS)
* i.e. wim >> (CWP + 1) == 1
*/

and %l0, PSR_CWP, %l5
add %l5, 1, %l5
cmp %l5, NWINDOWS
bne irq_cwp_done2
rd %wim, %l4

/* we'd end up in non-existent window #NWINDOWS, it means it's #0 */
mov 0, %l5

irq_cwp_done2:
/* l4 = wim, l5 = CWP + 1 (mod NWINDOWS)
* check if wim >> (CWP + 1) == 1 (window underflow)
*/
srl %l4, %l5, %l6
cmp %l6, 1
bne irq_return
/* uses the delay slot
* calculate new wim
* %l4 = current %wim
* wim = (wim << 1) ^ (wim >> (NWINDOWS - 1))
*/
sll %l4, 1, %l5
srl %l4, (NWINDOWS - 1), %l4
wr %l4, %l5, %wim
nop
nop
nop
restore
ldd [%sp + 0x00], %l0
ldd [%sp + 0x08], %l2
ldd [%sp + 0x10], %l4
ldd [%sp + 0x18], %l6
ldd [%sp + 0x20], %i0
ldd [%sp + 0x28], %i2
ldd [%sp + 0x30], %i4
ldd [%sp + 0x38], %fp
save

irq_return:
wr %l0, %psr
nop
nop
nop

jmp %l1
rett %l2
.size _interrupts_dispatch, . - _interrupts_dispatch
Loading
Loading