summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/amd64/amd64/proc_machdep.c3
-rw-r--r--sys/dev/cons/cons.c28
-rw-r--r--sys/dev/cons/cons_ansi.c3
-rw-r--r--sys/dev/ic/ahci.c3
-rw-r--r--sys/dev/pci/pci.c77
-rw-r--r--sys/fs/initramfs.c2
-rw-r--r--sys/include/dev/acpi/tables.h30
-rw-r--r--sys/include/dev/cons/cons.h1
-rw-r--r--sys/include/dev/pci/pci.h1
-rw-r--r--sys/include/sys/limits.h1
-rw-r--r--sys/include/sys/proc.h2
-rw-r--r--sys/include/sys/spawn.h2
-rw-r--r--sys/kern/exec_elf64.c1
-rw-r--r--sys/kern/kern_exec.c2
-rw-r--r--sys/kern/kern_exit.c7
-rw-r--r--sys/kern/kern_spawn.c53
-rw-r--r--sys/vm/vm_physmem.c33
17 files changed, 201 insertions, 48 deletions
diff --git a/sys/arch/amd64/amd64/proc_machdep.c b/sys/arch/amd64/amd64/proc_machdep.c
index 407adb1..aa8847a 100644
--- a/sys/arch/amd64/amd64/proc_machdep.c
+++ b/sys/arch/amd64/amd64/proc_machdep.c
@@ -40,7 +40,7 @@
#include <vm/map.h>
#include <string.h>
-void
+uintptr_t
md_td_stackinit(struct proc *td, void *stack_top, struct exec_prog *prog)
{
uintptr_t *sp = stack_top;
@@ -97,6 +97,7 @@ md_td_stackinit(struct proc *td, void *stack_top, struct exec_prog *prog)
STACK_PUSH(sp, argc);
tfp = &td->tf;
tfp->rsp = (uintptr_t)sp - VM_HIGHER_HALF;
+ return tfp->rsp;
}
void
diff --git a/sys/dev/cons/cons.c b/sys/dev/cons/cons.c
index ce2b154..0735f11 100644
--- a/sys/dev/cons/cons.c
+++ b/sys/dev/cons/cons.c
@@ -65,7 +65,6 @@ static struct cdevsw cons_cdevsw;
static void cons_draw_cursor(struct cons_screen *scr, uint32_t color);
static int cons_handle_special(struct cons_screen *scr, char c);
-static void cons_clear_scr(struct cons_screen *scr, uint32_t bg);
static uint32_t
rgb_invert(uint32_t rgb)
@@ -191,22 +190,14 @@ cons_handle_special(struct cons_screen *scr, char c)
SHOW_CURSOR(scr);
return 0;
case ASCII_LF:
- HIDE_CURSOR(scr);
-
/* Are we past screen width? */
if (scr->ch_row >= scr->nrows - 1) {
cons_clear_scr(scr, scr->bg);
- cons_flush(scr);
- scr->ch_col = 0;
- scr->ch_row = 0;
-
- /* Update cursor */
- scr->curs_row = 0;
- scr->curs_col = 0;
- SHOW_CURSOR(scr);
return 0;
}
+ HIDE_CURSOR(scr);
+
/* Make a newline */
cons_flush(scr);
++scr->ch_row;
@@ -255,18 +246,25 @@ cons_draw_cursor(struct cons_screen *scr, uint32_t color)
* @scr: Screen to clear.
* @bg: Color to clear it to.
*/
-static void
+void
cons_clear_scr(struct cons_screen *scr, uint32_t bg)
{
struct fbdev fbdev = scr->fbdev;
- struct cons_buf *bp;
+
+ cons_flush(scr);
+ HIDE_CURSOR(scr);
+
+ scr->ch_col = 0;
+ scr->ch_row = 0;
+ scr->curs_col = 0;
+ scr->curs_row = 0;
for (size_t i = 0; i < fbdev.height * fbdev.pitch; ++i) {
scr->fb_mem[i] = bg;
}
- bp = scr->ob[scr->nrows - 1];
- bp->flags |= CONS_BUF_CLEAN;
+ SHOW_CURSOR(scr);
+
}
/*
diff --git a/sys/dev/cons/cons_ansi.c b/sys/dev/cons/cons_ansi.c
index 4403f9c..ab1f22a 100644
--- a/sys/dev/cons/cons_ansi.c
+++ b/sys/dev/cons/cons_ansi.c
@@ -90,8 +90,7 @@ ansi_feed(struct ansi_state *statep, char c)
return c;
case 2:
if (c == 'H') {
- cons_reset_cursor(&g_root_scr);
- ansi_reset(statep);
+ cons_clear_scr(&g_root_scr, g_root_scr.bg);
return ANSI_UPDATE_CURSOR;
}
break;
diff --git a/sys/dev/ic/ahci.c b/sys/dev/ic/ahci.c
index 7d89dd3..d8d4a6f 100644
--- a/sys/dev/ic/ahci.c
+++ b/sys/dev/ic/ahci.c
@@ -806,8 +806,6 @@ ahci_init_port(struct ahci_hba *hba, uint32_t portno)
}
dp->fra = PHYS_TO_VIRT(fra);
- memset(dp->cmdlist, 0, clen * pagesz);
- memset(dp->fra, 0, pagesz);
/* Write the command list */
lo = cmdlist & 0xFFFFFFFF;
@@ -826,7 +824,6 @@ ahci_init_port(struct ahci_hba *hba, uint32_t portno)
tmp = vm_alloc_frame(1);
dp->cmdlist[i].prdtl = 1;
dp->cmdlist[i].ctba = tmp;
- memset(PHYS_TO_VIRT(tmp), 0, pagesz);
}
mmio_write32(&port->serr, 0xFFFFFFFF);
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
index 95fc5e2..9dfb90e 100644
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -32,20 +32,31 @@
#include <sys/syslog.h>
#include <sys/errno.h>
#include <sys/spinlock.h>
+#include <sys/mmio.h>
#include <dev/pci/pci.h>
#include <dev/pci/pciregs.h>
+#include <dev/acpi/acpi.h>
+#include <dev/acpi/tables.h>
#include <machine/pci/pci.h>
#include <vm/dynalloc.h>
+#include <vm/vm.h>
#include <lib/assert.h>
#define pr_trace(fmt, ...) kprintf("pci: " fmt, ##__VA_ARGS__)
static TAILQ_HEAD(, pci_device) device_list;
static struct spinlock devlist_lock = {0};
+static struct acpi_mcfg *mcfg;
struct cam_hook {
+ /* PCI CAM */
pcireg_t(*cam_readl)(struct pci_device *dev, uint32_t off);
void(*cam_writel)(struct pci_device *dev, uint32_t off, pcireg_t val);
+
+ /* PCIe ECAM */
+ pcireg_t(*ecam_readl)(struct pci_device *dev, uint32_t off);
+ void(*ecam_writel)(struct pci_device *dev, uint32_t off, pcireg_t val);
+ void *ecam_base[1];
} cam_hook = { NULL };
static bool
@@ -129,6 +140,9 @@ pci_set_device_info(struct pci_device *dev)
dev->prog_if = PCIREG_PROGIF(classrev);
dev->hdr_type = (uint8_t)pci_readl(dev, PCIREG_HDRTYPE);
+ /* This is a PCIe device if it has CAP ID of 0x10 */
+ dev->pci_express = pci_get_cap(dev, 0x10) != 0;
+
/* Set type-specific data */
switch (dev->hdr_type & ~BIT(7)) {
case PCI_HDRTYPE_NORMAL:
@@ -157,6 +171,53 @@ pci_set_device_info(struct pci_device *dev)
static void
pci_scan_bus(uint8_t bus);
+static inline vaddr_t
+pcie_ecam_addr(struct pci_device *dev)
+{
+ vaddr_t base = (vaddr_t)cam_hook.ecam_base[0];
+
+ base += dev->bus << 20 |
+ dev->slot << 15 |
+ dev->func << 12;
+ return base;
+}
+
+static pcireg_t
+pcie_ecam_readl(struct pci_device *dev, uint32_t offset)
+{
+ vaddr_t address;
+
+ address = pcie_ecam_addr(dev);
+ address += (offset & ~3);
+ return mmio_read32((void *)address);
+}
+
+static void
+pcie_ecam_writel(struct pci_device *dev, uint32_t offset, pcireg_t val)
+{
+ vaddr_t address;
+
+ address = pcie_ecam_addr(dev);
+ address += (offset & ~3);
+ mmio_write32((void *)address, val);
+}
+
+static int
+pcie_init(struct acpi_mcfg_base *base)
+{
+ void *iobase;
+
+ pr_trace("[group %02d] @ bus [%02d - %02d]\n", base->seg_grpno,
+ base->bus_start, base->bus_end);
+ pr_trace("ecam @ %p\n", base->base_pa);
+
+ iobase = PHYS_TO_VIRT(base->base_pa);
+ cam_hook.ecam_base[0] = iobase;
+ cam_hook.ecam_writel = pcie_ecam_writel;
+ cam_hook.ecam_readl = pcie_ecam_readl;
+ return 0;
+}
+
/*
* Attempt to register a device.
*
@@ -283,8 +344,10 @@ pci_add_device(struct pci_device *dev)
pcireg_t
pci_readl(struct pci_device *dev, uint32_t offset)
{
- if (cam_hook.cam_readl == NULL) {
- return (pcireg_t)-1;
+ bool have_ecam = cam_hook.ecam_readl != NULL;
+
+ if (dev->pci_express && have_ecam) {
+ return cam_hook.ecam_readl(dev, offset);
}
return cam_hook.cam_readl(dev, offset);
@@ -293,7 +356,10 @@ pci_readl(struct pci_device *dev, uint32_t offset)
void
pci_writel(struct pci_device *dev, uint32_t offset, pcireg_t val)
{
- if (cam_hook.cam_writel == NULL) {
+ bool have_ecam = cam_hook.ecam_writel != NULL;
+
+ if (dev->pci_express && have_ecam) {
+ cam_hook.ecam_writel(dev, offset, val);
return;
}
@@ -306,6 +372,11 @@ pci_init(void)
size_t ndev;
TAILQ_INIT(&device_list);
+ mcfg = acpi_query("MCFG");
+ if (mcfg != NULL) {
+ pcie_init(&mcfg->base[0]);
+ }
+
cam_hook.cam_readl = md_pci_readl;
cam_hook.cam_writel = md_pci_writel;
diff --git a/sys/fs/initramfs.c b/sys/fs/initramfs.c
index b12a64b..c3f9b14 100644
--- a/sys/fs/initramfs.c
+++ b/sys/fs/initramfs.c
@@ -223,6 +223,8 @@ initramfs_read(struct vnode *vp, struct sio_txn *sio)
return -EIO;
if (sio->buf == NULL)
return -EIO;
+ if (sio->len > n->size)
+ sio->len = n->size;
src = n->data;
dest = sio->buf;
diff --git a/sys/include/dev/acpi/tables.h b/sys/include/dev/acpi/tables.h
index 5215c86..d190150 100644
--- a/sys/include/dev/acpi/tables.h
+++ b/sys/include/dev/acpi/tables.h
@@ -132,4 +132,34 @@ struct __packed acpi_hpet {
uint8_t page_protection;
};
+/*
+ * PCIe / ACPI MCFG base address description
+ * table.
+ *
+ * @base_pa: Enhanced configuration base [physical]
+ * @seg_grpno: PCI segment group number
+ * @bus_start: Host bridge bus start
+ * @bus_end: Host bridge bus end
+ */
+struct __packed acpi_mcfg_base {
+ uint64_t base_pa;
+ uint16_t seg_grpno;
+ uint8_t bus_start;
+ uint8_t bus_end;
+ uint32_t reserved;
+};
+
+/*
+ * PCIe / ACPI MCFG structure
+ *
+ * @hdr: ACPI header
+ * @reserved: Do not use
+ * @base: ECAM MMIO address list
+ */
+struct __packed acpi_mcfg {
+ struct acpi_header hdr;
+ uint32_t reserved[2];
+ struct acpi_mcfg_base base[1];
+};
+
#endif /* _ACPI_TABLES_H_ */
diff --git a/sys/include/dev/cons/cons.h b/sys/include/dev/cons/cons.h
index 9868493..7599dd5 100644
--- a/sys/include/dev/cons/cons.h
+++ b/sys/include/dev/cons/cons.h
@@ -67,6 +67,7 @@ struct cons_screen {
void cons_init(void);
void cons_expose(void);
void cons_update_color(struct cons_screen *scr, uint32_t fg, uint32_t bg);
+void cons_clear_scr(struct cons_screen *scr, uint32_t bg);
void cons_reset_color(struct cons_screen *scr);
void cons_reset_cursor(struct cons_screen *scr);
int cons_putch(struct cons_screen *scr, char c);
diff --git a/sys/include/dev/pci/pci.h b/sys/include/dev/pci/pci.h
index a4de162..144b500 100644
--- a/sys/include/dev/pci/pci.h
+++ b/sys/include/dev/pci/pci.h
@@ -62,6 +62,7 @@ struct pci_device {
uint8_t pci_subclass;
uint8_t prog_if;
uint8_t hdr_type;
+ uint8_t pci_express : 1;
uint8_t pri_bus;
uint8_t sec_bus;
diff --git a/sys/include/sys/limits.h b/sys/include/sys/limits.h
index 198c963..f56958e 100644
--- a/sys/include/sys/limits.h
+++ b/sys/include/sys/limits.h
@@ -32,6 +32,7 @@
#define PATH_MAX 1024
#define SSIZE_MAX 32767
+#define ARG_MAX 4096
#define CHAR_BIT 8
#if defined(_KERNEL)
#define CPU_MAX 256
diff --git a/sys/include/sys/proc.h b/sys/include/sys/proc.h
index 2f1470a..241d990 100644
--- a/sys/include/sys/proc.h
+++ b/sys/include/sys/proc.h
@@ -95,7 +95,7 @@ int md_spawn(struct proc *p, struct proc *parent, uintptr_t ip);
scret_t sys_spawn(struct syscall_args *scargs);
pid_t spawn(struct proc *cur, void(*func)(void), void *p, int flags, struct proc **newprocp);
-void md_td_stackinit(struct proc *td, void *stack_top, struct exec_prog *prog);
+uintptr_t md_td_stackinit(struct proc *td, void *stack_top, struct exec_prog *prog);
__dead void md_td_kick(struct proc *td);
int fork1(struct proc *cur, int flags, void(*ip)(void), struct proc **newprocp);
diff --git a/sys/include/sys/spawn.h b/sys/include/sys/spawn.h
index 9d823db..0c54e4c 100644
--- a/sys/include/sys/spawn.h
+++ b/sys/include/sys/spawn.h
@@ -36,6 +36,6 @@
#define SPAWN_WAIT BIT(0)
#if !defined(_KERNEL)
-pid_t spawn(const char *pathname, int flags);
+pid_t spawn(const char *pathname, char **argv, char **envp, int flags);
#endif /* _KERNEL */
#endif /* !_SYS_SPAWN_H_ */
diff --git a/sys/kern/exec_elf64.c b/sys/kern/exec_elf64.c
index 3767b0b..987dda4 100644
--- a/sys/kern/exec_elf64.c
+++ b/sys/kern/exec_elf64.c
@@ -192,6 +192,7 @@ elf64_load(const char *pathname, struct proc *td, struct exec_prog *prog)
if ((status = elf64_verify(hdr)) != 0)
goto done;
+ memset(loadmap, 0, sizeof(loadmap));
pcbp = &td->pcb;
start = -1;
end = 0;
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
index b760912..2a53b8a 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -101,7 +101,7 @@ execve(struct proc *td, const struct execve_args *args)
stack_top = td->stack_base + (PROC_STACK_SIZE - 1);
/* Setup registers, signals and stack */
- md_td_stackinit(td, (void *)(stack_top + VM_HIGHER_HALF), &prog);
+ stack_top = md_td_stackinit(td, (void *)(stack_top + VM_HIGHER_HALF), &prog);
setregs(td, &prog, stack_top);
signals_init(td);
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index 6afae81..2f9e344 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -137,6 +137,10 @@ exit1(struct proc *td, int flags)
proc_reap(td);
}
+ if (td->data != NULL) {
+ dynfree(td->data);
+ }
+
/*
* Only free the process structure if we aren't
* being waited on, otherwise let it be so the
@@ -157,8 +161,6 @@ exit1(struct proc *td, int flags)
ci->curtd = NULL;
if (parent->pid == 0)
sched_enter();
- if (td->data == NULL)
- sched_enter();
parent->flags &= ~PROC_SLEEP;
sched_enter();
@@ -175,7 +177,6 @@ sys_exit(struct syscall_args *scargs)
{
struct proc *td = this_td();
- td->data = scargs->tf;
td->exit_status = scargs->arg0;
exit1(td, 0);
__builtin_unreachable();
diff --git a/sys/kern/kern_spawn.c b/sys/kern/kern_spawn.c
index 60d8e22..a953a6e 100644
--- a/sys/kern/kern_spawn.c
+++ b/sys/kern/kern_spawn.c
@@ -45,10 +45,17 @@
#define pr_trace(fmt, ...) kprintf("spawn: " fmt, ##__VA_ARGS__)
#define pr_error(...) pr_trace(__VA_ARGS__)
+#define ARGVP_MAX (ARG_MAX / sizeof(void *))
+
static volatile size_t nthreads = 0;
+/*
+ * TODO: envp
+ */
struct spawn_args {
char path[PATH_MAX];
+ char argv_blk[ARG_MAX];
+ char *argv[ARGVP_MAX];
};
static inline void
@@ -67,7 +74,6 @@ spawn_thunk(void)
struct proc *cur;
struct execve_args execve_args;
struct spawn_args *args;
- char *argv[] = { NULL, NULL };
char *envp[] = { NULL };
cur = this_td();
@@ -76,13 +82,10 @@ spawn_thunk(void)
memset(pathbuf, 0, sizeof(pathbuf));
memcpy(pathbuf, path, strlen(path));
- argv[0] = (char *)pathbuf;
- execve_args.pathname = argv[0];
- execve_args.argv = argv;
+ execve_args.pathname = pathbuf;
+ execve_args.argv = (char **)&args->argv[0];
execve_args.envp = envp;
-
path = NULL;
- dynfree(args);
if (execve(cur, &execve_args) != 0) {
pr_error("execve failed, aborting\n");
@@ -211,19 +214,26 @@ get_child(struct proc *cur, pid_t pid)
/*
* arg0: The file /path/to/executable
- * arg1: Optional flags (`flags')
+ * arg1: Argv
+ * arg2: Envp (TODO)
+ * arg3: Optional flags (`flags')
*/
scret_t
sys_spawn(struct syscall_args *scargs)
{
struct spawn_args *args;
- const char *u_path;
+ char *path;
+ const char *u_path, **u_argv;
+ const char *u_p = NULL;
struct proc *td;
int flags, error;
+ size_t len, bytes_copied = 0;
+ size_t argv_i = 0;
td = this_td();
- flags = scargs->arg1;
u_path = (const char *)scargs->arg0;
+ u_argv = (const char **)scargs->arg1;
+ flags = scargs->arg3;
args = dynalloc(sizeof(*args));
if (args == NULL) {
@@ -236,5 +246,30 @@ sys_spawn(struct syscall_args *scargs)
return error;
}
+ memset(args->argv, 0, ARG_MAX);
+ for (size_t i = 0; i < ARG_MAX - 1; ++i) {
+ error = copyin(&u_argv[argv_i], &u_p, sizeof(u_p));
+ if (error < 0) {
+ dynfree(args);
+ return error;
+ }
+ if (u_p == NULL) {
+ args->argv[argv_i++] = NULL;
+ break;
+ }
+
+ path = &args->argv_blk[i];
+ error = copyinstr(u_p, path, ARG_MAX - bytes_copied);
+ if (error < 0) {
+ dynfree(args);
+ return error;
+ }
+
+ args->argv[argv_i++] = &args->argv_blk[i];
+ len = strlen(path);
+ bytes_copied += (len + 1);
+ i += len;
+ }
+
return spawn(td, spawn_thunk, args, flags, NULL);
}
diff --git a/sys/vm/vm_physmem.c b/sys/vm/vm_physmem.c
index ed9b5d2..89f9ee6 100644
--- a/sys/vm/vm_physmem.c
+++ b/sys/vm/vm_physmem.c
@@ -36,11 +36,12 @@
#include <vm/vm.h>
#include <string.h>
-size_t highest_frame_idx = 0;
-size_t bitmap_size = 0;
-size_t bitmap_free_start = 0;
+static size_t highest_frame_idx = 0;
+static size_t bitmap_size = 0;
+static size_t bitmap_free_start = 0;
+static ssize_t last_idx = 0;
-uint8_t *bitmap;
+static uint8_t *bitmap;
static struct limine_memmap_response *resp = NULL;
static struct spinlock lock = {0};
@@ -137,15 +138,14 @@ physmem_init_bitmap(void)
*
* @count: Number of frames to allocate.
*/
-uintptr_t
-vm_alloc_frame(size_t count)
+static uintptr_t
+__vm_alloc_frame(size_t count)
{
size_t frames = 0;
ssize_t idx = -1;
uintptr_t ret = 0;
- spinlock_acquire(&lock);
- for (size_t i = 0; i < highest_frame_idx; ++i) {
+ for (size_t i = last_idx; i < highest_frame_idx; ++i) {
if (!testbit(bitmap, i)) {
if (idx < 0)
idx = i;
@@ -167,9 +167,24 @@ vm_alloc_frame(size_t count)
for (size_t i = idx; i < idx + count; ++i) {
setbit(bitmap, i);
}
-
ret = idx * DEFAULT_PAGESIZE;
+ last_idx = idx;
+ memset(PHYS_TO_VIRT(ret), 0, count * DEFAULT_PAGESIZE);
done:
+ return ret;
+}
+
+uintptr_t
+vm_alloc_frame(size_t count)
+{
+ uintptr_t ret;
+
+ spinlock_acquire(&lock);
+ if ((ret = __vm_alloc_frame(count)) == 0) {
+ last_idx = 0;
+ ret = __vm_alloc_frame(count);
+ }
+
spinlock_release(&lock);
return ret;
}