diff --git a/headers/private/drivers/poke.h b/headers/private/drivers/poke.h new file mode 100644 index 0000000000..b69a08de78 --- /dev/null +++ b/headers/private/drivers/poke.h @@ -0,0 +1,70 @@ +/* + * Copyright 2005, Oscar Lesta. All rights reserved. + * Distributed under the terms of the MIT License. + */ +#ifndef _POKE_DRIVER_H_ +#define _POKE_DRIVER_H_ + +#include +#include +#include + + +#define POKE_DEVICE_NAME "poke" +#define POKE_DEVICE_FULLNAME "/dev/misc/poke" +#define POKE_SIGNATURE 'wltp' // "We Like To Poke" + + +enum { + POKE_PORT_READ = B_DEVICE_OP_CODES_END + 1, + POKE_PORT_WRITE, + POKE_PORT_INDEXED_READ, + POKE_PORT_INDEXED_WRITE, + POKE_PCI_READ_CONFIG, + POKE_PCI_WRITE_CONFIG, + POKE_GET_NTH_PCI_INFO, + POKE_GET_PHYSICAL_ADDRESS, + POKE_MAP_MEMORY, + POKE_UNMAP_MEMORY +}; + + +typedef struct { + uint32 signature; + uint8 index; + pci_info* info; + status_t status; +} pci_info_args; + + +typedef struct { + uint32 signature; + uint16 port; + uint8 size; // == index for POKE_PORT_INDEXED_* + uint16 value; +} port_io_args; + + +typedef struct { + uint32 signature; + uint8 bus; + uint8 device; + uint8 function; + uint8 size; + uint8 offset; + uint32 value; +} pci_io_args; + + +typedef struct { + uint32 signature; + area_id area; + const char* name; + void* physical_address; + size_t size; + uint32 flags; + uint32 protection; + void* address; +} mem_map_args; + +#endif // _POKE_DRIVER_H_ diff --git a/src/add-ons/kernel/drivers/misc/Jamfile b/src/add-ons/kernel/drivers/misc/Jamfile index 14bf0b7eee..434ae3d3ee 100644 --- a/src/add-ons/kernel/drivers/misc/Jamfile +++ b/src/add-ons/kernel/drivers/misc/Jamfile @@ -1,7 +1,12 @@ SubDir OBOS_TOP src add-ons kernel drivers misc ; +UsePrivateHeaders drivers ; + + KernelAddon config : kernel drivers dev misc : config.c ; -KernelObjects config.c : -fno-pic ; +KernelAddon poke : kernel drivers dev misc : + poke.c + ; diff --git a/src/add-ons/kernel/drivers/misc/poke.c b/src/add-ons/kernel/drivers/misc/poke.c new file mode 100644 index 0000000000..4ac322a5fe --- /dev/null +++ b/src/add-ons/kernel/drivers/misc/poke.c @@ -0,0 +1,293 @@ +/* + * Copyright 2005, Oscar Lesta. All rights reserved. + * Distributed under the terms of the MIT License. + */ + + +#include +#include +#include +#include + +#include "poke.h" + + +//////////////////////////////////////////////////////////////////////////////// + +static status_t poke_open(const char*, uint32, void**); +static status_t poke_close(void*); +static status_t poke_free(void*); +static status_t poke_control(void*, uint32, void*, size_t); +static status_t poke_read(void*, off_t, void*, size_t*); +static status_t poke_write(void*, off_t, const void*, size_t*); + +//////////////////////////////////////////////////////////////////////////////// + +static const char* poke_name[] = { + "misc/"POKE_DEVICE_NAME, + NULL +}; + + +device_hooks poke_hooks = { + poke_open, + poke_close, + poke_free, + poke_control, + poke_read, + poke_write, +}; + +int32 api_version = B_CUR_DRIVER_API_VERSION; + +isa_module_info* isa; +pci_module_info* pci; + +static uint32 open_count; + +//////////////////////////////////////////////////////////////////////////////// + + +status_t +init_hardware(void) +{ + return B_OK; +} + + +status_t +init_driver(void) +{ + open_count = 0; + + if (get_module(B_ISA_MODULE_NAME, (module_info**) &isa) < B_OK) + return ENOSYS; + if (get_module(B_PCI_MODULE_NAME, (module_info**) &pci) < B_OK) + return ENOSYS; + + return B_OK; +} + + +void +uninit_driver(void) +{ + if (isa) put_module(B_ISA_MODULE_NAME); + if (pci) put_module(B_PCI_MODULE_NAME); +} + + +const char** +publish_devices(void) +{ + return poke_name; +} + + +device_hooks* +find_device(const char* name) +{ + return &poke_hooks; +} + + +//////////////////////////////////////////////////////////////////////////////// +// #pragma mark - + + +status_t +poke_open(const char* name, uint32 flags, void** cookie) +{ + *cookie = NULL; + + if (atomic_add(&open_count, 1) != 0) { + atomic_add(&open_count, -1); + return B_BUSY; + } + + return B_OK; +} + + +status_t +poke_close(void* cookie) +{ + return B_OK; +} + + +status_t +poke_free(void* cookie) +{ + atomic_add(&open_count, -1); + return B_OK; +} + + +status_t +poke_control(void* cookie, uint32 op, void* arg, size_t length) +{ + switch (op) { + case POKE_PORT_READ: + { + status_t result; + port_io_args* ioctl = (port_io_args*) arg; + if (ioctl->signature != POKE_SIGNATURE) + return B_BAD_VALUE; + + result = B_OK; + switch (ioctl->size) { + case 1: + ioctl->value = isa->read_io_8(ioctl->port); + break; + case 2: + ioctl->value = isa->read_io_16(ioctl->port); + break; + case 4: + ioctl->value = isa->read_io_32(ioctl->port); + break; + default: + result = B_BAD_VALUE; + } + + return result; + } + + case POKE_PORT_WRITE: + { + status_t result; + port_io_args* ioctl = (port_io_args*) arg; + if (ioctl->signature != POKE_SIGNATURE) + return B_BAD_VALUE; + + result = B_OK; + switch (ioctl->size) { + case 1: + isa->write_io_8(ioctl->port, ioctl->value); + break; + case 2: + isa->write_io_16(ioctl->port, ioctl->value); + break; + case 4: + isa->write_io_16(ioctl->port, ioctl->value); + break; + default: + result = B_BAD_VALUE; + } + + return result; + } + + case POKE_PORT_INDEXED_READ: + { + port_io_args* ioctl = (port_io_args*) arg; + if (ioctl->signature != POKE_SIGNATURE) + return B_BAD_VALUE; + + isa->write_io_8(ioctl->port, ioctl->size); + ioctl->value = isa->read_io_8(ioctl->port + 1); + return B_OK; + } + + case POKE_PORT_INDEXED_WRITE: + { + port_io_args* ioctl = (port_io_args*) arg; + if (ioctl->signature != POKE_SIGNATURE) + return B_BAD_VALUE; + + isa->write_io_8(ioctl->port, ioctl->size); + isa->write_io_8(ioctl->port + 1, ioctl->value); + return B_OK; + } + + case POKE_PCI_READ_CONFIG: + { + pci_io_args* ioctl = (pci_io_args*) arg; + if (ioctl->signature != POKE_SIGNATURE) + return B_BAD_VALUE; + + ioctl->value = pci->read_pci_config(ioctl->bus, ioctl->device, + ioctl->function, ioctl->offset, + ioctl->size); + return B_OK; + } + + case POKE_PCI_WRITE_CONFIG: + { + pci_io_args* ioctl = (pci_io_args*) arg; + if (ioctl->signature != POKE_SIGNATURE) + return B_BAD_VALUE; + + pci->write_pci_config(ioctl->bus, ioctl->device, ioctl->function, + ioctl->offset, ioctl->size, ioctl->value); + return B_OK; + } + + case POKE_GET_NTH_PCI_INFO: + { + pci_info_args* ioctl = (pci_info_args*) arg; + if (ioctl->signature != POKE_SIGNATURE) + return B_BAD_VALUE; + + ioctl->status = pci->get_nth_pci_info(ioctl->index, ioctl->info); + return B_OK; + } + + case POKE_GET_PHYSICAL_ADDRESS: + { + mem_map_args* ioctl = (mem_map_args*) arg; + physical_entry table; + status_t result; + + if (ioctl->signature != POKE_SIGNATURE) + return B_BAD_VALUE; + + result = get_memory_map(ioctl->address, ioctl->size, &table, 1); + ioctl->physical_address = table.address; + ioctl->size = table.size; + return result; + } + + case POKE_MAP_MEMORY: + { + mem_map_args* ioctl = (mem_map_args*) arg; + if (ioctl->signature != POKE_SIGNATURE) + return B_BAD_VALUE; + + ioctl->area = map_physical_memory(ioctl->name, + ioctl->physical_address, + ioctl->size, + ioctl->flags, + ioctl->protection, + (void**) &ioctl->address); + return ioctl->area; + } + + case POKE_UNMAP_MEMORY: + { + mem_map_args* ioctl = (mem_map_args*) arg; + if (ioctl->signature != POKE_SIGNATURE) + return B_BAD_VALUE; + + return delete_area(ioctl->area); + } + } + + return B_BAD_VALUE; +} + + +status_t +poke_read(void* cookie, off_t position, void* buffer, size_t* num_bytes) +{ + *num_bytes = 0; + return B_NOT_ALLOWED; +} + + +status_t +poke_write(void* cookie, off_t position, const void* buffer, size_t* num_bytes) +{ + *num_bytes = 0; + return B_NOT_ALLOWED; +}