Доброе время суток!
Имеется описание структуры в духе:
struct reg_map
{
u8 spacer1[0x3C];
u32 status_reg1;
u32 status_reg2;
u8 spacer2[0x2424];
u32 conf_reg1;
u32 conf_reg2;
};
//....
struct reg_map *my_dev = ptr_to_dev;
my_dev->conf_reg1 = CONST_HOST_TO_DEV32(0x01);
Можно делать иначе - определять просто адреса регистров:
#define MYDEV_CONF_REG1 0x2468
write_reg32(my_bar0 + MYDEV_CONF_REG1, 0x01);
Вопрос: как сделать что-то более интеллигентное, наподобие адовского «at cause»? Чтобы было и наглядно, и трудно ошибиться.
WORD : constant := 4; -- storage unit is byte, 4 bytes per word
type STATE is (A,M,W,P);
type MODE is (FIX, DEC, EXP, SIGNIF);
type BYTE_MASK is array (0.. 7) of BOOLEAN;
type STATE_MASK is array (STATE) of BOOLEAN;
type MODE_MASK is array (MODE) of BOOLEAN;
type PROGRAM_STATUS_WORD is
record
SYSTEM_MASK : BYTE_MASK;
PROTECTION_KEY : INTEGER range 0 .. 3;
MACHINE_STATE : STATE_MASK;
INTERRUPT_CAUSE : INTERRUPTION_CODE;
ILC : INTEGER range 0 .. 3;
CC : INTEGER range 0 .. 3;
PROGRAM_MASK : MODE_MASK;
INST_ADDRESS : ADDRESS;
end record;
for PROGRAM_STATUS_WORD use
record at mod 8;
SYSTEM_MASK at 0*WORD range 0 .. 7;
PROTECTION_KEY at 0*WORD range 10 .. 11; -- bits 8,9 unused
MACHINE_STATE at 0*WORD range 12 .. 15;
INTERRUPT_CAUSE at 0*WORD range 16 .. 31;
ILC at 1*WORD range 0 .. 1; -- second word
CC at 1*WORD range 2 .. 3;
PROGRAM_MASK at 1*WORD range 4 .. 7;
INST_ADDRESS at 1*WORD range 8 .. 31;
end record;
for PROGRAM_STATUS_WORD'SIZE use 8*SYSTEM.STORAGE_UNIT;