Robert Finch wrote:
On 2024-03-07 2:51 p.m., MitchAlsup1 wrote:
Robert Finch wrote:
On 2024-03-07 1:39 a.m., BGB wrote:
>
>
Bigfoot uses a whole byte for access rights, with separate read-write-execute for user and supervisor, and write protect for hypervisor and machine modes. He also uses 4 bits for the cache-ability which match the cache-ability bits on the bus.
Can you think of an example where a user Read-Only page would not be
writeable from super ?? Or a device on PCIe ??
Can you think of an example where a user Execute-Only page would not
be readable from super ?? Or a device on PCIe ??
I cannot think of examples. But I had thought the hypervisor / machine might want to treat supervisor mode like an alternate user mode. The bits can always just be set = 7.
Or, you can avoid blowing the 3-extra-bits and just assume a higher
privilege level can access pages the lesser privileged cannot.
Can you think of an example where a user page marked RWE = 000 would
not be readable and writeable from super ? Or a device on PCIe ??
A page marked RWE=000 is an unusable page. Perhaps to signal bad memory. Or perhaps as a hidden data page full of comments or remarks. If its not readable-writeable or executable what is it? Nothing should be able to access it, except maybe the machine/debug operating mode.
I choose this because I have a mandate on the Safe-Stack area that LDs
and STs (and prefetches and post pushes) cannot access the data--only
ENTER and EXIT can access the data so the contract (ABI) between caller
and callee cannot be violated {{avoiding may attack strategies}}
Can you think of an example where 2-bits denoting {L1, L2, LLC, DRAM}
does not describe the cache placement of a line adequately ??
The cache-ability bits were not directly describing cache placement. They were like the cache-ability bits in the bus. They specified cache-policy. Bufferable / non-bufferable. Write-through, write-back, allocate, etc. But now that I reviewed it I forgot I had removed these bits from the PTE / TLBE.
I do not like situations where all possible codes are used.
I would like to apply this argument to integer encodings--integers need
an encoding to represent "there is no value here" {similar to NaN}.
So, I would probably use three bits. Could a cache line be located in a Register for instance?
My cache lines are 64-bytes (512-bits) in size,
My registers are 64-bits in size.
Flip-flops can be any number of bits in size.
4 cache lines ARE my register FILE.
1 cache line IS my Thread Header 5 cache lines ARE my Thread State (all of it)
4 Thread States are accessible at any instant of time making context
switching easier. SVC goes up the chain to higher privilege, SVR does the reverse.
I cannot envision every usage, although a lot is known today, I thought it would be better to err on the side of providing too many bits rather than not enough.
This works only so long as you do not run out of bits. Once you start
scrambling to find an encoding of 2 (or 3) fields that would never be in use and use the combination of 2 fields to mean something "special"
you know you are in trouble.
Not enough is hard to add later. There are loads of bits available in the 128-bit PTE, 96 bits would be enough. But it is not a nice power of two.
Hmmmmmmmmmm,
I got pairs of 63-bit virtual address spaces into a 64-bit container.
And since we are only around 48-bits* of address space consumption,
it will outlast my lifetime.
(*) the largest servers while typical big desktops are down in the 35-37-bit range.
I am using the value of zero for the ASID to represent the machine mode’s ASID. A lot of hardware is initialized to zero at reset, so it’s automatically the machine mode’s. Other than zero the ASID could be anything assigned by the OS.
I do not rely on control registers being set to zero, instead part of
HW context switching end up reading these out of ROM and into those
registers--so they can have any reasonable bit pattern SW desires.
{{This is sort of like how Alpha comes out of reset and streams a ROM
through the scan path to initialize the internals.}}
I am also assuming that ASID = 0 is the highest level of privilege;
but this is purely a SW choice.
Assuming a zero at reset was more of a default ‘if I forget’ approach. I have machine state being initialized from ROM too.
In effect, I have 1 "register" that is set at reset {along with clearing
the control bits of the pipeline.} Everything else is loaded from ROM.
When control arrives after reset, you have a Thread Header which provides
{IP, Root, Call Stack Pointer, raised and Enabled exceptions, ASID, Why,
and a few more}. The privilege level determines which register file gets loaded. So by the time you are fetching instructions, you have a register
file (filled with data), a data stack pointer, a call stack pointer, and
30-odd registers containing whatever BOOT programmers thought was appropriate.
You also have MMU setup with the TLB enabled (and active). The MMU maps L1
and L2 in the allocated state, so you have at least 256KB of memory to work
in BEFORE DRAM is identified, configured, initialized, and tuned to the electrical environment they are plugged into. This, in turn means all (100%)
of BOOT can be written in a HLL (C) without access to an assembler.