📄 amcclib.c
字号:
/* */
/* Outputs: */
/* */
/* Return Value - Indicates presence of device */
/* SUCCESSFUL - Device found */
/* NOT_SUCCESSFUL - BIOS error */
/* BAD_REGISTER_NUMBER - Invalid Register Number */
/* */
/****************************************************************************/
int write_configuration_dword(byte bus_number,
byte device_and_function,
byte register_number,
dword dword_to_write)
{
int ret_status; /* Function Return Status */
/* Call write_configuration_area function with dword data */
ret_status = write_configuration_area(READ_CONFIG_DWORD,
bus_number,
device_and_function,
register_number,
dword_to_write);
return (ret_status);
}
/****************************************************************************/
/* */
/* WRITE_CONFIGURATION_AREA */
/* */
/* Purpose: Writes a byte/word/dword to the configuration space of a */
/* specific device */
/* */
/* Inputs: */
/* */
/* byte bus_number */
/* PCI bus to read configuration data from */
/* */
/* byte device_and_function */
/* Device Number in upper 5 bits, Function Number in lower 3 bits */
/* */
/* byte register_number */
/* Register Number of configuration space to read */
/* */
/* dword value */
/* Value to write to Configuration Space */
/* */
/* Outputs: */
/* */
/* Return Value - Indicates presence of device */
/* SUCCESSFUL - Device found */
/* NOT_SUCCESSFUL - BIOS error */
/* BAD_REGISTER_NUMBER - Invalid Register Number */
/* */
/****************************************************************************/
static int write_configuration_area(byte function,
byte bus_number,
byte device_and_function,
byte register_number,
dword value)
{
int ret_status; /* Function Return Status */
word ax, flags; /* Temporary variables to hold register values */
SWI_REGS regs;
/* Load entry registers for PCI BIOS */
regs.ebx = (bus_number << 8) | device_and_function;
regs.ecx = value;
regs.edi = register_number;
regs.eax = (PCI_FUNCTION_ID << 8) | function;
/* Call PCI BIOS Int 1Ah interface */
_dx_real_int(0x1a, ®s);
/* Save registers before overwritten by compiler usage of registers */
ax = regs.eax & 0xffff;
flags = regs.flags;
/* First check if CARRY FLAG Set, if so, error has occurred */
if ((flags & CARRY_FLAG) == 0) {
/* Get Return code from BIOS */
ret_status = HIGH_BYTE(ax);
}
else {
ret_status = NOT_SUCCESSFUL;
}
return (ret_status);
}
void
outport_byte(int port, int arg)
{
char ch;
ch = arg;
#ifdef _M_IX86
_outp(port, ch);
#else
_DX = port;
_AL = ch;
__emit__(0xee, 0x66); /* out dx, al */
#endif
}
int
inport_byte(int port)
{
int ret_status;
#ifdef _M_IX86
ret_status = _inp(port);
#else
_DX = port;
__emit__(0xec, 0x66); /* in al, dx */
ret_status = _AL;
#endif
return ret_status;
}
void (* BIOS32_entry)();
void
find_BIOS32_service_directory(void)
{
word ds_save, ax_val;
int i, ret_status;
dword address;
byte checksum;
char *data;
FARPTR p;
ret_status = NOT_SUCCESSFUL;
/* Search through E0000h-FFFFFh on 16-byte boundaries for "_32_" */
for (address = 0xe0000;address < 0xfffff; address += 16)
{
FP_SET(p, address, SS_DOSMEM);
data = (char *)PeekFarDWord(p);
if (memcmp(data, "_32_", 4) == 0) {
printf("Found _32_ at %x\n", address);
/* Compute checksum to see if valid */
checksum = 0;
for (i = 0; i < 16; i++) {
FP_SET(p, address + i, SS_DOSMEM);
printf("%x ", PeekFarByte(p));
checksum += PeekFarByte(p);
}
printf("\n");
if (checksum == 0) {
printf("Checksum Valid\n");
FP_SET(p, address + 4, SS_DOSMEM);
BIOS32_entry = (void (*)())PeekFarDWord(p);
printf("BIOS32_entry = 0x%0lx\n", BIOS32_entry);
if (add_memory_address(PeekFarDWord(p), &BIOS32_entry) == SUCCESSFUL) {
printf("Mapped BIOS32_entry = 0x%0lx\n", BIOS32_entry);
#ifdef COMMENTED_OUT
__asm {
mov eax, 049435024h
mov ebx,0
call BIOS32_entry
mov ax_val, ax;
}
printf("AX = %d\n", ax_val);
#endif
}
#ifdef COMMENTED_OUT
__asm {
mov ds_save, ds
mov eax, 049435024h
mov bx, cs
mov ds, bx
mov ebx,0
call BIOS32_entry
}
#endif
}
}
}
}
#include <windows.h>
/* 2 4K pages */
unsigned char map_memory[0x2000];
int
add_memory_address(dword mem_addr, dword *offset)
{
CONFIG_INF config_inf;
int ret_status; /* status to return to caller */
REALPTR realp;
dword base; /* PM base address (must be 4K boundary) */
char *p;
ReadRealMem(map_memory, realp, 0x2000);
*offset = (dword)map_memory + (mem_addr & 0xfff);
ret_status = SUCCESSFUL;
#ifdef COMMENT_OUT
if (!(p = VirtualAlloc(NULL, 0x2000, MEM_RESERVE, PAGE_NOACCESS)))
printf("VirtualAlloc failed\n");
ret_status = _dx_map_pgsn(p, 0x2000, base);
printf("ret_status=%d\n", ret_status);
if (!VirtualFree(p,0,MEM_RELEASE))
printf("VirtualFree failed\n");
_dx_config_inf(&config_inf, (UCHAR *)&config_inf);
printf("DPMI major=%d\n", config_inf.c_dpmimaj);
printf("DPMI minor=%d\n", config_inf.c_dpmimin);
_dx_config_inf(&config_inf, (UCHAR *)&config_inf);
printf("c_cs_sel=%x\n", config_inf.c_cs_sel);
ret_status = _dx_map_pgsn(map_memory, 0x2000, base);
printf("ret_status=%d\n", ret_status);
#endif
return(ret_status);
}
#ifdef TEST
int
main(int argc, char **argv)
{
find_BIOS32_service_directory();
return(0);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -