summaryrefslogtreecommitdiff
path: root/kernel/floppy.c
diff options
context:
space:
mode:
authorMichal Idziorek <m.i@gmx.at>2014-11-26 12:48:43 +0100
committerMichal Idziorek <m.i@gmx.at>2014-11-26 12:48:43 +0100
commit786bd02b01d80e335d4445698d721213a1884ff5 (patch)
treef10b97cca2e03c279cd5884919c23de03d3e7223 /kernel/floppy.c
parentaad4bfe0261ea623342adc392728281be5062967 (diff)
some cleanup
Diffstat (limited to 'kernel/floppy.c')
-rw-r--r--kernel/floppy.c575
1 files changed, 0 insertions, 575 deletions
diff --git a/kernel/floppy.c b/kernel/floppy.c
deleted file mode 100644
index 1dbe137..0000000
--- a/kernel/floppy.c
+++ /dev/null
@@ -1,575 +0,0 @@
-
-/*
- * Fool OS Simple Floppy Driver.
- *
- * coded by M.idziorek <m.i@gmx.at> on 20th of august 2014 A.D
- *
- * tested in : bochs, qemu and virutalbox so far
- *
- * resources:
- *
- * * http://wiki.osdev.org/Floppy_Disk_Controller#DMA_Data_Transfers
- * * http://forum.osdev.org/viewtopic.php?f=1&t=13538
- * * http://www.brokenthorn.com/Resources/OSDev20.html
- * * http://bochs.sourceforge.net/cgi-bin/lxr/source/iodev/floppy.cc
- * * http://viralpatel.net/taj/tutorial/chs_translation.php
- *
- */
-
-#define FOOLOS_MODULE_NAME "floppy"
-#include "config.h"
-
-#ifdef FOOLOS_COMPILE_FLOPPY
-
-#include "lib/logger/log.h"
-
-#include "x86.h"
-
-#define FLPY_SECTORS_PER_TRACK 18
-
-void flpydsk_send_command (uint8_t cmd);
-void flpydsk_wait_irq ();
-void flpydsk_check_int (uint32_t* st0, uint32_t* cyl);
-
-static volatile int _CurrentDrive=0;
-static volatile uint8_t _FloppyDiskIRQ;
-
-// temporary dma hack
-//! initialize DMA to use phys addr 1k-64k
-void flpydsk_initialize_dma () {
-
- x86_outb (0x0a,0x06); //mask dma channel 2
-
- x86_outb (0xd8,0xff); //reset master flip-flop
-
- //changed to 0x000 (Address)
- x86_outb (0x04, 0x00); //low
- x86_outb (0x04, 0x05); //high
- x86_outb (0x81,0x00); //page reg
-
- x86_outb (0xd8, 0xff); //reset master flip-flop
-
- // x86_outb (0x05, 0xff); //count to 0x23ff (number of bytes in a 3.5" floppy disk track)
-// x86_outb (0x05, 0x23);
-// hey, lets do just ONE sector instead (0x200)
- x86_outb (0x05, 0xff); //low
- x86_outb (0x05, 0x01); //high
-
- x86_outb (0x80, 0); //external page register = 0
-
- x86_outb (0x0a, 0x02); //unmask dma channel 2
- log("dma",FOOLOS_LOG_INFO,"initialized");
-}
-
-//! prepare the DMA for read transfer
-void flpydsk_dma_read () {
- x86_outb (0x0a, 0x06); //mask dma channel 2
-
- x86_outb (0x0b, 0x56); //single transfer, address increment, autoinit, read, channel 2
-
- x86_outb (0x0a, 0x02); //unmask dma channel 2
- log("dma",FOOLOS_LOG_INFO,"configured for reading");
-}
-
-//! prepare the DMA for write transfer
-void flpydsk_dma_write () {
-
- x86_outb (0x0a, 0x06); //mask dma channel 2
- x86_outb (0x0b, 0x5a); //single transfer, address increment, autoinit, write, channel 2
- x86_outb (0x0a, 0x02); //unmask dma channel 2
- log("dma",FOOLOS_LOG_INFO,"configured for writing");
-}
-//
-//
-
-enum FLPYDSK_IO {
-
- FLPYDSK_DOR = 0x3f2,
- FLPYDSK_MSR = 0x3f4,
- FLPYDSK_FIFO = 0x3f5, //data register
- FLPYDSK_CTRL = 0x3f7
-};
-
-enum FLPYDSK_DOR_MASK {
-
- FLPYDSK_DOR_MASK_DRIVE0 = 0, //00000000 = here for completeness sake
- FLPYDSK_DOR_MASK_DRIVE1 = 1, //00000001
- FLPYDSK_DOR_MASK_DRIVE2 = 2, //00000010
- FLPYDSK_DOR_MASK_DRIVE3 = 3, //00000011
- FLPYDSK_DOR_MASK_RESET = 4, //00000100
- FLPYDSK_DOR_MASK_DMA = 8, //00001000
- FLPYDSK_DOR_MASK_DRIVE0_MOTOR = 16, //00010000
- FLPYDSK_DOR_MASK_DRIVE1_MOTOR = 32, //00100000
- FLPYDSK_DOR_MASK_DRIVE2_MOTOR = 64, //01000000
- FLPYDSK_DOR_MASK_DRIVE3_MOTOR = 128 //10000000
-};
-
-enum FLPYDSK_MSR_MASK {
-
- FLPYDSK_MSR_MASK_DRIVE1_POS_MODE = 1, //00000001
- FLPYDSK_MSR_MASK_DRIVE2_POS_MODE = 2, //00000010
- FLPYDSK_MSR_MASK_DRIVE3_POS_MODE = 4, //00000100
- FLPYDSK_MSR_MASK_DRIVE4_POS_MODE = 8, //00001000
- FLPYDSK_MSR_MASK_BUSY = 16, //00010000
- FLPYDSK_MSR_MASK_DMA = 32, //00100000
- FLPYDSK_MSR_MASK_DATAIO = 64, //01000000
- FLPYDSK_MSR_MASK_DATAREG = 128 //10000000
-};
-
-enum FLPYDSK_CMD {
-
- FDC_CMD_READ_TRACK = 2,
- FDC_CMD_SPECIFY = 3,
- FDC_CMD_CHECK_STAT = 4,
- FDC_CMD_WRITE_SECT = 5,
- FDC_CMD_READ_SECT = 6,
- FDC_CMD_CALIBRATE = 7,
- FDC_CMD_CHECK_INT = 8,
- FDC_CMD_WRITE_DEL_S = 9,
- FDC_CMD_READ_ID_S = 0xa,
- FDC_CMD_READ_DEL_S = 0xc,
- FDC_CMD_FORMAT_TRACK = 0xd,
- FDC_CMD_SEEK = 0xf
-};
-
-enum FLPYDSK_CMD_EXT {
-
- FDC_CMD_EXT_SKIP = 0x20, //00100000
- FDC_CMD_EXT_DENSITY = 0x40, //01000000
- FDC_CMD_EXT_MULTITRACK = 0x80 //10000000
-};
-
-enum FLPYDSK_GAP3_LENGTH {
-
- FLPYDSK_GAP3_LENGTH_STD = 42,
- FLPYDSK_GAP3_LENGTH_5_14= 32,
- FLPYDSK_GAP3_LENGTH_3_5= 27
-};
-
-enum FLPYDSK_SECTOR_DTL {
-
- FLPYDSK_SECTOR_DTL_128 = 0,
- FLPYDSK_SECTOR_DTL_256 = 1,
- FLPYDSK_SECTOR_DTL_512 = 2,
- FLPYDSK_SECTOR_DTL_1024 = 4
-};
-
-void flpydsk_write_dor (uint8_t val ) {
-
- //! write the digital output register
- x86_outb (FLPYDSK_DOR, val);
-
-}
-
-void flpydsk_write_ccr (uint8_t val) {
-
- //! write the configuation control
- x86_outb (FLPYDSK_CTRL, val);
-}
-
-
-void flpydsk_motor_on()
-{
- log(FOOLOS_MODULE_NAME,FOOLOS_LOG_DEBUG,"starting motor...");
- //x86_outb (FLPYDSK_DOR, FLPYDSK_DOR_MASK_DRIVE0_MOTOR | FLPYDSK_DOR_MASK_RESET);
- x86_outb (FLPYDSK_DOR, 0x1c);
- sleep(10); // wait ~ 1/3 second
-}
-
-void flpydsk_motor_off()
-{
- log(FOOLOS_MODULE_NAME,FOOLOS_LOG_DEBUG,"stopping motor...");
- x86_outb (FLPYDSK_DOR, 0x0c);
-}
-
-int flpydsk_calibrate (uint32_t drive) {
-
- uint32_t st0, cyl;
-
- if (drive >= 4)
- {
-
- log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"ERROR!");
- return -2;
- }
-
- //! turn on the motor
- flpydsk_motor_on();
-
- int i;
- for (i = 0; i < 10; i++) {
-
- log(FOOLOS_MODULE_NAME,FOOLOS_LOG_DEBUG,"calibrating");
- //! send command
- flpydsk_send_command ( FDC_CMD_CALIBRATE );
- flpydsk_send_command ( drive );
- flpydsk_wait_irq ();
- flpydsk_check_int ( &st0, &cyl);
-
- //! did we fine cylinder 0? if so, we are done
- if (!cyl) {
- if(st0 & 0xC0) {
- log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"calibrating FAILED!");
- }
- // flpydsk_control_motor (false);
- flpydsk_motor_off();
- return 0;
- }
- }
- log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"calibrating FAILED!");
-
-// flpydsk_control_motor (false);
- flpydsk_motor_off();
- return -1;
-}
-
-
-
-void flpydsk_disable_controller () {
-
- flpydsk_write_dor (0);
-}
-
-void flpydsk_enable_controller () {
-
- flpydsk_write_dor ( FLPYDSK_DOR_MASK_RESET | FLPYDSK_DOR_MASK_DMA);
-}
-
-
-uint8_t flpydsk_read_status () {
-
- //! just return main status register
- return x86_inb (FLPYDSK_MSR);
-}
-
-uint8_t flpydsk_read_data () {
-
- //! same as above function but returns data register for reading
- int i;
- for (i = 0; i < 500; i++ )
- if ( flpydsk_read_status () & FLPYDSK_MSR_MASK_DATAREG )
- return x86_inb (FLPYDSK_FIFO);
-
- log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"reading data FAILED!");
-}
-void flpydsk_send_command (uint8_t cmd) {
-
- //! wait until data register is ready. We send commands to the data register
- int i;
- for (i = 0; i < 500; i++ )
- if ( flpydsk_read_status () & FLPYDSK_MSR_MASK_DATAREG )
- {
- x86_outb(FLPYDSK_FIFO, cmd);
- return;
- }
- log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"writing data FAILED!");
-}
-
-void flpydsk_drive_data (uint32_t stepr, uint32_t loadt, uint32_t unloadt, int dma ) {
-
- uint32_t data = 0;
-
- flpydsk_send_command (FDC_CMD_SPECIFY);
-
- data = ( (stepr & 0xf) << 4) | (unloadt & 0xf);
- flpydsk_send_command (data);
-
- data = (loadt) << 1 | dma;
- flpydsk_send_command (data);
-}
-
-void flpydsk_reset()
-{
- uint32_t st0, cyl;
-
- //! reset the controller
- log(FOOLOS_MODULE_NAME,FOOLOS_LOG_DEBUG,"reset controller");
- flpydsk_disable_controller ();
- flpydsk_enable_controller ();
- flpydsk_wait_irq ();
-
- //! send CHECK_INT/SENSE INTERRUPT command to all drives
- int i;
- for (i=0; i<4; i++)
- flpydsk_check_int (&st0,&cyl);
-
- //! transfer speed 500kb/s
- flpydsk_write_ccr (0);
-
- //! pass mechanical drive info. steprate=3ms, unload time=240ms, load time=16ms
-// flpydsk_drive_data (3,16,240,0);
-//
-
- flpydsk_send_command (FDC_CMD_SPECIFY);
- flpydsk_send_command (0xdf); /* steprate = 3ms, unload time = 240ms */
- flpydsk_send_command (0x02); /* load time = 16ms, no-DMA = 0 */
-
- //! calibrate the disk
- flpydsk_calibrate ( _CurrentDrive );
-}
-
-void int_floppy_handler()
-{
- X86_IRQ_BEGIN
- _FloppyDiskIRQ=1;
- X86_IRQ_END
-}
-
-void flpydsk_wait_irq()
-{
- log(FOOLOS_MODULE_NAME,FOOLOS_LOG_FINE,"waiting for irq6");
-
- while (1)
- {
- sleep(2);
- x86_int_disable();
- if(_FloppyDiskIRQ==1)break;
- x86_int_enable();
-
- }
- _FloppyDiskIRQ = 0;
- x86_int_enable();
-
- log(FOOLOS_MODULE_NAME,FOOLOS_LOG_FINE,"irq6 received");
-}
-
-void flpydsk_check_int (uint32_t* st0, uint32_t* cyl) {
-
- flpydsk_send_command (FDC_CMD_CHECK_INT);
-
- *st0 = flpydsk_read_data ();
- *cyl = flpydsk_read_data ();
-}
-
-void flpydsk_write_sector_imp (uint8_t head, uint8_t track, uint8_t sector) {
-
- //sector=1;
- //! set the DMA for read transfer
- flpydsk_dma_write ();
-
- //flpydsk_drive_data (13, 1, 0xf, 0);
- log(FOOLOS_MODULE_NAME,FOOLOS_LOG_DEBUG,"writing head/track/sector");
-
- uint32_t st0, cyl;
-
- //! write a sector
- flpydsk_send_command (
- FDC_CMD_WRITE_SECT | FDC_CMD_EXT_MULTITRACK |
- FDC_CMD_EXT_DENSITY);
- flpydsk_send_command ( head << 2 | _CurrentDrive );
- flpydsk_send_command ( track);
- flpydsk_send_command ( head); // first head should match with above!
- flpydsk_send_command ( sector);
- flpydsk_send_command ( FLPYDSK_SECTOR_DTL_512 );
- //flpydsk_send_command ( 1 ); // number of tracks we want
- flpydsk_send_command ( FLPY_SECTORS_PER_TRACK ); // number of tracks !
-
- /*
- flpydsk_send_command (
- ( ( sector + 1 ) >= FLPY_SECTORS_PER_TRACK )
- ? FLPY_SECTORS_PER_TRACK : sector + 1 );
- */
-
- flpydsk_send_command ( FLPYDSK_GAP3_LENGTH_3_5 );
- flpydsk_send_command ( 0xff );
-
- //! wait for irq
- flpydsk_wait_irq ();
-
- //! read status info
- int j;
- for (j=0; j<7; j++)
- flpydsk_read_data ();
-
- //! let FDC know we handled interrupt
- flpydsk_check_int (&st0,&cyl);
-}
-void flpydsk_read_sector_imp (uint8_t head, uint8_t track, uint8_t sector) {
-
- //sector=1;
- //! set the DMA for read transfer
- flpydsk_dma_read ();
-
- //flpydsk_drive_data (13, 1, 0xf, 0);
- log(FOOLOS_MODULE_NAME,FOOLOS_LOG_DEBUG,"reading head/track/sector");
-
- uint32_t st0, cyl;
-
- //! read in a sector
- flpydsk_send_command (
- FDC_CMD_READ_SECT | FDC_CMD_EXT_MULTITRACK |
- FDC_CMD_EXT_SKIP | FDC_CMD_EXT_DENSITY);
- flpydsk_send_command ( head << 2 | _CurrentDrive );
- flpydsk_send_command ( track);
- flpydsk_send_command ( head);
- flpydsk_send_command ( sector);
- flpydsk_send_command ( FLPYDSK_SECTOR_DTL_512 );
- //flpydsk_send_command ( 1 ); // number of tracks we want
- flpydsk_send_command ( FLPY_SECTORS_PER_TRACK ); // number of tracks !
-
- /*
- flpydsk_send_command (
- ( ( sector + 1 ) >= FLPY_SECTORS_PER_TRACK )
- ? FLPY_SECTORS_PER_TRACK : sector + 1 );
- */
-
-
- flpydsk_send_command ( FLPYDSK_GAP3_LENGTH_3_5 );
- flpydsk_send_command ( 0xff );
-
- //! wait for irq
- flpydsk_wait_irq ();
-
- //! read status info
- int j;
- for (j=0; j<7; j++)
- flpydsk_read_data ();
-
- //! let FDC know we handled interrupt
- flpydsk_check_int (&st0,&cyl);
-}
-
-int flpydsk_seek ( uint32_t cyl, uint32_t head )
-{
- //cyl=1;
- //head=1;
-
- uint32_t st0, cyl0;
-
- if (_CurrentDrive >= 4)
- return -1;
-
- int i;
- for (i = 0; i < 10; i++ ) {
-
- log(FOOLOS_MODULE_NAME,FOOLOS_LOG_DEBUG,"seeking cyl: %d, head: %d",cyl,head);
-
- //! send the command
- flpydsk_send_command (FDC_CMD_SEEK);
- flpydsk_send_command ( (head << 2) | _CurrentDrive);
- flpydsk_send_command (cyl);
-
-
- //! wait for the results phase IRQ
- flpydsk_wait_irq ();
- flpydsk_check_int (&st0,&cyl0);
-
- //! found the cylinder?
- if ( cyl0 == cyl)
- return 0;
- }
-
- return -1;
-}
-
-void flpydsk_lba_to_chs (int lba,int *head,int *track,int *sector) {
-
- //cylinder
- //
-// *track = lba % ( FLPY_SECTORS_PER_TRACK * 2 );
- /// *head = ( lba % FLPY_SECTORS_PER_TRACK ) % 2;//* 2 ) ) / ( FLPY_SECTORS_PER_TRACK );
- //*sector = (lba % FLPY_SECTORS_PER_TRACK) +1;
-
- *head = ( lba % ( FLPY_SECTORS_PER_TRACK * 2 ) ) / ( FLPY_SECTORS_PER_TRACK );
- *track = lba / ( FLPY_SECTORS_PER_TRACK * 2 );
- *sector = lba % FLPY_SECTORS_PER_TRACK + 1;
-}
-
-
-uint8_t* flpydsk_read_sector (int sectorLBA) {
-
- log(FOOLOS_MODULE_NAME,FOOLOS_LOG_DEBUG,"reading sector: %d",sectorLBA);
-
-
- if (_CurrentDrive >= 4)
- return 0;
-
- //! convert LBA sector to CHS
- int head=0, track=0, sector=1;
- flpydsk_lba_to_chs (sectorLBA, &head, &track, &sector);
-
-
- //! turn motor on and seek to track
- // start motor
- flpydsk_motor_on();
-
- if (flpydsk_seek (track, head) != 0)
- return 0;
-
- //! read sector and turn motor off
- flpydsk_read_sector_imp (head, track, sector);
- // flpydsk_control_motor (false);
- flpydsk_motor_off();
-
-
- //! warning: this is a bit hackish
- //return (uint8_t*) DMA_BUFFER;
- return (uint8_t*) 0x0;
-}
-
-uint8_t* flpydsk_write_sector (int sectorLBA) {
-
- log(FOOLOS_MODULE_NAME,FOOLOS_LOG_DEBUG,"writing sector: %d",sectorLBA);
-
- if (_CurrentDrive >= 4)
- return 0;
-
- //! convert LBA sector to CHS
- int head=0, track=0, sector=1;
- flpydsk_lba_to_chs (sectorLBA, &head, &track, &sector);
-
-
- //! turn motor on and seek to track
- // start motor
- flpydsk_motor_on();
-
- if (flpydsk_seek (track, head) != 0)
- return 0;
-
- //! read sector and turn motor off
- flpydsk_write_sector_imp (head, track, sector);
- // flpydsk_control_motor (false);
- flpydsk_motor_off();
-
-
- //! warning: this is a bit hackish
- //return (uint8_t*) DMA_BUFFER;
- return (uint8_t*) 0x0;
-}
-
-void floppy_init()
-{
- // init dma
- flpydsk_initialize_dma ();
-
- _CurrentDrive=0;
- _FloppyDiskIRQ = 0;
-
- log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"driver init (wathchdog: 0x%08X)",&_FloppyDiskIRQ);
-
-
- flpydsk_reset ();
-
- char *dma=0x0500;
-
- log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"test reading");
-
- flpydsk_read_sector(65);
- log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"finished reading");
-
- flpydsk_reset ();
-
- flpydsk_read_sector(64);
- log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"finished reading");
- log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"test read: %s",dma);
-
- flpydsk_reset ();
-
-// log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"test write (sector: 100)");
-// flpydsk_write_sector(100);
-// log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"finished writing");
-
-
-}
-
-#endif