--- /dev/null
+# Porting Lunaix to Other ISAs
+
+This document briefly describe how to add support for other ISA
+
+## Adding Implementations
+
+Lunaix provide bunch of headers that **MUST** be implemented.
+
++ 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.
+
++ Add implementation to function signature defined in header files under
+ `includes/lunaix/generic`
+
++ Add implementation of syscall dispatching (Reference: `arhc/i386/syscall.S`)
+
++ Add implementation of interrupt handler dispatching (Reference:
+ `arhc/i386/exceptions/intrhnds.S`)
+
++ Add implementation of context switching, signal handling. (Reference:
+ `arhc/i386/exceptions/interrupt.S`)
+ **TODO: make this procedure more standalone**
+
+## Preparing the Flows
+
+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.
+
+Before jumping to `kernel_bootstrap`, one
+
++ 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
+
+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
+provide better performance on these library functions by exploiting the
+architectural specific feature.
+
+All non-static function from these header can be overriden:
+
++ `klibc/string.h`
++ `klibc/crc.h`
++ `klibc/hash.h`
--- /dev/null
+#include <lunaix/spike.h>
+#include <hal/hwtimer.h>
+
+struct hwtimer*
+select_platform_timer()
+{
+ fail("unimplemented");
+}
\ No newline at end of file
--- /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_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;
+
+void
+hart_flow_redirect(struct hart_state* state, ptr_t pc, ptr_t sp);
+
+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 MEM_PAGE 0x1000UL
+#define MEM_1M 0x100000UL
+#define MEM_4M 0x400000UL
+#define MEM_HUGE 0x400000UL
+#define MEM_1G 0x40000000UL
+
+#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 * MEM_PAGE)
+
+/*
+ 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
+#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_PCI_HBA_H
+#define __LUNAIX_ARCH_PCI_HBA_H
+
+#include <hal/pci.h>
+#include <lunaix/types.h>
+
+#define PCI_MSI_BASE 0
+
+static inline pci_reg_t
+pci_read_cspace(ptr_t base, int offset)
+{
+ return 0;
+}
+
+static inline void
+pci_write_cspace(ptr_t base, int offset, pci_reg_t data)
+{
+ return;
+}
+
+static inline u16_t
+pci_config_msi_data(int vector) {
+ return vector;
+}
+
+static inline ptr_t
+pci_get_msi_base() {
+ return 0;
+}
+
+#endif /* __LUNAIX_ARCH_PCI_HBA_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/pagetable.h>
+#include <lunaix/mm/page.h>
+
+struct leaflet*
+dup_leaflet(struct leaflet* leaflet)
+{
+ fail("unimplemented");
+}
+
+void
+pmm_arch_init_pool(struct pmem* memory)
+{
+ fail("unimplemented");
+}
+
+ptr_t
+pmm_arch_init_remap(struct pmem* memory, struct boot_handoff* bctx)
+{
+ fail("unimplemented");
+}
\ No newline at end of file
+++ /dev/null
-Lunaix kernel arch specific ABI
-======
-
-This document provides a checklist if one wants to add support for novel architecture
-
-(It is far from complete, as the refactoring is going on)
-
-Implementation checklist:
- [ ] An entry point that recieve control from second stage bootloader.
- [ ] Interrupt vectoring must be done before invoking kernel_bootstrap.
- [ ] Prepare the boot_handoff state struct, according to system info provided
- by upstream bootloader
- [ ] Invoke the kernel_bootstrap, pass the boot_handoff as it's only argument
- This will transfer the control to Lunaix kernel.
- [ ] A syscall handler, syscall table, and the syscall vectoring
- [ ] A interrupt handler, must take care of context save/restore, signal handling
- [ ] A system virtual memory map
- [ ] Implement the following abstractions
-
-Referenced headers
- * <some_arch>/includes/sys/abi.h
- * <some_arch>/includes/sys/interrupt.h
- * <some_arch>/includes/sys/port_io.h
- * <some_arch>/includes/sys/pci_hba.h
- * <some_arch>/includes/mm/mempart.h
- * <some_arch>/includes/cpu.h
-
-Referenced functions
- * includes/hal/hwtimer.h:hwtimer_choose
- * includes/hal/hwrtc.h:hwrtc_choose
- * includes/hal/intc.h:intc_init
- * includes/lunaix/process.h:proc_init_transfer
\ No newline at end of file
-#include <hal/apic_timer.h>
-#include <hal/rtc/mc146818a.h>
-
-#include <hal/hwrtc.h>
#include <hal/hwtimer.h>
-#include <lunaix/isrm.h>
+#include <lunaix/generic/isrm.h>
#include <lunaix/spike.h>
-#include <sys/i386_intr.h>
-#include <sys/interrupts.h>
+#include "sys/i386_intr.h"
+#include "sys/hart.h"
+
+#include "hal/apic_timer.h"
void
exception_init()
}
extern void
-syscall_hndlr(const isr_param* param);
+syscall_hndlr(const struct hart_state* hstate);
void
arch_preinit()
}
struct hwtimer*
-hwtimer_choose()
+select_platform_timer()
{
struct hwtimer* timer;
-#include <lunaix/isrm.h>
+#include <lunaix/generic/isrm.h>
#include <lunaix/spike.h>
+#include <lunaix/owloysius.h>
-#include <hal/intc.h>
+#include "sys/x86_isa.h"
+#include "sys/ioapic.h"
+#include "sys/apic.h"
/*
total: 256 ivs
static isr_cb handlers[TOTAL_IV];
static ptr_t ivhand_payload[TOTAL_IV];
+static struct x86_intc arch_intc_ctx;
+
extern void
-intr_routine_fallback(const isr_param* param);
+intr_routine_fallback(const struct hart_state* state);
void
isrm_init()
}
// fixed, edge trigged, polarity=high
- intc_irq_attach(irq, iv, 0, IRQ_DEFAULT);
+ isrm_irq_attach(irq, iv, 0, IRQ_DEFAULT);
return iv;
}
}
ptr_t
-isrm_get_payload(const isr_param* param)
+isrm_get_payload(const struct hart_state* state)
{
- int iv = param->execp->vector;
+ int iv = state->execp->vector;
assert(iv < 256);
return ivhand_payload[iv];
assert(iv < 256);
ivhand_payload[iv] = payload;
-}
\ No newline at end of file
+}
+
+void
+isrm_irq_attach(int irq, int iv, cpu_t dest, u32_t flags)
+{
+ arch_intc_ctx.irq_attach(&arch_intc_ctx, irq, iv, dest, flags);
+}
+
+void
+isrm_notify_eoi(cpu_t id, int iv)
+{
+ arch_intc_ctx.notify_eoi(&arch_intc_ctx, id, iv);
+}
+
+void
+isrm_notify_eos(cpu_t id)
+{
+ isrm_notify_eoi(id, LUNAIX_SCHED);
+}
+
+
+static void
+__intc_init()
+{
+ apic_init();
+ ioapic_init();
+
+ arch_intc_ctx.name = "i386_apic";
+ arch_intc_ctx.irq_attach = ioapic_irq_remap;
+ arch_intc_ctx.notify_eoi = apic_on_eoi;
+}
+owloysius_fetch_init(__intc_init, on_earlyboot);
\ No newline at end of file
#define __ASM__
-#include <sys/interrupts.h>
+#include <sys/hart.h>
#include <sys/abi.h>
#include <sys/interrupt.S.inc>
# fxrstor (%eax)
1:
- popl %eax # discard isr_param::depth
+ popl %eax # discard struct hart_state::depth
popl %eax
popl %ebx
popl %ecx
movl current_thread, %eax
# nested intr: restore saved context
- popl thread_intr_ctx(%eax)
+ popl thread_hstate(%eax)
addl $8, %esp
由于这中间没有进行地址空间的交换,所以第二次跳转使用的是同一个内核栈,而之前默认tss.esp0的值是永远指向最顶部
这样一来就有可能会覆盖更早的上下文信息(比如嵌套的信号捕获函数)
*/
- movl thread_intr_ctx(%ebx), %ecx # __current->intr_ctx
+ movl thread_hstate(%ebx), %ecx # __current->hstate
movl %ecx, (tss_esp0_off + _tss)
jmp handle_signal
1:
- movl thread_intr_ctx(%ebx), %eax
+ movl thread_hstate(%ebx), %eax
jmp soft_iret
.type handle_signal, @function
# 注意1:任何对proc_sig的布局改动,都须及时的保证这里的一致性!
# 注意2:handle_signal在调用之前,须确保proc_sig已经写入用户栈!
# arg1 in %eax: addr of proc_sig structure in user stack
- movl psig_saved_ictx(%eax), %ebx # %ebx = &proc_sig->saved_ictx
+ movl psig_saved_hstate(%eax), %ebx # %ebx = &proc_sig->saved_hstate
pushl $UDATA_SEG
pushl %eax # esp
movl iexecp(%ebx), %ebx
- pushl exeflags(%ebx) # proc_sig->saved_ictx->execp->eflags
+ pushl exeflags(%ebx) # proc_sig->saved_hstate->execp->eflags
pushl $UCODE_SEG # cs
pushl psig_sigact(%eax) # %eip = proc_sig->sigact
#include <sys/cpu.h>
#include <sys/i386_intr.h>
-#include <sys/interrupts.h>
-#include <sys/x86_isa.h>
+#include <sys/hart.h>
+#include "sys/x86_isa.h"
-#include <hal/intc.h>
+#include "sys/x86_isa.h"
-#include <lunaix/isrm.h>
+#include <lunaix/generic/isrm.h>
#include <lunaix/mm/vmm.h>
#include <lunaix/process.h>
#include <lunaix/sched.h>
LOG_MODULE("INTR")
static inline void
-update_thread_context(isr_param* param)
+update_thread_context(struct hart_state* state)
{
if (!current_thread) {
return;
}
- isr_param* ppctx = current_thread->intr_ctx;
- param->execp->saved_prev_ctx = ppctx;
- current_thread->intr_ctx = param;
+ struct hart_state* parent = current_thread->hstate;
+ hart_push_state(parent, state);
+ current_thread->hstate = state;
- if (ppctx) {
- param->depth = ppctx->depth + 1;
+ if (parent) {
+ state->depth = parent->depth + 1;
}
}
void
-intr_handler(isr_param* param)
+intr_handler(struct hart_state* state)
{
- update_thread_context(param);
+ update_thread_context(state);
- volatile struct exec_param* execp = param->execp;
+ volatile struct exec_param* execp = state->execp;
if (execp->vector <= 255) {
isr_cb subscriber = isrm_get(execp->vector);
- subscriber(param);
+ subscriber(state);
goto done;
}
done:
if (execp->vector > IV_BASE_END) {
- intc_notify_eoi(0, execp->vector);
+ isrm_notify_eoi(0, execp->vector);
}
return;
-#include <sys/interrupts.h>
+#include <sys/hart.h>
-#include <lunaix/isrm.h>
+#include <lunaix/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/apic.h"
#include <sys/i386_intr.h>
LOG_MODULE("INTR")
extern void
-intr_routine_page_fault(const isr_param* param);
+intr_routine_page_fault(const struct hart_state* state);
extern u32_t debug_resv;
void
-__print_panic_msg(const char* msg, const isr_param* param)
+__print_panic_msg(const char* msg, const struct hart_state* state)
{
ERROR("panic: %s", msg);
failsafe_diagnostic();
}
void
-intr_routine_divide_zero(const isr_param* param)
+intr_routine_divide_zero(const struct hart_state* state)
{
- __print_panic_msg("div zero", param);
+ __print_panic_msg("div zero", state);
}
void
-intr_routine_general_protection(const isr_param* param)
+intr_routine_general_protection(const struct hart_state* state)
{
- __print_panic_msg("general protection", param);
+ __print_panic_msg("general protection", state);
}
void
-intr_routine_sys_panic(const isr_param* param)
+intr_routine_sys_panic(const struct hart_state* state)
{
- __print_panic_msg((char*)(param->registers.edi), param);
+ __print_panic_msg((char*)(state->registers.edi), state);
}
void
-intr_routine_fallback(const isr_param* param)
+intr_routine_fallback(const struct hart_state* state)
{
- __print_panic_msg("unknown interrupt", param);
+ __print_panic_msg("unknown interrupt", state);
}
/**
* @brief ISR for Spurious interrupt
*
- * @param isr_param passed by CPU
+ * @param struct hart_state passed by CPU
*/
void
-intr_routine_apic_spi(const isr_param* param)
+intr_routine_apic_spi(const struct hart_state* state)
{
// FUTURE: do nothing for now
}
void
-intr_routine_apic_error(const isr_param* param)
+intr_routine_apic_error(const struct hart_state* state)
{
u32_t error_reg = apic_read_reg(APIC_ESR);
char buf[32];
}
void
-intr_routine_sched(const isr_param* param)
+intr_routine_sched(const struct hart_state* state)
{
schedule();
}
--- /dev/null
+#include <sys/gdbstub.h>
+#include <sdbg/gdbstub.h>
+
+void
+arch_gdbstub_setup_state(struct gdb_state* state, struct hart_state* hstate)
+{
+ /* Translate vector to signal */
+ switch (hstate->execp->vector) {
+ case 1:
+ state->signum = 5;
+ break;
+ case 3:
+ state->signum = 5;
+ break;
+ default:
+ state->signum = 7;
+ }
+}
+
+void
+arch_gdbstub_save_regs(struct gdb_state* state, struct hart_state* hstate)
+{
+ /* Load Registers */
+ state->registers[GDB_CPU_I386_REG_EAX] = hstate->registers.eax;
+ state->registers[GDB_CPU_I386_REG_ECX] = hstate->registers.ecx;
+ state->registers[GDB_CPU_I386_REG_EDX] = hstate->registers.edx;
+ state->registers[GDB_CPU_I386_REG_EBX] = hstate->registers.ebx;
+ state->registers[GDB_CPU_I386_REG_ESP] = hstate->esp;
+ state->registers[GDB_CPU_I386_REG_EBP] = hstate->registers.ebp;
+ state->registers[GDB_CPU_I386_REG_ESI] = hstate->registers.esi;
+ state->registers[GDB_CPU_I386_REG_EDI] = hstate->registers.edi;
+ state->registers[GDB_CPU_I386_REG_PC] = hstate->execp->eip;
+ state->registers[GDB_CPU_I386_REG_CS] = hstate->execp->cs;
+ state->registers[GDB_CPU_I386_REG_PS] = hstate->execp->eflags;
+ state->registers[GDB_CPU_I386_REG_SS] = hstate->execp->ss;
+ state->registers[GDB_CPU_I386_REG_DS] = hstate->registers.ds;
+ state->registers[GDB_CPU_I386_REG_ES] = hstate->registers.es;
+ state->registers[GDB_CPU_I386_REG_FS] = hstate->registers.fs;
+ state->registers[GDB_CPU_I386_REG_GS] = hstate->registers.gs;
+}
+
+void
+arch_gdbstub_restore_regs(struct gdb_state* state, struct hart_state* hstate)
+{
+ /* Restore Registers */
+ hstate->registers.eax = state->registers[GDB_CPU_I386_REG_EAX];
+ hstate->registers.ecx = state->registers[GDB_CPU_I386_REG_ECX];
+ hstate->registers.edx = state->registers[GDB_CPU_I386_REG_EDX];
+ hstate->registers.ebx = state->registers[GDB_CPU_I386_REG_EBX];
+ hstate->esp = state->registers[GDB_CPU_I386_REG_ESP];
+ hstate->registers.ebp = state->registers[GDB_CPU_I386_REG_EBP];
+ hstate->registers.esi = state->registers[GDB_CPU_I386_REG_ESI];
+ hstate->registers.edi = state->registers[GDB_CPU_I386_REG_EDI];
+ hstate->execp->eip = state->registers[GDB_CPU_I386_REG_PC];
+ hstate->execp->cs = state->registers[GDB_CPU_I386_REG_CS];
+ hstate->execp->eflags = state->registers[GDB_CPU_I386_REG_PS];
+ hstate->execp->ss = state->registers[GDB_CPU_I386_REG_SS];
+ hstate->registers.ds = state->registers[GDB_CPU_I386_REG_DS];
+ hstate->registers.es = state->registers[GDB_CPU_I386_REG_ES];
+ hstate->registers.fs = state->registers[GDB_CPU_I386_REG_FS];
+ hstate->registers.gs = state->registers[GDB_CPU_I386_REG_GS];
+}
+
+
+int
+gdb_sys_continue(struct gdb_state* state)
+{
+ state->registers[GDB_CPU_I386_REG_PS] &= ~(1 << 8);
+ return 0;
+}
+
+int
+gdb_sys_step(struct gdb_state* state)
+{
+ state->registers[GDB_CPU_I386_REG_PS] |= 1 << 8;
+ return 0;
+}
\ No newline at end of file
*
*/
-#include <hal/intc.h>
+#include "sys/x86_isa.h"
#include <sys/cpu.h>
-#include <sys/apic.h>
-#include <sys/interrupts.h>
+#include "sys/apic.h"
+#include <sys/hart.h>
#include <lunaix/mm/mmio.h>
#include <lunaix/spike.h>
}
void
-apic_on_eoi(struct intc_context* intc_ctx, cpu_t cpu, int iv)
+apic_on_eoi(struct x86_intc* intc_ctx, cpu_t cpu, int iv)
{
// for all external interrupts except the spurious interrupt
// this is required by Intel Manual Vol.3A, section 10.8.1 & 10.8.5
-#include <hal/apic_timer.h>
+#include "apic_timer.h"
#include <hal/hwtimer.h>
#include <lunaix/clock.h>
#include <lunaix/compiler.h>
-#include <lunaix/isrm.h>
+#include <lunaix/generic/isrm.h>
#include <lunaix/spike.h>
#include <lunaix/syslog.h>
-#include <sys/apic.h>
+#include "sys/apic.h"
LOG_MODULE("APIC_TIMER")
static timer_tick_cb tick_cb = NULL;
static void
-temp_intr_routine_apic_timer(const isr_param* param)
+temp_intr_routine_apic_timer(const struct hart_state* state)
{
apic_timer_done = 1;
}
static void
-apic_timer_tick_isr(const isr_param* param)
+apic_timer_tick_isr(const struct hart_state* state)
{
systicks++;
#include <hal/acpi/acpi.h>
-#include <hal/intc.h>
#include <lunaix/mm/mmio.h>
-#include <sys/interrupts.h>
-#include <sys/ioapic.h>
+#include <sys/hart.h>
+#include "sys/ioapic.h"
+#include "sys/x86_isa.h"
#define IOAPIC_IOREGSEL 0x00
#define IOAPIC_IOWIN 0x10
}
void
-ioapic_irq_remap(struct intc_context*, int irq, int iv, cpu_t dest, u32_t flags)
+ioapic_irq_remap(struct x86_intc* intc, int irq, int iv, cpu_t dest, u32_t flags)
{
/*
FIXME move it to HAL level. since every platform might have their own
*
*/
-#include <lunaix/isrm.h>
+#include <lunaix/generic/isrm.h>
#include <lunaix/mm/valloc.h>
#include <lunaix/status.h>
-#include <lunaix/pcontext.h>
+#include <lunaix/hart_state.h>
-#include <hal/rtc/mc146818a.h>
+#include <hal/hwrtc.h>
#include <klibc/string.h>
#define RTC_FREQUENCY_1024HZ 0b110
#define RTC_DIVIDER_33KHZ (0b010 << 4)
+#define PC_AT_IRQ_RTC 8
+
struct mc146818
{
struct hwrtc* rtc_context;
}
static void
-__rtc_tick(const isr_param* param)
+__rtc_tick(const struct hart_state* hstate)
{
- struct mc146818* state = (struct mc146818*)isrm_get_payload(param);
+ struct mc146818* state = (struct mc146818*)isrm_get_payload(hstate);
state->tick_counts++;
+++ /dev/null
-#include <sys/apic.h>
-#include <sys/pci_hba.h>
-
-void
-pci_setup_msi(struct pci_device* device, int vector)
-{
- // Dest: APIC#0, Physical Destination, No redirection
- u32_t msi_addr = (__APIC_BASE_PADDR);
-
- // Edge trigger, Fixed delivery
- u32_t msi_data = vector;
-
- pci_write_cspace(
- device->cspace_base, PCI_MSI_ADDR(device->msi_loc), msi_addr);
-
- pci_reg_t reg1 = pci_read_cspace(device->cspace_base, device->msi_loc);
- pci_reg_t msg_ctl = reg1 >> 16;
-
- int offset = !!(msg_ctl & MSI_CAP_64BIT) * 4;
- pci_write_cspace(device->cspace_base,
- PCI_MSI_DATA(device->msi_loc, offset),
- msi_data & 0xffff);
-
- if ((msg_ctl & MSI_CAP_MASK)) {
- pci_write_cspace(
- device->cspace_base, PCI_MSI_MASK(device->msi_loc, offset), 0);
- }
-
- // manipulate the MSI_CTRL to allow device using MSI to request service.
- reg1 = (reg1 & 0xff8fffff) | 0x10000;
- pci_write_cspace(device->cspace_base, device->msi_loc, reg1);
-}
\ No newline at end of file
#include <lunaix/clock.h>
#include <lunaix/ds/mutex.h>
#include <lunaix/input.h>
-#include <lunaix/isrm.h>
+#include <lunaix/generic/isrm.h>
#include <lunaix/keyboard.h>
#include <lunaix/syslog.h>
#include <lunaix/timer.h>
-#include <lunaix/pcontext.h>
+#include <lunaix/hart_state.h>
-#include <hal/intc.h>
+#include "sys/x86_isa.h"
#include <klibc/string.h>
#define PS2_NO_ARG 0xff00
+#define PC_AT_IRQ_KBD 1
+
struct ps2_cmd
{
char cmd;
// #define KBD_DBGLOG
static void
-intr_ps2_kbd_handler(const isr_param* param);
+intr_ps2_kbd_handler(const struct hart_state* hstate);
static u8_t
ps2_issue_cmd_wretry(char cmd, u16_t arg);
}
static void
-intr_ps2_kbd_handler(const isr_param* param)
+intr_ps2_kbd_handler(const struct hart_state* hstate)
{
// This is important! Don't believe me? try comment it out and run on Bochs!
+++ /dev/null
-#include <hal/intc.h>
-#include <sys/apic.h>
-#include <sys/ioapic.h>
-
-extern struct intc_context arch_intc_ctx;
-
-void
-intc_init()
-{
- apic_init();
- ioapic_init();
-
- arch_intc_ctx.name = "i386_apic";
- arch_intc_ctx.irq_attach = ioapic_irq_remap;
- arch_intc_ctx.notify_eoi = apic_on_eoi;
-}
#include <lunaix/process.h>
-#include <lunaix/pcontext.h>
+#include <lunaix/hart_state.h>
#include <lunaix/mm/vmm.h>
#include <klibc/string.h>
.ss0 = KDATA_SEG };
bool
-inject_transfer_context(ptr_t vm_mnt, struct transfer_context* tctx)
+install_hart_transition(ptr_t vm_mnt, struct hart_transition* ht)
{
pte_t pte;
- if (!vmm_lookupat(vm_mnt, tctx->inject, &pte)) {
+ if (!vmm_lookupat(vm_mnt, ht->inject, &pte)) {
return false;
}
mount_page(PG_MOUNT_4, pte_paddr(pte));
- ptr_t mount_inject = PG_MOUNT_4 + va_offset(tctx->inject);
- memcpy((void*)mount_inject, &tctx->transfer, sizeof(tctx->transfer));
+ ptr_t mount_inject = PG_MOUNT_4 + va_offset(ht->inject);
+ memcpy((void*)mount_inject, &ht->transfer, sizeof(ht->transfer));
unmount_page(PG_MOUNT_4);
return true;
}
void
-thread_setup_trasnfer(struct transfer_context* tctx,
+hart_prepare_transition(struct hart_transition* ht,
ptr_t kstack_tp, ptr_t ustack_pt,
ptr_t entry, bool to_user)
{
- ptr_t offset = (ptr_t)&tctx->transfer.eret - (ptr_t)&tctx->transfer;
- tctx->inject = align_stack(kstack_tp - sizeof(tctx->transfer));
+ ptr_t offset = (ptr_t)&ht->transfer.eret - (ptr_t)&ht->transfer;
+ ht->inject = align_stack(kstack_tp - sizeof(ht->transfer));
- tctx->transfer.isr = (isr_param){
+ ht->transfer.state = (struct hart_state){
.registers = {
.ds = KDATA_SEG,
.es = KDATA_SEG,
.fs = KDATA_SEG,
.gs = KDATA_SEG
},
- .execp = (struct exec_param*)(tctx->inject + offset)
+ .execp = (struct exec_param*)(ht->inject + offset)
};
int code_seg = KCODE_SEG, data_seg = KDATA_SEG;
mstate |= 0x200; // enable interrupt
}
- tctx->transfer.eret = (struct exec_param) {
+ ht->transfer.eret = (struct exec_param) {
.cs = code_seg, .eip = entry,
.ss = data_seg, .esp = align_stack(ustack_pt),
.eflags = mstate
#ifndef __LUNAIX_I386ABI_H
#define __LUNAIX_I386ABI_H
-#include <sys/x86_isa.h>
+#include "sys/x86_isa.h"
#define stack_alignment 0xfffffff0
#ifndef __ASM__
#define align_stack(ptr) ((ptr) & stack_alignment)
-#define store_retval(retval) current_thread->intr_ctx->registers.eax = (retval)
+#define store_retval(retval) current_thread->hstate->registers.eax = (retval)
-#define store_retval_to(th, retval) (th)->intr_ctx->registers.eax = (retval)
+#define store_retval_to(th, retval) (th)->hstate->registers.eax = (retval)
-#define eret_target(th) (th)->intr_ctx->execp->eip
-#define eret_stack(th) (th)->intr_ctx->execp->esp
-#define intr_ivec(th) (th)->intr_ctx->execp->vector
-#define intr_ierr(th) (th)->intr_ctx->execp->err_code
-
-#define j_usr(sp, pc) \
- asm volatile("movw %0, %%ax\n" \
- "movw %%ax, %%es\n" \
- "movw %%ax, %%ds\n" \
- "movw %%ax, %%fs\n" \
- "movw %%ax, %%gs\n" \
- "pushl %0\n" \
- "pushl %1\n" \
- "pushl %2\n" \
- "pushl %3\n" \
- "retf" ::"i"(UDATA_SEG), \
- "r"(sp), \
- "i"(UCODE_SEG), \
- "r"(pc) \
+static inline void must_inline
+j_usr(ptr_t sp, ptr_t pc)
+{
+ asm volatile("movw %0, %%ax\n"
+ "movw %%ax, %%es\n"
+ "movw %%ax, %%ds\n"
+ "movw %%ax, %%fs\n"
+ "movw %%ax, %%gs\n"
+ "pushl %0\n"
+ "pushl %1\n"
+ "pushl %2\n"
+ "pushl %3\n"
+ "retf" ::"i"(UDATA_SEG),
+ "r"(sp),
+ "i"(UCODE_SEG),
+ "r"(pc)
: "eax", "memory");
+}
static inline void must_inline noret
#ifndef __LUNAIX_APIC_H
#define __LUNAIX_APIC_H
-#include <hal/intc.h>
+#include "sys/x86_isa.h"
#include <lunaix/types.h>
#define __APIC_BASE_PADDR 0xFEE00000
apic_init();
void
-apic_on_eoi(struct intc_context* intc_ctx, cpu_t cpu, int iv);
+apic_on_eoi(struct x86_intc* intc_ctx, cpu_t cpu, int iv);
#endif /* __LUNAIX_APIC_H */
/**
* @brief Load current processor state
*
- * @return u32_t
+ * @return reg_t
*/
-static inline u32_t
+static inline reg_t
cpu_ldstate()
{
ptr_t val;
/**
* @brief Load current processor config
*
- * @return u32_t
+ * @return reg_t
*/
-static inline u32_t
+static inline reg_t
cpu_ldconfig()
{
- ptr_t val;
+ reg_t val;
asm volatile("movl %%cr0,%0" : "=r"(val));
return val;
}
/**
* @brief Change current processor state
*
- * @return u32_t
+ * @return reg_t
*/
static inline void
-cpu_chconfig(u32_t val)
+cpu_chconfig(reg_t val)
{
asm("mov %0, %%cr0" ::"r"(val));
}
/**
* @brief Change current virtual memory space
*
- * @return u32_t
+ * @return reg_t
*/
static inline void
-cpu_chvmspace(u32_t val)
+cpu_chvmspace(reg_t val)
{
asm("mov %0, %%cr3" ::"r"(val));
}
--- /dev/null
+#ifndef __LUNAIX_ARCH_GDBSTUB_ARCH_H
+#define __LUNAIX_ARCH_GDBSTUB_ARCH_H
+
+#include "sys/hart.h"
+
+enum GDB_REGISTER
+{
+ GDB_CPU_I386_REG_EAX = 0,
+ GDB_CPU_I386_REG_ECX = 1,
+ GDB_CPU_I386_REG_EDX = 2,
+ GDB_CPU_I386_REG_EBX = 3,
+ GDB_CPU_I386_REG_ESP = 4,
+ GDB_CPU_I386_REG_EBP = 5,
+ GDB_CPU_I386_REG_ESI = 6,
+ GDB_CPU_I386_REG_EDI = 7,
+ GDB_CPU_I386_REG_PC = 8,
+ GDB_CPU_I386_REG_PS = 9,
+ GDB_CPU_I386_REG_CS = 10,
+ GDB_CPU_I386_REG_SS = 11,
+ GDB_CPU_I386_REG_DS = 12,
+ GDB_CPU_I386_REG_ES = 13,
+ GDB_CPU_I386_REG_FS = 14,
+ GDB_CPU_I386_REG_GS = 15,
+ 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 */
--- /dev/null
+#ifndef __LUNAIX_ARCH_HART_H
+#define __LUNAIX_ARCH_HART_H
+
+#include "vectors.h"
+
+#ifndef __ASM__
+#include <lunaix/compiler.h>
+#include <sys/cpu.h>
+
+struct exec_param;
+
+struct regcontext
+{
+ reg_t eax;
+ reg_t ebx;
+ reg_t ecx;
+ reg_t edx;
+ reg_t edi;
+ reg_t ebp;
+ reg_t esi;
+ reg_t ds;
+ reg_t es;
+ reg_t fs;
+ reg_t gs;
+} compact;
+
+struct hart_state
+{
+ unsigned int depth;
+ struct regcontext registers;
+ union
+ {
+ reg_t esp;
+ volatile struct exec_param* execp;
+ };
+} compact;
+
+struct exec_param
+{
+ struct hart_state* parent_state;
+ reg_t vector;
+ reg_t err_code;
+ reg_t eip;
+ reg_t cs;
+ reg_t eflags;
+ reg_t esp;
+ reg_t ss;
+} compact;
+
+
+static inline void
+hart_flow_redirect(struct hart_state* hstate, ptr_t pc, ptr_t sp)
+{
+ hstate->execp->eip = pc;
+ hstate->execp->esp = sp;
+}
+
+static inline ptr_t
+hart_pc(struct hart_state* hstate)
+{
+ return hstate->execp->eip;
+}
+
+static inline ptr_t
+hart_sp(struct hart_state* hstate)
+{
+ return hstate->execp->esp;
+}
+
+static inline bool
+kernel_context(struct hart_state* hstate)
+{
+ return !((hstate->execp->cs) & 0b11);
+}
+
+static inline ptr_t
+hart_stack_frame(struct hart_state* hstate)
+{
+ return hstate->registers.ebp;
+}
+
+static inline int
+hart_vector_stamp(struct hart_state* hstate) {
+ return hstate->execp->vector;
+}
+
+static inline unsigned int
+hart_ecause(struct hart_state* hstate) {
+ return hstate->execp->err_code;
+}
+
+static inline struct hart_state*
+hart_parent_state(struct hart_state* hstate)
+{
+ return hstate->execp->parent_state;
+}
+
+static inline void
+hart_push_state(struct hart_state* p_hstate, struct hart_state* hstate)
+{
+ hstate->execp->parent_state = p_hstate;
+}
+
+#endif
+
+#endif /* __LUNAIX_ARCH_HART_H */
iexecp:
iesp:
.struct iesp + regsize
-isave_prev:
- .struct isave_prev + regsize
+isave_parent:
+ .struct isave_parent + regsize
ivec:
.struct ivec + regsize
iecode:
/* struct layout: critical section of struct proc_info */
.struct 0
-thread_intr_ctx:
- .struct thread_intr_ctx + regsize
+thread_hstate:
+ .struct thread_hstate + regsize
thread_ustack_top:
/* struct layout: proc_sig */
.struct psig_sigact + regsize
psig_sighand:
.struct psig_sighand + regsize
-psig_saved_ictx:
\ No newline at end of file
+psig_saved_hstate:
\ No newline at end of file
+++ /dev/null
-#ifndef __LUNAIX_INTERRUPTS_H
-#define __LUNAIX_INTERRUPTS_H
-
-#include "vectors.h"
-
-#ifndef __ASM__
-#include <lunaix/compiler.h>
-#include <sys/cpu.h>
-
-struct exec_param;
-
-struct regcontext
-{
- u32_t eax;
- u32_t ebx;
- u32_t ecx;
- u32_t edx;
- u32_t edi;
- u32_t ebp;
- u32_t esi;
- u32_t ds;
- u32_t es;
- u32_t fs;
- u32_t gs;
-} compact;
-
-struct pcontext
-{
- unsigned int depth;
- struct regcontext registers;
- union
- {
- u32_t esp;
- volatile struct exec_param* execp;
- };
-} compact;
-
-struct exec_param
-{
- struct pcontext* saved_prev_ctx;
- u32_t vector;
- u32_t err_code;
- u32_t eip;
- u32_t cs;
- u32_t eflags;
- u32_t esp;
- u32_t ss;
-} compact;
-
-#define saved_fp(isrm) ((isrm)->registers.ebp)
-#define kernel_context(isrm) (!(((isrm)->execp->cs) & 0b11))
-
-#endif
-
-#endif /* __LUNAIX_INTERRUPTS_H */
#ifndef __LUNAIX_IOAPIC_H
#define __LUNAIX_IOAPIC_H
-#include <hal/intc.h>
+#include "sys/x86_isa.h"
void
ioapic_init();
void
-ioapic_irq_remap(struct intc_context*,
+ioapic_irq_remap(struct x86_intc*,
int irq,
int iv,
cpu_t dest,
-#ifndef __LUNAIX_MEMORY_H
-#define __LUNAIX_MEMORY_H
+#ifndef __LUNAIX_ARCH_MEMORY_H
+#define __LUNAIX_ARCH_MEMORY_H
#include <lunaix/mm/pagetable.h>
#include <lunaix/mann_flags.h>
}
-#endif /* __LUNAIX_MEMORY_H */
+#endif /* __LUNAIX_ARCH_MEMORY_H */
#ifndef __LUNAIX_MEMPART_H
#define __LUNAIX_MEMPART_H
-/* Physical Adress Space Partition */
-/* Generated from mempart.h.j2. Do NOT modify */
#define MEM_PAGE 0x1000UL
#define MEM_1M 0x100000UL
#define MEM_HUGE 0x400000UL
#define MEM_1G 0x40000000UL
+#define END_POINT(name) (name + name##_SIZE - 1)
+
#define KSTACK_AREA 0x100000UL
#define KSTACK_AREA_SIZE 0x300000UL
-#define KSTACK_AREA_END 0x3ffff0UL
+#define KSTACK_AREA_END END_POINT(KSTACK_AREA)
#define USR_EXEC 0x400000UL
#define USR_EXEC_SIZE 0x20000000UL
-#define USR_EXEC_END 0x203fffffUL
+#define USR_EXEC_END END_POINT(USR_EXEC)
#define USR_MMAP 0x20400000UL
#define USR_MMAP_SIZE 0x9fbc0000UL
-#define USR_MMAP_END 0xbffbffffUL
+#define USR_MMAP_END END_POINT(USR_MMAP)
#define USR_STACK 0xbffc0000UL
#define USR_STACK_SIZE 0x40000UL
-#define USR_STACK_END 0xbffffff0UL
+#define USR_STACK_END END_POINT(USR_STACK)
#define KERNEL_IMG 0xc0000000UL
#define KERNEL_IMG_SIZE 0x4000000UL
-#define KERNEL_IMG_END 0xc3ffffffUL
+#define KERNEL_IMG_END END_POINT(KERNEL_IMG)
#define PG_MOUNT_1 0xc4000000UL
#define PG_MOUNT_1_SIZE 0x1000UL
-#define PG_MOUNT_1_END 0xc4000fffUL
+#define PG_MOUNT_1_END END_POINT(PG_MOUNT_1)
#define PG_MOUNT_2 0xc4001000UL
#define PG_MOUNT_2_SIZE 0x1000UL
-#define PG_MOUNT_2_END 0xc4001fffUL
+#define PG_MOUNT_2_END END_POINT(PG_MOUNT_2)
#define PG_MOUNT_3 0xc4002000UL
#define PG_MOUNT_3_SIZE 0x1000UL
-#define PG_MOUNT_3_END 0xc4002fffUL
+#define PG_MOUNT_3_END END_POINT(PG_MOUNT_3)
#define PG_MOUNT_4 0xc4003000UL
#define PG_MOUNT_4_SIZE 0x1000UL
-#define PG_MOUNT_4_END 0xc4003fffUL
+#define PG_MOUNT_4_END END_POINT(PG_MOUNT_4)
#define PG_MOUNT_VAR 0xc4004000UL
#define PG_MOUNT_VAR_SIZE 0x3fc000UL
-#define PG_MOUNT_VAR_END 0xc43fffffUL
+#define PG_MOUNT_VAR_END END_POINT(PG_MOUNT_VAR)
#define VMAP 0xc4400000UL
#define VMAP_SIZE 0x3b400000UL
-#define VMAP_END 0xff7fffffUL
+#define VMAP_END END_POINT(VMAP)
#define VMS_MOUNT_1 0xff800000UL
#define VMS_MOUNT_1_SIZE 0x400000UL
-#define VMS_MOUNT_1_END 0xffbfffffUL
-
-#define PD_REF 0xffc00000UL
-#define PD_REF_SIZE 0x400000UL
-#define PD_REF_END 0xffffffffUL
+#define VMS_MOUNT_1_END END_POINT(VMS_MOUNT_1)
#endif
\ No newline at end of file
#include <lunaix/ds/llist.h>
#include "mm_defs.h"
-#define MAX_GROUP_PAGE_SIZE ( 0x8000 )
#define PPLIST_STARTVM VMAP
struct ppage_arch
port_wrdword(PCI_CONFIG_DATA, data);
}
-/**
- * @brief 配置并启用设备MSI支持。
- * 参阅:PCI LB Spec. (Rev 3) Section 6.8 & 6.8.1
- * 以及:Intel Manual, Vol 3, Section 10.11
- *
- * @param device PCI device
- * @param vector interrupt vector.
- */
-void
-pci_setup_msi(struct pci_device* device, int vector);
+static inline u16_t
+pci_config_msi_data(int vector) {
+ return vector;
+}
+
+static inline ptr_t
+pci_get_msi_base() {
+ return 0xFEE00000;
+}
+
#endif /* __LUNAIX_PCI_HBA_H */
#define APIC_SPIV_IV 252
#define APIC_TIMER_IV 253
-#define PC_AT_IRQ_RTC 8
-#define PC_AT_IRQ_KBD 1
-
// clang-format on
#endif /* __LUNAIX_VECTORS_H */
#ifndef __ASM__
#include <lunaix/types.h>
+
+#define IRQ_TRIG_EDGE 0b0
+#define IRQ_TRIG_LEVEL 0b1
+
+#define IRQ_TYPE_FIXED (0b01 << 1)
+#define IRQ_TYPE_NMI (0b11 << 1)
+#define IRQ_TYPE (0b11 << 1)
+
+#define IRQ_VE_HI (0b1 << 3)
+#define IRQ_VE_LO (0b0 << 3)
+
+#define IRQ_DEFAULT (IRQ_TRIG_EDGE | IRQ_TYPE_FIXED | IRQ_VE_HI)
+
+
struct x86_tss
{
u32_t link;
} __attribute__((packed));
void tss_update_esp(u32_t esp0);
+
+struct x86_intc
+{
+ char* name;
+ void* data;
+
+ void (*irq_attach)(struct x86_intc*,
+ int irq,
+ int iv,
+ cpu_t dest,
+ u32_t flags);
+ void (*notify_eoi)(struct x86_intc*, cpu_t id, int iv);
+};
+
+
#endif
#endif /* __LUNAIX_I386_ASM_H */
--- /dev/null
+#include <lunaix/types.h>
+#include <klibc/crc.h>
+
+#ifdef CONFIG_X86_SSE4
+unsigned int
+crc32b(unsigned char* data, unsigned int size)
+{
+ unsigned int ret;
+ asm volatile(
+ "xorl %%ebx, %%ebx\n"
+ "xorl %%eax, %%eax\n"
+ "1:\n"
+ "crc32 (%%edx, %%ebx, 1), %%eax\n"
+ "incl %%ebx\n"
+ "cmpl %%ebx, %%ecx\n"
+ "jne 1b\n"
+ : "=a"(ret)
+ : "d"((ptr_t)data),
+ "c"(size)
+ :
+ );
+ return ret;
+}
+#endif
\ No newline at end of file
--- /dev/null
+#include <klibc/string.h>
+
+void*
+memcpy(void* dest, const void* src, unsigned long num)
+{
+ if (!num)
+ return dest;
+
+ asm volatile("movl %1, %%edi\n"
+ "rep movsb\n" ::"S"(src),
+ "r"(dest),
+ "c"(num)
+ : "edi", "memory");
+ return dest;
+}
+
+void*
+memset(void* ptr, int value, unsigned long num)
+{
+ asm volatile("movl %1, %%edi\n"
+ "rep stosb\n" ::"c"(num),
+ "r"(ptr),
+ "a"(value)
+ : "edi", "memory");
+ return ptr;
+}
\ No newline at end of file
#include <lunaix/mm/fault.h>
#include <lunaix/mm/region.h>
#include <lunaix/process.h>
-#include <lunaix/pcontext.h>
+#include <lunaix/hart_state.h>
#include <sys/mm/mm_defs.h>
bool
__arch_prepare_fault_context(struct fault_context* fault)
{
- isr_param* ictx = fault->ictx;
+ struct hart_state* ictx = fault->hstate;
ptr_t ptr = cpu_ldeaddr();
if (!ptr) {
#include <lunaix/types.h>
-#include <sys/x86_isa.h>
+#include "sys/x86_isa.h"
#define SD_TYPE(x) (x << 8)
#define SD_CODE_DATA(x) (x << 12)
syscall_hndlr:
pushl %ebp
movl %esp, %ebp
- movl 8(%esp), %ebx // isr_param*
+ movl 8(%esp), %ebx // struct hart_state*
addl $4, %ebx
movl (%ebx), %eax /* eax: call code as well as the return value from syscall */
--- /dev/null
+#include <lunaix/trace.h>
+
+void
+trace_print_transistion_short(struct hart_state* hstate)
+{
+ trace_log(" trigger: iv=%d, ecause=%p",
+ hart_vector_stamp(hstate),
+ hart_ecause(hstate));
+}
+
+void
+trace_print_transition_full(struct hart_state* hstate)
+{
+ trace_log("hart state transition");
+ trace_log(" vector=%d, ecause=0x%x",
+ hart_vector_stamp(hstate),
+ hart_ecause(hstate));
+ trace_log(" eflags=0x%x", hstate->execp->eflags);
+ trace_log(" sp=%p, [seg_sel=0x%04x]",
+ hstate->execp->esp,
+ hstate->execp->esp);
+ trace_log(" ip=%p, seg_sel=0x%04x",
+ hstate->execp->eip,
+ hstate->execp->cs);
+}
+
+void
+trace_dump_state(struct hart_state* hstate)
+{
+ struct regcontext* rh = &hstate->registers;
+ struct exec_param* ep = hstate->execp;
+ trace_log("hart state dump (depth=%d)", hstate->depth);
+ trace_log(" eax=0x%08x, ebx=0x%08x, ecx=0x%08x",
+ rh->eax, rh->ebx, rh->ecx);
+ trace_log(" edx=0x%08x, ebp=0x%08x",
+ rh->edx, rh->ebp);
+ trace_log(" ds=0x%04x, edi=0x%08x",
+ rh->ds, rh->edi);
+ trace_log(" es=0x%04x, esi=0x%08x",
+ rh->es, rh->esi);
+ trace_log(" fs=0x%04x, gs=0x%x",
+ rh->fs, rh->gs);
+ trace_log(" cs=0x%04x, ip=0x%08x",
+ ep->cs, ep->eip);
+ trace_log(" [ss=0x%04x],sp=0x%08x",
+ ep->ss, ep->eip);
+ trace_log(" eflags=0x%08x",
+ ep->eflags);
+}
\ No newline at end of file
#include <klibc/string.h>
#include <lunaix/block.h>
-#include <lunaix/isrm.h>
+#include <lunaix/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/isrm.h>
+#include <lunaix/generic/isrm.h>
#include <lunaix/mm/valloc.h>
#include <lunaix/syslog.h>
LOG_MODULE("io_evt")
void
-ahci_hba_isr(const isr_param* param)
+ahci_hba_isr(const struct hart_state* hstate)
{
struct ahci_hba* hba;
struct ahci_driver *pos, *n;
- struct llist_header* ahcis = (struct llist_header*)isrm_get_payload(param);
+ struct llist_header* ahcis = (struct llist_header*)isrm_get_payload(hstate);
llist_for_each(pos, n, ahcis, ahci_drvs)
{
- if (pos->id == (int)param->execp->vector) {
+ if (pos->id == hart_vector_stamp(hstate)) {
hba = &pos->hba;
goto proceed;
}
*
*/
#include <lunaix/device.h>
-#include <lunaix/isrm.h>
+#include <lunaix/generic/isrm.h>
#include <sys/port_io.h>
}
static void
-com_irq_handler(const isr_param* param)
+com_irq_handler(const struct hart_state* hstate)
{
- uart_general_irq_handler(param->execp->vector, &com_ports);
+ int vector = hart_vector_stamp(hstate);
+ uart_general_irq_handler(vector, &com_ports);
}
static int
+++ /dev/null
-#include <hal/intc.h>
-#include <lunaix/spike.h>
-
-#include <sys/vectors.h>
-
-struct intc_context arch_intc_ctx;
-
-void
-intc_irq_attach(int irq, int iv, cpu_t dest, u32_t flags)
-{
- arch_intc_ctx.irq_attach(&arch_intc_ctx, irq, iv, dest, flags);
-}
-
-void
-intc_notify_eoi(cpu_t id, int iv)
-{
- arch_intc_ctx.notify_eoi(&arch_intc_ctx, id, iv);
-}
-
-void
-intc_notify_eos(cpu_t id)
-{
- intc_notify_eoi(id, LUNAIX_SCHED);
-}
\ No newline at end of file
}
}
+void
+pci_setup_msi(struct pci_device* device, int vector)
+{
+ // PCI LB Spec. (Rev 3) Section 6.8 & 6.8.1
+
+ ptr_t msi_addr = pci_get_msi_base();
+ u32_t msi_data = pci_config_msi_data(vector);
+
+ pci_reg_t reg1 = pci_read_cspace(device->cspace_base, device->msi_loc);
+ pci_reg_t msg_ctl = reg1 >> 16;
+ int offset_cap64 = !!(msg_ctl & MSI_CAP_64BIT) * 4;
+
+ pci_write_cspace(device->cspace_base,
+ PCI_MSI_ADDR_LO(device->msi_loc),
+ msi_addr);
+
+ if (offset_cap64) {
+ pci_write_cspace(device->cspace_base,
+ PCI_MSI_ADDR_HI(device->msi_loc),
+ (u64_t)msi_addr >> 32);
+ }
+
+ pci_write_cspace(device->cspace_base,
+ PCI_MSI_DATA(device->msi_loc, offset_cap64),
+ msi_data & 0xffff);
+
+ if ((msg_ctl & MSI_CAP_MASK)) {
+ pci_write_cspace(
+ device->cspace_base, PCI_MSI_MASK(device->msi_loc, offset_cap64), 0);
+ }
+
+ // manipulate the MSI_CTRL to allow device using MSI to request service.
+ reg1 = (reg1 & 0xff8fffff) | 0x10000;
+ pci_write_cspace(device->cspace_base, device->msi_loc, reg1);
+}
+
void
pci_probe_msi_info(struct pci_device* device)
{
void
hwtimer_init(u32_t hertz, void* tick_callback)
{
- struct hwtimer* hwt_ctx = hwtimer_choose();
+ struct hwtimer* hwt_ctx = select_platform_timer();
hwt_ctx->init(hwt_ctx, hertz, tick_callback);
hwt_ctx->running_freq = hertz;
#define __LUNAIX_AHCI_H
#include "hba.h"
-#include <lunaix/isrm.h>
+#include <lunaix/generic/isrm.h>
/*
* Macro naming rule:
ahci_driver_init(struct ahci_driver_param* param);
void
-ahci_hba_isr(const isr_param* param);
+ahci_hba_isr(const struct hart_state* hstate);
#endif /* __LUNAIX_AHCI_H */
hwtimer_init(u32_t hertz, void* tick_callback);
struct hwtimer*
-hwtimer_choose();
+select_platform_timer();
ticks_t
hwtimer_base_frequency();
+++ /dev/null
-#ifndef __LUNAIX_INTC_H
-#define __LUNAIX_INTC_H
-
-#include <lunaix/types.h>
-
-#define IRQ_TRIG_EDGE 0b0
-#define IRQ_TRIG_LEVEL 0b1
-
-#define IRQ_TYPE_FIXED (0b01 << 1)
-#define IRQ_TYPE_NMI (0b11 << 1)
-#define IRQ_TYPE (0b11 << 1)
-
-#define IRQ_VE_HI (0b1 << 3)
-#define IRQ_VE_LO (0b0 << 3)
-
-#define IRQ_DEFAULT (IRQ_TRIG_EDGE | IRQ_TYPE_FIXED | IRQ_VE_HI)
-
-struct intc_context
-{
- char* name;
- void* data;
-
- void (*irq_attach)(struct intc_context*,
- int irq,
- int iv,
- cpu_t dest,
- u32_t flags);
- void (*notify_eoi)(struct intc_context*, cpu_t id, int iv);
-};
-
-void
-intc_init();
-
-void
-intc_irq_attach(int irq, int iv, cpu_t dest, u32_t flags);
-
-/**
- * @brief Notify end of interrupt event
- *
- * @param id
- */
-void
-intc_notify_eoi(cpu_t id, int iv);
-
-/**
- * @brief Notify end of scheduling event
- *
- * @param id
- */
-void
-intc_notify_eos(cpu_t id);
-
-#endif /* __LUNAIX_INTC_H */
#define PCI_BAR_ADDR_MM(x) ((x) & ~0xf)
#define PCI_BAR_ADDR_IO(x) ((x) & ~0x3)
-#define PCI_MSI_ADDR(msi_base) ((msi_base) + 4)
+#define PCI_MSI_ADDR_LO(msi_base) ((msi_base) + 4)
+#define PCI_MSI_ADDR_HI(msi_base) ((msi_base) + 8)
#define PCI_MSI_DATA(msi_base, offset) ((msi_base) + 8 + offset)
#define PCI_MSI_MASK(msi_base, offset) ((msi_base) + 0xc + offset)
void
pci_probe_bar_info(struct pci_device* device);
+void
+pci_setup_msi(struct pci_device* device, int vector);
+
void
pci_probe_msi_info(struct pci_device* device);
+++ /dev/null
-#ifndef __LUNAIX_MC146818A_H
-#define __LUNAIX_MC146818A_H
-
-/*
- FIXME the drivers should go into ldga
-*/
-
-#include <hal/hwrtc.h>
-
-struct hwrtc*
-mc146818a_rtc_context();
-
-#endif /* __LUNAIX_MC146818A_H */
#ifndef __LUNAIX_CRC_H
#define __LUNAIX_CRC_H
+
unsigned int
crc32b(unsigned char* data, unsigned int size);
--- /dev/null
+#ifndef __LUNAIX_IAUTILS_H
+#define __LUNAIX_IAUTILS_H
+
+char* itoa(int value, char* str, int base);
+
+#endif /* __LUNAIX_IAUTILS_H */
+++ /dev/null
-#ifndef __LUNAIX_STDLIB_H
-#define __LUNAIX_STDLIB_H
-
-#ifdef __LUNAIX_LIBC
-char* __uitoa_internal(unsigned int value, char* str, int base, unsigned int* size);
-char* __itoa_internal(int value, char* str, int base, unsigned int* size);
-#endif
-
-char* itoa(int value, char* str, int base);
-
-#endif /* __LUNAIX_STDLIB_H */
#ifndef __LUNAIX_HASHTABLE_H
#define __LUNAIX_HASHTABLE_H
-#include <lib/hash.h>
+#include <klibc/hash.h>
#include <lunaix/ds/llist.h>
struct hbucket
#ifndef __LUNAIX_HSTR_H
#define __LUNAIX_HSTR_H
-#include <lib/hash.h>
+#include <klibc/hash.h>
#define HSTR_FULL_HASH 32
#define __LUNAIX_ISRM_H
#include <lunaix/types.h>
-#include <lunaix/pcontext.h>
+#include <lunaix/hart_state.h>
-typedef void (*isr_cb)(const isr_param*);
+typedef void (*isr_cb)(const struct hart_state*);
void
isrm_init();
isrm_get(int iv);
ptr_t
-isrm_get_payload(const isr_param*);
+isrm_get_payload(const struct hart_state*);
void
isrm_set_payload(int iv, ptr_t);
+void
+isrm_irq_attach(int irq, int iv, cpu_t dest, u32_t flags);
+
+/**
+ * @brief Notify end of interrupt event
+ *
+ * @param id
+ */
+void
+isrm_notify_eoi(cpu_t id, int iv);
+
+/**
+ * @brief Notify end of scheduling event
+ *
+ * @param id
+ */
+void
+isrm_notify_eos(cpu_t id);
+
#endif /* __LUNAIX_ISRM_H */
--- /dev/null
+#ifndef __LUNAIX_TRACE_ARCH_H
+#define __LUNAIX_TRACE_ARCH_H
+
+#include <lunaix/hart_state.h>
+
+void
+trace_print_transistion_short(struct hart_state* hstate);
+
+void
+trace_print_transition_full(struct hart_state* hstate);
+
+void
+trace_dump_state(struct hart_state* hstate);
+
+#endif /* __LUNAIX_TRACE_ARCH_H */
struct exec_param;
struct regcontext;
-struct pcontext;
-typedef struct pcontext isr_param;
+struct hart_state;
#include <lunaix/compiler.h>
-#include <sys/interrupts.h>
+#include <sys/hart.h>
-struct transfer_context
+struct hart_transition
{
ptr_t inject;
struct {
- struct pcontext isr;
+ struct hart_state state;
struct exec_param eret;
} compact transfer;
};
bool
-inject_transfer_context(ptr_t vm_mnt, struct transfer_context* tctx);
+install_hart_transition(ptr_t vm_mnt, struct hart_transition* tctx);
void
-thread_setup_trasnfer(struct transfer_context* tctx,
+hart_prepare_transition(struct hart_transition* tctx,
ptr_t kstack_tp, ptr_t ustack_pt,
ptr_t entry, bool to_user);
static inline void
-thread_create_user_transfer(struct transfer_context* tctx,
+hart_user_transfer(struct hart_transition* tctx,
ptr_t kstack_tp, ptr_t ustack_pt,
ptr_t entry)
{
- thread_setup_trasnfer(tctx, kstack_tp, ustack_pt, entry, true);
+ hart_prepare_transition(tctx, kstack_tp, ustack_pt, entry, true);
}
static inline void
-thread_create_kernel_transfer(struct transfer_context* tctx,
+hart_kernel_transfer(struct hart_transition* tctx,
ptr_t kstack_tp, ptr_t entry)
{
- thread_setup_trasnfer(tctx, kstack_tp, 0, entry, false);
+ hart_prepare_transition(tctx, kstack_tp, 0, entry, false);
}
#endif /* __LUNAIX_CONTEXT_H */
#include <lunaix/mm/mm.h>
#include <lunaix/mm/page.h>
#include <lunaix/mm/procvm.h>
-#include <lunaix/pcontext.h>
+#include <lunaix/hart_state.h>
#define RESOLVE_OK ( 0b000001 )
#define NO_PREALLOC ( 0b000010 )
struct fault_context
{
- isr_param* ictx;
+ struct hart_state* hstate;
struct
{
#include <lunaix/timer.h>
#include <lunaix/types.h>
#include <lunaix/spike.h>
-#include <lunaix/pcontext.h>
+#include <lunaix/hart_state.h>
#include <stdint.h>
int sig_num;
void* sigact;
void* sighand;
- isr_param* saved_ictx;
+ struct hart_state* saved_hstate;
} __attribute__((packed));
*/
struct
{
- isr_param* intr_ctx;
+ struct hart_state* hstate;
ptr_t ustack_top;
}; // *critical section
};
struct proc_mm* mm;
- struct sigregister* sigreg;
+ struct sigregistry* sigreg;
struct v_fdtable* fdtable;
struct v_dnode* cwd;
struct {
static inline struct sigact*
active_signal(struct thread* thread) {
struct sigctx* sigctx = &thread->sigctx;
- struct sigregister* sigreg = thread->process->sigreg;
+ struct sigregistry* sigreg = thread->process->sigreg;
return sigreg->signals[sigctx->sig_active];
}
pid_t sender;
};
-struct sigregister {
+struct sigregistry {
struct sigact* signals[_SIG_NUM];
};
signal_dup_context(struct sigctx* dest_ctx);
void
-signal_dup_registers(struct sigregister* dest_reg);
+signal_dup_registry(struct sigregistry* dest_reg);
void
signal_reset_context(struct sigctx* sigctx);
void
-signal_reset_register(struct sigregister* sigreg);
+signal_reset_registry(struct sigregistry* sigreg);
void
-signal_free_registers(struct sigregister* sigreg);
+signal_free_registry(struct sigregistry* sigreg);
#endif /* __LUNAIX_SIGNAL_H */
#include <lunaix/ds/llist.h>
#include <lunaix/time.h>
-#include <lunaix/pcontext.h>
+#include <lunaix/hart_state.h>
#define SYS_TIMER_FREQUENCY_HZ 1000
#define __LUNAIX_TRACE_H
#include <lunaix/boot_generic.h>
-#include <lunaix/pcontext.h>
+#include <lunaix/hart_state.h>
+#include <lunaix/generic/trace_arch.h>
struct ksym_entry
{
* @param isrm
*/
void
-trace_printstack_isr(const isr_param* isrm);
+trace_printstack_isr(const struct hart_state* hstate);
/**
* @brief Print the stack trace starting from caller's frame pointer.
void
trace_printstack();
+void
+trace_log(const char* fmt, ...);
+
#endif /* __LUNAIX_TRACE_H */
typedef unsigned int u32_t;
typedef unsigned long long u64_t;
typedef unsigned long ptr_t;
+typedef unsigned long reg_t;
typedef int pid_t;
typedef signed long ssize_t;
-// typedef unsigned long size_t;
-// typedef unsigned long off_t;
typedef unsigned int cpu_t;
#ifndef __LUNAIX_GDBSTUB_H
#define __LUNAIX_GDBSTUB_H
-#include <lunaix/pcontext.h>
+#include <lunaix/hart_state.h>
+#include <hal/serial.h>
+
+struct gdb_state
+{
+ int signum;
+ struct serial_dev* sdev;
+ reg_t registers[GDB_CPU_NUM_REGISTERS];
+};
void
-gdbstub_loop(isr_param* param);
+gdbstub_loop(struct hart_state* hstate);
#endif /* __LUNAIX_GDBSTUB_H */
#ifndef __LUNAIX_LSDBG_H
#define __LUNAIX_LSDBG_H
-#include <lunaix/pcontext.h>
+#include <lunaix/hart_state.h>
#define SDBG_CLNT_HI 0x10
#define SDBG_CLNT_QUIT 0xff
#define SDBG_STATE_WAIT_BRK 2
void
-lunaix_sdbg_loop(isr_param* param);
+lunaix_sdbg_loop(struct hart_state* hstate);
#endif /* __LUNAIX_LSDBG_H */
#include <sys/muldiv64.h>
-#include <lib/crc.h>
+#include <klibc/crc.h>
#define GPT_BLKSIZE 512
#define LBA2OFF(lba) ((lba) * GPT_BLKSIZE)
#include <hal/ahci/hba.h>
-#include <lib/crc.h>
+#include <klibc/crc.h>
#include <lunaix/blkpart_gpt.h>
#include <lunaix/block.h>
void
do_failsafe_unrecoverable(ptr_t frame_link, ptr_t stack_link)
{
+ ERROR("------- [cut here] ------- \n");
ERROR("diagnositic mode");
-
ERROR("check: init stack: %s",
check_bootstack_sanity() ? "ok" : "smashing");
// TODO ...check other invariants
+ if (current_thread && current_thread->hstate)
+ {
+ struct hart_state* hstate = current_thread->hstate;
+
+ trace_print_transition_full(hstate);
+ ERROR("++++++");
- ERROR("non recoverable: Nightmare Moon arrival.");
+ trace_dump_state(hstate);
+ ERROR("++++++");
+ }
trace_printstack();
-
+ ERROR("++++++");
+
+ ERROR("non recoverable: Nightmare Moon arrival.");
spin();
}
\ No newline at end of file
#include <hal/serial.h>
#include <klibc/string.h>
#include <sdbg/gdbstub.h>
-#include <sys/port_io.h>
-
-/*****************************************************************************
- * Types
- ****************************************************************************/
-#ifndef GDBSTUB_DONT_DEFINE_STDINT_TYPES
-typedef unsigned char u8_t;
-typedef unsigned short u16_t;
-typedef unsigned long uint32_t;
-#endif
-
-typedef unsigned int address;
-typedef unsigned int reg;
-
-enum GDB_REGISTER
-{
- GDB_CPU_I386_REG_EAX = 0,
- GDB_CPU_I386_REG_ECX = 1,
- GDB_CPU_I386_REG_EDX = 2,
- GDB_CPU_I386_REG_EBX = 3,
- GDB_CPU_I386_REG_ESP = 4,
- GDB_CPU_I386_REG_EBP = 5,
- GDB_CPU_I386_REG_ESI = 6,
- GDB_CPU_I386_REG_EDI = 7,
- GDB_CPU_I386_REG_PC = 8,
- GDB_CPU_I386_REG_PS = 9,
- GDB_CPU_I386_REG_CS = 10,
- GDB_CPU_I386_REG_SS = 11,
- GDB_CPU_I386_REG_DS = 12,
- GDB_CPU_I386_REG_ES = 13,
- GDB_CPU_I386_REG_FS = 14,
- GDB_CPU_I386_REG_GS = 15,
- GDB_CPU_NUM_REGISTERS = 16
-};
-
-struct gdb_state
-{
- int signum;
- struct serial_dev* sdev;
- reg registers[GDB_CPU_NUM_REGISTERS];
-};
-
-/*****************************************************************************
- *
- * GDB Remote Serial Protocol
- *
- ****************************************************************************/
+#include <sys/port_io.h>
+#include <sys/cpu.h>
+#include <sys/gdbstub.h>
/*****************************************************************************
* Macros
#define GDB_PRINT(...)
-#define COM_PORT SERIAL_COM1
-
#define GDB_EOF (-1)
-#ifndef NULL
-#define NULL ((void*)0)
-#endif
-
#ifndef GDB_ASSERT
#define GDB_ASSERT(x) \
do { \
int
gdb_sys_putchar(struct gdb_state* state, int ch);
int
-gdb_sys_mem_readb(struct gdb_state* state, address addr, char* val);
-int
-gdb_sys_mem_writeb(struct gdb_state* state, address addr, char val);
-int
-gdb_sys_continue(struct gdb_state* state);
+gdb_sys_mem_readb(struct gdb_state* state, ptr_t addr, char* val);
int
-gdb_sys_step(struct gdb_state* state);
+gdb_sys_mem_writeb(struct gdb_state* state, ptr_t addr, char val);
+
/*****************************************************************************
* Types
unsigned int buf_len,
unsigned int len);
-/* String processing helper functions */
-static int
-gdb_strlen(const char* ch);
+
static char
gdb_get_digit(int val);
static int
gdb_mem_read(struct gdb_state* state,
char* buf,
unsigned int buf_len,
- address addr,
+ ptr_t addr,
unsigned int len,
gdb_enc_func enc);
static int
gdb_mem_write(struct gdb_state* state,
const char* buf,
unsigned int buf_len,
- address addr,
+ ptr_t addr,
unsigned int len,
gdb_dec_func dec);
static int
* String Processing Helper Functions
****************************************************************************/
-/*
- * Get null-terminated string length.
- */
-static int
-gdb_strlen(const char* ch)
-{
- int len;
-
- len = 0;
- while (*ch++) {
- len += 1;
- }
-
- return len;
-}
-
/*
* Get integer value for a string representation.
*
gdb_mem_read(struct gdb_state* state,
char* buf,
unsigned int buf_len,
- address addr,
+ ptr_t addr,
unsigned int len,
gdb_enc_func enc)
{
gdb_mem_write(struct gdb_state* state,
const char* buf,
unsigned int buf_len,
- address addr,
+ ptr_t addr,
unsigned int len,
gdb_dec_func dec)
{
}
buf[0] = 'O';
- status = gdb_enc_hex(&buf[1], buf_len - 1, msg, gdb_strlen(msg));
+ status = gdb_enc_hex(&buf[1], buf_len - 1, msg, strlen(msg));
if (status == GDB_EOF) {
return GDB_EOF;
}
int
gdb_main(struct gdb_state* state)
{
- address addr;
+ ptr_t addr;
char pkt_buf[256];
int status;
unsigned int length;
return 0;
}
-/*****************************************************************************
- * Types
- ****************************************************************************/
-
-struct gdb_idtr
-{
- u16_t len;
- uint32_t offset;
-} __attribute__((packed));
-
-struct gdb_idt_gate
-{
- u16_t offset_low;
- u16_t segment;
- u16_t flags;
- u16_t offset_high;
-} __attribute__((packed));
-
-/*****************************************************************************
- * Prototypes
- ****************************************************************************/
-#define gdb_x86_io_write_8(port, val) port_wrbyte(port, val)
-#define gdb_x86_io_read_8(port) port_rdbyte(port)
-
-#define gdb_x86_serial_getc() serial_rx_byte(COM_PORT)
-#define gdb_x86_serial_putchar(ch) serial_tx_byte(COM_PORT, ch)
-
-#ifdef __STRICT_ANSI__
-#define asm __asm__
-#endif
static struct gdb_state gdb_state;
static volatile int start_debugging = 0;
* Debug interrupt handler.
*/
void
-gdbstub_loop(isr_param* param)
+gdbstub_loop(struct hart_state* hstate)
{
- /* Translate vector to signal */
- switch (param->execp->vector) {
- case 1:
- gdb_state.signum = 5;
- break;
- case 3:
- gdb_state.signum = 5;
- break;
- default:
- gdb_state.signum = 7;
- }
-
- /* Load Registers */
- gdb_state.registers[GDB_CPU_I386_REG_EAX] = param->registers.eax;
- gdb_state.registers[GDB_CPU_I386_REG_ECX] = param->registers.ecx;
- gdb_state.registers[GDB_CPU_I386_REG_EDX] = param->registers.edx;
- gdb_state.registers[GDB_CPU_I386_REG_EBX] = param->registers.ebx;
- gdb_state.registers[GDB_CPU_I386_REG_ESP] = param->esp;
- gdb_state.registers[GDB_CPU_I386_REG_EBP] = param->registers.ebp;
- gdb_state.registers[GDB_CPU_I386_REG_ESI] = param->registers.esi;
- gdb_state.registers[GDB_CPU_I386_REG_EDI] = param->registers.edi;
- gdb_state.registers[GDB_CPU_I386_REG_PC] = param->execp->eip;
- gdb_state.registers[GDB_CPU_I386_REG_CS] = param->execp->cs;
- gdb_state.registers[GDB_CPU_I386_REG_PS] = param->execp->eflags;
- gdb_state.registers[GDB_CPU_I386_REG_SS] = param->execp->ss;
- gdb_state.registers[GDB_CPU_I386_REG_DS] = param->registers.ds;
- gdb_state.registers[GDB_CPU_I386_REG_ES] = param->registers.es;
- gdb_state.registers[GDB_CPU_I386_REG_FS] = param->registers.fs;
- gdb_state.registers[GDB_CPU_I386_REG_GS] = param->registers.gs;
-
+ arch_gdbstub_setup_state(&gdb_state, hstate);
+ arch_gdbstub_save_regs(&gdb_state, hstate);
+
gdb_main(&gdb_state);
- /* Restore Registers */
- param->registers.eax = gdb_state.registers[GDB_CPU_I386_REG_EAX];
- param->registers.ecx = gdb_state.registers[GDB_CPU_I386_REG_ECX];
- param->registers.edx = gdb_state.registers[GDB_CPU_I386_REG_EDX];
- param->registers.ebx = gdb_state.registers[GDB_CPU_I386_REG_EBX];
- param->esp = gdb_state.registers[GDB_CPU_I386_REG_ESP];
- param->registers.ebp = gdb_state.registers[GDB_CPU_I386_REG_EBP];
- param->registers.esi = gdb_state.registers[GDB_CPU_I386_REG_ESI];
- param->registers.edi = gdb_state.registers[GDB_CPU_I386_REG_EDI];
- param->execp->eip = gdb_state.registers[GDB_CPU_I386_REG_PC];
- param->execp->cs = gdb_state.registers[GDB_CPU_I386_REG_CS];
- param->execp->eflags = gdb_state.registers[GDB_CPU_I386_REG_PS];
- param->execp->ss = gdb_state.registers[GDB_CPU_I386_REG_SS];
- param->registers.ds = gdb_state.registers[GDB_CPU_I386_REG_DS];
- param->registers.es = gdb_state.registers[GDB_CPU_I386_REG_ES];
- param->registers.fs = gdb_state.registers[GDB_CPU_I386_REG_FS];
- param->registers.gs = gdb_state.registers[GDB_CPU_I386_REG_GS];
+ arch_gdbstub_restore_regs(&gdb_state, hstate);
}
/*****************************************************************************
* Read one byte from memory.
*/
int
-gdb_sys_mem_readb(struct gdb_state* state, address addr, char* val)
+gdb_sys_mem_readb(struct gdb_state* state, ptr_t addr, char* val)
{
*val = *(volatile char*)addr;
return 0;
* Write one byte to memory.
*/
int
-gdb_sys_mem_writeb(struct gdb_state* state, address addr, char val)
+gdb_sys_mem_writeb(struct gdb_state* state, ptr_t addr, char val)
{
*(volatile char*)addr = val;
return 0;
}
-
-/*
- * Continue program execution.
- */
-int
-gdb_sys_continue(struct gdb_state* state)
-{
- gdb_state.registers[GDB_CPU_I386_REG_PS] &= ~(1 << 8);
- return 0;
-}
-
-/*
- * Single step the next instruction.
- */
-int
-gdb_sys_step(struct gdb_state* state)
-{
- gdb_state.registers[GDB_CPU_I386_REG_PS] |= 1 << 8;
- return 0;
-}
\ No newline at end of file
+++ /dev/null
-// FIXME Re-design needed!!
-
-#include <hal/serial.h>
-#include <klibc/strfmt.h>
-#include <lunaix/syslog.h>
-#include <sdbg/gdbstub.h>
-#include <sdbg/lsdbg.h>
-#include <sdbg/protocol.h>
-
-#include <lunaix/isrm.h>
-
-// #define USE_LSDBG_BACKEND
-
-LOG_MODULE("SDBG")
-
-volatile int debug_mode = 0;
-
-// begin: @cmc
-#define DBG_START 0x636d6340UL
-
-// begin: @yay
-#define DBG_END 0x79617940UL
-
-static int
-sdbg_serial_callback(struct serial_dev* sdev)
-{
- u32_t dbg_sig = *(u32_t*)sdev->rw.buf;
-
- if (dbg_sig == DBG_START) {
- debug_mode = 1;
- } else if (dbg_sig == DBG_END) {
- debug_mode = 0;
- }
-
- // Debugger should be run later
- // TODO implement a defer execution mechanism (i.e., soft interrupt)
-
- return SERIAL_AGAIN;
-}
-
-void
-sdbg_imm(const isr_param* param)
-{
- struct exec_param* execp = param->execp;
- DEBUG("Quick debug mode\n");
- DEBUG("cs=%p eip=%p eax=%p ebx=%p\n",
- execp->cs,
- execp->eip,
- param->registers.eax,
- param->registers.ebx);
- DEBUG("ecx=%p edx=%p edi=%p esi=%p\n",
- param->registers.ecx,
- param->registers.edx,
- param->registers.edi,
- param->registers.esi);
- DEBUG("u.esp=%p k.esp=%p ebp=%p ps=%p\n",
- param->esp,
- execp->esp,
- param->registers.ebp,
- execp->eflags);
- DEBUG("ss=%p ds=%p es=%p fs=%p gs=%p\n",
- execp->ss,
- param->registers.ds,
- param->registers.es,
- param->registers.fs,
- param->registers.gs);
- while (1)
- ;
-}
-
-static char buf[4];
-
-static void
-__sdbg_breakpoint(const isr_param* param)
-{
- gdbstub_loop(param);
-}
-
-void
-sdbg_init()
-{
- struct serial_dev* sdev = serial_get_avilable();
-
- if (!sdev) {
- ERROR("no serial port available\n");
- return;
- }
-
- kprintf("listening: %s\n", sdev->dev->name.value);
-
- serial_rwbuf_async(sdev, buf, 4, sdbg_serial_callback, SERIAL_RW_RX);
-}
\ No newline at end of file
static struct trace_context trace_ctx;
+void
+trace_log(const char* fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+
+ kprintf_m("TRACE", fmt, args);
+
+ va_end(args);
+}
+
void
trace_modksyms_init(struct boot_handoff* bhctx)
{
trace_print_code_entry(ptr_t sym_pc, ptr_t inst_pc, char* sym)
{
if (sym_pc) {
- DEBUG("%s+%p", sym, inst_pc - sym_pc);
+ trace_log("%s+%p", sym, inst_pc - sym_pc);
} else {
- DEBUG("%s [%p]", sym, sym_pc);
+ trace_log("%s [%p]", sym, sym_pc);
}
}
int n = trace_walkback(tbs, fp, NB_TRACEBACK, &fp);
if (fp) {
- DEBUG("...<truncated>");
+ trace_log("...<truncated>");
}
for (int i = 0; i < n; i++) {
trace_printstack()
{
if (current_thread) {
- trace_printstack_isr(current_thread->intr_ctx);
+ trace_printstack_isr(current_thread->hstate);
}
else {
trace_printstack_of(abi_get_callframe());
}
static void
-trace_printswctx(const isr_param* p, bool from_usr, bool to_usr)
+trace_printswctx(const struct hart_state* hstate, bool from_usr, bool to_usr)
{
- struct ksym_entry* sym = trace_sym_lookup(p->execp->eip);
+ struct ksym_entry* sym = trace_sym_lookup(hstate->execp->eip);
- DEBUG("^^^^^ --- %s", to_usr ? "user" : "kernel");
- DEBUG(" interrupted on #%d, ecode=%p",
- p->execp->vector,
- p->execp->err_code);
- DEBUG("vvvvv --- %s", from_usr ? "user" : "kernel");
+ trace_log("^^^^^ --- %s", to_usr ? "user" : "kernel");
+ trace_print_transistion_short(hstate);
+ trace_log("vvvvv --- %s", from_usr ? "user" : "kernel");
- ptr_t sym_pc = sym ? sym->pc : p->execp->eip;
- trace_print_code_entry(sym_pc, p->execp->eip, ksym_getstr(sym));
+ ptr_t sym_pc = sym ? sym->pc : hart_pc(hstate);
+ trace_print_code_entry(sym_pc, hart_pc(hstate), ksym_getstr(sym));
}
void
-trace_printstack_isr(const isr_param* isrm)
+trace_printstack_isr(const struct hart_state* hstate)
{
- isr_param* p = isrm;
+ struct hart_state* p = hstate;
ptr_t fp = abi_get_callframe();
int prev_usrctx = 0;
- DEBUG("stack trace (pid=%d)\n", __current->pid);
+ trace_log("stack trace (pid=%d)\n", __current->pid);
trace_printstack_of(fp);
trace_printswctx(p, false, true);
}
- fp = saved_fp(p);
+ fp = hart_stack_frame(p);
if (!valid_fp(fp)) {
- DEBUG("??? invalid frame: %p", fp);
+ trace_log("??? invalid frame: %p", fp);
break;
}
prev_usrctx = !kernel_context(p);
- p = p->execp->saved_prev_ctx;
+ p = hart_parent_state(p);
}
- DEBUG("----- [trace end] -----\n");
+ trace_log("----- [trace end] -----\n");
}
\ No newline at end of file
#include <lunaix/fs/twifs.h>
#include <lunaix/status.h>
-#include <lib/hash.h>
+#include <klibc/hash.h>
#include <klibc/strfmt.h>
// we will jump to new entry point (_u_start) upon syscall's
// return so execve 'will not return' from the perspective of it's invoker
- eret_target(current_thread) = container.exe.entry;
- eret_stack(current_thread) = container.stack_top;
+ hart_flow_redirect(current_thread->hstate,
+ container.exe.entry, container.stack_top);
// these become meaningless once execved!
current_thread->ustack_top = 0;
signal_reset_context(¤t_thread->sigctx);
- signal_reset_register(__current->sigreg);
+ signal_reset_registry(__current->sigreg);
done:
// set return value
#include <lunaix/trace.h>
#include <lunaix/tty/tty.h>
#include <lunaix/owloysius.h>
-#include <lunaix/pcontext.h>
+#include <lunaix/hart_state.h>
#include <hal/acpi/acpi.h>
-#include <hal/intc.h>
#include <sys/abi.h>
#include <sys/mm/mm_defs.h>
device_scan_drivers();
- invoke_init_function(on_earlyboot);
-
device_sysconf_load();
- /* Get intc online, this is the cornerstone when initing devices */
- intc_init();
+ invoke_init_function(on_earlyboot);
clock_init();
timer_init();
#include <lunaix/status.h>
#include <lunaix/syslog.h>
#include <lunaix/trace.h>
-#include <lunaix/pcontext.h>
+#include <lunaix/hart_state.h>
#include <lunaix/failsafe.h>
#include <sys/mm/mm_defs.h>
fault->resolving = pte_mkloaded(fault->resolving);
fault->kernel_vmfault = kernel_vmfault;
- fault->kernel_access = kernel_context(fault->ictx);
+ fault->kernel_access = kernel_context(fault->hstate);
return true;
}
failsafe_diagnostic();
}
- trace_printstack_isr(fault->ictx);
+ trace_printstack_isr(fault->hstate);
thread_setsignal(current_thread, _SIGSEGV);
}
void
-intr_routine_page_fault(const isr_param* param)
+intr_routine_page_fault(const struct hart_state* hstate)
{
- if (param->depth > 10) {
+ if (hstate->depth > 10) {
// Too many nested fault! we must messed up something
// XXX should we failed silently?
spin();
}
- struct fault_context fault = { .ictx = param };
+ struct fault_context fault = { .hstate = hstate };
if (!__prepare_fault_context(&fault)) {
__fail_to_resolve(&fault);
return NULL;
}
- th->intr_ctx = current_thread->intr_ctx;
+ th->hstate = current_thread->hstate;
th->kstack = current_thread->kstack;
signal_dup_context(&th->sigctx);
#include <sys/abi.h>
#include <sys/mm/mempart.h>
-#include <hal/intc.h>
#include <sys/cpu.h>
#include <lunaix/fs/taskfs.h>
#include <lunaix/status.h>
#include <lunaix/syscall.h>
#include <lunaix/syslog.h>
-#include <lunaix/pcontext.h>
+#include <lunaix/hart_state.h>
#include <lunaix/kpreempt.h>
+#include <lunaix/generic/isrm.h>
+
#include <klibc/string.h>
struct thread empty_thread_obj;
sched_ctx.procs_index = to_check->process->pid;
done:
- intc_notify_eos(0);
+ isrm_notify_eos(0);
run(to_check);
fail("unexpected return from scheduler");
proc->created = clock_systime();
proc->pgid = proc->pid;
- proc->sigreg = vzalloc(sizeof(struct sigregister));
+ proc->sigreg = vzalloc(sizeof(struct sigregistry));
proc->fdtable = vzalloc(sizeof(struct v_fdtable));
proc->mm = procvm_create(proc);
vfree(proc->fdtable);
- signal_free_registers(proc->sigreg);
+ signal_free_registry(proc->sigreg);
procvm_mount(mm);
return 0;
}
- struct sigregister* sigreg = __current->sigreg;
+ struct sigregistry* sigreg = __current->sigreg;
struct sigctx* psig = ¤t_thread->sigctx;
struct sigact* prev_working = active_signal(current_thread);
sigset_t mask = psig->sig_mask | (prev_working ? prev_working->sa_mask : 0);
sigframe->sigact = action->sa_actor;
sigframe->sighand = action->sa_handler;
- sigframe->saved_ictx = current_thread->intr_ctx;
+ sigframe->saved_hstate = current_thread->hstate;
sigactive_push(current_thread, sig_selected);
}
void
-signal_dup_registers(struct sigregister* dest_reg)
+signal_dup_registry(struct sigregistry* dest_reg)
{
- struct sigregister* oldreg = __current->sigreg;
+ struct sigregistry* oldreg = __current->sigreg;
for (int i = 0; i < _SIG_NUM; i++) {
struct sigact* oldact = oldreg->signals[i];
if (!oldact) {
}
void
-signal_reset_register(struct sigregister* sigreg) {
+signal_reset_registry(struct sigregistry* sigreg) {
for (int i = 0; i < _SIG_NUM; i++) {
struct sigact* act = sigreg->signals[i];
if (act) {
}
void
-signal_free_registers(struct sigregister* sigreg) {
- signal_reset_register(sigreg);
+signal_free_registry(struct sigregistry* sigreg) {
+ signal_reset_registry(sigreg);
vfree(sigreg);
}
schedule();
}
- current_thread->intr_ctx = sig_ctx->saved_ictx;
+ current_thread->hstate = sig_ctx->saved_hstate;
if (proc_terminated(__current)) {
__current->exit_code |= PEXITSIG;
} else if (sigset_test(CORE, sig_ctx->sig_num)) {
signal_terminate(sig_ctx->sig_num);
}
- ptr_t ictx = (ptr_t)current_thread->intr_ctx;
+ ptr_t ictx = (ptr_t)current_thread->hstate;
/*
Ensure our restored context is within kernel stack
LOG_MODULE("THREAD")
static ptr_t
-__alloc_user_thread_stack(struct proc_info* proc, struct mm_region** stack_region, ptr_t vm_mnt)
+__alloc_user_thread_stack(struct proc_info* proc,
+ struct mm_region** stack_region, ptr_t vm_mnt)
{
ptr_t th_stack_top = (proc->thread_count + 1) * USR_STACK_SIZE;
th_stack_top = ROUNDUP(USR_STACK_END - th_stack_top, MEM_PAGE);
.flags = MAP_ANON | MAP_PRIVATE,
.type = REGION_TYPE_STACK };
- int errno = mmap_user((void**)&th_stack_top, &vmr, th_stack_top, NULL, ¶m);
-
+ int errno;
+
+ errno = mmap_user((void**)&th_stack_top, &vmr, th_stack_top, NULL, ¶m);
if (errno) {
WARN("failed to create user thread stack: %d", errno);
return 0;
assert(mm->vm_mnt);
- struct transfer_context transfer;
+ struct hart_transition transition;
if (!kernel_addr(entry)) {
assert(th->ustack);
ptr_t ustack_top = align_stack(th->ustack->end - 1);
ustack_top -= 16; // pre_allocate a 16 byte for inject parameter
- thread_create_user_transfer(&transfer, th->kstack, ustack_top, entry);
+ hart_user_transfer(&transition, th->kstack, ustack_top, entry);
th->ustack_top = ustack_top;
}
else {
- thread_create_kernel_transfer(&transfer, th->kstack, entry);
+ hart_kernel_transfer(&transition, th->kstack, entry);
}
- inject_transfer_context(mm->vm_mnt, &transfer);
- th->intr_ctx = (isr_param*)transfer.inject;
+ install_hart_transition(mm->vm_mnt, &transition);
+ th->hstate = (struct hart_state*)transition.inject;
commit_thread(th);
}
#include <klibc/strfmt.h>
#include <lunaix/spike.h>
-#include <lunaix/pcontext.h>
+#include <lunaix/hart_state.h>
#include <lunaix/syslog.h>
#include <lunaix/trace.h>
#include <lunaix/failsafe.h>
#include <lunaix/spike.h>
#include <lunaix/syslog.h>
#include <lunaix/timer.h>
-#include <lunaix/pcontext.h>
+#include <lunaix/hart_state.h>
#include <hal/hwtimer.h>
-#include <lib/crc.h>
+#include <klibc/crc.h>
+#include <lunaix/compiler.h>
// crc32 lookup table. (https://web.mit.edu/freebsd/head/sys/libkern/crc32.c)
-const unsigned int crc32_tab[] = {
+static const unsigned int crc32_tab[] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
* @param size
* @return unsigned int
*/
-unsigned int
+unsigned int weak
crc32b(unsigned char* data, unsigned int size)
{
unsigned int crc = (unsigned int)-1, i = 0;
-#include <lib/hash.h>
+#include <klibc/hash.h>
+#include <lunaix/compiler.h>
/**
* @brief Simple string hash function
* @param str
* @return unsigned int
*/
-u32_t
+u32_t weak
strhash_32(const char* str, u32_t truncate_to)
{
if (!str)
#define __LUNAIX_LIBC
-#include <klibc/stdlib.h>
+#include <klibc/ia_utils.h>
#include <lunaix/types.h>
char base_char[] = "0123456789abcdefghijklmnopqrstuvwxyz";
-char*
+static char*
__uitoa_internal(unsigned int value, char* str, int base, unsigned int* size)
{
unsigned int ptr = 0;
return str;
}
-char*
+static char*
__itoa_internal(int value, char* str, int base, unsigned int* size)
{
if (value < 0 && base == 10) {
#define __LUNAIX_LIBC
-#include <klibc/stdlib.h>
+#include <klibc/ia_utils.h>
#include <klibc/strfmt.h>
#include <klibc/string.h>
#include <lunaix/types.h>
#include <klibc/string.h>
#include <lunaix/types.h>
-void*
+void* weak
memcpy(void* dest, const void* src, unsigned long num)
{
- if (!num)
- return dest;
- asm volatile("movl %1, %%edi\n"
- "rep movsb\n" ::"S"(src),
- "r"(dest),
- "c"(num)
- : "edi", "memory");
+ for (size_t i = 0; i < num; i++) {
+ ((u8_t*)dest)[i] = ((u8_t*)src)[i];
+ }
+
return dest;
}
-void*
+void* weak
memmove(void* dest, const void* src, unsigned long num)
{
u8_t* dest_ptr = (u8_t*)dest;
return dest;
}
-void*
+void* weak
memset(void* ptr, int value, unsigned long num)
{
- asm volatile("movl %1, %%edi\n"
- "rep stosb\n" ::"c"(num),
- "r"(ptr),
- "a"(value)
- : "edi", "memory");
+ for (size_t i = 0; i < num; i++) {
+ ((u8_t*)ptr)[i] = 0;
+ }
+
return ptr;
}
-int
+int weak
memcmp(const void* ptr1, const void* ptr2, unsigned long num)
{
u8_t* p1 = (u8_t*)ptr1;
#include <klibc/string.h>
#include <lunaix/types.h>
-const char*
+const char* weak
strchr(const char* str, int character)
{
char c = (char)character;
#include <klibc/string.h>
+#include <lunaix/compiler.h>
-int
+int weak
streq(const char* a, const char* b)
{
while (*a == *b) {
#include <klibc/string.h>
+#include <lunaix/compiler.h>
-char*
+char* weak
strcpy(char* dest, const char* src)
{
char c;
return &dest[i];
}
-char*
+char* weak
strncpy(char* dest, const char* src, unsigned long n)
{
char c;
#include <klibc/string.h>
+#include <lunaix/compiler.h>
-unsigned long
+unsigned long weak
strlen(const char* str)
{
unsigned long len = 0;
return len;
}
-unsigned long
+unsigned long weak
strnlen(const char* str, unsigned long max_len)
{
unsigned long len = 0;
#include <klibc/string.h>
+#include <lunaix/compiler.h>
#define WS_CHAR(c) \
(c == ' ' || c == '\t' || c == '\n' || c == '\f' || c == '\v' || c == '\r')
-void
+void weak
strrtrim(char* str)
{
unsigned long l = strlen(str);
str[l + 1] = '\0';
}
-char*
+char* weak
strltrim_safe(char* str)
{
unsigned long l = 0;