diff --git a/mentos/inc/descriptor_tables/isr.h b/mentos/inc/descriptor_tables/isr.h index 1f5b468..2c52c9a 100644 --- a/mentos/inc/descriptor_tables/isr.h +++ b/mentos/inc/descriptor_tables/isr.h @@ -41,7 +41,12 @@ void irq_init(); /// @param handler Exception handler. /// @param description Exception description. /// @return 0 on success, -1 otherwise. -int isr_install_handler(uint32_t i, interrupt_handler_t handler, char *description); +int isr_install_handler(unsigned i, interrupt_handler_t handler, char *description); + +/// @brief Uninstall an ISR handler. +/// @param i Interrupt identifier. +/// @return 0 on success, -1 otherwise. +int isr_uninstall_handler(unsigned i); /// @brief Installs an ISR to handle an interrupt. /// @param i Interrupt identifier. @@ -50,6 +55,11 @@ int isr_install_handler(uint32_t i, interrupt_handler_t handler, char *descripti /// @return 0 on success, -1 otherwise. int irq_install_handler(unsigned i, interrupt_handler_t handler, char *description); +/// @brief Uninstall an IRQ handler. +/// @param i Interrupt identifier. +/// @return 0 on success, -1 otherwise. +int irq_uninstall_handler(unsigned i, interrupt_handler_t handler); + /// @brief Method called by CPU to handle interrupts. /// @param f The interrupt stack frame. extern void irq_handler(pt_regs *f); diff --git a/mentos/inc/drivers/ata.h b/mentos/inc/drivers/ata.h index a8241b5..2e50512 100644 --- a/mentos/inc/drivers/ata.h +++ b/mentos/inc/drivers/ata.h @@ -1,6 +1,6 @@ /// MentOS, The Mentoring Operating system project /// @file ata.h -/// @brief ATA values and data structures. +/// @brief Drivers for the Advanced Technology Attachment (ATA) devices. /// @details /// IDE is a keyword which refers to the electrical specification of the cables /// which connect ATA drives (like hard drives) to another device. The drives @@ -10,196 +10,23 @@ /// for the SCSI command set. /// @copyright (c) 2014-2021 This file is distributed under the MIT License. /// See LICENSE.md for details. -///! @cond Doxygen_Suppress +/// @addtogroup drivers Device Drivers +/// @{ +/// @addtogroup ata Advanced Technology Attachment (ATA) +/// @brief Drivers for the Advanced Technology Attachment (ATA) devices. +/// @{ #pragma once #include "stdint.h" -/// @defgroup ata_defines The ATA configuration registers. -/// @{ - -/// @defgroup status_register Status register bits. -/// @{ - -#define ATA_STAT_BUSY 0x80 /// Device Busy -#define ATA_STAT_READY 0x40 ///< Device Ready -#define ATA_STAT_FAULT 0x20 ///< Device Fault -#define ATA_STAT_SEEK 0x10 ///< Device Seek Complete -#define ATA_STAT_DRQ 0x08 ///< Data Request (ready) -#define ATA_STAT_CORR 0x04 ///< Corrected Data Error -#define ATA_STAT_INDEX 0x02 ///< Vendor specific -#define ATA_STAT_ERR 0x01 ///< Error - -///< @} - -/// @defgroup ata_commands ATA Commands -/// @{ - -#define ATA_CMD_READ 0x20 ///< Read Sectors (with retries) -#define ATA_CMD_READN 0x21 ///< Read Sectors (no retries) -#define ATA_CMD_WRITE 0x30 ///< Write Sectores (with retries) -#define ATA_CMD_WRITEN 0x31 ///< Write Sectors (no retries) -#define ATA_CMD_VRFY 0x40 ///< Read Verify (with retries) -#define ATA_CMD_VRFYN 0x41 ///< Read verify (no retries) -#define ATA_CMD_SEEK 0x70 ///< Seek -#define ATA_CMD_DIAG 0x90 ///< Execute Device Diagnostic -#define ATA_CMD_INIT 0x91 ///< Initialize Device Parameters -#define ATA_CMD_RD_MULT 0xC4 ///< Read Multiple -#define ATA_CMD_WR_MULT 0xC5 ///< Write Multiple -#define ATA_CMD_SETMULT 0xC6 ///< Set Multiple Mode -#define ATA_CMD_RD_DMA 0xC8 ///< Read DMA (with retries) -#define ATA_CMD_RD_DMAN 0xC9 ///< Read DMS (no retries) -#define ATA_CMD_WR_DMA 0xCA ///< Write DMA (with retries) -#define ATA_CMD_WR_DMAN 0xCB ///< Write DMA (no retires) -#define ATA_CMD_IDENT 0xEC ///< Identify Device -#define ATA_CMD_CH_FLSH 0xE7 ///< Cache flush. -#define ATA_CMD_SETF 0xEF ///< Set Features -#define ATA_CMD_CHK_PWR 0xE5 ///< Check Power Mode - -///< @} - -/// @defgroup atapi_commands ATAPI Commands -/// @{ - -#define ATAPI_CMD_PACKET 0xA0 -#define ATAPI_CMD_ID_PCKT 0xA1 - -/// @} - -/// @defgroup ata_ident_brits Identification Space Bits -/// @brief Definitions used to read information from the identification space. -/// @{ - -#define ATA_IDENT_DEVICETYPE 0 -#define ATA_IDENT_CYLINDERS 2 -#define ATA_IDENT_HEADS 6 -#define ATA_IDENT_SECTORS 12 -#define ATA_IDENT_SERIAL 20 -#define ATA_IDENT_MODEL 54 -#define ATA_IDENT_CAPABILITIES 98 -#define ATA_IDENT_FIELDVALID 106 -#define ATA_IDENT_MAX_LBA 120 -#define ATA_IDENT_COMMANDSETS 164 -#define ATA_IDENT_MAX_LBA_EXT 200 - -/// @} - -/// @defgroup ata_interface Interface Type -/// @{ - -#define IDE_ATA 0x00 ///< ATA (Advanced Technology Attachment) interface. -#define IDE_ATAPI 0x01 ///< Extended ATA with support for SCSI command set. - -/// @} - -/// @defgroup ata_priority Interface Priority -/// @{ - -#define ATA_DEVICE_0 0x00 -#define ATA_DEVICE_1 0x01 - -/// @} - -/// @defgroup ata_command_block_registers Command block registers -/// @{ - -#define ATA_REG_DATA 0x00 ///< Read/Write PIO data bytes. -#define ATA_REG_ERROR 0x01 ///< Error generated by the last ATA command. -#define ATA_REG_FEATURES 0x01 ///< Control command specific interface features. -#define ATA_REG_SECCOUNT0 0x02 ///< Number of sectors to read/write (0 is a special value). -#define ATA_REG_LBA0 0x03 ///< Sector Number Register. -#define ATA_REG_LBA1 0x04 ///< Cylinder Low Register. -#define ATA_REG_LBA2 0x05 ///< Cylinder High Register. -#define ATA_REG_HDDEVSEL 0x06 ///< Used to select a drive and/or head. -#define ATA_REG_COMMAND 0x07 ///< Used to send ATA commands to the device. -#define ATA_REG_STATUS 0x07 ///< Used to read the current status. -#define ATA_REG_SECCOUNT1 0x08 ///< -#define ATA_REG_LBA3 0x09 ///< -#define ATA_REG_LBA4 0x0A ///< -#define ATA_REG_LBA5 0x0B ///< -#define ATA_REG_CONTROL 0x0C ///< -#define ATA_REG_ALTSTATUS 0x0C ///< -#define ATA_REG_DEVADDRESS 0x0D ///< - -/// @} - -/// @defgroup ata_channels Channels -/// @{ - -#define ATA_PRIMARY 0x00 ///< Primary channel. -#define ATA_SECONDARY 0x01 ///< Secondary channel. -/// @} - -/// @defgroup ata_directions Directions -/// @{ - -#define ATA_READ 0x00 ///< Read direction. -#define ATA_WRITE 0x01 ///< Write direction. - -/// @} -/// @} - -/// @brief Stores information of a channel. -typedef struct ide_channel_regs_t{ - uint16_t base; ///< I/O Base. - uint16_t ctrl; ///< Control Base - uint16_t bmide; ///< Bus Master IDE - uint16_t nien; ///< nIEN (No Interrupt); -} ide_channel_regs_t; - -/// @brief Stores information of a device. -typedef struct ide_device_t{ - uint8_t reserved; ///< 0 (Empty) or 1 (This Drive really exists). - uint8_t channel; ///< 0 (Primary Channel) or 1 (Secondary Channel). - uint8_t drive; ///< 0 (Drive 0) or 1 (Drive 1). - uint16_t type; ///< 0: ATA, 1:ATAPI. - uint16_t signature; ///< Drive Signature. - uint16_t capabilities; ///< Features. - uint32_t command_sets; ///< Command Sets Supported. - uint32_t size; ///< Size in Sectors. - uint8_t model[41]; ///< Model in string. -} ide_device_t; - -/// @brief -typedef struct partition_t{ - uint8_t status; ///< - uint8_t chs_first_sector[3]; ///< - uint8_t type; ///< - uint8_t chs_last_sector[3]; ///< - uint32_t lba_first_sector; ///< - uint32_t sector_count; ///< -} partition_t; - -typedef struct ata_identify_t{ - uint16_t flags; - uint16_t unused1[9]; - char serial[20]; - uint16_t unused2[3]; - char firmware[8]; - char model[40]; - uint16_t sectors_per_int; - uint16_t unused3; - uint16_t capabilities[2]; - uint16_t unused4[2]; - uint16_t valid_ext_data; - uint16_t unused5[5]; - uint16_t size_of_rw_mult; - uint32_t sectors_28; - uint16_t unused6[38]; - uint64_t sectors_48; - uint16_t unused7[152]; -} __attribute__((packed)) ata_identify_t; - -/// @brief Master Boot Record. -typedef struct mbr_t{ - uint8_t boostrap[446]; - partition_t partitions[4]; - uint8_t signature[2]; -} __attribute__((packed)) mbr_t; - +/// @brief Initializes the ATA drivers. +/// @return 0 on success, 1 on error. int ata_initialize(); +/// @brief De-initializes the ATA drivers. +/// @return 0 on success, 1 on error. int ata_finalize(); -///! @endcond \ No newline at end of file +/// @} +/// @} \ No newline at end of file diff --git a/mentos/inc/drivers/fdc.h b/mentos/inc/drivers/fdc.h index 8d751d4..bb36931 100644 --- a/mentos/inc/drivers/fdc.h +++ b/mentos/inc/drivers/fdc.h @@ -3,42 +3,21 @@ /// @brief Definitions about the floppy. /// @copyright (c) 2014-2021 This file is distributed under the MIT License. /// See LICENSE.md for details. +/// @addtogroup drivers Device Drivers +/// @{ +/// @addtogroup fdc Floppy Disc Controller (FDC) +/// @brief Routines for interfacing with the floppy disc controller. +/// @{ #pragma once -/// @brief Floppy Disk Controller (FDC) registers. -typedef enum fdc_registers_t { - STATUS_REGISTER_A = 0x3F0, - ///< This register is read-only and monitors the state of the - ///< interrupt pin and several disk interface pins. - STATUS_REGISTER_B = 0x3F1, - ///< This register is read-only and monitors the state of several - ///< isk interface pins. - DOR = 0x3F2, - ///< The Digital Output Register contains the drive select and - ///< motor enable bits, a reset bit and a DMA GATE bit. - TAPE_DRIVE_REGISTER = 0x3F3, - ///< This register allows the user to assign tape support to a - ///< particular drive during initialization. - MAIN_STATUS_REGISTER = 0x3F4, - ///< The Main Status Register is a read-only register and is used - ///< for controlling command input and result output for all commands. - DATARATE_SELECT_REGISTER = 0x3F4, - ///< This register is included for compatibility with the 82072 - ///< floppy controller and is write-only. - DATA_FIFO = 0x3F5, - ///< All command parameter information and disk data transfers go - ///< through the FIFO. - DIGITAL_INPUT_REGISTER = 0x3F7, - ///< This register is read only in all modes. - CONFIGURATION_CONTROL_REGISTER = 0x3F7 - ///< This register sets the datarate and is write only. -} fdc_registers_t; +/// @brief Initializes the floppy disk controller. +/// @return 0 on success, 1 on error. +int fdc_initialize(); -/// @brief Allows to enable the motor. -/// @details The motor enable pins are directly controlled via the DOR and -/// are a function of the mapping based on BOOTSEL bits in the TDR. -void fdc_enable_motor(void); +/// @brief De-initializes the floppy disk controller. +/// @return 0 on success, 1 on error. +int fdc_finalize(); -/// @brief Allows to disable the motor. -void fdc_disable_motor(void); +/// @} +/// @} \ No newline at end of file diff --git a/mentos/inc/drivers/keyboard/keyboard.h b/mentos/inc/drivers/keyboard/keyboard.h index 0e6b81a..1560292 100644 --- a/mentos/inc/drivers/keyboard/keyboard.h +++ b/mentos/inc/drivers/keyboard/keyboard.h @@ -1,18 +1,18 @@ /// MentOS, The Mentoring Operating system project /// @file keyboard.h -/// @brief Definitions about the keyboard. +/// @brief Drivers for the Keyboard devices. /// @copyright (c) 2014-2021 This file is distributed under the MIT License. /// See LICENSE.md for details. +/// @addtogroup drivers Device Drivers +/// @{ +/// @addtogroup keyboard Keyboard +/// @brief Drivers for the Keyboard devices. +/// @{ #pragma once #include "kernel.h" -/// @brief The dimension of the circular buffer used to store video history. -#define BUFSIZE 256 - -/// @brief Function used to install the keyboard. -void keyboard_install(); /// @brief The interrupt service routine of the keyboard. /// @param f The interrupt stack frame. @@ -31,3 +31,14 @@ void keyboard_update_leds(); /// @details It loops until there is something new to read. /// @return The read character. int keyboard_getc(); + +/// @brief Initializes the keyboard drivers. +/// @return 0 on success, 1 on error. +int keyboard_initialize(); + +/// @brief De-initializes the keyboard drivers. +/// @return 0 on success, 1 on error. +int keyboard_finalize(); + +/// @} +/// @} \ No newline at end of file diff --git a/mentos/inc/drivers/keyboard/keymap.h b/mentos/inc/drivers/keyboard/keymap.h index 15aba91..4ba7273 100644 --- a/mentos/inc/drivers/keyboard/keymap.h +++ b/mentos/inc/drivers/keyboard/keymap.h @@ -3,6 +3,10 @@ /// @brief Keymap for keyboard. /// @copyright (c) 2014-2021 This file is distributed under the MIT License. /// See LICENSE.md for details. +/// @addtogroup drivers Device Drivers +/// @{ +/// @addtogroup keyboard Keyboard +/// @{ #pragma once @@ -40,7 +44,7 @@ const keymap_t *get_keymap(); /// @brief Initializes the supported keymaps. void init_keymaps(); -/// @defgroup keyboardcodes Keyboard Codes +/// @name Keyboard Codes /// @brief This is the list of keyboard codes. /// @{ @@ -149,3 +153,6 @@ void init_keymaps(); #define CODE_BREAK 0x0080U ///< Code break code /// @} + +/// @} +/// @} \ No newline at end of file diff --git a/mentos/inc/drivers/mouse.h b/mentos/inc/drivers/mouse.h index 0021782..838cf34 100644 --- a/mentos/inc/drivers/mouse.h +++ b/mentos/inc/drivers/mouse.h @@ -3,7 +3,11 @@ /// @brief Driver for *PS2* Mouses. /// @copyright (c) 2014-2021 This file is distributed under the MIT License. /// See LICENSE.md for details. -///! @cond Doxygen_Suppress +/// @addtogroup drivers Device Drivers +/// @{ +/// @addtogroup mouse Mouse +/// @brief Routines for interfacing with the mouse. +/// @{ #pragma once @@ -12,38 +16,13 @@ */ #include "kernel.h" -#define MOUSE_ENABLE_PACKET 0xF4 +/// @brief Initializes the mouse. +/// @return 0 on success, 1 on error. +int mouse_initialize(); -/// The mouse stops sending automatic packets. -#define MOUSE_DISABLE_PACKET 0xF5 +/// @brief De-initializes the mouse. +/// @return 0 on success, 1 on error. +int mouse_finalize(); -/// Disables streaming, sets the packet rate to 100 per second, and -/// resolution to 4 pixels per mm. -#define MOUSE_USE_DEFAULT_SETTINGS 0xF6 - -/// @brief Sets up the mouse by installing the mouse handler into IRQ12. -void mouse_install(); - -/// @brief Enable the mouse driver. -void mouse_enable(); - -/// @brief Disable the mouse driver. -void mouse_disable(); - -/// @brief Mouse wait for a command. -/// @param type 1 for sending - 0 for receiving. -void mouse_waitcmd(unsigned char type); - -/// @brief Send data to mouse. -/// @param data The data to send. -void mouse_write(unsigned char data); - -/// @brief Read data from mouse. -/// @return The data received from mouse. -unsigned char mouse_read(); - -/// @brief The interrupt service routine of the mouse. -/// @param f The interrupt stack frame. -void mouse_isr(pt_regs *f); - -///! @endcond \ No newline at end of file +/// @} +/// @} \ No newline at end of file diff --git a/mentos/inc/drivers/rtc.h b/mentos/inc/drivers/rtc.h index 0588835..f66eb17 100644 --- a/mentos/inc/drivers/rtc.h +++ b/mentos/inc/drivers/rtc.h @@ -4,6 +4,7 @@ /// @copyright (c) 2014-2021 This file is distributed under the MIT License. /// See LICENSE.md for details. /// @addtogroup drivers Device Drivers +/// @brief Routines for interfacing with peripheral devices. /// @{ /// @addtogroup rtc Real Time Clock (RTC) /// @brief Routines for interfacing with the real-time clock. @@ -17,7 +18,13 @@ /// @param time Pointer where we store the global time. extern void gettime(tm_t *time); -/// @brief Installs the Real Time Clock. -extern void rtc_install(void); +/// @brief Initializes the Real Time Clock (RTC). +/// @return 0 on success, 1 on error. +int rtc_initialize(); +/// @brief De-initializes the Real Time Clock (RTC). +/// @return 0 on success, 1 on error. +int rtc_finalize(); + +/// @} /// @} \ No newline at end of file diff --git a/mentos/src/descriptor_tables/exception.c b/mentos/src/descriptor_tables/exception.c index 571790a..3d52d2a 100644 --- a/mentos/src/descriptor_tables/exception.c +++ b/mentos/src/descriptor_tables/exception.c @@ -89,7 +89,7 @@ void isrs_init() } } -int isr_install_handler(uint32_t i, interrupt_handler_t handler, char *description) +int isr_install_handler(unsigned i, interrupt_handler_t handler, char *description) { // Sanity check. if (i > 31 && i != 80) { @@ -99,3 +99,13 @@ int isr_install_handler(uint32_t i, interrupt_handler_t handler, char *descripti isr_routines_description[i] = description; return 0; } + +int isr_uninstall_handler(unsigned i) +{ + if (i > 31 && i != 80) { + return -1; + } + isr_routines[i] = default_isr_handler; + isr_routines_description[i] = "NONE"; + return 0; +} diff --git a/mentos/src/descriptor_tables/interrupt.c b/mentos/src/descriptor_tables/interrupt.c index 8b67c91..3780a94 100644 --- a/mentos/src/descriptor_tables/interrupt.c +++ b/mentos/src/descriptor_tables/interrupt.c @@ -62,16 +62,47 @@ void irq_init() int irq_install_handler(unsigned i, interrupt_handler_t handler, char *description) { // We have maximun IRQ_NUM IRQ lines. - assert((i < IRQ_NUM) && "Unidentified IRQ number."); + if (i >= IRQ_NUM) { + pr_err("There are no handler for IRQ `%d`\n", i); + return -1; + } // Create a new irq_struct_t to save the given handler. irq_struct_t *irq_struct = __irq_struct_alloc(); - irq_struct->description = description; - irq_struct->handler = handler; + if (irq_struct == NULL) { + pr_err("Failed to allocate more IRQ structures for IRQ `%d`\n", i); + return -1; + } + irq_struct->description = description; + irq_struct->handler = handler; // Add the handler to the list of his siblings. list_head_add_tail(&irq_struct->siblings, &shared_interrupt_handlers[i]); return 0; } +int irq_uninstall_handler(unsigned i, interrupt_handler_t handler) +{ + // We have maximun IRQ_NUM IRQ lines. + if (i >= IRQ_NUM) { + pr_err("There are no handler for IRQ `%d`\n", i); + return -1; + } + if (list_head_empty(&shared_interrupt_handlers[i])) { + pr_err("There are no handler for IRQ `%d`\n", i); + return -1; + } + list_for_each_decl(it, &shared_interrupt_handlers[i]) + { + // Get the interrupt structure. + irq_struct_t *irq_struct = list_entry(it, irq_struct_t, siblings); + assert(irq_struct && "Something went wrong."); + if (irq_struct->handler == handler) { + list_head_del(&irq_struct->siblings); + } + __irq_struct_dealloc(irq_struct); + } + return 0; +} + void irq_handler(pt_regs *f) { // Keep in mind, diff --git a/mentos/src/drivers/ata.c b/mentos/src/drivers/ata.c index 647040b..c5035b9 100644 --- a/mentos/src/drivers/ata.c +++ b/mentos/src/drivers/ata.c @@ -3,9 +3,11 @@ /// @brief /// @copyright (c) 2014-2021 This file is distributed under the MIT License. /// See LICENSE.md for details. -///! @cond Doxygen_Suppress +/// @addtogroup ata +/// @{ #include "drivers/ata.h" + #include "klib/spinlock.h" #include "fcntl.h" #include "mem/vmem_map.h" @@ -23,7 +25,166 @@ #include "io/port_io.h" #include "time.h" -// #define COMPLETE_SCHEDULER +/// @name ATA Status registers +/// @{ +#define ATA_STAT_BUSY 0x80 ///< Device Busy +#define ATA_STAT_READY 0x40 ///< Device Ready +#define ATA_STAT_FAULT 0x20 ///< Device Fault +#define ATA_STAT_SEEK 0x10 ///< Device Seek Complete +#define ATA_STAT_DRQ 0x08 ///< Data Request (ready) +#define ATA_STAT_CORR 0x04 ///< Corrected Data Error +#define ATA_STAT_INDEX 0x02 ///< Vendor specific +#define ATA_STAT_ERR 0x01 ///< Error +/// @} + +/// @name ATA Commands +/// @{ +#define ATA_CMD_READ 0x20 ///< Read Sectors (with retries) +#define ATA_CMD_READN 0x21 ///< Read Sectors (no retries) +#define ATA_CMD_WRITE 0x30 ///< Write Sectores (with retries) +#define ATA_CMD_WRITEN 0x31 ///< Write Sectors (no retries) +#define ATA_CMD_VRFY 0x40 ///< Read Verify (with retries) +#define ATA_CMD_VRFYN 0x41 ///< Read verify (no retries) +#define ATA_CMD_SEEK 0x70 ///< Seek +#define ATA_CMD_DIAG 0x90 ///< Execute Device Diagnostic +#define ATA_CMD_INIT 0x91 ///< Initialize Device Parameters +#define ATA_CMD_RD_MULT 0xC4 ///< Read Multiple +#define ATA_CMD_WR_MULT 0xC5 ///< Write Multiple +#define ATA_CMD_SETMULT 0xC6 ///< Set Multiple Mode +#define ATA_CMD_RD_DMA 0xC8 ///< Read DMA (with retries) +#define ATA_CMD_RD_DMAN 0xC9 ///< Read DMS (no retries) +#define ATA_CMD_WR_DMA 0xCA ///< Write DMA (with retries) +#define ATA_CMD_WR_DMAN 0xCB ///< Write DMA (no retires) +#define ATA_CMD_IDENT 0xEC ///< Identify Device +#define ATA_CMD_CH_FLSH 0xE7 ///< Cache flush. +#define ATA_CMD_SETF 0xEF ///< Set Features +#define ATA_CMD_CHK_PWR 0xE5 ///< Check Power Mode +/// @} + +/// @name ATAPI Commands +/// @{ +#define ATAPI_CMD_PACKET 0xA0 ///< +#define ATAPI_CMD_ID_PCKT 0xA1 ///< +/// @} + +/// @name ATA Identification Space Bits +/// @brief Definitions used to read information from the identification space. +/// @{ +#define ATA_IDENT_DEVICETYPE 0 ///< +#define ATA_IDENT_CYLINDERS 2 ///< +#define ATA_IDENT_HEADS 6 ///< +#define ATA_IDENT_SECTORS 12 ///< +#define ATA_IDENT_SERIAL 20 ///< +#define ATA_IDENT_MODEL 54 ///< +#define ATA_IDENT_CAPABILITIES 98 ///< +#define ATA_IDENT_FIELDVALID 106 ///< +#define ATA_IDENT_MAX_LBA 120 ///< +#define ATA_IDENT_COMMANDSETS 164 ///< +#define ATA_IDENT_MAX_LBA_EXT 200 ///< +/// @} + +/// @name ATA Interface Type +/// @{ +#define IDE_ATA 0x00 ///< ATA (Advanced Technology Attachment) interface. +#define IDE_ATAPI 0x01 ///< Extended ATA with support for SCSI command set. +/// @} + +/// @name ATA Interface Priority +/// @{ +#define ATA_DEVICE_0 0x00 ///< +#define ATA_DEVICE_1 0x01 ///< +/// @} + +/// @name ATA Command block registers +/// @{ +#define ATA_REG_DATA 0x00 ///< Read/Write PIO data bytes. +#define ATA_REG_ERROR 0x01 ///< Error generated by the last ATA command. +#define ATA_REG_FEATURES 0x01 ///< Control command specific interface features. +#define ATA_REG_SECCOUNT0 0x02 ///< Number of sectors to read/write (0 is a special value). +#define ATA_REG_LBA0 0x03 ///< Sector Number Register. +#define ATA_REG_LBA1 0x04 ///< Cylinder Low Register. +#define ATA_REG_LBA2 0x05 ///< Cylinder High Register. +#define ATA_REG_HDDEVSEL 0x06 ///< Used to select a drive and/or head. +#define ATA_REG_COMMAND 0x07 ///< Used to send ATA commands to the device. +#define ATA_REG_STATUS 0x07 ///< Used to read the current status. +#define ATA_REG_SECCOUNT1 0x08 ///< +#define ATA_REG_LBA3 0x09 ///< +#define ATA_REG_LBA4 0x0A ///< +#define ATA_REG_LBA5 0x0B ///< +#define ATA_REG_CONTROL 0x0C ///< +#define ATA_REG_ALTSTATUS 0x0C ///< +#define ATA_REG_DEVADDRESS 0x0D ///< +/// @} + +/// @name ATA Channels +/// @{ +#define ATA_PRIMARY 0x00 ///< Primary channel. +#define ATA_SECONDARY 0x01 ///< Secondary channel. +/// @} + +/// @name ATA Directions +/// @{ +#define ATA_READ 0x00 ///< Read direction. +#define ATA_WRITE 0x01 ///< Write direction. +/// @} + +/// @brief Stores information of a channel. +typedef struct ide_channel_regs_t { + uint16_t base; ///< I/O Base. + uint16_t ctrl; ///< Control Base + uint16_t bmide; ///< Bus Master IDE + uint16_t nien; ///< nIEN (No Interrupt); +} ide_channel_regs_t; + +/// @brief Stores information of a device. +typedef struct ide_device_t { + uint8_t reserved; ///< 0 (Empty) or 1 (This Drive really exists). + uint8_t channel; ///< 0 (Primary Channel) or 1 (Secondary Channel). + uint8_t drive; ///< 0 (Drive 0) or 1 (Drive 1). + uint16_t type; ///< 0: ATA, 1:ATAPI. + uint16_t signature; ///< Drive Signature. + uint16_t capabilities; ///< Features. + uint32_t command_sets; ///< Command Sets Supported. + uint32_t size; ///< Size in Sectors. + uint8_t model[41]; ///< Model in string. +} ide_device_t; + +/// @brief +typedef struct partition_t { + uint8_t status; ///< + uint8_t chs_first_sector[3]; ///< + uint8_t type; ///< + uint8_t chs_last_sector[3]; ///< + uint32_t lba_first_sector; ///< + uint32_t sector_count; ///< +} partition_t; + +typedef struct ata_identify_t { + uint16_t flags; ///< + uint16_t unused1[9]; ///< + char serial[20]; ///< + uint16_t unused2[3]; ///< + char firmware[8]; ///< + char model[40]; ///< + uint16_t sectors_per_int; ///< + uint16_t unused3; ///< + uint16_t capabilities[2]; ///< + uint16_t unused4[2]; ///< + uint16_t valid_ext_data; ///< + uint16_t unused5[5]; ///< + uint16_t size_of_rw_mult; ///< + uint32_t sectors_28; ///< + uint16_t unused6[38]; ///< + uint64_t sectors_48; ///< + uint16_t unused7[152]; ///< +} __attribute__((packed)) ata_identify_t; + +/// @brief Master Boot Record. +typedef struct mbr_t { + uint8_t boostrap[446]; ///< + partition_t partitions[4]; ///< + uint8_t signature[2]; ///< +} __attribute__((packed)) mbr_t; static char ata_drive_char = 'a'; static int cdrom_number = 0; @@ -1017,4 +1178,4 @@ int ata_finalize() return 0; } -///! @endcond \ No newline at end of file +/// @} \ No newline at end of file diff --git a/mentos/src/drivers/fdc.c b/mentos/src/drivers/fdc.c index 9eb0f3d..4ba0c07 100644 --- a/mentos/src/drivers/fdc.c +++ b/mentos/src/drivers/fdc.c @@ -3,25 +3,60 @@ /// @brief Floppy driver controller handling. /// @copyright (c) 2014-2021 This file is distributed under the MIT License. /// See LICENSE.md for details. +/// @addtogroup fdc +/// @{ #include "drivers/fdc.h" #include "io/video.h" #include "io/port_io.h" -void fdc_disable_motor() +/// @brief Floppy Disk Controller (FDC) registers. +typedef enum fdc_registers_t { + STATUS_REGISTER_A = 0x3F0, + ///< This register is read-only and monitors the state of the + ///< interrupt pin and several disk interface pins. + STATUS_REGISTER_B = 0x3F1, + ///< This register is read-only and monitors the state of several + ///< isk interface pins. + DOR = 0x3F2, + ///< The Digital Output Register contains the drive select and + ///< motor enable bits, a reset bit and a DMA GATE bit. + TAPE_DRIVE_REGISTER = 0x3F3, + ///< This register allows the user to assign tape support to a + ///< particular drive during initialization. + MAIN_STATUS_REGISTER = 0x3F4, + ///< The Main Status Register is a read-only register and is used + ///< for controlling command input and result output for all commands. + DATARATE_SELECT_REGISTER = 0x3F4, + ///< This register is included for compatibility with the 82072 + ///< floppy controller and is write-only. + DATA_FIFO = 0x3F5, + ///< All command parameter information and disk data transfers go + ///< through the FIFO. + DIGITAL_INPUT_REGISTER = 0x3F7, + ///< This register is read only in all modes. + CONFIGURATION_CONTROL_REGISTER = 0x3F7 + ///< This register sets the datarate and is write only. +} fdc_registers_t; + +int fdc_initialize() { /* Setting bits: * 2: (RESET) * 3: (IRQ) */ outportb(DOR, 0x0c); + return 0; } -void fdc_enable_motor() +int fdc_finalize() { /* Setting bits: * 3: (IRQ) * 4: (MOTA) */ outportb(DOR, 0x18); + return 0; } + +/// @} \ No newline at end of file diff --git a/mentos/src/drivers/keyboard/keyboard.c b/mentos/src/drivers/keyboard/keyboard.c index 18691f6..af32aef 100644 --- a/mentos/src/drivers/keyboard/keyboard.c +++ b/mentos/src/drivers/keyboard/keyboard.c @@ -3,6 +3,8 @@ /// @brief Keyboard handling. /// @copyright (c) 2014-2021 This file is distributed under the MIT License. /// See LICENSE.md for details. +/// @addtogroup keyboard +/// @{ #include "drivers/keyboard/keyboard.h" @@ -16,6 +18,9 @@ #include "descriptor_tables/isr.h" #include "process/scheduler.h" +/// The dimension of the circular buffer used to store video history. +#define BUFSIZE 256 + /// A macro from Ivan to update buffer indexes. #define STEP(x) (((x) == BUFSIZE - 1) ? 0 : ((x) + 1)) @@ -62,16 +67,6 @@ static inline int read_character() return c; } -void keyboard_install() -{ - // Initialize the keymaps. - init_keymaps(); - // Install the IRQ. - irq_install_handler(IRQ_KEYBOARD, keyboard_isr, "keyboard"); - // Enable the IRQ. - pic8259_irq_enable(IRQ_KEYBOARD); -} - void keyboard_isr(pt_regs *f) { (void)f; @@ -273,3 +268,25 @@ int keyboard_getc() { return read_character(); } + +int keyboard_initialize() +{ + // Initialize the keymaps. + init_keymaps(); + // Install the IRQ. + irq_install_handler(IRQ_KEYBOARD, keyboard_isr, "keyboard"); + // Enable the IRQ. + pic8259_irq_enable(IRQ_KEYBOARD); + return 0; +} + +int keyboard_finalize() +{ + // Install the IRQ. + irq_uninstall_handler(IRQ_KEYBOARD, keyboard_isr); + // Enable the IRQ. + pic8259_irq_disable(IRQ_KEYBOARD); + return 0; +} + +/// @} \ No newline at end of file diff --git a/mentos/src/drivers/keyboard/keymap.c b/mentos/src/drivers/keyboard/keymap.c index 9a2438b..61b453a 100644 --- a/mentos/src/drivers/keyboard/keymap.c +++ b/mentos/src/drivers/keyboard/keymap.c @@ -3,6 +3,8 @@ /// @brief Keymap for keyboard. /// @copyright (c) 2014-2021 This file is distributed under the MIT License. /// See LICENSE.md for details. +/// @addtogroup keyboard +/// @{ #include "drivers/keyboard/keymap.h" #include "string.h" @@ -281,4 +283,6 @@ void init_keymaps() keymaps[KEYMAP_US].numlock[KEY_KP7] = '7'; keymaps[KEYMAP_US].numlock[KEY_KP8] = '8'; keymaps[KEYMAP_US].numlock[KEY_KP9] = '9'; -} \ No newline at end of file +} + +/// @} \ No newline at end of file diff --git a/mentos/src/drivers/mouse.c b/mentos/src/drivers/mouse.c index 83acc45..36c984a 100644 --- a/mentos/src/drivers/mouse.c +++ b/mentos/src/drivers/mouse.c @@ -3,69 +3,33 @@ /// @brief Driver for *PS2* Mouses. /// @copyright (c) 2014-2021 This file is distributed under the MIT License. /// See LICENSE.md for details.is distributed under the MIT License. -///// See LICENSE.md for details. -/////! @cond Doxygen_Suppress +/// @addtogroup mouse +/// @{ #include "drivers/mouse.h" +#include "descriptor_tables/isr.h" #include "hardware/pic8259.h" #include "io/port_io.h" +/// The mouse starts sending automatic packets. +#define MOUSE_ENABLE_PACKET 0xF4 +/// The mouse stops sending automatic packets. +#define MOUSE_DISABLE_PACKET 0xF5 +/// Disables streaming, sets the packet rate to 100 per second, and resolution to 4 pixels per mm. +#define MOUSE_USE_DEFAULT_SETTINGS 0xF6 + +/// Mouse ISR cycle. static uint8_t mouse_cycle = 0; - +/// Mouse communication data. static int8_t mouse_bytes[3]; - +/// Mouse x position. static int32_t mouse_x = (800 / 2); - +/// Mouse y position. static int32_t mouse_y = (600 / 2); -void mouse_install() -{ - // Enable the auxiliary mouse device. - mouse_waitcmd(1); - outportb(0x64, 0xA8); - - // Enable the interrupts. - mouse_waitcmd(1); - outportb(0x64, 0x20); - mouse_waitcmd(0); - uint8_t status_byte = (inportb(0x60) | 2); - mouse_waitcmd(1); - outportb(0x64, 0x60); - mouse_waitcmd(1); - outportb(0x60, status_byte); - - // Tell the mouse to use default settings. - mouse_write(MOUSE_USE_DEFAULT_SETTINGS); - // Acknowledge. - mouse_read(); - - // Setup the mouse handler. - // pic8259_irq_install_handler(IRQ_MOUSE, mouse_isr); - - mouse_enable(); -} - -void mouse_enable() -{ - // Enable the mouse interrupts. - pic8259_irq_enable(IRQ_MOUSE); - // Disable the mouse. - mouse_write(MOUSE_ENABLE_PACKET); - // Acknowledge. - mouse_read(); -} - -void mouse_disable() -{ - // Disable the mouse interrupts. - pic8259_irq_disable(IRQ_MOUSE); - // Disable the mouse. - mouse_write(MOUSE_DISABLE_PACKET); - // Acknowledge. - mouse_read(); -} - -void mouse_waitcmd(unsigned char type) +/// @brief Mouse wait for a command. +/// @param type 1 for sending - 0 for receiving. +static void __mouse_waitcmd(unsigned char type) { register unsigned int _time_out = 100000; if (type == 0) { @@ -87,21 +51,27 @@ void mouse_waitcmd(unsigned char type) } } -void mouse_write(unsigned char data) +/// @brief Send data to mouse. +/// @param data The data to send. +static void __mouse_write(unsigned char data) { - mouse_waitcmd(1); + __mouse_waitcmd(1); outportb(0x64, 0xD4); - mouse_waitcmd(1); + __mouse_waitcmd(1); outportb(0x60, data); } -unsigned char mouse_read() +/// @brief Read data from mouse. +/// @return The data received from mouse. +static unsigned char __mouse_read() { - mouse_waitcmd(0); + __mouse_waitcmd(0); return inportb(0x60); } -void mouse_isr(pt_regs *f) +/// @brief The interrupt service routine of the mouse. +/// @param f The interrupt stack frame. +static void __mouse_isr(pt_regs *f) { (void)f; // Get the input bytes. @@ -177,4 +147,65 @@ void mouse_isr(pt_regs *f) pic8259_send_eoi(IRQ_MOUSE); } -///! @endcond \ No newline at end of file +/// @brief Enable the mouse driver. +static void __mouse_enable() +{ + // Enable the mouse interrupts. + pic8259_irq_enable(IRQ_MOUSE); + // Disable the mouse. + __mouse_write(MOUSE_ENABLE_PACKET); + // Acknowledge. + __mouse_read(); +} + +/// @brief Disable the mouse driver. +static void __mouse_disable() +{ + // Disable the mouse interrupts. + pic8259_irq_disable(IRQ_MOUSE); + // Disable the mouse. + __mouse_write(MOUSE_DISABLE_PACKET); + // Acknowledge. + __mouse_read(); +} + +int mouse_initialize() +{ + // Enable the auxiliary mouse device. + __mouse_waitcmd(1); + outportb(0x64, 0xA8); + + // Enable the interrupts. + __mouse_waitcmd(1); + outportb(0x64, 0x20); + __mouse_waitcmd(0); + uint8_t status_byte = (inportb(0x60) | 2); + __mouse_waitcmd(1); + outportb(0x64, 0x60); + __mouse_waitcmd(1); + outportb(0x60, status_byte); + + // Tell the mouse to use default settings. + __mouse_write(MOUSE_USE_DEFAULT_SETTINGS); + // Acknowledge. + __mouse_read(); + + // Setup the mouse handler. + irq_install_handler(IRQ_MOUSE, __mouse_isr, "mouse"); + + // Enable the mouse. + __mouse_enable(); + return 0; +} + +int mouse_finalize() +{ + // Uninstall the IRQ. + irq_uninstall_handler(IRQ_MOUSE, __mouse_isr); + + // Disable the mouse. + __mouse_disable(); + return 0; +} + +/// @} \ No newline at end of file diff --git a/mentos/src/drivers/rtc.c b/mentos/src/drivers/rtc.c index 153043e..65bfce8 100644 --- a/mentos/src/drivers/rtc.c +++ b/mentos/src/drivers/rtc.c @@ -3,6 +3,8 @@ /// @brief Real Time Clock (RTC) driver. /// @copyright (c) 2014-2021 This file is distributed under the MIT License. /// See LICENSE.md for details. +/// @addtogroup rtc +/// @{ #include "drivers/rtc.h" @@ -117,7 +119,7 @@ void gettime(tm_t *time) memcpy(time, &global_time, sizeof(tm_t)); } -void rtc_install(void) +int rtc_initialize() { unsigned char status; @@ -135,4 +137,16 @@ void rtc_install(void) irq_install_handler(IRQ_REAL_TIME_CLOCK, rtc_handler_isr, "Real Time Clock (RTC)"); // Enable the IRQ. pic8259_irq_enable(IRQ_REAL_TIME_CLOCK); -} \ No newline at end of file + return 0; +} + +int rtc_finalize() +{ + // Uninstall the IRQ. + irq_uninstall_handler(IRQ_REAL_TIME_CLOCK, rtc_handler_isr); + // Disable the IRQ. + pic8259_irq_disable(IRQ_REAL_TIME_CLOCK); + return 0; +} + +/// @} \ No newline at end of file diff --git a/mentos/src/kernel.c b/mentos/src/kernel.c index 6ec25bb..7e40467 100644 --- a/mentos/src/kernel.c +++ b/mentos/src/kernel.c @@ -202,7 +202,7 @@ int kmain(boot_info_t *boot_informations) //========================================================================== pr_notice("Install RTC.\n"); printf("Setting up RTC..."); - rtc_install(); + rtc_initialize(); print_ok(); //========================================================================== @@ -270,7 +270,7 @@ int kmain(boot_info_t *boot_informations) //========================================================================== pr_notice("Setting up keyboard driver...\n"); printf("Setting up keyboard driver..."); - keyboard_install(); + keyboard_initialize(); print_ok(); //========================================================================== @@ -281,10 +281,6 @@ int kmain(boot_info_t *boot_informations) print_ok(); #endif - //========================================================================== - pr_notice("Uninstall the floppy driver.\n"); - fdc_disable_motor(); - //========================================================================== pr_notice("Initialize the scheduler.\n"); printf("Initialize the scheduler...");