Implement PIT interrupts

This commit is contained in:
2025-08-22 12:37:48 +02:00
parent 9d8849a425
commit 182c6e2956
13 changed files with 354 additions and 145 deletions

View File

@ -9,6 +9,10 @@
#include "util/util.h" #include "util/util.h"
#include "bootinfo/bootinfo.h" #include "bootinfo/bootinfo.h"
#include "uacpi/uacpi.h" #include "uacpi/uacpi.h"
#include "uacpi/acpi.h"
#include "apic.h"
struct acpi_madt *MADT = NULL;
// uACPI // uACPI
@ -55,5 +59,22 @@ void acpi_init(void) {
LOG("hal", "acpi init\n"); LOG("hal", "acpi init\n");
} }
/* uint32_t acpi_remapirq(uint32_t irq) { */ uint8_t acpi_remapirq(uint8_t irq) {
/* } */ uint64_t cur = (uint64_t)&MADT->entries;
uint64_t end = cur + MADT->hdr.length;
while (cur < end) {
struct acpi_entry_hdr *ent = (struct acpi_entry_hdr *)cur;
if (ent->type == ACPI_MADT_ENTRY_TYPE_INTERRUPT_SOURCE_OVERRIDE) {
struct acpi_madt_interrupt_source_override *override = (struct acpi_madt_interrupt_source_override *)ent;
if (override->source == irq) {
return override->gsi;
}
}
cur += ent->length;
}
return irq;
}

View File

@ -2,8 +2,11 @@
#define HAL_ACPI_H_ #define HAL_ACPI_H_
#include <stdint.h> #include <stdint.h>
#include "uacpi/acpi.h"
extern struct acpi_madt *MADT;
void acpi_init(void); void acpi_init(void);
uint32_t acpi_remapirq(uint32_t irq); uint8_t acpi_remapirq(uint8_t irq);
#endif // HAL_ACPI_H_ #endif // HAL_ACPI_H_

View File

@ -11,68 +11,14 @@
#include "util/util.h" #include "util/util.h"
#include "cpu.h" #include "cpu.h"
#include "util/mmio.h" #include "util/mmio.h"
#include "acpi.h"
#define IOAPIC_IOREGSEL 0x00
#define IOAPIC_IOWIN 0x10
#define IOAPIC_IOAPICID 0x00
#define IOAPIC_IOAPICVER 0x01
#define IOAPIC_IOAPICARB 0x02
#define IOAPIC_IOREDTBL 0x10
#define LAPIC_ID 0x0020
#define LAPIC_VER 0x0030
#define LAPIC_TPR 0x0080
#define LAPIC_APR 0x0090
#define LAPIC_PPR 0x00A0
#define LAPIC_EOI 0x00B0
#define LAPIC_RRD 0x00C0
#define LAPIC_LDR 0x00D0
#define LAPIC_DFR 0x00E0
#define LAPIC_SVR 0x00F0
#define LAPIC_ISR 0x0100
#define LAPIC_TMR 0x0180
#define LAPIC_IRR 0x0200
#define LAPIC_ESR 0x0280
#define LAPIC_ICRLO 0x0300
#define LAPIC_ICRHI 0x0310
#define LAPIC_TIMER 0x0320
#define LAPIC_THERMAL 0x0330
#define LAPIC_PERF 0x0340
#define LAPIC_LINT0 0x0350
#define LAPIC_LINT1 0x0360
#define LAPIC_ERROR 0x0370
#define LAPIC_TICR 0x0380
#define LAPIC_TCCR 0x0390
#define LAPIC_TDCR 0x03E0
#define ICR_FIXED 0x00000000
#define ICR_LOWEST 0x00000100
#define ICR_SMI 0x00000200
#define ICR_NMI 0x00000400
#define ICR_INIT 0x00000500
#define ICR_STARTUP 0x00000600
#define ICR_PHYS 0x00000000
#define ICR_LOGC 0x00000800
#define ICR_IDLE 0x00000000
#define ICR_SEND_PENDING 0x00001000
#define ICR_DEASSERT 0x00000000
#define ICR_ASSERT 0x00004000
#define ICR_EDGE 0x00000000
#define ICR_LEVEL 0x00008000
#define ICR_NO_SHORTHAND 0x00000000
#define ICR_SELF 0x00040000
#define ICR_ALL_INC_SELF 0x00080000
#define ICR_ALL_EXCL_SELF 0x000C0000
#define ICR_DEST_SHIFT 24
typedef struct LApic { typedef struct LApic {
struct LApic *next; struct LApic *next;
uint8_t id; uint8_t id;
} LApic; } LApic;
struct acpi_madt *MADT = NULL;
uint8_t *IOAPIC; uint8_t *IOAPIC;
uint8_t *LAPIC; uint8_t *LAPIC;
LApic *LAPICS = NULL; LApic *LAPICS = NULL;

View File

@ -1,6 +1,70 @@
#ifndef HAL_APIC_H_ #ifndef HAL_APIC_H_
#define HAL_APIC_H_ #define HAL_APIC_H_
#include <stdint.h>
#define IOAPIC_IOREGSEL 0x00
#define IOAPIC_IOWIN 0x10
#define IOAPIC_IOAPICID 0x00
#define IOAPIC_IOAPICVER 0x01
#define IOAPIC_IOAPICARB 0x02
#define IOAPIC_IOREDTBL 0x10
#define LAPIC_ID 0x0020
#define LAPIC_VER 0x0030
#define LAPIC_TPR 0x0080
#define LAPIC_APR 0x0090
#define LAPIC_PPR 0x00A0
#define LAPIC_EOI 0x00B0
#define LAPIC_RRD 0x00C0
#define LAPIC_LDR 0x00D0
#define LAPIC_DFR 0x00E0
#define LAPIC_SVR 0x00F0
#define LAPIC_ISR 0x0100
#define LAPIC_TMR 0x0180
#define LAPIC_IRR 0x0200
#define LAPIC_ESR 0x0280
#define LAPIC_ICRLO 0x0300
#define LAPIC_ICRHI 0x0310
#define LAPIC_TIMER 0x0320
#define LAPIC_THERMAL 0x0330
#define LAPIC_PERF 0x0340
#define LAPIC_LINT0 0x0350
#define LAPIC_LINT1 0x0360
#define LAPIC_ERROR 0x0370
#define LAPIC_TICR 0x0380
#define LAPIC_TCCR 0x0390
#define LAPIC_TDCR 0x03E0
#define ICR_FIXED 0x00000000
#define ICR_LOWEST 0x00000100
#define ICR_SMI 0x00000200
#define ICR_NMI 0x00000400
#define ICR_INIT 0x00000500
#define ICR_STARTUP 0x00000600
#define ICR_PHYS 0x00000000
#define ICR_LOGC 0x00000800
#define ICR_IDLE 0x00000000
#define ICR_SEND_PENDING 0x00001000
#define ICR_DEASSERT 0x00000000
#define ICR_ASSERT 0x00004000
#define ICR_EDGE 0x00000000
#define ICR_LEVEL 0x00008000
#define ICR_NO_SHORTHAND 0x00000000
#define ICR_SELF 0x00040000
#define ICR_ALL_INC_SELF 0x00080000
#define ICR_ALL_EXCL_SELF 0x000C0000
#define ICR_DEST_SHIFT 24
extern uint8_t *IOAPIC;
void apic_init(void); void apic_init(void);
void ioapic_setentry(uint8_t *base, uint8_t idx, uint64_t data);
uint32_t ioapic_read(uint8_t *base, uint8_t reg);
void ioapic_write(uint8_t *base, uint8_t reg, uint32_t data);
void lapic_write(uint32_t reg, uint32_t data);
uint32_t lapic_read(uint32_t reg);
#endif // HAL_APIC_H_ #endif // HAL_APIC_H_

View File

@ -8,6 +8,7 @@
#include "intr.h" #include "intr.h"
#include "pic.h" #include "pic.h"
#include "apic.h" #include "apic.h"
#include "pit.h"
void hal_init(void) { void hal_init(void) {
if (!serial_init()) { if (!serial_init()) {
@ -28,5 +29,8 @@ void hal_init_withmalloc(void) {
pic_init(); pic_init();
apic_init(); apic_init();
intr_init(); intr_init();
pit_init();
ioapic_setentry(IOAPIC, acpi_remapirq(0x00), INTR_TIMER);
hal_intr_enable();
} }

View File

@ -6,6 +6,9 @@
#include "hal/hal.h" #include "hal/hal.h"
#include "kprintf.h" #include "kprintf.h"
#include "compiler/attr.h" #include "compiler/attr.h"
#include "pic.h"
#include "apic.h"
#include "pit.h"
void hal_intr_disable(void) { void hal_intr_disable(void) {
asm volatile("cli"); asm volatile("cli");
@ -104,54 +107,58 @@ static const char *exceptions[] = {
"#CP", "#CP",
}; };
extern void intr_vec0(void);
extern void intr_vec1(void);
extern void intr_vec2(void);
extern void intr_vec3(void);
extern void intr_vec4(void);
extern void intr_vec5(void);
extern void intr_vec6(void);
extern void intr_vec7(void);
extern void intr_vec8(void);
extern void intr_vec10(void);
extern void intr_vec11(void);
extern void intr_vec12(void);
extern void intr_vec13(void);
extern void intr_vec14(void);
extern void intr_vec16(void);
extern void intr_vec17(void);
extern void intr_vec18(void);
extern void intr_vec19(void);
extern void intr_vec20(void);
extern void intr_vec21(void);
extern void intr_vec32(void);
extern void intr_vec33(void);
extern void intr_vec39(void);
void intr_init(void) { void intr_init(void) {
idt_setentry(0, (uint64_t)&intr_vec0, 0, 0x8E); #define MKINTR(N, IST) \
idt_setentry(1, (uint64_t)&intr_vec1, 0, 0x8E); extern void intr_vec##N(void); \
idt_setentry(2, (uint64_t)&intr_vec2, 2, 0x8E); idt_setentry(N, (uint64_t)&intr_vec##N, IST, 0x8E);
idt_setentry(3, (uint64_t)&intr_vec3, 0, 0x8E);
idt_setentry(4, (uint64_t)&intr_vec4, 0, 0x8E); MKINTR(0, 0);
idt_setentry(5, (uint64_t)&intr_vec5, 0, 0x8E); MKINTR(1, 0);
idt_setentry(6, (uint64_t)&intr_vec6, 0, 0x8E); MKINTR(2, 2);
idt_setentry(7, (uint64_t)&intr_vec7, 0, 0x8E); MKINTR(4, 0);
idt_setentry(8, (uint64_t)&intr_vec8, 1, 0x8E); MKINTR(5, 0);
idt_setentry(10, (uint64_t)&intr_vec10, 0, 0x8E); MKINTR(6, 0);
idt_setentry(11, (uint64_t)&intr_vec11, 0, 0x8E); MKINTR(7, 0);
idt_setentry(12, (uint64_t)&intr_vec12, 0, 0x8E); MKINTR(8, 1);
idt_setentry(13, (uint64_t)&intr_vec13, 0, 0x8E); MKINTR(9, 0);
idt_setentry(14, (uint64_t)&intr_vec14, 0, 0x8E); MKINTR(10, 0);
idt_setentry(16, (uint64_t)&intr_vec16, 0, 0x8E); MKINTR(11, 0);
idt_setentry(17, (uint64_t)&intr_vec17, 0, 0x8E); MKINTR(12, 0);
idt_setentry(18, (uint64_t)&intr_vec18, 0, 0x8E); MKINTR(13, 0);
idt_setentry(19, (uint64_t)&intr_vec19, 0, 0x8E); MKINTR(14, 0);
idt_setentry(20, (uint64_t)&intr_vec20, 0, 0x8E); MKINTR(15, 0);
idt_setentry(21, (uint64_t)&intr_vec21, 0, 0x8E); MKINTR(16, 0);
idt_setentry(32, (uint64_t)&intr_vec32, 0, 0x8E); MKINTR(17, 0);
idt_setentry(33, (uint64_t)&intr_vec33, 0, 0x8E); MKINTR(18, 0);
idt_setentry(39, (uint64_t)&intr_vec39, 0, 0x8E); MKINTR(19, 0);
MKINTR(20, 0);
MKINTR(21, 0);
MKINTR(22, 0);
MKINTR(23, 0);
MKINTR(24, 0);
MKINTR(25, 0);
MKINTR(26, 0);
MKINTR(27, 0);
MKINTR(28, 0);
MKINTR(29, 0);
MKINTR(30, 0);
MKINTR(31, 0);
MKINTR(32, 0);
MKINTR(33, 0);
MKINTR(34, 0);
MKINTR(35, 0);
MKINTR(36, 0);
MKINTR(37, 0);
MKINTR(38, 0);
MKINTR(39, 0);
MKINTR(40, 3);
MKINTR(41, 0);
MKINTR(42, 0);
MKINTR(43, 0);
MKINTR(44, 0);
MKINTR(45, 0);
MKINTR(46, 0);
MKINTR(47, 0);
idt_init(); idt_init();
} }
@ -175,9 +182,20 @@ void intr_dumpframe(IntrStackFrame *frame) {
} }
void intr_handleintr(IntrStackFrame *frame) { void intr_handleintr(IntrStackFrame *frame) {
hal_intr_disable(); if (frame->trapnum >= 0 && frame->trapnum <= 31) {
ERR("ERROR", "%s, 0x%lX\n", exceptions[frame->trapnum], frame->errnum); // EXCEPTION
intr_dumpframe(frame); ERR("ERROR", "%s, 0x%lX\n", exceptions[frame->trapnum], frame->errnum);
hal_hang(); intr_dumpframe(frame);
hal_hang();
} else if (frame->trapnum >= 32 && frame->trapnum <= 47) {
if (frame->trapnum == INTR_TIMER) {
kprintf("ACK %d\n", PIT_TICKS);
PIT_TICKS++;
io_out8(PIC2_CMD, 0x20);
}
io_out8(PIC1_CMD, 0x20);
lapic_write(LAPIC_EOI, 0x00);
}
} }

View File

@ -2,6 +2,9 @@
#define HAL_INTR_H_ #define HAL_INTR_H_
#define INTR_IRQBASE 0x20 #define INTR_IRQBASE 0x20
#define INTR_IRQTIMER 0x00
#define INTR_TIMER 0x20
#define INTR_SPURIOUS 0xff
void intr_init(void); void intr_init(void);

View File

@ -9,20 +9,45 @@
.global intr_vec6 .global intr_vec6
.global intr_vec7 .global intr_vec7
.global intr_vec8 .global intr_vec8
.global intr_vec9
.global intr_vec10 .global intr_vec10
.global intr_vec11 .global intr_vec11
.global intr_vec12 .global intr_vec12
.global intr_vec13 .global intr_vec13
.global intr_vec14 .global intr_vec14
.global intr_vec15
.global intr_vec16 .global intr_vec16
.global intr_vec17 .global intr_vec17
.global intr_vec18 .global intr_vec18
.global intr_vec19 .global intr_vec19
.global intr_vec20 .global intr_vec20
.global intr_vec21 .global intr_vec21
.global intr_vec22
.global intr_vec23
.global intr_vec24
.global intr_vec25
.global intr_vec26
.global intr_vec27
.global intr_vec28
.global intr_vec29
.global intr_vec30
.global intr_vec31
.global intr_vec32 .global intr_vec32
.global intr_vec33 .global intr_vec33
.global intr_vec34
.global intr_vec35
.global intr_vec36
.global intr_vec37
.global intr_vec38
.global intr_vec39 .global intr_vec39
.global intr_vec40
.global intr_vec41
.global intr_vec42
.global intr_vec43
.global intr_vec44
.global intr_vec45
.global intr_vec46
.global intr_vec47
.macro _PUSHAQ .macro _PUSHAQ
push %rax push %rax
@ -77,60 +102,65 @@
push %rax push %rax
.endm .endm
.macro _POPACR
add $0x28, %rsp
.endm
.macro _vecintr_errorcode_present_save num .macro _vecintr_errorcode_present_save num
push $\num pushq $\num
_PUSHAQ _PUSHAQ
_PUSHACR _PUSHACR
.endm .endm
.macro _vecintr_plain_save num errorno .macro _vecintr_plain_save num
push $\errorno pushq $0x0
push $\num pushq $\num
_PUSHAQ _PUSHAQ
_PUSHACR _PUSHACR
.endm .endm
.macro _vecintr_restore siema:
add 40, %rsp jmp siema
_POPAQ
add 16, %rsp
.endm
.macro _vecintr_bodygen .macro _vecintr_bodygen
cld
mov %rsp, %rdi mov %rsp, %rdi
call intr_handleintr call intr_handleintr
_vecintr_restore _POPACR
_POPAQ
add $0x10, %rsp
iretq iretq
.endm .endm
intr_vec0: intr_vec0:
_vecintr_plain_save 0, 0 _vecintr_plain_save 0
_vecintr_bodygen _vecintr_bodygen
intr_vec1: intr_vec1:
_vecintr_plain_save 1, 0 _vecintr_plain_save 1
_vecintr_bodygen _vecintr_bodygen
intr_vec2: intr_vec2:
_vecintr_plain_save 2, 0 _vecintr_plain_save 2
_vecintr_bodygen _vecintr_bodygen
intr_vec3: intr_vec3:
_vecintr_plain_save 3, 0 _vecintr_plain_save 3
_vecintr_bodygen _vecintr_bodygen
intr_vec4: intr_vec4:
_vecintr_plain_save 4, 0 _vecintr_plain_save 4
_vecintr_bodygen _vecintr_bodygen
intr_vec5: intr_vec5:
_vecintr_plain_save 5, 0 _vecintr_plain_save 5
_vecintr_bodygen _vecintr_bodygen
intr_vec6: intr_vec6:
_vecintr_plain_save 6, 0 _vecintr_plain_save 6
_vecintr_bodygen _vecintr_bodygen
intr_vec7: intr_vec7:
_vecintr_plain_save 7, 0 _vecintr_plain_save 7
_vecintr_bodygen _vecintr_bodygen
intr_vec8: intr_vec8:
_vecintr_errorcode_present_save 8 _vecintr_errorcode_present_save 8
_vecintr_bodygen _vecintr_bodygen
intr_vec9:
_vecintr_plain_save 9
_vecintr_bodygen
intr_vec10: intr_vec10:
_vecintr_errorcode_present_save 10 _vecintr_errorcode_present_save 10
_vecintr_bodygen _vecintr_bodygen
@ -146,30 +176,104 @@ intr_vec13:
intr_vec14: intr_vec14:
_vecintr_errorcode_present_save 14 _vecintr_errorcode_present_save 14
_vecintr_bodygen _vecintr_bodygen
intr_vec15:
_vecintr_plain_save 15
_vecintr_bodygen
intr_vec16: intr_vec16:
_vecintr_plain_save 16, 0 _vecintr_plain_save 16
_vecintr_bodygen _vecintr_bodygen
intr_vec17: intr_vec17:
_vecintr_errorcode_present_save 17 _vecintr_errorcode_present_save 17
_vecintr_bodygen _vecintr_bodygen
intr_vec18: intr_vec18:
_vecintr_plain_save 18, 0 _vecintr_plain_save 18
_vecintr_bodygen _vecintr_bodygen
intr_vec19: intr_vec19:
_vecintr_plain_save 19, 0 _vecintr_plain_save 19
_vecintr_bodygen _vecintr_bodygen
intr_vec20: intr_vec20:
_vecintr_plain_save 20, 0 _vecintr_plain_save 20
_vecintr_bodygen _vecintr_bodygen
intr_vec21: intr_vec21:
_vecintr_errorcode_present_save 21 _vecintr_errorcode_present_save 21
_vecintr_bodygen _vecintr_bodygen
intr_vec32: intr_vec22:
_vecintr_plain_save 32, 0 _vecintr_plain_save 22
_vecintr_bodygen _vecintr_bodygen
intr_vec33: intr_vec23:
_vecintr_plain_save 33, 0 _vecintr_plain_save 23
_vecintr_bodygen _vecintr_bodygen
intr_vec39: intr_vec24:
_vecintr_plain_save 39, 0 _vecintr_plain_save 24
_vecintr_bodygen _vecintr_bodygen
intr_vec25:
_vecintr_plain_save 25
_vecintr_bodygen
intr_vec26:
_vecintr_plain_save 26
_vecintr_bodygen
intr_vec27:
_vecintr_plain_save 27
_vecintr_bodygen
intr_vec28:
_vecintr_plain_save 28
_vecintr_bodygen
intr_vec29:
_vecintr_errorcode_present_save 29
_vecintr_bodygen
intr_vec30:
_vecintr_errorcode_present_save 30
_vecintr_bodygen
intr_vec31:
_vecintr_plain_save 31
_vecintr_bodygen
intr_vec32:
_vecintr_plain_save 32
_vecintr_bodygen
intr_vec33:
_vecintr_plain_save 33
_vecintr_bodygen
intr_vec34:
_vecintr_plain_save 34
_vecintr_bodygen
intr_vec35:
_vecintr_plain_save 35
_vecintr_bodygen
intr_vec36:
_vecintr_plain_save 36
_vecintr_bodygen
intr_vec37:
_vecintr_plain_save 37
_vecintr_bodygen
intr_vec38:
_vecintr_plain_save 38
_vecintr_bodygen
intr_vec39:
_vecintr_plain_save 39
_vecintr_bodygen
intr_vec40:
_vecintr_plain_save 40
_vecintr_bodygen
intr_vec41:
_vecintr_plain_save 41
_vecintr_bodygen
intr_vec42:
_vecintr_plain_save 42
_vecintr_bodygen
intr_vec43:
_vecintr_plain_save 43
_vecintr_bodygen
intr_vec44:
_vecintr_plain_save 44
_vecintr_bodygen
intr_vec45:
_vecintr_plain_save 45
_vecintr_bodygen
intr_vec46:
_vecintr_plain_save 46
_vecintr_bodygen
intr_vec47:
_vecintr_plain_save 47
_vecintr_bodygen

40
kernel/hal/x86_64/pit.c Normal file
View File

@ -0,0 +1,40 @@
#include <stdint.h>
#include "pit.h"
#include "io.h"
#define PIT_COUNTER0 0x40
#define PIT_CMD 0x43
#define PIT_CMD_BINARY 0x00
#define PIT_CMD_BCD 0x01
#define PIT_CMD_MODE0 0x00
#define PIT_CMD_MODE1 0x02
#define PIT_CMD_MODE2 0x04
#define PIT_CMD_MODE3 0x06
#define PIT_CMD_MODE4 0x08
#define PIT_CMD_MODE5 0x0A
#define PIT_CMD_LATCH 0x00
#define PIT_CMD_RW_LOW 0x10
#define PIT_CMD_RW_HI 0x20
#define PIT_CMD_RW_BOTH 0x30
#define PIT_CMD_COUNTER0 0x00
#define PIT_CMD_COUNTER1 0x40
#define PIT_CMD_COUNTER2 0x80
#define PIT_CMD_READBACK 0xC0
#define PIT_FREQ 1193182
volatile uint32_t PIT_TICKS;
void pit_init(void) {
uint32_t hz = 1000;
uint32_t div = PIT_FREQ / hz;
io_out8(PIT_CMD, PIT_CMD_BINARY | PIT_CMD_MODE3 | PIT_CMD_RW_BOTH | PIT_CMD_COUNTER0);
io_out8(PIT_COUNTER0, div);
io_out8(PIT_COUNTER0, div >> 8);
}
void pit_wait(uint32_t ms) {
uint32_t now = PIT_TICKS;
++ms;
while (PIT_TICKS - now < ms);
}

11
kernel/hal/x86_64/pit.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef HAL_PIT_H_
#define HAL_PIT_H_
#include <stdint.h>
extern volatile uint32_t PIT_TICKS;
void pit_init(void);
void pit_wait(uint32_t ms);
#endif // HAL_PIT_H_

View File

@ -63,13 +63,12 @@ void kmain(void) {
paging_init(); paging_init();
dlmalloc_check(); dlmalloc_check();
hal_init_withmalloc(); hal_init_withmalloc();
/* hal_intr_disable(); */
storedev_init(); storedev_init();
baseimg_init(); baseimg_init();
vfs_init(); vfs_init();
kprintf(BANNER_TEXT "\n"); /* kprintf(BANNER_TEXT "\n"); */
/* *((int *)0xdeadbeef) = 123; */
hal_hang(); hal_hang();
} }

View File

@ -8,7 +8,6 @@
Term TERM; Term TERM;
void term_init(void) { void term_init(void) {
spinlock_init(&TERM.spinlock);
TERM.ftctx = flanterm_fb_init( TERM.ftctx = flanterm_fb_init(
NULL, NULL, NULL, NULL,
BOOT_INFO.fb->address, BOOT_INFO.fb->address,
@ -32,9 +31,7 @@ void term_init(void) {
} }
void term_write(const char *s, size_t len) { void term_write(const char *s, size_t len) {
spinlock_acquire(&TERM.spinlock);
flanterm_write(TERM.ftctx, s, len); flanterm_write(TERM.ftctx, s, len);
spinlock_release(&TERM.spinlock);
} }
#if PUTCHAR_ == PUTCHAR_FB #if PUTCHAR_ == PUTCHAR_FB

View File

@ -6,7 +6,6 @@
#include "spinlock/spinlock.h" #include "spinlock/spinlock.h"
typedef struct { typedef struct {
SpinLock spinlock;
struct flanterm_context *ftctx; struct flanterm_context *ftctx;
} Term; } Term;