diff --git a/ape/ape.S b/ape/ape.S index 13eba1c7e..aada551aa 100644 --- a/ape/ape.S +++ b/ape/ape.S @@ -235,8 +235,9 @@ pc: cld #endif ljmp $0,$REAL(1f) 1: mov %cx,%ds - mov $IMAGE_BASE_REAL-0x0500,%cx # clears bss - mov $0x0500>>4,%ax # struct mman + .set mm,0x0500 # struct mman + mov $IMAGE_BASE_REAL-mm,%cx # clears bss + mov $mm>>4,%ax mov %ax,%es xor %ax,%ax xor %di,%di @@ -328,7 +329,7 @@ dsknfo: push %bx movpp %es,%ds xor %si,%si mov %si,%es - mov $0x1d10,%si # mman::pc_drive_base_table + mov $mm+"struct mman::pc_drive_base_table",%si xchg %si,%di movsw #→ headunloadtime, headloadtime movsw #→ shutofftime, bytespersector @@ -381,11 +382,11 @@ pcread: push %ax add $512>>4,%si mov %si,%es inc %al # ++sector - cmp 0x1d1c,%al # mman::pc_drive_last_sector + cmp mm+"struct mman::pc_drive_last_sector",%al jbe 2f mov $1,%al inc %dh # ++head - cmp 0x1d20,%dh # mman::pc_drive_last_head + cmp mm+"struct mman::pc_drive_last_head",%dh jbe 2f xor %dh,%dh inc %cx # ++cylinder @@ -1288,10 +1289,9 @@ lcheck: pushf # check for i8086 / i8088 / i80186 .endfn lcheck // Gets memory map from BIOS. -e820: mov $0x0510>>4,%di # mman::e820 - mov %di,%es - xor %di,%di # es:di is destination buffer - xor %ebx,%ebx # ebx is an api state tracker +e820: xor %ebx,%ebx # %ebx is an api state tracker + mov %bx,%es + mov $mm+"struct mman::e820",%di # es:di is destination buffer 1: mov $0xE820,%eax # magic mov $8+8+4+4,%ecx # sizeof(struct SmapEntry) mov $0x534d4150,%edx # magic number @@ -1315,7 +1315,7 @@ e820: mov $0x0510>>4,%di # mman::e820 4: add $8+8+4+4,%di # keep entry 5: test %ebx,%ebx # last entry? jz 8f - cmp $(256-1)*(8+8+4+4),%di + cmp $mm+"struct mman::e820_end"-(8+8+4+4),%di jb 1b 8: xor %ax,%ax # add a blank sentinel entry mov $(8+8)/2,%cx @@ -1425,7 +1425,7 @@ pinit: push %ds // // @see Intel Manual V3A §4.1.2 golong: cli - lidt 0x1d22 # mman::bad_idt + lidt mm+"struct mman::bad_idt" mov %cr4,%eax or $CR4_PAE|CR4_PGE|CR4_OSFXSR,%eax mov %eax,%cr4 @@ -1458,7 +1458,7 @@ long: xor %eax,%eax xor %ebx,%ebx xor %ebp,%ebp push %rbp - mov $0x0500,%rdi # mman + mov $mm,%rdi mov %cr3,%rsi mov $IMAGE_BASE_REAL,%edx call __map_phdrs diff --git a/libc/intrin/mman.greg.c b/libc/intrin/mman.greg.c index 12cb3dc7e..e85eb9784 100644 --- a/libc/intrin/mman.greg.c +++ b/libc/intrin/mman.greg.c @@ -128,7 +128,26 @@ static noasan textreal void __invert_memory(struct mman *mm, uint64_t *pml4t) { } } +/** + * Exports information about the offset of a field within a structure type, + * so that assembly language routines can use it. This macro can be invoked + * from inside a function whose code is known to be emitted. + */ +#define export_offsetof(type, member) \ + do { \ + asm volatile(".globl \"" #type "::" #member "\"\n\t" \ + ".set \"" #type "::" #member "\",%c0" \ + : /* no outputs */ \ + : "i" (offsetof(type, member))); \ + } while (0) + noasan textreal void __setup_mman(struct mman *mm, uint64_t *pml4t) { + export_offsetof(struct mman, pc_drive_base_table); + export_offsetof(struct mman, pc_drive_last_sector); + export_offsetof(struct mman, pc_drive_last_head); + export_offsetof(struct mman, e820); + export_offsetof(struct mman, e820_end); + export_offsetof(struct mman, bad_idt); __normalize_e820(mm); __invert_memory(mm, pml4t); } diff --git a/libc/runtime/mman.internal.h b/libc/runtime/mman.internal.h index 8c582a52d..5a9e2b642 100644 --- a/libc/runtime/mman.internal.h +++ b/libc/runtime/mman.internal.h @@ -9,14 +9,15 @@ struct mman { int32_t pdpi; /* 0x0508 */ int32_t e820n; /* 0x050c */ struct SmapEntry e820[256]; /* 0x0510 */ + struct SmapEntry e820_end[0]; /* 0x1d10 */ char pc_drive_base_table[11]; /* 0x1d10 */ unsigned char pc_drive_type; /* 0x1d1b */ unsigned char pc_drive_last_sector; /* 0x1d1c */ - unsigned short pc_drive_last_cylinder; /* 0x1d1d */ - unsigned char pc_drives_attached; /* 0x1d1f */ - unsigned char pc_drive_last_head; /* 0x1d20 */ - unsigned char pc_drive; /* 0x1d21 */ - char bad_idt[6]; /* 0x1d22 */ + unsigned short pc_drive_last_cylinder; /* 0x1d1e */ + unsigned char pc_drives_attached; /* 0x1d20 */ + unsigned char pc_drive_last_head; /* 0x1d21 */ + unsigned char pc_drive; /* 0x1d22 */ + char bad_idt[6]; /* 0x1d23 */ }; COSMOPOLITAN_C_END_