diff --git a/build/jam/FloppyBootImage b/build/jam/FloppyBootImage index ea05ca505b..3c792844a7 100644 --- a/build/jam/FloppyBootImage +++ b/build/jam/FloppyBootImage @@ -3,12 +3,15 @@ local X86_ONLY = ; local PPC_ONLY = ; +local ARM_ONLY = ; if $(TARGET_ARCH) = x86 { X86_ONLY = "" ; } else if $(TARGET_ARCH) = ppc { X86_ONLY = ; } else if $(TARGET_ARCH) = m68k { X86_ONLY = ; +} else if $(TARGET_ARCH) = arm { + ARM_ONLY = "" ; } local GPL_ONLY = ; @@ -80,6 +83,7 @@ if $(TARGET_ARCH) = x86 { # drivers AddNewDriversToFloppyBootArchive disk scsi : scsi_cd scsi_disk ; +AddNewDriversToFloppyBootArchive disk : $(ARM_ONLY)norflash ; if $(USB_BOOT) = 1 { AddDriversToFloppyBootArchive disk usb : usb_disk ; } @@ -122,7 +126,7 @@ AddBootModuleSymlinksToFloppyBootArchive ahci generic_ide_pci $(X86_ONLY)ide_isa silicon_image_3112 legacy_sata it8211 $(USB_ONLY)uhci $(USB_ONLY)ohci $(USB_ONLY)ehci - scsi_cd scsi_disk $(USB_ONLY)usb_disk + scsi_cd scsi_disk $(USB_ONLY)usb_disk $(ARM_ONLY)norflash intel session $(SYSTEM_ADD_ONS_FILE_SYSTEMS) $(BOOT_ADD_ONS_NET) diff --git a/src/add-ons/kernel/drivers/disk/Jamfile b/src/add-ons/kernel/drivers/disk/Jamfile index 989aa4d3b9..d6ce88a04a 100644 --- a/src/add-ons/kernel/drivers/disk/Jamfile +++ b/src/add-ons/kernel/drivers/disk/Jamfile @@ -1,6 +1,7 @@ SubDir HAIKU_TOP src add-ons kernel drivers disk ; SubInclude HAIKU_TOP src add-ons kernel drivers disk floppy ; +SubInclude HAIKU_TOP src add-ons kernel drivers disk norflash ; SubInclude HAIKU_TOP src add-ons kernel drivers disk scsi ; SubInclude HAIKU_TOP src add-ons kernel drivers disk usb ; SubInclude HAIKU_TOP src add-ons kernel drivers disk virtual ; diff --git a/src/add-ons/kernel/drivers/disk/norflash/Jamfile b/src/add-ons/kernel/drivers/disk/norflash/Jamfile new file mode 100644 index 0000000000..2294d8d5bc --- /dev/null +++ b/src/add-ons/kernel/drivers/disk/norflash/Jamfile @@ -0,0 +1,10 @@ +SubDir HAIKU_TOP src add-ons kernel drivers disk norflash ; + +SetSubDirSupportedPlatformsBeOSCompatible ; + +UsePrivateHeaders drivers kernel ; + +KernelAddon norflash : + norflash.cpp +; + diff --git a/src/add-ons/kernel/drivers/disk/norflash/norflash.cpp b/src/add-ons/kernel/drivers/disk/norflash/norflash.cpp new file mode 100644 index 0000000000..a15db376c5 --- /dev/null +++ b/src/add-ons/kernel/drivers/disk/norflash/norflash.cpp @@ -0,0 +1,297 @@ +/* + * Copyright 2012, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Ithamar R. Adema + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +//#define TRACE_NORFLASH +#ifdef TRACE_NORFLASH +#define TRACE(x...) dprintf("nor: " x) +#else +#define TRACE(x...) +#endif + +#define NORFLASH_DEVICE_MODULE_NAME "drivers/disk/norflash/device_v1" +#define NORFLASH_DRIVER_MODULE_NAME "drivers/disk/norflash/driver_v1" + +#define NORFLASH_ADDR 0x00000000 + +struct nor_driver_info { + device_node *node; + size_t blocksize; + size_t totalsize; + + area_id id; + void *mapped; +}; + +static device_manager_info* sDeviceManager; + +static const char *sTabTab = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"; +#define DS "%.*s" +#define DA depth - 1, sTabTab + +static void +dump_hex(const char *data, int32 len, int depth = 1) +{ + char str[128]; + char astr[32]; + char *p; + int l; + int i; + + for (i = 0; i < len; ) { + p = str; + l = sizeof(str); + for (; i < len && (p == str || (i % 16 != 0)); i++) { + snprintf(p, l - 1, "%02x ", data[i]); + l -= strlen(p); + p += strlen(p); + astr[i % 16] = isprint(data[i]) ? data[i] : '.'; + astr[i % 16] = isprint(data[i]) ? data[i] : '.'; + astr[(i % 16) + 1] = '\0'; + } + dprintf(DS" %-48.48s %s\n", DA, str, astr); + } +} + + +static status_t +nor_init_device(void* _info, void** _cookie) +{ + TRACE("init_device\n"); + nor_driver_info* info = (nor_driver_info*)_info; + + info->mapped = NULL; + info->blocksize = 128 * 1024; + info->totalsize = info->blocksize * 256; + + info->id = map_physical_memory("NORFlash", NORFLASH_ADDR, info->totalsize, B_ANY_KERNEL_ADDRESS, B_READ_AREA, &info->mapped); + if (info->id < 0) + return info->id; + + *_cookie = info; + return B_OK; +} + + +static void +nor_uninit_device(void* _cookie) +{ + TRACE("uninit_device\n"); + nor_driver_info* info = (nor_driver_info*)_cookie; + if (info) + delete_area(info->id); +} + + +static status_t +nor_open(void *deviceCookie, const char *path, int openMode, + void **_cookie) +{ + TRACE("open(%s)\n", path); + *_cookie = deviceCookie; + return B_OK; +} + + +static status_t +nor_close(void *_cookie) +{ + TRACE("close()\n"); + return B_OK; +} + + +static status_t +nor_free(void *_cookie) +{ + TRACE("free()\n"); + return B_OK; +} + + +static status_t +nor_ioctl(void *cookie, uint32 op, void *buffer, size_t length) +{ + nor_driver_info* info = (nor_driver_info*)cookie; + TRACE("ioctl(%ld,%lu)\n", op, length); + + switch(op) { + case B_GET_GEOMETRY: + { + device_geometry *deviceGeometry = (device_geometry*)buffer; + deviceGeometry->removable = false; + deviceGeometry->bytes_per_sector = info->blocksize; + deviceGeometry->sectors_per_track = info->totalsize / info->blocksize; + deviceGeometry->cylinder_count = 1; + deviceGeometry->head_count = 1; + deviceGeometry->device_type = B_DISK; + deviceGeometry->removable = false; + deviceGeometry->read_only = true; + deviceGeometry->write_once = false; + return B_OK; + } + break; + case B_GET_DEVICE_NAME: + strlcpy((char*)buffer, "NORFlash", length); + break; + } + + return B_ERROR; +} + + +static status_t +nor_read(void *_cookie, off_t position, void *data, size_t *numbytes) +{ + nor_driver_info* info = (nor_driver_info*)_cookie; + TRACE("read(%Ld,%lu)\n", position, *numbytes); + + if (position + *numbytes > info->totalsize) + *numbytes = info->totalsize - (position + *numbytes); + + memcpy(data, info->mapped + position, *numbytes); + +#ifdef TRACE_NORFLASH + dump_hex((const char*)(info->mapped + position), *numbytes, 1); +#endif + + return B_OK; +} + + +static status_t +nor_write(void *_cookie, off_t position, const void *data, size_t *numbytes) +{ + TRACE("write(%Ld,%lu)\n", position, *numbytes); + *numbytes = 0; + return B_ERROR; +} + + +static float +nor_supports_device(device_node *parent) +{ + TRACE("supports_device\n"); + return 0.6; +} + + +static status_t +nor_register_device(device_node *node) +{ + TRACE("register_device\n"); + // ready to register + device_attr attrs[] = { + { NULL } + }; + + return sDeviceManager->register_node(node, NORFLASH_DRIVER_MODULE_NAME, + attrs, NULL, NULL); +} + + +static status_t +nor_init_driver(device_node *node, void **cookie) +{ + TRACE("init_driver\n"); + + nor_driver_info* info = (nor_driver_info*)malloc(sizeof(nor_driver_info)); + if (info == NULL) + return B_NO_MEMORY; + + memset(info, 0, sizeof(*info)); + + info->node = node; + + *cookie = info; + return B_OK; +} + + +static void +nor_uninit_driver(void *_cookie) +{ + TRACE("uninit_driver\n"); + nor_driver_info* info = (nor_driver_info*)_cookie; + free(info); +} + + +static status_t +nor_register_child_devices(void* _cookie) +{ + TRACE("register_child_devices\n"); + nor_driver_info* info = (nor_driver_info*)_cookie; + status_t status; + + status = sDeviceManager->publish_device(info->node, "disk/nor/0/raw", + NORFLASH_DEVICE_MODULE_NAME); + + return status; +} + +struct device_module_info sNORFlashDiskDevice = { + { + NORFLASH_DEVICE_MODULE_NAME, + 0, + NULL + }, + + nor_init_device, + nor_uninit_device, + NULL, //nor_remove, + + nor_open, + nor_close, + nor_free, + nor_read, + nor_write, + NULL, // nor_io, + nor_ioctl, + + NULL, // select + NULL, // deselect +}; + + + +struct driver_module_info sNORFlashDiskDriver = { + { + NORFLASH_DRIVER_MODULE_NAME, + 0, + NULL + }, + + nor_supports_device, + nor_register_device, + nor_init_driver, + nor_uninit_driver, + nor_register_child_devices, + NULL, // rescan + NULL, // removed +}; + +module_dependency module_dependencies[] = { + { B_DEVICE_MANAGER_MODULE_NAME, (module_info**)&sDeviceManager }, + { } +}; + +module_info* modules[] = { + (module_info*)&sNORFlashDiskDriver, + (module_info*)&sNORFlashDiskDevice, + NULL +};