k2/cardslots [ Modules ]
NAME
cardslots
FUNCTION
This module is intended to provide an abstraction of the virtual Kestrel-2 address space.
The vast majority of the time, you'll want to use these functions for accessing the Kestrel-2 memory space:
* slots_read_hword(), slots_write_hword()
for reading and writing 16-bit values, and,
* slots_read_byte(), slots_write_byte()
for reading and writing 8-bit values.
NOTE: Although the Kestrel-2EX's processor is a 64-bit processor, we only provide procedures for accessing 16-bit values. That's because a real hardware implementation will only have a 16-bit path to system RAM. The processor emulation module is responsible for breaking 32-bit and 64-bit accesses into smaller 16-bit chunks.
For the purposes of maintaining a GUI, there's a specialized function, slots_translate_address_from_virtual(), which helps provide efficient access to bitmap data for rendering to the screen. DO NOT call this function unless you know exactly what you're doing. It is easy to crash the application with it if you're not extra careful.
slots_init() is where you'll find the code that provides the initial virtual environment configuration. "Slots" (cardslot_t structures) are populated from what is believed to be the most frequently accessed resource to the least frequently accessed resource.
cardslots/cardslot_rd_fn, cardslots/cardslot_wr_fn [ Types ]
[ Top ] [ cardslots ] [ Types ]
NAME
cardslot_rd_fn
cardslot_wr_fn
SYNOPSIS
typedef void cardslot_rd_fn(
void* data, privilege_t privilege,
uint32_t addr, uint8_t lanes,
uint16_t* result, bool* error
);
typedef void cardslot_wr_fn(
void* data, privilege_t privilege,
uint32_t addr, uint8_t lanes, uint16_t value,
bool* error
);
FUNCTION
tbd
Although these callbacks may be called from any thread context, as long as you use the slots_{read,write}_{byte,hword} functions to invoke them, there is no need to explicitly lock resources; this should be done for you automatically by the public API.
INPUTS
data -- Resource-specific data (e.g., for memory resources, the base
local address of a buffer large enough to hold all of the
memory that resource provides).
privilege -- What privilege the processor was in when the resource
access was made.
addr -- The virtual address being accessed. NOTE: This is an hword
address, NOT a byte address!
lanes -- A bitmap indicating which byte lanes are involved in the
transfer. Bit 0 corresponds to data bits 0-7, bit 1 to data
bits 8-15.
result -- Pointer to a variable that will receive any read values.
Depending upon the lanes parameter, the upper byte, the lower
byte, or both bytes of a 16-bit half-word will be affected.
value -- The value to store into the resource. Depending upon the
lanes parameter, the data will be sourced either from bits
8-15, 0-7, or both.
error -- Pointer to a bool or gboolean variable indicating that
an error has happened while processing the memory request.
RESULT
If everything was successful, *error is not modified. Otherwise,
the virtual resource is not affected in any way, and *error is set
to true.
SEE ALSO
cardslot_t, slots_t
cardslots/cardslot_s, cardslots/cardslot_t [ Structures ]
[ Top ] [ cardslots ] [ Structures ]
NAME
struct cardslot_s
cardslot_t
FUNCTION
Provide a single virtual to local memory mapping.
To resolve a virtual address (VA) to a local address, the first step is to apply an and-mask and a xor-mask like so:
P = (VA & addr_and_mask) ^ xor_mask
If P evaluates to zero, we know we have a match; that is, this cardslot_t is responsible for handling the virtual address provided. If P evaluates to a non-zero value, this cardslot_t is not responsible, and you should look elsewhere.
Virtual addresses in the emulated environment are 32-bits wide, and MAY be between 24- and 32-bits in physical hardware. However, it is unlikely that any single card will provide gigabytes worth of storage on its own! Therefore, we need to constrain the address to just the significant bits that are considered "register selects". This will provide a byte offset into the card's resource space. In the electronics engineering field, this is called "partial address decoding."
For the purposes of emulation, once we have the byte offset in the card's resource space, we add the data pointer to acquire the actual local address.
LA = (P & addr_sel_mask) + data
It is pretty rare to work directly with local addresses; usually you just want to do something with the virtual address you're given. For this reason, each cardslot_t provides three methods for fulfilling a processor request: you can read from the resource, write to the resource, or attempt to perform an instruction fetch from a resource.
MEMBERS
addr_and_mask -- provides the AND mask, selecting which of the high
bits of the virtual address to check for an address match.
addr_xor_mask -- provides the XOR mask, selecting the precise value
those high bits selected by the AND mask must equal in order
to register a match.
addr_sel_mask -- provides another AND mask, but these select the low-
order memory address bits used to select a specific register
or byte address in a memory resource.
read, ifetch -- provides a callback which is invoked when something is
trying to read (fetch an instruction from, resp.) from the
card. This gives the card's handler an opportunity to perform
any desired side-effects as well (e.g., if writing to a color
palette register, it can cause the display to change color).
write -- provides a callback which is invoked when something is
trying to write to the card.
data -- For memory-type devices, this provides the local base address
of the backing memory.
SEE ALSO
slots_t, cardslot_rd_fn, cardslot_wr_fn
SOURCE
typedef struct cardslot_s {
uint32_t addr_and_mask;
uint32_t addr_xor_mask;
uint32_t addr_sel_mask;
cardslot_rd_fn* read;
cardslot_wr_fn* write;
cardslot_rd_fn* ifetch;
void* data;
} cardslot_t;
cardslots/privilege_e, cardslots/privilege_t [ Types ]
[ Top ] [ cardslots ] [ Types ]
NAME
enum privilege_e
privilege_t
FUNCTION
Provides a way of symbolically expressing the desired RISC-V privilege mode with which to perform a memory access.
SOURCE
typedef enum privilege_e {
PRIV_U = 0,
PRIV_S = 1,
PRIV_H = 2,
PRIV_M = 3,
} privilege_t;
cardslots/slots_s, cardslots/slots_t [ Structures ]
[ Top ] [ cardslots ] [ Structures ]
NAME
struct slots_s
slots_t
FUNCTION
This structure provides a virtual to local memory mapping.
When performing an address translation or attempting to read/write from a card's address space, a search is performed from the start of the enclosed array of slots to the end. Therefore, it is wise to place the most frequently accessed resource into slot 0, the next most frequently accessed resource into slot 1, and so forth.
Up to CARDSLOTS_N_SLOTS slots are permitted.
MEMBERS
slots_used -- the number of array elements in slots[] which hold valid
mappings.
slots -- an array of cardslot_t structures.
SEE ALSO
cardslot_t
SOURCE
typedef struct slots_s {
int slots_used;
cardslot_t slots[CARDSLOTS_N_SLOTS];
} slots_t;