[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.
This commit is contained in:
Travis Geiselbrecht
2019-10-12 21:54:04 -07:00
parent 9a6081399c
commit 89705cb065
21 changed files with 987 additions and 0 deletions

57
arch/vax/arch.c Normal file
View File

@@ -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 <assert.h>
#include <lk/trace.h>
#include <lk/debug.h>
#include <stdint.h>
#include <arch/ops.h>
#include <arch/vax.h>
#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; }

0
arch/vax/asm.S Normal file
View File

View File

@@ -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 <lk/compiler.h>
#include <lk/debug.h>
#include <arch/vax.h>
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;
}

View File

@@ -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 <sys/types.h>
#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 {
};

View File

@@ -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

View File

@@ -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);

View File

@@ -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 <arch/ops.h>
#include <stdbool.h>
#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);
}

View File

@@ -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 <arch/vax/mtpr.h>

View File

@@ -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_ */

118
arch/vax/linker.ld Normal file
View File

@@ -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) }
}

55
arch/vax/rules.mk Normal file
View File

@@ -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

62
arch/vax/start.S Normal file
View File

@@ -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:

68
arch/vax/thread.c Normal file
View File

@@ -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 <assert.h>
#include <lk/debug.h>
#include <lk/trace.h>
#include <sys/types.h>
#include <string.h>
#include <stdlib.h>
#include <kernel/thread.h>
#include <arch/vax.h>
#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);
}
}

View File

@@ -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))

39
platform/vax/console.c Normal file
View File

@@ -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 <lk/debug.h>
#include <platform.h>
#include <platform/debug.h>
// 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);
}

20
platform/vax/init.c Normal file
View File

@@ -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 <lk/debug.h>
#include <platform.h>
#include <platform/timer.h>
// 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;
}

10
platform/vax/rom.S Normal file
View File

@@ -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

53
platform/vax/rules.mk Normal file
View File

@@ -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

18
platform/vax/timer.c Normal file
View File

@@ -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 <lk/debug.h>
#include <lk/err.h>
#include <platform.h>
#include <platform/timer.h>
// stubbed out timer
status_t platform_set_periodic_timer(platform_timer_callback callback, void *arg, lk_time_t interval) {
return NO_ERROR;
PANIC_UNIMPLEMENTED;
}

6
project/vax-test.mk Normal file
View File

@@ -0,0 +1,6 @@
# main project for vim2
LOCAL_DIR := $(GET_LOCAL_DIR)
TARGET := vax
include project/virtual/test.mk

9
target/vax/rules.mk Normal file
View File

@@ -0,0 +1,9 @@
LOCAL_DIR := $(GET_LOCAL_DIR)
GLOBAL_INCLUDES += \
$(LOCAL_DIR)/include
PLATFORM := vax
#include make/module.mk