Changeset b808660 in mainline for kernel/arch/ia32/src/asm.S


Ignore:
Timestamp:
2010-07-08T20:03:52Z (15 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
bee2d4c
Parents:
9097982f
Message:

Do not align ia32 int handlers on any pre-defined power-of-two boundary but
rather define each one as a separate procedure with its own global label. The
label is used to populate the IDT and it also helps to maintain consistency
between C and assembly.

The old way was very error-prone because one did not get a warning when a
handler exceeded the size limit given by the alignment, which usually resulted
in very weird crashes.

In principle, the old way was also rather wasteful as the handler had to be
aligned on a power-of-two address. With the int handler size around 160 bytes,
the bytes 160 - 255 in each handler were simply wasted. In practice, however,
the image.iso size did not change (I'd expect it to drop by around 8K).

The old way did not detect a mistmatch between the C code idea of how many IDT
entries there are and the assembly language code idea of the same thing. It was
possible to initialize an IDT entry to point to some garbage and nobody would
notice until the int occurred.

The new method was a bit tiresome to write as there was a lot of copy'n'paste.
But since it was a one-time effort, I lumped it. If you know of a way to write a
for-loop in C preprocessor or use GAS assmebler macros in a sensible way, I will
gladly use your improvement.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/ia32/src/asm.S

    r9097982f rb808660  
    4444.global paging_on
    4545.global enable_l_apic_in_msr
    46 .global interrupt_handlers
    4746.global memsetb
    4847.global memsetw
     
    273272 *
    274273 */
    275 #define INTERRUPT_ALIGN  256
    276 
    277 .macro handler i n
     274
     275.macro handler i
     276.global int_\i
     277int_\i:
    278278        .ifeq \i - 0x30
    279279                /* Syscall handler */
     
    472472               
    473473        .endif
    474        
    475         .align INTERRUPT_ALIGN
    476         .if (\n - \i) - 1
    477                 handler "(\i + 1)", \n
    478         .endif
    479474.endm
    480475
    481 /* Keep in sync with pm.h! */
    482 #define IDT_ITEMS  64
    483 
    484 .align INTERRUPT_ALIGN
     476#define LIST_0_63 \
     477        0, 1, 2, 3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,\
     478        28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,\
     479        53,54,55,56,57,58,59,60,61,62,63
     480
    485481interrupt_handlers:
    486         h_start:
    487                 handler 0 IDT_ITEMS
    488         h_end:
     482.irp cnt, LIST_0_63
     483        handler \cnt
     484.endr
    489485
    490486/** Print Unicode character to EGA display.
     
    635631        ret
    636632
    637 .data
    638 .global interrupt_handler_size
    639 
    640 interrupt_handler_size: .long (h_end - h_start) / IDT_ITEMS
Note: See TracChangeset for help on using the changeset viewer.