mirror of
git://projects.qi-hardware.com/iris.git
synced 2024-11-04 23:08:26 +02:00
288 lines
11 KiB
Plaintext
288 lines
11 KiB
Plaintext
#pypp 0
|
|
// Iris: micro-kernel for a capability-based operating system.
|
|
// boot-programs/devices.hhp: interfaces for core devices.
|
|
// Copyright 2009 Bas Wijnen <wijnen@debian.org>
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
#ifndef __IRIS_DEVICES_HH
|
|
#define __IRIS_DEVICES_HH
|
|
|
|
#include "iris.hh"
|
|
|
|
// List interface.
|
|
template <typename _T> //
|
|
struct List : public Kernel::Caps:
|
|
List (Kernel::Caps c = Kernel::Cap ()) : Kernel::Caps (c):
|
|
List <_T> create (unsigned size, Kernel::Memory mem = Kernel::my_memory):
|
|
return List <_T> (mem.create_caps (size))
|
|
void set (unsigned idx, _T value):
|
|
return Kernel::Caps::set (idx, value)
|
|
_T get (unsigned idx):
|
|
return _T (Kernel::Caps::get (idx))
|
|
|
|
/// A block of data with a size and content. Any character can be stored in it (including '\0').
|
|
struct String : public Kernel::Cap:
|
|
String (Kernel::Cap c = Kernel::Cap ()) : Kernel::Cap (c):
|
|
enum request:
|
|
GET_SIZE = 0x2001
|
|
GET_CHARS
|
|
GET_PAGE
|
|
ID
|
|
/// Get the size of the string.
|
|
Kernel::Num get_size ():
|
|
return call (CAP_MASTER_DIRECT | GET_SIZE)
|
|
/// Get exactly 16 characters. The index must be word-aligned.
|
|
char *get_chars (Kernel::Num idx, char buffer[16]):
|
|
call (CAP_MASTER_DIRECT | GET_CHARS, idx)
|
|
unsigned *b = (unsigned *)buffer
|
|
b[0] = Kernel::recv.data[0].l
|
|
b[1] = Kernel::recv.data[0].h
|
|
b[2] = Kernel::recv.data[1].l
|
|
b[3] = Kernel::recv.data[1].h
|
|
return buffer
|
|
/// Get a page from the string. This need not be implemented for strings smaller than PAGE_SIZE. The index must be page-aligned.
|
|
Cap get_page (Kernel::Num idx, Kernel::Page ret = Kernel::my_memory.create_page ()):
|
|
ocall (ret, CAP_MASTER_DIRECT | GET_PAGE, idx)
|
|
return ret
|
|
|
|
/// A writable String.
|
|
struct WString : public String:
|
|
WString (Kernel::Cap c = Kernel::Cap ()) : String (c):
|
|
enum request:
|
|
TRUNCATE = String::ID
|
|
SET_CHARS
|
|
SET_PAGE
|
|
ID
|
|
/// Set the size of the string. Strings may have a limit to this setting.
|
|
void truncate (Kernel::Num size):
|
|
call (CAP_MASTER_DIRECT | TRUNCATE, size)
|
|
/// Set exactly 4 characters. The index must be word-aligned.
|
|
void set_chars (Kernel::Num idx, char buffer[4]):
|
|
call (Kernel::Num (CAP_MASTER_DIRECT | SET_CHARS, *(unsigned *)buffer), idx)
|
|
/// Overwrite a page from the string. This need not be implemented for strings smaller than PAGE_SIZE. The index must be page-aligned. The caller may lose the frame in the transaction.
|
|
void set_page (Kernel::Num idx, Kernel::Page page):
|
|
ocall (page, CAP_MASTER_DIRECT | SET_PAGE, idx)
|
|
|
|
// Interface for talking to the parent process.
|
|
struct Parent : public Kernel::Cap:
|
|
Parent (Kernel::Cap c = Kernel::Cap ()) : Kernel::Cap (c):
|
|
enum request:
|
|
GET_DEVICE = WString::ID
|
|
EXIT
|
|
ID
|
|
// Get a device handle.
|
|
template <typename _T> _T get_device (unsigned num = 0):
|
|
icall (CAP_MASTER_DIRECT | GET_DEVICE, Kernel::Num (_T::ID, num))
|
|
return Kernel::get_arg ()
|
|
// Exit the program. The parent does not reply, but kills the process.
|
|
void exit (Kernel::Num code):
|
|
call (CAP_MASTER_DIRECT | EXIT, code)
|
|
|
|
// Every process which wants to be switchable through a terminal must implement this interface.
|
|
struct Device : public Kernel::Cap:
|
|
Device (Kernel::Cap c = Kernel::Cap ()) : Kernel::Cap (c):
|
|
enum request:
|
|
CREATE_USER = Parent::ID
|
|
DESTROY_USER
|
|
UNUSE
|
|
USE
|
|
ID
|
|
// Create a new user for this device. It will not be the active user.
|
|
// The provided storage must allow object creation; no other actions may be used by the terminal.
|
|
Kernel::Cap create_user (Kernel::Memory storage):
|
|
iocall (storage, CAP_MASTER_DIRECT | CREATE_USER)
|
|
return Kernel::get_arg ()
|
|
// Destroy a user. It must not be active.
|
|
void destroy_user (Kernel::Cap user):
|
|
ocall (user, CAP_MASTER_DIRECT | DESTROY_USER)
|
|
// Make user inactive.
|
|
void unuse (Kernel::Cap user):
|
|
ocall (user, CAP_MASTER_DIRECT | UNUSE)
|
|
// Make user active.
|
|
void use (Kernel::Cap user):
|
|
ocall (user, CAP_MASTER_DIRECT | USE)
|
|
|
|
// Keyboard interface.
|
|
struct Keyboard : public Kernel::Cap:
|
|
Keyboard (Kernel::Cap c = Kernel::Cap ()) : Kernel::Cap (c):
|
|
enum request:
|
|
SET_CB = Device::ID
|
|
GET_NUM_KEYS
|
|
GET_KEYS
|
|
ID
|
|
// At event: the callback is called with a keycode. One bit defines if it's a press or release event.
|
|
enum constant:
|
|
RELEASE = 1 << 31
|
|
// Set the event callback. Currently pressed keys emit a key press event to the new callback immediately.
|
|
void set_cb (Kernel::Cap cb):
|
|
ocall (cb, CAP_MASTER_DIRECT | SET_CB)
|
|
unsigned get_num_keys ():
|
|
return call (CAP_MASTER_DIRECT | GET_NUM_KEYS).l
|
|
void get_keys (unsigned first):
|
|
call (CAP_MASTER_DIRECT | GET_KEYS, first)
|
|
|
|
// Buzzer interface.
|
|
struct Buzzer : public Kernel::Cap:
|
|
Buzzer (Kernel::Cap c = Kernel::Cap ()) : Kernel::Cap (c):
|
|
enum request:
|
|
BEEP = Keyboard::ID
|
|
STOP
|
|
ID
|
|
// Emit a beep of specified frequency, time and volume. Volume may not be supported.
|
|
void beep (unsigned freq, unsigned ms, unsigned volume, Kernel::Cap cb = Kernel::Cap ()):
|
|
ocall (cb, Kernel::Num (CAP_MASTER_DIRECT | BEEP, volume), Kernel::Num (freq, ms))
|
|
// Abort current beep, if any.
|
|
void stop ():
|
|
call (CAP_MASTER_DIRECT | STOP)
|
|
|
|
// Display interface.
|
|
struct Display : public Kernel::Cap:
|
|
Display (Kernel::Cap c = Kernel::Cap ()) : Kernel::Cap (c):
|
|
enum request:
|
|
EOF_CB = Buzzer::ID
|
|
CREATE_FB
|
|
USE_FB
|
|
GET_INFO
|
|
ID
|
|
// Register an end-of-frame callback.
|
|
// At end of frame, the callback is invoked and forgotten. It must be reregistered to keep a stream of events.
|
|
void set_eof_cb (Kernel::Cap cb):
|
|
ocall (cb, CAP_MASTER_DIRECT | EOF_CB)
|
|
// Create a framebuffer for the display. When not in use, it can be freed by the user.
|
|
// The pages must be cappages holding Page capabilities. They are filled by the display.
|
|
// The passed numbers must be 0 or match a mode that the device can use.
|
|
// The returned number is the physical address of the framebuffer. It can be used with display_use_framebuffer.
|
|
unsigned create_framebuffer (unsigned w = 0, unsigned h = 0, unsigned mode = 0):
|
|
return icall (Kernel::Num (CAP_MASTER_DIRECT | CREATE_FB, 0), Kernel::Num ((w << 16) | h, mode)).l
|
|
// Use a framebuffer. The address must have been returned from display_create_framebuffer.
|
|
// w, h and mode must match the values given at creation time.
|
|
// unuse_cb is called the next time this operation is requested for this display.
|
|
void use_framebuffer (unsigned addr, Kernel::Cap unuse_cb = Kernel::Cap (), unsigned w = 0, unsigned h = 0, unsigned mode = 0):
|
|
ocall (unuse_cb, Kernel::Num (CAP_MASTER_DIRECT | USE_FB, addr), Kernel::Num ((w << 16) | h, mode))
|
|
// Get information about the display.
|
|
void get_info ():
|
|
// TODO: Interface is to be designed.
|
|
|
|
|
|
|
|
// File system interface.
|
|
// filesystem-related interfaces: file, directory, stream, seekable, mappable.
|
|
// Normal files implement at least stream or seekable file. Directories implement directory.
|
|
struct File : public Kernel::Cap:
|
|
File (Kernel::Cap c = Kernel::Cap ()) : Kernel::Cap (c):
|
|
enum request:
|
|
INFO = Display::ID
|
|
CLOSE
|
|
MAP_HANDLE
|
|
ID
|
|
// Get information about the file.
|
|
Kernel::Num get_info (unsigned type):
|
|
return icall (Kernel::Num (CAP_MASTER_DIRECT | INFO, type))
|
|
// Close a file. If this is a directory, it implicitly closes all files opened from it.
|
|
void close ():
|
|
call (CAP_MASTER_DIRECT | CLOSE)
|
|
// Map a file handle. This can be useful for closing all children at once. The new handle itself is a child of the original handle.
|
|
File map_handle ():
|
|
icall (CAP_MASTER_DIRECT | MAP_HANDLE)
|
|
return Kernel::get_arg ()
|
|
|
|
// Directory interface.
|
|
struct Directory : public File:
|
|
Directory (Kernel::Cap c = Kernel::Cap ()) : File (c):
|
|
enum request:
|
|
GET_SIZE = File::ID
|
|
GET_NAME
|
|
GET_FILE
|
|
GET_FILE_INFO
|
|
CREATE_FILE
|
|
DELETE_FILE
|
|
ID
|
|
// Get the number of entries in this directory.
|
|
Kernel::Num get_size ():
|
|
return call (CAP_MASTER_DIRECT | GET_SIZE)
|
|
// Get the filename. The return value is the size of the string, the page is filled with the string itself.
|
|
String get_name (Kernel::Num idx):
|
|
icall (CAP_MASTER_DIRECT | GET_NAME, idx)
|
|
return Kernel::get_arg ()
|
|
// Get the file.
|
|
File get_file (Kernel::Num idx):
|
|
icall (CAP_MASTER_DIRECT | GET_FILE, idx)
|
|
return Kernel::get_arg ()
|
|
// Get file info. This returns the same information as file_get_info, without opening the file.
|
|
Kernel::Num get_file_info (Kernel::Num idx, unsigned type):
|
|
return icall (Kernel::Num (CAP_MASTER_DIRECT | GET_FILE_INFO, type), idx)
|
|
// Create a new file. After this, any index may map to a different file.
|
|
File create_file (String name):
|
|
icall (CAP_MASTER_DIRECT | CREATE_FILE)
|
|
return Kernel::get_arg ()
|
|
// Delete a file. After this, any index may map to a different file.
|
|
void delete_file (Kernel::Num idx):
|
|
call (CAP_MASTER_DIRECT | DELETE_FILE, idx)
|
|
|
|
// Stream interface.
|
|
struct Stream : public File:
|
|
Stream (Kernel::Cap c = Kernel::Cap ()) : File (c):
|
|
enum request:
|
|
READ = Directory::ID
|
|
WRITE
|
|
ID
|
|
// Try to read size bytes. Returns the number of bytes successfully read.
|
|
Kernel::Num read (Kernel::Num size):
|
|
return icall (CAP_MASTER_DIRECT | READ, size)
|
|
// Try to write size bytes. Returns the number of bytes successfully written.
|
|
Kernel::Num write (String s, Kernel::Num size):
|
|
return ocall (s, CAP_MASTER_DIRECT | WRITE, size)
|
|
|
|
// Seekable file interface.
|
|
struct Seekable : public File:
|
|
Seekable (Kernel::Cap c = Kernel::Cap ()) : File (c):
|
|
enum request:
|
|
READ = Stream::ID
|
|
WRITE
|
|
TRUNCATE
|
|
ID
|
|
// Try to read size bytes from position idx. Returns the number of bytes successfully read.
|
|
Kernel::Num read (Kernel::Num idx, unsigned size):
|
|
return icall (Kernel::Num (CAP_MASTER_DIRECT | READ, size), idx)
|
|
// Try to write size bytes at position idx; the file is extended with zeroes if the write is past the end. Returns the number of bytes successfully written.
|
|
Kernel::Num write (Kernel::Num idx, String s):
|
|
return ocall (s, CAP_MASTER_DIRECT | WRITE, idx)
|
|
// Truncate file to size idx. The file is extended with zeroes if it gets longer.
|
|
void truncate (Kernel::Num idx):
|
|
call (CAP_MASTER_DIRECT | TRUNCATE, idx)
|
|
|
|
// Mappable file interface.
|
|
struct Mappable : public Seekable:
|
|
Mappable (Kernel::Cap c = Kernel::Cap ()) : Seekable (c):
|
|
// TODO: to be designed.
|
|
|
|
|
|
|
|
// Block device interface.
|
|
struct Block_device : public Mappable:
|
|
Block_device (Kernel::Cap c = Kernel::Cap ()) : Mappable (c):
|
|
// TODO: to be designed.
|
|
|
|
|
|
// TODO.
|
|
// Sound interface.
|
|
// Usb interfaces (port, device).
|
|
// Pointer interface. (Only movement; buttons follow keyboard interface.)
|
|
// Network interface.
|
|
// Camera interface.
|
|
// Terminal interfaces.
|
|
|
|
#endif
|