mirror of
https://github.com/tailix/libkernaux.git
synced 2024-11-06 10:56:30 -05:00
Add a driver for Intel 8253-compatible PIT (#93)
This commit is contained in:
parent
a71618b258
commit
f714df3ba8
6 changed files with 101 additions and 53 deletions
34
Makefile.am
34
Makefile.am
|
@ -56,17 +56,6 @@ if ASM_X86_64
|
|||
libkernaux_la_SOURCES += src/asm/x86_64.S
|
||||
endif
|
||||
|
||||
###########
|
||||
# Drivers #
|
||||
###########
|
||||
|
||||
if WITH_DRIVERS
|
||||
libkernaux_la_SOURCES += \
|
||||
src/drivers/console.c \
|
||||
src/drivers/framebuffer.c \
|
||||
src/drivers/intel_8259_pic.c
|
||||
endif
|
||||
|
||||
####################
|
||||
# Default packages #
|
||||
####################
|
||||
|
@ -115,3 +104,26 @@ endif
|
|||
if WITH_UNITS
|
||||
libkernaux_la_SOURCES += src/units.c
|
||||
endif
|
||||
|
||||
###########
|
||||
# Drivers #
|
||||
###########
|
||||
|
||||
if WITH_DRIVERS
|
||||
libkernaux_la_SOURCES += \
|
||||
src/drivers/console.c \
|
||||
src/drivers/framebuffer.c
|
||||
|
||||
# Intel 8253-compatible programmable interval timer
|
||||
|
||||
if ASM_I386
|
||||
libkernaux_la_SOURCES += src/drivers/intel_8253_pit.c
|
||||
endif
|
||||
|
||||
# Intel 8259-compatible programmable interrupt controller
|
||||
|
||||
if ASM_I386
|
||||
libkernaux_la_SOURCES += src/drivers/intel_8259_pic.c
|
||||
endif
|
||||
|
||||
endif # WITH_DRIVERS
|
||||
|
|
|
@ -90,7 +90,8 @@ zero). Work-in-progress APIs can change at any time.
|
|||
* Device drivers (for debugging only)
|
||||
* [Serial console](/include/kernaux/drivers/console.h) (*work in progress*)
|
||||
* [Framebuffer](/include/kernaux/drivers/framebuffer.h) (*planned*)
|
||||
* [Intel 8259 PIC](/include/kernaux/drivers/intel_8259_pic.h) (*planned*)
|
||||
* [Intel 8253-compatible PIT](/include/kernaux/drivers/intel_8253_pit.h) (*work in progress*)
|
||||
* [Intel 8259-compatible PIC](/include/kernaux/drivers/intel_8259_pic.h) (*work in progress*)
|
||||
* USB (*planned*)
|
||||
|
||||
### Definitions
|
||||
|
|
|
@ -27,17 +27,6 @@ if ASM_X86_64
|
|||
nobase_include_HEADERS += kernaux/asm/x86_64.h
|
||||
endif
|
||||
|
||||
###########
|
||||
# Drivers #
|
||||
###########
|
||||
|
||||
if WITH_DRIVERS
|
||||
nobase_include_HEADERS += \
|
||||
kernaux/drivers/console.h \
|
||||
kernaux/drivers/framebuffer.h \
|
||||
kernaux/drivers/intel_8259_pic.h
|
||||
endif
|
||||
|
||||
####################
|
||||
# Default packages #
|
||||
####################
|
||||
|
@ -78,3 +67,26 @@ endif
|
|||
if WITH_UNITS
|
||||
nobase_include_HEADERS += kernaux/units.h
|
||||
endif
|
||||
|
||||
###########
|
||||
# Drivers #
|
||||
###########
|
||||
|
||||
if WITH_DRIVERS
|
||||
nobase_include_HEADERS += \
|
||||
kernaux/drivers/console.h \
|
||||
kernaux/drivers/framebuffer.h
|
||||
|
||||
# Intel 8253-compatible programmable interval timer
|
||||
|
||||
if ASM_I386
|
||||
nobase_include_HEADERS += kernaux/drivers/intel_8253_pit.h
|
||||
endif
|
||||
|
||||
# Intel 8259-compatible programmable interrupt controller
|
||||
|
||||
if ASM_I386
|
||||
nobase_include_HEADERS += kernaux/drivers/intel_8259_pic.h
|
||||
endif
|
||||
|
||||
endif # WITH_DRIVERS
|
||||
|
|
21
include/kernaux/drivers/intel_8253_pit.h
Normal file
21
include/kernaux/drivers/intel_8253_pit.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
/**
|
||||
* @brief A driver for Intel 8253-compatible programmable interval timer
|
||||
*
|
||||
* @see https://en.wikipedia.org/wiki/Intel_8253
|
||||
* @see https://wiki.osdev.org/PIT
|
||||
*/
|
||||
|
||||
#ifndef KERNAUX_INCLUDED_DRIVERS_INTEL_8253_PIT
|
||||
#define KERNAUX_INCLUDED_DRIVERS_INTEL_8253_PIT
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void kernaux_drivers_intel_8253_pit_initialize(unsigned int freq);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
31
src/drivers/intel_8253_pit.c
Normal file
31
src/drivers/intel_8253_pit.c
Normal file
|
@ -0,0 +1,31 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <kernaux/assert.h>
|
||||
#include <kernaux/drivers/intel_8253_pit.h>
|
||||
|
||||
#ifdef ASM_I386
|
||||
#include <kernaux/asm/i386.h>
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(ASM_I386)
|
||||
# define inportb kernaux_asm_i386_inportb
|
||||
# define outportb kernaux_asm_i386_outportb
|
||||
#endif
|
||||
|
||||
void kernaux_drivers_intel_8253_pit_initialize(const unsigned int freq)
|
||||
{
|
||||
KERNAUX_ASSERT(freq);
|
||||
|
||||
const unsigned int divisor = 1193180 / freq;
|
||||
|
||||
const uint8_t l = divisor & 0xff;
|
||||
const uint8_t h = (divisor >> 8) & 0xff;
|
||||
|
||||
outportb(0x43, 0x36);
|
||||
outportb(0x40, l);
|
||||
outportb(0x40, h);
|
||||
}
|
|
@ -21,10 +21,7 @@
|
|||
#define IRQS_COUNT 8
|
||||
#define IRQS_TOTAL 16
|
||||
|
||||
#undef AVAILABLE
|
||||
#define NOT_AVAILABLE_MSG "Intel 8259-compatible PIC is not available"
|
||||
#ifdef ASM_I386
|
||||
# define AVAILABLE
|
||||
#if defined(ASM_I386)
|
||||
# define inportb kernaux_asm_i386_inportb
|
||||
# define outportb kernaux_asm_i386_outportb
|
||||
#endif
|
||||
|
@ -34,30 +31,18 @@ static unsigned char slave_start = 8;
|
|||
|
||||
void kernaux_drivers_intel_8259_pic_enable_all()
|
||||
{
|
||||
#ifndef AVAILABLE
|
||||
KERNAUX_PANIC(NOT_AVAILABLE_MSG);
|
||||
#else
|
||||
outportb(MASTER_DATA_PORT, 0);
|
||||
outportb(SLAVE_DATA_PORT, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void kernaux_drivers_intel_8259_pic_disable_all()
|
||||
{
|
||||
#ifndef AVAILABLE
|
||||
KERNAUX_PANIC(NOT_AVAILABLE_MSG);
|
||||
#else
|
||||
outportb(MASTER_DATA_PORT, 0xFF);
|
||||
outportb(SLAVE_DATA_PORT, 0xFF);
|
||||
#endif
|
||||
}
|
||||
|
||||
void kernaux_drivers_intel_8259_pic_enable(const unsigned char number)
|
||||
{
|
||||
#ifndef AVAILABLE
|
||||
(void)number;
|
||||
KERNAUX_PANIC(NOT_AVAILABLE_MSG);
|
||||
#else
|
||||
KERNAUX_ASSERT(number < IRQS_TOTAL);
|
||||
|
||||
if (number < IRQS_COUNT) {
|
||||
|
@ -67,15 +52,10 @@ void kernaux_drivers_intel_8259_pic_enable(const unsigned char number)
|
|||
const uint8_t mask = inportb(SLAVE_DATA_PORT);
|
||||
outportb(SLAVE_DATA_PORT, mask & ~(1 << (number - IRQS_COUNT)));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void kernaux_drivers_intel_8259_pic_disable(const unsigned char number)
|
||||
{
|
||||
#ifndef AVAILABLE
|
||||
(void)number;
|
||||
KERNAUX_PANIC(NOT_AVAILABLE_MSG);
|
||||
#else
|
||||
KERNAUX_ASSERT(number < IRQS_TOTAL);
|
||||
|
||||
if (number < IRQS_COUNT) {
|
||||
|
@ -85,16 +65,12 @@ void kernaux_drivers_intel_8259_pic_disable(const unsigned char number)
|
|||
const uint8_t mask = inportb(SLAVE_DATA_PORT);
|
||||
outportb(SLAVE_DATA_PORT, mask | (1 << (number - IRQS_COUNT)));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void kernaux_drivers_intel_8259_pic_remap(
|
||||
const unsigned char new_master_start,
|
||||
const unsigned char new_slave_start
|
||||
) {
|
||||
#ifndef AVAILABLE
|
||||
KERNAUX_PANIC(NOT_AVAILABLE_MSG);
|
||||
#else
|
||||
master_start = new_master_start;
|
||||
slave_start = new_slave_start;
|
||||
|
||||
|
@ -121,14 +97,10 @@ void kernaux_drivers_intel_8259_pic_remap(
|
|||
// Restore masks
|
||||
outportb(MASTER_DATA_PORT, master_mask);
|
||||
outportb(SLAVE_DATA_PORT, slave_mask);
|
||||
#endif
|
||||
}
|
||||
|
||||
void kernaux_drivers_intel_8259_pic_eoi(const unsigned char number)
|
||||
{
|
||||
#ifndef AVAILABLE
|
||||
KERNAUX_PANIC(NOT_AVAILABLE_MSG);
|
||||
#else
|
||||
KERNAUX_ASSERT(number < IRQS_TOTAL);
|
||||
|
||||
const bool to_slave =
|
||||
|
@ -138,5 +110,4 @@ void kernaux_drivers_intel_8259_pic_eoi(const unsigned char number)
|
|||
|
||||
if (to_slave) outportb(SLAVE_COMMAND_PORT, 0x20);
|
||||
if (to_master) outportb(MASTER_COMMAND_PORT, 0x20);
|
||||
#endif
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue