chore: reorganize file directories

We have reorganized all the file directories that previously looked ugly as hell (cough cough arch/x86_64 cough)

Now it looks much cleaner

Signed-off-by: kaguya <vpshinomiya@protonmail.com>
This commit is contained in:
kaguya
2026-04-26 14:44:40 -04:00
parent d22d5ab2e4
commit 336af1c2ad
67 changed files with 96 additions and 99 deletions
+158
View File
@@ -0,0 +1,158 @@
#include "ata.h"
#include "arch/x86_64/cpu/io.h"
#include "libk/stdio.h"
#include <stdbool.h>
#define ATA_PRIMARY_DATA 0x1F0
#define ATA_PRIMARY_ERROR 0x1F1
#define ATA_PRIMARY_SECCOUNT 0x1F2
#define ATA_PRIMARY_LBALOW 0x1F3
#define ATA_PRIMARY_LBAMID 0x1F4
#define ATA_PRIMARY_LBAHIGH 0x1F5
#define ATA_PRIMARY_DRIVE 0x1F6
#define ATA_PRIMARY_STATUS 0x1F7
#define ATA_PRIMARY_COMMAND 0x1F7
#define ATA_STATUS_BSY 0x80
#define ATA_STATUS_DRDY 0x40
#define ATA_STATUS_DRQ 0x08
#define ATA_STATUS_ERR 0x01
#define ATA_CMD_IDENTIFY 0xEC
#define ATA_CMD_READ_SECTORS 0x20
static void ata_wait_ready(void)
{
while (x86_64_inb(ATA_PRIMARY_STATUS) & ATA_STATUS_BSY) {}
while (!(x86_64_inb(ATA_PRIMARY_STATUS) & ATA_STATUS_DRDY)) {}
}
static bool ata_poll(void)
{
// 400 ns delay
for (int i = 0; i < 4; i++)
x86_64_inb(ATA_PRIMARY_STATUS);
uint8_t status;
while ((status = x86_64_inb(ATA_PRIMARY_STATUS)) & ATA_STATUS_BSY);
if (status & ATA_STATUS_ERR) return false;
while (!(status & ATA_STATUS_DRQ)) {
status = x86_64_inb(ATA_PRIMARY_STATUS);
if (status & ATA_STATUS_ERR) return false;
}
return true;
}
void ata_init(void)
{
x86_64_outb(0x3F6, 0x02); // disable interrupts on primary controller
ata_wait_ready();
x86_64_outb(ATA_PRIMARY_DRIVE, 0xA0); // select master
ata_wait_ready();
printf("ATA: Primary master (hda) initialized\n");
}
void ata_identify(void)
{
static uint16_t buffer[256];
x86_64_outb(ATA_PRIMARY_DRIVE, 0xA0);
x86_64_outb(ATA_PRIMARY_SECCOUNT, 0);
x86_64_outb(ATA_PRIMARY_LBALOW, 0);
x86_64_outb(ATA_PRIMARY_LBAMID, 0);
x86_64_outb(ATA_PRIMARY_LBAHIGH, 0);
x86_64_outb(ATA_PRIMARY_COMMAND, ATA_CMD_IDENTIFY);
if (x86_64_inb(ATA_PRIMARY_STATUS) == 0) {
printf("ATA: No primary master drive detected\n");
return;
}
if (!ata_poll()) {
printf("ATA poll failed at ATA_IDENTIFY\n");
}
if (x86_64_inb(ATA_PRIMARY_STATUS) & ATA_STATUS_ERR) {
printf("ATA: Identify error\n");
return;
}
x86_64_insw(ATA_PRIMARY_DATA, buffer, 256);
printf("ATA: Disk model: ");
for (int i = 27; i <= 46; i++) {
uint16_t w = buffer[i];
char high = w >> 8;
char low = w & 0xFF;
printf("%c%c", high, low); // swap bytes
}
printf("\n");
printf("ATA: Total sectors: %lu\n", (uint64_t)buffer[60] | ((uint64_t)buffer[61] << 16));
}
bool ata_read_sectors(uint64_t lba, uint8_t sector_count, void* buffer)
{
if (sector_count == 0) return true;
ata_wait_ready();
x86_64_outb(ATA_PRIMARY_DRIVE, 0xE0 | ((lba >> 24) & 0x0F));
x86_64_outb(ATA_PRIMARY_SECCOUNT, sector_count);
x86_64_outb(ATA_PRIMARY_LBALOW, (uint8_t)lba);
x86_64_outb(ATA_PRIMARY_LBAMID, (uint8_t)(lba >> 8));
x86_64_outb(ATA_PRIMARY_LBAHIGH, (uint8_t)(lba >> 16));
x86_64_outb(ATA_PRIMARY_COMMAND, ATA_CMD_READ_SECTORS);
uint16_t* buf = buffer;
for (uint8_t i = 0; i < sector_count; i++) {
if (!ata_poll()) {
printf("ATA poll failed at ATA_read_sectors\n");
}
if (x86_64_inb(ATA_PRIMARY_STATUS) & ATA_STATUS_ERR) {
printf("ATA read error at LBA %lu\n", lba + i);
return false;
}
x86_64_insw(ATA_PRIMARY_DATA, buf, 256); // 512 bytes
buf += 256;
}
return true;
}
bool ata_write_sectors(uint64_t lba, uint8_t sector_count, void* buffer) {
if (sector_count == 0) return true;
ata_wait_ready();
x86_64_outb(ATA_PRIMARY_DRIVE, 0xE0 | ((lba >> 24) & 0x0F));
x86_64_outb(ATA_PRIMARY_SECCOUNT, sector_count);
x86_64_outb(ATA_PRIMARY_LBALOW, (uint8_t)lba);
x86_64_outb(ATA_PRIMARY_LBAMID, (uint8_t)(lba >> 8));
x86_64_outb(ATA_PRIMARY_LBAHIGH, (uint8_t)(lba >> 16));
x86_64_outb(ATA_PRIMARY_COMMAND, 0x30); // write sectors
uint16_t* buf = buffer;
for (uint8_t i = 0; i < sector_count; i++) {
if (!ata_poll()) {
return false;
}
x86_64_outsw(ATA_PRIMARY_DATA, buf, 256);
buf += 256;
}
return true;
}
+13
View File
@@ -0,0 +1,13 @@
#pragma once
#include <stdint.h>
#include <stdbool.h>
void ata_init(void);
void ata_identify(void);
// Read `sector_count` 512-byte sectors starting at LBA `lba` into `buffer`.
// Buffer must be large enough (sector_count * 512).
bool ata_read_sectors(uint64_t lba, uint8_t sector_count, void* buffer);
bool ata_write_sectors(uint64_t lba, uint8_t sector_count, void* buffer);
+137
View File
@@ -0,0 +1,137 @@
#include "pci.h"
#include "arch/x86_64/cpu/io.h"
#include "libk/stdio.h"
#define PCI_CFG_ADDR 0x0CF8
#define PCI_CFG_DATA 0x0CFC
static uint32_t pci_pack_addr(pci_address_t addr, uint16_t offset)
{
return (1u << 31) |
((uint32_t)addr.bus << 16) |
((uint32_t)addr.device << 11) |
((uint32_t)addr.function << 8) |
(offset & 0xFCu);
}
uint8_t pci_read8(pci_address_t addr, uint16_t offset)
{
x86_64_outl(PCI_CFG_ADDR, pci_pack_addr(addr, offset));
return (uint8_t)(x86_64_inl(PCI_CFG_DATA) >> ((offset & 3) * 8));
}
uint16_t pci_read16(pci_address_t addr, uint16_t offset)
{
x86_64_outl(PCI_CFG_ADDR, pci_pack_addr(addr, offset));
return (uint16_t)(x86_64_inl(PCI_CFG_DATA) >> ((offset & 2) * 8));
}
uint32_t pci_read32(pci_address_t addr, uint16_t offset)
{
x86_64_outl(PCI_CFG_ADDR, pci_pack_addr(addr, offset));
return x86_64_inl(PCI_CFG_DATA);
}
void pci_write8(pci_address_t addr, uint16_t offset, uint8_t val)
{
uint32_t tmp = pci_read32(addr, offset & ~3u);
uint8_t shift = (offset & 3) * 8;
tmp = (tmp & ~(0xFFu << shift)) | ((uint32_t)val << shift);
x86_64_outl(PCI_CFG_ADDR, pci_pack_addr(addr, offset));
x86_64_outl(PCI_CFG_DATA, tmp);
}
void pci_write16(pci_address_t addr, uint16_t offset, uint16_t val)
{
uint32_t tmp = pci_read32(addr, offset & ~3u);
uint8_t shift = (offset & 2) * 8;
tmp = (tmp & ~(0xFFFFu << shift)) | ((uint32_t)val << shift);
x86_64_outl(PCI_CFG_ADDR, pci_pack_addr(addr, offset));
x86_64_outl(PCI_CFG_DATA, tmp);
}
void pci_write32(pci_address_t addr, uint16_t offset, uint32_t val)
{
x86_64_outl(PCI_CFG_ADDR, pci_pack_addr(addr, offset));
x86_64_outl(PCI_CFG_DATA, val);
}
static void pci_read_bars(pci_device_t* dev)
{
for (int i = 0; i < 6; i++) {
uint16_t off = 0x10 + i * 4;
dev->bar[i] = pci_read32(dev->addr, off);
// If it's a 64-bit BAR we skip the next one (simple version)
if ((dev->bar[i] & 0x7) == 0x4)
i++;
}
}
void pci_init(void)
{
printf("[PCI] Scanning bus 0...\n");
pci_print_all();
}
void pci_print_all(void)
{
for (uint8_t bus = 0; bus < 1; bus++) { // start with bus 0 only
for (uint8_t dev = 0; dev < 32; dev++) {
for (uint8_t func = 0; func < 8; func++) {
pci_address_t addr = {bus, dev, func};
uint16_t vendor = pci_read16(addr, 0x00);
if (vendor == 0xFFFF) {
if (func == 0) break; // no device
continue;
}
uint16_t device_id = pci_read16(addr, 0x02);
uint16_t class_sub = pci_read16(addr, 0x0A);
uint8_t prog_if = pci_read8 (addr, 0x09);
uint8_t revision = pci_read8 (addr, 0x08);
pci_device_t d = {
.addr = addr,
.vendor_id = vendor,
.device_id = device_id,
.class_code = class_sub,
.prog_if = prog_if,
.revision = revision,
};
pci_read_bars(&d);
printf("[PCI] %02x:%02x.%x %04x:%04x class %04x rev %02x\n",
bus, dev, func, vendor, device_id, class_sub, revision);
if (func == 0 && (pci_read8(addr, 0x0E) & 0x80) == 0)
break; // not multifunction
}
}
}
}
bool pci_find_hda(pci_device_t* out_dev)
{
// Same scan as above, but stop at first HDA device
for (uint8_t bus = 0; bus < 256; bus++) {
for (uint8_t dev = 0; dev < 32; dev++) {
for (uint8_t func = 0; func < 8; func++) {
pci_address_t addr = {bus, dev, func};
uint16_t vendor = pci_read16(addr, 0x00);
if (vendor == 0xFFFF) continue;
uint16_t class_sub = pci_read16(addr, 0x0A);
if (((class_sub >> 8) == PCI_CLASS_AUDIO) && ((class_sub & 0xFF) == PCI_SUBCLASS_HDA)) {
out_dev->addr = addr;
out_dev->vendor_id = vendor;
out_dev->device_id = pci_read16(addr, 0x02);
out_dev->class_code = class_sub;
pci_read_bars(out_dev);
return true;
}
}
}
}
return false;
}
+39
View File
@@ -0,0 +1,39 @@
#pragma once
#include <stdint.h>
#include <stdbool.h>
typedef struct {
uint8_t bus;
uint8_t device;
uint8_t function;
} pci_address_t;
typedef struct {
pci_address_t addr;
uint16_t vendor_id;
uint16_t device_id;
uint16_t class_code; // (class << 8) | subclass
uint8_t prog_if;
uint8_t revision;
uint32_t bar[6];
bool is_multifunction;
} pci_device_t;
#define PCI_CLASS_AUDIO 0x04
#define PCI_SUBCLASS_HDA 0x03
// Read/write config space
uint8_t pci_read8 (pci_address_t addr, uint16_t offset);
uint16_t pci_read16(pci_address_t addr, uint16_t offset);
uint32_t pci_read32(pci_address_t addr, uint16_t offset);
void pci_write8 (pci_address_t addr, uint16_t offset, uint8_t val);
void pci_write16(pci_address_t addr, uint16_t offset, uint16_t val);
void pci_write32(pci_address_t addr, uint16_t offset, uint32_t val);
// Scan and print all PCI devices
void pci_init(void);
void pci_print_all(void);
// Find first HDA controller (returns true if found)
bool pci_find_hda(pci_device_t* out_dev);