summaryrefslogtreecommitdiff
path: root/kernel/src/apic
diff options
context:
space:
mode:
authorAleksa Vuckovic <aleksa@vuckovic.cc>2023-03-02 20:30:55 +0100
committerAleksa Vuckovic <aleksa@vuckovic.cc>2023-03-02 20:30:55 +0100
commitfbc2cc52c8a38c3c63a34f5547ba7c4209a667ac (patch)
tree985e3b96308123dc1771abfc30e9fe4f8daac5f4 /kernel/src/apic
parent1e1c00c09991846257af4c8e50a177178355d986 (diff)
scheduling usermode processes & code refactoring
Diffstat (limited to 'kernel/src/apic')
-rw-r--r--kernel/src/apic/apic.c132
-rw-r--r--kernel/src/apic/ioapic.c10
-rw-r--r--kernel/src/apic/madt.c11
-rw-r--r--kernel/src/apic/rsdp.c61
4 files changed, 116 insertions, 98 deletions
diff --git a/kernel/src/apic/apic.c b/kernel/src/apic/apic.c
index ad3ccec..0316b5c 100644
--- a/kernel/src/apic/apic.c
+++ b/kernel/src/apic/apic.c
@@ -22,84 +22,88 @@ uint8_t curr_cpu_apic_id()
0xFF);
}
+void clear_apic_errors()
+{
+ *((__volatile__ uint32_t *)(lapic_addr + 0x280)) = 0;
+}
+
+void wait_for_delivery()
+{
+ do {
+ __asm__ __volatile__("pause" : : : "memory");
+ } while (*((__volatile__ uint32_t *)(uint64_t)(lapic_addr + 0x300)) &
+ (1 << 12));
+}
+
+void select_ap(uint32_t apic_id)
+{
+ *((__volatile__ uint32_t *)(lapic_addr + 0x310)) =
+ (*((__volatile__ uint32_t *)(lapic_addr + 0x310)) &
+ 0x00ffffff) |
+ apic_id;
+}
+
+void send_init_ipi(uint32_t apic_id)
+{
+ clear_apic_errors();
+ select_ap(apic_id);
+
+ /* trigger INIT IPI */
+ *((__volatile__ uint32_t *)(lapic_addr + 0x300)) =
+ (*((__volatile__ uint32_t *)(lapic_addr + 0x300)) &
+ 0xfff00000) |
+ 0x00C500;
+
+ wait_for_delivery();
+ select_ap(apic_id);
+
+ /* deassert */
+ *((__volatile__ uint32_t *)(lapic_addr + 0x300)) =
+ (*((__volatile__ uint32_t *)(lapic_addr + 0x300)) &
+ 0xfff00000) |
+ 0x008500;
+
+ wait_for_delivery();
+}
+
+void send_sipi(uint32_t apic_id)
+{
+ clear_apic_errors();
+ select_ap(apic_id);
+
+ /* trigger STARTUP IPI for 0800:0000 */
+ *((__volatile__ uint32_t *)(lapic_addr + 0x300)) =
+ (*((__volatile__ uint32_t *)(lapic_addr + 0x300)) &
+ 0xfff0f800) |
+ 0x000608;
+
+ /* wait 200 usec */
+ wait(1);
+ wait_for_delivery();
+}
+
void init_ap_cpus()
{
- uint8_t bspid = curr_cpu_apic_id();
+ uint8_t bspid;
+ size_t i;
+ size_t j;
init_mutex(&cnt_lock);
map_addr(lapic_addr, lapic_addr, FLAG_PRESENT);
- size_t i;
- size_t j;
+ bspid = curr_cpu_apic_id();
+
for (i = 0; i < numcores; i++) {
/* do not start BSP, that's already running this code */
if (cpu_apic_ids[i] == bspid)
continue;
- /* send INIT IPI */
-
- /* clear APIC errors */
- *((__volatile__ uint32_t *)(lapic_addr + 0x280)) = 0;
- /* select AP */
- *((__volatile__ uint32_t *)(lapic_addr + 0x310)) =
- (*((__volatile__ uint32_t *)(lapic_addr + 0x310)) &
- 0x00ffffff) |
- ((uint32_t)cpu_apic_ids[i] << 24);
- /* trigger INIT IPI */
- *((__volatile__ uint32_t *)(lapic_addr + 0x300)) =
- (*((__volatile__ uint32_t *)(lapic_addr + 0x300)) &
- 0xfff00000) |
- 0x00C500;
- /* wait for delivery */
- do {
- __asm__ __volatile__("pause" : : : "memory");
- } while (*((__volatile__ uint32_t *)(uint64_t)(lapic_addr +
- 0x300)) &
- (1 << 12));
- /* select AP */
- *((__volatile__ uint32_t *)(lapic_addr + 0x310)) =
- (*((__volatile__ uint32_t *)(lapic_addr + 0x310)) &
- 0x00ffffff) |
- ((uint32_t)cpu_apic_ids[i] << 24);
- /* deassert */
- *((__volatile__ uint32_t *)(lapic_addr + 0x300)) =
- (*((__volatile__ uint32_t *)(lapic_addr + 0x300)) &
- 0xfff00000) |
- 0x008500;
- /* wait for delivery */
- do {
- __asm__ __volatile__("pause" : : : "memory");
- } while (*((__volatile__ uint32_t *)(uint64_t)(lapic_addr +
- 0x300)) &
- (1 << 12));
- /* wait 10 msec */
- wait(10);
+ send_init_ipi((uint32_t)cpu_apic_ids[i] << 24);
- /* send STARTUP IPI (twice) */
+ wait(10);
for (j = 0; j < 2; j++) {
- /* clear APIC errors */
- *((__volatile__ uint32_t *)(lapic_addr + 0x280)) = 0;
- /* select AP */
- *((__volatile__ uint32_t *)(lapic_addr + 0x310)) =
- (*((__volatile__ uint32_t *)(lapic_addr +
- 0x310)) &
- 0x00ffffff) |
- ((uint32_t)cpu_apic_ids[i] << 24);
- /* trigger STARTUP IPI for 0800:0000 */
- *((__volatile__ uint32_t *)(lapic_addr + 0x300)) =
- (*((__volatile__ uint32_t *)(lapic_addr +
- 0x300)) &
- 0xfff0f800) |
- 0x000608;
- /* wait 200 usec */
- wait(1);
- /* wait for delivery */
- do {
- __asm__ __volatile__("pause" : : : "memory");
- } while (*((__volatile__ uint32_t
- *)(uint64_t)(lapic_addr + 0x300)) &
- (1 << 12));
+ send_sipi((uint32_t)cpu_apic_ids[i] << 24);
}
}
diff --git a/kernel/src/apic/ioapic.c b/kernel/src/apic/ioapic.c
index 7fe005b..1e20486 100644
--- a/kernel/src/apic/ioapic.c
+++ b/kernel/src/apic/ioapic.c
@@ -30,14 +30,16 @@ void ioapic_set_irq(uint8_t irq, uint64_t apic_id, uint8_t vector)
{
const uint32_t low_index = (uint32_t)0x10 + irq * 2;
const uint32_t high_index = (uint32_t)0x10 + irq * 2 + 1;
+ uint32_t high;
+ uint32_t low;
- uint32_t high = ioapic_read((uint8_t)high_index);
+ high = ioapic_read((uint8_t)high_index);
/* set APIC ID */
high &= (uint32_t)~0xff000000;
high |= (uint32_t)apic_id << 24;
ioapic_write((uint8_t)high_index, high);
- uint32_t low = ioapic_read((uint8_t)low_index);
+ low = ioapic_read((uint8_t)low_index);
/* unmask the IRQ */
low &= (uint32_t) ~(1 << 16);
@@ -57,10 +59,12 @@ void ioapic_set_irq(uint8_t irq, uint64_t apic_id, uint8_t vector)
void apic_remap_interrupts()
{
+ uint8_t bspid;
+
map_addr(ioapic_addr, ioapic_addr, FLAG_PRESENT);
map_addr(lapic_addr, lapic_addr, FLAG_PRESENT);
- uint8_t bspid = curr_cpu_apic_id();
+ bspid = curr_cpu_apic_id();
/* irq is 2 because of gsi remap */
ioapic_set_irq(0x2, bspid, 0x20); /* timer */
diff --git a/kernel/src/apic/madt.c b/kernel/src/apic/madt.c
index 2ddf90f..d45b1cb 100644
--- a/kernel/src/apic/madt.c
+++ b/kernel/src/apic/madt.c
@@ -66,25 +66,28 @@ void madt_parse_lapic_addr_ovr(uint64_t *addr)
void parse_madt()
{
uint64_t *madt_addr = find_sys_table_addr("APIC");
+ struct MADT *madt;
+ size_t curr_size;
+ uint8_t type;
+ uint8_t len;
if (madt_addr == NULL) {
printf("MADT NOT FOUND\n");
return;
}
- struct MADT *madt = (struct MADT *)kalloc(sizeof(struct MADT));
+ madt = (struct MADT *)kalloc(sizeof(struct MADT));
memcpy(madt, madt_addr, sizeof(struct MADT));
lapic_addr = madt->lapic_addr;
- size_t curr_size;
for (curr_size = sizeof(struct MADT); curr_size < madt->h.Length;) {
struct MADT_type_header *m = (struct MADT_type_header *)kalloc(
sizeof(struct MADT_type_header));
memcpy(m,
(uint64_t *)((uint64_t)madt_addr + (uint64_t)curr_size),
sizeof(struct MADT_type_header));
- uint8_t type = m->type;
- uint8_t len = m->len;
+ type = m->type;
+ len = m->len;
kfree(m);
switch (type) {
diff --git a/kernel/src/apic/rsdp.c b/kernel/src/apic/rsdp.c
index 6a1505f..fa16816 100644
--- a/kernel/src/apic/rsdp.c
+++ b/kernel/src/apic/rsdp.c
@@ -6,14 +6,17 @@
uint64_t *find_rsdp()
{
- map_addr(0x0, 0x0, FLAG_PRESENT);
const char *rsdp_cs = "RSD PTR ";
uint64_t i;
size_t j;
+ char *x;
+ uint8_t ind;
+
+ map_addr(0x0, 0x0, FLAG_PRESENT);
for (i = 0x10; i < 0x100000; i += 0x10) {
- char *x = (char *)i;
- uint8_t ind = 1;
+ x = (char *)i;
+ ind = 1;
for (j = 0; j < strlen(rsdp_cs); j++) {
if (rsdp_cs[j] != x[j]) {
ind = 0;
@@ -30,33 +33,35 @@ uint64_t *find_rsdp()
void list_sys_tables(void)
{
uint64_t *rsdp = find_rsdp();
+ struct RSDP_descriptor *rsdp_desc;
+ struct ACPI_header *rsdt;
+ uint32_t entries;
+ size_t i;
+ size_t j;
+ uint32_t na_addr;
+ uint32_t addr;
+ struct ACPI_header *t;
if (rsdp == NULL) {
printf("RSDP NOT FOUND\n");
return;
}
- struct RSDP_descriptor *rsdp_desc = (struct RSDP_descriptor *)rsdp;
+ rsdp_desc = (struct RSDP_descriptor *)rsdp;
map_addr(rsdp_desc->RsdtAddress, rsdp_desc->RsdtAddress, FLAG_PRESENT);
- struct ACPI_header *rsdt =
- (struct ACPI_header *)kalloc(sizeof(struct ACPI_header));
+ rsdt = (struct ACPI_header *)kalloc(sizeof(struct ACPI_header));
memcpy(rsdt, (uint64_t *)(uint64_t)rsdp_desc->RsdtAddress,
sizeof(struct ACPI_header));
- uint32_t entries =
- (rsdt->Length - (uint32_t)sizeof(struct ACPI_header)) / 4;
- size_t i;
- size_t j;
+ entries = (rsdt->Length - (uint32_t)sizeof(struct ACPI_header)) / 4;
for (i = 0; i < entries; i++) {
- uint32_t na_addr = (uint32_t)rsdp_desc->RsdtAddress +
- (uint32_t)sizeof(struct ACPI_header) +
- (uint32_t)i * 4;
- uint32_t addr;
+ na_addr = (uint32_t)rsdp_desc->RsdtAddress +
+ (uint32_t)sizeof(struct ACPI_header) +
+ (uint32_t)i * 4;
memcpy(&addr, (uint64_t *)(uint64_t)na_addr, 4);
- struct ACPI_header *t = (struct ACPI_header *)kalloc(
- sizeof(struct ACPI_header));
+ t = (struct ACPI_header *)kalloc(sizeof(struct ACPI_header));
memcpy(t, (uint64_t *)(uint64_t)addr,
sizeof(struct ACPI_header));
@@ -75,38 +80,40 @@ void list_sys_tables(void)
uint64_t *find_sys_table_addr(const char *signature)
{
uint64_t *rsdp = find_rsdp();
+ struct RSDP_descriptor *rsdp_desc;
+ struct ACPI_header *rsdt;
+ uint32_t entries;
+ size_t i;
+ size_t j;
+ uint32_t addr;
+ struct ACPI_header *t;
+ uint8_t ind = 1;
if (rsdp == NULL) {
printf("RSDP NOT FOUND\n");
return NULL;
}
- struct RSDP_descriptor *rsdp_desc = (struct RSDP_descriptor *)rsdp;
+ rsdp_desc = (struct RSDP_descriptor *)rsdp;
map_addr(rsdp_desc->RsdtAddress, rsdp_desc->RsdtAddress, FLAG_PRESENT);
- struct ACPI_header *rsdt =
- (struct ACPI_header *)kalloc(sizeof(struct ACPI_header));
+ rsdt = (struct ACPI_header *)kalloc(sizeof(struct ACPI_header));
memcpy(rsdt, (uint64_t *)(uint64_t)rsdp_desc->RsdtAddress,
sizeof(struct ACPI_header));
- uint32_t entries =
- (rsdt->Length - (uint32_t)sizeof(struct ACPI_header)) / 4;
+ entries = (rsdt->Length - (uint32_t)sizeof(struct ACPI_header)) / 4;
- size_t i;
- size_t j;
for (i = 0; i < entries; i++) {
uint32_t na_addr = (uint32_t)rsdp_desc->RsdtAddress +
(uint32_t)sizeof(struct ACPI_header) +
(uint32_t)i * 4;
- uint32_t addr;
memcpy(&addr, (uint64_t *)(uint64_t)na_addr, 4);
- struct ACPI_header *t = (struct ACPI_header *)kalloc(
- sizeof(struct ACPI_header));
+ t = (struct ACPI_header *)kalloc(sizeof(struct ACPI_header));
memcpy(t, (uint64_t *)(uint64_t)addr,
sizeof(struct ACPI_header));
- int ind = 1;
+ ind = 1;
for (j = 0; j < 4; j++) {
if (t->Signature[j] != signature[j])
ind = 0;