mirror of
https://github.com/tailix/libkernaux.git
synced 2024-11-13 11:04:27 -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
|
libkernaux_la_SOURCES += src/asm/x86_64.S
|
||||||
endif
|
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 #
|
# Default packages #
|
||||||
####################
|
####################
|
||||||
|
@ -115,3 +104,26 @@ endif
|
||||||
if WITH_UNITS
|
if WITH_UNITS
|
||||||
libkernaux_la_SOURCES += src/units.c
|
libkernaux_la_SOURCES += src/units.c
|
||||||
endif
|
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)
|
* Device drivers (for debugging only)
|
||||||
* [Serial console](/include/kernaux/drivers/console.h) (*work in progress*)
|
* [Serial console](/include/kernaux/drivers/console.h) (*work in progress*)
|
||||||
* [Framebuffer](/include/kernaux/drivers/framebuffer.h) (*planned*)
|
* [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*)
|
* USB (*planned*)
|
||||||
|
|
||||||
### Definitions
|
### Definitions
|
||||||
|
|
|
@ -27,17 +27,6 @@ if ASM_X86_64
|
||||||
nobase_include_HEADERS += kernaux/asm/x86_64.h
|
nobase_include_HEADERS += kernaux/asm/x86_64.h
|
||||||
endif
|
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 #
|
# Default packages #
|
||||||
####################
|
####################
|
||||||
|
@ -78,3 +67,26 @@ endif
|
||||||
if WITH_UNITS
|
if WITH_UNITS
|
||||||
nobase_include_HEADERS += kernaux/units.h
|
nobase_include_HEADERS += kernaux/units.h
|
||||||
endif
|
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_COUNT 8
|
||||||
#define IRQS_TOTAL 16
|
#define IRQS_TOTAL 16
|
||||||
|
|
||||||
#undef AVAILABLE
|
#if defined(ASM_I386)
|
||||||
#define NOT_AVAILABLE_MSG "Intel 8259-compatible PIC is not available"
|
|
||||||
#ifdef ASM_I386
|
|
||||||
# define AVAILABLE
|
|
||||||
# define inportb kernaux_asm_i386_inportb
|
# define inportb kernaux_asm_i386_inportb
|
||||||
# define outportb kernaux_asm_i386_outportb
|
# define outportb kernaux_asm_i386_outportb
|
||||||
#endif
|
#endif
|
||||||
|
@ -34,30 +31,18 @@ static unsigned char slave_start = 8;
|
||||||
|
|
||||||
void kernaux_drivers_intel_8259_pic_enable_all()
|
void kernaux_drivers_intel_8259_pic_enable_all()
|
||||||
{
|
{
|
||||||
#ifndef AVAILABLE
|
|
||||||
KERNAUX_PANIC(NOT_AVAILABLE_MSG);
|
|
||||||
#else
|
|
||||||
outportb(MASTER_DATA_PORT, 0);
|
outportb(MASTER_DATA_PORT, 0);
|
||||||
outportb(SLAVE_DATA_PORT, 0);
|
outportb(SLAVE_DATA_PORT, 0);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void kernaux_drivers_intel_8259_pic_disable_all()
|
void kernaux_drivers_intel_8259_pic_disable_all()
|
||||||
{
|
{
|
||||||
#ifndef AVAILABLE
|
|
||||||
KERNAUX_PANIC(NOT_AVAILABLE_MSG);
|
|
||||||
#else
|
|
||||||
outportb(MASTER_DATA_PORT, 0xFF);
|
outportb(MASTER_DATA_PORT, 0xFF);
|
||||||
outportb(SLAVE_DATA_PORT, 0xFF);
|
outportb(SLAVE_DATA_PORT, 0xFF);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void kernaux_drivers_intel_8259_pic_enable(const unsigned char number)
|
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);
|
KERNAUX_ASSERT(number < IRQS_TOTAL);
|
||||||
|
|
||||||
if (number < IRQS_COUNT) {
|
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);
|
const uint8_t mask = inportb(SLAVE_DATA_PORT);
|
||||||
outportb(SLAVE_DATA_PORT, mask & ~(1 << (number - IRQS_COUNT)));
|
outportb(SLAVE_DATA_PORT, mask & ~(1 << (number - IRQS_COUNT)));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void kernaux_drivers_intel_8259_pic_disable(const unsigned char number)
|
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);
|
KERNAUX_ASSERT(number < IRQS_TOTAL);
|
||||||
|
|
||||||
if (number < IRQS_COUNT) {
|
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);
|
const uint8_t mask = inportb(SLAVE_DATA_PORT);
|
||||||
outportb(SLAVE_DATA_PORT, mask | (1 << (number - IRQS_COUNT)));
|
outportb(SLAVE_DATA_PORT, mask | (1 << (number - IRQS_COUNT)));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void kernaux_drivers_intel_8259_pic_remap(
|
void kernaux_drivers_intel_8259_pic_remap(
|
||||||
const unsigned char new_master_start,
|
const unsigned char new_master_start,
|
||||||
const unsigned char new_slave_start
|
const unsigned char new_slave_start
|
||||||
) {
|
) {
|
||||||
#ifndef AVAILABLE
|
|
||||||
KERNAUX_PANIC(NOT_AVAILABLE_MSG);
|
|
||||||
#else
|
|
||||||
master_start = new_master_start;
|
master_start = new_master_start;
|
||||||
slave_start = new_slave_start;
|
slave_start = new_slave_start;
|
||||||
|
|
||||||
|
@ -121,14 +97,10 @@ void kernaux_drivers_intel_8259_pic_remap(
|
||||||
// Restore masks
|
// Restore masks
|
||||||
outportb(MASTER_DATA_PORT, master_mask);
|
outportb(MASTER_DATA_PORT, master_mask);
|
||||||
outportb(SLAVE_DATA_PORT, slave_mask);
|
outportb(SLAVE_DATA_PORT, slave_mask);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void kernaux_drivers_intel_8259_pic_eoi(const unsigned char number)
|
void kernaux_drivers_intel_8259_pic_eoi(const unsigned char number)
|
||||||
{
|
{
|
||||||
#ifndef AVAILABLE
|
|
||||||
KERNAUX_PANIC(NOT_AVAILABLE_MSG);
|
|
||||||
#else
|
|
||||||
KERNAUX_ASSERT(number < IRQS_TOTAL);
|
KERNAUX_ASSERT(number < IRQS_TOTAL);
|
||||||
|
|
||||||
const bool to_slave =
|
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_slave) outportb(SLAVE_COMMAND_PORT, 0x20);
|
||||||
if (to_master) outportb(MASTER_COMMAND_PORT, 0x20);
|
if (to_master) outportb(MASTER_COMMAND_PORT, 0x20);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue