3 Revīzijas 2157a8e9eb ... 38ced47171

Autors SHA1 Ziņojums Datums
  coderain 38ced47171 Now booting goes further with the new memory manager 5 gadi atpakaļ
  coderain a2008648fd Make the rest of the drivers work with the new MM as well 5 gadi atpakaļ
  coderain 39e299164b Make the floppy driver and ISA DMA work with the new memory manager 5 gadi atpakaļ

+ 25 - 23
drivers/acpica/src/osmlxf.c

@@ -148,43 +148,45 @@ void AcpiOsFree(void *Memory)
 ACPI_STATUS AcpiOsReadMemory(ACPI_PHYSICAL_ADDRESS Address, UINT64 *Value, UINT32 Width)
 {
     *Value = 0;
-    dword_t ret = read_physical((void*)((uintptr_t)Address), Value, Width / 8);
-
-    if (ret == ERR_SUCCESS) return AE_OK;
-    if (ret == ERR_NOMEMORY) return AE_NO_MEMORY;
-    return AE_ERROR;
+    Width = (Width + 7) / 8;
+    void *Pointer = AcpiOsMapMemory(Address, Width);
+    if (!Pointer) return AE_ERROR;
+    memcpy(&Value, Pointer, Width);
+    AcpiOsUnmapMemory(Pointer, Width);
+    return AE_OK;
 }
 
 ACPI_STATUS AcpiOsWriteMemory(ACPI_PHYSICAL_ADDRESS Address, UINT64 Value, UINT32 Width)
 {
-    dword_t ret = write_physical((void*)((uintptr_t)Address), &Value, Width / 8);
-
-    if (ret == ERR_SUCCESS) return AE_OK;
-    if (ret == ERR_NOMEMORY) return AE_NO_MEMORY;
-    return AE_ERROR;
+    Width = (Width + 7) / 8;
+    void *Pointer = AcpiOsMapMemory(Address, Width);
+    if (!Pointer) return AE_ERROR;
+    memcpy(Pointer, &Value, Width);
+    AcpiOsUnmapMemory(Pointer, Width);
+    return AE_OK;
 }
 
 void *AcpiOsMapMemory(ACPI_PHYSICAL_ADDRESS Address, ACPI_SIZE Length)
 {
-    void *virtual = NULL;
+    area_t area = {
+        .pages = memory_find_page_by_address(Address),
+        .count = PAGE_NUMBER(PAGE_ALIGN_UP(PAGE_OFFSET(Address) + Length))
+    };
+    if (!is_area_valid(&area)) return NULL;
 
-    if (map_memory((void*)PAGE_ALIGN((uintptr_t)Address),
-                   &virtual,
-                   PAGE_ALIGN_UP(PAGE_OFFSET((uintptr_t)Address) + Length),
-                   MEMORY_BLOCK_ACCESSIBLE | MEMORY_BLOCK_WRITABLE) == ERR_SUCCESS)
-    {
-        return (void*)((uintptr_t)virtual + PAGE_OFFSET((uintptr_t)Address));
-    }
-    else
-    {
-        return NULL;
-    }
+    void *virtual = NULL;
+    return memory_view_area(memory_upper_space, &virtual, &area,
+                            MEMORY_FLAG_ACCESSIBLE
+                            | MEMORY_FLAG_WRITABLE
+                            | MEMORY_FLAG_STICKY) == ERR_SUCCESS
+        ? (void*)((uintptr_t)virtual + (uintptr_t)PAGE_OFFSET(Address))
+        : NULL;
 }
 
 void AcpiOsUnmapMemory(void *Address, ACPI_SIZE Length)
 {
     UNUSED_PARAMETER(Length);
-    unmap_memory(Address);
+    memory_free(memory_upper_space, Address);
 }
 
 ACPI_STATUS AcpiOsCreateLock(ACPI_SPINLOCK *OutHandle)

+ 37 - 18
drivers/floppy/src/main.c

@@ -2,7 +2,7 @@
  * Floppy Driver
  * main.c
  *
- * Copyright (C) 2016 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+ * Copyright (C) 2019 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License as
@@ -344,8 +344,19 @@ static dword_t floppy_read(device_t *device, void *buffer, qword_t offset, size_
     else if (strcmp(device->name, FLOPPY_SECOND_NAME) == 0) drive = 1;
     else return ERR_INVALID;
 
-    dma_buffer = (byte_t*)isa_dma_alloc();
-    if (dma_buffer == NULL) return ERR_NOMEMORY;
+    size_t max_transfer = ((dword_t)(offset + length - 1) / FLOPPY_SECTOR_SIZE) - ((dword_t)offset / FLOPPY_SECTOR_SIZE) + 1;
+    if (max_transfer > FLOPPY_SPT) max_transfer = FLOPPY_SPT;
+
+    area_t dma_area;
+    ret = isa_dma_alloc(max_transfer * FLOPPY_SECTOR_SIZE, &dma_area);
+    if (ret != ERR_SUCCESS) return ret;
+
+    ret = memory_view_area(memory_upper_space, (void**)&dma_buffer, &dma_area, MEMORY_FLAG_ACCESSIBLE);
+    if (ret != ERR_SUCCESS)
+    {
+        isa_dma_free(&dma_area);
+        return ret;
+    }
 
     lock_acquire(&floppy_lock);
     floppy_select(drive);
@@ -386,7 +397,7 @@ static dword_t floppy_read(device_t *device, void *buffer, qword_t offset, size_
                 };
                 byte_t command_output[FLOPPY_RW_OUTPUTS];
 
-                isa_dma_write(FLOPPY_DMA_CHANNEL, dma_buffer, amount);
+                isa_dma_write(FLOPPY_DMA_CHANNEL, &dma_area, amount);
 
                 for (i = 0; i < FLOPPY_RW_INPUTS; i++) if (!floppy_fifo_write(command_input[i])) goto timeout;
                 if (floppy_wait_irq(FLOPPY_READ_TIMEOUT) == ERR_TIMEOUT) goto timeout;
@@ -408,9 +419,7 @@ static dword_t floppy_read(device_t *device, void *buffer, qword_t offset, size_
                 goto done;
             }
 
-            ret = read_physical(&dma_buffer[sector_offset], (void*)((uintptr_t)buffer + count), MIN(length - count, amount - sector_offset));
-            if (ret != ERR_SUCCESS) goto done;
-
+            memcpy(&((byte_t*)buffer)[count], &dma_buffer[sector_offset], MIN(length - count, amount - sector_offset));
             count += MIN(length - count, amount - sector_offset);
             sector_offset = 0;
         }
@@ -419,7 +428,8 @@ static dword_t floppy_read(device_t *device, void *buffer, qword_t offset, size_
 done:
     floppy_motor_off(drive);
     lock_release(&floppy_lock);
-    isa_dma_free(dma_buffer);
+    memory_free(memory_upper_space, dma_buffer);
+    isa_dma_free(&dma_area);
 
     if (bytes_read) *bytes_read = count;
     return ret;
@@ -456,8 +466,19 @@ static dword_t floppy_write(device_t *device, const void *buffer, qword_t offset
         if (ret != ERR_SUCCESS) return ret;
     }
 
-    dma_buffer = (byte_t*)isa_dma_alloc();
-    if (dma_buffer == NULL) return ERR_NOMEMORY;
+    size_t max_transfer = ((dword_t)(offset + length - 1) / FLOPPY_SECTOR_SIZE) - ((dword_t)offset / FLOPPY_SECTOR_SIZE) + 1;
+    if (max_transfer > FLOPPY_SPT) max_transfer = FLOPPY_SPT;
+
+    area_t dma_area;
+    ret = isa_dma_alloc(max_transfer * FLOPPY_SECTOR_SIZE, &dma_area);
+    if (ret != ERR_SUCCESS) return ret;
+
+    ret = memory_view_area(memory_upper_space, (void**)&dma_buffer, &dma_area, MEMORY_FLAG_ACCESSIBLE | MEMORY_FLAG_WRITABLE);
+    if (ret != ERR_SUCCESS)
+    {
+        isa_dma_free(&dma_area);
+        return ret;
+    }
 
     lock_acquire(&floppy_lock);
     floppy_select(drive);
@@ -483,18 +504,15 @@ static dword_t floppy_write(device_t *device, const void *buffer, qword_t offset
 
             if (sector_offset)
             {
-                ret = write_physical(dma_buffer, first_sector_data, FLOPPY_SECTOR_SIZE);
-                if (ret != ERR_SUCCESS) goto done;
+                memcpy(dma_buffer, first_sector_data, FLOPPY_SECTOR_SIZE);
             }
 
             if ((length - count) < amount)
             {
-                ret = write_physical(&dma_buffer[amount - FLOPPY_SECTOR_SIZE], last_sector_data, FLOPPY_SECTOR_SIZE);
-                if (ret != ERR_SUCCESS) goto done;
+                memcpy(&dma_buffer[amount - FLOPPY_SECTOR_SIZE], last_sector_data, FLOPPY_SECTOR_SIZE);
             }
 
-            ret = write_physical(&dma_buffer[sector_offset], (void*)((uintptr_t)buffer + count), MIN(length - count, amount - sector_offset));
-            if (ret != ERR_SUCCESS) goto done;
+            memcpy(&dma_buffer[sector_offset], &((const byte_t*)buffer)[count], MIN(length - count, amount - sector_offset));
 
             while (retries--)
             {
@@ -513,7 +531,7 @@ static dword_t floppy_write(device_t *device, const void *buffer, qword_t offset
                 };
                 byte_t command_output[FLOPPY_RW_OUTPUTS];
 
-                isa_dma_read(FLOPPY_DMA_CHANNEL, dma_buffer, amount);
+                isa_dma_read(FLOPPY_DMA_CHANNEL, &dma_area, amount);
 
                 for (i = 0; i < FLOPPY_RW_INPUTS; i++) if (!floppy_fifo_write(command_input[i])) goto write_timeout;
                 if (floppy_wait_irq(FLOPPY_READ_TIMEOUT) == ERR_TIMEOUT) goto write_timeout;
@@ -543,7 +561,8 @@ static dword_t floppy_write(device_t *device, const void *buffer, qword_t offset
 done:
     floppy_motor_off(drive);
     lock_release(&floppy_lock);
-    isa_dma_free(dma_buffer);
+    memory_free(memory_upper_space, dma_buffer);
+    isa_dma_free(&dma_area);
 
     if (bytes_written) *bytes_written = count;
     return ret;

+ 14 - 6
drivers/serial/src/main.c

@@ -76,17 +76,25 @@ static void serial_irq_handler(registers_t *regs, byte_t irq_num)
     }
 }
 
-static dword_t serial_init(void)
+static sysret_t serial_init(void)
 {
-    dword_t ret;
+    sysret_t ret;
     dword_t i;
-    word_t bda_data[9];
+    word_t *bda_data = NULL;
     char name[MAX_DEVICE_NAME];
 
-    ret = read_physical((void*)0x400, &bda_data, sizeof(bda_data));
+    page_t *bda_page = memory_find_page_by_address(0x400);
+    if (bda_page == NULL) return ERR_INVALID;
+
+    area_t area = {
+        .pages = bda_page,
+        .count = 1,
+    };
+
+    ret = memory_view_area(memory_upper_space, (void**)&bda_data, &area, MEMORY_FLAG_ACCESSIBLE);
     if (ret != ERR_SUCCESS) return ret;
 
-    num_ports = (bda_data[8] >> 9) & 0x07;
+    num_ports = (bda_data[0x208] >> 9) & 0x07;
     if (num_ports == 0) return ERR_NOTFOUND;
 
     for (i = 0; i < num_ports; i++)
@@ -101,7 +109,7 @@ static dword_t serial_init(void)
         sprintf(device->header.name, "COM%d", i + 1);
         device->header.driver = &serial_driver;
         lock_init(&device->header.lock);
-        device->port = bda_data[i];
+        device->port = bda_data[0x200 + i];
 
         init_semaphore(&device->read_mutex, 0, 1);
         init_semaphore(&device->write_mutex, 0, 1);

+ 72 - 23
drivers/vesa/src/main.c

@@ -81,49 +81,98 @@ static dword_t vesa_set_mode(dword_t mode_number)
 
 dword_t vesa_init(list_entry_t *video_devices)
 {
-    int i;
     dword_t ret;
-    vbe_controller_info_t info;
 
     if (video_devices->next == video_devices) return ERR_NOTFOUND;
 
-    word_t data_segment = vm86_alloc(VBE_BUFFER_SIZE);
-    if (data_segment == 0) return ERR_NOMEMORY;
+    page_t *page = memory_acquire_page(MIN_PHYS_ADDR_BITS, 19, PAGE_SIZE);
+    if (!page) return ERR_NOMEMORY;
 
-    vm86_registers_t regs = {.eax = 0x4F00,.es = data_segment, .edi = 0x0000 };
+    vm86_registers_t regs = {.eax = 0x4F00,.es = (page->number * PAGE_SIZE) >> 4, .edi = 0x0000 };
     vm86_interrupt(0x10, &regs);
     if (regs.eax != 0x4F)
     {
-        ret = ERR_HARDWARE;
-        goto cleanup;
+        memory_release_page(page);
+        return ERR_HARDWARE;
     }
 
-    ret = read_physical((void*)(data_segment << 4), &info, sizeof(vbe_controller_info_t));
-    if (ret != ERR_SUCCESS) goto cleanup;
+    void *data = NULL;
+    {
+        area_t area = { .pages = page, .count = 1 };
+        ret = memory_view_area(memory_upper_space, &data, &area, MEMORY_FLAG_ACCESSIBLE);
+    }
 
-    word_t *modes = (word_t*)((info.videomodes[1] << 4) + info.videomodes[0]);
-    word_t *numbers = __builtin_alloca(sizeof(word_t) * MAX_NUM_MODES);
-    ret = read_physical(modes, numbers, sizeof(word_t) * MAX_NUM_MODES);
-    if (ret != ERR_SUCCESS) goto cleanup;
+    if (ret != ERR_SUCCESS)
+    {
+        memory_release_page(page);
+        return ERR_HARDWARE;
+    }
 
-    num_available_modes = 0;
+    vbe_controller_info_t info = *(vbe_controller_info_t*)data;
+    physical_t modes = (info.videomodes[1] << 4) + info.videomodes[0];
+    word_t *numbers = NULL;
+
+    if (PAGE_NUMBER(modes) != page->number)
+    {
+        memory_free(memory_upper_space, data);
+        data = NULL;
+
+        area_t area = { .pages = memory_find_page_by_address(modes), .count = 1 };
+        if (!area.pages)
+        {
+            memory_release_page(page);
+            return ERR_HARDWARE;
+        }
+
+        ret = memory_view_area(memory_upper_space, (void**)&data, &area, MEMORY_FLAG_ACCESSIBLE);
+        if (ret != ERR_SUCCESS)
+        {
+            memory_release_page(page);
+            return ret;
+        }
 
-    for (i = 0; (numbers[i] != 0xFFFF) && (i < MAX_NUM_MODES); i++)
+        numbers = data;
+    }
+    else
     {
-        vbe_mode_info_t mode_info;
+        numbers = (word_t*)((uintptr_t)data + (ptrdiff_t)(modes - page->number * PAGE_SIZE));
+    }
+
+    size_t count;
+    for (count = 0; (numbers[count] != 0xFFFF) && (count < MAX_NUM_MODES); count++);
 
+    word_t local_numbers[count];
+    memcpy(local_numbers, numbers, count * sizeof(word_t));
+    numbers = local_numbers;
+
+    memory_free(memory_upper_space, data);
+    data = NULL;
+    {
+        area_t area = { .pages = page, .count = 1 };
+        ret = memory_view_area(memory_upper_space, &data, &area, MEMORY_FLAG_ACCESSIBLE);
+    }
+
+    if (ret != ERR_SUCCESS)
+    {
+        memory_release_page(page);
+        return ret;
+    }
+
+    num_available_modes = 0;
+    for (size_t i = 0; (numbers[i] != 0xFFFF) && (i < MAX_NUM_MODES); i++)
+    {
         regs.eax = 0x4F01;
         regs.ecx = numbers[i];
-        regs.es = data_segment;
-        regs.edi = 0x0000;
+        regs.es = (page->number * PAGE_SIZE) >> 4;
+        regs.edi = 0;
         vm86_interrupt(0x10, &regs);
         if (regs.eax != 0x4F) continue;
 
-        ret = read_physical((void*)(data_segment << 4), &mode_info, sizeof(vbe_mode_info_t));
-        if (mode_info.mem_model_type != 0 && mode_info.mem_model_type != 4 && mode_info.mem_model_type != 6) continue;
+        vbe_mode_info_t *mode_info = data;
+        if (mode_info->mem_model_type != 0 && mode_info->mem_model_type != 4 && mode_info->mem_model_type != 6) continue;
 
         available_mode_numbers[num_available_modes] = numbers[i];
-        available_modes[num_available_modes] = mode_info;
+        available_modes[num_available_modes] = *mode_info;
         num_available_modes++;
     }
 
@@ -132,8 +181,8 @@ dword_t vesa_init(list_entry_t *video_devices)
         CONTAINER_OF(video_devices->next, video_device_t, list)->driver = &driver;
     }
 
-cleanup:
-    vm86_free(data_segment);
+    memory_free(memory_upper_space, data);
+    memory_release_page(page);
     return ret;
 }
 

+ 6 - 5
kernel/include/isa_dma.h

@@ -1,7 +1,7 @@
 /*
  * isa_dma.h
  *
- * Copyright (C) 2013 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+ * Copyright (C) 2019 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License as
@@ -18,6 +18,7 @@
  */
 
 #include <common.h>
+#include <memory.h>
 
 #define ISA_DMA_MEM_START 0x200000
 #define ISA_DMA_MEM_END 0x280000
@@ -39,7 +40,7 @@
 #define ISA_DMA_MASK_RESET_REG(x) (((x) < 4) ? 0x0E : 0xDC)
 #define ISA_DMA_MULTI_MASK_REG(x) (((x) < 4) ? 0x0F : 0xDE)
 
-void *isa_dma_alloc(void);
-void isa_dma_free(void *dma_buffer);
-void isa_dma_read(dword_t channel, void *buffer, word_t count);
-void isa_dma_write(dword_t channel, void *buffer, dword_t count);
+sysret_t isa_dma_alloc(word_t size, area_t *dma_buffer);
+void isa_dma_free(const area_t *dma_buffer);
+void isa_dma_read(dword_t channel, const area_t *dma_buffer, word_t count);
+void isa_dma_write(dword_t channel, const area_t *dma_buffer, word_t count);

+ 7 - 0
kernel/include/memory.h

@@ -136,6 +136,11 @@ void memory_claim_physical_region(physical_t address, qword_t size, page_status_
 void memory_abandon_physical_region(physical_t address, qword_t size);
 void memory_init_physical(memory_map_entry_t *mmap, size_t entry_count);
 
+static inline bool_t is_area_valid(const area_t *area)
+{
+    return area->pages && area->count > 0 ? TRUE : FALSE;
+}
+
 page_t *memory_get_page_mapping(page_table_t table, void *address);
 sysret_t memory_map_page(page_table_t table, page_t *page, void *address, memory_flags_t access_flags);
 sysret_t memory_map_area(page_table_t table, const area_t *area, void *address, memory_flags_t access_flags);
@@ -159,6 +164,8 @@ sysret_t memory_view_area(address_space_t *space, void **address, const area_t *
 sysret_t memory_pin_buffer(const void *virtual, void **pinned, size_t size, bool_t lock_contents);
 void memory_init_virtual(const area_t *kernel_area);
 
+bool_t memory_fault_handler(void *address, registers_t *regs);
+
 void memory_cleanup(object_t *object);
 
 #endif

+ 1 - 1
kernel/src/boot/boot.asm

@@ -28,7 +28,7 @@ extern kernel_main
 MULTIBOOT_MAGIC         EQU     0xE85250D6
 PHYSICAL_ADDRESS        EQU     0x100000
 VIRTUAL_ADDRESS         EQU     0x80000000
-PAGE_DIR_SELF_ENTRY     EQU     768
+PAGE_DIR_SELF_ENTRY     EQU     1023
 
 multiboot:              DD      MULTIBOOT_MAGIC
                         DD      0

+ 1 - 3
kernel/src/exception.c

@@ -84,8 +84,6 @@ static void raise_exception_internal(thread_t *thread, processor_mode_t mode, ex
     }
 }
 
-bool_t new_memory_fault_handler(void *address, registers_t *regs);
-
 static void exception_handler(registers_t *regs, byte_t int_num)
 {
     exception_info_t info;
@@ -150,7 +148,7 @@ static void exception_handler(registers_t *regs, byte_t int_num)
 
     case CPU_EXCEPTION_PF:
         faulting_address = (void*)cpu_read_faulting_address();
-        if (new_memory_fault_handler(faulting_address, regs)) return;
+        if (memory_fault_handler(faulting_address, regs)) return;
 
         info.number = EXCEPTION_MEMORY_ACCESS;
         memcpy(info.parameters, &faulting_address, sizeof(faulting_address));

+ 25 - 22
kernel/src/isa_dma.c

@@ -1,7 +1,7 @@
 /*
  * isa_dma.c
  *
- * Copyright (C) 2013 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+ * Copyright (C) 2019 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License as
@@ -20,40 +20,41 @@
 #include <isa_dma.h>
 #include <lock.h>
 
-static dword_t isa_dma_bitmap[1 + ((ISA_DMA_MEM_BLOCKS - 1) / 32)] = { 0 };
 static DECLARE_LOCK(dma_lock);
 
-void *isa_dma_alloc(void)
+sysret_t isa_dma_alloc(word_t size, area_t *buffer)
 {
-    dword_t i;
-
-    for (i = 0; i < ISA_DMA_MEM_BLOCKS; i++) if (!test_bit(isa_dma_bitmap, i))
-    {
-        set_bit(isa_dma_bitmap, i);
-        return (void*)(ISA_DMA_MEM_START + (i * ISA_DMA_MEM_ALIGNMENT));
-    }
-
-    return NULL;
+    if (!size) return ERR_INVALID;
+
+    memory_acquire_area(MIN_PHYS_ADDR_BITS,
+                        23,
+                        PAGE_ALIGN_UP((size_t)size),
+                        /* Choose an alignment so that it doesn't cross a 64K boundary */
+                        1 << (32 - __builtin_clz(PAGE_ALIGN_UP((unsigned int)size))),
+                        buffer);
+    return is_area_valid(buffer) ? ERR_SUCCESS : ERR_NOMEMORY;
 }
 
-void isa_dma_free(void *dma_buffer)
+void isa_dma_free(const area_t *buffer)
 {
-    clear_bit(isa_dma_bitmap, ((dword_t)dma_buffer - ISA_DMA_MEM_START) / ISA_DMA_MEM_ALIGNMENT);
+    memory_release_area(buffer);
 }
 
-void isa_dma_read(dword_t channel, void *buffer, word_t count)
+void isa_dma_read(dword_t channel, const area_t *buffer, word_t count)
 {
     channel &= 7;
+    ASSERT(count <= buffer->count * PAGE_SIZE);
     if (count == 0) return;
     else count--;
 
+    uintptr_t address = buffer->pages->number * PAGE_SIZE;
     lock_acquire(&dma_lock);
     cpu_write_port_byte(ISA_DMA_SINGLE_MASK_REG(channel), ISA_DMA_MASK_ON | (channel & 3));
 
     cpu_write_port_byte(ISA_DMA_FF_RESET_REG(channel), 0xFF);
-    cpu_write_port_byte(ISA_DMA_SAR(channel), (dword_t)buffer & 0xFF);
-    cpu_write_port_byte(ISA_DMA_SAR(channel), ((dword_t)buffer >> 8) & 0xFF);
-    cpu_write_port_byte(ISA_DMA_PAR(channel), ((dword_t)buffer >> 16) & 0xFF);
+    cpu_write_port_byte(ISA_DMA_SAR(channel), address & 0xFF);
+    cpu_write_port_byte(ISA_DMA_SAR(channel), (address >> 8) & 0xFF);
+    cpu_write_port_byte(ISA_DMA_PAR(channel), (address >> 16) & 0xFF);
 
     cpu_write_port_byte(ISA_DMA_FF_RESET_REG(channel), 0xFF);
     cpu_write_port_byte(ISA_DMA_CNT(channel), count & 0xFF);
@@ -65,19 +66,21 @@ void isa_dma_read(dword_t channel, void *buffer, word_t count)
     lock_release(&dma_lock);
 }
 
-void isa_dma_write(dword_t channel, void *buffer, dword_t count)
+void isa_dma_write(dword_t channel, const area_t *buffer, word_t count)
 {
     channel &= 7;
+    ASSERT(count <= buffer->count * PAGE_SIZE);
     if (count == 0) return;
     else count--;
 
+    uintptr_t address = buffer->pages->number * PAGE_SIZE;
     lock_acquire(&dma_lock);
     cpu_write_port_byte(ISA_DMA_SINGLE_MASK_REG(channel), ISA_DMA_MASK_ON | (channel & 3));
 
     cpu_write_port_byte(ISA_DMA_FF_RESET_REG(channel), 0xFF);
-    cpu_write_port_byte(ISA_DMA_SAR(channel), (dword_t)buffer & 0xFF);
-    cpu_write_port_byte(ISA_DMA_SAR(channel), ((dword_t)buffer >> 8) & 0xFF);
-    cpu_write_port_byte(ISA_DMA_PAR(channel), ((dword_t)buffer >> 16) & 0xFF);
+    cpu_write_port_byte(ISA_DMA_SAR(channel), address & 0xFF);
+    cpu_write_port_byte(ISA_DMA_SAR(channel), (address >> 8) & 0xFF);
+    cpu_write_port_byte(ISA_DMA_PAR(channel), (address >> 16) & 0xFF);
 
     cpu_write_port_byte(ISA_DMA_FF_RESET_REG(channel), 0xFF);
     cpu_write_port_byte(ISA_DMA_CNT(channel), count & 0xFF);

+ 0 - 0
kernel/src/memory/fault.c


Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels