/drivers/devman/acpinfo/Makefile |
---|
0,0 → 1,50 |
CC = gcc |
FASM = e:/fasm/fasm.exe |
CFLAGS = -c -O2 -fomit-frame-pointer -fno-builtin-printf |
DRV_DIR = $(CURDIR)/../.. |
DRV_INCLUDES = $(DRV_DIR)/include |
INCLUDES = -I$(DRV_INCLUDES) -I$(DRV_DIR)/include/linux |
DEFINES = -D__KERNEL__ -DCONFIG_X86_32 |
LDFLAGS = -nostdlib -shared -s -Map acpi.map --image-base 0\ |
--file-alignment 512 --section-alignment 4096 |
LIBPATH:= -L$(DRV_DIR)/ddk |
LIBS:= -lgcc -lddk -lcore |
NAME= acpi |
NAME_SRCS= main.c \ |
acpi.c \ |
utils.asm |
all: $(NAME).dll |
NAME_OBJS = $(patsubst %.S, %.o, $(patsubst %.asm, %.o,\ |
$(patsubst %.c, %.o, $(NAME_SRCS)))) |
$(NAME).dll: $(NAME_OBJS) acpi.lds Makefile |
ld $(LIBPATH) $(LDFLAGS) -T acpi.lds -o $@ $(NAME_OBJS) $(LIBS) |
%.o : %.c $(HFILES) Makefile |
$(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o $@ $< |
%.o : %.S $(HFILES) Makefile |
as -o $@ $< |
%.o : %.asm $(HFILES) Makefile |
fasm $< $@ |
/drivers/devman/acpinfo/_utils.c |
---|
0,0 → 1,50 |
#include <ddk.h> |
#include <syscall.h> |
#include "acpi.h" |
extern acpi_rsdp_t* acpi_rsdp; |
extern acpi_rsdt_t* acpi_rsdt; |
addr_t acpi_ioapic; |
addr_t acpi_local_apic; |
u8_t __fastcall acpi_table_checksum(u32_t length, u8_t *buffer); |
acpi_rsdp_t* acpi_locate() |
{ |
/** @todo checksum, check version */ |
addr_t p; |
for (p = ACPI_HI_RSDP_WINDOW_START; p < ACPI_HI_RSDP_WINDOW_END; p+=16) |
{ |
acpi_rsdp_t* r = (acpi_rsdp_t*) p; |
if ((r->sig[0] == 0x20445352) && |
(r->sig[1] == 0x20525450) && |
acpi_table_checksum(ACPI_RSDP_CHECKSUM_LENGTH, (u8_t*)r)==0 ) |
{ |
return r; |
}; |
}; |
/* not found */ |
return NULL; |
}; |
addr_t __fastcall rsdt_find(acpi_rsdt_t *rsdt, u32_t sig) |
{ |
addr_t head = 0; |
u32_t i; |
for (i = 0; i < ((rsdt->header.len-sizeof(acpi_thead_t))/ |
sizeof(rsdt->ptrs[0])); i++) |
{ |
acpi_thead_t* t= (acpi_thead_t*)acpi_remap_table(rsdt->ptrs[i]); |
if (t->sig == sig) |
{ |
head = rsdt->ptrs[i]; |
break; |
}; |
} |
return head; |
}; |
/drivers/devman/acpinfo/acpi.c |
---|
0,0 → 1,164 |
#include <ddk.h> |
#include <syscall.h> |
#include "acpi.h" |
extern acpi_rsdp_t* acpi_rsdp; |
extern acpi_rsdt_t* acpi_rsdt; |
addr_t acpi_ioapic; |
addr_t acpi_local_apic; |
u8_t __fastcall acpi_table_checksum(u32_t length, u8_t *buffer); |
u8_t __fastcall acpi_table_checksum(u32_t length, u8_t *buffer) |
{ |
u8_t sum = 0; |
u8_t *end = buffer + length; |
while (buffer < end) |
{ |
sum = (u8_t)(sum + *(buffer++)); |
} |
return sum; |
}; |
void* acpi_remap_table(addr_t table) |
{ |
addr_t ptr; |
if( (table >= acpi_rsdp->rsdt_ptr)&& |
(table < acpi_rsdp->rsdt_ptr+0x10000)) |
ptr = (table - acpi_rsdp->rsdt_ptr+(addr_t)acpi_rsdt); |
return (void*)ptr; |
}; |
void print_rsdt(acpi_rsdt_t *rsdt) |
{ |
u32_t i; |
dbgprintf("ACPI RSD Table\n"); |
for (i = 0; i < ((rsdt->header.len-sizeof(acpi_thead_t))/ |
sizeof(rsdt->ptrs[0])); i++) |
{ |
acpi_thead_t* t = (acpi_thead_t*)acpi_remap_table(rsdt->ptrs[i]); |
char *p = (char*)&t->sig; |
dbgprintf("sig %d: %c%c%c%c base %x\n", i, |
p[0],p[1],p[2],p[3], t); |
}; |
}; |
void print_madt (acpi_madt_t * madt) |
{ |
u32_t i; |
acpi_local_apic = madt->local_apic_addr; |
dbgprintf ("Local APIC at 0x%x\n\n", acpi_local_apic); |
for (i = 0; i < (madt->header.len - sizeof (acpi_madt_t));) |
{ |
acpi_madt_hdr_t * h = (acpi_madt_hdr_t*) &madt->data[i]; |
switch (h->type) |
{ |
case 0: |
{ |
// Local APIC |
acpi_madt_lapic_t * lapic = (acpi_madt_lapic_t *) h; |
dbgprintf ("Local APIC "); |
dbgprintf ("[Id: 0x%x, CPU Id: 0x%x, %s]\n", |
lapic->id, lapic->apic_processor_id, |
lapic->flags.enabled ? "enabled" : "disabled"); |
break; |
} |
case 1: |
{ |
// I/O Apic |
acpi_madt_ioapic_t * ioapic = (acpi_madt_ioapic_t *) h; |
acpi_ioapic = ioapic->address; |
dbgprintf ("I/O APIC "); |
dbgprintf ("[Id: 0x%x, IRQ base: %d, Addr: 0x%x]\n", |
ioapic->id, ioapic->irq_base, acpi_ioapic); |
break; |
} |
case 2: |
{ |
// Interrupt Source Override |
acpi_madt_irq_t * irq = (acpi_madt_irq_t *) h; |
polarity_t p = irq_get_polarity(irq); |
trigger_mode_t t = irq_get_trigger_mode(irq); |
dbgprintf ("Interrupt Override "); |
dbgprintf ("[%s, Bus IRQ: %d, Glob IRQ: %d, Pol: %s, Trigger: %s]\n", |
irq->src_bus == 0 ? "ISA" : "unknown bus", |
irq->src_irq, irq->dest, |
p == conform_polarity ? "conform" : |
p == active_high ? "active high" : |
p == active_low ? "active low" : "?", |
t == conform_trigger ? "conform" : |
t == edge ? "edge" : |
t == level ? "level" : "?"); |
break; |
} |
case 3: |
{ |
// NMI Source |
acpi_madt_nmi_t * nmi = (acpi_madt_nmi_t *) h; |
polarity_t p = nmi_get_polarity(nmi); |
trigger_mode_t t = nmi_get_trigger_mode(nmi); |
dbgprintf ("NMI Source "); |
dbgprintf ("[Glob IRQ: %d, Pol: %s, Trigger: %s]\n", |
nmi->irq, |
p == conform_polarity ? "conform" : |
p == active_high ? "active high" : |
p == active_low ? "active low" : "?", |
t == conform_trigger ? "conform" : |
t == edge ? "edge" : |
t == level ? "level" : "?"); |
break; |
} |
case 4: |
{ |
// Local APIC NMI |
acpi_lapic_nmi_t *nmi = (acpi_lapic_nmi_t *) h; |
polarity_t p = lapic_nmi_get_polarity(nmi); |
trigger_mode_t t = lapic_nmi_get_trigger_mode(nmi); |
dbgprintf ("Local APIC NMI\n"); |
dbgprintf ("[CPU id: %d, LINT#: %d Pol: %s, Trigger: %s]\n", |
nmi->apic_processor_id, |
nmi->lint, |
p == conform_polarity ? "conform" : |
p == active_high ? "active high" : |
p == active_low ? "active low" : "?", |
t == conform_trigger ? "conform" : |
t == edge ? "edge" : |
t == level ? "level" : "?"); |
break; |
} |
case 5: |
{ |
// Local APIC Address Override |
dbgprintf ("Local APIC Address Override\n"); |
break; |
} |
case 8: |
{ |
// Platform Interrupt Source |
dbgprintf ("Platform Interrupt Source\n"); |
break; |
} |
} |
i += h->len; |
} |
}; |
/drivers/devman/acpinfo/acpi.h |
---|
0,0 → 1,250 |
#define ACPI_NAME_SIZE 4 |
#define ACPI_OEM_ID_SIZE 6 |
#define ACPI_OEM_TABLE_ID_SIZE 8 |
typedef struct __attribute__((packed)) |
{ |
u8_t type; |
u8_t len; |
}acpi_madt_hdr_t; |
typedef struct __attribute__((packed)) |
{ |
acpi_madt_hdr_t header; |
u8_t apic_processor_id; |
u8_t id; |
struct { |
u32_t enabled : 1; |
u32_t : 31; |
} flags; |
}acpi_madt_lapic_t; |
typedef struct __attribute__((packed)) |
{ |
acpi_madt_hdr_t header; |
u8_t id; /* APIC id */ |
u8_t _rsvd_3; |
u32_t address; /* physical address */ |
u32_t irq_base; /* global irq number base */ |
}acpi_madt_ioapic_t; |
typedef enum { |
conform_polarity = 0, |
active_high = 1, |
reserved_polarity = 2, |
active_low = 3 |
}polarity_t ; |
typedef enum { |
conform_trigger = 0, |
edge = 1, |
reserved_trigger = 2, |
level = 3 |
}trigger_mode_t; |
typedef struct __attribute__((packed)) |
{ |
acpi_madt_hdr_t header; |
u8_t src_bus; /* source bus, fixed 0=ISA */ |
u8_t src_irq; /* source bus irq */ |
u32_t dest; /* global irq number */ |
union { |
u16_t flags; /* irq flags */ |
struct { |
u16_t polarity : 2; |
u16_t trigger_mode : 2; |
u16_t reserved : 12; |
} x; |
}; |
}acpi_madt_irq_t; |
static inline polarity_t irq_get_polarity(acpi_madt_irq_t *irq) |
{ return (polarity_t) irq->x.polarity; } |
static inline trigger_mode_t irq_get_trigger_mode(acpi_madt_irq_t *irq) |
{ return (trigger_mode_t) irq->x.trigger_mode; } |
typedef struct __attribute__((packed)) |
{ |
acpi_madt_hdr_t header; |
union { |
u16_t flags; |
struct { |
u16_t polarity : 2; |
u16_t trigger_mode : 2; |
u16_t reserved : 12; |
} x; |
}; |
u32_t irq; |
}acpi_madt_nmi_t; |
static inline polarity_t nmi_get_polarity(acpi_madt_nmi_t *nmi) |
{ return (polarity_t) nmi->x.polarity; } |
static inline trigger_mode_t nmi_get_trigger_mode(acpi_madt_nmi_t *nmi) |
{ return (trigger_mode_t) nmi->x.trigger_mode; } |
typedef struct __attribute__((packed)) |
{ |
acpi_madt_hdr_t header; |
u8_t apic_processor_id; |
union { |
u16_t flags; |
struct { |
u16_t polarity : 2; |
u16_t trigger_mode : 2; |
u16_t reserved : 12; |
} x; |
}; |
u8_t lint; |
}acpi_lapic_nmi_t; |
static inline polarity_t lapic_nmi_get_polarity(acpi_lapic_nmi_t *nmi) |
{ return (polarity_t) nmi->x.polarity; } |
static inline trigger_mode_t lapic_nmi_get_trigger_mode(acpi_lapic_nmi_t *nmi) |
{ return (trigger_mode_t) nmi->x.trigger_mode; } |
typedef struct __attribute__((packed)) |
{ |
u32_t sig; |
u32_t len; |
u8_t rev; |
u8_t csum; |
char oem_id[ACPI_OEM_ID_SIZE]; |
char oem_tid[ACPI_OEM_TABLE_ID_SIZE]; |
u32_t oem_rev; |
u32_t creator_id; |
u32_t creator_rev; |
}acpi_thead_t; |
typedef struct __attribute__((packed)) |
{ |
acpi_thead_t header; |
u32_t local_apic_addr; |
u32_t apic_flags; |
u8_t data[0]; |
} acpi_madt_t; |
typedef struct __attribute__((packed)) |
{ |
acpi_thead_t header; |
u32_t ptrs[0]; |
}acpi_rsdt_t; |
typedef struct __attribute__((packed)) |
{ |
acpi_thead_t header; |
u64_t ptrs[0]; |
}acpi_xsdt_t; |
typedef struct |
{ |
u32_t sig[2]; |
u8_t csum; |
char oemid[6]; |
u8_t rev; |
u32_t rsdt_ptr; |
u32_t rsdt_len; |
u64_t xsdt_ptr; |
u8_t xcsum; |
u8_t _rsvd_33[3]; |
}acpi_rsdp_t; |
typedef struct __attribute__((packed)) |
{ |
u8_t SpaceId; /* Address space where struct or register exists */ |
u8_t BitWidth; /* Size in bits of given register */ |
u8_t BitOffset; /* Bit offset within the register */ |
u8_t AccessWidth; /* Minimum Access size (ACPI 3.0) */ |
u64_t Address; /* 64-bit address of struct or register */ |
} acpi_address_t; |
typedef struct __attribute__((packed)) |
{ |
acpi_thead_t Header; /* Common ACPI table header */ |
u32_t Facs; /* 32-bit physical address of FACS */ |
u32_t Dsdt; /* 32-bit physical address of DSDT */ |
u8_t Model; /* System Interrupt Model (ACPI 1.0) - not used in ACPI 2.0+ */ |
u8_t PreferredProfile; /* Conveys preferred power management profile to OSPM. */ |
u16_t SciInterrupt; /* System vector of SCI interrupt */ |
u32_t SmiCommand; /* 32-bit Port address of SMI command port */ |
u8_t AcpiEnable; /* Value to write to smi_cmd to enable ACPI */ |
u8_t AcpiDisable; /* Value to write to smi_cmd to disable ACPI */ |
u8_t S4BiosRequest; /* Value to write to SMI CMD to enter S4BIOS state */ |
u8_t PstateControl; /* Processor performance state control*/ |
u32_t Pm1aEventBlock; /* 32-bit Port address of Power Mgt 1a Event Reg Blk */ |
u32_t Pm1bEventBlock; /* 32-bit Port address of Power Mgt 1b Event Reg Blk */ |
u32_t Pm1aControlBlock; /* 32-bit Port address of Power Mgt 1a Control Reg Blk */ |
u32_t Pm1bControlBlock; /* 32-bit Port address of Power Mgt 1b Control Reg Blk */ |
u32_t Pm2ControlBlock; /* 32-bit Port address of Power Mgt 2 Control Reg Blk */ |
u32_t PmTimerBlock; /* 32-bit Port address of Power Mgt Timer Ctrl Reg Blk */ |
u32_t Gpe0Block; /* 32-bit Port address of General Purpose Event 0 Reg Blk */ |
u32_t Gpe1Block; /* 32-bit Port address of General Purpose Event 1 Reg Blk */ |
u8_t Pm1EventLength; /* Byte Length of ports at Pm1xEventBlock */ |
u8_t Pm1ControlLength; /* Byte Length of ports at Pm1xControlBlock */ |
u8_t Pm2ControlLength; /* Byte Length of ports at Pm2ControlBlock */ |
u8_t PmTimerLength; /* Byte Length of ports at PmTimerBlock */ |
u8_t Gpe0BlockLength; /* Byte Length of ports at Gpe0Block */ |
u8_t Gpe1BlockLength; /* Byte Length of ports at Gpe1Block */ |
u8_t Gpe1Base; /* Offset in GPE number space where GPE1 events start */ |
u8_t CstControl; /* Support for the _CST object and C States change notification */ |
u16_t C2Latency; /* Worst case HW latency to enter/exit C2 state */ |
u16_t C3Latency; /* Worst case HW latency to enter/exit C3 state */ |
u16_t FlushSize; /* Processor's memory cache line width, in bytes */ |
u16_t FlushStride; /* Number of flush strides that need to be read */ |
u8_t DutyOffset; /* Processor duty cycle index in processor's P_CNT reg*/ |
u8_t DutyWidth; /* Processor duty cycle value bit width in P_CNT register.*/ |
u8_t DayAlarm; /* Index to day-of-month alarm in RTC CMOS RAM */ |
u8_t MonthAlarm; /* Index to month-of-year alarm in RTC CMOS RAM */ |
u8_t Century; /* Index to century in RTC CMOS RAM */ |
u16_t BootFlags; /* IA-PC Boot Architecture Flags. See Table 5-10 for description */ |
u8_t Reserved; /* Reserved, must be zero */ |
u32_t Flags; /* Miscellaneous flag bits (see below for individual flags) */ |
acpi_address_t ResetRegister; /* 64-bit address of the Reset register */ |
u8_t ResetValue; /* Value to write to the ResetRegister port to reset the system */ |
u8_t Reserved4[3]; /* Reserved, must be zero */ |
u64_t XFacs; /* 64-bit physical address of FACS */ |
u64_t XDsdt; /* 64-bit physical address of DSDT */ |
acpi_address_t XPm1aEventBlock; /* 64-bit Extended Power Mgt 1a Event Reg Blk address */ |
acpi_address_t XPm1bEventBlock; /* 64-bit Extended Power Mgt 1b Event Reg Blk address */ |
acpi_address_t XPm1aControlBlock; /* 64-bit Extended Power Mgt 1a Control Reg Blk address */ |
acpi_address_t XPm1bControlBlock; /* 64-bit Extended Power Mgt 1b Control Reg Blk address */ |
acpi_address_t XPm2ControlBlock; /* 64-bit Extended Power Mgt 2 Control Reg Blk address */ |
acpi_address_t XPmTimerBlock; /* 64-bit Extended Power Mgt Timer Ctrl Reg Blk address */ |
acpi_address_t XGpe0Block; /* 64-bit Extended General Purpose Event 0 Reg Blk address */ |
acpi_address_t XGpe1Block; /* 64-bit Extended General Purpose Event 1 Reg Blk address */ |
} acpi_fadt_t; |
#define OS_BASE 0x80000000 |
#define ACPI_HI_RSDP_WINDOW_START (OS_BASE+0x000E0000) |
#define ACPI_HI_RSDP_WINDOW_END (OS_BASE+0x00100000) |
#define ACPI_RSDP_CHECKSUM_LENGTH 20 |
#define ACPI_RSDP_XCHECKSUM_LENGTH 36 |
#define ACPI_MADT_SIGN 0x43495041 |
#define addr_offset(addr, off) \ |
(addr_t)((addr_t)(addr) + (addr_t)(off)) |
#define ACPI_ADDR(x) \ |
(addr_t)((addr_t)(x)+OS_BASE) |
#define acpi_remap(x) (x) |
/drivers/devman/acpinfo/acpi.lds |
---|
0,0 → 1,56 |
OUTPUT_FORMAT(pei-i386) |
ENTRY("_drvEntry") |
SECTIONS |
{ |
. = SIZEOF_HEADERS; |
. = ALIGN(__section_alignment__); |
.text __image_base__ + ( __section_alignment__ < 0x1000 ? . : __section_alignment__ ) : |
{ |
*(.text) *(.rdata) |
} |
.data ALIGN(__section_alignment__) : |
{ |
*(.data) |
} |
.bss ALIGN(__section_alignment__): |
{ |
*(.bss) |
*(COMMON) |
} |
/DISCARD/ : |
{ |
*(.debug$S) |
*(.debug$T) |
*(.debug$F) |
*(.drectve) |
*(.edata) |
} |
.idata ALIGN(__section_alignment__): |
{ |
SORT(*)(.idata$2) |
SORT(*)(.idata$3) |
/* These zeroes mark the end of the import list. */ |
LONG (0); LONG (0); LONG (0); LONG (0); LONG (0); |
SORT(*)(.idata$4) |
SORT(*)(.idata$5) |
SORT(*)(.idata$6) |
SORT(*)(.idata$7) |
} |
.reloc ALIGN(__section_alignment__) : |
{ |
*(.reloc) |
} |
} |
/drivers/devman/acpinfo/main.c |
---|
0,0 → 1,71 |
#include <ddk.h> |
#include <syscall.h> |
#include "acpi.h" |
acpi_rsdp_t* acpi_locate(); |
acpi_rsdp_t* acpi_rsdp; |
acpi_rsdt_t* acpi_rsdt; |
acpi_madt_t* acpi_madt; |
addr_t acpi_rsdt_base; |
addr_t acpi_madt_base; |
addr_t acpi_lapic_base; |
addr_t acpi_ioapic_base; |
addr_t __fastcall rsdt_find(acpi_rsdt_t *rsdt, u32_t sig); |
u32_t drvEntry(int action, char *cmdline) |
{ |
u32_t ret; |
if(action != 1) |
return 0; |
if( !dbg_open("/rd/1/drivers/acpi.log") ) |
{ |
printf("Can't open /rd/1/drivers/acpi.log\nExit\n"); |
return 0; |
} |
acpi_rsdp = acpi_locate(); |
if (unlikely(acpi_rsdp == NULL)) |
{ |
dbgprintf("No ACPI RSD table\n"); |
return 0; |
}; |
dbgprintf("rsd base address %x\n", acpi_rsdp); |
acpi_rsdt_base = acpi_rsdp->rsdt_ptr; |
acpi_rsdt = (acpi_rsdt_t*)(MapIoMem(acpi_rsdt_base,0x10000,5)); |
dbgprintf("rsdt base 0x%x, kernel 0x%x\n", acpi_rsdt_base, acpi_rsdt); |
if (unlikely(acpi_rsdt == NULL)) |
{ |
dbgprintf("Invalid ACPI RSD table\n"); |
return 0; |
}; |
// print_rsdt(acpi_rsdt); |
acpi_madt_base = rsdt_find(acpi_rsdt, ACPI_MADT_SIGN); |
if( unlikely(acpi_madt_base == 0) ) |
{ |
dbgprintf("No ACPI MAD Table\n"); |
return 0; |
}; |
acpi_madt =(acpi_madt_t*)acpi_remap_table(acpi_madt_base); |
dbgprintf("madt base 0x%x, kernel 0x%x\n", acpi_madt_base, acpi_madt); |
// print_madt(acpi_madt); |
return 0; |
}; |
/drivers/devman/acpinfo/types.h |
---|
--- acpinfo/utils.asm (nonexistent) |
+++ acpinfo/utils.asm (revision 3019) |
@@ -0,0 +1,79 @@ |
+format MS COFF |
+ |
+extrn _acpi_rsdt_base |
+ |
+public _acpi_locate |
+public @rsdt_find@8 |
+ |
+OS_BASE equ 0x80000000 |
+ |
+ACPI_HI_RSDP_WINDOW_START equ (OS_BASE+0x000E0000) |
+ACPI_HI_RSDP_WINDOW_END equ (OS_BASE+0x00100000) |
+ACPI_RSDP_CHECKSUM_LENGTH equ 20 |
+ |
+section '.text' code readable executable align 16 |
+ |
+ |
+_acpi_locate: |
+ push ebx |
+ mov ebx, ACPI_HI_RSDP_WINDOW_START |
+.check: |
+ cmp [ebx], dword 0x20445352 |
+ jne .next |
+ cmp [ebx+4], dword 0x20525450 |
+ jne .next |
+ |
+ mov edx, ebx |
+ mov ecx, ACPI_RSDP_CHECKSUM_LENGTH |
+ xor eax, eax |
+.sum: |
+ add al, [edx] |
+ inc edx |
+ loop .sum |
+ |
+ test al, al |
+ jnz .next |
+ |
+ mov eax, ebx |
+ pop ebx |
+ ret |
+.next: |
+ add ebx, 16 |
+ cmp ebx, ACPI_HI_RSDP_WINDOW_END |
+ jb .check |
+ |
+ pop ebx |
+ xor eax, eax |
+ ret |
+ |
+align 4 |
+@rsdt_find@8: ;ecx= rsdt edx= SIG |
+ push ebx |
+ push esi |
+ |
+ lea ebx, [ecx+36] |
+ mov esi, [ecx+4] |
+ add esi, ecx |
+.next: |
+ mov eax, [ebx] |
+ sub eax, [_acpi_rsdt_base] |
+ add eax, ecx |
+ |
+ cmp [eax], edx |
+ je .done |
+ |
+ add ebx, 4 |
+ cmp ebx, esi |
+ jb .next |
+ |
+ xor eax, eax |
+ pop esi |
+ pop ebx |
+ ret |
+ |
+.done: |
+ mov eax, [ebx] |
+ pop esi |
+ pop ebx |
+ ret |
+ |
/drivers/devman/acpinfo |
---|
Property changes: |
Added: bugtraq:number |
+true |
\ No newline at end of property |