__pycache__
.config.json
-.builder
\ No newline at end of file
+.builder
+
+.vscode
\ No newline at end of file
+++ /dev/null
-{
- "configurations": [
- {
- "name": "OS-DEV",
- "includePath": [
- "${workspaceFolder}/includes",
- "${workspaceFolder}/includes/usr",
- "${workspaceFolder}/usr/includes",
- "${workspaceFolder}/arch/x86/includes",
- ],
- "compilerArgs": [
- "-ffreestanding",
- "-m32",
- "-include .builder/configs.h"
- ],
- "defines": [],
- "compilerPath": "/usr/bin/gcc",
- "cStandard": "gnu99",
- "intelliSenseMode": "gcc-x86"
- },
- {
- "name": "OS-DEV64",
- "includePath": [
- "${workspaceFolder}/includes",
- "${workspaceFolder}/includes/usr",
- "${workspaceFolder}/usr/includes",
- "${workspaceFolder}/arch/x86/includes",
- ],
- "compilerArgs": [
- "-ffreestanding",
- "-m64",
- "-include .builder/configs.h"
- ],
- "defines": [],
- "compilerPath": "/usr/bin/gcc",
- "cStandard": "gnu99",
- "intelliSenseMode": "gcc-x86"
- }
- ],
- "version": 4
-}
\ No newline at end of file
+++ /dev/null
-{
- // 使用 IntelliSense 了解相关属性。
- // 悬停以查看现有属性的描述。
- // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
- "version": "0.2.0",
- "configurations": [
- {
- "type": "gdb",
- "request": "attach",
- "name": "LunaixOS",
- "executable": "${workspaceRoot}/build/bin/kernel.bin",
- "target": ":1234",
- "remote": true,
- "cwd": "${workspaceRoot}",
- "valuesFormatting": "parseText",
- "preLaunchTask": "Launch LunaixOS"
- }
- ]
-}
\ No newline at end of file
+++ /dev/null
-{
- "version": "2.0.0",
- "tasks": [
- {
- "label": "Launch LunaixOS",
- "type": "shell",
- "command": "make debug-qemu-vscode",
- "isBackground": true,
- "problemMatcher": {
- "background": {
- "activeOnStart": true,
- "endsPattern": "^\\(qemu\\).*"
- }
- }
- }
- ]
-}
\ No newline at end of file
+use("generic")
+
use({
config("arch"): {
"i386": "x86",
This document briefly describe how to add support for other ISA
-## Adding Implementations
+## Introduction
-Lunaix provide bunch of headers that **MUST** be implemented.
+As of most modern operating system, Lunaix's abstraction layer allow
+a clean separation between regular kernel code and the
+architecture specific code, these parts defined as follow:
+ + kernel code: Provide the functionality of a kernel that do not assume
+ anything other than the kernel basic service and feature. This part of
+ code is thus said to be architecture-agnostic.
+ + architecture specific code: Provide implementation of low-level operations
+ or features required by the aforementioned kernel kernel basic service and
+ feature for them to function normally and expected.
-+ Follow the structure and derive the template header files according to
- `arch/generic/includes`.
- ! You **MUST** copy the header file and add your own
- declaration & other stuffs.
- ! You **MUST NOT** remove or modify the data structure,
- function signature or any declaration that already in the template header
- files unless stated explicitly.
- ! Read the comment carefully, it may contains implementation recommendation
- which is vital to the overall correctness.
+## General Structure
-+ Add implementation to function signature defined in header files under
- `includes/lunaix/generic`
+Each architectural support is housed under the directory of
+their respective name. For example, all support for x86 is
+placed under `x86/`.
-+ Add implementation of syscall dispatching (Reference: `arhc/x86/syscall.S`)
+Aside from this, a special architecture
+called `generic` is defined, which designed to be a fallback
+option for any features/operations that are not being implemented or does not required to be implemented in architecture-specific way. However, not all feature/operations
+have their respective fallback; In that case, presence of architectural support for these features/operations are mandatory.
-+ Add implementation of interrupt handler dispatching (Reference:
- `arhc/x86/exceptions/intrhnds.S`)
+Regardless, a typical architecture support must be a valid derivation of the following subdirectory layout:
-+ Add implementation of context switching, signal handling. (Reference:
- `arhc/x86/exceptions/interrupt.S`)
- **TODO: make this procedure more standalone**
+```
+<arch>/
+ includes/
+ asm/
+ linking/
+ sys/
+ ...
+ (anything you want)
+```
-## Preparing the Flows
+where:
-When system boot up, Lunaix start the execution from `start_`, and then the
-control flow will transfer to the `kinit.c::kernel_bootstrap`. A boot hand-over
-context `struct boot_handoff*` must passed to the bootstrap procedure.
+ + `asm` define all assembly level headers. These header is
+ typically designated to perform low-level architectural
+ tasks such as register manipulation, MMU/TLB
+ maintainance, SoC resource managment, or context saving/restoring.
+ + `sys` define all headers that is related to some kernel
+ service. These services, similar but unlike the **regular kernel code**, require architectural support or
+ optimisation. For example, syscall interfacing or cpu state dumping for debugging purpose.
+ + `linking` contain linker scripts that describe the linking
+ procedure for linking the architectural support with other subsystem such that a valid kernel binary can be produced. There is no limit on how many linker script can be put under it, however, only one specific linker script will be taken into account when linking, more detail as follow.
-Before jumping to `kernel_bootstrap`, one
+An implementation is required to follow this structure and must implement all mandatory header file, as described in the following section.
-+ Must constructure a proper `struct boot_handoff` context.
-+ Must remap the kernel to architecturally favoured address range.
- **TODO: the algorithm for doing kernel remapping should be arch-agnostic**
-+ Must perform any essential CPU statet initialization, for example, setting up
- address translation scheme, enable/disable ISA extensions, probing CPU/SOC
- features.
-## Alternative Implementation
+## Implementation
+
+### Mandatory and Optional Features
+
+Lunaix provide bunch of headers that **MUST** be implemented in order to behave correctly.
+
+```
+includes/asm/cpu.h
+includes/asm-generic/isrm.h
+includes/asm/muldiv64.h
+includes/asm/hart.h
+includes/asm/mempart.h
+includes/asm/abi.h
+includes/asm/tlb.h
+includes/asm/pagetable.h
+
+includes/sys/syscall_utils.h
+includes/sys/failsafe.h
+includes/sys/gdbstub.h
+includes/sys-generic/elf.h
+```
+
+An implementation should copy these file out of `arch/x86`, replacing any `x86` specific function-body/structure-members/macros with the chosen architecture.
+
+Most headers located under `generic/` has default implementation and is designed to eliminate common code. The defaults can be optionally override, except for those with `fail()` as their only definition or those listed in above.
+
+### Preparing Linker Script
+
+Lunaix use CC's preprocessing system on creating modularised linker script. Such linker scripts in denoted with 'ldx' as extension in contrast to the genuine one.
+
+There is no limit on the number of linker scripts present. However, the following list the mandatory linker scripts required for an architectural support, as these scripts are referenced by the main script.
+
++ `base_defs.ld.inc` Define the macros related to kernel
+ binary structure, the following macros are mandatory:
+ + `LOAD_OFF` base physical address of kernel when loaded into memory by firmware.
+ + `PAGE_GRAN` base page granule, used for section alignment
+ + `ENTRY_POINT` the entry point of kernel, where the firmware-kernel hand-off happened.
+ + `KEXEC_BASE` base virtual address of kernel, this define the boundary of kernel and user space.
++ `boot_secs.ldx` Define the sections used by boot code, these section should be normally used without virtual address relocation. **Important: Implementation must not define variable-sized section such as .bss**
+
+### Booting and Initialising
+
+Lunaix will always start the execution from entry point defined by `ENTRY_POINT` (see above section). A boot protocol might be invoked as earlier as possible in this stage. Such protocol defines the format and method to perform message exchange when firmware hand-over the control to the kernel. It is the implementation's responsibility for to decide whether such protocol is necessary and implement it accordingly.
+
+After the completion of architectural tasks defined in boot stage, implementation must hand-over the control to the architecture-agnostic kernel entry-point: `kernel_bootstrap`, together with the an architecture-agnostically defined boot message structure: `struct boot_handoff` as the only parameter taken by the entry-point. In this structure, the implementation must provide **either** the following information:
+
+1. `mem` sub-structure and pointer and length to the kernel command-line raw string.
+2. `dtb_pa`, physical pointer to the devicetree blob (dtb) placed in memory. Fields stated in #1 will be ignored if `dtb_pa` is non-zero.
+
+Implementation may also provide callback to `release` and `prepare` function pointer. Where the implementation-defined action can be performed before and after the kernel initialisation.
+
+### System-on-Chip Resources
+
+Most of the SoC resources such as interrupt controller can be abstracted away by some mandatory headers defined in `asm/`, or as a regular device driver integrated into the Lunaix device subsystem. However, not all SoC resources can be fit into the said framework. The following list the such resources:
+
++ **System Timer**
+
+### Architectural Optimisation on klibc
Most functions in `klibc` can be override by an architectural port. To achieve
this, one just need to add definition of such function. This allow port to
--- /dev/null
+headers("includes")
+
+sources([
+ "bootmem.c",
+ "trace.c",
+ "vmutils.c",
+ "procvm.c",
+ "arch.c",
+])
\ No newline at end of file
-#include <lunaix/spike.h>
#include <hal/hwtimer.h>
+#include <lunaix/spike.h>
-struct hwtimer*
+_default struct hwtimer*
select_platform_timer()
{
- fail("unimplemented");
+ fail("not implemented");
}
\ No newline at end of file
-#include <lunaix/generic/bootmem.h>
+#include <sys-generic/bootmem.h>
#include <lunaix/sections.h>
#include <lunaix/spike.h>
static reclaimable char bootmem_pool[BOOTMEM_SIZE];
static unsigned int pos;
-void*
+_default void*
bootmem_alloc(unsigned int size)
{
ptr_t res;
pos += size;
if (pos >= BOOTMEM_SIZE) {
- asm ("ud2");
+ spin();
unreachable;
}
return (void*)res;
}
-void
+_default void
bootmem_free(void* ptr)
{
// not need to support, as they are all one-shot
+++ /dev/null
-#include <lunaix/process.h>
-#include <lunaix/hart_state.h>
-#include <lunaix/mm/vmm.h>
-#include <klibc/string.h>
-
-bool
-install_hart_transition(ptr_t vm_mnt, struct hart_transition* tctx)
-{
- return false;
-}
-
-void
-hart_prepare_transition(struct hart_transition* tctx,
- ptr_t kstack_tp, ptr_t ustack_pt,
- ptr_t entry, bool to_user)
-{
- fail("unimplemented");
-}
\ No newline at end of file
--- /dev/null
+#ifndef __LUNAIX_ARCH_MULDIV64_H
+#define __LUNAIX_ARCH_MULDIV64_H
+
+#include <lunaix/types.h>
+
+#ifdef CONFIG_ARCH_BITS_64
+static inline u64_t
+udiv64(u64_t n, unsigned int base)
+{
+ return n / base;
+}
+
+static inline unsigned int
+umod64(u64_t n, unsigned int base)
+{
+ return n % base;
+}
+#else
+#error "no generic muldiv64 for 32 bits arch"
+#endif
+
+
+#endif /* __LUNAIX_ARCH_MULDIV64_H */
-#ifndef __LUNAIX_ARCH_ELF_H
-#define __LUNAIX_ARCH_ELF_H
+#ifndef __LUNAIX_ARCH_GENERIC_ELF_H
+#define __LUNAIX_ARCH_GENERIC_ELF_H
#include <lunaix/types.h>
#define ELFDATA2LSB 1
#define ELFDATA2MSB 2
-#ifdef CONFIG_ARCH_X86_64
+#ifdef CONFIG_ARCH_BITS_64
typedef unsigned long elf_ptr_t;
typedef unsigned short elf_hlf_t;
typedef unsigned long elf_off_t;
struct elf_phdr
{
-#ifdef CONFIG_ARCH_X86_64
+#ifdef CONFIG_ARCH_BITS_64
elf_wrd_t p_type;
elf_wrd_t p_flags;
elf_off_t p_offset;
#endif
};
-#endif /* __LUNAIX_ARCH_ELF_H */
+#endif /* __LUNAIX_ARCH_GENERIC_ELF_H */
void
trace_dump_state(struct hart_state* hstate);
-
#endif /* __LUNAIX_TRACE_ARCH_H */
+++ /dev/null
-#ifndef __LUNAIX_ARCH_ABI_H
-#define __LUNAIX_ARCH_ABI_H
-
-#include <lunaix/types.h>
-
-#define stack_alignment 0
-
-#ifndef __ASM__
-#define align_stack(ptr) ((ptr) & stack_alignment)
-#define store_retval(retval) (void)
-
-#define store_retval_to(th, retval) (void)
-
-static inline void must_inline noret
-j_usr(ptr_t sp, ptr_t pc)
-{
-
-}
-
-
-static inline void must_inline noret
-switch_context() {
- unreachable;
-}
-
-#define push_arg1(stack_ptr, arg) (void)
-
-#define push_arg2(stack_ptr, arg1, arg2) \
- { }
-
-#define push_arg3(stack_ptr, arg1, arg2, arg3) \
- { }
-
-#define push_arg4(stack_ptr, arg1, arg2, arg3, arg4) \
- { }
-
-
-static inline ptr_t must_inline
-abi_get_callframe()
-{
- return 0;
-}
-
-static inline ptr_t
-abi_get_retaddr()
-{
- return 0;
-}
-
-static inline ptr_t
-abi_get_retaddrat(ptr_t fp)
-{
- return 0;
-}
-
-#endif
-#endif /* __LUNAIX_ABI_H */
-
+++ /dev/null
-#ifndef __LUNAIX_CPU_H
-#define __LUNAIX_CPU_H
-
-#include <lunaix/types.h>
-
-/**
- * @brief Get processor ID string
- *
- * @param id_out
- */
-void
-cpu_get_id(char* id_out);
-
-void
-cpu_trap_sched();
-
-void
-cpu_trap_panic(char* message);
-
-
-/**
- * @brief Load current processor state
- *
- * @return ptr_t
- */
-ptr_t
-cpu_ldstate();
-
-/**
- * @brief Load current processor config
- *
- * @return ptr_t
- */
-ptr_t
-cpu_ldconfig();
-
-/**
- * @brief Change current processor state
- *
- * @return ptr_t
- */
-void
-cpu_chconfig(ptr_t val);
-
-/**
- * @brief Change current virtual memory space
- *
- * @return ptr_t
- */
-void
-cpu_chvmspace(ptr_t val);
-
-void
-cpu_enable_interrupt();
-
-void
-cpu_disable_interrupt();
-
-void
-cpu_wait();
-
-/**
- * @brief Read exeception address
- *
- * @return ptr_t
- */
-ptr_t
-cpu_ldeaddr();
-
-
-#endif /* __LUNAIX_CPU_H */
+++ /dev/null
-#ifndef __LUNAIX_FAILSAFE_H
-#define __LUNAIX_FAILSAFE_H
-
-#define STACK_SANITY 0xbeefc0de
-
-#ifndef __ASM__
-
-#include <lunaix/types.h>
-
-static inline bool
-check_bootstack_sanity()
-{
- return true;
-}
-
-static inline void must_inline noret
-failsafe_diagnostic() {
- unreachable;
-}
-
-#endif
-
-#endif /* __LUNAIX_FAILSAFE_H */
+++ /dev/null
-#ifndef __LUNAIX_ARCH_GDBSTUB_ARCH_H
-#define __LUNAIX_ARCH_GDBSTUB_ARCH_H
-
-#include "sys/hart.h"
-
-enum GDB_REGISTER
-{
- // TODO add your registers
- GDB_CPU_NUM_REGISTERS
-};
-
-struct gdb_state;
-
-void
-arch_gdbstub_setup_state(struct gdb_state* state, struct hart_state* hstate);
-
-void
-arch_gdbstub_save_regs(struct gdb_state* state, struct hart_state* hstate);
-
-void
-arch_gdbstub_restore_regs(struct gdb_state* state, struct hart_state* hstate);
-
-int
-gdb_sys_continue(struct gdb_state* state);
-
-int
-gdb_sys_step(struct gdb_state* state);
-
-#endif /* __LUNAIX_ARCH_GDBSTUB_ARCH_H */
\ No newline at end of file
+++ /dev/null
-#ifndef __LUNAIX_ARCH_HART_H
-#define __LUNAIX_ARCH_HART_H
-
-#ifndef __ASM__
-#include <lunaix/compiler.h>
-#include <sys/cpu.h>
-
-struct exec_param;
-
-struct regcontext
-{
-
-} compact;
-
-struct hart_state
-{
-
-} compact;
-
-struct exec_param
-{
- struct hart_state* parent_state;
-} compact;
-
-ptr_t
-hart_pc(struct hart_state* state);
-
-ptr_t
-hart_sp(struct hart_state* state);
-
-bool
-kernel_context(struct hart_state* hstate);
-
-ptr_t
-hart_stack_frame(struct hart_state* hstate);
-
-int
-hart_vector_stamp(struct hart_state* hstate);
-
-unsigned int
-hart_ecause(struct hart_state* hstate);
-
-struct hart_state*
-hart_parent_state(struct hart_state* hstate);
-
-void
-hart_push_state(struct hart_state* p_hstate, struct hart_state* hstate);
-
-#endif
-
-#endif /* __LUNAIX_ARCH_HART_H */
+++ /dev/null
-#ifndef __LUNAIX_ARCH_MEMORY_H
-#define __LUNAIX_ARCH_MEMORY_H
-
-#include <lunaix/mm/pagetable.h>
-#include <lunaix/mann_flags.h>
-
-static inline pte_attr_t
-translate_vmr_prot(unsigned int vmr_prot)
-{
- return 0;
-}
-
-
-#endif /* __LUNAIX_ARCH_MEMORY_H */
+++ /dev/null
-#ifndef __LUNAIX_ARCH_MEMPART_H
-#define __LUNAIX_ARCH_MEMPART_H
-
-
-#define END_POINT(name) (name + name##_SIZE - 1)
-
-#define KSTACK_AREA 0
-#define KSTACK_AREA_SIZE 0
-#define KSTACK_AREA_END END_POINT(KSTACK_AREA)
-
-#define USR_EXEC 0
-#define USR_EXEC_SIZE 0
-#define USR_EXEC_END END_POINT(USR_EXEC)
-
-#define USR_MMAP 0
-#define USR_MMAP_SIZE 0
-#define USR_MMAP_END END_POINT(USR_MMAP)
-
-#define USR_STACK 0
-#define USR_STACK_SIZE 0
-#define USR_STACK_END END_POINT(USR_STACK)
-
-#define KERNEL_IMG 0
-#define KERNEL_IMG_SIZE 0
-#define KERNEL_IMG_END END_POINT(KERNEL_IMG)
-
-#define PG_MOUNT_1 0
-#define PG_MOUNT_1_SIZE 0
-#define PG_MOUNT_1_END END_POINT(PG_MOUNT_1)
-
-#define PG_MOUNT_2 0
-#define PG_MOUNT_2_SIZE 0
-#define PG_MOUNT_2_END END_POINT(PG_MOUNT_2)
-
-#define PG_MOUNT_3 0
-#define PG_MOUNT_3_SIZE 0
-#define PG_MOUNT_3_END END_POINT(PG_MOUNT_3)
-
-#define PG_MOUNT_4 0
-#define PG_MOUNT_4_SIZE 0
-#define PG_MOUNT_4_END END_POINT(PG_MOUNT_4)
-
-#define PG_MOUNT_VAR 0
-#define PG_MOUNT_VAR_SIZE 0
-#define PG_MOUNT_VAR_END END_POINT(PG_MOUNT_VAR)
-
-#define VMAP 0
-#define VMAP_SIZE 0
-#define VMAP_END END_POINT(VMAP)
-
-#define VMS_MOUNT_1 0
-#define VMS_MOUNT_1_SIZE 0
-#define VMS_MOUNT_1_END END_POINT(VMS_MOUNT_1)
-
-#endif
+++ /dev/null
-#ifndef __LUNAIX_MM_DEFS_H
-#define __LUNAIX_MM_DEFS_H
-
-
-#include "mempart.h"
-#include "pagetable.h"
-
-#define KSTACK_PAGES 3
-#define KSTACK_SIZE (KSTACK_PAGES * PAGE_SIZE)
-
-/*
- Regardless architecture we need to draw the line very carefully, and must
- take the size of VM into account. In general, we aims to achieve
- "sufficiently large" of memory for kernel
-
- In terms of x86_32:
- * #768~1022 PTEs of PD (0x00000000c0000000, ~1GiB)
-
- In light of upcomming x86_64 support (for Level 4&5 Paging):
- * #510 entry of PML4 (0x0000ff0000000000, ~512GiB)
- * #510 entry of PML5 (0x01fe000000000000, ~256TiB)
-*/
-// Where the kernel getting re-mapped.
-#define KERNEL_RESIDENT 0x0
-
-// Pages reserved for kernel image
-#define KEXEC_RSVD 16
-
-#define kernel_addr(addr) (addr)
-
-#define to_kphysical(k_va) ((ptr_t)(k_va))
-#define to_kvirtual(k_pa) ((ptr_t)(k_pa))
-
-#endif /* __LUNAIX_MM_DEFS_H */
+++ /dev/null
-/**
- * @file pagetable.h
- * @author Lunaixsky (lunaxisky@qq.com)
- * @brief Generic (skeleton) definition for pagetable.h
- * @version 0.1
- * @date 2024-02-18
- *
- * @copyright Copyright (c) 2024
- *
- */
-
-#ifndef __LUNAIX_ARCH_PAGETABLE_H
-#define __LUNAIX_ARCH_PAGETABLE_H
-
-#include <lunaix/types.h>
-#include <lunaix/compiler.h>
-
-/* ******** Page Table Manipulation ******** */
-
-// Levels of page table to traverse for a single page walk
-#define _PTW_LEVEL 2
-
-#define _PAGE_BASE_SHIFT 12
-#define _PAGE_BASE_SIZE ( 1UL << _PAGE_BASE_SHIFT )
-#define _PAGE_BASE_MASK ( _PAGE_BASE_SIZE - 1)
-
-#define _PAGE_LEVEL_SHIFT 10
-#define _PAGE_LEVEL_SIZE ( 1UL << _PAGE_LEVEL_SHIFT )
-#define _PAGE_LEVEL_MASK ( _PAGE_LEVEL_SIZE - 1 )
-#define _PAGE_Ln_SIZE(n) ( 1UL << (_PAGE_BASE_SHIFT + _PAGE_LEVEL_SHIFT * (_PTW_LEVEL - (n) - 1)) )
-
-// Note: we set VMS_SIZE = VMS_MASK as it is impossible
-// to express 4Gi in 32bit unsigned integer
-
-#define VMS_MASK ( -1UL )
-#define VMS_SIZE VMS_MASK
-
-/* General size of a LnT huge page */
-
-#define L0T_SIZE _PAGE_Ln_SIZE(0)
-#define L1T_SIZE _PAGE_Ln_SIZE(1)
-#define L2T_SIZE _PAGE_Ln_SIZE(1)
-#define L3T_SIZE _PAGE_Ln_SIZE(1)
-#define LFT_SIZE _PAGE_Ln_SIZE(1)
-
-/* General mask to get page offset of a LnT huge page */
-
-#define L0T_MASK ( L0T_SIZE - 1 )
-#define L1T_MASK ( L1T_SIZE - 1 )
-#define L2T_MASK ( L2T_SIZE - 1 )
-#define L3T_MASK ( L3T_SIZE - 1 )
-#define LFT_MASK ( LFT_SIZE - 1 )
-
-/* Masks to get index of a LnTE */
-
-#define L0T_INDEX_MASK ( VMS_MASK ^ L0T_MASK )
-#define L1T_INDEX_MASK ( L0T_MASK ^ L1T_MASK )
-#define L2T_INDEX_MASK ( L1T_MASK ^ L2T_MASK )
-#define L3T_INDEX_MASK ( L2T_MASK ^ L3T_MASK )
-#define LFT_INDEX_MASK ( L3T_MASK ^ LFT_MASK )
-
-#define PAGE_SHIFT _PAGE_BASE_SHIFT
-#define PAGE_SIZE _PAGE_BASE_SIZE
-#define PAGE_MASK _PAGE_BASE_MASK
-
-#define LEVEL_SHIFT _PAGE_LEVEL_SHIFT
-#define LEVEL_SIZE _PAGE_LEVEL_SIZE
-#define LEVEL_MASK _PAGE_LEVEL_MASK
-
-// max PTEs number
-#define MAX_PTEN _PAGE_LEVEL_SIZE
-
-// max translation level supported
-#define MAX_LEVEL _PTW_LEVEL
-
-
-/* ******** PTE Manipulation ******** */
-
-struct __pte {
- unsigned int val;
-} align(4);
-
-#ifndef pte_t
-typedef struct __pte pte_t;
-#endif
-
-typedef unsigned int pfn_t;
-typedef unsigned int pte_attr_t;
-
-#define _PTE_P (0)
-#define _PTE_W (0)
-#define _PTE_U (0)
-#define _PTE_A (0)
-#define _PTE_D (0)
-#define _PTE_X (0)
-#define _PTE_R (0)
-
-#define _PTE_PROT_MASK ( _PTE_W | _PTE_U | _PTE_X )
-
-#define KERNEL_PAGE ( _PTE_P )
-#define KERNEL_EXEC ( KERNEL_PAGE | _PTE_X )
-#define KERNEL_DATA ( KERNEL_PAGE | _PTE_W )
-#define KERNEL_RDONLY ( KERNEL_PAGE )
-
-#define USER_PAGE ( _PTE_P | _PTE_U )
-#define USER_EXEC ( USER_PAGE | _PTE_X )
-#define USER_DATA ( USER_PAGE | _PTE_W )
-#define USER_RDONLY ( USER_PAGE )
-
-#define SELF_MAP ( KERNEL_DATA | _PTE_WT | _PTE_CD )
-
-#define __mkpte_from(pte_val) ((pte_t){ .val = (pte_val) })
-#define __MEMGUARD 0xdeadc0deUL
-
-#define null_pte ( __mkpte_from(0) )
-#define guard_pte ( __mkpte_from(__MEMGUARD) )
-#define pte_val(pte) ( pte.val )
-
-
-static inline bool
-pte_isguardian(pte_t pte)
-{
- return pte.val == __MEMGUARD;
-}
-
-static inline pte_t
-mkpte_prot(pte_attr_t prot)
-{
- return null_pte;
-}
-
-static inline pte_t
-mkpte(ptr_t paddr, pte_attr_t prot)
-{
- return null_pte;
-}
-
-static inline pte_t
-mkpte_root(ptr_t paddr, pte_attr_t prot)
-{
- return null_pte;
-}
-
-static inline pte_t
-mkpte_raw(unsigned long pte_val)
-{
- return null_pte;
-}
-
-static inline pte_t
-pte_setpaddr(pte_t pte, ptr_t paddr)
-{
- return pte;
-}
-
-static inline ptr_t
-pte_paddr(pte_t pte)
-{
- return 0;
-}
-
-static inline pte_t
-pte_setprot(pte_t pte, ptr_t prot)
-{
- return pte;
-}
-
-static inline pte_attr_t
-pte_prot(pte_t pte)
-{
- return 0;
-}
-
-static inline bool
-pte_isnull(pte_t pte)
-{
- return !pte.val;
-}
-
-static inline pte_t
-pte_mkhuge(pte_t pte)
-{
- return pte;
-}
-
-static inline pte_t
-pte_mkvolatile(pte_t pte)
-{
- return pte;
-}
-
-static inline pte_t
-pte_mkroot(pte_t pte)
-{
- return pte;
-}
-
-static inline pte_t
-pte_usepat(pte_t pte)
-{
- return pte;
-}
-
-static inline bool
-pte_huge(pte_t pte)
-{
- return false;
-}
-
-static inline pte_t
-pte_mkloaded(pte_t pte)
-{
- return pte;
-}
-
-static inline pte_t
-pte_mkunloaded(pte_t pte)
-{
- return pte;
-}
-
-static inline bool
-pte_isloaded(pte_t pte)
-{
- return false;
-}
-
-static inline pte_t
-pte_mkwprotect(pte_t pte)
-{
- return pte;
-}
-
-static inline pte_t
-pte_mkwritable(pte_t pte)
-{
- return pte;
-}
-
-static inline bool
-pte_iswprotect(pte_t pte)
-{
- return false;
-}
-
-static inline pte_t
-pte_mkuser(pte_t pte)
-{
- return pte;
-}
-
-static inline pte_t
-pte_mkkernel(pte_t pte)
-{
- return pte;
-}
-
-static inline bool
-pte_allow_user(pte_t pte)
-{
- return false;
-}
-
-static inline pte_t
-pte_mkexec(pte_t pte)
-{
- return pte;
-}
-
-static inline pte_t
-pte_mknonexec(pte_t pte)
-{
- return pte;
-}
-
-static inline bool
-pte_isexec(pte_t pte)
-{
- return false;
-}
-
-static inline pte_t
-pte_mkuntouch(pte_t pte)
-{
- return pte;
-}
-
-static inline bool
-pte_istouched(pte_t pte)
-{
- return false;
-}
-
-static inline pte_t
-pte_mkclean(pte_t pte)
-{
- return pte;
-}
-
-static inline bool
-pte_dirty(pte_t pte)
-{
- return false;
-}
-
-static inline void
-set_pte(pte_t* ptep, pte_t pte)
-{
- ptep->val = pte.val;
-}
-
-static inline pte_t
-pte_at(pte_t* ptep) {
- return *ptep;
-}
-
-
-#endif /* __LUNAIX_ARCH_PAGETABLE_H */
+++ /dev/null
-#ifndef __LUNAIX_ARCH_PHYSICAL_H
-#define __LUNAIX_ARCH_PHYSICAL_H
-
-#include <lunaix/ds/llist.h>
-#include "mm_defs.h"
-
-#define PPLIST_STARTVM VMAP
-
-struct ppage_arch
-{
-
-};
-
-#endif /* __LUNAIX_ARCH_PHYSICAL_H */
\ No newline at end of file
+++ /dev/null
-#ifndef __LUNAIX_ARCH_TLB_H
-#define __LUNAIX_ARCH_TLB_H
-
-#include <lunaix/compiler.h>
-#include <lunaix/mm/procvm.h>
-#include <lunaix/mm/physical.h>
-
-/**
- * @brief Invalidate entries of all address spaces
- *
- * @param asid
- * @param addr
- * @param npages
- */
-void
-tlb_flush_range(ptr_t addr, unsigned int npages);
-
-/**
- * @brief Invalidate entries of an address space identified
- * by ASID
- *
- * @param asid
- * @param addr
- * @param npages
- */
-void
-tlb_flush_asid_range(unsigned int asid, ptr_t addr, unsigned int npages);
-
-/**
- * @brief Invalidate an entry of kernel address spaces
- *
- * @param asid
- * @param addr
- * @param npages
- */
-void
-tlb_flush_kernel(ptr_t addr);
-
-/**
- * @brief Invalidate entries of kernel address spaces
- *
- * @param asid
- * @param addr
- * @param npages
- */
-void
-tlb_flush_kernel_ranged(ptr_t addr, unsigned int npages);
-
-/**
- * @brief Invalidate an entry within a process memory space
- *
- * @param asid
- * @param addr
- * @param npages
- */
-void
-tlb_flush_mm(struct proc_mm* mm, ptr_t addr);
-
-/**
- * @brief Invalidate entries within a process memory space
- *
- * @param asid
- * @param addr
- * @param npages
- */
-void
-tlb_flush_mm_range(struct proc_mm* mm, ptr_t addr, unsigned int npages);
-
-/**
- * @brief Invalidate an entry within a vm region
- *
- * @param asid
- * @param addr
- * @param npages
- */
-void
-tlb_flush_vmr(struct mm_region* vmr, ptr_t va);
-
-/**
- * @brief Invalidate all entries within a vm region
- *
- * @param asid
- * @param addr
- * @param npages
- */
-void
-tlb_flush_vmr_all(struct mm_region* vmr);
-
-/**
- * @brief Invalidate entries within a vm region
- *
- * @param asid
- * @param addr
- * @param npages
- */
-void
-tlb_flush_vmr_range(struct mm_region* vmr, ptr_t addr, unsigned int npages);
-
-#endif /* __LUNAIX_VMTLB_H */
+++ /dev/null
-#ifndef __LUNAIX_ARCH_MULDIV64_H
-#define __LUNAIX_ARCH_MULDIV64_H
-
-
-#include <lunaix/spike.h>
-#include <lunaix/types.h>
-
-u64_t
-udiv64(u64_t n, unsigned int base);
-
-unsigned int
-umod64(u64_t n, unsigned int base);
-
-
-#endif /* __LUNAIX_ARCH_MULDIV64_H */
+++ /dev/null
-#ifndef __LUNAIX_ARCH_PORT_IO_H
-#define __LUNAIX_ARCH_PORT_IO_H
-
-#include <lunaix/types.h>
-
-static inline u8_t
-port_rdbyte(int port)
-{
- return 0;
-}
-
-static inline void
-port_rdbytes(int port, void* addr, int cnt)
-{
- return;
-}
-
-static inline u16_t
-port_rdword(int port)
-{
- return 0;
-}
-
-static inline void
-port_rdwords(int port, void* addr, int cnt)
-{
- asm volatile("cld\n"
- "repne\n"
- "insw"
- : "=D"(addr), "=c"(cnt)
- : "d"(port), "0"(addr), "1"(cnt)
- : "memory", "cc");
-}
-
-static inline u32_t
-port_rddword(int port)
-{
- return 0;
-}
-
-static inline void
-port_rddwords(int port, void* addr, int cnt)
-{
- return;
-}
-
-static inline void
-port_wrbyte(int port, u8_t data)
-{
- return;
-}
-
-static inline void
-port_wrbytes(int port, const void* addr, int cnt)
-{
- return;
-}
-
-static inline void
-port_wrword(int port, u16_t data)
-{
- return;
-}
-
-static inline void
-port_wrwords(int port, const void* addr, int cnt)
-{
- return;
-}
-
-static inline void
-port_wrdwords(int port, const void* addr, int cnt)
-{
- return;
-}
-
-static inline void
-port_wrdword(int port, u32_t data)
-{
- return;
-}
-
-static inline void
-port_delay(int counter)
-{
- return;
-}
-
-#endif /* __LUNAIX_ARCH_PORT_IO_H */
+++ /dev/null
-#ifndef __LUNAIX_ARCH_TRACE_H
-#define __LUNAIX_ARCH_TRACE_H
-
-#include <lunaix/types.h>
-
-static inline bool
-arch_valid_fp(ptr_t ptr) {
- return false;
-}
-
-#endif /* __LUNAIX_ARCH_TRACE_H */
+++ /dev/null
-#include <lunaix/mm/fault.h>
-
-bool
-__arch_prepare_fault_context(struct fault_context* fault)
-{
- return false;
-}
\ No newline at end of file
--- /dev/null
+#include <lunaix/mm/procvm.h>
+#include <lunaix/mm/pagetable.h>
+#include <lunaix/mm/page.h>
+
+_default void
+procvm_link_kernel(ptr_t dest_mnt)
+{
+ pte_t *ptep_smx, *src_smx;
+ struct leaflet* leaflet;
+ unsigned int i;
+
+ i = va_level_index(KERNEL_RESIDENT, L0T_SIZE);
+ ptep_smx = mkl1tep_va(VMS_SELF, dest_mnt);
+ src_smx = mkl0tep_va(VMS_SELF, 0);
+
+ for (; i < LEVEL_SIZE; i++)
+ {
+ pte_t* ptep = &ptep_smx[i];
+ pte_t pte = pte_at(&src_smx[i]);
+ if (lntep_implie_vmnts(ptep, L0T_SIZE)) {
+ continue;
+ }
+
+ // sanity check
+ leaflet = pte_leaflet_aligned(pte);
+ assert(leaflet_refcount(leaflet) > 0);
+
+ set_pte(ptep, pte);
+ }
+}
+
+_default void
+procvm_unlink_kernel()
+{
+ // nothing to do here.
+}
\ No newline at end of file
--- /dev/null
+#include <lunaix/trace.h>
+
+#include <sys-generic/trace_arch.h>
+
+_default void
+trace_print_transistion_short(struct hart_state* hstate)
+{
+ trace_log("<not implemented>");
+}
+
+_default void
+trace_print_transition_full(struct hart_state* hstate)
+{
+ trace_log("<not implemented>");
+}
+
+_default void
+trace_dump_state(struct hart_state* hstate)
+{
+ trace_log("<not implemented>");
+}
\ No newline at end of file
#include <lunaix/mm/pagetable.h>
#include <lunaix/mm/page.h>
-struct leaflet*
+_default struct leaflet*
dup_leaflet(struct leaflet* leaflet)
{
fail("unimplemented");
}
-void
+_default void
pmm_arch_init_pool(struct pmem* memory)
{
fail("unimplemented");
}
-ptr_t
+_default ptr_t
pmm_arch_init_remap(struct pmem* memory, struct boot_handoff* bctx)
{
fail("unimplemented");
-}
\ No newline at end of file
+}
"boot/mb_parser.c",
"boot/kpt_setup.c",
"boot/boot_helper.c",
- "boot/bootmem.c"
])
sources([
#include <hal/hwtimer.h>
-#include <lunaix/generic/isrm.h>
+#include <asm-generic/isrm.h>
#include <lunaix/spike.h>
#include <lunaix/process.h>
-#include "sys/int_handler.h"
-#include "sys/x86_isa.h"
-#include "sys/hart.h"
+#include "asm/x86.h"
+#include "asm/hart.h"
#include "hal/apic_timer.h"
// TODO select alternatives...
- panick("no timer to use.");
+ fail("no timer to use.");
}
void
#include <lunaix/mm/pmm.h>
#include <lunaix/spike.h>
#include <lunaix/sections.h>
-#include <lunaix/generic/bootmem.h>
-#include <sys/mm/mm_defs.h>
+#include <asm/mm_defs.h>
#include <sys/boot/bstage.h>
+#include <sys-generic/bootmem.h>
#ifdef CONFIG_ARCH_X86_64
#include "sys/boot/archinit.h"
-#include "sys/crx.h"
-#include "sys/cpu.h"
+#include "asm/x86_cpu.h"
ptr_t __multiboot_addr boot_data;
#include <lunaix/sections.h>
#include <sys/boot/bstage.h>
-#include <sys/mm/mm_defs.h>
+#include <asm/mm_defs.h>
#define PF_X 0x1
#define PF_W 0x2
/* 高半核入口点 - 0xC0000000 */
#define __ASM__
-#include <sys/abi.h>
+#include <asm/abi.h>
#include <sys/failsafe.h>
.section .bss.kstack
#include <lunaix/compiler.h>
#include <sys/boot/bstage.h>
-#include <sys/mm/mm_defs.h>
+#include <asm/mm_defs.h>
ptr_t boot_text
#define __BOOT_CODE__
#include <lunaix/boot_generic.h>
-#include <lunaix/generic/bootmem.h>
#include <sys/boot/bstage.h>
#include <sys/boot/multiboot.h>
-#include <sys/mm/mempart.h>
+#include <sys-generic/bootmem.h>
+
+#include <asm/mempart.h>
#include <klibc/string.h>
#include "sys/boot/multiboot.S.inc"
#endif
-#include "sys/mm/mempart64.h"
+#include "asm/variants/mempart64.h"
.section .boot.data
.align 8
#include "sys/boot/archinit.h"
-#include "sys/crx.h"
-#include "sys/cpu.h"
+#include "asm/x86_cpu.h"
ptr_t __multiboot_addr boot_data;
#include <lunaix/sections.h>
#include <sys/boot/bstage.h>
-#include <sys/mm/mm_defs.h>
+#include <asm/mm_defs.h>
#define RSVD_PAGES 32
/* 高半核入口点 - 0xC0000000 */
#define __ASM__
-#include <sys/abi.h>
+#include <asm/abi.h>
#include <sys/failsafe.h>
.section .bss.kstack
#define __ASM__
-#include <sys/hart.h>
-#include <sys/abi.h>
-#include <sys/interrupt32.S.inc>
+#include <asm/hart.h>
+#include <asm/abi.h>
+#include <asm/variants/interrupt32.S.inc>
#include <lunaix/syscall.h>
#define __ASM__
-#include <sys/hart.h>
-#include <sys/abi.h>
-#include <sys/interrupt64.S.inc>
+#include <asm/hart.h>
+#include <asm/abi.h>
+#include <asm/variants/interrupt64.S.inc>
#include <lunaix/syscall.h>
-#include <sys/cpu.h>
-#include <sys/int_handler.h>
-#include <sys/hart.h>
-#include "sys/x86_isa.h"
+#include <asm/hart.h>
+#include "asm/x86.h"
-#include "sys/x86_isa.h"
+#include <asm-generic/isrm.h>
-#include <lunaix/generic/isrm.h>
#include <lunaix/mm/vmm.h>
#include <lunaix/process.h>
#include <lunaix/sched.h>
-#include <sys/hart.h>
+#include <asm/hart.h>
-#include <lunaix/generic/isrm.h>
+#include <asm-generic/isrm.h>
#include <lunaix/process.h>
#include <lunaix/sched.h>
#include <lunaix/spike.h>
#include <klibc/strfmt.h>
-#include "sys/apic.h"
-#include <sys/int_handler.h>
+#include "asm/soc/apic.h"
+#include "asm/x86.h"
LOG_MODULE("INTR")
/* Generated from i386_isrdef.c.j2. Do NOT modify */
#include <lunaix/types.h>
-#include "sys/int_handler.h"
-#include "sys/vectors.h"
-#include "sys/x86_isa.h"
+#include "asm/x86_ivs.h"
+#include "asm/x86.h"
#define IDT_INTERRUPT 0x70
#define IDT_ATTR(dpl, type) (((type) << 5) | ((dpl & 3) << 13) | (1 << 15))
-#include <lunaix/generic/isrm.h>
#include <lunaix/spike.h>
#include <lunaix/owloysius.h>
+#include <asm-generic/isrm.h>
-#include "sys/x86_isa.h"
-#include "sys/ioapic.h"
-#include "sys/apic.h"
+#include "asm/x86.h"
+#include "asm/soc/ioapic.h"
+#include "asm/soc/apic.h"
/*
total: 256 ivs
*
*/
-#include "sys/x86_isa.h"
-#include <sys/cpu.h>
+#include "asm/x86.h"
+#include "asm/x86_cpu.h"
-#include "sys/apic.h"
-#include <sys/hart.h>
+#include "asm/soc/apic.h"
+#include <asm/hart.h>
#include <lunaix/mm/mmio.h>
#include <lunaix/spike.h>
#include <lunaix/clock.h>
#include <lunaix/compiler.h>
-#include <lunaix/generic/isrm.h>
+#include <asm-generic/isrm.h>
#include <lunaix/spike.h>
#include <lunaix/syslog.h>
-#include "sys/apic.h"
+#include "asm/soc/apic.h"
LOG_MODULE("APIC_TIMER")
-#include <cpuid.h>
#include <lunaix/types.h>
-#include <sys/cpu.h>
-#include <sys/vectors.h>
-#define BRAND_LEAF 0x80000000UL
-
-void
-cpu_get_model(char* model_out)
-{
- u32_t* out = (u32_t*)model_out;
- u32_t eax = 0, ebx = 0, edx = 0, ecx = 0;
-
- __get_cpuid(0, &eax, &ebx, &ecx, &edx);
-
- out[0] = ebx;
- out[1] = edx;
- out[2] = ecx;
- model_out[12] = '\0';
-}
-
-int
-cpu_brand_string_supported()
-{
- u32_t supported = __get_cpuid_max(BRAND_LEAF, 0);
- return (supported >= 0x80000004UL);
-}
-
-void
-cpu_get_id(char* id_out)
-{
- if (!cpu_brand_string_supported()) {
- id_out[0] = '?';
- id_out[1] = '\0';
- }
- u32_t* out = (u32_t*)id_out;
- u32_t eax = 0, ebx = 0, edx = 0, ecx = 0;
- for (u32_t i = 2, j = 0; i < 5; i++) {
- __get_cpuid(BRAND_LEAF + i, &eax, &ebx, &ecx, &edx);
- out[j] = eax;
- out[j + 1] = ebx;
- out[j + 2] = ecx;
- out[j + 3] = edx;
- j += 4;
- }
- id_out[48] = '\0';
-}
+#include "asm/x86_ivs.h"
+#include "asm/x86_cpu.h"
void
cpu_rdmsr(u32_t msr_idx, u32_t* reg_high, u32_t* reg_low)
{
asm("int %0" ::"i"(LUNAIX_SCHED));
}
-
-void
-cpu_trap_panic(char* message)
-{
- asm("int %0" ::"i"(LUNAIX_SYS_PANIC), "D"(message));
-}
#include <lunaix/mm/mmio.h>
-#include <sys/hart.h>
-#include "sys/ioapic.h"
-#include "sys/x86_isa.h"
+#include <asm/hart.h>
+#include "asm/soc/ioapic.h"
+#include "asm/x86.h"
#define IOAPIC_IOREGSEL 0x00
#define IOAPIC_IOWIN 0x10
*
*/
-#include <lunaix/generic/isrm.h>
+#include <asm-generic/isrm.h>
#include <lunaix/mm/valloc.h>
#include <lunaix/status.h>
#include <lunaix/hart_state.h>
#include <klibc/string.h>
-#include <sys/port_io.h>
+#include <asm/x86_pmio.h>
#define RTC_INDEX_PORT 0x70
#define RTC_TARGET_PORT 0x71
#include <hal/pci.h>
-#include <sys/port_io.h>
+#include <asm/x86_pmio.h>
#ifdef CONFIG_PCI_PMIO
#define PCI_CONFIG_ADDR 0xcf8
#include <lunaix/clock.h>
#include <lunaix/ds/mutex.h>
#include <lunaix/input.h>
-#include <lunaix/generic/isrm.h>
+#include <asm-generic/isrm.h>
#include <lunaix/keyboard.h>
#include <lunaix/syslog.h>
#include <lunaix/timer.h>
#include <lunaix/hart_state.h>
-#include "sys/x86_isa.h"
+#include "asm/x86.h"
#include <klibc/string.h>
-#include <sys/cpu.h>
-#include <sys/port_io.h>
+#include "asm/x86_cpu.h"
+#include <asm/x86_pmio.h>
#define PS2_PORT_ENC_DATA 0x60
#define PS2_PORT_ENC_CMDREG 0x60
#include <lunaix/mm/vmm.h>
#include <klibc/string.h>
-#include <sys/mm/mempart.h>
+#include <asm/mempart.h>
bool
install_hart_transition(ptr_t vm_mnt, struct hart_transition* ht)
#include <lunaix/mm/vmm.h>
#include <klibc/string.h>
-#include <sys/mm/mempart.h>
-#include <sys/abi.h>
+#include <asm/mempart.h>
+#include <asm/abi.h>
volatile struct x86_tss _tss = { .link = 0,
.esp0 = 0,
#include <lunaix/mm/vmm.h>
#include <klibc/string.h>
-#include <sys/mm/mempart.h>
-#include <sys/abi.h>
+#include <asm/mempart.h>
+#include <asm/abi.h>
volatile struct x86_tss _tss = { };
#define __LUNAIX_I386ABI_H
#ifdef CONFIG_ARCH_X86_64
-# include "abi64.h"
+# include "variants/abi64.h"
#else
-# include "abi32.h"
+# include "variants/abi32.h"
#endif
#ifndef __ASM__
--- /dev/null
+#ifndef __LUNAIX_ARCH_CPU_H
+#define __LUNAIX_ARCH_CPU_H
+
+#include <lunaix/types.h>
+
+void
+cpu_trap_sched();
+
+static inline void
+cpu_enable_interrupt()
+{
+ asm volatile("sti");
+}
+
+static inline void
+cpu_disable_interrupt()
+{
+ asm volatile("cli");
+}
+
+static inline void
+cpu_wait()
+{
+ asm("hlt");
+}
+
+#endif /* __LUNAIX_CPU_H */
#ifndef __LUNAIX_ARCH_HART_H
#define __LUNAIX_ARCH_HART_H
-#include "vectors.h"
+#include "x86_ivs.h"
#ifndef __ASM__
-#include <lunaix/compiler.h>
-#include <sys/cpu.h>
+#include <lunaix/types.h>
+#include "x86_cpu.h"
struct hart_state;
#define __LUNAIX_MEMPART_H
#ifdef CONFIG_ARCH_X86_64
-# include "mempart64.h"
+# include "variants/mempart64.h"
#else
-# include "mempart32.h"
+# include "variants/mempart32.h"
#endif
#endif
\ No newline at end of file
#ifdef CONFIG_ARCH_X86_64
-#include "pt_def64.h"
+#include "variants/pt_def64.h"
#else
-#include "pt_def32.h"
+#include "variants/pt_def32.h"
#endif
// max translation level supported
#define MAX_LEVEL _PTW_LEVEL
-#ifndef pte_t
typedef struct __pte pte_t;
-#endif
#define _PTE_PPFN_MASK ( (~PAGE_MASK & PMS_MASK))
return *ptep;
}
+pte_t
+translate_vmr_prot(unsigned int vmr_prot, pte_t pte);
#endif /* __LUNAIX_ARCH_PAGETABLE_H */
#ifndef __LUNAIX_APIC_H
#define __LUNAIX_APIC_H
-#include "sys/x86_isa.h"
+#include "asm/x86.h"
#include <lunaix/types.h>
#define __APIC_BASE_PADDR 0xFEE00000
#ifndef __LUNAIX_IOAPIC_H
#define __LUNAIX_IOAPIC_H
-#include "sys/x86_isa.h"
+#include "asm/x86.h"
void
ioapic_init();
#ifndef __LUNAIX_ARCH_ABI32_H
#define __LUNAIX_ARCH_ABI32_H
-#include "sys/x86_isa.h"
+#include "asm/x86.h"
#define stack_alignment 0xfffffff0
#ifndef __LUNAIX_ARCH_ABI64_H
#define __LUNAIX_ARCH_ABI64_H
-#include "sys/x86_isa.h"
+#include "asm/x86.h"
#define stack_alignment 0xfffffffffffffff0UL
#endif
+void
+exception_install_handler();
+
+void
+intr_routine_init();
+
#endif
#endif /* __LUNAIX_I386_ASM_H */
-#ifndef __LUNAIX_CPU_H
-#define __LUNAIX_CPU_H
+#ifndef __LUNAIX_CPU_X86_H
+#define __LUNAIX_CPU_X86_H
-#include <lunaix/types.h>
+#include "cpu.h"
+#include "x86_crx.h"
#ifdef CONFIG_ARCH_X86_64
# define _POP "popq "
# define _MOV "movl "
#endif
-/**
- * @brief Get processor ID string
- *
- * @param id_out
- */
-void
-cpu_get_id(char* id_out);
-
-void
-cpu_trap_sched();
-
-void
-cpu_trap_panic(char* message);
-
/**
* @brief Load current processor state
*
return val;
}
-
-static inline void
-cpu_enable_interrupt()
-{
- asm volatile("sti");
-}
-
-static inline void
-cpu_disable_interrupt()
-{
- asm volatile("cli");
-}
-
-static inline void
-cpu_wait()
-{
- asm("hlt");
-}
-
-#endif /* __LUNAIX_CPU_H */
+#endif /* __LUNAIX_CPU_X86_H */
-#ifndef __LUNAIX_VECTORS_H
-#define __LUNAIX_VECTORS_H
-
-// clang-format off
+#ifndef __LUNAIX_X86IVS_H
+#define __LUNAIX_X86IVS_H
#define TOTAL_IV 256
// clang-format on
-#endif /* __LUNAIX_VECTORS_H */
+#endif /* __LUNAIX_X86IVS_H */
#define __LUNAIX_BASE_DEFS_LD_INC
#define __LD__
-#include <sys/mm/mempart.h>
+#include <asm/mempart.h>
#define KEXEC_BASE KERNEL_IMG
#define PAGE_GRAN 4K
--- /dev/null
+#ifndef __LUNAIX_ARCH_X86_ELF_H
+#define __LUNAIX_ARCH_X86_ELF_H
+
+#include <sys-generic/elf.h>
+
+#endif /* __LUNAIX_ARCH_X86_ELF_H */
#ifndef __LUNAIX_ARCH_GDBSTUB_ARCH_H
#define __LUNAIX_ARCH_GDBSTUB_ARCH_H
-#include "sys/hart.h"
+#include "asm/hart.h"
enum GDB_REGISTER
{
+++ /dev/null
-#ifndef __LUNAIX_INT_HANDLER_H
-#define __LUNAIX_INT_HANDLER_H
-
-void
-exception_install_handler();
-
-void
-intr_routine_init();
-
-#endif /* __LUNAIX_INT_HANDLER_H */
+++ /dev/null
-#ifndef __LUNAIX_ARCH_MEMORY_H
-#define __LUNAIX_ARCH_MEMORY_H
-
-#include <lunaix/mm/pagetable.h>
-#include <lunaix/mann_flags.h>
-
-static inline pte_t
-translate_vmr_prot(unsigned int vmr_prot, pte_t pte)
-{
- pte = pte_mkuser(pte);
-
- if ((vmr_prot & PROT_WRITE)) {
- pte = pte_mkwritable(pte);
- }
-
- if ((vmr_prot & PROT_EXEC)) {
- pte = pte_mkexec(pte);
- }
- else {
- pte = pte_mknonexec(pte);
- }
-
- return pte;
-}
-
-
-#endif /* __LUNAIX_ARCH_MEMORY_H */
#include <lunaix/mm/fault.h>
-#include <lunaix/mm/region.h>
-#include <lunaix/process.h>
#include <lunaix/hart_state.h>
-#include <sys/mm/mm_defs.h>
-
bool
__arch_prepare_fault_context(struct fault_context* fault)
{
fault->fault_va = ptr;
return true;
+}
+
+
+void
+intr_routine_page_fault(const struct hart_state* hstate)
+{
+ if (hstate->depth > 10) {
+ // Too many nested fault! we must messed up something
+ // XXX should we failed silently?
+ spin();
+ }
+
+ struct fault_context fault = { .hstate = hstate };
+
+ if (!__arch_prepare_fault_context(&fault)) {
+ goto failed;
+ }
+
+ if (!handle_page_fault(&fault)) {
+ goto failed;
+ }
+
+ return;
+
+failed:
+ fault_resolving_failed(&fault);
}
\ No newline at end of file
#include <lunaix/types.h>
-#include "sys/x86_isa.h"
+#include "asm/x86.h"
#define SD_TYPE(x) (x << 8)
#define SD_CODE_DATA(x) (x << 12)
-#include <sys/mm/tlb.h>
+#include <asm/tlb.h>
#include <lunaix/process.h>
void
#include <lunaix/mm/page.h>
-#include <sys/mm/mm_defs.h>
+
+#include <asm/mm_defs.h>
struct leaflet*
dup_leaflet(struct leaflet* leaflet)
vunmap(dest_va, new_leaflet);
return new_leaflet;
-}
\ No newline at end of file
+}
+
+pte_t
+translate_vmr_prot(unsigned int vmr_prot, pte_t pte)
+{
+ pte = pte_mkuser(pte);
+
+ if ((vmr_prot & PROT_WRITE)) {
+ pte = pte_mkwritable(pte);
+ }
+
+ if ((vmr_prot & PROT_EXEC)) {
+ pte = pte_mkexec(pte);
+ }
+ else {
+ pte = pte_mknonexec(pte);
+ }
+
+ return pte;
+}
#define __ASM__
#include <lunaix/syscall.h>
-
-.section .data
- /*
- 注意,这里的顺序非常重要。每个系统调用在这个地址表里的索引等于其调用号。
- */
- syscall_table:
- 1:
- .long 0
- .long __lxsys_fork /* 1 */
- .long __lxsys_yield
- .long __lxsys_sbrk
- .long __lxsys_brk
- .long __lxsys_getpid /* 5 */
- .long __lxsys_getppid
- .long __lxsys_sleep
- .long __lxsys_exit
- .long __lxsys_wait
- .long __lxsys_waitpid /* 10 */
- .long __lxsys_sigreturn
- .long __lxsys_sigprocmask
- .long __lxsys_sys_sigaction
- .long __lxsys_pause
- .long __lxsys_kill /* 15 */
- .long __lxsys_alarm
- .long __lxsys_sigpending
- .long __lxsys_sigsuspend
- .long __lxsys_open
- .long __lxsys_close /* 20 */
- .long __lxsys_read
- .long __lxsys_write
- .long __lxsys_sys_readdir
- .long __lxsys_mkdir
- .long __lxsys_lseek /* 25 */
- .long __lxsys_geterrno
- .long __lxsys_readlink
- .long __lxsys_readlinkat
- .long __lxsys_rmdir
- .long __lxsys_unlink /* 30 */
- .long __lxsys_unlinkat
- .long __lxsys_link
- .long __lxsys_fsync
- .long __lxsys_dup
- .long __lxsys_dup2 /* 35 */
- .long __lxsys_realpathat
- .long __lxsys_symlink
- .long __lxsys_chdir
- .long __lxsys_fchdir
- .long __lxsys_getcwd /* 40 */
- .long __lxsys_rename
- .long __lxsys_mount
- .long __lxsys_unmount
- .long __lxsys_getxattr
- .long __lxsys_setxattr /* 45 */
- .long __lxsys_fgetxattr
- .long __lxsys_fsetxattr
- .long __lxsys_ioctl
- .long __lxsys_getpgid
- .long __lxsys_setpgid /* 50 */
- .long __lxsys_syslog
- .long __lxsys_sys_mmap
- .long __lxsys_munmap
- .long __lxsys_execve
- .long __lxsys_fstat /* 55 */
- .long __lxsys_pollctl
- .long __lxsys_th_create
- .long __lxsys_th_self
- .long __lxsys_th_exit
- .long __lxsys_th_join /* 60 */
- .long __lxsys_th_kill
- .long __lxsys_th_detach
- .long __lxsys_th_sigmask
- 2:
- .rept __SYSCALL_MAX - (2b - 1b)/4
- .long 0
- .endr
-
+#include "syscall_nr.inc"
.section .text
.type syscall_hndlr, @function
#define __ASM__
#include <lunaix/syscall.h>
-#include "sys/interrupt64.S.inc"
-
-.section .data
- /*
- 注意,这里的顺序非常重要。每个系统调用在这个地址表里的索引等于其调用号。
- */
- syscall_table:
- 1:
- .8byte 0
- .8byte __lxsys_fork /* 1 */
- .8byte __lxsys_yield
- .8byte __lxsys_sbrk
- .8byte __lxsys_brk
- .8byte __lxsys_getpid /* 5 */
- .8byte __lxsys_getppid
- .8byte __lxsys_sleep
- .8byte __lxsys_exit
- .8byte __lxsys_wait
- .8byte __lxsys_waitpid /* 10 */
- .8byte __lxsys_sigreturn
- .8byte __lxsys_sigprocmask
- .8byte __lxsys_sys_sigaction
- .8byte __lxsys_pause
- .8byte __lxsys_kill /* 15 */
- .8byte __lxsys_alarm
- .8byte __lxsys_sigpending
- .8byte __lxsys_sigsuspend
- .8byte __lxsys_open
- .8byte __lxsys_close /* 20 */
- .8byte __lxsys_read
- .8byte __lxsys_write
- .8byte __lxsys_sys_readdir
- .8byte __lxsys_mkdir
- .8byte __lxsys_lseek /* 25 */
- .8byte __lxsys_geterrno
- .8byte __lxsys_readlink
- .8byte __lxsys_readlinkat
- .8byte __lxsys_rmdir
- .8byte __lxsys_unlink /* 30 */
- .8byte __lxsys_unlinkat
- .8byte __lxsys_link
- .8byte __lxsys_fsync
- .8byte __lxsys_dup
- .8byte __lxsys_dup2 /* 35 */
- .8byte __lxsys_realpathat
- .8byte __lxsys_symlink
- .8byte __lxsys_chdir
- .8byte __lxsys_fchdir
- .8byte __lxsys_getcwd /* 40 */
- .8byte __lxsys_rename
- .8byte __lxsys_mount
- .8byte __lxsys_unmount
- .8byte __lxsys_getxattr
- .8byte __lxsys_setxattr /* 45 */
- .8byte __lxsys_fgetxattr
- .8byte __lxsys_fsetxattr
- .8byte __lxsys_ioctl
- .8byte __lxsys_getpgid
- .8byte __lxsys_setpgid /* 50 */
- .8byte __lxsys_syslog
- .8byte __lxsys_sys_mmap
- .8byte __lxsys_munmap
- .8byte __lxsys_execve
- .8byte __lxsys_fstat /* 55 */
- .8byte __lxsys_pollctl
- .8byte __lxsys_th_create
- .8byte __lxsys_th_self
- .8byte __lxsys_th_exit
- .8byte __lxsys_th_join /* 60 */
- .8byte __lxsys_th_kill
- .8byte __lxsys_th_detach
- .8byte __lxsys_th_sigmask
- 2:
- .rept __SYSCALL_MAX - (2b - 1b) / 8
- .8byte 0
- .endr
-
+#include "syscall_nr.inc"
+#include "asm/variants/interrupt64.S.inc"
.section .text
.type syscall_hndlr, @function
--- /dev/null
+#ifdef CONFIG_ARCH_X86_64
+# define PTR .8byte
+# define SIZE 8
+#else
+# define PTR .4byte
+# define SIZE 4
+#endif
+
+.section .data
+ syscall_table:
+ 1:
+ PTR 0
+ PTR __lxsys_fork /* 1 */
+ PTR __lxsys_yield
+ PTR __lxsys_sbrk
+ PTR __lxsys_brk
+ PTR __lxsys_getpid /* 5 */
+ PTR __lxsys_getppid
+ PTR __lxsys_sleep
+ PTR __lxsys_exit
+ PTR __lxsys_wait
+ PTR __lxsys_waitpid /* 10 */
+ PTR __lxsys_sigreturn
+ PTR __lxsys_sigprocmask
+ PTR __lxsys_sys_sigaction
+ PTR __lxsys_pause
+ PTR __lxsys_kill /* 15 */
+ PTR __lxsys_alarm
+ PTR __lxsys_sigpending
+ PTR __lxsys_sigsuspend
+ PTR __lxsys_open
+ PTR __lxsys_close /* 20 */
+ PTR __lxsys_read
+ PTR __lxsys_write
+ PTR __lxsys_sys_readdir
+ PTR __lxsys_mkdir
+ PTR __lxsys_lseek /* 25 */
+ PTR __lxsys_geterrno
+ PTR __lxsys_readlink
+ PTR __lxsys_readlinkat
+ PTR __lxsys_rmdir
+ PTR __lxsys_unlink /* 30 */
+ PTR __lxsys_unlinkat
+ PTR __lxsys_link
+ PTR __lxsys_fsync
+ PTR __lxsys_dup
+ PTR __lxsys_dup2 /* 35 */
+ PTR __lxsys_realpathat
+ PTR __lxsys_symlink
+ PTR __lxsys_chdir
+ PTR __lxsys_fchdir
+ PTR __lxsys_getcwd /* 40 */
+ PTR __lxsys_rename
+ PTR __lxsys_mount
+ PTR __lxsys_unmount
+ PTR __lxsys_getxattr
+ PTR __lxsys_setxattr /* 45 */
+ PTR __lxsys_fgetxattr
+ PTR __lxsys_fsetxattr
+ PTR __lxsys_ioctl
+ PTR __lxsys_getpgid
+ PTR __lxsys_setpgid /* 50 */
+ PTR __lxsys_syslog
+ PTR __lxsys_sys_mmap
+ PTR __lxsys_munmap
+ PTR __lxsys_execve
+ PTR __lxsys_fstat /* 55 */
+ PTR __lxsys_pollctl
+ PTR __lxsys_th_create
+ PTR __lxsys_th_self
+ PTR __lxsys_th_exit
+ PTR __lxsys_th_join /* 60 */
+ PTR __lxsys_th_kill
+ PTR __lxsys_th_detach
+ PTR __lxsys_th_sigmask
+ 2:
+ .rept __SYSCALL_MAX - (2b - 1b) / SIZE
+ .long 0
+ .endr
\ No newline at end of file
#include <hal/ahci/scsi.h>
#include <hal/pci.h>
-#include <sys/port_io.h>
+#include <asm/x86_pmio.h>
#include <klibc/string.h>
#include <lunaix/block.h>
-#include <lunaix/generic/isrm.h>
+#include <asm-generic/isrm.h>
#include <lunaix/mm/mmio.h>
#include <lunaix/mm/valloc.h>
#include <lunaix/mm/page.h>
#include <hal/ahci/ahci.h>
#include <hal/ahci/sata.h>
-#include <lunaix/generic/isrm.h>
+#include <asm-generic/isrm.h>
#include <lunaix/mm/valloc.h>
#include <lunaix/syslog.h>
#include <lunaix/status.h>
#include <lunaix/syslog.h>
-#include <sys/mm/pagetable.h>
+#include <asm/pagetable.h>
#include <hal/serial.h>
#include <hal/term.h>
#include <lunaix/device.h>
-#include <lunaix/generic/isrm.h>
+#include <asm-generic/isrm.h>
#include <lunaix/syslog.h>
-#include <sys/port_io.h>
+#include <asm/x86_pmio.h>
#include "16x50.h"
#include <lunaix/device.h>
-#include <lunaix/generic/isrm.h>
+#include <asm-generic/isrm.h>
#include <lunaix/mm/mmio.h>
#include "16x50.h"
#include <lunaix/device.h>
-#include <lunaix/generic/isrm.h>
+#include <asm-generic/isrm.h>
#include <lunaix/syslog.h>
#include <lunaix/mm/mmio.h>
*
*/
#include <lunaix/device.h>
-#include <lunaix/generic/isrm.h>
+#include <asm-generic/isrm.h>
-#include <sys/port_io.h>
+#include <asm/x86_pmio.h>
#include "16x50.h"
#include <lunaix/spike.h>
#include <lunaix/status.h>
-#include <sys/cpu.h>
+#include <asm/cpu.h>
#include "vga.h"
#include <lunaix/mm/pagetable.h>
#include <lunaix/mm/mmio.h>
-#include <sys/port_io.h>
+#include <asm/x86_pmio.h>
vga_attribute* tty_vga_buffer;
#define __LUNAIX_AHCI_H
#include "hba.h"
-#include <lunaix/generic/isrm.h>
+#include <asm-generic/isrm.h>
/*
* Macro naming rule:
struct boot_handoff
{
- size_t msize;
struct
{
size_t size;
#define unreachable __builtin_unreachable()
#define no_inline __attribute__((noinline))
-#define defualt weak
+#define _default weak
#define msbiti (sizeof(int) * 8 - 1)
#define clz(bits) __builtin_clz(bits)
#define __LUNAIX_ELF32_H
#include <lunaix/types.h>
-#include <sys/exebi/elf.h>
+#include <sys/elf.h>
#define ET_EXEC 2
#define ET_DYN 3
struct hart_state;
#include <lunaix/compiler.h>
-#include <sys/hart.h>
+#include <asm/hart.h>
struct hart_transition
{
#ifndef __LUNAIX_KPREEMPT_H
#define __LUNAIX_KPREEMPT_H
-#include <sys/abi.h>
-#include <sys/cpu.h>
+#include <asm/abi.h>
+#include <asm/cpu.h>
#include <lunaix/process.h>
static inline void
int resolve_type;
};
-bool
-__arch_prepare_fault_context(struct fault_context* context);
-
static inline void
fault_resolved(struct fault_context* fault, int flags)
{
fault->resolve_type |= (flags | RESOLVE_OK);
}
+
+bool
+handle_page_fault(struct fault_context* fault);
+
+void noret
+fault_resolving_failed(struct fault_context* fault);
+
#endif /* __LUNAIX_FAULT_H */
#include <lunaix/types.h>
#include <lunaix/ds/llist.h>
-#include <sys/mm/memory.h>
+#include <asm/pagetable.h>
#include <usr/lunaix/mann_flags.h>
typedef struct __pte pte_t;
-#include <sys/mm/mempart.h>
-#include <sys/mm/pagetable.h>
-#include <sys/cpu.h>
+#include <asm/mempart.h>
+#include <asm/pagetable.h>
+#include <asm/cpu.h>
#define VMS_SELF VMS_SELF_MOUNT
#define VMS_SELF_L0TI (__index(VMS_SELF_MOUNT) / L0T_SIZE)
return mkl3tep(mkptep_va(mnt, va));
}
+static inline pte_t*
+mklntep_va(int level, ptr_t mnt, ptr_t va)
+{
+ if (level == 0)
+ return mkl0tep_va(mnt, va);
+
+#if LnT_ENABLED(1)
+ if (level == 1)
+ return mkl1tep_va(mnt, va);
+#endif
+
+#if LnT_ENABLED(2)
+ if (level == 2)
+ return mkl2tep_va(mnt, va);
+#endif
+
+#if LnT_ENABLED(3)
+ if (level == 3)
+ return mkl3tep_va(mnt, va);
+#endif
+
+ return mkptep_va(mnt, va);
+}
+
+static inline unsigned long
+lnt_page_size(int level)
+{
+ if (level == 0)
+ return L0T_SIZE;
+ if (level == 1)
+ return L1T_SIZE;
+ if (level == 2)
+ return L2T_SIZE;
+ if (level == 3)
+ return L3T_SIZE;
+
+ return LFT_SIZE;
+}
+
static inline bool
pt_last_level(int level)
{
}
static inline bool
-l0tep_implie(pte_t* ptep, ptr_t addr)
+lntep_implie(pte_t* ptep, ptr_t addr, size_t lvl_size)
{
- return ptep_va(ptep, L0T_SIZE) == __vaddr(addr);
+ return ptep_va(ptep, lvl_size) == __vaddr(addr);
}
static inline bool
}
static inline bool
-l0tep_implie_vmnts(pte_t* ptep)
+lntep_implie_vmnts(pte_t* ptep, size_t lvl_size)
{
- return l0tep_implie(ptep, VMS_SELF) ||
- l0tep_implie(ptep, VMS_MOUNT_1);
+ return lntep_implie(ptep, VMS_SELF, lvl_size) ||
+ lntep_implie(ptep, VMS_MOUNT_1, lvl_size);
+}
+
+
+static inline int
+ptep_count_level(pte_t* ptep)
+{
+ int i = 0;
+ ptr_t addr = (ptr_t)ptep;
+
+ if (!is_ptep(addr << (LEVEL_SHIFT * i++)))
+ return MAX_LEVEL - i;
+
+#if LnT_ENABLED(1)
+ if (!is_ptep(addr << (LEVEL_SHIFT * i++)))
+ return MAX_LEVEL - i;
+#endif
+
+#if LnT_ENABLED(2)
+ if (!is_ptep(addr << (LEVEL_SHIFT * i++)))
+ return MAX_LEVEL - i;
+#endif
+
+#if LnT_ENABLED(3)
+ if (!is_ptep(addr << (LEVEL_SHIFT * i++)))
+ return MAX_LEVEL - i;
+#endif
+
+ return 0;
}
#endif /* __LUNAIX_PAGETABLE_H */
#define __LUNAIX_PHYSICAL_H
#include <lunaix/compiler.h>
-#include <sys/mm/physical.h>
+#include <asm/physical.h>
/**
* @brief 长久页:不会被缓存,但允许释放
void
procvm_exit_remote(struct remote_vmctx* rvmctx);
+/*
+ architecture-specific
+*/
+
+void
+procvm_link_kernel(ptr_t dest_mnt);
+
+void
+procvm_unlink_kernel();
+
#endif /* __LUNAIX_PROCVM_H */
#include <lunaix/process.h>
#include <lunaix/types.h>
-/**
- * @brief 初始化虚拟内存管理器
- *
- */
-void
-vmm_init();
-
static inline void
vmm_set_ptes_contig(pte_t* ptep, pte_t pte, size_t lvl_size, size_t n)
{
#ifndef __LUNAIX_TLB_H
#define __LUNAIX_TLB_H
-#include <sys/mm/tlb.h>
+#include <asm/tlb.h>
// TODO
#endif // CONFIG_NO_ASSERT
-void noret
-panick(const char* msg);
-
#define wait_until(cond) \
while (!(cond)) \
;
#include <lunaix/boot_generic.h>
#include <lunaix/hart_state.h>
-#include <lunaix/generic/trace_arch.h>
+
+#include <sys-generic/trace_arch.h>
struct ksym_entry
{
#include <lunaix/mm/valloc.h>
#include <lunaix/owloysius.h>
#include <lunaix/syslog.h>
-#include <sys/muldiv64.h>
+#include <asm/muldiv64.h>
LOG_MODULE("blkbuf")
#include <lunaix/mm/cake.h>
#include <lunaix/mm/valloc.h>
-#include <sys/cpu.h>
+#include <asm/cpu.h>
static struct cake_pile* blkio_reqpile;
#include <lunaix/status.h>
#include <lunaix/syslog.h>
-#include <sys/muldiv64.h>
+#include <asm/muldiv64.h>
#include <klibc/crc.h>
#include <lunaix/spike.h>
#include <lunaix/kcmd.h>
#include <lunaix/sections.h>
-#include <sys/mm/mm_defs.h>
+#include <asm/mm_defs.h>
/**
* @brief Reserve memory for kernel bootstrapping initialization
#include <klibc/string.h>
#include <sdbg/gdbstub.h>
-#include <sys/port_io.h>
-#include <sys/cpu.h>
+#include <asm/x86_pmio.h>
+#include <asm/cpu.h>
/*****************************************************************************
* Macros
#include <lunaix/trace.h>
#include <lunaix/sections.h>
-#include <sys/abi.h>
-#include <sys/mm/mm_defs.h>
+#include <asm/abi.h>
+#include <asm/mm_defs.h>
#include <sys/trace.h>
#include <klibc/string.h>
return 0;
}
-defualt int
+_default int
elf_open(struct elf* elf, const char* path)
{
struct v_dnode* elfdn;
return elf_do_open(elf, elffile);
}
-defualt int
+_default int
elf_openat(struct elf* elf, void* elf_vfile)
{
// so the ref count kept in sync
return elf_do_open(elf, elf_vfile);
}
-defualt int
+_default int
elf_close(struct elf* elf)
{
if (elf->pheaders) {
return 0;
}
-defualt int
+_default int
elf_static_linked(const struct elf* elf)
{
for (size_t i = 0; i < elf->eheader.e_phnum; i++) {
return 1;
}
-defualt size_t
+_default size_t
elf_loadable_memsz(const struct elf* elf)
{
// XXX: Hmmmm, I am not sure if we need this. This is designed to be handy
return sz;
}
-defualt int
+_default int
elf_find_loader(const struct elf* elf, char* path_out, size_t len)
{
int retval = NO_LOADER;
return retval;
}
-defualt int
+_default int
elf_read_ehdr(struct elf* elf)
{
struct v_file* elfile = (struct v_file*)elf->elf_file;
return elf_read(elfile, (void*)&elf->eheader, 0, SIZE_EHDR);
}
-defualt int
+_default int
elf_read_phdr(struct elf* elf)
{
int status = 0;
return entries;
}
-defualt int
+_default int
elf_check_exec(const struct elf* elf, int type)
{
const struct elf_ehdr* ehdr = &elf->eheader;
return (ehdr->e_entry) && ehdr->e_type == type;
}
-defualt int
+_default int
elf_check_arch(const struct elf* elf)
{
const struct elf_ehdr* ehdr = &elf->eheader;
#include <lunaix/mm/valloc.h>
#include <lunaix/spike.h>
-#include <sys/mm/mempart.h>
+#include <asm/mempart.h>
int
elf_smap(struct load_context* ldctx,
#include <lunaix/syscall.h>
#include <lunaix/syscall_utils.h>
-#include <sys/abi.h>
-#include <sys/mm/mm_defs.h>
+#include <asm/abi.h>
+#include <asm/mm_defs.h>
#include <klibc/string.h>
#include <lunaix/spike.h>
#include <klibc/string.h>
-#include <sys/mm/pagetable.h>
+#include <asm/pagetable.h>
int
iso9660_open(struct v_inode* this, struct v_file* file)
} else {
start = vfs_sysroot;
if (!vfs_sysroot->mnt) {
- panick("vfs: no root");
+ fail("vfs: no root");
}
}
#include <lunaix/mm/valloc.h>
#include <lunaix/spike.h>
-#include <sys/mm/pagetable.h>
+#include <asm/pagetable.h>
static struct twifs_node* fs_root;
#include <klibc/strfmt.h>
#include <klibc/string.h>
-#include <sys/mm/pagetable.h>
+#include <asm/pagetable.h>
#define TWIMAP_BUFFER_SIZE PAGE_SIZE
#include <lunaix/block.h>
#include <lunaix/boot_generic.h>
#include <lunaix/device.h>
-#include <lunaix/foptions.h>
#include <lunaix/input.h>
+
#include <lunaix/mm/cake.h>
#include <lunaix/mm/pmm.h>
#include <lunaix/mm/page.h>
#include <lunaix/mm/valloc.h>
#include <lunaix/mm/vmm.h>
+
#include <lunaix/process.h>
#include <lunaix/sched.h>
#include <lunaix/spike.h>
#include <lunaix/syslog.h>
#include <lunaix/sections.h>
-#include <hal/acpi/acpi.h>
#include <hal/devtree.h>
-#include <sys/abi.h>
-#include <sys/mm/mm_defs.h>
-
-#include <klibc/strfmt.h>
-#include <klibc/string.h>
+#include <asm/mm_defs.h>
LOG_MODULE("kinit")
unsigned int i = ptep_vfn(ptep);
do {
- if (l0tep_implie_vmnts(ptep)) {
+ if (lntep_implie_vmnts(ptep, L0T_SIZE)) {
ptep++;
continue;
}
void
kernel_bootstrap(struct boot_handoff* bhctx)
{
- vmm_init();
-
pmm_init(bhctx);
// now we can start reserving physical space
#include <lunaix/hart_state.h>
#include <lunaix/failsafe.h>
-#include <sys/mm/mm_defs.h>
+#include <asm/mm_defs.h>
#include <klibc/string.h>
context->fault_refva = refva;
}
-static bool
+static void
__prepare_fault_context(struct fault_context* fault)
{
- if (!__arch_prepare_fault_context(fault)) {
- return false;
- }
-
- __gather_memaccess_info(fault);
-
pte_t* fault_ptep = fault->fault_ptep;
ptr_t fault_va = fault->fault_va;
pte_t fault_pte = *fault_ptep;
fault->resolving = pte_mkloaded(fault_pte);
fault->kernel_vmfault = kernel_vmfault;
fault->kernel_access = kernel_context(fault->hstate);
-
- return true;
}
static inline void
}
-static void noret
-__fail_to_resolve(struct fault_context* fault)
+void noret
+fault_resolving_failed(struct fault_context* fault)
{
if (fault->prealloc) {
leaflet_return(fault->prealloc);
return !!(fault->resolve_type & RESOLVE_OK);
}
-void
-intr_routine_page_fault(const struct hart_state* hstate)
+bool
+handle_page_fault(struct fault_context* fault)
{
- if (hstate->depth > 10) {
- // Too many nested fault! we must messed up something
- // XXX should we failed silently?
- spin();
- }
-
- struct fault_context fault = { .hstate = hstate };
-
- if (!__prepare_fault_context(&fault)) {
- __fail_to_resolve(&fault);
- }
+ __gather_memaccess_info(fault);
+ __prepare_fault_context(fault);
- fault_prealloc_page(&fault);
+ fault_prealloc_page(fault);
- if (!__try_resolve_fault(&fault)) {
- __fail_to_resolve(&fault);
+ if (!__try_resolve_fault(fault)) {
+ return false;
}
- if ((fault.resolve_type & NO_PREALLOC)) {
- if (fault.prealloc) {
- leaflet_return(fault.prealloc);
+ if ((fault->resolve_type & NO_PREALLOC)) {
+ if (fault->prealloc) {
+ leaflet_return(fault->prealloc);
}
}
- tlb_flush_kernel(fault.fault_va);
-}
\ No newline at end of file
+ tlb_flush_kernel(fault->fault_va);
+ return true;
+}
#include <lunaix/syscall.h>
#include <lunaix/syscall_utils.h>
-#include <sys/mm/mm_defs.h>
+#include <asm/mm_defs.h>
#include <usr/lunaix/mann_flags.h>
#include <lunaix/mm/mmap.h>
#include <lunaix/process.h>
-#include <sys/mm/mm_defs.h>
+#include <asm/mm_defs.h>
#include <klibc/string.h>
return (1 << (leaflet_order(leaflet) % shifts)) - 1;
}
-static ptr_t
-vmscpy(ptr_t dest_mnt, ptr_t src_mnt, bool only_kernel)
+static inline int
+__descend(ptr_t dest_mnt, ptr_t src_mnt, ptr_t va, bool alloc)
{
- pte_t* ptep_dest = mkl0tep(mkptep_va(dest_mnt, 0));
- pte_t* ptep = mkl0tep(mkptep_va(src_mnt, 0));
- pte_t* ptepd_kernel = mkl0tep(mkptep_va(dest_mnt, KERNEL_RESIDENT));
- pte_t* ptep_kernel = mkl0tep(mkptep_va(src_mnt, KERNEL_RESIDENT));
+ pte_t *dest, *src, pte;
- // Build the self-reference on dest vms
+ int i = 0;
+ while (!pt_last_level(i))
+ {
+ dest = mklntep_va(i, dest_mnt, va);
+ src = mklntep_va(i, src_mnt, va);
+ pte = pte_at(src);
- /*
- * -- What the heck are ptep_ssm and ptep_sms ? --
- *
- * ptep_dest point to the pagetable itself that is mounted
- * at dest_mnt (or simply mnt):
- * mnt -> self -> self -> self -> L0TE@offset
- *
- * ptep_sms shallowed the recursion chain:
- * self -> mnt -> self -> self -> L0TE@self
- *
- * ptep_ssm shallowed the recursion chain:
- * self -> self -> mnt -> self -> L0TE@self
- *
- * Now, here is the problem, back to x86_32, the translation is
- * a depth-3 recursion:
- * L0T -> LFT -> Page
- *
- * So ptep_ssm will terminate at mnt and give us a leaf
- * slot for allocate a fresh page table for mnt:
- * self -> self -> L0TE@mnt
- *
- * but in x86_64 translation has extra two more step:
- * L0T -> L1T -> L2T -> LFT -> Page
- *
- * So we must continue push down....
- * ptep_sssms shallowed the recursion chain:
- * self -> self -> self -> mnt -> L0TE@self
- *
- * ptep_ssssm shallowed the recursion chain:
- * self -> self -> self -> self -> L0TE@mnt
- *
- * Note: PML4: 2 extra steps
- * PML5: 3 extra steps
- */
- pte_t* ptep_ssm = mkl0tep_va(VMS_SELF, dest_mnt);
- pte_t* ptep_sms = mkl1tep_va(VMS_SELF, dest_mnt) + VMS_SELF_L0TI;
- pte_t pte_sms = mkpte_prot(KERNEL_PGTAB);
+ if (!pte_isloaded(pte) || pte_huge(pte)) {
+ break;
+ }
- pte_sms = alloc_kpage_at(ptep_ssm, pte_sms, 0);
- set_pte(ptep_sms, pte_sms);
+ if (alloc && pte_isnull(pte_at(dest))) {
+ alloc_kpage_at(dest, pte, 0);
+ }
+
+ i++;
+ }
+
+ return i;
+}
+
+static inline void
+copy_leaf(pte_t* dest, pte_t* src, pte_t pte, int level)
+{
+ struct leaflet* leaflet;
+
+ set_pte(dest, pte);
+
+ if (!pte_isloaded(pte)) {
+ return;
+ }
+
+ leaflet = pte_leaflet(pte);
+ assert(leaflet_refcount(leaflet));
- tlb_flush_kernel((ptr_t)dest_mnt);
- tlb_flush_kernel((ptr_t)ptep_sms);
-
- if (only_kernel) {
- ptep = ptep_kernel;
- ptep_dest += ptep_vfn(ptep_kernel);
- } else {
- ptep++;
- ptep_dest++;
+ if (leaflet_ppfn(leaflet) == pte_ppfn(pte)) {
+ leaflet_borrow(leaflet);
}
+}
- int level = 0;
+static inline void
+copy_root(pte_t* dest, pte_t* src, pte_t pte, int level)
+{
+ alloc_kpage_at(dest, pte, 0);
+}
+
+static void
+vmrcpy(ptr_t dest_mnt, ptr_t src_mnt, struct mm_region* region)
+{
+ pte_t *src, *dest;
+ ptr_t loc;
+ int level;
struct leaflet* leaflet;
- while (ptep < ptep_kernel)
+ loc = region->start;
+ src = mkptep_va(src_mnt, loc);
+ dest = mkptep_va(dest_mnt, loc);
+
+ level = __descend(dest_mnt, src_mnt, loc, true);
+
+ while (loc < region->end)
{
- pte_t pte = *ptep;
+ pte_t pte = *src;
if (pte_isnull(pte)) {
goto cont;
}
if (pt_last_level(level) || pte_huge(pte)) {
- set_pte(ptep_dest, pte);
-
- if (pte_isloaded(pte)) {
- leaflet = pte_leaflet(pte);
- assert(leaflet_refcount(leaflet));
-
- if (leaflet_ppfn(leaflet) == pte_ppfn(pte)) {
- leaflet_borrow(leaflet);
- }
- }
+ copy_leaf(dest, src, pte, level);
+ goto cont;
}
- else if (!pt_last_level(level)) {
- alloc_kpage_at(ptep_dest, pte, 0);
+
+ if (!pt_last_level(level)) {
+ copy_root(dest, src, pte, level);
- ptep = ptep_step_into(ptep);
- ptep_dest = ptep_step_into(ptep_dest);
+ src = ptep_step_into(src);
+ dest = ptep_step_into(dest);
level++;
continue;
}
cont:
- while (ptep_vfn(ptep) == MAX_PTEN - 1) {
+ loc += lnt_page_size(level);
+ while (ptep_vfn(src) == MAX_PTEN - 1) {
assert(level > 0);
- ptep = ptep_step_out(ptep);
- ptep_dest = ptep_step_out(ptep_dest);
+ src = ptep_step_out(src);
+ dest = ptep_step_out(dest);
level--;
}
- ptep++;
- ptep_dest++;
- }
-
- // Ensure we step back to L0T
- assert(!level);
- assert(ptep_dest == ptepd_kernel);
-
- // Carry over the kernel (exclude last two entry)
- unsigned int i = ptep_vfn(ptep);
- while (i++ < MAX_PTEN) {
- pte_t pte = *ptep;
-
- if (l0tep_implie_vmnts(ptep)) {
- goto _cont;
- }
-
- assert(!pte_isnull(pte));
-
- // Ensure it is a next level pagetable,
- // we MAY relax this later allow kernel
- // to have huge leaflet mapped at L0T
- leaflet = pte_leaflet_aligned(pte);
- assert(leaflet_order(leaflet) == 0);
-
- set_pte(ptep_dest, pte);
- leaflet_borrow(leaflet);
-
- _cont:
- ptep++;
- ptep_dest++;
+ src++;
+ dest++;
}
-
- return pte_paddr(pte_sms);
}
static void
-vmsfree(ptr_t vm_mnt)
+vmrfree(ptr_t vm_mnt, struct mm_region* region)
{
+ pte_t *src, *end;
+ ptr_t loc;
+ int level;
struct leaflet* leaflet;
- pte_t* ptep_head = mkl0tep(mkptep_va(vm_mnt, 0));
- pte_t* ptep_self = mkl0tep(mkptep_va(vm_mnt, VMS_SELF));
- pte_t* ptep_kernel = mkl0tep(mkptep_va(vm_mnt, KERNEL_RESIDENT));
- int level = 0;
- pte_t* ptep = ptep_head;
- while (ptep < ptep_kernel)
+ loc = region->start;
+ src = mkptep_va(vm_mnt, region->start);
+ end = mkptep_va(vm_mnt, region->end);
+
+ level = __descend(0, vm_mnt, loc, false);
+
+ while (src < end)
{
- pte_t pte = *ptep;
+ pte_t pte = *src;
ptr_t pa = pte_paddr(pte);
if (pte_isnull(pte)) {
}
if (!pt_last_level(level) && !pte_huge(pte)) {
- ptep = ptep_step_into(ptep);
+ src = ptep_step_into(src);
level++;
continue;
leaflet = pte_leaflet_aligned(pte);
leaflet_return(leaflet);
- ptep += __ptep_advancement(leaflet, level);
+ src += __ptep_advancement(leaflet, level);
}
cont:
- while (ptep_vfn(ptep) == MAX_PTEN - 1) {
- ptep = ptep_step_out(ptep);
- leaflet = pte_leaflet_aligned(pte_at(ptep));
+ while (ptep_vfn(src) == MAX_PTEN - 1) {
+ src = ptep_step_out(src);
+ leaflet = pte_leaflet_aligned(pte_at(src));
assert(leaflet_order(leaflet) == 0);
leaflet_return(leaflet);
level--;
}
- ptep++;
+ src++;
+ }
+}
+
+static void
+vmscpy(struct proc_mm* dest_mm, struct proc_mm* src_mm)
+{
+ // Build the self-reference on dest vms
+
+ /*
+ * -- What the heck are ptep_ssm and ptep_sms ? --
+ *
+ * ptep_dest point to the pagetable itself that is mounted
+ * at dest_mnt (or simply mnt):
+ * mnt -> self -> self -> self -> L0TE@offset
+ *
+ * ptep_sms shallowed the recursion chain:
+ * self -> mnt -> self -> self -> L0TE@self
+ *
+ * ptep_ssm shallowed the recursion chain:
+ * self -> self -> mnt -> self -> L0TE@self
+ *
+ * Now, here is the problem, back to x86_32, the translation is
+ * a depth-3 recursion:
+ * L0T -> LFT -> Page
+ *
+ * So ptep_ssm will terminate at mnt and give us a leaf
+ * slot for allocate a fresh page table for mnt:
+ * self -> self -> L0TE@mnt
+ *
+ * but in x86_64 translation has extra two more step:
+ * L0T -> L1T -> L2T -> LFT -> Page
+ *
+ * So we must continue push down....
+ * ptep_sssms shallowed the recursion chain:
+ * self -> self -> self -> mnt -> L0TE@self
+ *
+ * ptep_ssssm shallowed the recursion chain:
+ * self -> self -> self -> self -> L0TE@mnt
+ *
+ * Note: PML4: 2 extra steps
+ * PML5: 3 extra steps
+ */
+
+ ptr_t dest_mnt, src_mnt;
+
+ dest_mnt = dest_mm->vm_mnt;
+ assert(dest_mnt);
+
+ pte_t* ptep_ssm = mkl0tep_va(VMS_SELF, dest_mnt);
+ pte_t* ptep_smx = mkl1tep_va(VMS_SELF, dest_mnt);
+ pte_t pte_sms = mkpte_prot(KERNEL_PGTAB);
+
+ pte_sms = alloc_kpage_at(ptep_ssm, pte_sms, 0);
+ set_pte(&ptep_smx[VMS_SELF_L0TI], pte_sms);
+
+ tlb_flush_kernel((ptr_t)dest_mnt);
+
+ if (!src_mm) {
+ goto done;
+ }
+
+ src_mnt = src_mm->vm_mnt;
+
+ struct mm_region *pos, *n;
+ llist_for_each(pos, n, &src_mm->regions, head)
+ {
+ vmrcpy(dest_mnt, src_mnt, pos);
}
+done:;
+ procvm_link_kernel(dest_mnt);
+
+ dest_mm->vmroot = pte_paddr(pte_sms);
+}
+
+static void
+vmsfree(struct proc_mm* mm)
+{
+ struct leaflet* leaflet;
+ ptr_t vm_mnt;
+ pte_t* ptep_self;
+
+ vm_mnt = mm->vm_mnt;
+ ptep_self = mkl0tep(mkptep_va(vm_mnt, VMS_SELF));
+
+ struct mm_region *pos, *n;
+ llist_for_each(pos, n, &mm->regions, head)
+ {
+ vmrfree(vm_mnt, pos);
+ }
+
+ procvm_unlink_kernel();
+
leaflet = pte_leaflet_aligned(pte_at(ptep_self));
leaflet_return(leaflet);
}
mm->heap = mm_current->heap;
mm->vm_mnt = VMS_MOUNT_1;
- mm->vmroot = vmscpy(VMS_MOUNT_1, VMS_SELF, false);
+ vmscpy(mm, mm_current);
region_copy_mm(mm_current, mm);
}
__attach_to_current_vms(mm);
mm->vm_mnt = VMS_MOUNT_1;
- mm->vmroot = vmscpy(VMS_MOUNT_1, VMS_SELF, true);
+ vmscpy(mm, NULL);
}
void
region_release(pos);
}
- vfree(mm);
- vmsfree(vm_mnt);
+ vmsfree(mm);
vms_unmount(vm_mnt);
+ vfree(mm);
__detach_from_current_vms(mm);
}
#include <lunaix/spike.h>
#include <lunaix/process.h>
-#include <sys/mm/mempart.h>
+#include <asm/mempart.h>
#include <klibc/string.h>
#include <lunaix/spike.h>
#include <lunaix/syslog.h>
-#include <sys/mm/mempart.h>
+#include <asm/mempart.h>
static ptr_t start = VMAP;
static volatile ptr_t prev_va = 0;
#include <lunaix/spike.h>
#include <lunaix/syslog.h>
-#include <sys/cpu.h>
-#include <sys/mm/mm_defs.h>
+#include <asm/cpu.h>
+#include <asm/mm_defs.h>
LOG_MODULE("VM")
-void
-vmm_init()
-{
- // XXX: something here?
-}
-
pte_t
vmm_tryptep(pte_t* ptep, size_t lvl_size)
{
#include <lunaix/signal.h>
#include <lunaix/kpreempt.h>
-#include <sys/abi.h>
-#include <sys/mm/mm_defs.h>
+#include <asm/abi.h>
+#include <asm/mm_defs.h>
#include <klibc/string.h>
#include <lunaix/exec.h>
#include <lunaix/fs.h>
-#include <sys/abi.h>
-#include <sys/mm/mm_defs.h>
+#include <asm/abi.h>
+#include <asm/mm_defs.h>
LOG_MODULE("PROC")
-#include <sys/abi.h>
-#include <sys/mm/mempart.h>
+#include <asm/abi.h>
+#include <asm/mempart.h>
-#include <sys/cpu.h>
+#include <asm/cpu.h>
#include <lunaix/fs/taskfs.h>
#include <lunaix/mm/cake.h>
#include <lunaix/hart_state.h>
#include <lunaix/kpreempt.h>
-#include <lunaix/generic/isrm.h>
+#include <asm-generic/isrm.h>
#include <klibc/string.h>
;
if (unlikely(i == MAX_PROCESS)) {
- panick("Panic in Ponyville shimmer!");
+ fail("Panic in Ponyville shimmer!");
}
return i;
assert(!kernel_process(proc));
if (proc->pid == 1) {
- panick("Attempt to kill init");
+ fail("Attempt to kill init");
}
terminate_proc_only(proc, exit_code);
#include <klibc/string.h>
-#include <sys/mm/mempart.h>
+#include <asm/mempart.h>
LOG_MODULE("SIG")
#include <usr/lunaix/threads.h>
-#include <sys/abi.h>
-#include <sys/mm/mm_defs.h>
+#include <asm/abi.h>
+#include <asm/mm_defs.h>
LOG_MODULE("THREAD")
ERROR("assertion fail (%s:%u)\n\t%s", file, line, expr);
failsafe_diagnostic();
-}
-
-void noret
-panick(const char* msg)
-{
- cpu_trap_panic(msg);
- spin();
-}
+}
\ No newline at end of file
-- \
-nographic &
-QMPORT=${hmp_port} gdb build/bin/kernel.bin -ex "target remote localhost:${gdb_port}"
\ No newline at end of file
+QMPORT=${hmp_port} gdb-multiarch \
+ build/bin/kernel.bin \
+ -ex "target remote localhost:${gdb_port}"
\ No newline at end of file
t = menu.create_title(self, "Lunaix Kernel Configuration" + suffix)
t2 = menu.create_title(self, repo_info)
- t2.set_alignment(Alignment.BOT | Alignment.RIGHT)
+ t2.set_alignment(Alignment.BOT | Alignment.LEFT)
root.add(t)
root.add(t2)
%.tool : %.c
$(call status,CC,$<)
- @$(CC) $< -o $@
+ @cc $< -o $@
.PHONY: all clean
// TODO test pthread + signal
printf("All test passed.\n");
+
+ return 0;
}
\ No newline at end of file