diff options
| author | Xavier Del Campo Romero <xavi92@disroot.org> | 2025-07-07 13:22:53 +0200 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi92@disroot.org> | 2025-11-11 00:08:15 +0100 |
| commit | 7861a52adf92a083bb2aed4c35f98d8035dce032 (patch) | |
| tree | 28cd3c40e4c878f730f5df3c1d93bdf91af490c3 /src/init/ps1 | |
| parent | 7fc48e9216ff809da5f8055a50b0be17628ef1df (diff) | |
| download | wnix-7861a52adf92a083bb2aed4c35f98d8035dce032.tar.gz | |
Setup project skeleton
Diffstat (limited to 'src/init/ps1')
| -rw-r--r-- | src/init/ps1/CMakeLists.txt | 37 | ||||
| -rw-r--r-- | src/init/ps1/private_include/init/ps1/types.h | 40 | ||||
| -rw-r--r-- | src/init/ps1/src/CMakeLists.txt | 23 | ||||
| -rw-r--r-- | src/init/ps1/src/boot.c | 251 | ||||
| -rw-r--r-- | src/init/ps1/src/globalvars.c | 21 | ||||
| -rw-r--r-- | src/init/ps1/src/port.c | 30 | ||||
| -rw-r--r-- | src/init/ps1/src/run.c | 27 | ||||
| -rw-r--r-- | src/init/ps1/src/time.c | 47 |
8 files changed, 476 insertions, 0 deletions
diff --git a/src/init/ps1/CMakeLists.txt b/src/init/ps1/CMakeLists.txt new file mode 100644 index 0000000..21df5d7 --- /dev/null +++ b/src/init/ps1/CMakeLists.txt @@ -0,0 +1,37 @@ +# wnix, a Unix-like operating system for WebAssembly applications. +# Copyright (C) 2025 Xavier Del Campo Romero +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +add_library(init_ps1) +add_subdirectory(src) +target_include_directories(init_ps1 PRIVATE private_include) +target_link_libraries(init_ps1 + PUBLIC + c + init + PRIVATE + aio + bin + drv_ps1_bios + drv_ps1_cpu + drv_ps1_irq + drv_ps1_rcnt + drv_ps1_time + iso9660 + kprintf + loop + net + state +) diff --git a/src/init/ps1/private_include/init/ps1/types.h b/src/init/ps1/private_include/init/ps1/types.h new file mode 100644 index 0000000..66702d1 --- /dev/null +++ b/src/init/ps1/private_include/init/ps1/types.h @@ -0,0 +1,40 @@ +/* + * wnix, a Unix-like operating system for WebAssembly applications. + * Copyright (C) 2025 Xavier Del Campo Romero + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#ifndef INIT_PS1_TYPES_H +#define INIT_PS1_TYPES_H + +#include <aio.h> +#include <sys/stat.h> +#include <time.h> + +struct init_ps1 +{ + struct aio *aio; + struct stat *sb; + unsigned retries; + const char *path; + struct timespec last_retry; + int (*next)(struct init_ps1 *); + int (*success)(struct init_ps1 *); + int (*retry)(struct init_ps1 *); +}; + +extern struct init_ps1 init_ps1; + +#endif diff --git a/src/init/ps1/src/CMakeLists.txt b/src/init/ps1/src/CMakeLists.txt new file mode 100644 index 0000000..68dab00 --- /dev/null +++ b/src/init/ps1/src/CMakeLists.txt @@ -0,0 +1,23 @@ +# wnix, a Unix-like operating system for WebAssembly applications. +# Copyright (C) 2025 Xavier Del Campo Romero +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +target_sources(init_ps1 PRIVATE + boot.c + globalvars.c + port.c + run.c + time.c +) diff --git a/src/init/ps1/src/boot.c b/src/init/ps1/src/boot.c new file mode 100644 index 0000000..062078c --- /dev/null +++ b/src/init/ps1/src/boot.c @@ -0,0 +1,251 @@ +/* + * wnix, a Unix-like operating system for WebAssembly applications. + * Copyright (C) 2025 Xavier Del Campo Romero + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include <init.h> +#include <init/ps1/types.h> +#include <aio.h> +#include <bin.h> +#include <iso9660.h> +#include <kprintf.h> +#include <loop.h> +#include <net.h> +#include <fcntl.h> +#include <sys/stat.h> +#include <stdlib.h> +#include <state.h> +#include <time.h> + +struct boot +{ + struct aio *aio; + struct init_ps1 *p; +}; + +enum {RETRIES = 5}; +static const char serial[] = "/dev/ttyS0"; + +static int retry_cd(struct init_ps1 *); + +static int wait_retry(struct init_ps1 *const p) +{ + struct timespec ts; + const time_t last = p->last_retry.tv_sec, timeout = 5; + + if (clock_gettime(CLOCK_REALTIME, &ts)) + return -1; + else if (ts.tv_sec - last >= timeout) + p->next = p->retry; + + return 0; +} + +static int stat_done(const enum state s, void *const args) +{ + int ret = 0; + struct init_ps1 *const p = args; + + if (s) + { + struct timespec ts; + + if (!--p->retries || clock_gettime(CLOCK_REALTIME, &ts)) + { + ret = -1; + goto end; + } + + p->last_retry = ts; + p->next = wait_retry; + } + else + { + p->next = p->success; + kprintf("Successfully initialized %s (took %u attempts)\n", + p->path, RETRIES - p->retries + 1); + } + +end: + loop_rm_aio(p->aio); + aio_free(p->aio); + free(p->sb); + return ret; +} + +static int mount_done(const enum state state, void *const args) +{ + struct boot *const b = args; + + if (loop_rm_aio(b->aio)) + return -1; + + aio_free(b->aio); + free(b); + + if (state) + kprintf("Failed to mount ISO9660 filesystem\n"); + else + { + const char *const args[] = {NULL}; + + kprintf("ISO9660 filesystem mounted successfully\n"); + kprintf("Opening second-stage initd\n"); + + /* TODO: create symbolic from /mnt/cdrom/bin to /bin */ + return bin_exec("/mnt/cdrom/bin/initd", args, 0, 0); + } + + return 0; +} + +static int mount_cd(struct init_ps1 *const p) +{ + struct aio *aio = NULL; + struct boot *const b = malloc(sizeof *b); + + if (!b) + goto failure; + + const struct aio_mount fm = + { + .mount = + { + .src = "/dev/cd0", + .tgt = "/mnt/cdrom", + .mode = 0755 + }, + + .type = "iso9660" + }; + + const struct aio_done d = + { + .args = b, + .f = mount_done + }; + + if (!(aio = aio_mount(&fm, &d)) || loop_add_aio(aio)) + goto failure; + + p->next = NULL; + *b = (const struct boot){.aio = aio, .p = p}; + kprintf("Mounting ISO9660 filesystem from %s to %s\n", + fm.mount.src, fm.mount.tgt); + return 0; + +failure: + kprintf("Failed to mount ISO9660 filesystem\n"); + aio_free(aio); + free(b); + return -1; +} + +static int retry_cd(struct init_ps1 *const p) +{ + static const char path[] = "/dev/cd0"; + struct aio *aio = NULL; + struct stat *const sb = malloc(sizeof *sb); + + if (!sb) + goto failure; + + const struct fs_stat s = {.path = path, .sb = sb}; + const struct aio_done d = {.f = stat_done, .args = p}; + const unsigned retries = p->retries; + + if (!(aio = aio_stat(&s, &d)) || loop_add_aio(aio)) + goto failure; + + *p = (const struct init_ps1) + { + .aio = aio, + .sb = sb, + .path = path, + .retries = retries, + .success = mount_cd, + .last_retry = {.tv_sec = (time_t)-1} + }; + + p->next = NULL; + kprintf("Initializing CD-ROM to %s (attempt %u)\n", path, + RETRIES - p->retries + 1); + return 0; + +failure: + free(aio); + free(sb); + return -1; +} + +static int init_net(struct init_ps1 *const p) +{ + if (net_init(serial)) + return -1; + + p->next = retry_cd; + return 0; +} + +static int retry_serial(struct init_ps1 *const p) +{ + struct aio *aio = NULL; + struct stat *const sb = malloc(sizeof *sb); + + if (!sb) + goto failure; + + const struct fs_stat s = {.path = serial, .sb = sb}; + const struct aio_done d = {.f = stat_done, .args = p}; + const unsigned retries = p->retries; + + if (!(aio = aio_stat(&s, &d)) || loop_add_aio(aio)) + goto failure; + + *p = (const struct init_ps1) + { + .aio = aio, + .sb = sb, + .path = serial, + .retries = retries, + .success = init_net, + .last_retry = {.tv_sec = (time_t)-1} + }; + + p->next = NULL; + kprintf("Initializing serial device to %s (attempt %u)\n", serial, + RETRIES - p->retries + 1); + return 0; + +failure: + free(aio); + free(sb); + return -1; +} + +int init_port_boot(void) +{ + if (iso9660_register()) + return -1; + + init_ps1 = (const struct init_ps1) + { + .retries = RETRIES, + .next = retry_serial + }; + + return 0; +} diff --git a/src/init/ps1/src/globalvars.c b/src/init/ps1/src/globalvars.c new file mode 100644 index 0000000..fcf6a6c --- /dev/null +++ b/src/init/ps1/src/globalvars.c @@ -0,0 +1,21 @@ +/* + * wnix, a Unix-like operating system for WebAssembly applications. + * Copyright (C) 2025 Xavier Del Campo Romero + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include <init/ps1/types.h> + +struct init_ps1 init_ps1; diff --git a/src/init/ps1/src/port.c b/src/init/ps1/src/port.c new file mode 100644 index 0000000..9bc2a8e --- /dev/null +++ b/src/init/ps1/src/port.c @@ -0,0 +1,30 @@ +/* + * wnix, a Unix-like operating system for WebAssembly applications. + * Copyright (C) 2025 Xavier Del Campo Romero + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include <init.h> +#include <drv/ps1/bios.h> +#include <drv/ps1/irq.h> + +int init_port(void) +{ + EnterCriticalSection(); + SetConf(16, 1, (void *)0x801ff800); + ExitCriticalSection(); + + return drv_ps1_irq_init(); +} diff --git a/src/init/ps1/src/run.c b/src/init/ps1/src/run.c new file mode 100644 index 0000000..bc4b645 --- /dev/null +++ b/src/init/ps1/src/run.c @@ -0,0 +1,27 @@ +/* + * wnix, a Unix-like operating system for WebAssembly applications. + * Copyright (C) 2025 Xavier Del Campo Romero + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include <init.h> +#include <init/ps1/types.h> + +int init_port_run(void) +{ + struct init_ps1 *const p = &init_ps1; + + return p->next ? p->next(p) : 0; +} diff --git a/src/init/ps1/src/time.c b/src/init/ps1/src/time.c new file mode 100644 index 0000000..1978945 --- /dev/null +++ b/src/init/ps1/src/time.c @@ -0,0 +1,47 @@ +/* + * wnix, a Unix-like operating system for WebAssembly applications. + * Copyright (C) 2025 Xavier Del Campo Romero + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include <init.h> +#include <init/ps1/types.h> +#include <drv/ps1/bios.h> +#include <drv/ps1/cpu.h> +#include <drv/ps1/rcnt.h> +#include <drv/ps1/time.h> +#include <time.h> + +int init_time(void) +{ + struct timespec ts; + const union drv_ps1_rcnt_cfg cfg = + { + .bits = + { + .reset = 1, + .repeat = 1, + .irq_tgt = 1, + .clocksrc = 3 + } + }; + + if (clock_getres(CLOCK_REALTIME, &ts)) + return -1; + + const uint16_t target = (DRV_PS1_CPU_F / 8) / (ts.tv_nsec / 1000); + + return drv_ps1_rcnt_init(DRV_PS1_RCNT2, target, &cfg, drv_ps1_time_tick); +} |
