[GOOD] BUILD 0.1.0.450 DATE 8/29/2011 AT 10:30 AM
==================================================== + Changed 'align 0x4' line above multiboot header in loader.asm to 'align 4' + Removed -e option for echo in build.sh + Modified build.sh for linux + Fixed triple fault when enabling paging + Fixed page faults at memory manager initialization + Fixed 'mem' console function + Added more info about page fault at crash screen + Added Panic() macro + Added verbose mode for memory manager [ BAD] BUILD 0.1.0.390 DATE 8/27/2011 AT 10:54 PM ==================================================== + Added stdlib routines, separated in different files + Rewritten physical memory manager + Added virtual mem manager + Added memory allocation/freeing + Added memory library + Added temporary allocation (at end of kernel), until paging is started - Removed functionality from debug console function 'mem' - Removed system.h, the one remaining function now in stdio.h
This commit is contained in:
384
Kernel/drivers/floppy/floppy.c
Normal file
384
Kernel/drivers/floppy/floppy.c
Normal file
@ -0,0 +1,384 @@
|
||||
/*
|
||||
* floppy.c
|
||||
*
|
||||
* Created on: Aug 20, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
|
||||
#include <debugio.h>
|
||||
#include <stdio.h>
|
||||
#include <types.h>
|
||||
#include <time.h>
|
||||
#include <storage.h>
|
||||
#include "floppy.h"
|
||||
#include "../dma/dma.h"
|
||||
#include "../cmos/cmos.h"
|
||||
|
||||
FloppyType fdTypes[] = {
|
||||
/* Sectors
|
||||
* | Sectors per track
|
||||
* | | Heads
|
||||
* | | | Tracks
|
||||
* | | | | Gap1
|
||||
* | | | | | Data rate
|
||||
* | | | | | | Spec1
|
||||
* | | | | | | | SRT HLT HUT Motor Spinup time
|
||||
* | | | | | | | | | | | Motor Spindown time
|
||||
* | | | | | | | | | | | | Interrupt timeout
|
||||
* | | | | | | | | | | | | | Disk type name string*/
|
||||
{ 0, 0,0, 0,0x00,0x00,0x00,0x00,0x00,0x00, 0, 0, 0, "none"},
|
||||
{ 720, 9,2,40,0x2A,0x01,0xDF,0x0C,0x04,0x00,1000,1000,3000, "5.25\" 360k"},
|
||||
{ 2400,15,2,80,0x1B,0x00,0xDF,0x0A,0x08,0x00, 400,1000,3000, "5.25\" 1.2M"},
|
||||
{ 1440, 9,2,80,0x2A,0x02,0xDF,0x0F,0x04,0x00,1000,1000,3000, "3.5\" 720k"},
|
||||
{ 2880,18,2,80,0x1B,0x00,0xCF,0x0C,0x08,0x00, 400,1000,3000, "3.5\" 1.44M"},
|
||||
//{ 2880,18,2,80,0x1B,0x00,0xCF,0x0C,0x08,0x00,2000,3000,3000, "3.5\" 1.44M"},
|
||||
{ 5760,36,2,80,0x1B,0x03,0xAF,0x0A,0x0F,0x00, 400,1000,3000, "3.5\" 2.88M AMI BIOS"},
|
||||
{ 5760,36,2,80,0x1B,0x03,0xAF,0x0A,0x0F,0x00, 400,1000,3000, "3.5\" 2.88M"},
|
||||
};
|
||||
|
||||
int8 fd0, fd1;
|
||||
|
||||
/**************************************
|
||||
* IRQ handler etc *
|
||||
**************************************/
|
||||
volatile uint8 FloppyIrqFired;
|
||||
void FloppyIrqHandler(_RegsStack32* UNUSED(r))
|
||||
{
|
||||
FloppyIrqFired = 1;
|
||||
}
|
||||
|
||||
void FloppyWaitIrq()
|
||||
{
|
||||
TimerStart(fdTypes[4].InterruptTimeout);
|
||||
|
||||
while (!FloppyIrqFired && !TimerIsDone());
|
||||
|
||||
if (!FloppyIrqFired) {
|
||||
Error("%#[Floppy] %#Irq timeout [%ums] !\n", ColorBrown, ColorLightRed, fdTypes[4].InterruptTimeout);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************************************
|
||||
* Installation *
|
||||
**************************************/
|
||||
void FloppyInitialize()
|
||||
{
|
||||
// Detect drives
|
||||
uint8 fd = CmosRead(0x10);
|
||||
fd0 = fd >> 4;
|
||||
fd1 = fd & 0xf;
|
||||
|
||||
if (fd0 > 6) fd0 = 0;
|
||||
if (fd1 > 6) fd1 = 0;
|
||||
|
||||
if (!fd0 && !fd1) {
|
||||
Error("%#[Floppy] %#No supported floppy drives found.", ColorBrown, ColorLightRed);
|
||||
outportb(FloppyRegisterDigitalOutput, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
Log("%#[Floppy] %#Detected floppy drives:", ColorBrown, ColorLightGray);
|
||||
if (fd0) Log(" %#fd0=%#%s", ColorLightCyan, Color(ColorCyan, ColorWhite), fdTypes[fd0].Name);
|
||||
if (fd1) Log(" %#fd1=%#%s", ColorLightCyan, Color(ColorCyan, ColorWhite), fdTypes[fd1].Name);
|
||||
Log("\n");
|
||||
|
||||
|
||||
// Reset floppy controller
|
||||
FloppyReset();
|
||||
|
||||
// Configure and lock
|
||||
FloppyConfigure();
|
||||
FloppySendCommand(FloppyCommandLock | 0x80);
|
||||
FloppyReadData();
|
||||
|
||||
// Enable perpendicular mode for 3.5" ED floppies
|
||||
if (fd0 > 4)
|
||||
{
|
||||
FloppySendCommand(FloppyCommandPerpendicularMode);
|
||||
FloppySendCommand(1);
|
||||
}
|
||||
if (fd1 > 4)
|
||||
{
|
||||
FloppySendCommand(FloppyCommandPerpendicularMode);
|
||||
FloppySendCommand(2);
|
||||
}
|
||||
|
||||
// Initialize DMA
|
||||
FloppyInitDma();
|
||||
}
|
||||
|
||||
void FloppyInitDma()
|
||||
{
|
||||
DmaMaskChannel(2);
|
||||
DmaResetFlipFlop(2);
|
||||
DmaSetAddress(2, 0, 0x10);
|
||||
DmaResetFlipFlop(2);
|
||||
DmaSetCount(2, 0xff, 0x23);
|
||||
DmaSetExternalPageRegisters(2,0);
|
||||
DmaUnmaskChannel(2);
|
||||
}
|
||||
|
||||
|
||||
/**************************************
|
||||
* Controller reset *
|
||||
**************************************/
|
||||
void FloppyReset()
|
||||
{
|
||||
FloppyIrqFired = 0; int32 i = 0;
|
||||
|
||||
Log("%#[Floppy] %#Resetting...\n", ColorBrown, ColorLightGray);
|
||||
|
||||
// Clear reset bit from DOR
|
||||
outportb(FloppyRegisterDigitalOutput, 0);
|
||||
for (i = 0; i < 1000; i++);
|
||||
outportb(FloppyRegisterDigitalOutput, 4|8);
|
||||
|
||||
// Wait for IRQ6
|
||||
FloppyWaitIrq(fd0);
|
||||
|
||||
// Recalibrate every drive
|
||||
if (fd0)
|
||||
{
|
||||
FloppyMotor(0,1);
|
||||
FloppySelectDrive(0);
|
||||
FloppyRecalibrate(0);
|
||||
FloppyMotor(0,0);
|
||||
}
|
||||
|
||||
if (fd1)
|
||||
{
|
||||
FloppyMotor(1,1);
|
||||
FloppySelectDrive(1);
|
||||
FloppyRecalibrate(1);
|
||||
FloppyMotor(1,0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**************************************
|
||||
* Configure floppy controller *
|
||||
**************************************/
|
||||
void FloppyConfigure()
|
||||
{
|
||||
FloppySendCommand(FloppyCommandConfigure);
|
||||
FloppySendCommand(0);
|
||||
FloppySendCommand(1<<6 | 7);
|
||||
FloppySendCommand(0);
|
||||
}
|
||||
|
||||
/**************************************
|
||||
* Base commands *
|
||||
**************************************/
|
||||
void FloppySendCommand (uint8 command)
|
||||
{
|
||||
int32 t;
|
||||
for (t = 0; t < 5000 && ((inportb(FloppyRegisterMainStatus) & FloppyMsrRQM) == 0); t++) ;
|
||||
|
||||
outportb (FloppyRegisterFIFO, command);
|
||||
|
||||
}
|
||||
|
||||
uint8 FloppyReadData ()
|
||||
{
|
||||
int32 t;
|
||||
for (t = 0; t < 5000 && ((inportb(FloppyRegisterMainStatus) & FloppyMsrRQM) == 0); t++) ;
|
||||
|
||||
return inportb (FloppyRegisterFIFO);
|
||||
}
|
||||
|
||||
/**************************************
|
||||
* Sense interrupt *
|
||||
**************************************/
|
||||
void FloppySenseInterrupt(uint8 *st0, uint8 *cyl)
|
||||
{
|
||||
FloppySendCommand(FloppyCommandSenseInterrupt);
|
||||
*st0 = FloppyReadData();
|
||||
*cyl = FloppyReadData();
|
||||
}
|
||||
|
||||
/**************************************
|
||||
* Specify *
|
||||
**************************************/
|
||||
void FloppySpecify (uint8 fd)
|
||||
{
|
||||
FloppySendCommand(FloppyCommandSpecify);
|
||||
FloppySendCommand((fdTypes[fd].SRT << 4) | fdTypes[fd].HUT);
|
||||
FloppySendCommand(fdTypes[fd].HLT << 1);
|
||||
}
|
||||
|
||||
/**************************************
|
||||
* Motor on/off *
|
||||
**************************************/
|
||||
void FloppyMotor (uint8 fd_number, uint8 status)
|
||||
{
|
||||
if (fd_number >= 2) return;
|
||||
|
||||
uint8 fd = (fd_number == 0) ? fd0 : fd1;
|
||||
uint8 temp = inportb(FloppyRegisterDigitalOutput);
|
||||
|
||||
// Turn motor on/off
|
||||
if (status) temp |= 0x1<<(4+fd_number);
|
||||
else temp &= ~(0x1<<(4+fd_number));
|
||||
outportb(FloppyRegisterDigitalOutput, temp);
|
||||
|
||||
// Wait for spinup/spindown
|
||||
if (status) TimerStart(fdTypes[fd].Spinup);
|
||||
else TimerStart(fdTypes[fd].Spindown);
|
||||
|
||||
Log("%#[Floppy] %#Waiting for motor...\n", ColorBrown, ColorLightGray);
|
||||
while (!TimerIsDone());
|
||||
}
|
||||
|
||||
/**************************************
|
||||
* Select drive *
|
||||
**************************************/
|
||||
void FloppySelectDrive(uint8 number)
|
||||
{
|
||||
if (number >= 2) return;
|
||||
uint8 fd = (number == 0) ? fd0 : fd1;
|
||||
|
||||
// Set CCR
|
||||
outportb(FloppyRegisterConfigurationControl, fdTypes[fd].DataRate);
|
||||
|
||||
// Specify
|
||||
FloppySpecify(fd);
|
||||
|
||||
// Select drive
|
||||
uint8 dor = inportb(FloppyRegisterDigitalOutput);
|
||||
dor = (dor & ~0xFF) | number;
|
||||
}
|
||||
|
||||
/**************************************
|
||||
* RECALIBRATE *
|
||||
* motor must be on, drive selected *
|
||||
**************************************/
|
||||
void FloppyRecalibrate(uint8 fd_number)
|
||||
{
|
||||
if (fd_number >= 2) return;
|
||||
|
||||
uint8 st0, cyl, timeout = 10;
|
||||
do {
|
||||
Log("%#[Floppy] %#Recalibrating: attempt %u/10\n", ColorBrown, ColorLightGray, 11-timeout);
|
||||
FloppyIrqFired = 0;
|
||||
FloppySendCommand(FloppyCommandRecalibrate);
|
||||
FloppySendCommand(fd_number);
|
||||
FloppyWaitIrq();
|
||||
|
||||
FloppySenseInterrupt(&st0, &cyl);
|
||||
|
||||
timeout--;
|
||||
} while((st0 & 0x20) == 0 && timeout > 0);
|
||||
}
|
||||
|
||||
/**************************************
|
||||
* SEEK *
|
||||
* motor must be on, drive selected *
|
||||
**************************************/
|
||||
void FloppySeek(uint8 fd_number, uint8 cylinder, uint8 head)
|
||||
{
|
||||
if (fd_number >= 2) return;
|
||||
|
||||
uint8 st0, cyl, timeout = 10;
|
||||
do {
|
||||
Log("%#[Floppy] %#Seeking: attempt %u/10\n", ColorBrown, ColorLightGray, 11-timeout);
|
||||
FloppyIrqFired = 0;
|
||||
FloppySendCommand(FloppyCommandSeek);
|
||||
FloppySendCommand(head<<2 | fd_number);
|
||||
FloppySendCommand(cylinder);
|
||||
FloppyWaitIrq();
|
||||
|
||||
FloppySenseInterrupt(&st0, &cyl);
|
||||
|
||||
timeout--;
|
||||
} while(cyl != cylinder && timeout > 0);
|
||||
|
||||
}
|
||||
|
||||
/**************************************
|
||||
* READ/WRITE *
|
||||
* motor must be on, drive selected *
|
||||
**************************************/
|
||||
void FloppyRW(uint8 isWrite, uint8 fd_number, uint8 head, uint8 cylinder, uint8 sector)
|
||||
{
|
||||
if (fd_number >= 2) return;
|
||||
uint8 fd = (fd_number == 0) ? fd0 : fd1;
|
||||
|
||||
uint8 timeout = 10;
|
||||
uint8 result[7], i, error;
|
||||
do
|
||||
{
|
||||
error = 0;
|
||||
Log("%#[Floppy] %#Read/write operation: attempt %u/10\n", ColorBrown, ColorLightGray, 11-timeout);
|
||||
FloppyIrqFired = 0;
|
||||
|
||||
if (isWrite) FloppySendCommand(FloppyCommandWriteData | FloppyModeMultitrack | FloppyModeMagneticEncoding);
|
||||
else FloppySendCommand(FloppyCommandReadData | FloppyModeMultitrack | FloppyModeMagneticEncoding);
|
||||
|
||||
FloppySendCommand(head<<2 | fd_number);
|
||||
FloppySendCommand(cylinder);
|
||||
FloppySendCommand(head);
|
||||
FloppySendCommand(sector);
|
||||
FloppySendCommand(2);
|
||||
FloppySendCommand(fdTypes[fd].SectorsPerTrack);
|
||||
FloppySendCommand(fdTypes[fd].Gap);
|
||||
FloppySendCommand(0xff);
|
||||
|
||||
FloppyWaitIrq();
|
||||
|
||||
for (i = 0; i < 7; i++)
|
||||
result[i] = FloppyReadData();
|
||||
|
||||
// Disk is write protected, don't try again
|
||||
if (result[1] & 2)
|
||||
{
|
||||
Error("%#[Floppy] %#Error: disk is write protected!\n", ColorBrown, ColorLightRed);
|
||||
return;
|
||||
}
|
||||
|
||||
// Any other error - try again
|
||||
if (result[0] & 0xC8) error = 1;
|
||||
if (result[1] & 0xB5) error = 1;
|
||||
if (result[2] & 0x77) error = 1;
|
||||
if (result[6] & 0x02) error = 1;
|
||||
|
||||
timeout--;
|
||||
} while (timeout > 0 && !error);
|
||||
}
|
||||
|
||||
uint32 FloppyRead(uint8 drive, uint32 lba)
|
||||
{
|
||||
if (drive >= 2) return 0;
|
||||
uint8 fd = (drive == 0) ? fd0 : fd1;
|
||||
|
||||
// Convert LBA to CHS
|
||||
uint32 cyl=0, head=0, sect=1;
|
||||
ConvertLbaToChs(fdTypes[fd].SectorsPerTrack, lba, &cyl, &head, §);
|
||||
Log("%#[Floppy] %#Converted LBA=%u to Cyl=%u Head=%u Sect=%u\n", ColorBrown, ColorLightGray, lba, cyl, head, sect);
|
||||
|
||||
FloppyInitDma();
|
||||
|
||||
// Reset drive if necessary
|
||||
if ((inportb(FloppyRegisterMainStatus) & 0xC0) != 0x80)
|
||||
FloppyReset();
|
||||
|
||||
// Start motor, select drive
|
||||
FloppyMotor(drive, 1);
|
||||
FloppySelectDrive(drive);
|
||||
|
||||
// Seek to correct location
|
||||
FloppySeek(drive, cyl, head);
|
||||
|
||||
// Start DMA read
|
||||
DmaMaskChannel(2);
|
||||
DmaSetMode(2, 0x46);
|
||||
DmaUnmaskChannel(2);
|
||||
|
||||
FloppyRW(0, drive, head, cyl, sect);
|
||||
|
||||
FloppyMotor(drive, 0);
|
||||
|
||||
return 0x1000;
|
||||
}
|
||||
|
||||
// Log("%#[Drivers] %#Initializing blah blah %d...", ColorWhite, ColorLightGray,PIT_FREQUENCY);
|
86
Kernel/drivers/floppy/floppy.h
Normal file
86
Kernel/drivers/floppy/floppy.h
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* floppy.h
|
||||
*
|
||||
* Created on: Aug 20, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
|
||||
#ifndef FLOPPY_H_
|
||||
#define FLOPPY_H_
|
||||
|
||||
#include <types.h>
|
||||
|
||||
enum FloppyRegisters
|
||||
{
|
||||
FloppyRegisterStatusA = 0x3F0, // read-only
|
||||
FloppyRegisterStatusB = 0x3F1, // read-only
|
||||
FloppyRegisterDigitalOutput = 0x3F2,
|
||||
FloppyRegisterTapeDrive = 0x3F3,
|
||||
FloppyRegisterMainStatus = 0x3F4, // read-only
|
||||
FloppyRegisterDatarateSelect = 0x3F4, // write-only
|
||||
FloppyRegisterFIFO = 0x3F5,
|
||||
FloppyRegisterDigitalInput = 0x3F7, // read-only
|
||||
FloppyRegisterConfigurationControl = 0x3F7 // write-only
|
||||
};
|
||||
|
||||
enum FloppyCommands
|
||||
{
|
||||
FloppyCommandReadTrack = 2, // generates IRQ6
|
||||
FloppyCommandSpecify = 3, // * set drive parameters
|
||||
FloppyCommandSenseDriveStatus = 4,
|
||||
FloppyCommandWriteData = 5, // * write to the disk
|
||||
FloppyCommandReadData = 6, // * read from the disk
|
||||
FloppyCommandRecalibrate = 7, // * seek to cylinder 0
|
||||
FloppyCommandSenseInterrupt = 8, // * ack IRQ6, get status of last command
|
||||
FloppyCommandWriteDeletedData = 9,
|
||||
FloppyCommandReadID = 10, // generates IRQ6
|
||||
FloppyCommandReadDeletedData = 12,
|
||||
FloppyCommandFormatTrack = 13, // *
|
||||
FloppyCommandSeek = 15, // * seek both heads to cylinder X
|
||||
FloppyCommandVersion = 16, // * used during initialization, once
|
||||
FloppyCommandScanEqual = 17,
|
||||
FloppyCommandPerpendicularMode = 18, // * used during initialization, once, maybe
|
||||
FloppyCommandConfigure = 19, // * set controller parameters
|
||||
FloppyCommandLock = 20, // * protect controller params from a reset
|
||||
FloppyCommandVerify = 22,
|
||||
FloppyCommandScanLowOrEqual = 25,
|
||||
FloppyCommandScanHighOrEqual = 29,
|
||||
|
||||
FloppyModeMultitrack = 0x80,
|
||||
FloppyModeMagneticEncoding = 0x40, // always set for read/write/verify/format
|
||||
FloppyModeSkip = 0x20
|
||||
};
|
||||
|
||||
enum FloppyMSRMasks
|
||||
{
|
||||
FloppyMsrRQM = 0x80,
|
||||
FloppyMsrDIO = 0x40,
|
||||
FloppyMsrNDMA = 0x20,
|
||||
FloppyMsrBusy = 0x10
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint32 Size, SectorsPerTrack, Heads, Tracks;
|
||||
uint8 Gap, DataRate, Spec1, SRT, HLT, HUT;
|
||||
uint32 Spinup, Spindown, InterruptTimeout;
|
||||
string Name;
|
||||
} FloppyType;
|
||||
|
||||
extern void FloppyInitialize();
|
||||
extern void FloppyIrqHandler(_RegsStack32 *r);
|
||||
extern void FloppyWaitIrq();
|
||||
extern void FloppyInitDma();
|
||||
|
||||
extern void FloppyReset();
|
||||
extern void FloppyConfigure();
|
||||
extern void FloppySendCommand (uint8 command);
|
||||
extern uint8 FloppyReadData ();
|
||||
extern void FloppySenseInterrupt(uint8 *st0, uint8 *cyl);
|
||||
extern void FloppySpecify (uint8 fd);
|
||||
extern void FloppyMotor (uint8 fd_number, uint8 status);
|
||||
extern void FloppySelectDrive(uint8 number);
|
||||
extern void FloppyRecalibrate(uint8 fd_number);
|
||||
extern void FloppyRW(uint8 isWrite, uint8 fd_number, uint8 head, uint8 cylinder, uint8 sector);
|
||||
extern uint32 FloppyRead(uint8 drive, uint32 lba);
|
||||
|
||||
#endif /* FLOPPY_H_ */
|
Reference in New Issue
Block a user