summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2025-04-20 20:54:19 -0400
committerFreya Murphy <freya@freyacat.org>2025-04-20 23:44:39 -0400
commit102a0aafc87ad894e7aba479df62ec4961bb6985 (patch)
treea6f59e352209e8de42f015733314a681a8e0d947 /kernel
parentadd ata_init to main and fix some compilation problems (diff)
downloadcomus-102a0aafc87ad894e7aba479df62ec4961bb6985.tar.gz
comus-102a0aafc87ad894e7aba479df62ec4961bb6985.tar.bz2
comus-102a0aafc87ad894e7aba479df62ec4961bb6985.zip
move kspin to use ms, add ata_report
Diffstat (limited to 'kernel')
-rw-r--r--kernel/drivers/ata.c70
-rw-r--r--kernel/drivers/clock.c1
-rw-r--r--kernel/drivers/pit.c8
-rw-r--r--kernel/include/comus/asm.h15
-rw-r--r--kernel/include/comus/drivers/ata.h13
-rw-r--r--kernel/include/comus/drivers/clock.h14
-rw-r--r--kernel/include/lib/klib.h39
-rw-r--r--kernel/lib/kspin.c15
-rw-r--r--kernel/lib/ktime.c15
-rw-r--r--kernel/main.c2
10 files changed, 103 insertions, 89 deletions
diff --git a/kernel/drivers/ata.c b/kernel/drivers/ata.c
index 727d738..ca48b00 100644
--- a/kernel/drivers/ata.c
+++ b/kernel/drivers/ata.c
@@ -195,7 +195,7 @@ static uint8_t ide_channel_read(struct ide_channel *channel, const uint8_t reg)
} else if (reg < 0x16) {
result = inb(channel->bus_master_ide_base + reg - 0x0E);
} else {
- assert(false, "invalid ide channel register %u", reg);
+ panic("invalid ide channel register %u", reg);
}
if (disable_interrupts) {
@@ -205,19 +205,6 @@ static uint8_t ide_channel_read(struct ide_channel *channel, const uint8_t reg)
return result;
}
-// TODO: fix stack-trashing in ide_read_id_space_buffer() so we can call
-// functions there and dont have to do this garbage. but i dont understand why
-// esp and es need to be overwritten in the first place so I'm afraid i'll break
-// something - Ian
-#define __insl_nocall(reg, buffer_uint32_ptr, quads) \
- do { \
- for (uint32_t index = 0; index < quads; ++index) { \
- uint32_t out; \
- __inl_nocall(reg, out); \
- buffer_uint32_ptr[index] = out; \
- } \
- } while (0)
-
void ide_read_id_space_buffer(struct ide_channel *channel, uint8_t reg,
uint32_t *out_buffer,
size_t out_buffer_size_bytes)
@@ -243,14 +230,13 @@ void ide_read_id_space_buffer(struct ide_channel *channel, uint8_t reg,
// __asm__ volatile("pushw %es; pushw %ax; movw %ds, %ax; movw %ax, %es; popw %ax;");
if (reg < 0x08) {
- __insl_nocall(channel->io_base + reg - 0x00, out_buffer, quads);
+ insl(channel->io_base + reg - 0x00, out_buffer, quads);
} else if (reg < 0x0C) {
- __insl_nocall(channel->io_base + reg - 0x06, out_buffer, quads);
+ insl(channel->io_base + reg - 0x06, out_buffer, quads);
} else if (reg < 0x0E) {
- __insl_nocall(channel->control_base + reg - 0x0A, out_buffer, quads);
+ insl(channel->control_base + reg - 0x0A, out_buffer, quads);
} else if (reg < 0x16) {
- __insl_nocall(channel->bus_master_ide_base + reg - 0x0E, out_buffer,
- quads);
+ insl(channel->bus_master_ide_base + reg - 0x0E, out_buffer, quads);
}
// __asm__ volatile("popw %es;");
@@ -420,12 +406,12 @@ void ide_initialize(uint32_t BAR0, uint32_t BAR1, uint32_t BAR2, uint32_t BAR3,
// This function should be implemented in your OS. which waits for 1 ms.
// it is based on System Timer Device Driver.
// sleep(1); // Wait 1ms for drive select to work.
- kspin_sleep_seconds(1); // TODO: sleep 1ms, this is way too long
+ kspin_milliseconds(1);
// (II) Send ATA Identify Command:
ide_channel_write(chan, ATA_REG_COMMAND, ATA_CMD_IDENTIFY);
// sleep(1);
- kspin_sleep_seconds(1); // TODO: sleep 1ms
+ kspin_milliseconds(1);
// (III) Polling:
if (ide_channel_read(chan, ATA_REG_STATUS) == 0) {
@@ -468,7 +454,7 @@ void ide_initialize(uint32_t BAR0, uint32_t BAR1, uint32_t BAR2, uint32_t BAR3,
ide_channel_write(chan, ATA_REG_COMMAND,
ATA_CMD_IDENTIFY_PACKET);
// sleep(1);
- kspin_sleep_seconds(1); // TODO: sleep one millisecond
+ kspin_milliseconds(1);
}
static uint8_t id_space_buf[2048] = { 0 };
@@ -644,22 +630,22 @@ uint8_t ide_device_ata_access(struct ide_device *dev, uint8_t direction,
if ((err = ide_channel_poll(chan, 1))) {
return err; // Polling, set error and exit if there is.
}
- __asm__ volatile("pushw %es");
- __asm__ volatile("mov %%ax, %%es" : : "a"(selector));
+ //__asm__ volatile("pushw %es");
+ //__asm__ volatile("mov %%ax, %%es" : : "a"(selector));
// receive data
__asm__ volatile("rep insw" : : "c"(words), "d"(bus), "D"(edi));
- __asm__ volatile("popw %es");
+ //__asm__ volatile("popw %es");
edi += (words * 2);
}
} else {
// PIO Write.
for (i = 0; i < numsects; i++) {
ide_channel_poll(chan, 0); // Polling.
- __asm__ volatile("pushw %ds");
- __asm__ volatile("mov %%ax, %%ds" ::"a"(selector));
+ //__asm__ volatile("pushw %ds");
+ //__asm__ volatile("mov %%ax, %%ds" ::"a"(selector));
__asm__ volatile("rep outsw" ::"c"(words), "d"(bus),
"S"(edi)); // Send Data
- __asm__ volatile("popw %ds");
+ //__asm__ volatile("popw %ds");
edi += (words * 2);
}
ide_channel_write(chan, ATA_REG_COMMAND,
@@ -732,14 +718,14 @@ uint32_t ide_device_write_sectors(struct ide_device *dev, uint8_t numsects,
}
}
-bool ata_init(void)
+int ata_init(void)
{
struct pci_device dev;
if (!pci_findby_class(&dev, CLASS_MASS_STORAGE_CONTROLLER,
SUBCLASS_IDE_CONTROLLER, NULL)) {
TRACE("No disks found by PCI class");
- return false;
+ return 1;
}
// const uint8_t prog_if = pci_rcfg_b(dev, PCI_PROG_IF_B);
@@ -747,7 +733,7 @@ bool ata_init(void)
if (header_type != 0x0) {
TRACE("Wrong header type for IDE_CONTROLLER device, not reading BARs");
- return false;
+ return 1;
}
// const bool primary_channel_is_pci_native =
@@ -773,5 +759,25 @@ bool ata_init(void)
ide_initialize(BAR0, BAR1, BAR2, BAR3, BAR4);
- return true;
+ return 0;
+}
+
+void ata_report(void)
+{
+ if (!ide_devices[0].is_reserved)
+ return;
+
+ kprintf("ATA DEVICES\n");
+ for (size_t i = 0; i < 4; i++) {
+ struct ide_device *dev = &ide_devices[i];
+ if (!dev->is_reserved)
+ continue;
+ char size[20];
+ btoa(dev->size_in_sectors * 512, size);
+ kprintf(
+ "[%u:%u] %s\nType: %s\nSignature: %#04x\nFeatures: %#04x\nCommands: %#08x\nSize: %s\n\n",
+ dev->channel_idx, dev->drive_idx, dev->model_str,
+ dev->type ? "ATAPI" : "ATA", dev->drive_signature, dev->features,
+ dev->supported_command_sets, size);
+ }
}
diff --git a/kernel/drivers/clock.c b/kernel/drivers/clock.c
index fadd938..f860c25 100644
--- a/kernel/drivers/clock.c
+++ b/kernel/drivers/clock.c
@@ -1,7 +1,6 @@
#include <lib.h>
#include <comus/asm.h>
#include <comus/time.h>
-#include <comus/drivers/clock.h>
#define CMOS_WRITE_PORT 0x70
#define CMOS_READ_PORT 0x71
diff --git a/kernel/drivers/pit.c b/kernel/drivers/pit.c
index cb3c091..fd42084 100644
--- a/kernel/drivers/pit.c
+++ b/kernel/drivers/pit.c
@@ -8,16 +8,18 @@
uint64_t ticks = 0;
-uint16_t pit_read_divider(void) {
+uint16_t pit_read_divider(void)
+{
uint16_t count = 0;
cli();
outb(CMD, 0); // clear bits
count = inb(CHAN_0); // low byte
- count |= inb(CHAN_0)<<8; // highbyte
+ count |= inb(CHAN_0) << 8; // highbyte
return count;
}
-void pit_set_divider(uint16_t count) {
+void pit_set_divider(uint16_t count)
+{
outb(CHAN_0, count & 0xFF); // low byte
outb(CHAN_0, (count & 0xFF00) >> 8); // high byte
}
diff --git a/kernel/include/comus/asm.h b/kernel/include/comus/asm.h
index 87393eb..08b61e2 100644
--- a/kernel/include/comus/asm.h
+++ b/kernel/include/comus/asm.h
@@ -26,18 +26,21 @@ static inline void outw(uint16_t port, uint16_t val)
__asm__ volatile("outw %0, %1" : : "a"(val), "Nd"(port));
}
-#define __inl_nocall(port, out_uint32) \
- do { \
- __asm__ volatile("inl %1, %0" : "=a"(out_uint32) : "Nd"(port)); \
- } while (0);
-
static inline uint32_t inl(uint16_t port)
{
uint32_t ret;
- __inl_nocall(port, ret);
+ __asm__ volatile("inl %1, %0" : "=a"(ret) : "Nd"(port));
return ret;
}
+static inline void insl(uint16_t port, uint32_t *buffer, uint32_t count)
+{
+ while (count--) {
+ __asm__ volatile("inl %1, %0" : "=a"(*buffer) : "Nd"(port));
+ buffer++;
+ }
+}
+
static inline void outl(uint16_t port, uint32_t val)
{
__asm__ volatile("outl %0, %1" : : "a"(val), "Nd"(port));
diff --git a/kernel/include/comus/drivers/ata.h b/kernel/include/comus/drivers/ata.h
index 1f4aeb3..06d3e78 100644
--- a/kernel/include/comus/drivers/ata.h
+++ b/kernel/include/comus/drivers/ata.h
@@ -5,14 +5,21 @@
* @file ata.h
*
* @author Ian McFarlane <i.mcfarlane2002@gmail.com>
+ * @author Freya Murphy <freya@freyacat.org>
*
* ATA driver
*/
#include <stdbool.h>
-/// Returns true if a PCE IDE device is connected and we will have disk space,
-/// false on no disks found.
-bool ata_init(void);
+/**
+ * @returns 0 on success, 1 on failure
+ */
+int ata_init(void);
+
+/**
+ * report all ata devices to console
+ */
+void ata_report(void);
#endif
diff --git a/kernel/include/comus/drivers/clock.h b/kernel/include/comus/drivers/clock.h
deleted file mode 100644
index 7099fa7..0000000
--- a/kernel/include/comus/drivers/clock.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/**
- * @file clock.h
- *
- * @author Freya Murphy <freya@freyacat.org>
- *
- * CMOS real time clock driver
- */
-
-#ifndef CLOCK_H_
-#define CLOCK_H_
-
-void clock_update(void);
-
-#endif /* clock.h */
diff --git a/kernel/include/lib/klib.h b/kernel/include/lib/klib.h
index e79af41..f1540c1 100644
--- a/kernel/include/lib/klib.h
+++ b/kernel/include/lib/klib.h
@@ -202,40 +202,40 @@ enum log_level {
// #define __AS_STR_LITERAL_IMPL(x) #x
#if LOG_LEVEL >= LOG_LEVEL_TRACE
-#define TRACE(...) \
- do { \
+#define TRACE(...) \
+ do { \
kprintf("[TRACE] [%s:%s:%d] : ", __FILE__, __func__, __LINE__); \
- kprintf(__VA_ARGS__); \
+ kprintf(__VA_ARGS__); \
} while (0)
#else
#define TRACE(...)
#endif
#if LOG_LEVEL >= LOG_LVL_INFO
-#define INFO(...) \
- do { \
+#define INFO(...) \
+ do { \
kprintf("[INFO] [%s:%s:%d] : ", __FILE__, __func__, __LINE__); \
- kprintf(__VA_ARGS__); \
+ kprintf(__VA_ARGS__); \
} while (0)
#else
#define INFO(...)
#endif
#if LOG_LEVEL >= LOG_LVL_WARN
-#define WARN(...) \
- do { \
+#define WARN(...) \
+ do { \
kprintf("[WARN] [%s:%s:%d] : ", __FILE__, __func__, __LINE__); \
- kprintf(__VA_ARGS__); \
+ kprintf(__VA_ARGS__); \
} while (0)
#else
#define WARN(format, ...)
#endif
#if LOG_LEVEL >= LOG_LVL_ERROR
-#define ERROR(...) \
- do { \
+#define ERROR(...) \
+ do { \
kprintf("[ERROR] [%s:%s:%d] : ", __FILE__, __func__, __LINE__); \
- kprintf(__VA_ARGS__); \
+ kprintf(__VA_ARGS__); \
} while (0)
#else
#define ERROR(...)
@@ -310,11 +310,20 @@ void *krealloc(void *ptr, size_t size);
*/
void kfree(void *ptr);
-/*
- * Calls unixtime over and over until a number of seconds have passed
+/**
+ * Assuming the PIT ticks every ms, uses how many ticks to decide when to return.
+ * Returns when n*1000 ticks have passed
*
* @param seconds - number of seconds to wait, minimum (may take longer)
*/
-void kspin_sleep_seconds(size_t seconds);
+void kspin_seconds(size_t seconds);
+
+/**
+ * Assuming the PIT ticks every ms, uses how many ticks to decide when to return.
+ * Returns when n ticks have passed
+ *
+ * @param milliseconds - number of milliseconds to wait, minimum (may take longer)
+ */
+void kspin_milliseconds(size_t milliseconds);
#endif /* klib.h */
diff --git a/kernel/lib/kspin.c b/kernel/lib/kspin.c
new file mode 100644
index 0000000..ad0b512
--- /dev/null
+++ b/kernel/lib/kspin.c
@@ -0,0 +1,15 @@
+#include <lib.h>
+#include <comus/drivers/pit.h>
+#include <comus/asm.h>
+
+void kspin_seconds(size_t seconds)
+{
+ kspin_milliseconds(seconds * 1000);
+}
+
+void kspin_milliseconds(size_t milliseconds)
+{
+ uint64_t start = ticks;
+ while ((ticks - start) < milliseconds)
+ int_wait();
+}
diff --git a/kernel/lib/ktime.c b/kernel/lib/ktime.c
deleted file mode 100644
index 9bfcaa9..0000000
--- a/kernel/lib/ktime.c
+++ /dev/null
@@ -1,15 +0,0 @@
-#include <lib/klib.h>
-#include <comus/time.h>
-
-void kspin_sleep_seconds(size_t seconds)
-{
- const uint64_t start = unixtime();
-
- while (1) {
- const uint64_t now = unixtime();
-
- if (now - start > seconds) {
- return;
- }
- }
-}
diff --git a/kernel/main.c b/kernel/main.c
index 8666511..4953940 100644
--- a/kernel/main.c
+++ b/kernel/main.c
@@ -6,6 +6,7 @@
#include <comus/drivers/acpi.h>
#include <comus/drivers/pci.h>
#include <comus/drivers/gpu.h>
+#include <comus/drivers/ata.h>
#include <comus/fs.h>
#include <lib.h>
@@ -15,6 +16,7 @@ void kreport(void)
memory_report();
acpi_report();
pci_report();
+ ata_report();
gpu_report();
}