/* Addresses of HP iLO 4 v2.50 firmware */
#include "hp_ilo.h"

struct CLI_SESSION {
    u8 padding[0x164];
    char argv[16][256]; /* 16 256-char-wide command arguments */
    u32 argc;
};
STATIC_ASSERT(offsetof(struct CLI_SESSION, argv) == 0x164);
STATIC_ASSERT(offsetof(struct CLI_SESSION, argc) == 0x1164);

/* ConAppCLI */
static int (__attribute__((format(printf, 2, 3))) *CLI_printf)(u32 cli_id, const char *fmt, ...) = (const void *)0x12f50;
static struct CLI_SESSION *(*ConAppCLI_get_CLI_session_ptr)(u32 cli_id) = (const void *)0x21e24;

/* libc.so */
static void *(*malloc)(size_t size) = (const void *)0x017B85E8;
static void (*free)(void *ptr) = (const void *)0x017B86F4;

static DIR *(*opendir)(const char *path) = (const void *)0x017A0CB4;
static void (*closedir)(DIR *dir) = (const void *)0x017A0D70;
static int (*readdir_r)(DIR *dir, struct dirent *entry, struct dirent **result) = (const void *)0x017A0DB4;

static int (*lstat)(const char *pathname, struct stat *statbuf) = (const void *)0x017AC75C;
static int (*ioctl)(int fd, unsigned long request, ...) = (const void *)0x017AD820;
static int (*open)(const char *pathname, int flags, mode_t mode) = (const void *)0x017AE89C;
static ssize_t (*write)(int fd, const void *buf, size_t count) = (const void *)0x017AE9D8;
static ssize_t (*read)(int fd, void *buf, size_t count) = (const void *)0x017AEABC;
static int (*close)(int fd) = (const void *)0x017AEC80;
static off_t (*lseek)(int fd, off_t offset, int whence) = (const void *)0x017AED24;

static int *(*get_errno_ptr)(void) = (const void *)0x017A25A0;

static int (__attribute__((format(printf, 3, 4))) *snprintf)(char *str, size_t size, const char *format, ...) = (const void *)0x017B3FE0;

#define REQUEST_RES_SYSPASS "!systempassword"
static int (*libc_RequestResource)(u32 *pRes, const char *szResName, const char *szSystemPassword) = (const void *)0x017A3948;

static u32 __ghs_VirtualMemoryRegionPool = 0x017D81DC;
static int (*AllocateAnyMemoryRegion)(u32 pool, u32 size, u32 *dwMemRegion) = (const void *)0x017A1DB4;

/* chif.elf */
struct HWMEM_0x80200000 {
    u8 padding0[96];
    u32 sawbase_SAW1;
    u32 sawbase_SAW2;
    u32 sawbase_SAW3;
    u8 padding6c[4];
    u32 pwmgr_system_status_bits; /* 0x1000000: bits valid, 0x2000000: powered off */
    u8 padding74[4];
    u32 sawbase_PERSTAT;
    u8 padding7C[56];
    u16 sawbase_SYSFAULT;
};
STATIC_ASSERT(offsetof(struct HWMEM_0x80200000, sawbase_SAW2) == 0x64);
STATIC_ASSERT(offsetof(struct HWMEM_0x80200000, pwmgr_system_status_bits) == 0x70);
STATIC_ASSERT(offsetof(struct HWMEM_0x80200000, sawbase_PERSTAT) == 0x78);
STATIC_ASSERT(offsetof(struct HWMEM_0x80200000, sawbase_SYSFAULT) == 0xb4);
static volatile struct HWMEM_0x80200000 *const MEM_0x1F02000 = (struct HWMEM_0x80200000 *)0x1F02000;

/* This looks like a PCI configuration register
 * offset 0 : vendor:device ID
 * offset 4, bit 2 (mask 0x04) = MSTR_EN for master enable
 */
struct HWMEM_0x802F0000 {
    u8 padding0[4];
    u32 sawbase_mstr_en;
    u8 padding8[116];
    u32 sawbase_D3hot_detected;
};
STATIC_ASSERT(offsetof(struct HWMEM_0x802F0000, sawbase_mstr_en) == 4);
STATIC_ASSERT(offsetof(struct HWMEM_0x802F0000, sawbase_D3hot_detected) == 0x7c);
static volatile struct HWMEM_0x802F0000 *const MEM_0x1F03000 = (struct HWMEM_0x802F0000 *)0x1F03000;

struct HWMEM_0x804F0000 {
    u8 padding0[244];
    u32 sawbase_access_ok_D3hot_in_FN4;
};
STATIC_ASSERT(offsetof(struct HWMEM_0x804F0000, sawbase_access_ok_D3hot_in_FN4) == 0xf4);
static volatile struct HWMEM_0x804F0000 *const MEM_0x1F07000 = (struct HWMEM_0x804F0000 *)0x1F07000;

/* libINTEGRITY.so */
static int (*INTEGRITY_CloseConnection)(u32 dwMemIndex) = (const void *)0x017808FC;
static int (*INTEGRITY_MapMemoryRegion)(u32 dwMemIndex, u32 dwMemoryRegion) = (const void *)0x017809AC;
static int (*INTEGRITY_UnMapMemoryRegion)(u32 dwMemIndex, u32 *pResult) = (const void *)0x017826D4;
static int (*INTEGRITY_SetMemoryRegionAttributes)(u32 dwMemoryRegion, u32 dwFlags) = (const void *)0x01782734;
static int (*INTEGRITY_CopyToMemoryRegion)(u32 physMR, u32 physaddr, const void *pInput, size_t ccbInput, u32 unknown_2832) = (const void *)0x1782818;
static int (*INTEGRITY_CopyFromMemoryRegion)(u32 dwPhysMemoryRegion, u32 dwPhysAddr, void *pOutput, u32 dwOutLen, u32 unknown_2049) = (const void *)0x0178284C;
static int (*INTEGRITY_GetMemoryRegionAttributes)(u32 dwMemoryRegion, u32 *pdwFlags) =(const void *) 0x01782964;
static int (*INTEGRITY_GetMemoryRegionAddress)(u32 dwMemIndex, u32 *pVirtAddrStart, u32 *pVirtAddrEnd) = (const void *)0x017829A0;
