Fixed pnp bios limits
PATCH 7/10 Fixed pnp bios limits
PnP BIOS data, code, and 32-bit entry segments all have fixed limits as well; set them in the GDT rather than adding more code. It would be nice to add these fixups to the boot GDT rather than setting the GDT for each CPU; perhaps I can wiggle this in later, but getting it in before the subsys init looks tricky.
Also, make some progress on deprecating the ugly Q_SET_SEL macros.
Signed-off-by Zachary Amsden <[email protected]>
arch/i386/kernel/head.S +8 -4
@@ -504,10 +504,14 @@ .quad 0x0000000000000000 /* 0x80 TSS descriptor */ .quad 0x0000000000000000 /* 0x88 LDT descriptor */ - /* Segments used for calling PnP BIOS have byte granularity */ - .quad 0x00409a0000000000 /* 0x90 32-bit code */ - .quad 0x00009a0000000000 /* 0x98 16-bit code */ - .quad 0x0000920000000000 /* 0xa0 16-bit data */ + /* + * Segments used for calling PnP BIOS have byte granularity. + * They code segments and data segments have fixed 64k limits, + * the transfer segment sizes are set at run time. + */ + .quad 0x00409a000000ffff /* 0x90 32-bit code */ + .quad 0x00009a000000ffff /* 0x98 16-bit code */ + .quad 0x000092000000ffff /* 0xa0 16-bit data */ .quad 0x0000920000000000 /* 0xa8 16-bit data */ .quad 0x0000920000000000 /* 0xb0 16-bit data */
drivers/pnp/pnpbios/bioscalls.c +4 -11
@@ -58,13 +58,6 @@".previous \n" ); -#define Q_SET_SEL (cpu, selname, address, size) \ -do { \ -struct desc_struct *gdt = get_cpu_gdt_table((cpu)); \ -set_base(gdt[(selname) >> 3], __va((u32)(address))); \ -set_limit(gdt[(selname) >> 3], size); \ -} while(0) -#define Q2_SET_SEL (cpu, selname, address, size) \ do { \ struct desc_struct *gdt = get_cpu_gdt_table((cpu)); \
@@ -534,8 +527,8 @@struct desc_struct *gdt =get_cpu_gdt_table (i);if (!gdt)continue ; -Q2_SET_SEL (i,PNP_CS32 , &pnp_bios_callfunc,64 *1024 ); -Q_SET_SEL (i,PNP_CS16 , header->fields.pm16cseg,64 *1024 ); -Q_SET_SEL (i,PNP_DS , header->fields.pm16dseg,64 *1024 ); - } +set_base (gdt[GDT_ENTRY_PNPBIOS_CS32 ], &pnp_bios_callfunc); +set_base (gdt[GDT_ENTRY_PNPBIOS_CS16 ],__va (header->fields.pm16cseg)); +set_base (gdt[GDT_ENTRY_PNPBIOS_DS ],__va (header->fields.pm16dseg)); + } }