Lesson 23, step 6

pull/6/head
Carlos 9 years ago
parent d9ee2545da
commit aa7a78349b

@ -39,6 +39,9 @@ C99 introduces standard fixed-width data types like `uint32_t`
We need to include `<stdint.h>` which works even in `-ffreestanding` (but requires stdlibs) We need to include `<stdint.h>` which works even in `-ffreestanding` (but requires stdlibs)
and use those data types instead of our own, then delete them on `type.h` and use those data types instead of our own, then delete them on `type.h`
We also delete the underscores around `__asm__` and `__volatile__` since they aren't needed.
4. Improperly aligned `kmalloc` 4. Improperly aligned `kmalloc`
------------------------------- -------------------------------
@ -53,12 +56,24 @@ For now, it will always return a new page-aligned memory block.
5. Missing functions 5. Missing functions
-------------------- --------------------
We will implement the missing `mem*` functions in following lessons
6. Interrupt handlers 6. Interrupt handlers
--------------------- ---------------------
- also cli, sti in interrupt handlers `cli` is redundant, since we already established on the IDT entries if interrupts
are enabled within a handler using the `idt_gate_t` flags.
`sti` is also redundant, as `iret` loads the eflags value from the stack, which contains a
bit telling whether interrupts are on or off.
In other words the interrupt handler automatically restores interrupts whether or not
interrupts were enabled before this interrupt
7. Structs and attributes On `cpu/isr.h`, `struct registers_t` has a couple issues.
------------------------- First, the alleged `esp` is renamed to `useless`.
The value is useless because it has to do with the current stack context, not what was interrupted.
Then, we rename `useresp` to `esp`
Finally, we add `cld` just before `call isr_handler` on `cpu/interrupt.asm`

@ -13,5 +13,5 @@ void set_idt() {
idt_reg.base = (uint32_t) &idt; idt_reg.base = (uint32_t) &idt;
idt_reg.limit = IDT_ENTRIES * sizeof(idt_gate_t) - 1; idt_reg.limit = IDT_ENTRIES * sizeof(idt_gate_t) - 1;
/* Don't make the mistake of loading &idt -- always load &idt_reg */ /* Don't make the mistake of loading &idt -- always load &idt_reg */
__asm__ __volatile__("lidtl (%0)" : : "r" (&idt_reg)); asm volatile("lidtl (%0)" : : "r" (&idt_reg));
} }

@ -15,6 +15,7 @@ isr_common_stub:
mov gs, ax mov gs, ax
; 2. Call C handler ; 2. Call C handler
cld ; C code following the sysV ABI requires DF to be clear on function entry
call isr_handler call isr_handler
; 3. Restore state ; 3. Restore state
@ -25,7 +26,6 @@ isr_common_stub:
mov gs, ax mov gs, ax
popa popa
add esp, 8 ; Cleans up the pushed error code and pushed ISR number add esp, 8 ; Cleans up the pushed error code and pushed ISR number
sti
iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP
; Common IRQ code. Identical to ISR code except for the 'call' ; Common IRQ code. Identical to ISR code except for the 'call'
@ -47,7 +47,6 @@ irq_common_stub:
mov gs, bx mov gs, bx
popa popa
add esp, 8 add esp, 8
sti
iret iret
; We don't get information about which interrupt was caller ; We don't get information about which interrupt was caller
@ -328,97 +327,81 @@ isr31:
; IRQ handlers ; IRQ handlers
irq0: irq0:
cli
push byte 0 push byte 0
push byte 32 push byte 32
jmp irq_common_stub jmp irq_common_stub
irq1: irq1:
cli
push byte 1 push byte 1
push byte 33 push byte 33
jmp irq_common_stub jmp irq_common_stub
irq2: irq2:
cli
push byte 2 push byte 2
push byte 34 push byte 34
jmp irq_common_stub jmp irq_common_stub
irq3: irq3:
cli
push byte 3 push byte 3
push byte 35 push byte 35
jmp irq_common_stub jmp irq_common_stub
irq4: irq4:
cli
push byte 4 push byte 4
push byte 36 push byte 36
jmp irq_common_stub jmp irq_common_stub
irq5: irq5:
cli
push byte 5 push byte 5
push byte 37 push byte 37
jmp irq_common_stub jmp irq_common_stub
irq6: irq6:
cli
push byte 6 push byte 6
push byte 38 push byte 38
jmp irq_common_stub jmp irq_common_stub
irq7: irq7:
cli
push byte 7 push byte 7
push byte 39 push byte 39
jmp irq_common_stub jmp irq_common_stub
irq8: irq8:
cli
push byte 8 push byte 8
push byte 40 push byte 40
jmp irq_common_stub jmp irq_common_stub
irq9: irq9:
cli
push byte 9 push byte 9
push byte 41 push byte 41
jmp irq_common_stub jmp irq_common_stub
irq10: irq10:
cli
push byte 10 push byte 10
push byte 42 push byte 42
jmp irq_common_stub jmp irq_common_stub
irq11: irq11:
cli
push byte 11 push byte 11
push byte 43 push byte 43
jmp irq_common_stub jmp irq_common_stub
irq12: irq12:
cli
push byte 12 push byte 12
push byte 44 push byte 44
jmp irq_common_stub jmp irq_common_stub
irq13: irq13:
cli
push byte 13 push byte 13
push byte 45 push byte 45
jmp irq_common_stub jmp irq_common_stub
irq14: irq14:
cli
push byte 14 push byte 14
push byte 46 push byte 46
jmp irq_common_stub jmp irq_common_stub
irq15: irq15:
cli
push byte 15 push byte 15
push byte 47 push byte 47
jmp irq_common_stub jmp irq_common_stub

@ -74,9 +74,9 @@ extern void irq15();
/* Struct which aggregates many registers */ /* Struct which aggregates many registers */
typedef struct { typedef struct {
uint32_t ds; /* Data segment selector */ uint32_t ds; /* Data segment selector */
uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; /* Pushed by pusha. */ uint32_t edi, esi, ebp, useless, ebx, edx, ecx, eax; /* Pushed by pusha. */
uint32_t int_no, err_code; /* Interrupt number and error code (if applicable) */ uint32_t int_no, err_code; /* Interrupt number and error code (if applicable) */
uint32_t eip, cs, eflags, useresp, ss; /* Pushed by the processor automatically */ uint32_t eip, cs, eflags, esp, ss; /* Pushed by the processor automatically */
} registers_t; } registers_t;
void isr_install(); void isr_install();

@ -13,7 +13,7 @@ uint8_t port_byte_in (uint16_t port) {
* *
* Inputs and outputs are separated by colons * Inputs and outputs are separated by colons
*/ */
__asm__("in %%dx, %%al" : "=a" (result) : "d" (port)); asm("in %%dx, %%al" : "=a" (result) : "d" (port));
return result; return result;
} }
@ -23,15 +23,15 @@ void port_byte_out (uint16_t port, uint8_t data) {
* However we see a comma since there are two variables in the input area * However we see a comma since there are two variables in the input area
* and none in the 'return' area * and none in the 'return' area
*/ */
__asm__ __volatile__("out %%al, %%dx" : : "a" (data), "d" (port)); asm volatile("out %%al, %%dx" : : "a" (data), "d" (port));
} }
uint16_t port_word_in (uint16_t port) { uint16_t port_word_in (uint16_t port) {
uint16_t result; uint16_t result;
__asm__("in %%dx, %%ax" : "=a" (result) : "d" (port)); asm("in %%dx, %%ax" : "=a" (result) : "d" (port));
return result; return result;
} }
void port_word_out (uint16_t port, uint16_t data) { void port_word_out (uint16_t port, uint16_t data) {
__asm__ __volatile__("out %%ax, %%dx" : : "a" (data), "d" (port)); asm volatile("out %%ax, %%dx" : : "a" (data), "d" (port));
} }

Loading…
Cancel
Save