From 91b7dc6abfc3fc58a90cb08d224cd14a991bf1fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Leczkowski?= Date: Wed, 14 Aug 2024 16:43:24 +0200 Subject: [PATCH] add sparcv8leon3-generic target JIRA: RTOS-887 --- hal/sparcv8leon3/_traps.S | 2 +- hal/sparcv8leon3/gaisler/Makefile | 2 + hal/sparcv8leon3/gaisler/generic/Makefile | 9 + hal/sparcv8leon3/gaisler/generic/_init.S | 276 ++++++++++++++++++++ hal/sparcv8leon3/gaisler/generic/config.h | 41 +++ hal/sparcv8leon3/gaisler/generic/generic.c | 138 ++++++++++ hal/sparcv8leon3/gaisler/generic/generic.h | 43 +++ hal/sparcv8leon3/gaisler/grlib-tn-0018.h | 21 +- include/arch/sparcv8leon3/generic/generic.h | 49 ++++ include/arch/sparcv8leon3/sparcv8leon3.h | 2 + 10 files changed, 573 insertions(+), 10 deletions(-) create mode 100644 hal/sparcv8leon3/gaisler/generic/Makefile create mode 100644 hal/sparcv8leon3/gaisler/generic/_init.S create mode 100644 hal/sparcv8leon3/gaisler/generic/config.h create mode 100644 hal/sparcv8leon3/gaisler/generic/generic.c create mode 100644 hal/sparcv8leon3/gaisler/generic/generic.h create mode 100644 include/arch/sparcv8leon3/generic/generic.h diff --git a/hal/sparcv8leon3/_traps.S b/hal/sparcv8leon3/_traps.S index 4b6c4e492..b926b2d2f 100644 --- a/hal/sparcv8leon3/_traps.S +++ b/hal/sparcv8leon3/_traps.S @@ -170,7 +170,7 @@ _start: .type _traps_stErrHandler, #function _traps_stErrHandler: - sta %g0, [%g0] ASI_CCTRL + sta %g0, [%g0] ASI_CACHE_CTRL TN_0018_WAIT_ICACHE(%l3, %l4) diff --git a/hal/sparcv8leon3/gaisler/Makefile b/hal/sparcv8leon3/gaisler/Makefile index f48e0119f..f72ff9675 100644 --- a/hal/sparcv8leon3/gaisler/Makefile +++ b/hal/sparcv8leon3/gaisler/Makefile @@ -16,4 +16,6 @@ ifeq ($(TARGET_SUBFAMILY), gr712rc) OBJS += $(addprefix $(PREFIX_O)hal/$(TARGET_SUFF)/gaisler/, irqmp.o) else ifeq ($(TARGET_SUBFAMILY), gr716) OBJS += $(addprefix $(PREFIX_O)hal/$(TARGET_SUFF)/gaisler/, irqamp.o) +else ifeq ($(TARGET_SUBFAMILY), generic) + OBJS += $(addprefix $(PREFIX_O)hal/$(TARGET_SUFF)/gaisler/, irqmp.o) endif diff --git a/hal/sparcv8leon3/gaisler/generic/Makefile b/hal/sparcv8leon3/gaisler/generic/Makefile new file mode 100644 index 000000000..1354f7d83 --- /dev/null +++ b/hal/sparcv8leon3/gaisler/generic/Makefile @@ -0,0 +1,9 @@ +# +# Makefile for Phoenix-RTOS kernel (sparcv8leon3-generic HAL) +# +# Copyright 2024 Phoenix Systems +# + +include hal/tlb/Makefile + +OBJS += $(addprefix $(PREFIX_O)hal/$(TARGET_SUFF)/gaisler/$(TARGET_SUBFAMILY)/, generic.o _init.o) diff --git a/hal/sparcv8leon3/gaisler/generic/_init.S b/hal/sparcv8leon3/gaisler/generic/_init.S new file mode 100644 index 000000000..564376aba --- /dev/null +++ b/hal/sparcv8leon3/gaisler/generic/_init.S @@ -0,0 +1,276 @@ +/* + * Phoenix-RTOS + * + * Operating system kernel + * + * Low level initialization + * + * Copyright 2024 Phoenix Systems + * Author: Lukasz Leczkowski + * + * This file is part of Phoenix-RTOS. + * + * %LICENSE% + */ + +#define __ASSEMBLY__ + +#include "config.h" +#include +#include + +#include "hal/sparcv8leon3/srmmu.h" + +#define ADDR_SRAM 0x40000000 + +#define PHY_ADDR(va) ((va) - VADDR_KERNEL + ADDR_SRAM) + +#define ADDR_CTXTAB PHY_ADDR(pmap_common) +#define ADDR_PDIR1 (ADDR_CTXTAB + 0x400) +#define ADDR_PDIR2 (ADDR_PDIR1 + 0x400) +#define ADDR_PDIR3 (ADDR_CTXTAB + 0x1000) + +#define VADDR_SYSPAGE (_end + SIZE_PAGE - 1) +#define PADDR_SYSPAGE PHY_ADDR(VADDR_SYSPAGE) + +#define VADDR_STACK (pmap_common + 7 * SIZE_PAGE) + + +.extern syspage +.extern _end + + +.macro calc_ptd paddr out + srl \paddr, 6, \out + sll \out, 2, \out + or \out, PAGE_DESCR, \out +.endm + + +.macro set_page_align addr out + sethi %hi(\addr), \out + srl \out, 12, \out + sll \out, 12, \out +.endm + + +.section ".text" +.align 4 +.global _init +_init: + wr %g0, %wim + nop + nop + nop + + wr %g0, PSR_S, %psr + + /* Get CPU ID */ + rd %asr17, %g1 + srl %g1, 28, %g1 + cmp %g1, %g0 + bnz _init_core + nop + + /* %g2 = syspage pa (from plo) */ + set PHY_ADDR(syspage), %g3 + set_page_align VADDR_SYSPAGE, %g1 + + /* store VADDR_SYSPAGE in syspage */ + st %g1, [%g3] + + set PHY_ADDR(relOffs), %g4 + /* %l0 = offset between VADDR_SYSPAGE and syspage pa */ + sub %g1, %g2, %l0 + st %l0, [%g4] + + set_page_align PADDR_SYSPAGE, %g3 + /* calculate pa of syspage end */ + ld [%g2 + 4], %l1 /* %l1 = syspage->size */ + add %g2, %l1, %l2 /* %l2 = plo syspage end */ + +syspage_cpy: + ld [%g2], %l0 + st %l0, [%g3] + add %g2, 4, %g2 + cmp %g2, %l2 + bl syspage_cpy + add %g3, 4, %g3 + + /* Flush TLB, I and D cache */ + sta %g0, [%g0] ASI_FLUSH_ALL + + /* Clear page tables */ + set ADDR_CTXTAB, %g2 /* %g2 = &pmap_common.pdir1 (phy) */ + set 0x5000, %g3 + clr %g1 + +clear_pdirs: + subcc %g3, 8, %g3 + std %g0, [%g2] + bnz clear_pdirs + add %g2, 8, %g2 + + /* Set context table pointer */ + set ADDR_CTXTAB, %g3 + set ADDR_PDIR1, %g4 + calc_ptd %g4, %g4 + st %g4, [%g3] + srl %g3, 6, %g3 + sll %g3, 2, %g3 + set MMU_CTX_PTR, %g4 + sta %g3, [%g4] ASI_MMU_REGS + + /* Choose context 0 */ + set MMU_CTX, %g3 + sta %g0, [%g3] ASI_MMU_REGS + + /* Set up page table level 1 */ + + set ADDR_PDIR1, %g1 /* %g1 = pmap_common.pdir1 */ + set ADDR_PDIR2, %g3 /* %g3 = pmap_common.pdir2 */ + + /* V 0x40000000 -> P 0x40000000 */ + sethi %hi(ADDR_SRAM), %g2 + srl %g2, 24, %g2 + sll %g2, 2, %g2 + add %g1, %g2, %g4 /* %g4 = &pmap_common.pdir1[(ADDR_SRAM >> 24)] */ + calc_ptd %g3, %g5 + st %g5, [%g4] /* pmap_common.pdir1[(ADDR_SRAM >> 24)] = PTD(&pmap_common.pdir2[0]) */ + + /* V 0xc0000000 -> P 0x40000000 */ + sethi %hi(VADDR_KERNEL), %g2 + srl %g2, 24, %g2 + sll %g2, 2, %g2 + /* %g1 = &pmap_common.pdir1 */ + add %g1, %g2, %g4 /* %g4 = &pmap_common.pdir1[(VADDR_KERNEL >> 24)] */ + st %g5, [%g4] /* pmap_common.pdir1[(VADDR_KERNEL >> 24)] = PTD(&pmap_common.pdir2[0]) */ + + /* Setup page tables level 2 & 3 */ + + set ADDR_PDIR2, %g1 /* %g1 = pmap_common.pdir2 */ + set ADDR_PDIR3, %g2 /* %g2 = pmap_common.pdir3 */ + sethi %hi(0x40000), %g3 /* 0x40000 = 256KB */ + sethi %hi(ADDR_SRAM), %g6 + or %g1, 0x100, %g5 /* end = 64 entries */ + set 0x1000, %l0 + + /* for (int i = 0; i < 64; i++) { + * pmap_common.pdir2[i] = PTD(&pmap_common.pdir3[i][0]); + * for (int j = 0; j < 64; j++) + * pmap_common.pdir3[i][j] = PTE(0x40000000 + (i * 256KB) + (j * 4KB)); + * } + */ + +set_pdir2: + add %g6, %g3, %g7 + calc_ptd %g2, %l2 + st %l2, [%g1] /* pmap_common.pdir2[i] = &pmap_common.pdir3[i][0] */ +set_pdir3: + srl %g6, 12, %l1 + sll %l1, 8, %l1 + or %l1, ((1 << 7) | (0x7 << 2) | PAGE_ENTRY), %l1 /* cacheable, supervisor RWX */ + st %l1, [%g2] + add %g6, %l0, %g6 + cmp %g6, %g7 + bne set_pdir3 + add %g2, 4, %g2 + + add %g1, 4, %g1 + cmp %g1, %g5 + bne set_pdir2 + nop + + /* Enable MMU */ + mov 0x1, %g1 + sta %g1, [%g0] ASI_MMU_REGS + + /* Set up trap table */ + sethi %hi(_trap_table), %g1 + wr %g1, %tbr + + /* Set PSR to "supervisor", enable traps, disable interrupts, set CWP to 0 */ + mov %psr, %g1 + or %g1, (PSR_ET | PSR_S | PSR_PIL), %g1 + andn %g1, (PSR_CWP), %g1 + wr %g1, %psr + nop + nop + nop + + wr %g0, 0x2, %wim + + /* Set stack pointer */ + clr %fp + set VADDR_STACK, %sp + sub %sp, 0x60, %sp + + set main, %g1 + call %g1 + mov %g0, %g1 +.size _init, . - _init + + +.global _init_core +.type _init_core, #function +_init_core: + /* Flush and enable cache */ + flush + set 0x81000f, %g1 + sta %g1, [%g0] ASI_CACHE_CTRL + + /* Set context table pointer */ + set ADDR_CTXTAB, %g3 + set ADDR_PDIR1, %g4 + calc_ptd %g4, %g4 + st %g4, [%g3] + srl %g3, 6, %g3 + sll %g3, 2, %g3 + set MMU_CTX_PTR, %g4 + sta %g3, [%g4] ASI_MMU_REGS + + clr %fp + set VADDR_STACK, %sp + + /* Get CPU ID */ + rd %asr17, %g1 + srl %g1, 28, %g1 + sll %g1, 12, %g1 + add %sp, %g1, %sp + sub %sp, 0x60, %sp + + /* Enable MMU */ + mov 0x1, %g1 + sta %g1, [%g0] ASI_MMU_REGS + + /* Set up trap table */ + sethi %hi(_trap_table), %g1 + wr %g1, %tbr + + mov %psr, %g1 + or %g1, (PSR_ET | PSR_S | PSR_PIL), %g1 + andn %g1, (PSR_CWP), %g1 + wr %g1, %psr + + /* Switch to virtual memory */ + sethi %hi(_vmem_switch), %g1 + jmp %g1 + %lo(_vmem_switch) + wr %g0, 0x2, %wim + +_vmem_switch: + call hal_cpuInitCore + nop + + /* Enable interrupts and wait to be scheduled */ + mov %psr, %g1 + andn %g1, (PSR_PIL), %g1 + wr %g1, %psr + nop + nop + nop + +_init_core_loop: + wr %g0, %asr19 + ba _init_core_loop + nop +.size _init_core, . - _init_core diff --git a/hal/sparcv8leon3/gaisler/generic/config.h b/hal/sparcv8leon3/gaisler/generic/config.h new file mode 100644 index 000000000..e13c539f3 --- /dev/null +++ b/hal/sparcv8leon3/gaisler/generic/config.h @@ -0,0 +1,41 @@ +/* + * Phoenix-RTOS + * + * Operating system kernel + * + * Configuration file for sparcv8leon3-generic + * + * Copyright 2024 Phoenix Systems + * Author: Lukasz Leczkowski + * + * This file is part of Phoenix-RTOS. + * + * %LICENSE% + */ + +#ifndef _HAL_CONFIG_H_ +#define _HAL_CONFIG_H_ + + +#ifndef __ASSEMBLY__ + + +#include "generic.h" + +#include "include/arch/sparcv8leon3/syspage.h" +#include "include/syspage.h" + +#define HAL_NAME_PLATFORM "SPARCv8 LEON3-Generic" + +#define ADDR_RAM 0x40000000 +#define SIZE_RAM (128 * 1024 * 1024) /* 128 MB */ + + +#endif /* __ASSEMBLY__ */ + + +#define NWINDOWS 8 +#define NUM_CPUS 1 + + +#endif diff --git a/hal/sparcv8leon3/gaisler/generic/generic.c b/hal/sparcv8leon3/gaisler/generic/generic.c new file mode 100644 index 000000000..aace2a064 --- /dev/null +++ b/hal/sparcv8leon3/gaisler/generic/generic.c @@ -0,0 +1,138 @@ +/* + * Phoenix-RTOS + * + * Operating system kernel + * + * HAL internal functions for sparcv8leon3-generic + * + * Copyright 2024 Phoenix Systems + * Author: Lukasz Leczkowski + * + * This file is part of Phoenix-RTOS. + * + * %LICENSE% + */ + +#include + +#include "hal/cpu.h" +#include "hal/interrupts.h" +#include "hal/tlb/tlb.h" +#include "hal/sparcv8leon3/sparcv8leon3.h" + +#include "hal/gaisler/ambapp.h" + +#include "include/arch/sparcv8leon3/generic/generic.h" + +#include "config.h" + + +static struct { + spinlock_t pltctlSp; + intr_handler_t tlbIrqHandler; +} generic_common; + + +volatile u32 hal_cpusStarted; + + +void hal_cpuHalt(void) +{ + /* clang-format off */ + __asm__ volatile ("wr %g0, %asr19"); + /* clang-format on */ +} + + +void hal_cpuInitCore(void) +{ + hal_tlbInitCore(hal_cpuGetID()); + hal_cpuAtomicInc(&hal_cpusStarted); +} + + +void _hal_cpuInit(void) +{ + hal_cpusStarted = 0; + hal_cpuInitCore(); + hal_cpuStartCores(); + + while (hal_cpusStarted != NUM_CPUS) { + } +} + + +int gaisler_setIomuxCfg(u8 pin, u8 opt, u8 pullup, u8 pulldn) +{ + (void)pin; + (void)opt; + (void)pullup; + (void)pulldn; + + return 0; +} + + +void hal_wdgReload(void) +{ +} + + +int hal_platformctl(void *ptr) +{ + platformctl_t *data = (platformctl_t *)ptr; + spinlock_ctx_t sc; + int ret = -1; + + hal_spinlockSet(&generic_common.pltctlSp, &sc); + + switch (data->type) { + case pctl_iomux: + if (data->action == pctl_set) { + ret = gaisler_setIomuxCfg(data->task.iocfg.pin, data->task.iocfg.opt, data->task.iocfg.pullup, data->task.iocfg.pulldn); + } + break; + + case pctl_ambapp: + if (data->action == pctl_get) { + ret = ambapp_findSlave(data->task.ambapp.dev, data->task.ambapp.instance); + } + break; + + case pctl_reboot: + if ((data->action == pctl_set) && (data->task.reboot.magic == PCTL_REBOOT_MAGIC)) { + hal_cpuReboot(); + } + break; + + default: + break; + } + hal_spinlockClear(&generic_common.pltctlSp, &sc); + + return ret; +} + + +void hal_cpuReboot(void) +{ + /* TODO */ + for (;;) { + } + + __builtin_unreachable(); +} + + +void _hal_platformInit(void) +{ + hal_spinlockCreate(&generic_common.pltctlSp, "pltctl"); + + generic_common.tlbIrqHandler.f = hal_tlbIrqHandler; + generic_common.tlbIrqHandler.n = TLB_IRQ; + generic_common.tlbIrqHandler.data = NULL; + + hal_interruptsSetHandler(&generic_common.tlbIrqHandler); + + ambapp_init(); +} diff --git a/hal/sparcv8leon3/gaisler/generic/generic.h b/hal/sparcv8leon3/gaisler/generic/generic.h new file mode 100644 index 000000000..62c0f1e1a --- /dev/null +++ b/hal/sparcv8leon3/gaisler/generic/generic.h @@ -0,0 +1,43 @@ +/* + * Phoenix-RTOS + * + * Operating system kernel + * + * HAL internal functions for sparcv8leon3-generic + * + * Copyright 2024 Phoenix Systems + * Author: Lukasz Leczkowski + * + * This file is part of Phoenix-RTOS. + * + * %LICENSE% + */ + +#ifndef _HAL_GENERIC_H_ +#define _HAL_GENERIC_H_ + + +#ifndef __ASSEMBLY__ + + +#include "hal/types.h" +#include + +#include "hal/gaisler/ambapp.h" + +#include "include/arch/sparcv8leon3/generic/generic.h" + + +int gaisler_setIomuxCfg(u8 pin, u8 opt, u8 pullup, u8 pulldn); + + +int hal_platformctl(void *ptr); + + +void _hal_platformInit(void); + + +#endif /* __ASSEMBLY__ */ + + +#endif diff --git a/hal/sparcv8leon3/gaisler/grlib-tn-0018.h b/hal/sparcv8leon3/gaisler/grlib-tn-0018.h index 656514ba0..b929ed73a 100644 --- a/hal/sparcv8leon3/gaisler/grlib-tn-0018.h +++ b/hal/sparcv8leon3/gaisler/grlib-tn-0018.h @@ -16,11 +16,14 @@ #ifndef _GRLIB_TN_0018_H_ #define _GRLIB_TN_0018_H_ + +#include "hal/sparcv8leon3/srmmu.h" + + #ifdef LEON3_TN_0018_FIX /* LEON3 Cache controller register - ASI 2 */ -#define ASI_CCTRL 0x2 #define CCTRL_IP_BIT 15 /* ICache flush pending bit */ #define CCTRL_ICS 0x3 /* ICache state */ @@ -29,7 +32,7 @@ #define TN_0018_WAIT_ICACHE(out1, out2) \ 1: \ /* Wait for ICache flush to complete */; \ - lda [%g0] ASI_CCTRL, out1; \ + lda [%g0] ASI_CACHE_CTRL, out1; \ srl out1, CCTRL_IP_BIT, out2; \ andcc out2, 1, %g0; \ bne 1b; \ @@ -37,13 +40,13 @@ #define TN_0018_FIX(in1, in2) \ -.align 0x20 /* Align sta for performance */; \ - sta in2, [%g0] ASI_CCTRL /* Disable ICache */; \ - nop /* Delay */; \ - or %l1, %l1, %l1 /* Delay + catch rf parity error on l1 */; \ - or %l2, %l2, %l2 /* Delay + catch rf parity error on l2 */; \ - sta in1, [%g0] ASI_CCTRL /* Re-enable ICache after rett */; \ - nop /* Delay ensures insn after gets cached */ +.align 0x20 /* Align sta for performance */; \ + sta in2, [%g0] ASI_CACHE_CTRL /* Disable ICache */; \ + nop /* Delay */; \ + or %l1, %l1, %l1 /* Delay + catch rf parity error on l1 */; \ + or %l2, %l2, %l2 /* Delay + catch rf parity error on l2 */; \ + sta in1, [%g0] ASI_CACHE_CTRL /* Re-enable ICache after rett */; \ + nop /* Delay ensures insn after gets cached */ #else diff --git a/include/arch/sparcv8leon3/generic/generic.h b/include/arch/sparcv8leon3/generic/generic.h new file mode 100644 index 000000000..7fcec9d7b --- /dev/null +++ b/include/arch/sparcv8leon3/generic/generic.h @@ -0,0 +1,49 @@ +/* + * Phoenix-RTOS + * + * Operating system kernel + * + * LEON3 Generic basic peripherals control functions + * + * Copyright 2024 Phoenix Systems + * Author: Lukasz Leczkowski + * + * This file is part of Phoenix-RTOS. + * + * %LICENSE% + */ + +#ifndef _PHOENIX_ARCH_GENERIC_H_ +#define _PHOENIX_ARCH_GENERIC_H_ + +#define PCTL_REBOOT_MAGIC 0xaa55aa55UL + +/* clang-format off */ + +typedef struct { + enum { pctl_set = 0, pctl_get } action; + enum { pctl_iomux = 0, pctl_ambapp, pctl_reboot } type; + + union { + struct { + unsigned char pin; + unsigned char opt; + unsigned char pullup; + unsigned char pulldn; + } iocfg; + + struct { + struct _ambapp_dev_t *dev; + unsigned int *instance; + } ambapp; + + struct { + unsigned int magic; + } reboot; + } task; +} __attribute__((packed)) platformctl_t; + +/* clang-format on */ + + +#endif diff --git a/include/arch/sparcv8leon3/sparcv8leon3.h b/include/arch/sparcv8leon3/sparcv8leon3.h index 979272802..76e07f72e 100644 --- a/include/arch/sparcv8leon3/sparcv8leon3.h +++ b/include/arch/sparcv8leon3/sparcv8leon3.h @@ -21,6 +21,8 @@ #include "gr716/gr716.h" #elif defined(__CPU_GR712RC) #include "gr712rc/gr712rc.h" +#elif defined(__CPU_GENERIC) +#include "generic/generic.h" #else #error "Unsupported TARGET" #endif