i386 Fixed pnp bios limits
PATCH 6/21 i386 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 @@ ENTRY(cpu_gdt_table) .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 +5 -11
@@ -58,12 +58,6 @@ __asm__(".previous \n" ); -#define Q_SET_SEL (cpu, selname, address, size) \ -do { \ -set_base(per_cpu(cpu_gdt_table,cpu)[(selname) >> 3], __va((u32)(address))); \ -set_limit(per_cpu(cpu_gdt_table,cpu)[(selname) >> 3], size); \ -} while(0) -#define Q2_SET_SEL (cpu, selname, address, size) \ do { \ set_base(per_cpu(cpu_gdt_table,cpu)[(selname) >> 3], (u32)(address)); \
@@ -523,10 +517,10 @@ void pnpbios_calls_init(union pnp_bios_i pnp_bios_callpoint.offset = header->fields.pm16offset; pnp_bios_callpoint.segment =PNP_CS16 ; -for (i=0 ; i <NR_CPUS ; i++) - { -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 ); +for (i=0 ; i <NR_CPUS ; i++) { +struct desc_struct *gdt =get_cpu_gdt_table (i); +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)); } }