I'm working in OSDev. I'm looking at a working implementation of AHCI and trying to make something like it in my own OS. The example looks like this:
typedef struct tagFIS_REG_H2D
{
// DWORD 0
unsigned char fis_type; // FIS_TYPE_REG_H2D
unsigned char pmport:4; // Port multiplier
unsigned char rsv0:3; // Reserved
unsigned char c:1; // 1: Command, 0: Control
unsigned char command; // Command register
unsigned char featurel; // Feature register, 7:0
// DWORD 1
unsigned char lba0; // LBA low register, 7:0
unsigned char lba1; // LBA mid register, 15:8
unsigned char lba2; // LBA high register, 23:16
unsigned char device; // Device register
// DWORD 2
unsigned char lba3; // LBA register, 31:24
unsigned char lba4; // LBA register, 39:32
unsigned char lba5; // LBA register, 47:40
unsigned char featureh; // Feature register, 15:8
// DWORD 3
unsigned char countl; // Count register, 7:0
unsigned char counth; // Count register, 15:8
unsigned char icc; // Isochronous command completion
unsigned char control; // Control register
// DWORD 4
unsigned char rsv1[4]; // Reserved
} FIS_REG_H2D;
This, in Rust, if directly translated, would be something like:
#[derive(Debug)]
pub struct FIS_REG_H2D {
// DWORD 0
pub fis_type: u8,
pub pmport: u8,
pub rsv0: u8,
pub c: u8,
pub command: u8,
pub featurel: u8,
// DWORD 1
pub lba0: u8,
pub lba1: u8,
pub lba2: u8,
pub device: u8,
// DWORD 2
pub lba3: u8,
pub lba4: u8,
pub lba5: u8,
pub featureh: u8,
// DWORD 3
pub countl: u8,
pub counth: u8,
pub icc: u8,
pub control: u8,
// DWORD 4
pub rsv1: [u8; 4],
}
The example creates this structue like this:
FIS_REG_H2D *cmdfis = (FIS_REG_H2D*)(&cmdtbl->cfis);
Assume, for this example, that &cmdtbl->cfis
is 0x400000. I'm just curious how I'd make accessing the structures fields access the respective memory locations.