diff --git a/Makefile b/Makefile index fbb1889d4..ee5139078 100755 --- a/Makefile +++ b/Makefile @@ -46,12 +46,14 @@ run_remote_mon: run_ahci_sata: $(QEMU) $(QEMU_FLAGS) -serial mon:stdio \ - -device ahci,id=ahci \ + -device ahci,id=ahci,debug=3 \ + -trace "ahci*" \ -drive id=thatdisk,file=disk.img,if=none \ -device ide-hd,drive=thatdisk,bus=ahci.0 \ -drive id=thatcdrom,file=/dev/cdrom,if=none \ -device ide-cd,drive=thatcdrom,bus=ahci.1 \ - # -trace "ahci*" \ + # -drive id=thatcdrom,file=TEST.iso,if=none \ + # -device ide-cd,drive=thatcdrom,bus=ahci.1 \ run_disks: $(QEMU) $(QEMU_FLAGS) -serial mon:stdio -hda disk1.img -hdb disk2.img -hdd disk3.img diff --git a/config.mk b/config.mk index c322b1c2b..88faba005 100755 --- a/config.mk +++ b/config.mk @@ -4,7 +4,7 @@ KERNEL = iso/boot/kernel.elf DEBUG =# -ggdb3 #-Werror -MEMORY_SIZE=128M +MEMORY_SIZE?=128M USE_SSE=true COMPILER_DETECTOR_FLAGS = "" @@ -220,7 +220,7 @@ SOURCES=\ OBJS = $(SOURCES:%.c=$(OBJ_DIRECTORY)/%.o) DEPS = $(OBJS:%.o=%.d) -KERNEL_NEED = $(ASM) $(OBJS) $(CPP_CODE) +KERNEL_NEED = $(ASM) $(OBJS) COMMON_FLAGS = -O0 -nostdlib -fno-stack-protector -fno-builtin -Ikernel/include/ -ffreestanding \ -Wall -Wno-div-by-zero -Wno-address-of-packed-member -Wno-implicit-function-declaration \ diff --git a/kernel/asm/64bit_on_32bit.s b/kernel/asm/64bit_on_32bit.s index 6f35f63f8..b33d10a0a 100644 --- a/kernel/asm/64bit_on_32bit.s +++ b/kernel/asm/64bit_on_32bit.s @@ -1,4 +1,4 @@ -# Code from https://github.com/llvm-mirror/compiler-rt/blob/master/lib/builtins/i386/udivdi3.S +# Code from https://github.com/llvm-mirror/compiler-rt/blob/master/lib/builtins/i386/ .text .balign 4 @@ -92,3 +92,97 @@ __udivdi3: movl %ebx, %edx # rhi:alo = qlo*b + rlo with 0 ≤ rlo < b popl %ebx # retl # and return qhi:qlo + + + + +.text +.balign 4 +.global __umoddi3 +__umoddi3: + pushl %ebx + movl 20(%esp), %ebx + bsrl %ebx, %ecx + jz 9f + + movl 16(%esp), %eax + + shrl %cl, %eax + shrl %eax + notl %ecx + shll %cl, %ebx + orl %eax, %ebx + movl 12(%esp), %edx + movl 8(%esp), %eax + cmpl %ebx, %edx + jae 2f + + divl %ebx + + pushl %edi + notl %ecx + shrl %eax + shrl %cl, %eax + movl %eax, %edi + mull 20(%esp) + movl 12(%esp), %ebx + movl 16(%esp), %ecx + subl %eax, %ebx + sbbl %edx, %ecx + movl 24(%esp), %eax + imull %edi, %eax + subl %eax, %ecx + + jnc 1f + addl 20(%esp), %ebx + adcl 24(%esp), %ecx +1: movl %ebx, %eax + movl %ecx, %edx + + popl %edi + popl %ebx + retl + + +2: + subl %ebx, %edx + divl %ebx + + pushl %edi + notl %ecx + shrl %eax + orl $0x80000000, %eax + shrl %cl, %eax + movl %eax, %edi + mull 20(%esp) + movl 12(%esp), %ebx + movl 16(%esp), %ecx + subl %eax, %ebx + sbbl %edx, %ecx + movl 24(%esp), %eax + imull %edi, %eax + subl %eax, %ecx + + jnc 3f + addl 20(%esp), %ebx + adcl 24(%esp), %ecx +3: movl %ebx, %eax + movl %ecx, %edx + + popl %edi + popl %ebx + retl + + +9: + movl 12(%esp), %eax + movl 16(%esp), %ecx + xorl %edx, %edx + divl %ecx + movl %eax, %ebx + movl 8(%esp), %eax + divl %ecx + movl %edx, %eax + popl %ebx + xorl %edx, %edx + retl diff --git a/kernel/asm/switch_task.s b/kernel/asm/switch_task.s index b39ae12af..b37841948 100644 --- a/kernel/asm/switch_task.s +++ b/kernel/asm/switch_task.s @@ -6,68 +6,131 @@ .extern current_proc .extern tss -.global task_switch - -task_switch: - cli - - pushf - - push %ebx - push %esi - push %edi - push %ebp - - # Save current thread - mov current_thread, %edx - - # Save current thread's stack - mov %esp, 28(%edx) - - # current_thread.list_item.next is next entry in list - mov 4(%edx), %ecx - - # Set current_thread to next entry - mov %ecx, current_thread - - # Load thread's stack - mov current_thread, %edx - mov 28(%edx), %esp - - # Load stack_top to tss - mov 40(%edx), %eax - mov $tss, %edx - mov %eax, 4(%edx) - - # WARNING: THIS CODE IS MAY BE BUGGY (NOT TESTED) - # IF YOU HAVING PROBLEMS WITH THIS CODE, PLEASE, REPORT IT TO NDRAEY - # OR REMOVE THESE FOKEN LINES UNTIL THE `popf` INSTRUCTION - - # Load process' page directory - # Load our process structure - mov current_thread, %ebx - mov 12(%ebx), %eax - mov %eax, current_proc - - mov current_proc, %ebx - - # Load our page directory address - mov 12(%ebx), %ebx - - mov %cr3, %eax - cmp %eax, %ebx - - je .no_switch_pd - - mov %ebx, %cr3 - - .no_switch_pd: - - pop %ebp - pop %edi - pop %esi - pop %ebx - - popf - - ret +#.global task_switch +# +#task_switch: +# cli +# +# pushf +# +# push %ebx +# push %esi +# push %edi +# push %ebp +# +# # Save current thread +# mov current_thread, %edx +# +# # Save current thread's stack +# mov %esp, 28(%edx) +# +# # current_thread.list_item.next is next entry in list +# mov 4(%edx), %ecx +# +# # Set current_thread to next entry +# mov %ecx, current_thread +# +# # Load thread's stack +# mov current_thread, %edx +# mov 28(%edx), %esp +# +# # Load stack_top to tss +# mov 40(%edx), %eax +# mov $tss, %edx +# mov %eax, 4(%edx) +# +# # WARNING: THIS CODE IS MAY BE BUGGY (NOT TESTED) +# # IF YOU HAVING PROBLEMS WITH THIS CODE, PLEASE, REPORT IT TO NDRAEY +# # OR REMOVE THESE FOKEN LINES UNTIL THE `popf` INSTRUCTION +# +# # Load process' page directory +# # Load our process structure +# mov current_thread, %ebx +# mov 12(%ebx), %eax +# mov %eax, current_proc +# +# mov current_proc, %ebx +# +# # Load our page directory address +# mov 12(%ebx), %ebx +# +# mov %cr3, %eax +# cmp %eax, %ebx +# +# je .no_switch_pd +# +# mov %ebx, %cr3 +# +# .no_switch_pd: +# +# pop %ebp +# pop %edi +# pop %esi +# pop %ebx +# +# popf +# +# ret + + +.global task_switch_v2 +task_switch_v2: + cli + + pushf + push %ebx + push %esi + push %edi + push %ebp + + mov 24(%esp), %eax # Current task + mov 28(%esp), %ebx # Next task + + cmp %eax, %ebx + je .no_need + + # Save current thread's stack + mov %esp, 28(%eax) + + # Set current_thread to next entry + mov %ebx, current_thread + + # Load thread's stack + mov %ebx, %edx + mov 28(%edx), %esp + + # Load stack_top to tss + mov 40(%edx), %eax + mov $tss, %edx + mov %eax, 4(%edx) + + # Load process' page directory + # Load our process structure + mov current_thread, %ebx + mov 12(%ebx), %eax + mov %eax, current_proc + + mov current_proc, %ebx + + # Load our page directory address + mov 12(%ebx), %ebx + + mov %cr3, %eax + cmp %eax, %ebx + + je .no_need + + mov %ebx, %cr3 + + # .a: jmp .a + + .no_need: + + pop %ebp + pop %edi + pop %esi + pop %ebx + + popf + + ret diff --git a/kernel/include/drv/disk/ahci.h b/kernel/include/drv/disk/ahci.h index 51b7b08dc..21be3b849 100644 --- a/kernel/include/drv/disk/ahci.h +++ b/kernel/include/drv/disk/ahci.h @@ -296,6 +296,8 @@ struct ahci_port_descriptor { size_t fis_virt; size_t fis_phys; + + bool is_atapi; }; void ahci_init(); diff --git a/kernel/include/mem/pmm.h b/kernel/include/mem/pmm.h index 8db365089..196e2c089 100644 --- a/kernel/include/mem/pmm.h +++ b/kernel/include/mem/pmm.h @@ -20,14 +20,14 @@ extern size_t kernel_end; #define PAGE_TABLE_INDEX_BITS 10 #define PAGE_TABLE_INDEX_MASK 0x3FF -#define PAGE_PRESENT (1 << 0) -#define PAGE_WRITEABLE (1 << 1) -#define PAGE_USER (1 << 2) -#define PAGE_WRITE_THROUGH (1 << 3) -#define PAGE_CACHE_DISABLE (1 << 4) -#define PAGE_ACCESSED (1 << 5) -#define PAGE_DIRTY (1 << 6) -#define PAGE_GLOBAL (1 << 8) +#define PAGE_PRESENT (1U << 0) +#define PAGE_WRITEABLE (1U << 1) +#define PAGE_USER (1U << 2) +#define PAGE_WRITE_THROUGH (1U << 3) +#define PAGE_CACHE_DISABLE (1U << 4) +#define PAGE_ACCESSED (1U << 5) +#define PAGE_DIRTY (1U << 6) +#define PAGE_GLOBAL (1U << 8) #define PAGE_BITMAP_SIZE (131072) diff --git a/kernel/include/sys/scheduler.h b/kernel/include/sys/scheduler.h index 0cb9d3c40..0b1a9bba4 100644 --- a/kernel/include/sys/scheduler.h +++ b/kernel/include/sys/scheduler.h @@ -7,6 +7,28 @@ #define DEFAULT_STACK_SIZE 0x4000 +typedef enum { + CREATED = 0, + RUNNING, + PAUSED, + DEAD +} thread_state_t; + +SAYORI_INLINE const char* thread_state_string(thread_state_t state) { + switch (state) { + case CREATED: + return "CREATED"; + case RUNNING: + return "RUNNING"; + case PAUSED: + return "PAUSED"; + case DEAD: + return "DEAD"; + default: + return "UNKNOWN"; + } +} + /*----------------------------------------------------------------------------- * Process structure *---------------------------------------------------------------------------*/ @@ -54,16 +76,18 @@ typedef struct uint32_t id; /* Thread ID */ // 40 uint32_t stack_top; - // registers here + // registers here [44] uint32_t eax, ebx, ecx, edx, esi, edi, ebp; -// uint32_t time_high; -// uint32_t time_low; // Time accounting + // 72 + thread_state_t state; }__attribute__((packed)) thread_t; /* Initialization */ void init_task_manager(void); extern void task_switch(registers_t regs); +void task_switch_v2_wrapper(__attribute__((unused)) registers_t regs); +extern void task_switch_v2(thread_t*, thread_t*); thread_t* _thread_create_unwrapped(process_t* proc, void* entry_point, size_t stack_size, bool kernel, bool suspend); diff --git a/kernel/include/sys/unwind.h b/kernel/include/sys/unwind.h index 9eefaa21e..6b44caf27 100644 --- a/kernel/include/sys/unwind.h +++ b/kernel/include/sys/unwind.h @@ -7,4 +7,8 @@ typedef struct stackframe { uint32_t eip; } stackframe; +#ifndef RELEASE void unwind_stack(uint32_t MaxFrames); +#else +#define unwind_stack(_) +#endif diff --git a/kernel/src/drv/disk/ahci.c b/kernel/src/drv/disk/ahci.c index d79ee525a..4bc88d554 100644 --- a/kernel/src/drv/disk/ahci.c +++ b/kernel/src/drv/disk/ahci.c @@ -12,7 +12,7 @@ #include "drv/atapi.h" #include "net/endianess.h" #include "drv/disk/dpm.h" -#include "debug/hexview.h" +//#include "debug/hexview.h" #define AHCI_CLASS 1 #define AHCI_SUBCLASS 6 @@ -62,9 +62,9 @@ void ahci_init() { // Get ABAR - abar = (volatile AHCI_HBA_MEM*)(pci_read32(ahci_busnum, ahci_slot, ahci_func, 0x24) & ~0b1111); + abar = (volatile AHCI_HBA_MEM*)(pci_read32(ahci_busnum, ahci_slot, ahci_func, 0x24) & ~0b1111U); - qemu_log("AHCI ABAR is: %x", abar); + qemu_log("AHCI ABAR is: %p", abar); // Map memory map_pages( @@ -77,7 +77,7 @@ void ahci_init() { qemu_log("Version: %x", abar->version); - if(abar->host_capabilities_extended & 1) { + if(abar->host_capabilities_extended & 1U) { for(int i = 0; i < 5; i++) { qemu_warn("PERFORMING BIOS HANDOFF!!!"); } @@ -87,8 +87,9 @@ void ahci_init() { while(1) { size_t status = abar->handoff_control_and_status; - if (~status & (1 << 0)) + if (~status & (1 << 0)) { break; + } } } else { qemu_ok("No BIOS Handoff"); @@ -110,7 +111,14 @@ void ahci_init() { register_interrupt_handler(32 + ahci_irq, ahci_irq_handler); // Init - abar->global_host_control |= (1 << 1); // AHCI Enable and AHCI Interrupts + abar->global_host_control |= (1 << 0); // Reset + + while((abar->global_host_control & 1) == 1) + ; + + tty_printf("Reset okay"); + + abar->global_host_control |= (1 << 31) | (1 << 1); // AHCI Enable and AHCI Interrupts qemu_ok("Enabled AHCI and INTERRUPTS"); @@ -133,17 +141,39 @@ void ahci_init() { if (implemented_ports & (1 << i)) { AHCI_HBA_PORT* port = AHCI_PORT(i); + // Additional initialization here + + if((port->command_and_status & (1 << 2)) != (1 << 2)) { + port->command_and_status |= (1 << 2); + + sleep_ms(200); // Replace them with checks + } + + if((port->command_and_status & (1 << 1)) != (1 << 1)) { + port->sata_error = 0xFFFFFFFF; + + port->sata_control = 0; + + port->command_and_status |= (1 << 1); // Spin up. + + sleep_ms(100); // Replace them with checks + } + if (!ahci_is_drive_attached(i)) { continue; } + port->sata_error = 0xFFFFFFFF; + + // Idk why we are clearing START bit. port->command_and_status = port->command_and_status & 0xfffffffe; - while(port->command_and_status & (1 << 15)); + while(port->command_and_status & (1 << 15)) + ; - ahci_rebase_memory_for(i); + tty_printf("[%d] AFTER CMD = %x\n", i, port->command_and_status); - // Additional initialization here + ahci_rebase_memory_for(i); } } @@ -151,7 +181,7 @@ void ahci_init() { if(abar->port_implemented & (1 << i)) { volatile AHCI_HBA_PORT* port = abar->ports + i; - qemu_log("[%x: Port %d]", port, i); + qemu_log("[%p: Port %d]", port, i); if(!ahci_is_drive_attached(i)) { qemu_log("\tNo drive attached to port!"); @@ -316,7 +346,7 @@ void ahci_irq_handler() { } } -void ahci_send_cmd(volatile AHCI_HBA_PORT *port, size_t slot) { +bool ahci_send_cmd(volatile AHCI_HBA_PORT *port, size_t slot) { int spin = 0; while ((port->task_file_data & (ATA_SR_BSY | ATA_SR_DRQ)) && spin < 1000000) { spin++; @@ -324,7 +354,7 @@ void ahci_send_cmd(volatile AHCI_HBA_PORT *port, size_t slot) { if (spin == 1000000) { qemu_err("Port is hung"); - return; + return false; } qemu_warn("DRIVE IS READY"); @@ -340,11 +370,12 @@ void ahci_send_cmd(volatile AHCI_HBA_PORT *port, size_t slot) { if (port->interrupt_status & AHCI_HBA_TFES) { // Task file error? Tell about error and exit qemu_err("Read disk error (Task file error); IS: %x", port->interrupt_status); - return; + return false; } } qemu_warn("OK"); + return true; } /** @@ -360,10 +391,14 @@ void ahci_read_sectors(size_t port_num, uint64_t location, size_t sector_count, return; } + struct ahci_port_descriptor desc = ports[port_num]; + + size_t block_size = desc.is_atapi ? 2048 : 512; + qemu_warn("\033[7mAHCI READ STARTED\033[0m"); - char* buffer_mem = kmalloc_common(sector_count * 512, PAGE_SIZE); - memset(buffer_mem, 0, sector_count * 512); + char* buffer_mem = kmalloc_common(sector_count * block_size, PAGE_SIZE); + memset(buffer_mem, 0, sector_count * block_size); size_t buffer_phys = virt2phys(get_kernel_page_directory(), (virtual_addr_t) buffer_mem); @@ -374,7 +409,7 @@ void ahci_read_sectors(size_t port_num, uint64_t location, size_t sector_count, AHCI_HBA_CMD_HEADER* hdr = ports[port_num].command_list_addr_virt; hdr->cfl = sizeof(AHCI_FIS_REG_DEVICE_TO_HOST) / sizeof(uint32_t); // Should be 5 - hdr->a = 0; // Not ATAPI + hdr->a = desc.is_atapi ? 1 : 0; // ATAPI / Not ATAPI hdr->w = 0; // Read hdr->p = 0; // No prefetch @@ -384,7 +419,7 @@ void ahci_read_sectors(size_t port_num, uint64_t location, size_t sector_count, memset(table, 0, sizeof(HBA_CMD_TBL)); - size_t bytes = sector_count * 512; + size_t bytes = sector_count * block_size; // FIXME: Simplify statements int index = 0; @@ -412,23 +447,52 @@ void ahci_read_sectors(size_t port_num, uint64_t location, size_t sector_count, AHCI_FIS_REG_HOST_TO_DEVICE *cmdfis = (AHCI_FIS_REG_HOST_TO_DEVICE*)&(table->cfis); - qemu_log("CMDFIS at: %x", cmdfis); + qemu_log("CMDFIS at: %p", cmdfis); cmdfis->fis_type = FIS_TYPE_REG_HOST_TO_DEVICE; cmdfis->c = 1; // Command - cmdfis->command = ATA_CMD_READ_DMA_EXT; + cmdfis->command = desc.is_atapi ? ATA_CMD_PACKET : ATA_CMD_READ_DMA_EXT; + + if(desc.is_atapi) { + qemu_log("ATAPI DEVICE"); + + char command[12] = { + ATAPI_CMD_READ, // Command + 0, // ? + (location >> 0x18) & 0xFF, // LBA + (location >> 0x10) & 0xFF, + (location >> 0x08) & 0xFF, + (location >> 0x00) & 0xFF, + (sector_count >> 0x18) & 0xFF, // Sector count + (sector_count >> 0x10) & 0xFF, + (sector_count >> 0x08) & 0xFF, + (sector_count >> 0x00) & 0xFF, + 0, // ? + 0 // ? + }; + + memcpy(table->acmd, command, 12); + + size_t bytecount = sector_count * 2048; + + cmdfis->lba0 = bytecount & 0xff; + cmdfis->lba1 = (bytecount >> 8) & 0xff; + cmdfis->lba2 = (bytecount >> 16) & 0xff; + } else { + qemu_log("JUST A DISK DEVICE"); - cmdfis->lba0 = location & 0xFF; - cmdfis->lba1 = (location >> 8) & 0xFF; - cmdfis->lba2 = (location >> 16) & 0xFF; - cmdfis->lba3 = (location >> 24) & 0xFF; - cmdfis->lba4 = (location >> 32) & 0xFF; - cmdfis->lba5 = (location >> 40) & 0xFF; + cmdfis->lba0 = location & 0xFF; + cmdfis->lba1 = (location >> 8) & 0xFF; + cmdfis->lba2 = (location >> 16) & 0xFF; + cmdfis->lba3 = (location >> 24) & 0xFF; + cmdfis->lba4 = (location >> 32) & 0xFF; + cmdfis->lba5 = (location >> 40) & 0xFF; - cmdfis->device = 1 << 6; // LBA mode + cmdfis->countl = sector_count & 0xffU; + cmdfis->counth = (sector_count >> 8) & 0xffU; - cmdfis->countl = sector_count & 0xff; - cmdfis->counth = (sector_count >> 8) & 0xff; + cmdfis->device = 1U << 6; // LBA mode + } ahci_send_cmd(port, 0); @@ -505,7 +569,7 @@ void ahci_write_sectors(size_t port_num, size_t location, size_t sector_count, v AHCI_FIS_REG_HOST_TO_DEVICE *cmdfis = (AHCI_FIS_REG_HOST_TO_DEVICE*)&(table->cfis); - qemu_log("CMDFIS at: %x", cmdfis); + qemu_log("CMDFIS at: %p", cmdfis); cmdfis->fis_type = FIS_TYPE_REG_HOST_TO_DEVICE; cmdfis->c = 1; // Command @@ -551,7 +615,7 @@ void ahci_eject_cdrom(size_t port_num) { ATAPI_CMD_START_STOP, // Command 0, 0, 0, // Reserved 1 << 1, // Eject the disc - 0, 0, 0, 0, // Reserved + 0, 0, 0, 0, 0 // Reserved }; memcpy(table->acmd, command, 10); @@ -574,11 +638,13 @@ void ahci_read(size_t port_num, uint8_t* buf, uint64_t location, uint32_t length // TODO: Get sector size somewhere (Now we hardcode it into 512). - uint64_t start_sector = location / 512; - uint64_t end_sector = (location + length - 1) / 512; + size_t block_size = ports[port_num].is_atapi ? 2048 : 512; + + uint64_t start_sector = location / block_size; + uint64_t end_sector = (location + length - 1) / block_size; uint64_t sector_count = end_sector - start_sector + 1; - uint64_t real_length = sector_count * 512; + uint64_t real_length = sector_count * block_size; qemu_log("Reading %d sectors...", (uint32_t)sector_count); @@ -586,17 +652,17 @@ void ahci_read(size_t port_num, uint8_t* buf, uint64_t location, uint32_t length ahci_read_sectors(port_num, start_sector, sector_count, real_buf); - memcpy(buf, real_buf + (location % 512), length); + memcpy(buf, real_buf + (location % block_size), length); kfree(real_buf); } size_t ahci_dpm_read(size_t Disk, uint64_t high_offset, uint64_t low_offset, size_t Size, void* Buffer){ - qemu_err("TODO: SATA DPM READ"); +// qemu_err("TODO: SATA DPM READ"); DPM_Disk dpm = dpm_info(Disk + 65); - ahci_read((uint8_t) dpm.Point, Buffer, low_offset, Size); + ahci_read((size_t) dpm.Point, Buffer, low_offset, Size); return Size; } @@ -619,6 +685,8 @@ void ahci_identify(size_t port_num, bool is_atapi) { int slot = 0; + uint32_t block_size = 512; + AHCI_HBA_CMD_HEADER* hdr = ports[port_num].command_list_addr_virt; hdr += slot; @@ -646,6 +714,7 @@ void ahci_identify(size_t port_num, bool is_atapi) { cmdfis->c = 1; // Command if(is_atapi) { cmdfis->command = ATA_CMD_IDENTIFY_PACKET; + block_size = 2048; } else { cmdfis->command = ATA_CMD_IDENTIFY; } @@ -668,25 +737,29 @@ void ahci_identify(size_t port_num, bool is_atapi) { tty_printf("[SATA] MODEL: '%s'; CAPACITY: %d sectors\n", model, capacity); - int disk_inx = dpm_reg( - (char)dpm_searchFreeIndex(0), - "SATA Disk", - "Unknown", - 1, - capacity * 512, - capacity, - 512, - 3, // Ставим 3ку, так как будем юзать функции для чтения и записи - "DISK1234567890", - (void*)port_num // Оставим тут индекс диска - ); - - if (disk_inx < 0){ - qemu_err("[SATA/DPM] [ERROR] An error occurred during disk registration, error code: %d", disk_inx); - } else { - qemu_ok("[SATA/DPM] [Successful] Registering OK"); - dpm_fnc_write(disk_inx + 65, &ahci_dpm_read, &ahci_dpm_write); - } + if(!is_atapi) { + int disk_inx = dpm_reg( + (char)dpm_searchFreeIndex(0), + "SATA Disk", + "Unknown", + 1, + capacity * block_size, + capacity, + block_size, + 3, // Ставим 3ку, так как будем юзать функции для чтения и записи + "DISK1234567890", + (void*)port_num // Оставим тут индекс диска + ); + + if (disk_inx < 0){ + qemu_err("[SATA/DPM] [ERROR] An error occurred during disk registration, error code: %d", disk_inx); + } else { + qemu_ok("[SATA/DPM] [Successful] Registering OK"); + dpm_fnc_write(disk_inx + 65, &ahci_dpm_read, &ahci_dpm_write); + } + } + + ports[port_num].is_atapi = is_atapi; kfree(memory); kfree(model); diff --git a/kernel/src/drv/disk/atapi.c b/kernel/src/drv/disk/atapi.c index 21556bc4f..a6e3ee085 100644 --- a/kernel/src/drv/disk/atapi.c +++ b/kernel/src/drv/disk/atapi.c @@ -86,7 +86,7 @@ size_t ata_scsi_receive_size_of_transfer(uint16_t bus) { return 0; } - return inb(ATA_PORT(bus) + ATA_REG_LBA2) << 8 + return (inb(ATA_PORT(bus) + ATA_REG_LBA2) << 8) | inb(ATA_PORT(bus) + ATA_REG_LBA1); } diff --git a/kernel/src/extra/cli.c b/kernel/src/extra/cli.c index 05c219a32..35ce2560d 100644 --- a/kernel/src/extra/cli.c +++ b/kernel/src/extra/cli.c @@ -413,11 +413,11 @@ uint32_t pci_print_list(uint32_t argc, char* argv[]); uint32_t rust_command(uint32_t argc, char* argv[]); uint32_t CLI_MEMINFO(uint32_t argc, char* argv[]) { tty_printf("Физическая:\n"); - tty_printf(" Используется: %d байт (%d MB)\n", used_phys_memory_size, used_phys_memory_size / MB); - tty_printf(" Свободно: %d байт (%d MB)\n", phys_memory_size - used_phys_memory_size, (phys_memory_size - used_phys_memory_size) / MB); + tty_printf(" Используется: %u байт (%u MB)\n", used_phys_memory_size, used_phys_memory_size / MB); + tty_printf(" Свободно: %u байт (%u MB)\n", phys_memory_size - used_phys_memory_size, (phys_memory_size - used_phys_memory_size) / MB); tty_printf("Виртуальная:\n"); - tty_printf(" %d записей\n", system_heap.allocated_count); - tty_printf(" Используется: %d байт (%d MB)\n", system_heap.used_memory, system_heap.used_memory / MB); + tty_printf(" %u записей\n", system_heap.allocated_count); + tty_printf(" Используется: %u байт (%u MB)\n", system_heap.used_memory, system_heap.used_memory / MB); return 0; } @@ -444,7 +444,10 @@ uint32_t proc_list(uint32_t argc, char* argv[]) { for(int j = 0; j < thread_list.count; j++) { thread_t* thread = (thread_t*)item_thread; - tty_printf(" Поток: %d [Стек: (%x, %x, %d)]\n", thread->id, thread->stack_top, thread->stack, thread->stack_size); + tty_printf(" Поток: #%u процесса #%u; Стек: (%x, %x, %d); Состояние: %s\n", + thread->id, thread->process->pid, thread->stack_top, thread->stack, thread->stack_size, + thread_state_string(thread->state) + ); item_thread = item_thread->next; } diff --git a/kernel/src/gfx/intel.c b/kernel/src/gfx/intel.c index 7628c335e..9db6b3f5b 100644 --- a/kernel/src/gfx/intel.c +++ b/kernel/src/gfx/intel.c @@ -43,6 +43,7 @@ void igfx_wait() { } void igfx_init() { + // TODO: Add 0x5a85 support pci_find_device(0x8086, 0x2a42, &igfx_bus, &igfx_slot, &igfx_func); if(igfx_bus == 0xFF) { diff --git a/kernel/src/kernel.c b/kernel/src/kernel.c index b35657e5a..1b81297e3 100644 --- a/kernel/src/kernel.c +++ b/kernel/src/kernel.c @@ -463,18 +463,20 @@ void __attribute__((noreturn)) kmain(multiboot_header_t* mboot, uint32_t initia // hda_init(); void k(); - // create_process(k, "process", false, true); + create_process(k, "process", false, true); +// thread_create(get_current_proc(), k, 4096, true, false); qemu_log("System initialized everything at: %f seconds.", (double) (getTicks() - kernel_start_time) / getFrequency()); cli(); - while(1); + while(1) + ; } -// void k() { -// for(int i = 0; i < 10; i++) { -// qemu_err("HELLO"); -// sleep_ms(250); -// } -// } +void k() { + for(int i = 0; i < 10; i++) { + qemu_err("HELLO"); + sleep_ms(250); + } +} diff --git a/kernel/src/sys/scheduler.c b/kernel/src/sys/scheduler.c index 72e1fe53d..7bebf6a83 100644 --- a/kernel/src/sys/scheduler.c +++ b/kernel/src/sys/scheduler.c @@ -159,11 +159,11 @@ process_t* get_current_proc(void) { return current_proc; } -void blyat_fire() { - qemu_note("PROCESS %d WANTS TO EXIT!", current_proc->pid); - qemu_err("BLYAT FIRE-RE-RE-RE-RE-RE-RE-RE-RE-RE-RE!!!"); - kill_process(current_proc->pid); - while(1); +__attribute__((noreturn)) void blyat_fire() { + qemu_note("THREAD %d WANTS TO EXIT!", current_thread->id); + thread_exit(current_thread); + while(1) // If something goes wrong, we loop here. + ; } /** @@ -246,65 +246,6 @@ thread_t* thread_create(process_t* proc, void* entry_point, size_t stack_size, return tmp_thread; } -void kill_process(size_t id) { - asm volatile("cli"); - - if(id == 0) { - goto end; - } - - qemu_note("Killing process: %d", id); - - bool found = false; - list_item_t* item = process_list.first; - for(int i = 0; i < process_list.count; i++) { - process_t* proc = (process_t*)item; - - if(proc->pid == id) { - found = true; - break; - } - - item = item->next; - } - - if(!found) { - goto end; - } - - - process_t* process = (process_t*)item; - - list_item_t* item_thread = thread_list.first; - for(int j = 0; j < thread_list.count; j++) { - thread_t* thread = (thread_t*)item_thread; - - if(thread->process->pid == id) { - process->threads_count--; - list_remove(&thread->list_item); - kfree(thread->stack); - kfree(thread); - } - - item_thread = item_thread->next; - } - - // TODO: FIND AND CLEAN PAGE TABLES - // IS IT DONE? - for(int i = 0; i < 1024; i++) { - if(process->page_tables_virts[i] != 0) { - kfree((void *) process->page_tables_virts[i]); - } - } - - kfree((void *) process->page_dir_virt); - - list_remove(&process->list_item); - - end: - asm volatile("sti"); -} - /** * @brief Остановить поток * @@ -325,16 +266,18 @@ void thread_exit(thread_t* thread){ __asm__ volatile ("cli"); /* Remove thread from queue */ - list_remove(&thread->list_item); - - thread->process->threads_count--; +// list_remove(&thread->list_item); +// +// thread->process->threads_count--; +// +// /* Free thread's memory (handler and stack) */ +// kfree(thread->stack); +// kfree(thread); - /* Free thread's memory (handler and stack) */ - kfree(thread->stack); - kfree(thread); + thread->state = DEAD; /* Load to ECX switch function address */ - __asm__ volatile ("mov %0, %%ecx"::"a"(&task_switch)); + __asm__ volatile ("mov %0, %%ecx"::"a"(&task_switch_v2_wrapper)); /* Enable all interrupts */ __asm__ volatile ("sti"); @@ -352,6 +295,48 @@ bool is_multitask(void){ return multi_task; } +void task_switch_v2_wrapper(__attribute__((unused)) registers_t regs) { + thread_t* next_thread = (thread_t *)current_thread->list_item.next; + + while(next_thread->state == PAUSED || next_thread->state == DEAD) { + thread_t* next_thread_soon = (thread_t *)next_thread->list_item.next; + + if(next_thread->state == DEAD) { + process_t* process = next_thread->process; + qemu_log("REMOVING DEAD THREAD: #%u", next_thread->id); + + list_remove(&next_thread->list_item); + + kfree(next_thread->stack); + kfree(next_thread); + + process->threads_count--; + + if(process->threads_count == 0) { + qemu_log("PROCESS DOES NOT HAVE ANY THREADS: #%u", process->pid); + + for(size_t pt = 0; pt < 1024; pt++) { + size_t page_table = process->page_tables_virts[pt]; + + if(page_table) { + kfree((void *) page_table); + } + } + + kfree((void *) process->page_dir_virt); + + list_remove(&process->list_item); + + kfree(process); + } + } + + next_thread = next_thread_soon; + } + + task_switch_v2(current_thread, next_thread); +} + /** * @brief Переключиться в пользовательский режим * diff --git a/kernel/src/sys/timer.c b/kernel/src/sys/timer.c index 94d8f3b83..cc401077a 100644 --- a/kernel/src/sys/timer.c +++ b/kernel/src/sys/timer.c @@ -81,7 +81,7 @@ void timer_callback(__attribute__((unused)) registers_t regs){ tick++; if (is_multitask() && scheduler_working) { - task_switch(regs); + task_switch_v2_wrapper(regs); } } diff --git a/kernel/src/sys/unwind.c b/kernel/src/sys/unwind.c index 85fd691f5..9e78affaf 100644 --- a/kernel/src/sys/unwind.c +++ b/kernel/src/sys/unwind.c @@ -2,6 +2,7 @@ #include "io/ports.h" #include "lib/string.h" +#ifndef RELEASE __attribute__((section(".debug_symbols"))) char function_addr_data[128 * 1024] = {0}; char _temp_funcname[1024] = {0}; @@ -74,3 +75,4 @@ void unwind_stack(uint32_t MaxFrames) { // qemu_log("%s", function_addr_data); } +#endif diff --git a/kernel/src/sys/variable.c b/kernel/src/sys/variable.c index 7eab661ea..9a5a5e5e6 100644 --- a/kernel/src/sys/variable.c +++ b/kernel/src/sys/variable.c @@ -13,7 +13,7 @@ #include #include -VARIABLE G_VARIABLE[512] = {0}; +VARIABLE G_VARIABLE[128] = {0}; size_t C_VARIABLE = 0; size_t variable_freeID(char* Key){ @@ -75,4 +75,4 @@ VARIABLE* variable_list(char* Search){ } list[inx].Ready = 0; return list; -} \ No newline at end of file +}