## Trebuchet Notes
This is a bunch of unstructured notes compiled for Trebuchet.
### Resources
- [MIPS64 Privileged Resource Architecture](https://s3-eu-west-1.amazonaws.com/downloads-mips/documents/MD00091-2B-MIPS64PRA-AFP-05.04.pdf)
- [MIPS Memory Map](https://training.mips.com/basic_mips/PDF/Memory_Map.pdf)
- [MIPS Exceptions Overview](https://training.mips.com/basic_mips/PDF/Exceptions.pdf)
- [MIPS R4000 Manual](https://course.ece.cmu.edu/~ece447/s15/lib/exe/fetch.php?media=mips_r4000_users_manual.pdf)
### Linux Kernel Source Notes
- see arch/mips/kernel/traps.c for the interrupt install logic
- main interrupt handler is implemented by [`except_vec3_generic`](https://livegrep.com/search/linux?q=except_vec3_generic&fold_case=auto®ex=false&context=true). And it's installed at 0x80 and 0x180.
- mips entry point is at [arch/mips/kernel/head.S](https://github.com/torvalds/linux/blob/v6.13/arch/mips/kernel/head.S#L85)
- Kernel quirk: See [arch/mips/mm/tlb-r4k.c](https://github.com/torvalds/linux/blob/v6.13/arch/mips/mm/tlb-r4k.c#L535)
- The ELPA bit is only set in `PageGrain` if the cpu "has rixi". So in order to take advantage of large addressing trebuchet may have to support rixi.
### Linux Kconfig
These are the settings you'll find in `make menuconfig`:
- System type - Malta board system
- Endianess - Big endian
- CPU Selection - MIPS64r2
- Kernel type / code model - 64-bit
- custom initramfs source (under General setup)
- (optional) Disable compressed initramfs (so `none` compression type) for faster emulation at linux boot.
### Building MIPS Kernel Image
Make sure you have the essential cross-compile packages. On Ubuntu:
```
sudo apt-get install crossbuild-essential-mips64 gcc-mips64-linux-gnuabi64
```
Then build the kernel:
```
export ARCH=mips
EXPORT CROSS_COMPILE=mips64-linux-gnuabi64-
git clone https://github.com/torvalds/linux
cd linux
# ensure you have the core kernel build tools
sudo apt-get install build-essential bc bison flex libssl-dev libelf-dev
cp /path/to/custom.kconfig .config
make defconfig
make -j8
```
### Building MIPS64 Go program
```
env GOOS=linux GOARCH=mips64 GOMIPS64=softfloat go build -o hello.mips64 ./main.go
```
## R4000 Notes
The R4000 processor supports the following interrupts: six hardware interrupts, one internal “timer interrupt,” two software interrupts, and one nonmaskable interrupt. The processor takes an exception on any interrupt.
### Exception Vector Locations
#### Exception Vector Base Addresses
The 64-bit-mode vector base address for all exceptions; the 32-bit mode address is the low-order 32 bits (for instance, the base address for NMI in 32-bit mode is 0xBFC0 0000):
| Exception | BEV 0 | BEV 1 |
| ---------------------- | --------------------- | --------------------- |
| Cache Error | 0xFFFF FFFF A000 0000 | 0xFFFF FFFF BFC0 0200 |
| Others | 0xFFFF FFFF 8000 0000 | 0xFFFF FFFF BFC0 0200 |
| Reset, NMI, Soft Reset | 0xFFFF FFFF BFC0 0000 | 0xFFFF FFFF BFC0 0000 |
#### Exception Vector Offsets
The vector offset added to the base address to create the exception address
| Exception | R4000 Processor Vector Offset |
| ------------------------------------- | ----------------------------- |
| TLB refill, EXL = 0 | 0x000 |
| XTLB refill, EXL = 0 (X = 64-bit TLB) | 0x080 |
| Cache Error | 0x100 |
| Others | 0x180 |
| Reset, Soft Reset, NMI | None |
### Exception Priority Order
- Reset
- Soft Reset
- NMI
- Address error - instruction fetch
- TLB refill - instruction fetch
- TLB invalid - instruction fetch
- Cache error - instruction fetch
- Virtual Coherency - instruction fetch
- Bus Error - instruction fetch
- Integer Overflow, Trap, System Call, Breakpoint, Reserved Instruction, Coprocessor Unusable
- Address Error - data access
- TLB refill - data access
- TLB invalid - data access
- TLB modified - data write
- Cache error - data access
- Watch
- Virtual Coherency – Data access
- Bus error – Data access
- Interrupt (lowest priority)
### Emulating using Qemu
Emulating the mips64 bzImage on qemu using a custom init:
```
qemu-system-mips64 -singlestep -d in_asm,cpu -M malta -cpu MIPS64R2-generic -kernel vmlinux -nographic -append "console=ttyS0 rdinit=/bin/hello.mips64"
```
Useful to quickly check how qemu emulates certain instructions. The `-singlestep -d in_asm,cpu` flags will dump the CPU state of every executed instruction.
## TODOs
### Performance-related open questions.
- Cache line size (see the `Config` register). It's 8K for I and D cache on the r4k. But might be worth tweaking. But I wouldn't be surprised if Linux doesn't handle non-standard sizes correctly here.
### Hardware Page Table Walk?
Basically to assist in page fault handling by checking page tables in the emulator, rather than rely on Linux to do this. This should reduce the overhead of emualting page faults. But we have to ensure linux supports this before emualting. This can be dealt with later if we see performance issues in the VM.
## CP0 Notes
### LLAddr
Contains the phyiscal address read by the most recent load linked instruction. The ISA states it's for diagnostic purposes only. But for trebuchet, it might be required to properly emulate and use for RMW emulation. Similar to how its counterpart is used in cannon.
### Config5
No need to reset. Segmentation control is a MIPS64 release 3 feature and not supported by Trebuchet. Same deal with EVA.
However, we will need to support RI/XI due to a Linux quirk.
### PRId
On r4k, this should be set to 0x04.
### PageMask
Always zeroed for 4KB pages.