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

Support for GOARCH=mips64 #8

Merged
merged 45 commits into from
Jul 11, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
6a290ce
First steps for mips support
clktmr Sep 27, 2023
161c832
move entry function to beginning of text section
clktmr Sep 30, 2023
ea7e39f
Implement _rt0_mips64_noos and rt0_go
clktmr Oct 7, 2023
79cc533
First draft for interrupt handler
clktmr Oct 13, 2023
2eca26e
rework implementation of inthandler
clktmr Oct 16, 2023
0b8255e
Save a few cycles in creg access
clktmr Oct 17, 2023
a323fd7
Use SW interrupts for signaling newwork()
clktmr Oct 19, 2023
5a1361c
Simple default write for debugging
clktmr Oct 19, 2023
55a6a27
Support user interrupt vectors
clktmr Oct 22, 2023
0eeeba5
Fix hardware interrupt handler
clktmr Oct 24, 2023
08c9559
Refactor inthandler in preparation for nested IRQ
clktmr Oct 24, 2023
4cd51f9
Reimplement context saving for external irqs
clktmr Oct 24, 2023
f412453
Fix save/restoreGPRs by including R23
clktmr Oct 24, 2023
f76a49c
Save and restore status register
clktmr Nov 8, 2023
f20c02f
Remove broken setAlarm() implementation
clktmr Nov 18, 2023
ec1102e
Mitigate sign-extended pointers with TLB
clktmr Nov 18, 2023
499c820
Don't allow preempting the scheduler for now
clktmr Nov 18, 2023
0ba3098
Fix CP0 hazards of ERET
clktmr Nov 18, 2023
0735c4b
Declare interrupt handler in go files
clktmr May 22, 2024
ddb7e84
Fix instruction for accessing boolean variable
clktmr May 22, 2024
c5f2c6c
Increase space for non-heap allocations
clktmr Jun 10, 2024
a0871ec
Add dependency to target specific machine package
clktmr Jun 12, 2024
522c4b2
Remove incorrect uncached memory accesses
clktmr Jun 12, 2024
90d1c56
Use Go register notation
clktmr Jun 12, 2024
7e70a6a
Implement meminit in Go instead of assembly
clktmr Jun 13, 2024
b456b3f
Cleanup asm_mips64.h
clktmr Jun 13, 2024
d91b545
Allow target specific unhandled exception handler
clktmr Jun 18, 2024
580244a
Cleanup tasker implementation
clktmr Jun 19, 2024
85aec39
Use only one of the two SW interrupts
clktmr Jun 19, 2024
0fcfaab
Consistent naming
clktmr Jun 19, 2024
ff68f75
Rework nested exceptions
clktmr Jun 19, 2024
92ecc79
Handle fast syscalls properly
clktmr Jun 19, 2024
0e93ef9
Improve documentation
clktmr Jun 20, 2024
2daae17
Make context restoration preemptable if possbile
clktmr Jun 20, 2024
7dbbef0
Remove unreachable code
clktmr Jun 20, 2024
77e5f9a
Allow nesting only for external interrupts
clktmr Jun 20, 2024
10ee6a2
Initialize cpu to not use any ISA extensions
clktmr Jun 20, 2024
8ae3c51
Remove dependency to n64 module
clktmr Jun 21, 2024
6187830
Fix errors reported by ./all.bash
clktmr Jun 21, 2024
c06b29b
Fix FPU context save in external interrupt
clktmr Jun 21, 2024
dfc55b5
Make function declarations arch dependent
clktmr Jun 22, 2024
5de02c6
Implement cachemaint syscall
clktmr Jun 22, 2024
e85dca9
Implement irqctl syscall
clktmr Jun 22, 2024
b0dc0af
Resolve minor review findings
clktmr Jun 25, 2024
a1f914a
Fix meminit() and other minor review findings
clktmr Jun 29, 2024
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
Prev Previous commit
Next Next commit
Cleanup asm_mips64.h
  • Loading branch information
clktmr committed Jun 30, 2024
commit b456b3f72974244963517fc5c938e1582dd194c7
275 changes: 100 additions & 175 deletions src/runtime/asm_mips64.h
Original file line number Diff line number Diff line change
@@ -1,177 +1,102 @@
/*
* standard MIPS register names.
*
* Copyright (c) 1995 Cygnus Support
*
* The authors hereby grant permission to use, copy, modify, distribute,
* and license this software and its documentation for any purpose, provided
* that existing copyright notices are retained in all copies and that this
* notice is included verbatim in any distributions. No written agreement,
* license, or royalty fee is required for any of the authorized uses.
* Modifications to this software may be copyrighted by their authors
* and need not follow the licensing terms described here, provided that
* the new terms are clearly indicated on the first page of each file where
* they apply.
*/

/* Standard MIPS register names: */
#define zero R0
#define z0 R0
#define at R1
#define v0 R2
#define v1 R3
#define a0 R4
#define a1 R5
#define a2 R6
#define a3 R7
#define t0 R8
#define t1 R9
#define t2 R10
#define t3 R11
#define t4 R12
#define t5 R13
#define t6 R14
#define t7 R15
#define s0 R16
#define s1 R17
#define s2 R18
#define s3 R19
#define s4 R20
#define s5 R21
#define s6 R22
#define s7 R23
#define t8 R24
#define t9 R25
#define k0 R26 /* kernel private register 0 */
#define k1 R27 /* kernel private register 1 */
#define gp R28 /* global data pointer */
#define sp R29 /* stack-pointer */
#define fp R30 /* frame-pointer */
#define ra R31 /* return address */

#define fp0 F0
#define fp1 F1

/* Useful memory constants: */
#define K0BASE 0x80000000
#ifndef __mips64
#define K1BASE 0xA0000000
#define K0BASE_ADDR ((char *)K0BASE)
#define K1BASE_ADDR ((char *)K1BASE)
#else
#define K1BASE 0xFFFFFFFFA0000000LL
#define K0BASE_ADDR ((char *)0xFFFFFFFF80000000LL)
#define K1BASE_ADDR ((char *)K1BASE)
#endif

#define PHYS_TO_K1(a) ((unsigned)(a) | K1BASE)

/* Standard Co-Processor 0 registers */
#define C0_INDEX 0 /* Index of TLB Entry */
#define C0_ENTRYLO0 2 /* TLB entry's first PFN */
#define C0_ENTRYLO1 3 /* TLB entry's second PFN */
#define C0_PAGEMASK 5 /* Size of TLB Entries */
#define C0_COUNT 9 /* Timer Count Register */
#define C0_ENTRYHI 10 /* VPN and ASID of two TLB entry */
#define C0_COMPARE 11 /* Timer Compare Register */
#define C0_SR 12 /* Status Register */
#define C0_CAUSE 13 /* last exception description */
#define C0_EPC 14 /* Exception error address */
#define C0_PRID 15 /* Processor Revision ID */
#define C0_CONFIG 16 /* CPU configuration */
#define C0_WATCHLO 18 /* Watchpoint */

/* Standard Processor Revision ID Register field offsets */
#define PR_IMP 8

/* Standard Config Register field offsets */
#define CR_DB 4
#define CR_IB 5
#define CR_DC 6 /* NOTE v4121 semantics != 43,5xxx semantics */
#define CR_IC 9 /* NOTE v4121 semantics != 43,5xxx semantics */
#define CR_SC 17
#define CR_SS 20
#define CR_SB 22


/* Standard Status Register bitmasks: */
#define SR_CU1 0x20000000 /* Mark CP1 as usable */
#define SR_FR 0x04000000 /* Enable MIPS III FP registers */
#define SR_BEV 0x00400000 /* Controls location of exception vectors */
#define SR_PE 0x00100000 /* Mark soft reset (clear parity error) */

#define SR_KX 0x00000080 /* Kernel extended addressing enabled */
#define SR_SX 0x00000040 /* Supervisor extended addressing enabled */
#define SR_UX 0x00000020 /* User extended addressing enabled */

#define SR_ERL 0x00000004 /* Error level */
#define SR_EXL 0x00000002 /* Exception level */
#define SR_IE 0x00000001 /* Interrupts enabled */

/* Standard Cause Register bitmasks: */
#define CAUSE_EXC_MASK (0x1F << 2)
#define CAUSE_EXC_INTERRUPT (0 << 2)
#define CAUSE_EXC_SYSCALL (8 << 2)
#define CAUSE_EXC_BREAKPOINT (9 << 2)
#define CAUSE_EXC_COPROCESSOR (11 << 2)
// Copyright (c) 1995 Cygnus Support
//
// The authors hereby grant permission to use, copy, modify, distribute, and
// license this software and its documentation for any purpose, provided that
// existing copyright notices are retained in all copies and that this notice is
// included verbatim in any distributions. No written agreement, license, or
// royalty fee is required for any of the authorized uses. Modifications to this
// software may be copyrighted by their authors and need not follow the
// licensing terms described here, provided that the new terms are clearly
// indicated on the first page of each file where they apply.


// Useful memory constants
#define KSEG0 0xFFFFFFFF80000000
#define KSEG1 0xFFFFFFFFA0000000

// Standard Co-Processor 0 registers
#define C0_INDEX 0 // Index of TLB Entry
#define C0_ENTRYLO0 2 // TLB entry's first PFN
#define C0_ENTRYLO1 3 // TLB entry's second PFN
#define C0_PAGEMASK 5 // Size of TLB Entries
#define C0_COUNT 9 // Timer Count Register
#define C0_ENTRYHI 10 // VPN and ASID of two TLB entry
#define C0_COMPARE 11 // Timer Compare Register
#define C0_SR 12 // Status Register
#define C0_CAUSE 13 // last exception description
#define C0_EPC 14 // Exception error address
#define C0_PRID 15 // Processor Revision ID
#define C0_CONFIG 16 // CPU configuration
#define C0_WATCHLO 18 // Watchpoint

// Standard Processor Revision ID Register field offsets
#define PR_IMP 8

// Standard Config Register field offsets
#define CR_DB 4
#define CR_IB 5
#define CR_DC 6
#define CR_IC 9
#define CR_SC 17
#define CR_SS 20
#define CR_SB 22

// Standard Status Register bitmasks
#define SR_CU1 0x20000000 // Mark CP1 as usable
#define SR_FR 0x04000000 // Enable MIPS III FP registers
#define SR_BEV 0x00400000 // Controls location of exception vectors
#define SR_PE 0x00100000 // Mark soft reset (clear parity error)

#define SR_KX 0x00000080 // Kernel extended addressing enabled
#define SR_SX 0x00000040 // Supervisor extended addressing enabled
#define SR_UX 0x00000020 // User extended addressing enabled

#define SR_ERL 0x00000004 // Error level
#define SR_EXL 0x00000002 // Exception level
#define SR_IE 0x00000001 // Interrupts enabled

// Standard Cause Register bitmasks
#define CAUSE_EXC_MASK (0x1F << 2)
#define CAUSE_EXC_INTERRUPT (0 << 2)
#define CAUSE_EXC_SYSCALL (8 << 2)
#define CAUSE_EXC_BREAKPOINT (9 << 2)
#define CAUSE_EXC_COPROCESSOR (11 << 2)

// Masks for Status Registers IM bits and Cause Registers IP bits
#define INTR_MASK (0xFF << 8)
#define INTR_SW (0x03 << 8)
#define INTR_EXT (0x7C << 8)
#define INTR_TIMER (0x80 << 8)

/* Standard (R4000) cache operations. Taken from "MIPS R4000
Microprocessor User's Manual" 2nd edition: */

#define CACHE_I (0) /* primary instruction */
#define CACHE_D (1) /* primary data */
#define CACHE_SI (2) /* secondary instruction */
#define CACHE_SD (3) /* secondary data (or combined instruction/data) */

#define INDEX_INVALIDATE (0) /* also encodes WRITEBACK if CACHE_D or CACHE_SD */
#define INDEX_LOAD_TAG (1)
#define INDEX_STORE_TAG (2)
#define CREATE_DIRTY_EXCLUSIVE (3) /* CACHE_D and CACHE_SD only */
#define HIT_INVALIDATE (4)
#define CACHE_FILL (5) /* CACHE_I only */
#define HIT_WRITEBACK_INVALIDATE (5) /* CACHE_D and CACHE_SD only */
#define HIT_WRITEBACK (6) /* CACHE_I, CACHE_D and CACHE_SD only */
#define HIT_SET_VIRTUAL (7) /* CACHE_SI and CACHE_SD only */

#define BUILD_CACHE_OP(o,c) (((o) << 2) | (c))

/* Individual cache operations: */
#define INDEX_INVALIDATE_I BUILD_CACHE_OP(INDEX_INVALIDATE,CACHE_I)
#define INDEX_WRITEBACK_INVALIDATE_D BUILD_CACHE_OP(INDEX_INVALIDATE,CACHE_D)
#define INDEX_INVALIDATE_SI BUILD_CACHE_OP(INDEX_INVALIDATE,CACHE_SI)
#define INDEX_WRITEBACK_INVALIDATE_SD BUILD_CACHE_OP(INDEX_INVALIDATE,CACHE_SD)

#define INDEX_LOAD_TAG_I BUILD_CACHE_OP(INDEX_LOAD_TAG,CACHE_I)
#define INDEX_LOAD_TAG_D BUILD_CACHE_OP(INDEX_LOAD_TAG,CACHE_D)
#define INDEX_LOAD_TAG_SI BUILD_CACHE_OP(INDEX_LOAD_TAG,CACHE_SI)
#define INDEX_LOAD_TAG_SD BUILD_CACHE_OP(INDEX_LOAD_TAG,CACHE_SD)

#define INDEX_STORE_TAG_I BUILD_CACHE_OP(INDEX_STORE_TAG,CACHE_I)
#define INDEX_STORE_TAG_D BUILD_CACHE_OP(INDEX_STORE_TAG,CACHE_D)
#define INDEX_STORE_TAG_SI BUILD_CACHE_OP(INDEX_STORE_TAG,CACHE_SI)
#define INDEX_STORE_TAG_SD BUILD_CACHE_OP(INDEX_STORE_TAG,CACHE_SD)

#define CREATE_DIRTY_EXCLUSIVE_D BUILD_CACHE_OP(CREATE_DIRTY_EXCLUSIVE,CACHE_D)
#define CREATE_DIRTY_EXCLUSIVE_SD BUILD_CACHE_OP(CREATE_DIRTY_EXCLUSIVE,CACHE_SD)

#define HIT_INVALIDATE_I BUILD_CACHE_OP(HIT_INVALIDATE,CACHE_I)
#define HIT_INVALIDATE_D BUILD_CACHE_OP(HIT_INVALIDATE,CACHE_D)
#define HIT_INVALIDATE_SI BUILD_CACHE_OP(HIT_INVALIDATE,CACHE_SI)
#define HIT_INVALIDATE_SD BUILD_CACHE_OP(HIT_INVALIDATE,CACHE_SD)

#define CACHE_FILL_I BUILD_CACHE_OP(CACHE_FILL,CACHE_I)
#define HIT_WRITEBACK_INVALIDATE_D BUILD_CACHE_OP(HIT_WRITEBACK_INVALIDATE,CACHE_D)
#define HIT_WRITEBACK_INVALIDATE_SD BUILD_CACHE_OP(HIT_WRITEBACK_INVALIDATE,CACHE_SD)

#define HIT_WRITEBACK_I BUILD_CACHE_OP(HIT_WRITEBACK,CACHE_I)
#define HIT_WRITEBACK_D BUILD_CACHE_OP(HIT_WRITEBACK,CACHE_D)
#define HIT_WRITEBACK_SD BUILD_CACHE_OP(HIT_WRITEBACK,CACHE_SD)

#define HIT_SET_VIRTUAL_SI BUILD_CACHE_OP(HIT_SET_VIRTUAL,CACHE_SI)
#define HIT_SET_VIRTUAL_SD BUILD_CACHE_OP(HIT_SET_VIRTUAL,CACHE_SD)
#define INTR_MASK (0xFF << 8)
#define INTR_SW (0x03 << 8)
#define INTR_EXT (0x7C << 8)
#define INTR_TIMER (0x80 << 8)

// BREAK is overloaded CACHE opcode. Register number specifies the cache op.
#define CACHE BREAK
// Prepend NOOP to ERET to avert CP0 hazards
#define ERET NOOP; NOOP; WORD $0x42000018

// Individual cache operations
#define INDEX_INVALIDATE_I R00
#define INDEX_WRITEBACK_INVALIDATE_D R01
#define INDEX_INVALIDATE_SI R02
#define INDEX_WRITEBACK_INVALIDATE_SD R03
#define INDEX_LOAD_TAG_I R04
#define INDEX_LOAD_TAG_D R05
#define INDEX_LOAD_TAG_SI R06
#define INDEX_LOAD_TAG_SD R07
#define INDEX_STORE_TAG_I R08
#define INDEX_STORE_TAG_D R09
#define INDEX_STORE_TAG_SI R10
#define INDEX_STORE_TAG_SD R11
#define CREATE_DIRTY_EXCLUSIVE_D R13
#define CREATE_DIRTY_EXCLUSIVE_SD R15
#define HIT_INVALIDATE_I R16
#define HIT_INVALIDATE_D R17
#define HIT_INVALIDATE_SI R18
#define HIT_INVALIDATE_SD R19
#define CACHE_FILL_I R20
#define HIT_WRITEBACK_INVALIDATE_D R21
#define HIT_WRITEBACK_INVALIDATE_SD R23
#define HIT_WRITEBACK_I R24
#define HIT_WRITEBACK_D R25
#define HIT_WRITEBACK_SD R27
#define HIT_SET_VIRTUAL_SI R30
#define HIT_SET_VIRTUAL_SD R31
1 change: 1 addition & 0 deletions src/runtime/rt0_noos_mips64.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package runtime
import "unsafe"

const pallocMin = 20 * 1024
const signalStackSize = 4096

//go:nosplit
func meminit(freeStart, freeEnd, nodmaStart, nodmaEnd uintptr) {
Expand Down
27 changes: 10 additions & 17 deletions src/runtime/rt0_noos_mips64.s
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@
#include "textflag.h"
#include "asm_mips64.h"

// BREAK is overloaded CACHE opcode. Register number specifies the cache op.
#define CACHE BREAK

TEXT _rt0_mips64_noos(SB),NOSPLIT|NOFRAME,$0
JMP ·rt0_target(SB)

Expand Down Expand Up @@ -51,10 +48,10 @@ loop:
MOVW R11, 0x80(R9)
MOVW R11, 0x100(R9)
MOVW R11, 0x180(R9)
CACHE R16, 0(R9)
CACHE R16, 0x80(R9)
CACHE R16, 0x100(R9)
CACHE R16, 0x180(R9)
CACHE HIT_INVALIDATE_I, 0(R9)
CACHE HIT_INVALIDATE_I, 0x80(R9)
CACHE HIT_INVALIDATE_I, 0x100(R9)
CACHE HIT_INVALIDATE_I, 0x180(R9)
ADD $4, R8
ADD $4, R9
ADDU $-1, R10
Expand All @@ -63,15 +60,13 @@ loop:
JMP runtime·rt0_go(SB)


#define PALLOC_MIN 20*1024

TEXT runtime·rt0_go(SB),NOSPLIT|NOFRAME|TOPFRAME,$0
// setup main stack in cpu0.gh
MOVV $runtime·cpu0(SB), R8 // gh is the first field of the cpuctx struct
MOVV $runtime·ramend(SB), R29 // main stack starts at the end of memory
SUB $16, R29
MOVV R29, (g_stack+stack_hi)(R8)
SUB $4096, R29, R9
SUB $const_signalStackSize, R29, R9
MOVV R9, (g_stack+stack_lo)(R8)
ADD $const_stackGuard, R9
MOVV R9, g_stackguard0(R8)
Expand All @@ -92,7 +87,7 @@ TEXT runtime·rt0_go(SB),NOSPLIT|NOFRAME|TOPFRAME,$0
MOVV $runtime·ramend(SB), R9
MOVV $runtime·nodmastart(SB), R10
MOVV $runtime·nodmaend(SB), R11
SUB $4096, R9
SUB $const_signalStackSize, R9

SUB $32, R29
MOVV R8, 8(R29)
Expand All @@ -103,8 +98,8 @@ TEXT runtime·rt0_go(SB),NOSPLIT|NOFRAME|TOPFRAME,$0
ADD $32, R29

// initialize noos tasker and Go scheduler
JAL runtime·taskerinit(SB)
JAL runtime·schedinit(SB)
JAL runtime·taskerinit(SB)
JAL runtime·schedinit(SB)

// allocate g0 for m0 and leave gh
SUB $16, R29
Expand Down Expand Up @@ -136,22 +131,20 @@ TEXT runtime·rt0_go(SB),NOSPLIT|NOFRAME|TOPFRAME,$0
MOVV R10, m_gsignal(R9) // cpu0.mh.gsignal = cpu0.gh (to easily check for handler mode)
MOVV R9, g_m(R10) // cpu0.gh.m = cpu0.mh

// TODO switch to the user mode?

// create a new goroutine to start program
SUB $16, R29
MOVV $runtime·mainPC(SB), R8
MOVV R8, 8(R29) // arg 1: fn
MOVV $0, R8
MOVV R8, 0(R29) // dummy LR
JAL runtime·newproc(SB)
ADD $16, R29 // pop args and LR
ADD $16, R29

// enable interrupts
// TODO where to enable interupts correctly?
MOVW R0, M(C0_COMPARE)
MOVW M(C0_SR), R8
OR $(SR_IE|INTR_SW|INTR_EXT), R8
OR $(SR_IE|INTR_SW|INTR_EXT), R8
MOVW R8, M(C0_SR)

// start this M
Expand Down
Loading