about summary refs log tree commit diff stats
path: root/063error.subx
blob: c3d8ca6827735f866b71d99670021ff6302a31f9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# Print an error message and exit.

== code
#   instruction                     effective address                                                   register    displacement    immediate
# . op          subop               mod             rm32          base        index         scale       r32
# . 1-3 bytes   3 bits              2 bits          3 bits        3 bits      3 bits        2 bits      2 bits      0/1/2/4 bytes   0/1/2/4 bytes

# write(out, "Error: "+msg+"\n") then stop(ed, 1)
error:  # ed: (addr exit-descriptor), out: fd or (addr stream byte), msg: (addr array byte)
    # . prologue
    55/push-ebp
    89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
    # write(out, "Error: ")
    # . . push args
    68/push  "Error: "/imm32
    ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           0xc/disp8       .                 # push *(ebp+12)
    # . . call
    e8/call  write/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
    # write(out, msg)
    # . . push args
    ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           0x10/disp8      .                 # push *(ebp+16)
    ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           0xc/disp8       .                 # push *(ebp+12)
    # . . call
    e8/call  write/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
    # write(out, "\n")
    # . . push args
    68/push  Newline/imm32
    ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           0xc/disp8       .                 # push *(ebp+12)
    # . . call
    e8/call  write/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
    # stop(ed, 1)
    # . . push args
    68/push  1/imm32
    ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           8/disp8         .                 # push *(ebp+8)
    # . . call
    e8/call  stop/disp32
    # should never get past this point
$error:dead-end:
    # . epilogue
    89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
    5d/pop-to-ebp
    c3/return

# . . vim:nowrap:textwidth=0
define KERNELMODE 0 #define USERMODE 1 #define MAX_OPENED_FILES 20 #include "common.h" #include "fs.h" #include "fifobuffer.h" #include "spinlock.h" typedef enum ThreadState { TS_RUN, TS_WAITIO, TS_WAITCHILD, TS_SLEEP, TS_SUSPEND, TS_YIELD } ThreadState; struct Process { char name[32]; uint32 pid; uint32 *pd; uint32 b_exec; uint32 e_exec; uint32 b_bss; uint32 e_bss; char *heapBegin; char *heapEnd; char *heapNextUnallocatedPageBegin; uint8 mmappedVirtualMemory[RAM_AS_4M_PAGES / 8]; uint32 signal; void* sigfn[32]; FileSystemNode* tty; FileSystemNode* workingDirectory; //Thread* mainThread; Process* parent; // Save exit status of child process that most recently performed exit(). int32 childExitStatusPresent; // boolean int32 childExitStatus; File* fd[MAX_OPENED_FILES]; } __attribute__ ((packed)); typedef struct Process Process; struct Thread { uint32 threadId; struct { uint32 eax, ecx, edx, ebx; uint32 esp, ebp, esi, edi; uint32 eip, eflags; uint32 cs:16, ss:16, ds:16, es:16, fs:16, gs:16; uint32 cr3; } regs __attribute__ ((packed)); struct { uint32 esp0; uint16 ss0; uint32 stackStart; } kstack __attribute__ ((packed)); uint32 userMode; ThreadState state; Process* owner; uint32 yield; uint32 contextSwitchCount; uint32 totalContextSwitchCount; uint32 totalContextSwitchCountPrevious; void* state_privateData; FifoBuffer* messageQueue; Spinlock messageQueueLock; struct Thread* next; }; typedef struct Thread Thread; typedef struct TimerInt_Registers { uint32 gs, fs, es, ds; uint32 edi, esi, ebp, esp, ebx, edx, ecx, eax; //pushed by pushad uint32 eip, cs, eflags, esp_if_privilege_change, ss_if_privilege_change; //pushed by the CPU } TimerInt_Registers; typedef void (*Function0)(); void initializeTasking(); Process* createUserProcessFromElfData(const char* name, uint8* elfData, char *const argv[], char *const envp[], Process* parent, FileSystemNode* tty); Process* createUserProcessEx(const char* name, uint32 processId, uint32 threadId, Function0 func, uint8* elfData, char *const argv[], char *const envp[], Process* parent, FileSystemNode* tty); void destroyThread(Thread* thread); void destroyProcess(Process* process); void threadStateToString(ThreadState state, uint8* buffer, uint32 bufferSize); void waitForSchedule(); void yield(uint32 count); int32 getEmptyFd(Process* process); int32 addFileToProcess(Process* process, File* file); int32 removeFileFromProcess(Process* process, File* file); Thread* getThreadById(uint32 threadId); Thread* getPreviousThread(Thread* thread); Thread* getMainKernelThread(); Thread* getCurrentThread(); void schedule(TimerInt_Registers* registers); BOOL isThreadValid(Thread* thread); BOOL isProcessValid(Process* process); uint32 getSystemContextSwitchCount(); #endif // PROCESS_H