More system calls

Added some more system calls. Made a slight change to the TRAP convention. Now using TRAP #15 for system calls, and moved everything down one register: D0 = function, D1 = param 1, etc.
This commit is contained in:
Peter Weingartner 2021-09-21 19:07:45 -04:00
parent 7498b83349
commit cb75f46b2e
14 changed files with 5938 additions and 5034 deletions

View file

@ -10,6 +10,7 @@
#include "dev/channel.h"
#include "dev/console.h"
#include "dev/ps2.h"
#include "dev/kbd_mo.h"
#include "dev/text_screen_iii.h"

View file

@ -7,6 +7,8 @@
*/
#include <string.h>
#include "log.h"
#include "syscalls.h"
#include "fsys.h"
#include "fatfs/ff.h"
#include "dev/channel.h"
@ -448,6 +450,34 @@ short fchan_ioctrl(t_channel * chan, short command, unsigned char * buffer, shor
return 0;
}
/*
* Mount, or remount the block device
*
* For the hard drive, this need be called only once, but for removable
* devices, this should be called whenever the media has changed.
*
* Inputs:
* bdev = the number of the block device to mount or re-mount
*
* Returns:
* 0 on success, any other number is an error
*/
short fsys_mount(short bdev) {
FRESULT fres;
char drive[3];
drive[0] = '0' + (char)bdev;
drive[1] = ':';
drive[2] = 0;
fres = f_mount(&g_drive[bdev], drive, 0);
if (fres != FR_OK) {
DEBUG("Unable to mount drive:");
DEBUG(drive);
return fres;
} else {
return 0;
}
}
/**
* Initialize the file system
@ -468,7 +498,14 @@ short fsys_init() {
g_fil_state[i] = 0;
}
/* TODO: Mount all logical drives that are present */
/* Mount all logical drives that are present */
for (i = 0; i < MAX_DRIVES; i++) {
short res = sys_bdev_status((short)i);
if (res >= 0) {
fsys_mount(i);
}
}
/* Register the channel driver for files. */
@ -486,4 +523,6 @@ short fsys_init() {
g_file_dev.flush = fchan_flush;
cdev_register(&g_file_dev);
return 0;
}

View file

@ -26,7 +26,7 @@ typedef struct s_file_info {
* Returns:
* 0 on success, negative number on failure.
*/
short fsys_init();
extern short fsys_init();
/**
* Attempt to open a file given the path to the file and the mode.

66
src/dev/wip/midi.c Normal file
View file

@ -0,0 +1,66 @@
/*
* Definitions for the MIDI ports
*/
#include "midi_reg.h"
#include "dev/midi.h"
/*
* Initilialize the MIDI port
*/
short midi_init() {
*MIDI_CMD = 0xff; /* Send the command to reset the MIDI port */
// while ((*MIDI_STAT & MIDI_STAT_RX_EMPTY) == 0) {
// /* While there is data, throw it out */
// unsigned char dummy = *MIDI_DATA;
// }
*MIDI_CMD = 0x3F; /* Switch the MIDI port into UART mode */
// while ((*MIDI_STAT & MIDI_STAT_RX_EMPTY) == 0) {
// /* While there is data, throw it out */
// unsigned char dummy = *MIDI_DATA;
// }
return 0;
}
/*
* Send a byte to the MIDI port
*
* Inputs:
* b = the byte to send
*/
short midi_put(unsigned char b) {
while ((*MIDI_STAT & MIDI_STAT_TX_BUSY) != 0) {
/* Wait until the MIDI transmitter is not busy */
;
}
/* Send the byte */
*MIDI_DATA = b;
while ((*MIDI_STAT & MIDI_STAT_TX_BUSY) != 0) {
/* Wait until the MIDI transmitter is not busy */
;
}
return 0;
}
/*
* Get a byte from the MIDI port
*
* Returns:
* b = the byte to send
*/
short midi_get_poll() {
if (*MIDI_STAT & MIDI_STAT_RX_EMPTY) {
/* There's no data... return 0 */
return 0;
} else {
/* Get and return the byte */
return (short)*MIDI_DATA;
}
}

29
src/dev/wip/midi.h Normal file
View file

@ -0,0 +1,29 @@
/*
* Declarations for the MIDI ports
*/
#ifndef __MIDI_H
#define __MIDI_H
/*
* Initilialize the MIDI port
*/
extern short midi_init();
/*
* Send a byte to the MIDI port
*
* Inputs:
* b = the byte to send
*/
extern short midi_put(unsigned char b);
/*
* Get a byte from the MIDI port
*
* Returns:
* b = the byte to send
*/
extern short midi_get_poll();
#endif

View file

@ -14,14 +14,14 @@
#include "dev/text_screen_iii.h"
#include "dev/pata.h"
#include "dev/ps2.h"
// #include "dev/kbd_mo.h"
#include "dev/kbd_mo.h"
#include "dev/sdc.h"
#include "dev/uart.h"
#include "snd/codec.h"
#include "snd/psg.h"
#include "snd/sid.h"
#include "fatfs/ff.h"
// #include "cli/cli.h"
#include "cli/cli.h"
#include "log.h"
const char* VolumeStr[FF_VOLUMES] = { "@S", "@F", "@H" };
@ -190,22 +190,23 @@ void initialize() {
DEBUG("PS/2 keyboard initialized.");
}
// if (res = kbdmo_init()) {
// print_error(0, "FAILED: A2560K built-in keyboard initialization", res);
// } else {
// DEBUG("A2560K built-in keyboard initialized.");
// }
if (res = kbdmo_init()) {
print_error(0, "FAILED: A2560K built-in keyboard initialization", res);
} else {
DEBUG("A2560K built-in keyboard initialized.");
}
// if (res = cli_init()) {
// print_error(0, "FAILED: CLI initialization", res);
// } else {
// DEBUG("CLI initialized.");
// }
if (res = cli_init()) {
print_error(0, "FAILED: CLI initialization", res);
} else {
DEBUG("CLI initialized.");
}
print(0, "MASK_GRP1: ");
unsigned short grp1 = *MASK_GRP1;
print_hex_16(0, grp1);
print(0, "\n");
if (res = fsys_init()) {
print_error(0, "FAILED: file system initialization", res);
} else {
DEBUG("File system initialized.");
}
/* Enable all interrupts */
// int_enable_all();
@ -421,7 +422,16 @@ int main(int argc, char * argv[]) {
// try_mo_scancodes(0);
// try_bdev_getput(0, BDEV_SDC);
cli_repl(1);
// print(0, "Watching for MIDI signals:\n");
// while (1) {
// midi_byte = midi_get_poll();
// if (midi_byte && (midi_byte != 0xFE) && (midi_byte != 0xF8)) {
// print_hex(0, midi_byte);
// print(0, "\n");
// }
// }
cli_repl(0);
DEBUG("Stopping.");

File diff suppressed because it is too large Load diff

15
src/include/midi_reg.h Normal file
View file

@ -0,0 +1,15 @@
/*
* Definitions for the SuperIO MIDI ports
*/
#ifndef __MIDI_REG_H
#define __MIDI_REG_H
#define MIDI_DATA ((volatile unsigned char *)0x00C02330)
#define MIDI_STAT ((volatile unsigned char *)0x00C02331)
#define MIDI_CMD ((volatile unsigned char *)0x00C02331)
#define MIDI_STAT_TX_BUSY 0x80
#define MIDI_STAT_RX_EMPTY 0x40
#endif

View file

@ -7,10 +7,14 @@
*
*/
#ifndef __SYSCALLS_M68K_H
#define __SYSCALLS_M68K_H
#ifndef __SYSCALLS_H
#define __SYSCALLS_H
#include "types.h"
#include "interrupt.h"
#include "dev/channel.h"
#include "dev/block.h"
#include "dev/fsys.h"
/*
* Syscall function numbers
@ -20,8 +24,13 @@
#define KFN_EXIT 0x00 /* Quick the current program and return to the command line */
#define KFN_WARMBOOT 0x01 /* Do a soft re-initialization */
#define KFN_SETHANDLER 0x02 /* Set a handler for an exception / interrupt */
#define KFN_SETINTERRUPT 0x03 /* Enable / Disable an interrupt */
#define KFN_INT_REGISTER 0x02 /* Set a handler for an exception / interrupt */
#define KFN_INT_ENABLE 0x03 /* Enable an interrupt */
#define KFN_INT_DISABLE 0x04 /* Disable an interrupt */
#define KFN_INT_ENABLE_ALL 0x05 /* Enable all interrupts */
#define KFN_INT_DISABLE_ALL 0x06 /* Disable all interrupts */
#define KFN_INT_CLEAR 0x05 /* Clear (acknowledge) an interrupt */
#define KFN_INT_PENDING 0x06 /* Return true if the interrupt is pending */
/* Channel system calls */
@ -60,25 +69,91 @@
#define KFN_MKDIR 0x39 /* Create a directory */
#define KFN_LOAD 0x3A /* Load a file into memory */
#define KFN_SAVE 0x3B /* Save a block of memory to a file */
/* Process system calls */
#define KFN_RUN 0x40 /* Load an execute a binary file */
#define KFN_LOAD_REGISTER 0x41 /* Register a file type handler for executable binaries */
#define KFN_RUN 0x3C /* Load an execute a binary file */
#define KFN_LOAD_REGISTER 0x3D /* Register a file type handler for executable binaries */
/* Timer calls */
#define KFN_DELAY 0x50 /* Block for a certain amount of time */
#define KFN_SET_ALARM 0x51 /* Set an alarm for a certain amount of time */
#define KFN_GET_TIMECODE 0x52 /* Gets the current time code (increments since boot) */
#define KFN_SET_DATETIME 0x53 /* Set the real time clock date-time */
#define KFN_GET_DATETIME 0x54 /* Get the real time clock date-time */
#define KFN_DELAY 0x40 /* Block for a certain amount of time */
#define KFN_SET_ALARM 0x41 /* Set an alarm for a certain amount of time */
#define KFN_GET_TIMECODE 0x42 /* Gets the current time code (increments since boot) */
#define KFN_SET_DATETIME 0x43 /* Set the real time clock date-time */
#define KFN_GET_DATETIME 0x44 /* Get the real time clock date-time */
/*
* Call into the kernel (provided by assembly)
*/
extern int32_t syscall(int32_t function, ...);
/***
*** Core system calls
***/
/*
* Enable all interrupts
*
* NOTE: this is actually provided in the low level assembly
*/
extern void sys_int_enable_all();
/*
* Disable all interrupts
*
* NOTE: this is actually provided in the low level assembly
*/
extern void sys_int_disable_all();
/*
* Disable an interrupt by masking it
*
* Inputs:
* n = the number of the interrupt: n[7..4] = group number, n[3..0] = individual number.
*/
extern void sys_int_disable(unsigned short n);
/*
* Enable an interrupt
*
* Inputs:
* n = the number of the interrupt
*/
extern void sys_int_enable(unsigned short n);
/*
* Register a handler for a given interrupt.
*
* Inputs:
* n = the number of the interrupt
* handler = pointer to the interrupt handler to register
*
* Returns:
* the pointer to the previous interrupt handler
*/
extern p_int_handler sys_int_register(unsigned short n, p_int_handler handler);
/*
* Return true (non-zero) if an interrupt is pending for the given interrupt
*
* Inputs:
* n = the number of the interrupt: n[7..4] = group number, n[3..0] = individual number.
*
* Returns:
* non-zero if interrupt n is pending, 0 if not
*/
extern short sys_int_pending(unsigned short n);
/*
* Acknowledge an interrupt (clear out its pending flag)
*
* Inputs:
* n = the number of the interrupt: n[7..4] = group number, n[3..0] = individual number.
*/
extern void sys_int_clear(unsigned short n);
/***
*** Channel system calls
***/
/*
* Read a single byte from the channel
*
@ -116,7 +191,7 @@ extern short sys_chan_read(short channel, unsigned char * buffer, short size);
*/
extern short sys_chan_readline(short channel, unsigned char * buffer, short size);
/*
/*
* Write a single byte to the device
*
* Inputs:
@ -140,5 +215,126 @@ extern short sys_chan_write_b(short channel, unsigned char b);
*/
extern short sys_chan_write(short channel, unsigned char * buffer, short size);
/*
* Return the status of the channel device
*
* Inputs:
* channel = the number of the channel
*
* Returns:
* the status of the device
*/
extern short sys_chan_status(short channel);
/*
* Ensure that any pending writes to teh device have been completed
*
* Inputs:
* channel = the number of the channel
*
* Returns:
* 0 on success, any negative number is an error code
*/
extern short sys_chan_flush(short channel);
/*
* Attempt to set the position of the channel cursor (if supported)
*
* Inputs:
* channel = the number of the channel
* position = the position of the cursor
* base = whether the position is absolute or relative to the current position
*
* Returns:
* 0 = success, a negative number is an error.
*/
extern short sys_chan_seek(short channel, long position, short base);
/*
* Issue a control command to the device
*
* Inputs:
* channel = the number of the channel
* command = the number of the command to send
* buffer = pointer to bytes of additional data for the command
* size = the size of the buffer
*
* Returns:
* 0 on success, any negative number is an error code
*/
extern short sys_chan_ioctrl(short channel, short command, uint8_t * buffer, short size);
/***
*** Block device system calls
***/
//
// Register a block device driver
//
extern short sys_bdev_register(p_dev_block device);
//
// Read a block from the device
//
// Inputs:
// dev = the number of the device
// lba = the logical block address of the block to read
// buffer = the buffer into which to copy the block data
// size = the size of the buffer.
//
// Returns:
// number of bytes read, any negative number is an error code
//
extern short sys_bdev_read(short dev, long lba, unsigned char * buffer, short size);
//
// Write a block from the device
//
// Inputs:
// dev = the number of the device
// lba = the logical block address of the block to write
// buffer = the buffer containing the data to write
// size = the size of the buffer.
//
// Returns:
// number of bytes written, any negative number is an error code
//
extern short sys_bdev_write(short dev, long lba, const unsigned char * buffer, short size);
//
// Return the status of the block device
//
// Inputs:
// dev = the number of the device
//
// Returns:
// the status of the device
//
extern short sys_bdev_status(short dev);
//
// Ensure that any pending writes to teh device have been completed
//
// Inputs:
// dev = the number of the device
//
// Returns:
// 0 on success, any negative number is an error code
//
extern short sys_bdev_flush(short dev);
//
// Issue a control command to the device
//
// Inputs:
// dev = the number of the device
// command = the number of the command to send
// buffer = pointer to bytes of additional data for the command
// size = the size of the buffer
//
// Returns:
// 0 on success, any negative number is an error code
//
extern short sys_bdev_ioctrl(short dev, short command, unsigned char * buffer, short size);
#endif

View file

@ -6,16 +6,10 @@ for the Motorola 68000 series processors.
## System Call Convention
System calls will be made through the ``TRAP`` instruction.
The caller will be expected to push parameters onto the stack using the
VBCC ABI, and then issuing a ``TRAP`` instruction.
* Stack pointer is A7
* All arguments are passed on the stack
* Registers D0, D1, A0, and A1 will be used as scratch.
* Registers D2 - D7, and A2 - A6 will be preserved by the kernel.
* Registers D1 - D7, and A0 - A6 will be preserved by the kernel.
* First parameter is in D1, second in D2, and so on.
* The caller places the function number in D0.
* All BIOS calls are issued through a ``TRAP #15`` instruction.
* Results are returned in D0.
## BIOS
All BIOS calls are issued through a ``TRAP #13`` instruction. Register D0 contains the number of the system call to make.

View file

@ -4,15 +4,61 @@
* NOTE: these routines are not called directly but are instead called through TRAP#13
*/
#include "log.h"
#include "types.h"
#include "syscalls.h"
#include "log.h"
#include "interrupt.h"
#include "dev/channel.h"
#include "dev/block.h"
#include "dev/fsys.h"
/*
* Determine the correct system function implementation and call it.
*/
int32_t syscall_dispatch(int32_t function, int32_t param0, int32_t param1, int32_t param2, int32_t param3, int32_t param4, int32_t param5) {
switch (function & 0x00f0) {
case 0x00:
/* Core System Calls */
switch (function) {
case KFN_EXIT:
break;
case KFN_WARMBOOT:
break;
case KFN_INT_REGISTER:
return (int32_t)int_register((unsigned short)param0, (p_int_handler)param1);
case KFN_INT_ENABLE:
int_enable((unsigned short)param0);
return;
case KFN_INT_DISABLE:
int_disable((unsigned short)param0);
return;
case KFN_INT_ENABLE_ALL:
int_enable_all();
return;
case KFN_INT_DISABLE_ALL:
int_disable_all();
return;
case KFN_INT_CLEAR:
int_clear((unsigned short)param0);
return;
case KFN_INT_PENDING:
return int_pending((unsigned short)param0);
default:
break;
}
break;
case 0x10:
/* Channel system calls */
switch (function) {
case KFN_CHAN_WRITE_B:
return chan_write_b((short)param0, (uint8_t)param1);
@ -29,9 +75,93 @@ int32_t syscall_dispatch(int32_t function, int32_t param0, int32_t param1, int32
case KFN_CHAN_READ_LINE:
return chan_readline((short)param0, (const uint8_t *)param1, (short)param2);
case KFN_CHAN_STATUS:
return chan_status((short)param0);
case KFN_CHAN_FLUSH:
return chan_flush((short)param0);
case KFN_CHAN_SEEK:
return chan_seek((short)param0, (long)param1, (short)param2);
case KFN_CHAN_IOCTRL:
return chan_ioctrl((short)param0, (short)param1, (unsigned char *)param2, (short)param3);
case KFN_CHAN_REGISTER:
return cdev_register((p_dev_chan)param0);
default:
break;
}
break;
case 0x20:
/* Block device system calls */
switch (function) {
case KFN_BDEV_GETBLOCK:
return bdev_read((short)param0, (long)param1, (unsigned char *)param2, (short)param3);
case KFN_BDEV_PUTBLOCK:
return bdev_write((short)param0, (long)param1, (unsigned char *)param2, (short)param3);
case KFN_BDEV_FLUSH:
return bdev_flush((short)param0);
case KFN_BDEV_STATUS:
return bdev_status((short)param0);
case KFN_BDEV_IOCTRL:
return bdev_ioctrl((short)param0, (short)param1, (unsigned char *)param2, (short)param3);
case KFN_BDEV_REGISTER:
return bdev_register((p_dev_block)param0);
default:
break;
}
break;
case 0x30:
/* File System Calls */
switch (function) {
case KFN_OPEN:
return fsys_open((const char *)param0, (short)param1);
case KFN_CLOSE:
return fsys_close((short)param0);
case KFN_OPENDIR:
return fsys_opendir((const char *)param0);
case KFN_CLOSEDIR:
return fsys_closedir((short)param0);
case KFN_READDIR:
return fsys_readdir((short)param0, (p_file_info)param1);
case KFN_FINDFIRST:
return fsys_findfirst((const char *)param0, (const char *)param1, (p_file_info)param2);
case KFN_FINDNEXT:
return fsys_findnext((short)param0, (p_file_info)param1);
case KFN_DELETE:
return fsys_delete((const char *)param0);
case KFN_RENAME:
return fsys_rename((const char *)param0, (const char *)param1);
default:
break;
}
break;
default:
break;
}
DEBUG("syscall unknown function\n");
do {} while (1);
return -1;
}
}

View file

@ -51,9 +51,9 @@
dc.l not_impl ; 42 - TRAP #10
dc.l not_impl ; 43 - TRAP #11
dc.l not_impl ; 44 - TRAP #12
dc.l h_trap_13 ; 45 - TRAP #13
dc.l not_impl ; 45 - TRAP #13
dc.l not_impl ; 46 - TRAP #14
dc.l not_impl ; 47 - TRAP #15
dc.l h_trap_15 ; 47 - TRAP #15
dc.l not_impl ; 48 - Reserved
dc.l not_impl ; 49 - Reserved
dc.l not_impl ; 50 - Reserved
@ -120,7 +120,7 @@ clrloop: clr.l (a0)+
bne clrloop
; Set TRAP #13 vector handler
lea h_trap_13,a0 ; Address of the handler
lea h_trap_15,a0 ; Address of the handler
move.l #(13+32)<<2,a1 ; TRAP#13 vector address
move.l a0,(a1) ; Set the vector
@ -214,31 +214,31 @@ _int_disable_all: ori.w #$0700,SR
;
_syscall:
movem.l d1-d7,-(sp) ; Save caller's registers
move.l (56,sp),d7 ; Parameter 5 to D7
move.l (52,sp),d6 ; Parameter 4 to D6
move.l (48,sp),d5 ; Parameter 3 to D5
move.l (44,sp),d4 ; Parameter 2 to D4
move.l (40,sp),d3 ; Parameter 1 to D3
move.l (36,sp),d2 ; Parameter 0 to D2
move.l (32,sp),d1 ; Function number to D1
move.l (56,sp),d6 ; Parameter 5 to D6
move.l (52,sp),d5 ; Parameter 4 to D5
move.l (48,sp),d4 ; Parameter 3 to D4
move.l (44,sp),d3 ; Parameter 2 to D3
move.l (40,sp),d2 ; Parameter 1 to D2
move.l (36,sp),d1 ; Parameter 0 to D1
move.l (32,sp),d0 ; Function number to D0
TRAP #13 ; Call into the kernel
TRAP #15 ; Call into the kernel
movem.l (sp)+,d1-d7 ; Restore caller's registers
rts
;
; TRAP#13 handler... transfer control to the C dispatcher
; TRAP#15 handler... transfer control to the C dispatcher
;
h_trap_13:
move.l d7,-(sp) ; Push the parameters to the stack for the C call
move.l d6,-(sp)
h_trap_15:
move.l d6,-(sp) ; Push the parameters to the stack for the C call
move.l d5,-(sp)
move.l d4,-(sp)
move.l d3,-(sp)
move.l d2,-(sp)
move.l d1,-(sp)
move.l d0,-(sp)
jsr _syscall_dispatch ; Call the C routine to do the dispatch
; Note: the C routine depends upon the register push order

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,90 @@
#include "syscalls.h"
#include "interrupt.h"
#include "dev/channel.h"
#include "dev/block.h"
/***
*** Core system calls
***/
/*
* Enable all interrupts
*
* NOTE: this is actually provided in the low level assembly
*/
void sys_int_enable_all() {
syscall(KFN_INT_ENABLE_ALL);
}
/*
* Disable all interrupts
*
* NOTE: this is actually provided in the low level assembly
*/
void sys_int_disable_all() {
syscall(KFN_INT_DISABLE_ALL);
}
/*
* Disable an interrupt by masking it
*
* Inputs:
* n = the number of the interrupt: n[7..4] = group number, n[3..0] = individual number.
*/
void sys_int_disable(unsigned short n) {
syscall(KFN_INT_DISABLE, n);
}
/*
* Enable an interrupt
*
* Inputs:
* n = the number of the interrupt
*/
void sys_int_enable(unsigned short n) {
syscall(KFN_INT_ENABLE, n);
}
/*
* Register a handler for a given interrupt.
*
* Inputs:
* n = the number of the interrupt
* handler = pointer to the interrupt handler to register
*
* Returns:
* the pointer to the previous interrupt handler
*/
p_int_handler sys_int_register(unsigned short n, p_int_handler handler) {
return (p_int_handler)syscall(KFN_INT_REGISTER, n, handler);
}
/*
* Return true (non-zero) if an interrupt is pending for the given interrupt
*
* Inputs:
* n = the number of the interrupt: n[7..4] = group number, n[3..0] = individual number.
*
* Returns:
* non-zero if interrupt n is pending, 0 if not
*/
short sys_int_pending(unsigned short n) {
return syscall(KFN_INT_PENDING, n);
}
/*
* Acknowledge an interrupt (clear out its pending flag)
*
* Inputs:
* n = the number of the interrupt: n[7..4] = group number, n[3..0] = individual number.
*/
void sys_int_clear(unsigned short n) {
syscall(KFN_INT_CLEAR, n);
}
/***
*** Channel system calls
***/
/*
* Read a single byte from the channel
@ -44,7 +130,7 @@ short sys_chan_readline(short channel, unsigned char * buffer, short size) {
}
/*
/*
* Write a single byte to the device
*
* Inputs:
@ -71,3 +157,145 @@ short sys_chan_write_b(short channel, unsigned char b) {
short sys_chan_write(short channel, unsigned char * buffer, short size) {
return syscall(KFN_CHAN_WRITE, channel, buffer, size);
}
/*
* Return the status of the channel device
*
* Inputs:
* channel = the number of the channel
*
* Returns:
* the status of the device
*/
short sys_chan_status(short channel) {
return syscall(KFN_CHAN_STATUS, channel);
}
/*
* Ensure that any pending writes to teh device have been completed
*
* Inputs:
* channel = the number of the channel
*
* Returns:
* 0 on success, any negative number is an error code
*/
short sys_chan_flush(short channel) {
return syscall(KFN_CHAN_FLUSH, channel);
}
/*
* Attempt to set the position of the channel cursor (if supported)
*
* Inputs:
* channel = the number of the channel
* position = the position of the cursor
* base = whether the position is absolute or relative to the current position
*
* Returns:
* 0 = success, a negative number is an error.
*/
short sys_chan_seek(short channel, long position, short base) {
return syscall(KFN_CHAN_SEEK, channel, position, base);
}
/*
* Issue a control command to the device
*
* Inputs:
* channel = the number of the channel
* command = the number of the command to send
* buffer = pointer to bytes of additional data for the command
* size = the size of the buffer
*
* Returns:
* 0 on success, any negative number is an error code
*/
short sys_chan_ioctrl(short channel, short command, uint8_t * buffer, short size) {
return syscall(KFN_CHAN_IOCTRL, channel, command, buffer, size);
}
/***
*** Block device system calls
***/
//
// Register a block device driver
//
short sys_bdev_register(p_dev_block device) {
return syscall(KFN_BDEV_REGISTER, device);
}
//
// Read a block from the device
//
// Inputs:
// dev = the number of the device
// lba = the logical block address of the block to read
// buffer = the buffer into which to copy the block data
// size = the size of the buffer.
//
// Returns:
// number of bytes read, any negative number is an error code
//
short sys_bdev_read(short dev, long lba, unsigned char * buffer, short size) {
return syscall(KFN_BDEV_GETBLOCK, dev, lba, buffer, size);
}
//
// Write a block from the device
//
// Inputs:
// dev = the number of the device
// lba = the logical block address of the block to write
// buffer = the buffer containing the data to write
// size = the size of the buffer.
//
// Returns:
// number of bytes written, any negative number is an error code
//
short sys_bdev_write(short dev, long lba, const unsigned char * buffer, short size) {
return syscall(KFN_BDEV_PUTBLOCK, dev, lba, buffer, size);
}
//
// Return the status of the block device
//
// Inputs:
// dev = the number of the device
//
// Returns:
// the status of the device
//
short sys_bdev_status(short dev) {
return syscall(KFN_BDEV_STATUS, dev);
}
//
// Ensure that any pending writes to teh device have been completed
//
// Inputs:
// dev = the number of the device
//
// Returns:
// 0 on success, any negative number is an error code
//
short sys_bdev_flush(short dev) {
return syscall(KFN_BDEV_FLUSH, dev);
}
//
// Issue a control command to the device
//
// Inputs:
// dev = the number of the device
// command = the number of the command to send
// buffer = pointer to bytes of additional data for the command
// size = the size of the buffer
//
// Returns:
// 0 on success, any negative number is an error code
//
short sys_bdev_ioctrl(short dev, short command, unsigned char * buffer, short size) {
return syscall(KFN_BDEV_IOCTRL, dev, command, buffer, size);
}