LEVITAS: an OS for Ternary microprocessor 5500FP

This forums is for OS project announcements including project openings, new releases, update notices, test requests, and job openings (both paying and volunteer).
Post Reply
clros
Posts: 5
Joined: Thu Jan 01, 2026 4:29 am

LEVITAS: an OS for Ternary microprocessor 5500FP

Post by clros »

LEVITAS 0.1 — a native OS for a real balanced-ternary CPU

Hi all,

I'd like to share LEVITAS, an operating system I've been writing for the 5500FP — a 24-trit balanced-ternary RISC processor I designed, running on real hardware (no binary emulation underneath). Version 0.1 is intentionally minimal, with a small shell and a syscall interface for I/O.

Image

Full details — shell commands, syscall table, ABI, downloads — are here:
https://www.ternary-computing.com/levitas/

Happy to answer questions about the ISA or the ternary hardware itself.

— Claudio "CP" La Rosa
Octocontrabass
Member
Member
Posts: 6245
Joined: Mon Mar 25, 2013 7:01 pm

Re: LEVITAS: an OS for Ternary microprocessor 5500FP

Post by Octocontrabass »

clros wrote: Tue Jul 28, 2026 6:57 amRISC

Happy to answer questions about the ISA or the ternary hardware itself.
Why does your CPU have separate memory and I/O address spaces? RISC CPUs usually have a single unified address space.
clros
Posts: 5
Joined: Thu Jan 01, 2026 4:29 am

Re: LEVITAS: an OS for Ternary microprocessor 5500FP

Post by clros »

Octocontrabass wrote: Tue Jul 28, 2026 10:38 am
clros wrote: Tue Jul 28, 2026 6:57 amRISC

Happy to answer questions about the ISA or the ternary hardware itself.
Why does your CPU have separate memory and I/O address spaces? RISC CPUs usually have a single unified address space.
Hi Octocontrabass,

Because it's actually very simple to implement.
And I can keep the two areas completely separate: memory from I/O.

The RISC concept has evolved over time, and many features of the original RISC definition have simply disappeared because...it wasn't worth keeping them.
In my case, among other things, I also preferred the implementation of explicit instructions for stack management (push/pop); these didn't exist on "traditional" or "original" RISCs, but implementing them simply increases code density.
Octocontrabass
Member
Member
Posts: 6245
Joined: Mon Mar 25, 2013 7:01 pm

Re: LEVITAS: an OS for Ternary microprocessor 5500FP

Post by Octocontrabass »

clros wrote: Tue Jul 28, 2026 2:21 pmBecause it's actually very simple to implement.
Being simple to implement does not mean it's a good idea. (And a simple implementation limits what you can do with it. Can you have drivers in user mode, or does all I/O access require kernel privileges?)
clros wrote: Tue Jul 28, 2026 2:21 pmAnd I can keep the two areas completely separate: memory from I/O.
What about memory-mapped I/O? You'll see a whole lot of that on x86 PCs, even though x86 also has a separate I/O address space.
clros
Posts: 5
Joined: Thu Jan 01, 2026 4:29 am

Re: LEVITAS: an OS for Ternary microprocessor 5500FP

Post by clros »

Octocontrabass wrote: Sat Aug 01, 2026 4:23 pm Being simple to implement does not mean it's a good idea. (And a simple implementation limits what you can do with it. Can you have drivers in user mode, or does all I/O access require kernel privileges?)
Yes, access to the IO memory area is privileged.
Octocontrabass wrote: What about memory-mapped I/O? You'll see a whole lot of that on x86 PCs, even though x86 also has a separate I/O address space.
Nothing stops I/O from being mapped into the memory address space on this CPU — there are 9 privilege levels by design, though only 2 are in use right now. The separate address space was easy to get both on the hardware side and on the instruction decoder side — it's essentially free.

That said, I suspect your question is pointing at something else — is it?
Octocontrabass
Member
Member
Posts: 6245
Joined: Mon Mar 25, 2013 7:01 pm

Re: LEVITAS: an OS for Ternary microprocessor 5500FP

Post by Octocontrabass »

clros wrote: Sun Aug 02, 2026 3:44 pmYes, access to the IO memory area is privileged.
And there's no way to get unprivileged access, so any userspace drivers that need to access the I/O address space will be slowed down by the system call overhead. Anyone who wants high performance is forced to put those drivers in the kernel.
clros wrote: Sun Aug 02, 2026 3:44 pmthere are 9 privilege levels by design, though only 2 are in use right now.
That seems like too many. RISC-V seems to be fine with four (firmware, hypervisor, system, user), and even though modern x86 has more than that, only the four equivalents to RISC-V are ever actually used. Why does your CPU have so many privilege levels?
clros wrote: Sun Aug 02, 2026 3:44 pmThat said, I suspect your question is pointing at something else — is it?
It seems like you might be repeating poor choices from other CPU designs without understanding why those choices caused problems.
clros
Posts: 5
Joined: Thu Jan 01, 2026 4:29 am

Re: LEVITAS: an OS for Ternary microprocessor 5500FP

Post by clros »

Octocontrabass wrote: Sun Aug 02, 2026 8:34 pm And there's no way to get unprivileged access, so any userspace drivers that need to access the I/O address space will be slowed down by the system call overhead. Anyone who wants high performance is forced to put those drivers in the kernel.
No, there's no way; after all, if the instructions are privileged, there must be a reason. I figured you were trying to get to that point, to highlight a performance issue. Well, it's a deliberate design choice, and it was carefully considered. Building the decode logic for memory-mapped I/O is possible in principle — nothing about the CPU prevents it — but it's not something I'll be implementing on the current motherboard.

Octocontrabass wrote: That seems like too many. RISC-V seems to be fine with four (firmware, hypervisor, system, user), and even though modern x86 has more than that, only the four equivalents to RISC-V are ever actually used. Why does your CPU have so many privilege levels?
It's not hard to understand, knowing it's a ternary CPU.

(9 turned out to be more than strictly needed, but it costs nothing in encoding.)
Octocontrabass wrote: It seems like you might be repeating poor choices from other CPU designs without understanding why those choices caused problems.
I don't see why using privileged instructions is inherently a mistake. My inspiration could just as well be a security-first OS that never allows direct hardware access outside the kernel, no exceptions, regardless of speed.

Separately, on the hardware side — that obviously doesn't rule out mapping I/O directly into memory at some point, though that would need actual external decoder hardware to make it work.
nullplan
Member
Member
Posts: 2033
Joined: Wed Aug 30, 2017 8:24 am

Re: LEVITAS: an OS for Ternary microprocessor 5500FP

Post by nullplan »

clros wrote: Sun Aug 02, 2026 11:51 pm No, there's no way; after all, if the instructions are privileged, there must be a reason. I figured you were trying to get to that point, to highlight a performance issue. Well, it's a deliberate design choice, and it was carefully considered. Building the decode logic for memory-mapped I/O is possible in principle — nothing about the CPU prevents it — but it's not something I'll be implementing on the current motherboard.
Looks to me like you spent a whole lot of effort reimplementing one of x86's weirder design choices but worse. x86 has the IOPB with which an OS can cede control of certain ports to userspace processes without requiring system call indirection.

All RISC architectures I am aware of (AVR, ARM, PowerPC, OpenRISC, and RISC-V) do not implement IO space separately, so the question does not even turn up. The OS can grant access to any particular range of physical memory by allowing it to be mapped into unprivileged memory.
clros wrote: Sun Aug 02, 2026 11:51 pm It's not hard to understand, knowing it's a ternary CPU.

(9 turned out to be more than strictly needed, but it costs nothing in encoding.)
Bravo. The four normal privilege levels of x86 protected mode also cost "nothing" as in, they are already part of all the tables. But still two of those four levels typically go unused. The smart design would be to learn from the mistakes of the past.
clros wrote: Sun Aug 02, 2026 11:51 pm I don't see why using privileged instructions is inherently a mistake. My inspiration could just as well be a security-first OS that never allows direct hardware access outside the kernel, no exceptions, regardless of speed.
Thus requiring a fat kernel that does everything. The more code is privileged, the more likely it is to have some error that is exploitable to at least get a denial of service, if not outright privilege escalation going. A strictly security-first approach would be a microkernel approach that pushes as much logic as possible into unprivileged userspace processes, so that errors (that will happen) cannot take down the entire system.

In practice this is hard to implement, I know. An evil driver can make DMAing hardware overwrite all memory it wants to, including the page tables (and if you can overwrite the page tables, you can map your own code with the highest privilege, and thus usurp the highest privilege). But pushing code into kernel space that does not belong there is definitely not the security-centric approach.
Carpe diem!
clros
Posts: 5
Joined: Thu Jan 01, 2026 4:29 am

Re: LEVITAS: an OS for Ternary microprocessor 5500FP

Post by clros »

nullplan wrote: Mon Aug 03, 2026 1:25 am Looks to me like you spent a whole lot of effort reimplementing one of x86's weirder design choices but worse. x86 has the IOPB with which an OS can cede control of certain ports to userspace processes without requiring system call indirection.

All RISC architectures I am aware of (AVR, ARM, PowerPC, OpenRISC, and RISC-V) do not implement IO space separately, so the question does not even turn up. The OS can grant access to any particular range of physical memory by allowing it to be mapped into unprivileged memory.
As I already told you, the implementation was ZERO cost.
I'm aware that some operating systems allow you to select certain processes to use privileged instructions without generating TRAPS, but... which ones?
Honestly, I don't know, and I don't know if this is the best solution.
So, it's fine like this: two address spaces and clear separation of instructions.
nullplan wrote: ]Bravo. The four normal privilege levels of x86 protected mode also cost "nothing" as in, they are already part of all the tables. But still two of those four levels typically go unused. The smart design would be to learn from the mistakes of the past.
I was just told that RISC uses four privilege levels.

With just one trit, I couldn't have four.
nullplan wrote: Thus requiring a fat kernel that does everything. The more code is privileged, the more likely it is to have some error that is exploitable to at least get a denial of service, if not outright privilege escalation going. A strictly security-first approach would be a microkernel approach that pushes as much logic as possible into unprivileged userspace processes, so that errors (that will happen) cannot take down the entire system.

In practice this is hard to implement, I know. An evil driver can make DMAing hardware overwrite all memory it wants to, including the page tables (and if you can overwrite the page tables, you can map your own code with the highest privilege, and thus usurp the highest privilege). But pushing code into kernel space that does not belong there is definitely not the security-centric approach.
I know the exact opposite.
As far as I know (correct me if I'm wrong), seL4 uses user-mode drivers, but they still need to switch to kernel mode at least for hardware configuration when they need to access hardware devices.
In any case, if you don't like it, there's nothing stopping you from implementing memory I/O, and you always have the separate space approach, which, as I said, was cost-free.
nullplan
Member
Member
Posts: 2033
Joined: Wed Aug 30, 2017 8:24 am

Re: LEVITAS: an OS for Ternary microprocessor 5500FP

Post by nullplan »

clros wrote: Mon Aug 03, 2026 2:04 am I'm aware that some operating systems allow you to select certain processes to use privileged instructions without generating TRAPS, but... which ones?
Linux, for example. https://man7.org/linux/man-pages/man2/ioperm.2.html
clros wrote: Mon Aug 03, 2026 2:04 am I was just told that RISC uses four privilege levels.
x86 initially added four privilege levels, but then operating systems proceeded to disregard two of them and they ended up unused. Support for hypervisors and firmware came later. For RISC architectures like PowerPC, the development was similar: They started out with two privilege levels (encoded in the MSR.PR bit), then later added more as the need for hypervisors developed.
clros wrote: Mon Aug 03, 2026 2:04 am With just one trit, I couldn't have four.
You can roll HV and firmware together, then you only need three.
Carpe diem!
JimCameron
Posts: 1
Joined: Sat Aug 08, 2026 2:22 am

Re: LEVITAS: an OS for Ternary microprocessor 5500FP

Post by JimCameron »

clros wrote: Tue Jul 28, 2026 2:21 pm The RISC concept has evolved over time, and many features of the original RISC definition have simply disappeared because...it wasn't worth keeping them.
In my case, among other things, I also preferred the implementation of explicit instructions for stack management (push/pop); these didn't exist on "traditional" or "original" RISCs, but implementing them simply increases code density.
Only if you have shorter encodings for those instructions. The ARM stack pointer was defined purely by convention until Thumb came along. (In fact there was an early version of the calling convention that used R12 as a stack pointer instead of R13!) With 81 registers and fixed-width instructions there's no reason not to burn one on a stack pointer. You've got plenty of room in the instruction space for a rich set of auto-increment/decrement instructions. Or if you want better code density, go the Thumb route and introduce compact (12-trit) encodings for some instructions.
Post Reply