[metal] Export struct offsets from C code (#625)

Rather than computing them by hand.
This commit is contained in:
tkchia 2022-09-18 17:54:55 +08:00 committed by GitHub
parent cdf9e8c8a3
commit c937fbb222
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 37 additions and 17 deletions

View file

@ -235,8 +235,9 @@ pc: cld
#endif #endif
ljmp $0,$REAL(1f) ljmp $0,$REAL(1f)
1: mov %cx,%ds 1: mov %cx,%ds
mov $IMAGE_BASE_REAL-0x0500,%cx # clears bss .set mm,0x0500 # struct mman
mov $0x0500>>4,%ax # struct mman mov $IMAGE_BASE_REAL-mm,%cx # clears bss
mov $mm>>4,%ax
mov %ax,%es mov %ax,%es
xor %ax,%ax xor %ax,%ax
xor %di,%di xor %di,%di
@ -328,7 +329,7 @@ dsknfo: push %bx
movpp %es,%ds movpp %es,%ds
xor %si,%si xor %si,%si
mov %si,%es mov %si,%es
mov $0x1d10,%si # mman::pc_drive_base_table mov $mm+"struct mman::pc_drive_base_table",%si
xchg %si,%di xchg %si,%di
movsw # headunloadtime, headloadtime movsw # headunloadtime, headloadtime
movsw # shutofftime, bytespersector movsw # shutofftime, bytespersector
@ -381,11 +382,11 @@ pcread: push %ax
add $512>>4,%si add $512>>4,%si
mov %si,%es mov %si,%es
inc %al # ++sector inc %al # ++sector
cmp 0x1d1c,%al # mman::pc_drive_last_sector cmp mm+"struct mman::pc_drive_last_sector",%al
jbe 2f jbe 2f
mov $1,%al mov $1,%al
inc %dh # ++head inc %dh # ++head
cmp 0x1d20,%dh # mman::pc_drive_last_head cmp mm+"struct mman::pc_drive_last_head",%dh
jbe 2f jbe 2f
xor %dh,%dh xor %dh,%dh
inc %cx # ++cylinder inc %cx # ++cylinder
@ -1288,10 +1289,9 @@ lcheck: pushf # check for i8086 / i8088 / i80186
.endfn lcheck .endfn lcheck
// Gets memory map from BIOS. // Gets memory map from BIOS.
e820: mov $0x0510>>4,%di # mman::e820 e820: xor %ebx,%ebx # %ebx is an api state tracker
mov %di,%es mov %bx,%es
xor %di,%di # es:di is destination buffer mov $mm+"struct mman::e820",%di # es:di is destination buffer
xor %ebx,%ebx # ebx is an api state tracker
1: mov $0xE820,%eax # magic 1: mov $0xE820,%eax # magic
mov $8+8+4+4,%ecx # sizeof(struct SmapEntry) mov $8+8+4+4,%ecx # sizeof(struct SmapEntry)
mov $0x534d4150,%edx # magic number 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 4: add $8+8+4+4,%di # keep entry
5: test %ebx,%ebx # last entry? 5: test %ebx,%ebx # last entry?
jz 8f jz 8f
cmp $(256-1)*(8+8+4+4),%di cmp $mm+"struct mman::e820_end"-(8+8+4+4),%di
jb 1b jb 1b
8: xor %ax,%ax # add a blank sentinel entry 8: xor %ax,%ax # add a blank sentinel entry
mov $(8+8)/2,%cx mov $(8+8)/2,%cx
@ -1425,7 +1425,7 @@ pinit: push %ds
// //
// @see Intel Manual V3A §4.1.2 // @see Intel Manual V3A §4.1.2
golong: cli golong: cli
lidt 0x1d22 # mman::bad_idt lidt mm+"struct mman::bad_idt"
mov %cr4,%eax mov %cr4,%eax
or $CR4_PAE|CR4_PGE|CR4_OSFXSR,%eax or $CR4_PAE|CR4_PGE|CR4_OSFXSR,%eax
mov %eax,%cr4 mov %eax,%cr4
@ -1458,7 +1458,7 @@ long: xor %eax,%eax
xor %ebx,%ebx xor %ebx,%ebx
xor %ebp,%ebp xor %ebp,%ebp
push %rbp push %rbp
mov $0x0500,%rdi # mman mov $mm,%rdi
mov %cr3,%rsi mov %cr3,%rsi
mov $IMAGE_BASE_REAL,%edx mov $IMAGE_BASE_REAL,%edx
call __map_phdrs call __map_phdrs

View file

@ -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) { 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); __normalize_e820(mm);
__invert_memory(mm, pml4t); __invert_memory(mm, pml4t);
} }

View file

@ -9,14 +9,15 @@ struct mman {
int32_t pdpi; /* 0x0508 */ int32_t pdpi; /* 0x0508 */
int32_t e820n; /* 0x050c */ int32_t e820n; /* 0x050c */
struct SmapEntry e820[256]; /* 0x0510 */ struct SmapEntry e820[256]; /* 0x0510 */
struct SmapEntry e820_end[0]; /* 0x1d10 */
char pc_drive_base_table[11]; /* 0x1d10 */ char pc_drive_base_table[11]; /* 0x1d10 */
unsigned char pc_drive_type; /* 0x1d1b */ unsigned char pc_drive_type; /* 0x1d1b */
unsigned char pc_drive_last_sector; /* 0x1d1c */ unsigned char pc_drive_last_sector; /* 0x1d1c */
unsigned short pc_drive_last_cylinder; /* 0x1d1d */ unsigned short pc_drive_last_cylinder; /* 0x1d1e */
unsigned char pc_drives_attached; /* 0x1d1f */ unsigned char pc_drives_attached; /* 0x1d20 */
unsigned char pc_drive_last_head; /* 0x1d20 */ unsigned char pc_drive_last_head; /* 0x1d21 */
unsigned char pc_drive; /* 0x1d21 */ unsigned char pc_drive; /* 0x1d22 */
char bad_idt[6]; /* 0x1d22 */ char bad_idt[6]; /* 0x1d23 */
}; };
COSMOPOLITAN_C_END_ COSMOPOLITAN_C_END_