From 89705cb065fc9e9218450001e58e2f1b911f6c79 Mon Sep 17 00:00:00 2001 From: Travis Geiselbrecht Date: Sat, 12 Oct 2019 21:54:04 -0700 Subject: [PATCH] [arch][vax] initial stab at booting on a vax Booting on a real MicroVAX 3100/40 via netboot and on simh emulating a micrvax 3900. Doesn't fully work, lots of stuff is stubbed out, but it starts to run and hits unimplemented bits and stops. --- arch/vax/arch.c | 57 +++++++++ arch/vax/asm.S | 0 arch/vax/include/arch/arch_ops.h | 71 +++++++++++ arch/vax/include/arch/arch_thread.h | 43 +++++++ arch/vax/include/arch/defines.h | 16 +++ arch/vax/include/arch/riscv.h | 77 ++++++++++++ arch/vax/include/arch/spinlock.h | 58 +++++++++ arch/vax/include/arch/vax.h | 8 ++ arch/vax/include/arch/vax/mtpr.h | 188 ++++++++++++++++++++++++++++ arch/vax/linker.ld | 118 +++++++++++++++++ arch/vax/rules.mk | 55 ++++++++ arch/vax/start.S | 62 +++++++++ arch/vax/thread.c | 68 ++++++++++ lib/libc/string/arch/vax/rules.mk | 11 ++ platform/vax/console.c | 39 ++++++ platform/vax/init.c | 20 +++ platform/vax/rom.S | 10 ++ platform/vax/rules.mk | 53 ++++++++ platform/vax/timer.c | 18 +++ project/vax-test.mk | 6 + target/vax/rules.mk | 9 ++ 21 files changed, 987 insertions(+) create mode 100644 arch/vax/arch.c create mode 100644 arch/vax/asm.S create mode 100644 arch/vax/include/arch/arch_ops.h create mode 100644 arch/vax/include/arch/arch_thread.h create mode 100644 arch/vax/include/arch/defines.h create mode 100644 arch/vax/include/arch/riscv.h create mode 100644 arch/vax/include/arch/spinlock.h create mode 100644 arch/vax/include/arch/vax.h create mode 100644 arch/vax/include/arch/vax/mtpr.h create mode 100644 arch/vax/linker.ld create mode 100644 arch/vax/rules.mk create mode 100644 arch/vax/start.S create mode 100644 arch/vax/thread.c create mode 100644 lib/libc/string/arch/vax/rules.mk create mode 100644 platform/vax/console.c create mode 100644 platform/vax/init.c create mode 100644 platform/vax/rom.S create mode 100644 platform/vax/rules.mk create mode 100644 platform/vax/timer.c create mode 100644 project/vax-test.mk create mode 100644 target/vax/rules.mk diff --git a/arch/vax/arch.c b/arch/vax/arch.c new file mode 100644 index 00000000..11c48fde --- /dev/null +++ b/arch/vax/arch.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2019 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 + */ +#include +#include +#include +#include +#include +#include + +#define LOCAL_TRACE 0 + +void arch_early_init(void) { + // set the top level exception handler + //riscv_csr_write(mtvec, (uintptr_t)&riscv_exception_entry); + + // mask all exceptions, just in case + //riscv_csr_clear(mstatus, RISCV_STATUS_MIE); + //riscv_csr_clear(mie, RISCV_MIE_MTIE | RISCV_MIE_MSIE | RISCV_MIE_SEIE | RISCV_MIE_MEIE); + + // enable cycle counter (disabled for now, unimplemented on sifive-e) + //riscv_csr_set(mcounteren, 1); +} + +void arch_init(void) { + // print some arch info + //dprintf(INFO, "RISCV: mvendorid %#lx marchid %#lx mimpid %#lx mhartid %#lx\n", + // riscv_csr_read(mvendorid), riscv_csr_read(marchid), + // riscv_csr_read(mimpid), riscv_csr_read(mhartid)); + //dprintf(INFO, "RISCV: misa %#lx\n", riscv_csr_read(misa)); + + // enable external interrupts + //riscv_csr_set(mie, RISCV_MIE_MEIE); +} + +void arch_idle(void) { + // disabled for now, QEMU seems to have some trouble emulating wfi properly + // also have trouble breaking into sifive-e board with openocd when wfi +// __asm__ volatile("wfi"); +} + +void arch_chain_load(void *entry, ulong arg0, ulong arg1, ulong arg2, ulong arg3) { + PANIC_UNIMPLEMENTED; +} + +/* unimplemented cache operations */ +void arch_disable_cache(uint flags) { PANIC_UNIMPLEMENTED; } +void arch_enable_cache(uint flags) { PANIC_UNIMPLEMENTED; } + +void arch_clean_cache_range(addr_t start, size_t len) { PANIC_UNIMPLEMENTED; } +void arch_clean_invalidate_cache_range(addr_t start, size_t len) { PANIC_UNIMPLEMENTED; } +void arch_invalidate_cache_range(addr_t start, size_t len) { PANIC_UNIMPLEMENTED; } +void arch_sync_cache_range(addr_t start, size_t len) { PANIC_UNIMPLEMENTED; } diff --git a/arch/vax/asm.S b/arch/vax/asm.S new file mode 100644 index 00000000..e69de29b diff --git a/arch/vax/include/arch/arch_ops.h b/arch/vax/include/arch/arch_ops.h new file mode 100644 index 00000000..abcfe4ef --- /dev/null +++ b/arch/vax/include/arch/arch_ops.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2015 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 +#include +#include + +static inline void arch_enable_ints(void) { + // set the IPL to 0 + mtpr(PR_IPL, 0); +} + +static inline void arch_disable_ints(void) { + // set the IPL to 31 + mtpr(PR_IPL, 31); +} + +static inline bool arch_ints_disabled(void) { + uint32_t ipl = mfpr(PR_IPL); + return ipl > 0; +} + +static inline int atomic_add(volatile int *ptr, int val) { + // XXX not actually atomic + int oldval = *ptr; + *ptr += val; + return oldval; + //return __atomic_fetch_add(ptr, val, __ATOMIC_RELAXED); +} + +static inline int atomic_or(volatile int *ptr, int val) { + return __atomic_fetch_or(ptr, val, __ATOMIC_RELAXED); +} + +static inline int atomic_and(volatile int *ptr, int val) { + return __atomic_fetch_and(ptr, val, __ATOMIC_RELAXED); +} + +static inline int atomic_swap(volatile int *ptr, int val) { + return __atomic_exchange_n(ptr, val, __ATOMIC_RELAXED); +} + +/* use a global pointer to store the current_thread */ +extern struct thread *_current_thread; + +static inline struct thread *get_current_thread(void) { + return _current_thread; +} + +static inline void set_current_thread(struct thread *t) { + _current_thread = t; +} + +static inline uint32_t arch_cycle_count(void) { + uint32_t count = 0; + + //__asm__("rdcycle %0" : "=r"(count)); + //count = riscv_csr_read(mcycle); + return count; +} + +static inline uint arch_curr_cpu_num(void) { + return 0; +} + diff --git a/arch/vax/include/arch/arch_thread.h b/arch/vax/include/arch/arch_thread.h new file mode 100644 index 00000000..104e74f6 --- /dev/null +++ b/arch/vax/include/arch/arch_thread.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2015 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 + +#if 0 +struct riscv32_context_switch_frame { + uint32_t ra; // return address (x1) + uint32_t sp; // stack pointer (x2) + uint32_t tp; // thread pointer (x4) + + uint32_t s0; // x8-x9 + uint32_t s1; + + uint32_t s2; // x18-x27 + uint32_t s3; + uint32_t s4; + uint32_t s5; + uint32_t s6; + uint32_t s7; + uint32_t s8; + uint32_t s9; + uint32_t s10; + uint32_t s11; +}; + +struct arch_thread { + struct riscv32_context_switch_frame cs_frame; +}; + +void riscv32_context_switch(struct riscv32_context_switch_frame *oldcs, + struct riscv32_context_switch_frame *newcs); +#endif + +struct arch_thread { +}; + diff --git a/arch/vax/include/arch/defines.h b/arch/vax/include/arch/defines.h new file mode 100644 index 00000000..d04ae484 --- /dev/null +++ b/arch/vax/include/arch/defines.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2015 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 + +#define PAGE_SIZE 512 +#define PAGE_SIZE_SHIFT 9 + +// XXX is this right? +#define CACHE_LINE 32 + +#define ARCH_DEFAULT_STACK_SIZE 1024 diff --git a/arch/vax/include/arch/riscv.h b/arch/vax/include/arch/riscv.h new file mode 100644 index 00000000..5540d191 --- /dev/null +++ b/arch/vax/include/arch/riscv.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2015 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 + +#define RISCV_STATUS_SIE (1u << 2) +#define RISCV_STATUS_MIE (1u << 3) +#define RISCV_STATUS_MPIE (1u << 7) +#define RISCV_STATUS_MPP_MASK (3u << 11) + +#define RISCV_MIE_MSIE (1u << 3) +#define RISCV_MIE_MTIE (1u << 7) +#define RISCV_MIE_SEIE (1u << 9) +#define RISCV_MIE_MEIE (1u << 11) + +#define RISCV_MIP_MSIP (1u << 3) +#define RISCV_MIP_MTIP (1u << 7) +#define RISCV_MIP_MEIP (1u << 11) + +#define RISCV_MCAUSE_INT (1u << 31) + +#define riscv_csr_clear(csr, bits) \ +({ \ + ulong __val = bits; \ + __asm__ volatile( \ + "csrc " #csr ", %0" \ + :: "rK" (__val) \ + : "memory"); \ +}) + +#define riscv_csr_read_clear(csr, bits) \ +({ \ + ulong __val = bits; \ + ulong __val_out; \ + __asm__ volatile( \ + "csrrc %0, " #csr ", %1" \ + : "=r"(__val_out) \ + : "rK" (__val) \ + : "memory"); \ + __val_out; \ +}) + +#define riscv_csr_set(csr, bits) \ +({ \ + ulong __val = bits; \ + __asm__ volatile( \ + "csrs " #csr ", %0" \ + :: "rK" (__val) \ + : "memory"); \ +}) + +#define riscv_csr_read(csr) \ +({ \ + ulong __val; \ + __asm__ volatile( \ + "csrr %0, " #csr \ + : "=r" (__val) \ + :: "memory"); \ + __val; \ +}) + +#define riscv_csr_write(csr, val) \ +({ \ + ulong __val = (ulong)val; \ + __asm__ volatile( \ + "csrw " #csr ", %0" \ + :: "rK" (__val) \ + : "memory"); \ + __val; \ +}) + +void riscv_exception_entry(void); +enum handler_return riscv_timer_exception(void); diff --git a/arch/vax/include/arch/spinlock.h b/arch/vax/include/arch/spinlock.h new file mode 100644 index 00000000..e3c7bc97 --- /dev/null +++ b/arch/vax/include/arch/spinlock.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2015 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 +#include + +#if WITH_SMP +#error vax does not support SMP +#endif + +#define SPIN_LOCK_INITIAL_VALUE (0) + +typedef unsigned int spin_lock_t; + +typedef unsigned long 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 + +static inline void +arch_interrupt_save(spin_lock_saved_state_t *statep, spin_lock_save_flags_t flags) { + /* disable interrupts by clearing the MIE bit while atomically saving the old state */ + //*statep = riscv_csr_read_clear(mstatus, RISCV_STATUS_MIE) & RISCV_STATUS_MIE; +} + +static inline void +arch_interrupt_restore(spin_lock_saved_state_t old_state, spin_lock_save_flags_t flags) { + /* drop the old MIE flag into the status register */ + //riscv_csr_set(mstatus, old_state); +} + diff --git a/arch/vax/include/arch/vax.h b/arch/vax/include/arch/vax.h new file mode 100644 index 00000000..dc1c7a88 --- /dev/null +++ b/arch/vax/include/arch/vax.h @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2019 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 + */ +#include diff --git a/arch/vax/include/arch/vax/mtpr.h b/arch/vax/include/arch/vax/mtpr.h new file mode 100644 index 00000000..d24bc838 --- /dev/null +++ b/arch/vax/include/arch/vax/mtpr.h @@ -0,0 +1,188 @@ +/* $NetBSD: mtpr.h,v 1.23 2017/05/22 17:12:11 ragge Exp $ */ + +/* + * Copyright (c) 1994 Ludd, University of Lule}, Sweden. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + /* All bugs are subject to removal without further notice */ + +#ifndef _VAX_MTPR_H_ +#define _VAX_MTPR_H_ + +/****************************************************************************** + + Processor register numbers in the VAX /IC + +******************************************************************************/ + + +#define PR_KSP 0 /* Kernel Stack Pointer */ +#define PR_ESP 1 /* Executive Stack Pointer */ +#define PR_SSP 2 /* Supervisor Stack Pointer */ +#define PR_USP 3 /* User Stack Pointer */ +#define PR_ISP 4 /* Interrupt Stack Pointer */ + +#define PR_P0BR 8 /* P0 Base Register */ +#define PR_P0LR 9 /* P0 Length Register */ +#define PR_P1BR 10 /* P1 Base Register */ +#define PR_P1LR 11 /* P1 Length Register */ +#define PR_SBR 12 /* System Base Register */ +#define PR_SLR 13 /* System Limit Register */ +#define PR_PCBB 16 /* Process Control Block Base */ +#define PR_SCBB 17 /* System Control Block Base */ +#define PR_IPL 18 /* Interrupt Priority Level */ +#define PR_ASTLVL 19 /* AST Level */ +#define PR_SIRR 20 /* Software Interrupt Request */ +#define PR_SISR 21 /* Software Interrupt Summary */ +#define PR_IPIR 22 /* KA820 Interprocessor register */ +#define PR_MCSR 23 /* Machine Check Status Register 11/750 */ +#define PR_ICCS 24 /* Interval Clock Control */ +#define PR_NICR 25 /* Next Interval Count */ +#define PR_ICR 26 /* Interval Count */ +#define PR_TODR 27 /* Time Of Year (optional) */ +#define PR_CSRS 28 /* Console Storage R/S */ +#define PR_CSRD 29 /* Console Storage R/D */ +#define PR_CSTS 30 /* Console Storage T/S */ +#define PR_CSTD 31 /* Console Storage T/D */ +#define PR_RXCS 32 /* Console Receiver C/S */ +#define PR_RXDB 33 /* Console Receiver D/B */ +#define PR_TXCS 34 /* Console Transmit C/S */ +#define PR_TXDB 35 /* Console Transmit D/B */ +#define PR_TBDR 36 /* Translation Buffer Group Disable Register 11/750 */ +#define PR_CADR 37 /* Cache Disable Register 11/750 */ +#define PR_MCESR 38 /* Machiune Check Error Summary Register 11/750 */ +#define PR_CAER 39 /* Cache Error Register 11/750 */ +#define PR_ACCS 40 /* Accelerator control register */ +#define PR_SAVISP 41 /* Console Saved ISP */ +#define PR_SAVPC 42 /* Console Saved PC */ +#define PR_SAVPSL 43 /* Console Saved PSL */ +#define PR_WCSA 44 /* WCS Address */ +#define PR_WCSB 45 /* WCS Data */ +#define PR_SBIFS 48 /* SBI Fault/Status */ +#define PR_SBIS 49 /* SBI Silo */ +#define PR_SBISC 50 /* SBI Silo Comparator */ +#define PR_SBIMT 51 /* SBI Silo Maintenance */ +#define PR_SBIER 52 /* SBI Error Register */ +#define PR_SBITA 53 /* SBI Timeout Address Register */ +#define PR_SBIQC 54 /* SBI Quadword Clear */ +#define PR_IUR 55 /* Initialize Unibus Register 11/750 */ +#define PR_MAPEN 56 /* Memory Management Enable */ +#define PR_TBIA 57 /* Trans. Buf. Invalidate All */ +#define PR_TBIS 58 /* Trans. Buf. Invalidate Single */ +#define PR_TBDATA 59 /* Translation Buffer Data */ +#define PR_MBRK 60 /* Microprogram Break */ +#define PR_PMR 61 /* Performance Monnitor Enable */ +#define PR_SID 62 /* System ID Register */ +#define PR_TBCHK 63 /* Translation Buffer Check */ + +#define PR_PAMACC 64 /* Physical Address Memory Map Access (KA86) */ +#define PR_PAMLOC 65 /* Physical Address Memory Map Location (KA86) */ +#define PR_CSWP 66 /* Cache Sweep (KA86) */ +#define PR_MDECC 67 /* MBOX Data Ecc Register (KA86) */ +#define PR_MENA 68 /* MBOX Error Enable Register (KA86) */ +#define PR_MDCTL 69 /* MBOX Data Control Register (KA86) */ +#define PR_MCCTL 70 /* MBOX Mcc Control Register (KA86) */ +#define PR_MERG 71 /* MBOX Error Generator Register (KA86) */ +#define PR_CRBT 72 /* Console Reboot (KA86) */ +#define PR_DFI 73 /* Diagnostic Fault Insertion Register (KA86) */ +#define PR_EHSR 74 /* Error Handling Status Register (KA86) */ +#define PR_STXCS 76 /* Console Storage C/S (KA86) */ +#define PR_STXDB 77 /* Console Storage D/B (KA86) */ +#define PR_ESPA 78 /* EBOX Scratchpad Address (KA86) */ +#define PR_ESPD 79 /* EBOX Scratchpad Data (KA86) */ + +#define PR_RXCS1 80 /* Serial-Line Unit 1 Receive CSR (KA820) */ +#define PR_RXDB1 81 /* Serial-Line Unit 1 Receive Data Buffer (KA820) */ +#define PR_TXCS1 82 /* Serial-Line Unit 1 Transmit CSR (KA820) */ +#define PR_TXDB1 83 /* Serial-Line Unit 1 Transmit Data Buffer (KA820) */ +#define PR_RXCS2 84 /* Serial-Line Unit 2 Receive CSR (KA820) */ +#define PR_RXDB2 85 /* Serial-Line Unit 2 Receive Data Buffer (KA820) */ +#define PR_TXCS2 86 /* Serial-Line Unit 2 Transmit CSR (KA820) */ +#define PR_TXDB2 87 /* Serial-Line Unit 2 Transmit Data Buffer (KA820) */ +#define PR_RXCS3 88 /* Serial-Line Unit 3 Receive CSR (KA820) */ +#define PR_RXDB3 89 /* Serial-Line Unit 3 Receive Data Buffer (KA820) */ +#define PR_TXCS3 90 /* Serial-Line Unit 3 Transmit CSR (KA820) */ +#define PR_TXDB3 91 /* Serial-Line Unit 3 Transmit Data Buffer (KA820) */ +#define PR_RXCD 92 /* Receive Console Data from another CPU (KA820) */ +#define PR_CACHEX 93 /* Cache invalidate Register (KA820) */ +#define PR_BINID 94 /* VAXBI node ID Register (KA820) */ +#define PR_BISTOP 95 /* VAXBI Stop Register (KA820) */ + +#define PR_BCBTS 113 /* Backup Cache Tag Store (KA670) */ +#define PR_BCP1TS 114 /* Primary Tag Store 1st half (KA670) */ +#define PR_BCP2TS 115 /* Primary Tag Store 2st half (KA670) */ +#define PR_BCRFR 116 /* Refresh Register (KA670) */ +#define PR_BCIDX 117 /* Index Register (KA670) */ +#define PR_BCSTS 118 /* Status (KA670) */ +#define PR_BCCTL 119 /* Control Register (KA670) */ +#define PR_BCERR 120 /* Error Address (KA670) */ +#define PR_BCFBTS 121 /* Flush backup tag store (KA670) */ +#define PR_BCFPTS 122 /* Flush primary tag store (KA670) */ + +#define PR_VINTSR 123 /* vector i/f error status (KA43/KA46) */ +#define PR_PCTAG 124 /* primary cache tag store (KA43/KA46) */ +#define PR_PCIDX 125 /* primary cache index (KA43/KA46) */ +#define PR_PCERR 126 /* primary cache error address (KA43/KA46) */ +#define PR_PCSTS 127 /* primary cache status (KA43/KA46) */ + +#define PR_VPSR 144 /* Vector processor status register */ +#define PR_VAER 145 /* Vector arithmetic error register */ +#define PR_VMAC 146 /* Vector memory activity register */ +#define PR_VTBIA 147 /* Vector TBIA */ +#define PR_VSAR 148 /* Vector state address register */ +#define PR_VIADR 157 /* Vector indirect address register */ +#define PR_VIDLO 158 /* Vector indirect data low */ +#define PR_VIDHI 159 /* Vector indirect data high */ + +/* Definitions for AST */ +#define AST_NO 4 +#define AST_OK 3 + +#ifndef _LOCORE + +typedef unsigned int register_t; + +static inline void +mtpr(register_t val, int reg) +{ + __asm volatile ( + "mtpr %0,%1" + : /* No output */ + : "g" (val), "g" (reg) + : "memory"); +} + +static inline register_t +mfpr(int reg) +{ + register_t __val; + __asm volatile ( + "mfpr %1,%0" + : "=g" (__val) + : "g" (reg)); + return __val; +} +#endif /* _LOCORE */ + +#endif /* _VAX_MTPR_H_ */ diff --git a/arch/vax/linker.ld b/arch/vax/linker.ld new file mode 100644 index 00000000..81327de3 --- /dev/null +++ b/arch/vax/linker.ld @@ -0,0 +1,118 @@ +OUTPUT_FORMAT("elf32-vax", "elf32-vax", "elf32-vax") +OUTPUT_ARCH(vax) + +ENTRY(_start) +SECTIONS +{ + . = %KERNEL_BASE% + %KERNEL_LOAD_OFFSET%; + + _start = .; + + /* text/read-only data */ + /* set the load address to physical MEMBASE */ + .text : AT(%MEMBASE% + %KERNEL_LOAD_OFFSET%) { + KEEP(*(.text.boot.vectab1)) + KEEP(*(.text.boot.vectab2)) + KEEP(*(.text.boot)) + *(.text* .sram.text.glue_7* .gnu.linkonce.t.*) + } + + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) *(.rel.gnu.linkonce.t*) } + .rela.text : { *(.rela.text) *(.rela.gnu.linkonce.t*) } + .rel.data : { *(.rel.data) *(.rel.gnu.linkonce.d*) } + .rela.data : { *(.rela.data) *(.rela.gnu.linkonce.d*) } + .rel.rodata : { *(.rel.rodata) *(.rel.gnu.linkonce.r*) } + .rela.rodata : { *(.rela.rodata) *(.rela.gnu.linkonce.r*) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.init : { *(.rel.init) } + .rela.init : { *(.rela.init) } + .rel.fini : { *(.rel.fini) } + .rela.fini : { *(.rela.fini) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } =0x9090 + .plt : { *(.plt) } + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } + __exidx_end = .; + + .rodata : ALIGN(4) { + __rodata_start = .; + __fault_handler_table_start = .; + KEEP(*(.rodata.fault_handler_table)) + __fault_handler_table_end = .; + *(.rodata .rodata.* .gnu.linkonce.r.*) + } + + /* + * extra linker scripts tend to insert sections just after .rodata, + * so we want to make sure this symbol comes after anything inserted above, + * but not aligned to the next section necessarily. + */ + .dummy_post_rodata : { + __rodata_end = .; + } + + .data : ALIGN(512) { + /* writable data */ + __data_start_rom = .; + /* in one segment binaries, the rom data address is on top of the ram data address */ + __data_start = .; + *(.data .data.* .gnu.linkonce.d.*) + } + + .ctors : ALIGN(4) { + __ctor_list = .; + KEEP(*(.ctors .init_array)) + __ctor_end = .; + } + .dtors : ALIGN(4) { + __dtor_list = .; + KEEP(*(.dtors .fini_array)) + __dtor_end = .; + } + .got : { *(.got.plt) *(.got) } + .dynamic : { *(.dynamic) } + + /* + * extra linker scripts tend to insert sections just after .data, + * so we want to make sure this symbol comes after anything inserted above, + * but not aligned to the next section necessarily. + */ + .dummy_post_data : { + __data_end = .; + } + + /* uninitialized data (in same segment as writable data) */ + .bss : ALIGN(4) { + KEEP(*(.bss.prebss.*)) + . = ALIGN(4); + __bss_start = .; + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + __bss_end = .; + } + + _end = .; + + . = %KERNEL_BASE% + %MEMSIZE%; + _end_of_ram = .; + + /* Strip unnecessary stuff */ + /DISCARD/ : { *(.comment .note .eh_frame) } +} diff --git a/arch/vax/rules.mk b/arch/vax/rules.mk new file mode 100644 index 00000000..ed1285af --- /dev/null +++ b/arch/vax/rules.mk @@ -0,0 +1,55 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +MODULE := $(LOCAL_DIR) + +MODULE_SRCS += $(LOCAL_DIR)/start.S +MODULE_SRCS += $(LOCAL_DIR)/arch.c +MODULE_SRCS += $(LOCAL_DIR)/asm.S +MODULE_SRCS += $(LOCAL_DIR)/thread.c + +GLOBAL_DEFINES += \ + SMP_MAX_CPUS=1 + +# set the default toolchain to vax-linux +ifndef TOOLCHAIN_PREFIX +TOOLCHAIN_PREFIX := vax-linux- +endif + +WITH_LINKER_GC ?= 0 + +cc-option = $(shell if test -z "`$(1) $(2) -S -o /dev/null -xc /dev/null 2>&1`"; \ + then echo "$(2)"; else echo "$(3)"; fi ;) + +ARCH_COMPILEFLAGS := +ARCH_OPTFLAGS := -O2 +ARCH_LDFLAGS := -z max-page-size=512 + +LIBGCC := $(shell $(TOOLCHAIN_PREFIX)gcc $(GLOBAL_COMPILEFLAGS) $(ARCH_COMPILEFLAGS) $(GLOBAL_CFLAGS) -print-libgcc-file-name) +$(info LIBGCC = $(LIBGCC)) + +KERNEL_BASE ?= $(MEMBASE) +KERNEL_LOAD_OFFSET ?= 0 +ROMBASE ?= 0 + +GLOBAL_DEFINES += \ + ROMBASE=$(ROMBASE) \ + MEMBASE=$(MEMBASE) \ + MEMSIZE=$(MEMSIZE) + +# potentially generated files that should be cleaned out with clean make rule +GENERATED += \ + $(BUILDDIR)/linker.ld + +# rules for generating the linker +$(BUILDDIR)/linker.ld: $(LOCAL_DIR)/linker.ld $(wildcard arch/*.ld) linkerscript.phony + @echo generating $@ + @$(MKDIR) + $(NOECHO)sed "s/%ROMBASE%/$(ROMBASE)/;s/%MEMBASE%/$(MEMBASE)/;s/%MEMSIZE%/$(MEMSIZE)/;s/%KERNEL_BASE%/$(KERNEL_BASE)/;s/%KERNEL_LOAD_OFFSET%/$(KERNEL_LOAD_OFFSET)/;s/%VECTOR_BASE_PHYS%/$(VECTOR_BASE_PHYS)/" < $< > $@.tmp + @$(call TESTANDREPLACEFILE,$@.tmp,$@) + +linkerscript.phony: +.PHONY: linkerscript.phony + +LINKER_SCRIPT += $(BUILDDIR)/linker.ld + +include make/module.mk diff --git a/arch/vax/start.S b/arch/vax/start.S new file mode 100644 index 00000000..29c9c77e --- /dev/null +++ b/arch/vax/start.S @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2019 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 + */ +.section .text.boot + +.globl _start +_start: + nop + nop + + // save our bootargs + moval bootargs_end,%sp + pushr $0x1fff + + // see if we need to be relocated + movab _start, %r0 // where we are + movl $_start, %r1 // where we want to be + cmpl %r0,%r1 + beql relocated + + // compute the copy length + subl3 %r1, $__data_end, %r2 + + // copy us down to the final location +1: + movb (%r0)+,(%r1)+ + sobgtr %r2,1b + + // zero bss + subl3 $_end, $__data_end, %r2 +1: + movb $0,(%r1)+ + sobgtr %r2,1b + + // branch to our new spot + movl $relocated, %r0 + jmp (%r0) + +relocated: + // set the stack to the end of us + moval stack_end,%sp + + // branch into main and we're done + calls $0, lk_main + halt + +.section .data +.align 4 +.globl bootargs +bootargs: + .skip 13*4 +bootargs_end: + +.section .bss +.align 4 +stack: + .skip 1024 +stack_end: diff --git a/arch/vax/thread.c b/arch/vax/thread.c new file mode 100644 index 00000000..9ef1165e --- /dev/null +++ b/arch/vax/thread.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2019 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 + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#define LOCAL_TRACE 0 + +struct thread *_current_thread; + +static void initial_thread_func(void) __NO_RETURN; +static void initial_thread_func(void) { + DEBUG_ASSERT(arch_ints_disabled()); + + thread_t *ct = get_current_thread(); + +#if LOCAL_TRACE + LTRACEF("thread %p calling %p with arg %p\n", ct, ct->entry, ct->arg); + dump_thread(ct); +#endif + + /* release the thread lock that was implicitly held across the reschedule */ + spin_unlock(&thread_lock); + arch_enable_ints(); + + int ret = ct->entry(ct->arg); + + LTRACEF("thread %p exiting with %d\n", ct, ret); + + thread_exit(ret); +} + +void arch_thread_initialize(thread_t *t) { + LTRACEF("t %p (%s)\n", t, t->name); + + /* zero out the thread context */ + memset(&t->arch, 0, sizeof(t->arch)); + + //t->arch.cs_frame.sp = (vaddr_t)t->stack + t->stack_size; + //t->arch.cs_frame.ra = (vaddr_t)&initial_thread_func; +} + +void arch_context_switch(thread_t *oldthread, thread_t *newthread) { + DEBUG_ASSERT(arch_ints_disabled()); + + LTRACEF("old %p (%s), new %p (%s)\n", oldthread, oldthread->name, newthread, newthread->name); + + PANIC_UNIMPLEMENTED; + //riscv32_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.sp); + } +} + diff --git a/lib/libc/string/arch/vax/rules.mk b/lib/libc/string/arch/vax/rules.mk new file mode 100644 index 00000000..3dc080bb --- /dev/null +++ b/lib/libc/string/arch/vax/rules.mk @@ -0,0 +1,11 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +ASM_STRING_OPS := #bcopy bzero memcpy memmove memset + +MODULE_SRCS += \ + #$(LOCAL_DIR)/memcpy.S \ + #$(LOCAL_DIR)/memset.S + +# filter out the C implementation +C_STRING_OPS := $(filter-out $(ASM_STRING_OPS),$(C_STRING_OPS)) + diff --git a/platform/vax/console.c b/platform/vax/console.c new file mode 100644 index 00000000..c93ee5c5 --- /dev/null +++ b/platform/vax/console.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2019 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 + */ +#include +#include +#include + +// todo: move to .S file +unsigned int rom_putchar_addr = 0x20040068; +extern int rom_putchar(int c); + +// select the above routine +int (*putchar_func)(int c) = &rom_putchar; + +void platform_dputc(char c) { + if (c == '\n') + putchar_func('\r'); + putchar_func(c); +} + +int platform_dgetc(char *c, bool wait) { + return -1; +} + +// crash time versions, for the moment use the above +void platform_pputc(char c) { + platform_dputc(c); +} + +int platform_pgetc(char *c, bool wait) { + return platform_dgetc(c, wait); +} + + + diff --git a/platform/vax/init.c b/platform/vax/init.c new file mode 100644 index 00000000..3685da6d --- /dev/null +++ b/platform/vax/init.c @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2019 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 + */ +#include +#include +#include + +// stubbed out time +static lk_time_t t = 0; +lk_time_t current_time() { + return ++t; +} + +lk_bigtime_t current_time_hires() { + return (++t) * 1000; +} diff --git a/platform/vax/rom.S b/platform/vax/rom.S new file mode 100644 index 00000000..e59a98cf --- /dev/null +++ b/platform/vax/rom.S @@ -0,0 +1,10 @@ +.text + +.globl rom_putchar +.type rom_putchar@function +rom_putchar: + .word 0x0004 # save r2 + movl 4(%ap), %r2 + jsb *rom_putchar_addr + ret + diff --git a/platform/vax/rules.mk b/platform/vax/rules.mk new file mode 100644 index 00000000..331a6a5d --- /dev/null +++ b/platform/vax/rules.mk @@ -0,0 +1,53 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +MODULE := $(LOCAL_DIR) + +ARCH := vax + +#MODULE_DEPS := \ + lib/bio \ + lib/cbuf \ + lib/watchdog \ + dev/cache/pl310 \ + dev/interrupt/arm_gic \ + dev/timer/arm_cortex_a9 + +MODULE_SRCS += \ + $(LOCAL_DIR)/console.c \ + $(LOCAL_DIR)/init.c \ + $(LOCAL_DIR)/rom.S \ + $(LOCAL_DIR)/timer.c \ + +# $(LOCAL_DIR)/clocks.c \ + $(LOCAL_DIR)/debug.c \ + $(LOCAL_DIR)/fpga.c \ + $(LOCAL_DIR)/gpio.c \ + $(LOCAL_DIR)/platform.c \ + $(LOCAL_DIR)/qspi.c \ + $(LOCAL_DIR)/spiflash.c \ + $(LOCAL_DIR)/start.S \ + $(LOCAL_DIR)/swdt.c \ + $(LOCAL_DIR)/uart.c \ + +MEMBASE := 0x00000000 +MEMSIZE ?= 0x00800000 # default to 8MB +KERNEL_LOAD_OFFSET := 0x00100000 # loaded 1MB into physical space + +# put our kernel at 0x80000000 once we get the mmu running +#KERNEL_BASE = 0x80000000 +KERNEL_BASE = 0 + +#LINKER_SCRIPT += \ +# $(BUILDDIR)/system-onesegment.ld + +# python script to generate the zynq's bootrom bootheader +#MKBOOTHEADER := $(LOCAL_DIR)/mkbootheader.py +#EXTRA_BUILDDEPS += $(BOOTHEADERBIN) +#GENERATED += $(BOOTHEADERBIN) + +#$(BOOTHEADERBIN): $(OUTBIN) $(MKBOOTHEADER) +# @$(MKDIR) +# $(NOECHO)echo generating $@; \ +# $(MKBOOTHEADER) $(OUTBIN) $@ + +include make/module.mk diff --git a/platform/vax/timer.c b/platform/vax/timer.c new file mode 100644 index 00000000..7481d3c6 --- /dev/null +++ b/platform/vax/timer.c @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2019 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 + */ +#include +#include +#include +#include + +// stubbed out timer +status_t platform_set_periodic_timer(platform_timer_callback callback, void *arg, lk_time_t interval) { + return NO_ERROR; + PANIC_UNIMPLEMENTED; +} + diff --git a/project/vax-test.mk b/project/vax-test.mk new file mode 100644 index 00000000..adf8b987 --- /dev/null +++ b/project/vax-test.mk @@ -0,0 +1,6 @@ +# main project for vim2 +LOCAL_DIR := $(GET_LOCAL_DIR) + +TARGET := vax + +include project/virtual/test.mk diff --git a/target/vax/rules.mk b/target/vax/rules.mk new file mode 100644 index 00000000..608cdbbc --- /dev/null +++ b/target/vax/rules.mk @@ -0,0 +1,9 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +GLOBAL_INCLUDES += \ + $(LOCAL_DIR)/include + +PLATFORM := vax + +#include make/module.mk +