From c2d1fc4ffa7236283061c6358c31f9067c672ca6 Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Sun, 27 May 2012 21:46:50 -0400 Subject: [PATCH 01/39] Fix updating of source path. Factor out updating of the source path view into a dedicated function, and fix some errors that would sometimes result in the text not updating properly when switching stack frames, particularly if the target frame didn't have source code available. --- .../gui/team_window/TeamWindow.cpp | 59 +++++++++++-------- .../gui/team_window/TeamWindow.h | 1 + 2 files changed, 35 insertions(+), 25 deletions(-) diff --git a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp index c499dfeedf..e52718472e 100644 --- a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp @@ -990,6 +990,7 @@ TeamWindow::_SetActiveSourceCode(SourceCode* sourceCode) fSourceView->SetSourceCode(fActiveSourceCode); + _UpdateSourcePathState(); _ScrollToActiveFunction(); } @@ -1049,6 +1050,39 @@ TeamWindow::_UpdateRunButtons() } +void +TeamWindow::_UpdateSourcePathState() +{ + LocatableFile* sourceFile = NULL; + BString sourceText = "Source file unavailable."; + BString truncatedText; + + if (fActiveSourceCode != NULL) { + sourceFile = fActiveFunction->GetFunctionDebugInfo()->SourceFile(); + + if (sourceFile != NULL && !sourceFile->GetLocatedPath(sourceText)) + sourceFile->GetPath(sourceText); + + if (fActiveSourceCode->GetSourceFile() == NULL && sourceFile != NULL) { + sourceText.Prepend("Click to locate source file '"); + sourceText += "'"; + truncatedText = sourceText; + fSourcePathView->TruncateString(&truncatedText, B_TRUNCATE_MIDDLE, + fSourcePathView->Bounds().Width()); + } else if (sourceFile != NULL) { + sourceText.Prepend("File: "); + } + } + + if (!truncatedText.IsEmpty() && truncatedText != sourceText) { + fSourcePathView->SetToolTip(sourceText.String()); + fSourcePathView->SetText(truncatedText); + } + else + fSourcePathView->SetText(sourceText); +} + + void TeamWindow::_ScrollToActiveFunction() { @@ -1183,34 +1217,9 @@ TeamWindow::_HandleSourceCodeChanged() AutoLocker< ::Team> locker(fTeam); SourceCode* sourceCode = fActiveFunction->GetFunction()->GetSourceCode(); - LocatableFile* sourceFile = NULL; - BString sourceText; - BString truncatedText; if (sourceCode == NULL) sourceCode = fActiveFunction->GetSourceCode(); - if (sourceCode != NULL) - sourceFile = fActiveFunction->GetFunctionDebugInfo()->SourceFile(); - - if (sourceFile != NULL && !sourceFile->GetLocatedPath(sourceText)) - sourceFile->GetPath(sourceText); - - if (sourceCode != NULL && sourceCode->GetSourceFile() == NULL - && sourceFile != NULL) { - sourceText.Prepend("Click to locate source file '"); - sourceText += "'"; - truncatedText = sourceText; - fSourcePathView->TruncateString(&truncatedText, B_TRUNCATE_MIDDLE, - fSourcePathView->Bounds().Width()); - if (sourceText != truncatedText) - fSourcePathView->SetToolTip(sourceText.String()); - fSourcePathView->SetText(truncatedText.String()); - } else if (sourceFile != NULL) { - sourceText.Prepend("File: "); - fSourcePathView->SetText(sourceText.String()); - } else - fSourcePathView->SetText("Source file unavailable."); - BReference sourceCodeReference(sourceCode); locker.Unlock(); diff --git a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.h b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.h index 3732ed0870..14635d4a77 100644 --- a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.h +++ b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.h @@ -132,6 +132,7 @@ private: void _SetActiveSourceCode(SourceCode* sourceCode); void _UpdateCpuState(); void _UpdateRunButtons(); + void _UpdateSourcePathState(); void _ScrollToActiveFunction(); void _HandleThreadStateChanged(thread_id threadID); From 72b7db341bb4b8be491ba2aa3453c297b621129f Mon Sep 17 00:00:00 2001 From: Reznikov Sergei Date: Mon, 21 May 2012 17:10:47 +0400 Subject: [PATCH 02/39] Added resize to fit shortcuts. Partially fixes #7467. * Adjusted initial tracker windows width to fit modified column. * Resolved a TODO: Added get info shortcut to Open with window. Author: Sergei Reznikov Signed-off-by: Alexandre Deckner --- src/kits/tracker/ContainerWindow.cpp | 2 +- src/kits/tracker/FilePanelPriv.cpp | 7 ++++++- src/kits/tracker/OpenWithWindow.cpp | 9 +++++++-- src/kits/tracker/TrackerInitialState.cpp | 2 +- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/kits/tracker/ContainerWindow.cpp b/src/kits/tracker/ContainerWindow.cpp index be5af6bcda..bcbb092d4f 100644 --- a/src/kits/tracker/ContainerWindow.cpp +++ b/src/kits/tracker/ContainerWindow.cpp @@ -141,7 +141,7 @@ const int32 kContainerWindowHeightLimit = 85; const int32 kWindowStaggerBy = 17; -BRect BContainerWindow::sNewWindRect(85, 50, 415, 280); +BRect BContainerWindow::sNewWindRect(85, 50, 548, 280); namespace BPrivate { diff --git a/src/kits/tracker/FilePanelPriv.cpp b/src/kits/tracker/FilePanelPriv.cpp index f42b55b991..a4a9b419b5 100644 --- a/src/kits/tracker/FilePanelPriv.cpp +++ b/src/kits/tracker/FilePanelPriv.cpp @@ -159,7 +159,7 @@ TFilePanel::TFilePanel(file_panel_mode mode, BMessenger *target, fIsSavePanel = (mode == B_SAVE_PANEL); - BRect windRect(85, 50, 510, 296); + BRect windRect(85, 50, 568, 296); MoveTo(windRect.LeftTop()); ResizeTo(windRect.Width(), windRect.Height()); @@ -739,6 +739,7 @@ TFilePanel::Init(const BMessage *) AddShortcut('A', B_COMMAND_KEY | B_SHIFT_KEY, new BMessage(kShowSelectionWindow)); AddShortcut('A', B_COMMAND_KEY, new BMessage(B_SELECT_ALL), PoseView()); AddShortcut('S', B_COMMAND_KEY, new BMessage(kInvertSelection), PoseView()); + AddShortcut('Y', B_COMMAND_KEY, new BMessage(kResizeToFit), PoseView()); AddShortcut(B_DOWN_ARROW, B_COMMAND_KEY, new BMessage(kOpenDir)); AddShortcut(B_DOWN_ARROW, B_COMMAND_KEY | B_OPTION_KEY, new BMessage(kOpenDir)); AddShortcut(B_UP_ARROW, B_COMMAND_KEY, new BMessage(kOpenParentDir)); @@ -1182,6 +1183,10 @@ TFilePanel::MessageReceived(BMessage *message) PostMessage(B_QUIT_REQUESTED); break; + case kResizeToFit: + ResizeToFit(); + break; + case kOpenDir: OpenDirectory(); break; diff --git a/src/kits/tracker/OpenWithWindow.cpp b/src/kits/tracker/OpenWithWindow.cpp index cfefdc9e7a..464a1eeb47 100644 --- a/src/kits/tracker/OpenWithWindow.cpp +++ b/src/kits/tracker/OpenWithWindow.cpp @@ -84,7 +84,7 @@ OpenWithContainerWindow::OpenWithContainerWindow(BMessage *entriesToOpen, { AutoLock lock(this); - BRect windowRect(85, 50, 510, 296); + BRect windowRect(85, 50, 718, 296); MoveTo(windowRect.LeftTop()); ResizeTo(windowRect.Width(), windowRect.Height()); @@ -328,6 +328,10 @@ OpenWithContainerWindow::MessageReceived(BMessage *message) case B_OBSERVER_NOTICE_CHANGE: return; + + case kResizeToFit: + ResizeToFit(); + break; } _inherited::MessageReceived(message); } @@ -368,7 +372,8 @@ OpenWithContainerWindow::ShowContextMenu(BPoint, const entry_ref *, BView *) void OpenWithContainerWindow::AddShortcuts() { - // add get info here + AddShortcut('I', B_COMMAND_KEY, new BMessage(kGetInfo), PoseView()); + AddShortcut('Y', B_COMMAND_KEY, new BMessage(kResizeToFit), PoseView()); } diff --git a/src/kits/tracker/TrackerInitialState.cpp b/src/kits/tracker/TrackerInitialState.cpp index ca1dc12eb2..9229de3e5c 100644 --- a/src/kits/tracker/TrackerInitialState.cpp +++ b/src/kits/tracker/TrackerInitialState.cpp @@ -96,7 +96,7 @@ const char *kPeopleSignature = "application/x-vnd.Be-PEPL"; // file system endianness swapping, etc., the correct endianness for the // correct machine has to be used here -const BRect kDefaultFrame(40, 40, 500, 350); +const BRect kDefaultFrame(40, 40, 695, 350); const int32 kDefaultQueryTemplateCount = 3; const AttributeTemplate kDefaultQueryTemplate[] = From e0a6e07bb31229a8d7277e8d7bdfffccdb35ed3e Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Mon, 28 May 2012 14:51:03 -0400 Subject: [PATCH 03/39] Minor cleanup, no functional change. --- .../debugger/user_interface/gui/team_window/TeamWindow.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp index e52718472e..bb8ca25c42 100644 --- a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp @@ -1075,10 +1075,9 @@ TeamWindow::_UpdateSourcePathState() } if (!truncatedText.IsEmpty() && truncatedText != sourceText) { - fSourcePathView->SetToolTip(sourceText.String()); + fSourcePathView->SetToolTip(sourceText); fSourcePathView->SetText(truncatedText); - } - else + } else fSourcePathView->SetText(sourceText); } From dbf07c84a22f5b395d00d66e7d3b0e1160cb2f13 Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Mon, 28 May 2012 15:39:38 -0400 Subject: [PATCH 04/39] Fix problems unwinding call frames. Our more recent build of gcc4 appears to have switched to using .eh_frame for almost all useful call frame information when built with debugging. Use a somewhat crude heuristic (size) to determine if the .debug_frame section we've been given might actually be of use or not (assuming it exists at all, this was inconsistent in my tests. Sometimes apps had no .debug_frame at all, other times it was present but was only roundabouts 100 bytes). Fixes ticket #8508. --- src/apps/debugger/dwarf/DwarfFile.cpp | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/apps/debugger/dwarf/DwarfFile.cpp b/src/apps/debugger/dwarf/DwarfFile.cpp index 647edbb393..d4cb185c49 100644 --- a/src/apps/debugger/dwarf/DwarfFile.cpp +++ b/src/apps/debugger/dwarf/DwarfFile.cpp @@ -350,15 +350,25 @@ DwarfFile::Load(const char* fileName) fDebugRangesSection = fElfFile->GetSection(".debug_ranges"); fDebugLineSection = fElfFile->GetSection(".debug_line"); fDebugFrameSection = fElfFile->GetSection(".debug_frame"); - if (fDebugFrameSection == NULL) { - fDebugFrameSection = fElfFile->GetSection(".eh_frame"); - fUsingEHFrameSection = fDebugFrameSection != NULL; - if (fUsingEHFrameSection) { - fGCC4EHFrameSection = !fDebugFrameSection->IsWritable(); - // Crude heuristic for recognizing GCC 4 (Itanium ABI) style - // .eh_frame sections. The ones generated by GCC 2 are writable, - // the ones generated by GCC 4 aren't. + ElfSection* ehFrameSection = fElfFile->GetSection(".eh_frame"); + if (fDebugFrameSection != NULL) { + if (ehFrameSection != NULL && ehFrameSection->Size() + > fDebugFrameSection->Size()) { + fElfFile->PutSection(fDebugFrameSection); + fDebugFrameSection = ehFrameSection; + fUsingEHFrameSection = true; } + + } else if (ehFrameSection != NULL) { + fDebugFrameSection = ehFrameSection; + fUsingEHFrameSection = true; + } + + if (fUsingEHFrameSection) { + fGCC4EHFrameSection = !fDebugFrameSection->IsWritable(); + // Crude heuristic for recognizing GCC 4 (Itanium ABI) style + // .eh_frame sections. The ones generated by GCC 2 are writable, + // the ones generated by GCC 4 aren't. } fDebugLocationSection = fElfFile->GetSection(".debug_loc"); fDebugPublicTypesSection = fElfFile->GetSection(".debug_pubtypes"); From f4ee2d048e0d4e754b94ec1e5c271c2d3ecf96ec Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Mon, 28 May 2012 15:48:00 -0400 Subject: [PATCH 05/39] Slight and cleanup and fix potential section leak. --- src/apps/debugger/dwarf/DwarfFile.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/apps/debugger/dwarf/DwarfFile.cpp b/src/apps/debugger/dwarf/DwarfFile.cpp index d4cb185c49..49b5a9c6da 100644 --- a/src/apps/debugger/dwarf/DwarfFile.cpp +++ b/src/apps/debugger/dwarf/DwarfFile.cpp @@ -351,14 +351,13 @@ DwarfFile::Load(const char* fileName) fDebugLineSection = fElfFile->GetSection(".debug_line"); fDebugFrameSection = fElfFile->GetSection(".debug_frame"); ElfSection* ehFrameSection = fElfFile->GetSection(".eh_frame"); - if (fDebugFrameSection != NULL) { - if (ehFrameSection != NULL && ehFrameSection->Size() - > fDebugFrameSection->Size()) { + if (fDebugFrameSection != NULL && ehFrameSection != NULL) { + if (ehFrameSection->Size() > fDebugFrameSection->Size()) { fElfFile->PutSection(fDebugFrameSection); fDebugFrameSection = ehFrameSection; fUsingEHFrameSection = true; - } - + } else + fElfFile->PutSection(ehFrameSection); } else if (ehFrameSection != NULL) { fDebugFrameSection = ehFrameSection; fUsingEHFrameSection = true; @@ -370,6 +369,7 @@ DwarfFile::Load(const char* fileName) // .eh_frame sections. The ones generated by GCC 2 are writable, // the ones generated by GCC 4 aren't. } + fDebugLocationSection = fElfFile->GetSection(".debug_loc"); fDebugPublicTypesSection = fElfFile->GetSection(".debug_pubtypes"); From 9c02217342b431de9ca99a3ad6a3febe423a32f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Tue, 29 May 2012 18:50:32 +0200 Subject: [PATCH 06/39] PPC: Add PVR identifiers for 440 and 460 cpus * from QEMU, 440EP is 0x4222. * from the datasheet, 460EX is 0x1302. --- headers/private/kernel/arch/ppc/arch_cpu.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/headers/private/kernel/arch/ppc/arch_cpu.h b/headers/private/kernel/arch/ppc/arch_cpu.h index e65acbec64..b48adf1548 100644 --- a/headers/private/kernel/arch/ppc/arch_cpu.h +++ b/headers/private/kernel/arch/ppc/arch_cpu.h @@ -187,8 +187,10 @@ enum ppc_processor_version { IBMPOWER3 = 0x0041, MPC860 = 0x0050, MPC8240 = 0x0081, + AMCC460EX = 0x1302, IBM405GP = 0x4011, IBM405L = 0x4161, + AMCC440EP = 0x4222, IBM750FX = 0x7000, MPC7450 = 0x8000, MPC7455 = 0x8001, From e0ee3b7971889f4656b26baae75f6ee96f42c190 Mon Sep 17 00:00:00 2001 From: Gerald Zajac Date: Wed, 30 May 2012 15:21:18 -0500 Subject: [PATCH 07/39] driver: New intel 810 video driver * Introduced by Gerald Zajac in #8615 * Will need reviewed, tested, and some style cleanup * Not in images until steps above complete --- .../graphics/intel_810/DriverInterface.h | 110 +++ src/add-ons/accelerants/Jamfile | 1 + src/add-ons/accelerants/intel_810/Jamfile | 19 + .../accelerants/intel_810/accelerant.cpp | 236 ++++++ .../accelerants/intel_810/accelerant.h | 117 +++ src/add-ons/accelerants/intel_810/engine.cpp | 81 +++ src/add-ons/accelerants/intel_810/hooks.cpp | 84 +++ .../accelerants/intel_810/i810_dpms.cpp | 101 +++ .../accelerants/intel_810/i810_init.cpp | 70 ++ .../accelerants/intel_810/i810_mode.cpp | 288 ++++++++ src/add-ons/accelerants/intel_810/i810_regs.h | 163 +++++ .../accelerants/intel_810/i810_watermark.cpp | 143 ++++ src/add-ons/accelerants/intel_810/mode.cpp | 339 +++++++++ src/add-ons/kernel/drivers/graphics/Jamfile | 1 + .../kernel/drivers/graphics/intel_810/Jamfile | 9 + .../drivers/graphics/intel_810/driver.cpp | 674 ++++++++++++++++++ 16 files changed, 2436 insertions(+) create mode 100644 headers/private/graphics/intel_810/DriverInterface.h create mode 100644 src/add-ons/accelerants/intel_810/Jamfile create mode 100644 src/add-ons/accelerants/intel_810/accelerant.cpp create mode 100644 src/add-ons/accelerants/intel_810/accelerant.h create mode 100644 src/add-ons/accelerants/intel_810/engine.cpp create mode 100644 src/add-ons/accelerants/intel_810/hooks.cpp create mode 100644 src/add-ons/accelerants/intel_810/i810_dpms.cpp create mode 100644 src/add-ons/accelerants/intel_810/i810_init.cpp create mode 100644 src/add-ons/accelerants/intel_810/i810_mode.cpp create mode 100644 src/add-ons/accelerants/intel_810/i810_regs.h create mode 100644 src/add-ons/accelerants/intel_810/i810_watermark.cpp create mode 100644 src/add-ons/accelerants/intel_810/mode.cpp create mode 100644 src/add-ons/kernel/drivers/graphics/intel_810/Jamfile create mode 100644 src/add-ons/kernel/drivers/graphics/intel_810/driver.cpp diff --git a/headers/private/graphics/intel_810/DriverInterface.h b/headers/private/graphics/intel_810/DriverInterface.h new file mode 100644 index 0000000000..a265aef865 --- /dev/null +++ b/headers/private/graphics/intel_810/DriverInterface.h @@ -0,0 +1,110 @@ +/* + * Copyright 2007-2012 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT license. + * + * Authors: + * Gerald Zajac + */ + +#ifndef DRIVERINTERFACE_H +#define DRIVERINTERFACE_H + + +#include +#include +#include +#include + + +// This file contains info that is shared between the kernel driver and the +// accelerant, and info that is shared among the source files of the +// accelerant. + + +#define ENABLE_DEBUG_TRACE // if defined, turns on debug output to syslog + + +#define ARRAY_SIZE(a) (int(sizeof(a) / sizeof(a[0]))) // get number of elements in an array + + +struct Benaphore { + sem_id sem; + int32 count; + + status_t Init(const char* name) + { + count = 0; + sem = create_sem(0, name); + return sem < 0 ? sem : B_OK; + } + + status_t Acquire() + { + if (atomic_add(&count, 1) > 0) + return acquire_sem(sem); + return B_OK; + } + + status_t Release() + { + if (atomic_add(&count, -1) > 1) + return release_sem(sem); + return B_OK; + } + + void Delete() { delete_sem(sem); } +}; + + + +enum { + INTEL_GET_SHARED_DATA = B_DEVICE_OP_CODES_END + 234, + INTEL_DEVICE_NAME, + INTEL_GET_EDID, +}; + + +struct DisplayModeEx : display_mode { + uint8 bitsPerPixel; + uint8 bytesPerPixel; + uint16 bytesPerRow; // number of bytes in one line/row +}; + + +struct SharedInfo { + // Device ID info. + uint16 vendorID; // PCI vendor ID, from pci_info + uint16 deviceID; // PCI device ID, from pci_info + uint8 revision; // PCI device revsion, from pci_info + char chipName[32]; // user recognizable name of chip + + bool bAccelerantInUse; // true = accelerant has been initialized + + // Memory mappings. + area_id regsArea; // area_id for the memory mapped registers. It will + // be cloned into accelerant's address space. + area_id videoMemArea; // video memory area_id. Addr's shared with all teams. + addr_t videoMemAddr; // virtual video memory addr + phys_addr_t videoMemPCI; // physical video memory addr + uint32 videoMemSize; // video memory size in bytes (for frame buffer). + + uint32 maxFrameBufferSize; // max available video memory for frame buffer + + // Color spaces supported by current video chip/driver. + color_space colorSpaces[6]; + uint32 colorSpaceCount; // number of color spaces in array colorSpaces + + // List of screen modes. + area_id modeArea; // area containing list of display modes the driver supports + uint32 modeCount; // number of display modes in the list + + DisplayModeEx displayMode; // current display mode configuration + + edid1_info edidInfo; + bool bHaveEDID; // true = EDID info from device is in edidInfo + + Benaphore engineLock; // for serializing access to the acceleration engine +}; + + +#endif // DRIVERINTERFACE_H diff --git a/src/add-ons/accelerants/Jamfile b/src/add-ons/accelerants/Jamfile index 1b10992896..442e4c16c3 100644 --- a/src/add-ons/accelerants/Jamfile +++ b/src/add-ons/accelerants/Jamfile @@ -4,6 +4,7 @@ SubInclude HAIKU_TOP src add-ons accelerants 3dfx ; SubInclude HAIKU_TOP src add-ons accelerants ati ; SubInclude HAIKU_TOP src add-ons accelerants common ; SubInclude HAIKU_TOP src add-ons accelerants et6x00 ; +SubInclude HAIKU_TOP src add-ons accelerants intel_810 ; SubInclude HAIKU_TOP src add-ons accelerants intel_extreme ; SubInclude HAIKU_TOP src add-ons accelerants matrox ; SubInclude HAIKU_TOP src add-ons accelerants neomagic ; diff --git a/src/add-ons/accelerants/intel_810/Jamfile b/src/add-ons/accelerants/intel_810/Jamfile new file mode 100644 index 0000000000..3fcb69e860 --- /dev/null +++ b/src/add-ons/accelerants/intel_810/Jamfile @@ -0,0 +1,19 @@ +SubDir HAIKU_TOP src add-ons accelerants intel_810 ; + +UsePrivateHeaders graphics ; +UsePrivateHeaders [ FDirName graphics intel_810 ] ; +UsePrivateHeaders [ FDirName graphics common ] ; + +Addon intel_810.accelerant : + accelerant.cpp + engine.cpp + hooks.cpp + mode.cpp + + i810_dpms.cpp + i810_init.cpp + i810_mode.cpp + i810_watermark.cpp + + : be libaccelerantscommon.a +; diff --git a/src/add-ons/accelerants/intel_810/accelerant.cpp b/src/add-ons/accelerants/intel_810/accelerant.cpp new file mode 100644 index 0000000000..475847c213 --- /dev/null +++ b/src/add-ons/accelerants/intel_810/accelerant.cpp @@ -0,0 +1,236 @@ +/* + * Copyright 2007-2012 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT license. + * + * Authors: + * Gerald Zajac + */ + +#include "accelerant.h" + +#include +#include +#include + + + +AccelerantInfo gInfo; // global data used by source files of accelerant + +static uint32 videoValue; + + +static int32 +SuppressArtifacts(void* dataPtr) +{ + // The Intel 810 & 815 video chips create annoying artifacts which are + // most noticeable when the cursor is moved by itself or the user goes up + // and down through a menu. However, if a large number of video memory + // locations are accessed frequently like when the GLTeapot demo is + // running, the artifacts are greatly suppressed. Thus, that is the reason + // why this function accesses a large number of video memory locations + // frequently. Note that the accessed memory locations are at the end of + // the video memory. This is because some artifacts still occur at the + // top of the screen if the accessed memory is at the beginning of the + // video memory. + + // Note that this function will reduce the general performance of a + // computer somewhat, but it is much less of a hit than if double + // buffering was used for the video. Base on the frame rate of the + // the GLTeapot demo, it is less than a 10% reduction. + + SharedInfo& si = *((SharedInfo*)dataPtr); + + while (true) + { + uint32* src = ((uint32*)(si.videoMemAddr)) + si.videoMemSize / 4 - 1; + uint32 count = 65000; + + while (count-- > 0) + videoValue = *src--; + + snooze(30000); // sleep for 30 msec + } + + return 0; +} + + +static status_t +InitCommon(int fileDesc) +{ + // Initialization function used by primary and cloned accelerants. + + gInfo.deviceFileDesc = fileDesc; + + // Get area ID of shared data from driver. + + area_id sharedArea; + status_t result = ioctl(gInfo.deviceFileDesc, INTEL_GET_SHARED_DATA, + &sharedArea, sizeof(sharedArea)); + if (result != B_OK) + return result; + + gInfo.sharedInfoArea = clone_area("i810 shared info", + (void**)&(gInfo.sharedInfo), B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, + sharedArea); + if (gInfo.sharedInfoArea < 0) + return gInfo.sharedInfoArea; // sharedInfoArea has error code + + gInfo.regsArea = clone_area("i810 regs area", (void**)&(gInfo.regs), + B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, gInfo.sharedInfo->regsArea); + if (gInfo.regsArea < 0) { + delete_area(gInfo.sharedInfoArea); + return gInfo.regsArea; // regsArea has error code + } + + return B_OK; +} + + +static void +UninitCommon(void) +{ + // This function is used by both primary and cloned accelerants. + + delete_area(gInfo.regsArea); + gInfo.regs = 0; + + delete_area(gInfo.sharedInfoArea); + gInfo.sharedInfo = 0; +} + + +status_t +InitAccelerant(int fileDesc) +{ + // Initialize the accelerant. fileDesc is the file handle of the device + // (in /dev/graphics) that has been opened by the app_server. + + TRACE("Enter InitAccelerant()\n"); + + gInfo.bAccelerantIsClone = false; // indicate this is primary accelerant + + status_t result = InitCommon(fileDesc); + if (result == B_OK) { + SharedInfo& si = *gInfo.sharedInfo; + + TRACE("Vendor ID: 0x%X, Device ID: 0x%X\n", si.vendorID, si.deviceID); + + // Ensure that InitAccelerant is executed just once (copies should be + // clones) + + if (si.bAccelerantInUse) { + result = B_NOT_ALLOWED; + } else { + result = I810_Init(); // perform init related to current chip + if (result == B_OK) { + result = si.engineLock.Init("i810 engine lock"); + if (result == B_OK) { + // Ensure that this function won't be executed again + // (copies should be clones) + si.bAccelerantInUse = true; + + thread_id threadID = spawn_thread(SuppressArtifacts, + "SuppressArtifacts_Thread", B_DISPLAY_PRIORITY, + gInfo.sharedInfo); + result = resume_thread(threadID); + } + } + } + + if (result != B_OK) + UninitCommon(); + } + + TRACE("Leave InitAccelerant(), result: 0x%X\n", result); + return result; +} + + +ssize_t +AccelerantCloneInfoSize(void) +{ + // Return the number of bytes required to hold the information required + // to clone the device. The information is merely the name of the device; + // thus, return the size of the name buffer. + + return B_OS_NAME_LENGTH; +} + + +void +GetAccelerantCloneInfo(void* data) +{ + // Return the info required to clone the device. Argument data points to + // a buffer which is the size returned by AccelerantCloneInfoSize(). + + ioctl(gInfo.deviceFileDesc, INTEL_DEVICE_NAME, data, B_OS_NAME_LENGTH); +} + + +status_t +CloneAccelerant(void* data) +{ + // Initialize a copy of the accelerant as a clone. Argument data points to + // a copy of the data which was returned by GetAccelerantCloneInfo(). + + TRACE("Enter CloneAccelerant()\n"); + + char path[MAXPATHLEN] = "/dev/"; + strcat(path, (const char*)data); + + gInfo.deviceFileDesc = open(path, B_READ_WRITE); // open the device + if (gInfo.deviceFileDesc < 0) + return errno; + + gInfo.bAccelerantIsClone = true; + + status_t result = InitCommon(gInfo.deviceFileDesc); + if (result != B_OK) { + close(gInfo.deviceFileDesc); + return result; + } + + result = gInfo.modeListArea = clone_area("i810 cloned display_modes", + (void**) &gInfo.modeList, B_ANY_ADDRESS, B_READ_AREA, + gInfo.sharedInfo->modeArea); + if (result < 0) { + UninitCommon(); + close(gInfo.deviceFileDesc); + return result; + } + + TRACE("Leave CloneAccelerant()\n"); + return B_OK; +} + + +void +UninitAccelerant(void) +{ + delete_area(gInfo.modeListArea); + gInfo.modeList = NULL; + + UninitCommon(); + + if (gInfo.bAccelerantIsClone) + close(gInfo.deviceFileDesc); +} + + +status_t +GetAccelerantDeviceInfo(accelerant_device_info* adi) +{ + // Get info about the device. + + SharedInfo& si = *gInfo.sharedInfo; + + adi->version = 1; + strcpy(adi->name, "Intel 810/815 chipset"); + strcpy(adi->chipset, si.chipName); + strcpy(adi->serial_no, "unknown"); + adi->memory = si.maxFrameBufferSize; + adi->dac_speed = 270; + + return B_OK; +} diff --git a/src/add-ons/accelerants/intel_810/accelerant.h b/src/add-ons/accelerants/intel_810/accelerant.h new file mode 100644 index 0000000000..9406337b60 --- /dev/null +++ b/src/add-ons/accelerants/intel_810/accelerant.h @@ -0,0 +1,117 @@ +/* + * Copyright 2007-2012 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT license. + * + * Authors: + * Gerald Zajac + */ + +#ifndef _ACCELERANT_H +#define _ACCELERANT_H + +#include "DriverInterface.h" + + + +#undef TRACE + +#ifdef ENABLE_DEBUG_TRACE +extern "C" void _sPrintf(const char* format, ...); +# define TRACE(x...) _sPrintf("i810: " x) +#else +# define TRACE(x...) ; +#endif + + +// Global data used by various source files of the accelerant. + +struct AccelerantInfo { + int deviceFileDesc; // file descriptor of kernel driver + + SharedInfo* sharedInfo; // address of info shared between + // accelerants & driver + area_id sharedInfoArea; // shared info area ID + + uint8* regs; // base address of MMIO register area + area_id regsArea; // MMIO register area ID + + display_mode* modeList; // list of standard display modes + area_id modeListArea; // mode list area ID + + bool bAccelerantIsClone; // true if this is a cloned accelerant +}; + +extern AccelerantInfo gInfo; + + +// Prototypes of the interface functions called by the app_server. Note that +// the functions that are unique to a particular chip family, will be prefixed +// with the name of the family, and the functions that are applicable to all +// chips will have no prefix. +//================================================================ + +#if defined(__cplusplus) +extern "C" { +#endif + +// General +status_t InitAccelerant(int fd); +ssize_t AccelerantCloneInfoSize(void); +void GetAccelerantCloneInfo(void* data); +status_t CloneAccelerant(void* data); +void UninitAccelerant(void); +status_t GetAccelerantDeviceInfo(accelerant_device_info* adi); + +// Mode Configuration +uint32 AccelerantModeCount(void); +status_t GetModeList(display_mode* dm); +status_t ProposeDisplayMode(display_mode* target, const display_mode* low, + const display_mode* high); +status_t SetDisplayMode(display_mode* mode_to_set); +status_t GetDisplayMode(display_mode* current_mode); +status_t GetFrameBufferConfig(frame_buffer_config* a_frame_buffer); +status_t GetPixelClockLimits(display_mode* dm, uint32* low, uint32* high); +status_t MoveDisplay(uint16 h_display_start, uint16 v_display_start); +void I810_SetIndexedColors(uint count, uint8 first, uint8* color_data, + uint32 flags); +status_t GetEdidInfo(void* info, size_t size, uint32* _version); + +// DPMS +uint32 I810_DPMSCapabilities(void); +uint32 I810_GetDPMSMode(void); +status_t I810_SetDPMSMode(uint32 dpms_flags); + +// Engine Management +uint32 AccelerantEngineCount(void); +status_t AcquireEngine(uint32 capabilities, uint32 max_wait, sync_token* st, + engine_token** et); +status_t ReleaseEngine(engine_token* et, sync_token* st); +void WaitEngineIdle(void); +status_t GetSyncToken(engine_token* et, sync_token* st); +status_t SyncToToken(sync_token* st); + +#if defined(__cplusplus) +} +#endif + + + +// Prototypes for other functions that are called from source files other than +// where they are defined. +//============================================================================ + +status_t CreateModeList(bool (*checkMode)(const display_mode* mode)); +bool IsModeUsable(const display_mode* mode); + +// Intel 810 functions. + +status_t I810_Init(void); +bool I810_GetColorSpaceParams(int colorSpace, uint8& bpp, + uint32& maxPixelClk); +uint32 I810_GetWatermark(const DisplayModeEx& mode); + +void I810_AdjustFrame(const DisplayModeEx& mode); +status_t I810_SetDisplayMode(const DisplayModeEx& mode); + + +#endif // _ACCELERANT_H diff --git a/src/add-ons/accelerants/intel_810/engine.cpp b/src/add-ons/accelerants/intel_810/engine.cpp new file mode 100644 index 0000000000..87e24136fe --- /dev/null +++ b/src/add-ons/accelerants/intel_810/engine.cpp @@ -0,0 +1,81 @@ +/* + * Copyright 2007-2012 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT license. + * + * Authors: + * Gerald Zajac + */ + +#include "accelerant.h" +#include "i810_regs.h" + + +static engine_token sEngineToken = { 1, B_2D_ACCELERATION, NULL }; + + +uint32 +AccelerantEngineCount(void) +{ + return 1; +} + + +status_t +AcquireEngine(uint32 capabilities, uint32 maxWait, + sync_token* syncToken, engine_token** engineToken) +{ + (void)capabilities; // avoid compiler warning for unused arg + (void)maxWait; // avoid compiler warning for unused arg + + if (gInfo.sharedInfo->engineLock.Acquire() != B_OK) + return B_ERROR; + + if (syncToken) + SyncToToken(syncToken); + + *engineToken = &sEngineToken; + return B_OK; +} + + +status_t +ReleaseEngine(engine_token* engineToken, sync_token* syncToken) +{ + if (syncToken) + GetSyncToken(engineToken, syncToken); + + gInfo.sharedInfo->engineLock.Release(); + return B_OK; +} + + +void +WaitEngineIdle(void) +{ + // Wait until engine is idle. + + int k = 10000000; + + while ((INREG16(INST_DONE) & 0x7B) != 0x7B && k > 0) + k--; +} + + +status_t +GetSyncToken(engine_token* engineToken, sync_token* syncToken) +{ + syncToken->engine_id = engineToken->engine_id; + syncToken->counter = 0; + return B_OK; +} + + +status_t +SyncToToken(sync_token* syncToken) +{ + (void)syncToken; // avoid compiler warning for unused arg + + WaitEngineIdle(); + return B_OK; +} + diff --git a/src/add-ons/accelerants/intel_810/hooks.cpp b/src/add-ons/accelerants/intel_810/hooks.cpp new file mode 100644 index 0000000000..b06a95a1b6 --- /dev/null +++ b/src/add-ons/accelerants/intel_810/hooks.cpp @@ -0,0 +1,84 @@ +/* + * Copyright 2008-2012 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT license. + * + * Authors: + * Gerald Zajac + */ + +#include "accelerant.h" + + +extern "C" void* +get_accelerant_hook(uint32 feature, void* data) +{ + (void)data; // avoid compiler warning for unused arg + + switch (feature) { + // General + case B_INIT_ACCELERANT: + return (void*)InitAccelerant; + case B_UNINIT_ACCELERANT: + return (void*)UninitAccelerant; + case B_CLONE_ACCELERANT: + return (void*)CloneAccelerant; + case B_ACCELERANT_CLONE_INFO_SIZE: + return (void*)AccelerantCloneInfoSize; + case B_GET_ACCELERANT_CLONE_INFO: + return (void*)GetAccelerantCloneInfo; + case B_GET_ACCELERANT_DEVICE_INFO: + return (void*)GetAccelerantDeviceInfo; + case B_ACCELERANT_RETRACE_SEMAPHORE: + return NULL; + + // Mode Configuration + case B_ACCELERANT_MODE_COUNT: + return (void*)AccelerantModeCount; + case B_GET_MODE_LIST: + return (void*)GetModeList; + case B_PROPOSE_DISPLAY_MODE: + return (void*)ProposeDisplayMode; + case B_SET_DISPLAY_MODE: + return (void*)SetDisplayMode; + case B_GET_DISPLAY_MODE: + return (void*)GetDisplayMode; +#ifdef __HAIKU__ + case B_GET_EDID_INFO: + return (void*)GetEdidInfo; +#endif + case B_GET_FRAME_BUFFER_CONFIG: + return (void*)GetFrameBufferConfig; + case B_GET_PIXEL_CLOCK_LIMITS: + return (void*)GetPixelClockLimits; + case B_MOVE_DISPLAY: + return (void*)MoveDisplay; + case B_SET_INDEXED_COLORS: + return (void*)(I810_SetIndexedColors); + case B_GET_TIMING_CONSTRAINTS: + return NULL; + + // DPMS + case B_DPMS_CAPABILITIES: + return (void*)(I810_DPMSCapabilities); + case B_DPMS_MODE: + return (void*)(I810_GetDPMSMode); + case B_SET_DPMS_MODE: + return (void*)(I810_SetDPMSMode); + + // Engine Management + case B_ACCELERANT_ENGINE_COUNT: + return (void*)AccelerantEngineCount; + case B_ACQUIRE_ENGINE: + return (void*)AcquireEngine; + case B_RELEASE_ENGINE: + return (void*)ReleaseEngine; + case B_WAIT_ENGINE_IDLE: + return (void*)WaitEngineIdle; + case B_GET_SYNC_TOKEN: + return (void*)GetSyncToken; + case B_SYNC_TO_TOKEN: + return (void*)SyncToToken; + } + + return NULL; // Return null pointer for any feature not handled above +} diff --git a/src/add-ons/accelerants/intel_810/i810_dpms.cpp b/src/add-ons/accelerants/intel_810/i810_dpms.cpp new file mode 100644 index 0000000000..f49361d805 --- /dev/null +++ b/src/add-ons/accelerants/intel_810/i810_dpms.cpp @@ -0,0 +1,101 @@ +/* + * Copyright 2012 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT license. + * + * Authors: + * Gerald Zajac + */ + +/*! + Haiku Intel-810 video driver was adapted from the X.org intel driver which + has the following copyright. + + Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. + All Rights Reserved. + */ + + +#include "accelerant.h" +#include "i810_regs.h" + + +#define DPMS_SYNC_SELECT 0x5002 +#define H_SYNC_OFF 0x02 +#define V_SYNC_OFF 0x08 + + +uint32 +I810_DPMSCapabilities(void) +{ + // Return DPMS modes supported by this device. + + return B_DPMS_ON | B_DPMS_STAND_BY | B_DPMS_SUSPEND | B_DPMS_OFF; +} + + +uint32 +I810_GetDPMSMode(void) +{ + // Return the current DPMS mode. + + uint32 tmp = INREG8(DPMS_SYNC_SELECT) & (H_SYNC_OFF | V_SYNC_OFF); + uint32 mode; + + if (tmp == 0 ) + mode = B_DPMS_ON; + else if (tmp == H_SYNC_OFF) + mode = B_DPMS_STAND_BY; + else if (tmp == V_SYNC_OFF) + mode = B_DPMS_SUSPEND; + else + mode = B_DPMS_OFF; + + TRACE("I810_DPMSMode() mode: %d\n", mode); + return mode; +} + + +status_t +I810_SetDPMSMode(uint32 dpmsMode) +{ + // Set the display into one of the Display Power Management modes, + // and return B_OK if successful, else return B_ERROR. + + TRACE("I810_SetDPMSMode() mode: %d\n", dpmsMode); + + uint8 seq01 = ReadSeqReg(1) & ~0x20; + uint8 dpmsSyncSelect = 0; + + switch (dpmsMode) { + case B_DPMS_ON: + // Screen: On; HSync: On, VSync: On. + break; + + case B_DPMS_STAND_BY: + // Screen: Off; HSync: Off, VSync: On. + seq01 |= 0x20; + dpmsSyncSelect = H_SYNC_OFF; + break; + + case B_DPMS_SUSPEND: + // Screen: Off; HSync: On, VSync: Off. + seq01 |= 0x20; + dpmsSyncSelect = V_SYNC_OFF; + break; + + case B_DPMS_OFF: + // Screen: Off; HSync: Off, VSync: Off. + seq01 |= 0x20; + dpmsSyncSelect = H_SYNC_OFF | V_SYNC_OFF; + break; + + default: + TRACE("Invalid DPMS mode %d\n", dpmsMode); + return B_ERROR; + } + + WriteSeqReg(1, seq01); // turn the screen on/off + OUTREG8(DPMS_SYNC_SELECT, dpmsSyncSelect); // set DPMS mode + + return B_OK; +} diff --git a/src/add-ons/accelerants/intel_810/i810_init.cpp b/src/add-ons/accelerants/intel_810/i810_init.cpp new file mode 100644 index 0000000000..3c4f4c03a5 --- /dev/null +++ b/src/add-ons/accelerants/intel_810/i810_init.cpp @@ -0,0 +1,70 @@ +/* + * Copyright 2012 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT license. + * + * Authors: + * Gerald Zajac + */ + +/*! + Haiku Intel-810 video driver was adapted from the X.org intel driver which + has the following copyright. + + Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. + All Rights Reserved. + */ + + +#include "accelerant.h" +#include "i810_regs.h" + + + +bool +I810_GetColorSpaceParams(int colorSpace, uint8& bitsPerPixel, + uint32& maxPixelClock) +{ + // Get parameters for a color space which is supported by the i810 chips. + // Argument maxPixelClock is in KHz. + // Return true if the color space is supported; else return false. + + switch (colorSpace) { + case B_RGB16: + bitsPerPixel = 16; + maxPixelClock = 163000; + break; + break; + case B_CMAP8: + bitsPerPixel = 8; + maxPixelClock = 203000; + break; + default: + TRACE("Unsupported color space: 0x%X\n", colorSpace); + return false; + } + + return true; +} + + +status_t +I810_Init(void) +{ + TRACE("I810_Init()\n"); + + SharedInfo& si = *gInfo.sharedInfo; + + // Use all of video memory for the frame buffer. + + si.maxFrameBufferSize = si.videoMemSize; + + // Set up the array of the supported color spaces. + + si.colorSpaces[0] = B_CMAP8; + si.colorSpaces[1] = B_RGB16; + si.colorSpaceCount = 2; + + // Setup the mode list. + + return CreateModeList(IsModeUsable); +} diff --git a/src/add-ons/accelerants/intel_810/i810_mode.cpp b/src/add-ons/accelerants/intel_810/i810_mode.cpp new file mode 100644 index 0000000000..3c95d5f1be --- /dev/null +++ b/src/add-ons/accelerants/intel_810/i810_mode.cpp @@ -0,0 +1,288 @@ +/* + * Copyright 2012 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT license. + * + * Authors: + * Gerald Zajac +*/ + +/*! + Haiku Intel-810 video driver was adapted from the X.org intel driver which + has the following copyright. + + Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. + All Rights Reserved. + */ + +#include "accelerant.h" +#include "i810_regs.h" + +#include // common accelerant header file +#include +#include + + + +// I810_CalcVCLK -- Determine closest clock frequency to the one requested. + +#define MAX_VCO_FREQ 600.0 +#define TARGET_MAX_N 30 +#define REF_FREQ 24.0 + +#define CALC_VCLK(m,n,p) (double)m / ((double)n * (1 << p)) * 4 * REF_FREQ + +static void +CalcVCLK(double freq, uint16& clkM, uint16& clkN, uint16& clkP) { + int m, n, p; + double f_out, f_best; + double f_err; + double f_vco; + int m_best = 0, n_best = 0, p_best = 0; + double f_target = freq; + double errMax = 0.005; + double errTarget = 0.001; + double errBest = 999999.0; + + p_best = p = int(log(MAX_VCO_FREQ / f_target) / log((double)2)); + // Make sure p is within range. + if (p_best > 5) { + p_best = p = 5; + } + + f_vco = f_target * (1 << p); + + n = 2; + do { + n++; + m = int(f_vco / (REF_FREQ / (double)n) / (double)4.0 + 0.5); + if (m < 3) + m = 3; + f_out = CALC_VCLK(m, n, p); + f_err = 1.0 - (f_target / f_out); + if (fabs(f_err) < errMax) { + m_best = m; + n_best = n; + f_best = f_out; + errBest = f_err; + } + } while ((fabs(f_err) >= errTarget) && + ((n <= TARGET_MAX_N) || (fabs(errBest) > errMax))); + + if (fabs(f_err) < errTarget) { + m_best = m; + n_best = n; + } + + clkM = (m_best - 2) & 0x3FF; + clkN = (n_best - 2) & 0x3FF; + clkP = (p_best << 4); + + TRACE("Setting dot clock to %.1f MHz [ 0x%x 0x%x 0x%x ] [ %d %d %d ]\n", + CALC_VCLK(m_best, n_best, p_best), + clkM, clkN, clkP, m_best, n_best, p_best); +} + + +static void +SetCrtcTimingValues(const DisplayModeEx& mode) +{ + // Set the timing values for CRTC registers cr00 to cr18, and some extended + // CRTC registers. + + int hTotal = mode.timing.h_total / 8 - 5; + int hDisp_e = mode.timing.h_display / 8 - 1; + int hSync_s = mode.timing.h_sync_start / 8; + int hSync_e = mode.timing.h_sync_end / 8; + int hBlank_s = hDisp_e + 1; // start of horizontal blanking + int hBlank_e = hTotal; // end of horizontal blanking + + int vTotal = mode.timing.v_total - 2; + int vDisp_e = mode.timing.v_display - 1; + int vSync_s = mode.timing.v_sync_start; + int vSync_e = mode.timing.v_sync_end; + int vBlank_s = vDisp_e; // start of vertical blanking + int vBlank_e = vTotal; // end of vertical blanking + + uint16 offset = mode.bytesPerRow / 8; + + // CRTC Controller values + + uint8 crtc[25]; + crtc[0x00] = hTotal; + crtc[0x01] = hDisp_e; + crtc[0x02] = hBlank_s; + crtc[0x03] = (hBlank_e & 0x1f) | 0x80; + crtc[0x04] = hSync_s; + crtc[0x05] = ((hSync_e & 0x1f) | ((hBlank_e & 0x20) << 2)); + crtc[0x06] = vTotal; + crtc[0x07] = (((vTotal & 0x100) >> 8) + | ((vDisp_e & 0x100) >> 7) + | ((vSync_s & 0x100) >> 6) + | ((vBlank_s & 0x100) >> 5) + | 0x10 + | ((vTotal & 0x200) >> 4) + | ((vDisp_e & 0x200) >> 3) + | ((vSync_s & 0x200) >> 2)); + + crtc[0x08] = 0x00; + crtc[0x09] = ((vBlank_s & 0x200) >> 4) | 0x40; + crtc[0x0a] = 0x00; + crtc[0x0b] = 0x00; + crtc[0x0c] = 0x00; + crtc[0x0d] = 0x00; + crtc[0x0e] = 0x00; + crtc[0x0f] = 0x00; + crtc[0x10] = vSync_s; + crtc[0x11] = (vSync_e & 0x0f) | 0x20; + crtc[0x12] = vDisp_e; + crtc[0x13] = offset; + crtc[0x14] = 0x00; + crtc[0x15] = vBlank_s; + crtc[0x16] = vBlank_e; + crtc[0x17] = 0xc3; + crtc[0x18] = 0xff; + + // Set the standard CRTC vga regs; however, before setting them, unlock + // CRTC reg's 0-7 by clearing bit 7 of cr11 + + WriteCrtcReg(0x11, crtc[0x11] & ~0x80); + + for (uint8 j = 0; j <= 0x18; j++) + WriteCrtcReg(j, crtc[j]); + + // Set the extended CRTC reg's. + + WriteCrtcReg(EXT_VERT_TOTAL, vTotal >> 8); + WriteCrtcReg(EXT_VERT_DISPLAY, vDisp_e >> 8); + WriteCrtcReg(EXT_VERT_SYNC_START, vSync_s >> 8); + WriteCrtcReg(EXT_VERT_BLANK_START, vBlank_s >> 8); + WriteCrtcReg(EXT_HORIZ_TOTAL, hTotal >> 8); + WriteCrtcReg(EXT_HORIZ_BLANK, (hBlank_e & 0x40) >> 6); + WriteCrtcReg(EXT_OFFSET, offset >> 8); + + WriteCrtcReg(INTERLACE_CNTL, INTERLACE_DISABLE); // turn off interlace + + // Enable high resolution mode. + WriteCrtcReg(IO_CTNL, ReadCrtcReg(IO_CTNL) | EXTENDED_CRTC_CNTL); +} + + +status_t +I810_SetDisplayMode(const DisplayModeEx& mode) +{ + if (mode.bitsPerPixel != 8 && mode.bitsPerPixel != 16) { + // Only 8 & 16 bits/pixel are suppoted. + TRACE("Unsupported color depth: %d bpp\n", mode.bitsPerPixel); + return B_ERROR; + } + + snooze(50000); + + // Turn off DRAM refresh. + uint8 temp = INREG8(DRAM_ROW_CNTL_HI) & ~DRAM_REFRESH_RATE; + OUTREG8(DRAM_ROW_CNTL_HI, temp | DRAM_REFRESH_DISABLE); + + snooze(1000); // wait 1 ms + + // Calculate the VCLK that most closely matches the requested pixel clock, + // and then set the M, N, and P values. + + uint16 m, n, p; + CalcVCLK(mode.timing.pixel_clock / 1000.0, m, n, p); + + OUTREG16(VCLK2_VCO_M, m); + OUTREG16(VCLK2_VCO_N, n); + OUTREG8(VCLK2_VCO_DIV_SEL, p); + + // Setup HSYNC & VSYNC polarity and select clock source 2 (0x08) for + // programmable PLL. + + uint8 miscOutReg = 0x08 | 0x01; + if (!(mode.timing.flags & B_POSITIVE_HSYNC)) + miscOutReg |= 0x40; + if (!(mode.timing.flags & B_POSITIVE_VSYNC)) + miscOutReg |= 0x80; + + OUTREG8(MISC_OUT_W, miscOutReg); + + SetCrtcTimingValues(mode); + + OUTREG32(MEM_MODE, INREG32(MEM_MODE) | 4); + + // Set the address mapping to use the frame buffer memory mapped via the + // GTT table instead of the VGA buffer. + + uint8 addrMapping = ReadGraphReg(ADDRESS_MAPPING); + addrMapping &= 0xE0; // preserve reserved bits 7:5 + addrMapping |= (GTT_MEM_MAP_ENABLE | LINEAR_MODE_ENABLE); + WriteGraphReg(ADDRESS_MAPPING, addrMapping); + + // Turn on DRAM refresh. + temp = INREG8(DRAM_ROW_CNTL_HI) & ~DRAM_REFRESH_RATE; + OUTREG8(DRAM_ROW_CNTL_HI, temp | DRAM_REFRESH_60HZ); + + temp = INREG8(BITBLT_CNTL) & ~COLEXP_MODE; + temp |= (mode.bitsPerPixel == 8 ? COLEXP_8BPP : COLEXP_16BPP); + OUTREG8(BITBLT_CNTL, temp); + + // Turn on 8 bit dac mode so that the indexed colors are displayed properly, + // and put display in high resolution mode. + + uint32 temp32 = INREG32(PIXPIPE_CONFIG) & 0xF3E062FC; + temp32 |= (DAC_8_BIT | HIRES_MODE | NO_BLANK_DELAY | + (mode.bitsPerPixel == 8 ? DISPLAY_8BPP_MODE : DISPLAY_16BPP_MODE)); + OUTREG32(PIXPIPE_CONFIG, temp32); + + OUTREG16(EIR, 0); + + temp32 = INREG32(FWATER_BLC); + temp32 &= ~(LM_BURST_LENGTH | LM_FIFO_WATERMARK | + MM_BURST_LENGTH | MM_FIFO_WATERMARK); + temp32 |= I810_GetWatermark(mode); + OUTREG32(FWATER_BLC, temp32); + + // Enable high resolution mode. + WriteCrtcReg(IO_CTNL, ReadCrtcReg(IO_CTNL) | EXTENDED_CRTC_CNTL); + + I810_AdjustFrame(mode); + return B_OK; +} + + +void +I810_AdjustFrame(const DisplayModeEx& mode) +{ + // Adjust start address in frame buffer. + + uint32 address = ((mode.v_display_start * mode.virtual_width + + mode.h_display_start) * mode.bytesPerPixel) >> 2; + + WriteCrtcReg(START_ADDR_LO, address & 0xff); + WriteCrtcReg(START_ADDR_HI, (address >> 8) & 0xff); + WriteCrtcReg(EXT_START_ADDR_HI, (address >> 22) & 0xff); + WriteCrtcReg(EXT_START_ADDR, + ((address >> 16) & 0x3f) | EXT_START_ADDR_ENABLE); +} + + +void +I810_SetIndexedColors(uint count, uint8 first, uint8* colorData, uint32 flags) +{ + // Set the indexed color palette for 8-bit color depth mode. + + (void)flags; // avoid compiler warning for unused arg + + if (gInfo.sharedInfo->displayMode.space != B_CMAP8) + return ; + + OUTREG8(DAC_MASK, 0xff); + OUTREG8(DAC_W_INDEX, first); // initial color index + + while (count--) { + OUTREG8(DAC_DATA, colorData[0]); // red + OUTREG8(DAC_DATA, colorData[1]); // green + OUTREG8(DAC_DATA, colorData[2]); // blue + + colorData += 3; + } +} diff --git a/src/add-ons/accelerants/intel_810/i810_regs.h b/src/add-ons/accelerants/intel_810/i810_regs.h new file mode 100644 index 0000000000..61ddc91d02 --- /dev/null +++ b/src/add-ons/accelerants/intel_810/i810_regs.h @@ -0,0 +1,163 @@ +/* + * Copyright 2012 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT license. + * + * Authors: + * Gerald Zajac + */ + +/*! + Haiku Intel-810 video driver was adapted from the X.org intel driver which + has the following copyright. + + Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. + All Rights Reserved. + */ + +#ifndef __I810_REGS_H__ +#define __I810_REGS_H__ + + +// CRT Controller Registers. +#define START_ADDR_HI 0x0C +#define START_ADDR_LO 0x0D +#define VERT_SYNC_END 0x11 +#define EXT_VERT_TOTAL 0x30 +#define EXT_VERT_DISPLAY 0x31 +#define EXT_VERT_SYNC_START 0x32 +#define EXT_VERT_BLANK_START 0x33 +#define EXT_HORIZ_TOTAL 0x35 +#define EXT_HORIZ_BLANK 0x39 +#define EXT_START_ADDR 0x40 +#define EXT_START_ADDR_ENABLE 0x80 +#define EXT_OFFSET 0x41 +#define EXT_START_ADDR_HI 0x42 +#define INTERLACE_CNTL 0x70 +#define INTERLACE_ENABLE 0x80 +#define INTERLACE_DISABLE 0x00 + +// CR80 - IO Control +#define IO_CTNL 0x80 +#define EXTENDED_ATTR_CNTL 0x02 +#define EXTENDED_CRTC_CNTL 0x01 + +// GR10 - Address mapping +#define ADDRESS_MAPPING 0x10 +#define PAGE_TO_LOCAL_MEM_ENABLE 0x10 +#define GTT_MEM_MAP_ENABLE 0x08 +#define PACKED_MODE_ENABLE 0x04 +#define LINEAR_MODE_ENABLE 0x02 +#define PAGE_MAPPING_ENABLE 0x01 + +#define FENCE 0x2000 + +#define INST_DONE 0x2090 + +// General error reporting regs. +#define EIR 0x20B0 +#define EMR 0x20B4 +#define ESR 0x20B8 + +// FIFO Watermark and Burst Length Control Register. +#define FWATER_BLC 0x20d8 +#define MM_BURST_LENGTH 0x00700000 +#define MM_FIFO_WATERMARK 0x0001F000 +#define LM_BURST_LENGTH 0x00000700 +#define LM_FIFO_WATERMARK 0x0000001F + +#define MEM_MODE 0x020DC + +#define DRAM_ROW_CNTL_HI 0x3002 +#define DRAM_REFRESH_RATE 0x18 +#define DRAM_REFRESH_DISABLE 0x00 +#define DRAM_REFRESH_60HZ 0x08 + +#define VCLK2_VCO_M 0x6008 +#define VCLK2_VCO_N 0x600a +#define VCLK2_VCO_DIV_SEL 0x6012 + +#define PIXPIPE_CONFIG 0x70008 +#define NO_BLANK_DELAY 0x100000 +#define DISPLAY_8BPP_MODE 0x020000 +#define DISPLAY_15BPP_MODE 0x040000 +#define DISPLAY_16BPP_MODE 0x050000 +#define DAC_8_BIT 0x008000 +#define HIRES_MODE 0x000001 + +// Blitter control. +#define BITBLT_CNTL 0x7000c +#define COLEXP_MODE 0x30 +#define COLEXP_8BPP 0x00 +#define COLEXP_16BPP 0x10 + +// Color Palette Registers. +#define DAC_MASK 0x3C6 +#define DAC_W_INDEX 0x3C8 +#define DAC_DATA 0x3C9 + + +#define MISC_OUT_R 0x3CC // read +#define MISC_OUT_W 0x3C2 // write +#define SEQ_INDEX 0x3C4 +#define SEQ_DATA 0x3C5 +#define GRAPH_INDEX 0x3CE +#define GRAPH_DATA 0x3CF +#define CRTC_INDEX 0x3D4 +#define CRTC_DATA 0x3D5 + + +// Macros for memory mapped I/O. +//============================== + +#define INREG8(addr) (*((vuint8*)(gInfo.regs + (addr)))) +#define INREG16(addr) (*((vuint16*)(gInfo.regs + (addr)))) +#define INREG32(addr) (*((vuint32*)(gInfo.regs + (addr)))) + +#define OUTREG8(addr, val) (*((vuint8*)(gInfo.regs + (addr))) = (val)) +#define OUTREG16(addr, val) (*((vuint16*)(gInfo.regs + (addr))) = (val)) +#define OUTREG32(addr, val) (*((vuint32*)(gInfo.regs + (addr))) = (val)) + +// Write a value to an 32-bit reg using a mask. The mask selects the +// bits to be modified. +#define OUTREGM(addr, value, mask) \ + (OUTREG(addr, (INREG(addr) & ~mask) | (value & mask))) + + +static inline uint8 ReadCrtcReg(uint8 index) +{ + OUTREG8(CRTC_INDEX, index); + return INREG8(CRTC_DATA); +} + +static inline void WriteCrtcReg(uint8 index, uint8 value) +{ + OUTREG8(CRTC_INDEX, index); + OUTREG8(CRTC_DATA, value); +} + +static inline uint8 ReadGraphReg(uint8 index) +{ + OUTREG8(GRAPH_INDEX, index); + return INREG8(GRAPH_DATA); +} + +static inline void WriteGraphReg(uint8 index, uint8 value) +{ + OUTREG8(GRAPH_INDEX, index); + OUTREG8(GRAPH_DATA, value); +} + +static inline uint8 ReadSeqReg(uint8 index) +{ + OUTREG8(SEQ_INDEX, index); + return INREG8(SEQ_DATA); +} + +static inline void WriteSeqReg(uint8 index, uint8 value) +{ + OUTREG8(SEQ_INDEX, index); + OUTREG8(SEQ_DATA, value); +} + + +#endif // __I810_REGS_H__ diff --git a/src/add-ons/accelerants/intel_810/i810_watermark.cpp b/src/add-ons/accelerants/intel_810/i810_watermark.cpp new file mode 100644 index 0000000000..8d0cb1d064 --- /dev/null +++ b/src/add-ons/accelerants/intel_810/i810_watermark.cpp @@ -0,0 +1,143 @@ +/* + * Copyright 2012 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT license. + * + * Authors: + * Gerald Zajac + */ + +// The code in this file was adapted from the X.org intel driver which had +// the following copyright and license. + +/************************************************************************** +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +**************************************************************************/ + +#include "accelerant.h" + + +struct WatermarkInfo { + double freq; + uint32 watermark; +}; + +static WatermarkInfo watermarks_8[] = { + { 0, 0x22003000}, + {25.2, 0x22003000}, + {28.0, 0x22003000}, + {31.5, 0x22003000}, + {36.0, 0x22007000}, + {40.0, 0x22007000}, + {45.0, 0x22007000}, + {49.5, 0x22008000}, + {50.0, 0x22008000}, + {56.3, 0x22008000}, + {65.0, 0x22008000}, + {75.0, 0x22008000}, + {78.8, 0x22008000}, + {80.0, 0x22008000}, + {94.0, 0x22008000}, + {96.0, 0x22107000}, + {99.0, 0x22107000}, + {108.0, 0x22107000}, + {121.0, 0x22107000}, + {128.9, 0x22107000}, + {132.0, 0x22109000}, + {135.0, 0x22109000}, + {157.5, 0x2210b000}, + {162.0, 0x2210b000}, + {175.5, 0x2210b000}, + {189.0, 0x2220e000}, + {202.5, 0x2220e000} +}; + +static WatermarkInfo watermarks_16[] = { + { 0, 0x22004000}, + {25.2, 0x22006000}, + {28.0, 0x22006000}, + {31.5, 0x22007000}, + {36.0, 0x22007000}, + {40.0, 0x22007000}, + {45.0, 0x22007000}, + {49.5, 0x22009000}, + {50.0, 0x22009000}, + {56.3, 0x22108000}, + {65.0, 0x2210e000}, + {75.0, 0x2210e000}, + {78.8, 0x2210e000}, + {80.0, 0x22210000}, + {94.5, 0x22210000}, + {96.0, 0x22210000}, + {99.0, 0x22210000}, + {108.0, 0x22210000}, + {121.0, 0x22210000}, + {128.9, 0x22210000}, + {132.0, 0x22314000}, + {135.0, 0x22314000}, + {157.5, 0x22415000}, + {162.0, 0x22416000}, + {175.5, 0x22416000}, + {189.0, 0x22416000}, + {195.0, 0x22416000}, + {202.5, 0x22416000} +}; + + + +uint32 +I810_GetWatermark(const DisplayModeEx& mode) +{ + WatermarkInfo *table; + uint32 tableLen; + + // Get burst length and FIFO watermark based upon the bus frequency and + // pixel clock. + + switch (mode.bitsPerPixel) { + case 8: + table = watermarks_8; + tableLen = ARRAY_SIZE(watermarks_8); + break; + case 16: + table = watermarks_16; + tableLen = ARRAY_SIZE(watermarks_16); + break; + default: + return 0; + } + + uint32 i; + double clockFreq = mode.timing.pixel_clock / 1000.0; + + for (i = 0; i < tableLen && table[i].freq < clockFreq; i++) + ; + + if (i == tableLen) + i--; + + TRACE("chosen watermark 0x%lx (freq %f)\n", table[i].watermark, + table[i].freq); + + return table[i].watermark; +} diff --git a/src/add-ons/accelerants/intel_810/mode.cpp b/src/add-ons/accelerants/intel_810/mode.cpp new file mode 100644 index 0000000000..9f95ccca40 --- /dev/null +++ b/src/add-ons/accelerants/intel_810/mode.cpp @@ -0,0 +1,339 @@ +/* + * Copyright 2007-2012 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT license. + + * Authors: + * Gerald Zajac + */ + +#include "accelerant.h" + +#include // common accelerant header file +#include +#include + + + +static bool +IsThereEnoughFBMemory(const display_mode* mode, uint32 bitsPerPixel) +{ + // Test if there is enough Frame Buffer memory for the mode and color depth + // specified by the caller, and return true if there is sufficient memory. + + uint32 maxWidth = mode->virtual_width; + if (mode->timing.h_display > maxWidth) + maxWidth = mode->timing.h_display; + + uint32 maxHeight = mode->virtual_height; + if (mode->timing.v_display > maxHeight) + maxHeight = mode->timing.v_display; + + uint32 bytesPerPixel = (bitsPerPixel + 7) / 8; + + return (maxWidth * maxHeight * bytesPerPixel + <= gInfo.sharedInfo->maxFrameBufferSize); +} + + + +bool +IsModeUsable(const display_mode* mode) +{ + // Test if the display mode is usable by the current video chip. That is, + // does the chip have enough memory for the mode and is the pixel clock + // within the chips allowable range, etc. + // + // Return true if the mode is usable. + + SharedInfo& si = *gInfo.sharedInfo; + uint8 bitsPerPixel; + uint32 maxPixelClock; + + if (!I810_GetColorSpaceParams(mode->space, bitsPerPixel, maxPixelClock)) + return false; + + // Is there enough frame buffer memory to handle the mode? + + if (!IsThereEnoughFBMemory(mode, bitsPerPixel)) + return false; + + if (mode->timing.pixel_clock > maxPixelClock) + return false; + + // Is the color space supported? + + bool colorSpaceSupported = false; + for (uint32 j = 0; j < si.colorSpaceCount; j++) { + if (mode->space == uint32(si.colorSpaces[j])) { + colorSpaceSupported = true; + break; + } + } + + if (!colorSpaceSupported) + return false; + + // Reject modes with a width of 640 and a height < 480 since they do not + // work properly with the i810 chipsets. + + if (mode->timing.h_display == 640 && mode->timing.v_display < 480) + return false; + + return true; +} + + +status_t +CreateModeList(bool (*checkMode)(const display_mode* mode)) +{ + SharedInfo& si = *gInfo.sharedInfo; + + // Obtain EDID info which is needed for for building the mode list. + + si.bHaveEDID = false; + + if (!si.bHaveEDID) { + edid1_raw rawEdid; // raw EDID info to obtain + + if (ioctl(gInfo.deviceFileDesc, INTEL_GET_EDID, &rawEdid, + sizeof(rawEdid)) == B_OK) { + if (rawEdid.version.version != 1 || rawEdid.version.revision > 4) { + TRACE("CreateModeList(); EDID version %d.%d out of range\n", + rawEdid.version.version, rawEdid.version.revision); + } else { + edid_decode(&si.edidInfo, &rawEdid); // decode & save EDID info + si.bHaveEDID = true; + } + } + + if (si.bHaveEDID) { +#ifdef ENABLE_DEBUG_TRACE + edid_dump(&(si.edidInfo)); +#endif + } else { + TRACE("CreateModeList(); Unable to get EDID info\n"); + } + } + + display_mode* list; + uint32 count = 0; + area_id listArea; + + listArea = create_display_modes("i810 modes", + si.bHaveEDID ? &si.edidInfo : NULL, + NULL, 0, si.colorSpaces, si.colorSpaceCount, + (check_display_mode_hook)checkMode, &list, &count); + + if (listArea < 0) + return listArea; // listArea has error code + + si.modeArea = gInfo.modeListArea = listArea; + si.modeCount = count; + gInfo.modeList = list; + return B_OK; +} + + + +status_t +ProposeDisplayMode(display_mode* target, const display_mode* low, + const display_mode* high) +{ + (void)low; // avoid compiler warning for unused arg + (void)high; // avoid compiler warning for unused arg + + TRACE("ProposeDisplayMode() %dx%d, pixel clock: %d kHz, space: 0x%X\n", + target->timing.h_display, target->timing.v_display, + target->timing.pixel_clock, target->space); + + // Search the mode list for the specified mode. + + uint32 modeCount = gInfo.sharedInfo->modeCount; + + for (uint32 j = 0; j < modeCount; j++) { + display_mode& mode = gInfo.modeList[j]; + + if (target->timing.h_display == mode.timing.h_display + && target->timing.v_display == mode.timing.v_display + && target->space == mode.space) + return B_OK; // mode found in list + } + + return B_BAD_VALUE; // mode not found in list +} + + +status_t +SetDisplayMode(display_mode* pMode) +{ + // First validate the mode, then call a function to set the registers. + + TRACE("SetDisplayMode() begin\n"); + + SharedInfo& si = *gInfo.sharedInfo; + DisplayModeEx mode; + (display_mode&)mode = *pMode; + + uint32 maxPixelClock; + if (!I810_GetColorSpaceParams(mode.space, mode.bitsPerPixel, maxPixelClock)) + return B_BAD_VALUE; + + if (ProposeDisplayMode(&mode, pMode, pMode) != B_OK) + return B_BAD_VALUE; + + mode.bytesPerPixel = (mode.bitsPerPixel + 7) / 8; + mode.bytesPerRow = mode.timing.h_display * mode.bytesPerPixel; + + // Is there enough frame buffer memory for this mode? + + if ( ! IsThereEnoughFBMemory(&mode, mode.bitsPerPixel)) + return B_NO_MEMORY; + + TRACE("Set display mode: %dx%d virtual size: %dx%d " + "color depth: %d bits/pixel\n", + mode.timing.h_display, mode.timing.v_display, + mode.virtual_width, mode.virtual_height, mode.bitsPerPixel); + + TRACE(" mode timing: %d %d %d %d %d %d %d %d %d\n", + mode.timing.pixel_clock, + mode.timing.h_display, + mode.timing.h_sync_start, mode.timing.h_sync_end, + mode.timing.h_total, + mode.timing.v_display, + mode.timing.v_sync_start, mode.timing.v_sync_end, + mode.timing.v_total); + + TRACE(" mode hFreq: %.1f kHz vFreq: %.1f Hz %chSync %cvSync\n", + double(mode.timing.pixel_clock) / mode.timing.h_total, + ((double(mode.timing.pixel_clock) / mode.timing.h_total) * 1000.0) + / mode.timing.v_total, + (mode.timing.flags & B_POSITIVE_HSYNC) ? '+' : '-', + (mode.timing.flags & B_POSITIVE_VSYNC) ? '+' : '-'); + + status_t status = I810_SetDisplayMode(mode); + if (status != B_OK) { + TRACE("SetDisplayMode() failed; status 0x%x\n", status); + return status; + } + + si.displayMode = mode; + + TRACE("SetDisplayMode() done\n"); + return B_OK; +} + + + +status_t +MoveDisplay(uint16 horizontalStart, uint16 verticalStart) +{ + // Set which pixel of the virtual frame buffer will show up in the + // top left corner of the display device. Used for page-flipping + // games and virtual desktops. + + DisplayModeEx& mode = gInfo.sharedInfo->displayMode; + + if (mode.timing.h_display + horizontalStart > mode.virtual_width + || mode.timing.v_display + verticalStart > mode.virtual_height) + return B_ERROR; + + mode.h_display_start = horizontalStart; + mode.v_display_start = verticalStart; + + I810_AdjustFrame(mode); + return B_OK; +} + + +uint32 +AccelerantModeCount(void) +{ + // Return the number of display modes in the mode list. + + return gInfo.sharedInfo->modeCount; +} + + +status_t +GetModeList(display_mode* dmList) +{ + // Copy the list of supported video modes to the location pointed at + // by dmList. + + memcpy(dmList, gInfo.modeList, + gInfo.sharedInfo->modeCount * sizeof(display_mode)); + return B_OK; +} + + +status_t +GetDisplayMode(display_mode* current_mode) +{ + *current_mode = gInfo.sharedInfo->displayMode; // return current display mode + return B_OK; +} + + +status_t +GetFrameBufferConfig(frame_buffer_config* pFBC) +{ + SharedInfo& si = *gInfo.sharedInfo; + + pFBC->frame_buffer = (void*)((addr_t)(si.videoMemAddr)); + pFBC->frame_buffer_dma = (void*)((addr_t)(si.videoMemPCI)); + pFBC->bytes_per_row = si.displayMode.virtual_width + * si.displayMode.bytesPerPixel; + + return B_OK; +} + + +status_t +GetPixelClockLimits(display_mode* mode, uint32* low, uint32* high) +{ + // Return the maximum and minium pixel clock limits for the specified mode. + + uint8 bitsPerPixel; + uint32 maxPixelClock; + + if (!I810_GetColorSpaceParams(mode->space, bitsPerPixel, maxPixelClock)) + return B_ERROR; + + if (low != NULL) { + // lower limit of about 48Hz vertical refresh + uint32 totalClocks = (uint32)mode->timing.h_total + * (uint32)mode->timing.v_total; + uint32 lowClock = (totalClocks * 48L) / 1000L; + if (lowClock > maxPixelClock) + return B_ERROR; + + *low = lowClock; + } + + if (high != NULL) + *high = maxPixelClock; + + return B_OK; +} + + + +#ifdef __HAIKU__ + +status_t +GetEdidInfo(void* info, size_t size, uint32* _version) +{ + SharedInfo& si = *gInfo.sharedInfo; + + if ( ! si.bHaveEDID) + return B_ERROR; + + if (size < sizeof(struct edid1_info)) + return B_BUFFER_OVERFLOW; + + memcpy(info, &si.edidInfo, sizeof(struct edid1_info)); + *_version = EDID_VERSION_1; + return B_OK; +} + +#endif // __HAIKU__ diff --git a/src/add-ons/kernel/drivers/graphics/Jamfile b/src/add-ons/kernel/drivers/graphics/Jamfile index 79e0815728..83781eb4bb 100644 --- a/src/add-ons/kernel/drivers/graphics/Jamfile +++ b/src/add-ons/kernel/drivers/graphics/Jamfile @@ -4,6 +4,7 @@ SubInclude HAIKU_TOP src add-ons kernel drivers graphics 3dfx ; SubInclude HAIKU_TOP src add-ons kernel drivers graphics ati ; SubInclude HAIKU_TOP src add-ons kernel drivers graphics common ; SubInclude HAIKU_TOP src add-ons kernel drivers graphics et6x00 ; +SubInclude HAIKU_TOP src add-ons kernel drivers graphics intel_810 ; SubInclude HAIKU_TOP src add-ons kernel drivers graphics intel_extreme ; SubInclude HAIKU_TOP src add-ons kernel drivers graphics matrox ; SubInclude HAIKU_TOP src add-ons kernel drivers graphics neomagic ; diff --git a/src/add-ons/kernel/drivers/graphics/intel_810/Jamfile b/src/add-ons/kernel/drivers/graphics/intel_810/Jamfile new file mode 100644 index 0000000000..b11837359d --- /dev/null +++ b/src/add-ons/kernel/drivers/graphics/intel_810/Jamfile @@ -0,0 +1,9 @@ +SubDir HAIKU_TOP src add-ons kernel drivers graphics intel_810 ; + +UsePrivateHeaders [ FDirName graphics intel_810 ] ; +UsePrivateHeaders [ FDirName graphics common ] ; +UsePrivateHeaders graphics kernel ; + +KernelAddon intel_810 : + driver.cpp +; diff --git a/src/add-ons/kernel/drivers/graphics/intel_810/driver.cpp b/src/add-ons/kernel/drivers/graphics/intel_810/driver.cpp new file mode 100644 index 0000000000..f411ae7194 --- /dev/null +++ b/src/add-ons/kernel/drivers/graphics/intel_810/driver.cpp @@ -0,0 +1,674 @@ +/* + * Copyright 2007-2012 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT license. + * + * Authors: + * Gerald Zajac + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "DriverInterface.h" + + +#undef TRACE + +#ifdef ENABLE_DEBUG_TRACE +# define TRACE(x...) dprintf("i810: " x) +#else +# define TRACE(x...) ; +#endif + + +#define ACCELERANT_NAME "intel_810.accelerant" + +#define ROUND_TO_PAGE_SIZE(x) (((x) + (B_PAGE_SIZE) - 1) & ~((B_PAGE_SIZE) - 1)) + +#define MAX_DEVICES 4 +#define DEVICE_FORMAT "%04X_%04X_%02X%02X%02X" + +#define VENDOR_ID 0x8086 // Intel vendor ID + + +struct ChipInfo { + uint16 chipID; // PCI device id of the chip + const char* chipName; // user recognizable name (must be < 32 chars) +}; + + +// This table maps a PCI device ID to a chip type identifier and the chip name. + +static const ChipInfo chipTable[] = { + { 0x7121, "i810" }, + { 0x7123, "i810-dc100" }, + { 0x7125, "i810e" }, + { 0x1132, "i815" }, + { 0, NULL } +}; + + +struct DeviceInfo { + uint32 openCount; // count of how many times device has been opened + int32 flags; + area_id sharedArea; // area shared between driver and accelerants + SharedInfo* sharedInfo; // pointer to shared info area memory + vuint8* regs; // pointer to memory mapped registers + const ChipInfo* pChipInfo; // info about the selected chip + pci_info pciInfo; // copy of pci info for this device + area_id gttArea; // area used for GTT + addr_t gttAddr; // virtual address of GTT + char name[B_OS_NAME_LENGTH]; // name of device +}; + + +static Benaphore gLock; +static DeviceInfo gDeviceInfo[MAX_DEVICES]; +static char* gDeviceNames[MAX_DEVICES + 1]; +static pci_module_info* gPCI; + + +// Prototypes for device hook functions. + +static status_t device_open(const char* name, uint32 flags, void** cookie); +static status_t device_close(void* dev); +static status_t device_free(void* dev); +static status_t device_read(void* dev, off_t pos, void* buf, size_t* len); +static status_t device_write(void* dev, off_t pos, const void* buf, + size_t* len); +static status_t device_ioctl(void* dev, uint32 msg, void* buf, size_t len); + +static device_hooks gDeviceHooks = +{ + device_open, + device_close, + device_free, + device_ioctl, + device_read, + device_write, + NULL, + NULL, + NULL, + NULL +}; + + + +// Video chip register definitions. +//================================= + +#define INTERRUPT_ENABLED 0x020a0 +#define INTERRUPT_MASK 0x020a8 + +// Graphics address translation table. +#define PAGE_TABLE_CONTROL 0x02020 +#define PAGE_TABLE_ENABLED 0x01 + +#define PTE_BASE 0x10000 +#define PTE_VALID 0x01 + + +// Macros for memory mapped I/O. +//============================== + +#define INREG16(addr) (*((vuint16*)(di.regs + (addr)))) +#define INREG32(addr) (*((vuint32*)(di.regs + (addr)))) + +#define OUTREG16(addr, val) (*((vuint16*)(di.regs + (addr))) = (val)) +#define OUTREG32(addr, val) (*((vuint32*)(di.regs + (addr))) = (val)) + + + +static inline uint32 +GetPCI(pci_info& info, uint8 offset, uint8 size) +{ + return gPCI->read_pci_config(info.bus, info.device, info.function, offset, + size); +} + + +static inline void +SetPCI(pci_info& info, uint8 offset, uint8 size, uint32 value) +{ + gPCI->write_pci_config(info.bus, info.device, info.function, offset, size, + value); +} + + +static status_t +GetEdidFromBIOS(edid1_raw& edidRaw) +{ + // Get the EDID info from the video BIOS, and return B_OK if successful. + +#define ADDRESS_SEGMENT(address) ((addr_t)(address) >> 4) +#define ADDRESS_OFFSET(address) ((addr_t)(address) & 0xf) + + vm86_state vmState; + + status_t status = vm86_prepare(&vmState, 0x2000); + if (status != B_OK) { + TRACE("GetEdidFromBIOS(); vm86_prepare() failed, status: 0x%lx\n", + status); + return status; + } + + vmState.regs.eax = 0x4f15; + vmState.regs.ebx = 0; // 0 = report DDC service + vmState.regs.ecx = 0; + vmState.regs.es = 0; + vmState.regs.edi = 0; + + status = vm86_do_int(&vmState, 0x10); + if (status == B_OK) { + // AH contains the error code, and AL determines wether or not the + // function is supported. + if (vmState.regs.eax != 0x4f) + status = B_NOT_SUPPORTED; + + // Test if DDC is supported by the monitor. + if ((vmState.regs.ebx & 3) == 0) + status = B_NOT_SUPPORTED; + } + + if (status == B_OK) { + // According to the author of the vm86 functions, the address of any + // object to receive data must be >= 0x1000 and within the ram size + // specified in the second argument of the vm86_prepare() call above. + // Thus, the address of the struct to receive the EDID info is set to + // 0x1000. + + edid1_raw* edid = (edid1_raw*)0x1000; + + vmState.regs.eax = 0x4f15; + vmState.regs.ebx = 1; // 1 = read EDID + vmState.regs.ecx = 0; + vmState.regs.edx = 0; + vmState.regs.es = ADDRESS_SEGMENT(edid); + vmState.regs.edi = ADDRESS_OFFSET(edid); + + status = vm86_do_int(&vmState, 0x10); + if (status == B_OK) { + if (vmState.regs.eax != 0x4f) { + status = B_NOT_SUPPORTED; + } else { + // Copy the EDID info to the caller's location, and compute the + // checksum of the EDID info while copying. + + uint8 sum = 0; + uint8 allOr = 0; + uint8* dest = (uint8*)&edidRaw; + uint8* src = (uint8*)edid; + + for (uint32 j = 0; j < sizeof(edidRaw); j++) { + sum += *src; + allOr |= *src; + *dest++ = *src++; + } + + if (allOr == 0) { + TRACE("GetEdidFromBIOS(); EDID info contains only zeros\n"); + status = B_ERROR; + } else if (sum != 0) { + TRACE("GetEdidFromBIOS(); Checksum error in EDID info\n"); + status = B_ERROR; + } + } + } + } + + vm86_cleanup(&vmState); + + TRACE("GetEdidFromBIOS() status: 0x%lx\n", status); + return status; +} + + +static status_t +InitDevice(DeviceInfo& di) +{ + // Perform initialization and mapping of the device, and return B_OK if + // sucessful; else, return error code. + + TRACE("enter InitDevice()\n"); + + // Create the area for shared info with NO user-space read or write + // permissions, to prevent accidental damage. + + size_t sharedSize = (sizeof(SharedInfo) + 7) & ~7; + + di.sharedArea = create_area("i810 shared info", + (void**) &(di.sharedInfo), + B_ANY_KERNEL_ADDRESS, + ROUND_TO_PAGE_SIZE(sharedSize), + B_FULL_LOCK, 0); + if (di.sharedArea < 0) + return di.sharedArea; // return error code + + SharedInfo& si = *(di.sharedInfo); + memset(&si, 0, sharedSize); + si.regsArea = -1; // indicate area has not yet been created + si.videoMemArea = -1; + + pci_info& pciInfo = di.pciInfo; + + si.vendorID = pciInfo.vendor_id; + si.deviceID = pciInfo.device_id; + si.revision = pciInfo.revision; + strcpy(si.chipName, di.pChipInfo->chipName); + + // Enable memory mapped IO and bus master. + + SetPCI(pciInfo, PCI_command, 2, GetPCI(pciInfo, PCI_command, 2) + | PCI_command_io | PCI_command_memory | PCI_command_master); + + // Map the MMIO register area. + + phys_addr_t regsBase = pciInfo.u.h0.base_registers[1]; + uint32 regAreaSize = pciInfo.u.h0.base_register_sizes[1]; + + si.regsArea = map_physical_memory("i810 mmio registers", + regsBase, + regAreaSize, + B_ANY_KERNEL_ADDRESS, + B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, + (void**)&di.regs); + + if (si.regsArea < 0) { + TRACE("Unable to map MMIO, error: 0x%lx\n", si.regsArea); + return si.regsArea; + } + + // Allocate memory for the GTT which must be 64K for the 810/815 chips. + + uint32 gttSize = 64 * 1024; + di.gttArea = create_area("GTT memory", (void**) &(di.gttAddr), + B_ANY_KERNEL_ADDRESS, gttSize, B_FULL_LOCK | B_CONTIGUOUS, + B_READ_AREA | B_WRITE_AREA); + + if (di.gttArea < B_OK) { + TRACE("Unable to create GTT, error: 0x%lx\n", di.gttArea); + return B_NO_MEMORY; + } + + memset((void*)(di.gttAddr), 0, gttSize); + + // Get the physical address of the GTT, and set GTT address in the chip. + + physical_entry entry; + status_t status = get_memory_map((void *)(di.gttAddr), + B_PAGE_SIZE, &entry, 1); + if (status < B_OK) { + TRACE("Unable to get physical address of GTT, error: 0x%lx\n", status); + return status; + } + + OUTREG32(PAGE_TABLE_CONTROL, entry.address | PAGE_TABLE_ENABLED); + INREG32(PAGE_TABLE_CONTROL); + + // Allocate video memory to be used for the frame buffer. + + si.videoMemSize = 4 * 1024 * 1024; + si.videoMemArea = create_area("video memory", (void**)&(si.videoMemAddr), + B_ANY_ADDRESS, si.videoMemSize, B_FULL_LOCK, + B_READ_AREA | B_WRITE_AREA); + if (si.videoMemArea < B_OK) { + TRACE("Unable to create video memory, error: 0x%lx\n", si.videoMemArea); + return B_NO_MEMORY; + } + + // Get the physical address of each page of the video memory, and put + // the physical address of each page into the GTT table. + + for (uint32 offset = 0; offset < si.videoMemSize; offset += B_PAGE_SIZE) { + status = get_memory_map((void *)(si.videoMemAddr + offset), + B_PAGE_SIZE, &entry, 1); + if (status < B_OK) { + TRACE("Unable to get physical address of video memory page, error:" + " 0x%lx offset: %ld\n", status, offset); + return status; + } + + if (offset == 0) + si.videoMemPCI = entry.address; + + OUTREG32(PTE_BASE + ((offset / B_PAGE_SIZE) * 4), + entry.address | PTE_VALID); + } + + TRACE("InitDevice() exit OK\n"); + return B_OK; +} + + +static void +DeleteAreas(DeviceInfo& di) +{ + // Delete all areas that were created. + + if (di.sharedArea >= 0 && di.sharedInfo != NULL) { + SharedInfo& si = *(di.sharedInfo); + if (si.regsArea >= 0) + delete_area(si.regsArea); + if (si.videoMemArea >= 0) + delete_area(si.videoMemArea); + } + + if (di.gttArea >= 0) + delete_area(di.gttArea); + di.gttArea = -1; + di.gttAddr = (addr_t)NULL; + + if (di.sharedArea >= 0) + delete_area(di.sharedArea); + di.sharedArea = -1; + di.sharedInfo = NULL; +} + + +static const ChipInfo* +GetNextSupportedDevice(uint32& pciIndex, pci_info& pciInfo) +{ + // Search the PCI devices for a device that is supported by this driver. + // The search starts at the device specified by argument pciIndex, and + // continues until a supported device is found or there are no more devices + // to examine. Argument pciIndex is incremented after each device is + // examined. + + // If a supported device is found, return a pointer to the struct containing + // the chip info; else return NULL. + + while (gPCI->get_nth_pci_info(pciIndex, &pciInfo) == B_OK) { + + if (pciInfo.vendor_id == VENDOR_ID) { + + // Search the table of supported devices to find a chip/device that + // matches device ID of the current PCI device. + + const ChipInfo* pDevice = chipTable; + + while (pDevice->chipID != 0) { // end of table? + if (pDevice->chipID == pciInfo.device_id) + return pDevice; // matching device/chip found + + pDevice++; + } + } + + pciIndex++; + } + + return NULL; // no supported device found +} + + + +// #pragma mark - Kernel Interface + + +status_t +init_hardware(void) +{ + // Return B_OK if a device supported by this driver is found; otherwise, + // return B_ERROR so the driver will be unloaded. + + status_t status = get_module(B_PCI_MODULE_NAME, (module_info**)&gPCI); + if (status != B_OK) { + TRACE("PCI module unavailable, error 0x%lx\n", status); + return status; + } + + // Check pci devices for a device supported by this driver. + + uint32 pciIndex = 0; + pci_info pciInfo; + const ChipInfo* pDevice = GetNextSupportedDevice(pciIndex, pciInfo); + + TRACE("init_hardware() - %s\n", + pDevice == NULL ? "no supported devices" : "device supported"); + + put_module(B_PCI_MODULE_NAME); // put away the module manager + + return (pDevice == NULL ? B_ERROR : B_OK); +} + + +status_t +init_driver(void) +{ + // Get handle for the pci bus. + + status_t status = get_module(B_PCI_MODULE_NAME, (module_info**)&gPCI); + if (status != B_OK) { + TRACE("PCI module unavailable, error 0x%lx\n", status); + return status; + } + + status = gLock.Init("i810 driver lock"); + if (status < B_OK) { + put_module(B_AGP_GART_MODULE_NAME); + put_module(B_PCI_MODULE_NAME); + return status; + } + + // Get info about all the devices supported by this driver. + + uint32 pciIndex = 0; + uint32 count = 0; + + while (count < MAX_DEVICES) { + DeviceInfo& di = gDeviceInfo[count]; + + const ChipInfo* pDevice = GetNextSupportedDevice(pciIndex, di.pciInfo); + if (pDevice == NULL) + break; // all supported devices have been obtained + + // Compose device name. + sprintf(di.name, "graphics/" DEVICE_FORMAT, + di.pciInfo.vendor_id, di.pciInfo.device_id, + di.pciInfo.bus, di.pciInfo.device, di.pciInfo.function); + TRACE("init_driver() match found; name: %s\n", di.name); + + gDeviceNames[count] = di.name; + di.openCount = 0; // mark driver as available for R/W open + di.sharedArea = -1; // indicate shared area not yet created + di.sharedInfo = NULL; + di.gttArea = -1; // indicate GTT area not yet created + di.gttAddr = (addr_t)NULL; + di.pChipInfo = pDevice; + count++; + pciIndex++; + } + + gDeviceNames[count] = NULL; // terminate list with null pointer + + TRACE("init_driver() %ld supported devices\n", count); + + return B_OK; +} + + +void +uninit_driver(void) +{ + // Free the driver data. + + gLock.Delete(); + put_module(B_AGP_GART_MODULE_NAME); + put_module(B_PCI_MODULE_NAME); // put the pci module away +} + + +const char** +publish_devices(void) +{ + return (const char**)gDeviceNames; // return list of supported devices +} + + +device_hooks* +find_device(const char* name) +{ + int i = 0; + while (gDeviceNames[i] != NULL) { + if (strcmp(name, gDeviceNames[i]) == 0) + return &gDeviceHooks; + i++; + } + + return NULL; +} + + + +// #pragma mark - Device Hooks + + +static status_t +device_open(const char* name, uint32 /*flags*/, void** cookie) +{ + status_t status = B_OK; + + TRACE("device_open() - name: %s, cookie: 0x%08lx)\n", name, (uint32)cookie); + + // Find the device name in the list of devices. + + int32 i = 0; + while (gDeviceNames[i] != NULL && (strcmp(name, gDeviceNames[i]) != 0)) + i++; + + if (gDeviceNames[i] == NULL) + return B_BAD_VALUE; // device name not found in list of devices + + DeviceInfo& di = gDeviceInfo[i]; + + gLock.Acquire(); // make sure no one else has write access to common data + + if (di.openCount == 0) { + status = InitDevice(di); + if (status < B_OK) + DeleteAreas(di); // error occurred; delete any areas created + } + + gLock.Release(); + + if (status == B_OK) { + di.openCount++; // mark device open + *cookie = &di; // send cookie to opener + } + + TRACE("device_open() returning 0x%lx, open count: %ld\n", status, + di.openCount); + return status; +} + + +static status_t +device_read(void* dev, off_t pos, void* buf, size_t* len) +{ + // Following 3 lines of code are here to eliminate "unused parameter" + // warnings. + (void)dev; + (void)pos; + (void)buf; + + *len = 0; + return B_NOT_ALLOWED; +} + + +static status_t +device_write(void* dev, off_t pos, const void* buf, size_t* len) +{ + // Following 3 lines of code are here to eliminate "unused parameter" + // warnings. + (void)dev; + (void)pos; + (void)buf; + + *len = 0; + return B_NOT_ALLOWED; +} + + +static status_t +device_close(void* dev) +{ + (void)dev; // avoid compiler warning for unused arg + + TRACE("device_close()\n"); + return B_NO_ERROR; +} + + +static status_t +device_free(void* dev) +{ + DeviceInfo& di = *((DeviceInfo*)dev); + + TRACE("enter device_free()\n"); + + gLock.Acquire(); // lock driver + + // If opened multiple times, merely decrement the open count and exit. + + if (di.openCount <= 1) + DeleteAreas(di); + + if (di.openCount > 0) + di.openCount--; // mark device available + + gLock.Release(); // unlock driver + + TRACE("exit device_free() openCount: %ld\n", di.openCount); + return B_OK; +} + + +static status_t +device_ioctl(void* dev, uint32 msg, void* buffer, size_t bufferLength) +{ + DeviceInfo& di = *((DeviceInfo*)dev); + + TRACE("device_ioctl(); ioctl: %lu, buffer: 0x%08lx, bufLen: %lu\n", msg, + (uint32)buffer, bufferLength); + + switch (msg) { + case B_GET_ACCELERANT_SIGNATURE: + strcpy((char*)buffer, ACCELERANT_NAME); + TRACE("Intel 810 accelerant: %s\n", ACCELERANT_NAME); + return B_OK; + + case INTEL_DEVICE_NAME: + strncpy((char*)buffer, di.name, B_OS_NAME_LENGTH); + ((char*)buffer)[B_OS_NAME_LENGTH -1] = '\0'; + return B_OK; + + case INTEL_GET_SHARED_DATA: + if (bufferLength != sizeof(area_id)) + return B_BAD_DATA; + + *((area_id*)buffer) = di.sharedArea; + return B_OK; + + case INTEL_GET_EDID: + { + if (bufferLength != sizeof(edid1_raw)) + return B_BAD_DATA; + + edid1_raw rawEdid; + status_t status = GetEdidFromBIOS(rawEdid); + if (status == B_OK) + user_memcpy((edid1_raw*)buffer, &rawEdid, sizeof(rawEdid)); + return status; + } + } + + return B_DEV_INVALID_IOCTL; +} From 0e8316cc908c3f24496bdf57855a6dcde483b82f Mon Sep 17 00:00:00 2001 From: Alexander von Gluck IV Date: Wed, 30 May 2012 16:09:52 -0500 Subject: [PATCH 08/39] intel_810: Style cleanup. No functional change * I think the FunctionNames need to change to function_name --- .../graphics/intel_810/DriverInterface.h | 14 +++--- .../accelerants/intel_810/accelerant.cpp | 13 +++-- .../accelerants/intel_810/accelerant.h | 10 ++-- src/add-ons/accelerants/intel_810/engine.cpp | 11 +++-- src/add-ons/accelerants/intel_810/hooks.cpp | 4 +- .../accelerants/intel_810/i810_init.cpp | 3 +- .../accelerants/intel_810/i810_mode.cpp | 30 ++++++------ src/add-ons/accelerants/intel_810/i810_regs.h | 26 ++++++---- .../accelerants/intel_810/i810_watermark.cpp | 22 ++++----- src/add-ons/accelerants/intel_810/mode.cpp | 18 +++---- .../drivers/graphics/intel_810/driver.cpp | 48 +++++++++---------- 11 files changed, 97 insertions(+), 102 deletions(-) diff --git a/headers/private/graphics/intel_810/DriverInterface.h b/headers/private/graphics/intel_810/DriverInterface.h index a265aef865..1bae923655 100644 --- a/headers/private/graphics/intel_810/DriverInterface.h +++ b/headers/private/graphics/intel_810/DriverInterface.h @@ -5,7 +5,6 @@ * Authors: * Gerald Zajac */ - #ifndef DRIVERINTERFACE_H #define DRIVERINTERFACE_H @@ -23,7 +22,6 @@ #define ENABLE_DEBUG_TRACE // if defined, turns on debug output to syslog - #define ARRAY_SIZE(a) (int(sizeof(a) / sizeof(a[0]))) // get number of elements in an array @@ -81,12 +79,12 @@ struct SharedInfo { bool bAccelerantInUse; // true = accelerant has been initialized // Memory mappings. - area_id regsArea; // area_id for the memory mapped registers. It will - // be cloned into accelerant's address space. - area_id videoMemArea; // video memory area_id. Addr's shared with all teams. + area_id regsArea; // area_id for the memory mapped registers. It + // will be cloned into accelerant address space. + area_id videoMemArea; // addr shared with all teams. addr_t videoMemAddr; // virtual video memory addr phys_addr_t videoMemPCI; // physical video memory addr - uint32 videoMemSize; // video memory size in bytes (for frame buffer). + uint32 videoMemSize; // video memory size in bytes (for frame buffer) uint32 maxFrameBufferSize; // max available video memory for frame buffer @@ -95,7 +93,7 @@ struct SharedInfo { uint32 colorSpaceCount; // number of color spaces in array colorSpaces // List of screen modes. - area_id modeArea; // area containing list of display modes the driver supports + area_id modeArea; // area containing list of display modes uint32 modeCount; // number of display modes in the list DisplayModeEx displayMode; // current display mode configuration @@ -103,7 +101,7 @@ struct SharedInfo { edid1_info edidInfo; bool bHaveEDID; // true = EDID info from device is in edidInfo - Benaphore engineLock; // for serializing access to the acceleration engine + Benaphore engineLock; // serializing access to the acceleration engine }; diff --git a/src/add-ons/accelerants/intel_810/accelerant.cpp b/src/add-ons/accelerants/intel_810/accelerant.cpp index 475847c213..0d4b4959f2 100644 --- a/src/add-ons/accelerants/intel_810/accelerant.cpp +++ b/src/add-ons/accelerants/intel_810/accelerant.cpp @@ -6,6 +6,7 @@ * Gerald Zajac */ + #include "accelerant.h" #include @@ -13,7 +14,6 @@ #include - AccelerantInfo gInfo; // global data used by source files of accelerant static uint32 videoValue; @@ -32,7 +32,7 @@ SuppressArtifacts(void* dataPtr) // the video memory. This is because some artifacts still occur at the // top of the screen if the accessed memory is at the beginning of the // video memory. - + // Note that this function will reduce the general performance of a // computer somewhat, but it is much less of a hit than if double // buffering was used for the video. Base on the frame rate of the @@ -40,8 +40,7 @@ SuppressArtifacts(void* dataPtr) SharedInfo& si = *((SharedInfo*)dataPtr); - while (true) - { + while (true) { uint32* src = ((uint32*)(si.videoMemAddr)) + si.videoMemSize / 4 - 1; uint32 count = 65000; @@ -74,13 +73,13 @@ InitCommon(int fileDesc) (void**)&(gInfo.sharedInfo), B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, sharedArea); if (gInfo.sharedInfoArea < 0) - return gInfo.sharedInfoArea; // sharedInfoArea has error code + return gInfo.sharedInfoArea; // sharedInfoArea has error code gInfo.regsArea = clone_area("i810 regs area", (void**)&(gInfo.regs), B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, gInfo.sharedInfo->regsArea); if (gInfo.regsArea < 0) { delete_area(gInfo.sharedInfoArea); - return gInfo.regsArea; // regsArea has error code + return gInfo.regsArea; // regsArea has error code } return B_OK; @@ -129,7 +128,7 @@ InitAccelerant(int fileDesc) // Ensure that this function won't be executed again // (copies should be clones) si.bAccelerantInUse = true; - + thread_id threadID = spawn_thread(SuppressArtifacts, "SuppressArtifacts_Thread", B_DISPLAY_PRIORITY, gInfo.sharedInfo); diff --git a/src/add-ons/accelerants/intel_810/accelerant.h b/src/add-ons/accelerants/intel_810/accelerant.h index 9406337b60..bee07d1c02 100644 --- a/src/add-ons/accelerants/intel_810/accelerant.h +++ b/src/add-ons/accelerants/intel_810/accelerant.h @@ -5,12 +5,11 @@ * Authors: * Gerald Zajac */ - #ifndef _ACCELERANT_H #define _ACCELERANT_H -#include "DriverInterface.h" +#include "DriverInterface.h" #undef TRACE @@ -24,7 +23,6 @@ extern "C" void _sPrintf(const char* format, ...); // Global data used by various source files of the accelerant. - struct AccelerantInfo { int deviceFileDesc; // file descriptor of kernel driver @@ -48,7 +46,7 @@ extern AccelerantInfo gInfo; // the functions that are unique to a particular chip family, will be prefixed // with the name of the family, and the functions that are applicable to all // chips will have no prefix. -//================================================================ +// ================================================================ #if defined(__cplusplus) extern "C" { @@ -95,11 +93,9 @@ status_t SyncToToken(sync_token* st); #endif - // Prototypes for other functions that are called from source files other than // where they are defined. -//============================================================================ - +// ============================================================================ status_t CreateModeList(bool (*checkMode)(const display_mode* mode)); bool IsModeUsable(const display_mode* mode); diff --git a/src/add-ons/accelerants/intel_810/engine.cpp b/src/add-ons/accelerants/intel_810/engine.cpp index 87e24136fe..df2735a6af 100644 --- a/src/add-ons/accelerants/intel_810/engine.cpp +++ b/src/add-ons/accelerants/intel_810/engine.cpp @@ -6,6 +6,7 @@ * Gerald Zajac */ + #include "accelerant.h" #include "i810_regs.h" @@ -22,7 +23,7 @@ AccelerantEngineCount(void) status_t AcquireEngine(uint32 capabilities, uint32 maxWait, - sync_token* syncToken, engine_token** engineToken) + sync_token* syncToken, engine_token** engineToken) { (void)capabilities; // avoid compiler warning for unused arg (void)maxWait; // avoid compiler warning for unused arg @@ -55,9 +56,9 @@ WaitEngineIdle(void) // Wait until engine is idle. int k = 10000000; - + while ((INREG16(INST_DONE) & 0x7B) != 0x7B && k > 0) - k--; + k--; } @@ -73,9 +74,9 @@ GetSyncToken(engine_token* engineToken, sync_token* syncToken) status_t SyncToToken(sync_token* syncToken) { - (void)syncToken; // avoid compiler warning for unused arg + (void)syncToken; + // avoid compiler warning for unused arg WaitEngineIdle(); return B_OK; } - diff --git a/src/add-ons/accelerants/intel_810/hooks.cpp b/src/add-ons/accelerants/intel_810/hooks.cpp index b06a95a1b6..3bd4481301 100644 --- a/src/add-ons/accelerants/intel_810/hooks.cpp +++ b/src/add-ons/accelerants/intel_810/hooks.cpp @@ -6,13 +6,15 @@ * Gerald Zajac */ + #include "accelerant.h" extern "C" void* get_accelerant_hook(uint32 feature, void* data) { - (void)data; // avoid compiler warning for unused arg + (void)data; + // avoid compiler warning for unused arg switch (feature) { // General diff --git a/src/add-ons/accelerants/intel_810/i810_init.cpp b/src/add-ons/accelerants/intel_810/i810_init.cpp index 3c4f4c03a5..71c2714fc4 100644 --- a/src/add-ons/accelerants/intel_810/i810_init.cpp +++ b/src/add-ons/accelerants/intel_810/i810_init.cpp @@ -19,10 +19,9 @@ #include "i810_regs.h" - bool I810_GetColorSpaceParams(int colorSpace, uint8& bitsPerPixel, - uint32& maxPixelClock) + uint32& maxPixelClock) { // Get parameters for a color space which is supported by the i810 chips. // Argument maxPixelClock is in KHz. diff --git a/src/add-ons/accelerants/intel_810/i810_mode.cpp b/src/add-ons/accelerants/intel_810/i810_mode.cpp index 3c95d5f1be..a09fcb871f 100644 --- a/src/add-ons/accelerants/intel_810/i810_mode.cpp +++ b/src/add-ons/accelerants/intel_810/i810_mode.cpp @@ -14,6 +14,7 @@ All Rights Reserved. */ + #include "accelerant.h" #include "i810_regs.h" @@ -22,15 +23,14 @@ #include - // I810_CalcVCLK -- Determine closest clock frequency to the one requested. - #define MAX_VCO_FREQ 600.0 #define TARGET_MAX_N 30 #define REF_FREQ 24.0 #define CALC_VCLK(m,n,p) (double)m / ((double)n * (1 << p)) * 4 * REF_FREQ + static void CalcVCLK(double freq, uint16& clkM, uint16& clkN, uint16& clkP) { int m, n, p; @@ -65,8 +65,8 @@ CalcVCLK(double freq, uint16& clkM, uint16& clkN, uint16& clkP) { f_best = f_out; errBest = f_err; } - } while ((fabs(f_err) >= errTarget) && - ((n <= TARGET_MAX_N) || (fabs(errBest) > errMax))); + } while ((fabs(f_err) >= errTarget) && ((n <= TARGET_MAX_N) + || (fabs(errBest) > errMax))); if (fabs(f_err) < errTarget) { m_best = m; @@ -83,7 +83,7 @@ CalcVCLK(double freq, uint16& clkM, uint16& clkN, uint16& clkP) { } -static void +static void SetCrtcTimingValues(const DisplayModeEx& mode) { // Set the timing values for CRTC registers cr00 to cr18, and some extended @@ -104,7 +104,7 @@ SetCrtcTimingValues(const DisplayModeEx& mode) int vBlank_e = vTotal; // end of vertical blanking uint16 offset = mode.bytesPerRow / 8; - + // CRTC Controller values uint8 crtc[25]; @@ -151,7 +151,7 @@ SetCrtcTimingValues(const DisplayModeEx& mode) WriteCrtcReg(j, crtc[j]); // Set the extended CRTC reg's. - + WriteCrtcReg(EXT_VERT_TOTAL, vTotal >> 8); WriteCrtcReg(EXT_VERT_DISPLAY, vDisp_e >> 8); WriteCrtcReg(EXT_VERT_SYNC_START, vSync_s >> 8); @@ -161,7 +161,7 @@ SetCrtcTimingValues(const DisplayModeEx& mode) WriteCrtcReg(EXT_OFFSET, offset >> 8); WriteCrtcReg(INTERLACE_CNTL, INTERLACE_DISABLE); // turn off interlace - + // Enable high resolution mode. WriteCrtcReg(IO_CTNL, ReadCrtcReg(IO_CTNL) | EXTENDED_CRTC_CNTL); } @@ -211,7 +211,7 @@ I810_SetDisplayMode(const DisplayModeEx& mode) // Set the address mapping to use the frame buffer memory mapped via the // GTT table instead of the VGA buffer. - + uint8 addrMapping = ReadGraphReg(ADDRESS_MAPPING); addrMapping &= 0xE0; // preserve reserved bits 7:5 addrMapping |= (GTT_MEM_MAP_ENABLE | LINEAR_MODE_ENABLE); @@ -224,7 +224,7 @@ I810_SetDisplayMode(const DisplayModeEx& mode) temp = INREG8(BITBLT_CNTL) & ~COLEXP_MODE; temp |= (mode.bitsPerPixel == 8 ? COLEXP_8BPP : COLEXP_16BPP); OUTREG8(BITBLT_CNTL, temp); - + // Turn on 8 bit dac mode so that the indexed colors are displayed properly, // and put display in high resolution mode. @@ -236,15 +236,15 @@ I810_SetDisplayMode(const DisplayModeEx& mode) OUTREG16(EIR, 0); temp32 = INREG32(FWATER_BLC); - temp32 &= ~(LM_BURST_LENGTH | LM_FIFO_WATERMARK | - MM_BURST_LENGTH | MM_FIFO_WATERMARK); + temp32 &= ~(LM_BURST_LENGTH | LM_FIFO_WATERMARK + | MM_BURST_LENGTH | MM_FIFO_WATERMARK); temp32 |= I810_GetWatermark(mode); OUTREG32(FWATER_BLC, temp32); // Enable high resolution mode. WriteCrtcReg(IO_CTNL, ReadCrtcReg(IO_CTNL) | EXTENDED_CRTC_CNTL); - I810_AdjustFrame(mode); + I810_AdjustFrame(mode); return B_OK; } @@ -255,13 +255,13 @@ I810_AdjustFrame(const DisplayModeEx& mode) // Adjust start address in frame buffer. uint32 address = ((mode.v_display_start * mode.virtual_width - + mode.h_display_start) * mode.bytesPerPixel) >> 2; + + mode.h_display_start) * mode.bytesPerPixel) >> 2; WriteCrtcReg(START_ADDR_LO, address & 0xff); WriteCrtcReg(START_ADDR_HI, (address >> 8) & 0xff); WriteCrtcReg(EXT_START_ADDR_HI, (address >> 22) & 0xff); WriteCrtcReg(EXT_START_ADDR, - ((address >> 16) & 0x3f) | EXT_START_ADDR_ENABLE); + ((address >> 16) & 0x3f) | EXT_START_ADDR_ENABLE); } diff --git a/src/add-ons/accelerants/intel_810/i810_regs.h b/src/add-ons/accelerants/intel_810/i810_regs.h index 61ddc91d02..7668ffd531 100644 --- a/src/add-ons/accelerants/intel_810/i810_regs.h +++ b/src/add-ons/accelerants/intel_810/i810_regs.h @@ -13,7 +13,6 @@ Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. All Rights Reserved. */ - #ifndef __I810_REGS_H__ #define __I810_REGS_H__ @@ -29,7 +28,7 @@ #define EXT_HORIZ_TOTAL 0x35 #define EXT_HORIZ_BLANK 0x39 #define EXT_START_ADDR 0x40 -#define EXT_START_ADDR_ENABLE 0x80 +#define EXT_START_ADDR_ENABLE 0x80 #define EXT_OFFSET 0x41 #define EXT_START_ADDR_HI 0x42 #define INTERLACE_CNTL 0x70 @@ -123,37 +122,48 @@ (OUTREG(addr, (INREG(addr) & ~mask) | (value & mask))) -static inline uint8 ReadCrtcReg(uint8 index) +static inline uint8 +ReadCrtcReg(uint8 index) { OUTREG8(CRTC_INDEX, index); return INREG8(CRTC_DATA); } -static inline void WriteCrtcReg(uint8 index, uint8 value) + +static inline void +WriteCrtcReg(uint8 index, uint8 value) { OUTREG8(CRTC_INDEX, index); OUTREG8(CRTC_DATA, value); } -static inline uint8 ReadGraphReg(uint8 index) + +static inline uint8 +ReadGraphReg(uint8 index) { OUTREG8(GRAPH_INDEX, index); return INREG8(GRAPH_DATA); } -static inline void WriteGraphReg(uint8 index, uint8 value) + +static inline void +WriteGraphReg(uint8 index, uint8 value) { OUTREG8(GRAPH_INDEX, index); OUTREG8(GRAPH_DATA, value); } -static inline uint8 ReadSeqReg(uint8 index) + +static inline uint8 +ReadSeqReg(uint8 index) { OUTREG8(SEQ_INDEX, index); return INREG8(SEQ_DATA); } -static inline void WriteSeqReg(uint8 index, uint8 value) + +static inline void +WriteSeqReg(uint8 index, uint8 value) { OUTREG8(SEQ_INDEX, index); OUTREG8(SEQ_DATA, value); diff --git a/src/add-ons/accelerants/intel_810/i810_watermark.cpp b/src/add-ons/accelerants/intel_810/i810_watermark.cpp index 8d0cb1d064..cfd3399621 100644 --- a/src/add-ons/accelerants/intel_810/i810_watermark.cpp +++ b/src/add-ons/accelerants/intel_810/i810_watermark.cpp @@ -34,6 +34,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ + #include "accelerant.h" @@ -104,7 +105,6 @@ static WatermarkInfo watermarks_16[] = { }; - uint32 I810_GetWatermark(const DisplayModeEx& mode) { @@ -115,16 +115,16 @@ I810_GetWatermark(const DisplayModeEx& mode) // pixel clock. switch (mode.bitsPerPixel) { - case 8: - table = watermarks_8; - tableLen = ARRAY_SIZE(watermarks_8); - break; - case 16: - table = watermarks_16; - tableLen = ARRAY_SIZE(watermarks_16); - break; - default: - return 0; + case 8: + table = watermarks_8; + tableLen = ARRAY_SIZE(watermarks_8); + break; + case 16: + table = watermarks_16; + tableLen = ARRAY_SIZE(watermarks_16); + break; + default: + return 0; } uint32 i; diff --git a/src/add-ons/accelerants/intel_810/mode.cpp b/src/add-ons/accelerants/intel_810/mode.cpp index 9f95ccca40..f56ad1f1cb 100644 --- a/src/add-ons/accelerants/intel_810/mode.cpp +++ b/src/add-ons/accelerants/intel_810/mode.cpp @@ -1,11 +1,12 @@ /* * Copyright 2007-2012 Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT license. - + * * Authors: * Gerald Zajac */ + #include "accelerant.h" #include // common accelerant header file @@ -13,7 +14,6 @@ #include - static bool IsThereEnoughFBMemory(const display_mode* mode, uint32 bitsPerPixel) { @@ -31,11 +31,10 @@ IsThereEnoughFBMemory(const display_mode* mode, uint32 bitsPerPixel) uint32 bytesPerPixel = (bitsPerPixel + 7) / 8; return (maxWidth * maxHeight * bytesPerPixel - <= gInfo.sharedInfo->maxFrameBufferSize); + <= gInfo.sharedInfo->maxFrameBufferSize); } - bool IsModeUsable(const display_mode* mode) { @@ -101,7 +100,7 @@ CreateModeList(bool (*checkMode)(const display_mode* mode)) TRACE("CreateModeList(); EDID version %d.%d out of range\n", rawEdid.version.version, rawEdid.version.revision); } else { - edid_decode(&si.edidInfo, &rawEdid); // decode & save EDID info + edid_decode(&si.edidInfo, &rawEdid); // decode & save EDID info si.bHaveEDID = true; } } @@ -134,7 +133,6 @@ CreateModeList(bool (*checkMode)(const display_mode* mode)) } - status_t ProposeDisplayMode(display_mode* target, const display_mode* low, const display_mode* high) @@ -223,7 +221,6 @@ SetDisplayMode(display_mode* pMode) } - status_t MoveDisplay(uint16 horizontalStart, uint16 verticalStart) { @@ -269,7 +266,7 @@ GetModeList(display_mode* dmList) status_t GetDisplayMode(display_mode* current_mode) { - *current_mode = gInfo.sharedInfo->displayMode; // return current display mode + *current_mode = gInfo.sharedInfo->displayMode; // current display mode return B_OK; } @@ -281,7 +278,7 @@ GetFrameBufferConfig(frame_buffer_config* pFBC) pFBC->frame_buffer = (void*)((addr_t)(si.videoMemAddr)); pFBC->frame_buffer_dma = (void*)((addr_t)(si.videoMemPCI)); - pFBC->bytes_per_row = si.displayMode.virtual_width + pFBC->bytes_per_row = si.displayMode.virtual_width * si.displayMode.bytesPerPixel; return B_OK; @@ -317,9 +314,7 @@ GetPixelClockLimits(display_mode* mode, uint32* low, uint32* high) } - #ifdef __HAIKU__ - status_t GetEdidInfo(void* info, size_t size, uint32* _version) { @@ -335,5 +330,4 @@ GetEdidInfo(void* info, size_t size, uint32* _version) *_version = EDID_VERSION_1; return B_OK; } - #endif // __HAIKU__ diff --git a/src/add-ons/kernel/drivers/graphics/intel_810/driver.cpp b/src/add-ons/kernel/drivers/graphics/intel_810/driver.cpp index f411ae7194..eddd81d017 100644 --- a/src/add-ons/kernel/drivers/graphics/intel_810/driver.cpp +++ b/src/add-ons/kernel/drivers/graphics/intel_810/driver.cpp @@ -6,6 +6,7 @@ * Gerald Zajac */ + #include #include #include @@ -47,18 +48,18 @@ struct ChipInfo { // This table maps a PCI device ID to a chip type identifier and the chip name. static const ChipInfo chipTable[] = { - { 0x7121, "i810" }, - { 0x7123, "i810-dc100" }, - { 0x7125, "i810e" }, - { 0x1132, "i815" }, - { 0, NULL } + { 0x7121, "i810" }, + { 0x7123, "i810-dc100" }, + { 0x7125, "i810e" }, + { 0x1132, "i815" }, + { 0, NULL } }; struct DeviceInfo { - uint32 openCount; // count of how many times device has been opened + uint32 openCount; // how many times device has been opened int32 flags; - area_id sharedArea; // area shared between driver and accelerants + area_id sharedArea; // shared between driver and accelerants SharedInfo* sharedInfo; // pointer to shared info area memory vuint8* regs; // pointer to memory mapped registers const ChipInfo* pChipInfo; // info about the selected chip @@ -76,13 +77,12 @@ static pci_module_info* gPCI; // Prototypes for device hook functions. - static status_t device_open(const char* name, uint32 flags, void** cookie); static status_t device_close(void* dev); static status_t device_free(void* dev); static status_t device_read(void* dev, off_t pos, void* buf, size_t* len); static status_t device_write(void* dev, off_t pos, const void* buf, - size_t* len); + size_t* len); static status_t device_ioctl(void* dev, uint32 msg, void* buf, size_t len); static device_hooks gDeviceHooks = @@ -100,9 +100,8 @@ static device_hooks gDeviceHooks = }; - // Video chip register definitions. -//================================= +// ================================= #define INTERRUPT_ENABLED 0x020a0 #define INTERRUPT_MASK 0x020a8 @@ -116,7 +115,7 @@ static device_hooks gDeviceHooks = // Macros for memory mapped I/O. -//============================== +// ============================== #define INREG16(addr) (*((vuint16*)(di.regs + (addr)))) #define INREG32(addr) (*((vuint32*)(di.regs + (addr)))) @@ -125,7 +124,6 @@ static device_hooks gDeviceHooks = #define OUTREG32(addr, val) (*((vuint32*)(di.regs + (addr))) = (val)) - static inline uint32 GetPCI(pci_info& info, uint8 offset, uint8 size) { @@ -147,8 +145,8 @@ GetEdidFromBIOS(edid1_raw& edidRaw) { // Get the EDID info from the video BIOS, and return B_OK if successful. -#define ADDRESS_SEGMENT(address) ((addr_t)(address) >> 4) -#define ADDRESS_OFFSET(address) ((addr_t)(address) & 0xf) + #define ADDRESS_SEGMENT(address) ((addr_t)(address) >> 4) + #define ADDRESS_OFFSET(address) ((addr_t)(address) & 0xf) vm86_state vmState; @@ -295,12 +293,12 @@ InitDevice(DeviceInfo& di) if (di.gttArea < B_OK) { TRACE("Unable to create GTT, error: 0x%lx\n", di.gttArea); return B_NO_MEMORY; - } + } memset((void*)(di.gttAddr), 0, gttSize); // Get the physical address of the GTT, and set GTT address in the chip. - + physical_entry entry; status_t status = get_memory_map((void *)(di.gttAddr), B_PAGE_SIZE, &entry, 1); @@ -309,8 +307,8 @@ InitDevice(DeviceInfo& di) return status; } - OUTREG32(PAGE_TABLE_CONTROL, entry.address | PAGE_TABLE_ENABLED); - INREG32(PAGE_TABLE_CONTROL); + OUTREG32(PAGE_TABLE_CONTROL, entry.address | PAGE_TABLE_ENABLED); + INREG32(PAGE_TABLE_CONTROL); // Allocate video memory to be used for the frame buffer. @@ -395,7 +393,7 @@ GetNextSupportedDevice(uint32& pciIndex, pci_info& pciInfo) while (pDevice->chipID != 0) { // end of table? if (pDevice->chipID == pciInfo.device_id) - return pDevice; // matching device/chip found + return pDevice; // matching device/chip found pDevice++; } @@ -404,11 +402,10 @@ GetNextSupportedDevice(uint32& pciIndex, pci_info& pciInfo) pciIndex++; } - return NULL; // no supported device found + return NULL; // no supported device found } - // #pragma mark - Kernel Interface @@ -471,8 +468,8 @@ init_driver(void) // Compose device name. sprintf(di.name, "graphics/" DEVICE_FORMAT, - di.pciInfo.vendor_id, di.pciInfo.device_id, - di.pciInfo.bus, di.pciInfo.device, di.pciInfo.function); + di.pciInfo.vendor_id, di.pciInfo.device_id, + di.pciInfo.bus, di.pciInfo.device, di.pciInfo.function); TRACE("init_driver() match found; name: %s\n", di.name); gDeviceNames[count] = di.name; @@ -526,7 +523,6 @@ find_device(const char* name) } - // #pragma mark - Device Hooks @@ -555,7 +551,7 @@ device_open(const char* name, uint32 /*flags*/, void** cookie) if (status < B_OK) DeleteAreas(di); // error occurred; delete any areas created } - + gLock.Release(); if (status == B_OK) { From 3a1a1e1b82b7a9e280ee040d1aad27d356983876 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Wed, 16 May 2012 01:06:26 +0200 Subject: [PATCH 09/39] Style cleanup. --- src/apps/sudoku/SudokuField.h | 72 +++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 33 deletions(-) diff --git a/src/apps/sudoku/SudokuField.h b/src/apps/sudoku/SudokuField.h index bd270e30bb..f16b3f6488 100644 --- a/src/apps/sudoku/SudokuField.h +++ b/src/apps/sudoku/SudokuField.h @@ -1,5 +1,5 @@ /* - * Copyright 2007-2010, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2007-2012, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. */ #ifndef SUDOKU_FIELD_H @@ -17,39 +17,42 @@ enum { class SudokuField : public BArchivable { public: - SudokuField(uint32 size); - SudokuField(const BMessage* archive); - SudokuField(const SudokuField& other); - virtual ~SudokuField(); + SudokuField(uint32 size); + SudokuField(const BMessage* archive); + SudokuField(const SudokuField& other); + virtual ~SudokuField(); - status_t InitCheck(); + status_t InitCheck(); - virtual status_t Archive(BMessage* archive, bool deep) const; - static SudokuField* Instantiate(BMessage* archive); + virtual status_t Archive(BMessage* archive, bool deep) const; + static SudokuField* Instantiate(BMessage* archive); - status_t SetTo(char base, const char* data); - void SetTo(const SudokuField* other); - void Reset(); + status_t SetTo(char base, const char* data); + void SetTo(const SudokuField* other); + void Reset(); - bool IsSolved() const; - bool IsEmpty() const; + bool IsSolved() const; + bool IsEmpty() const; - uint32 Size() const { return fSize; } - uint32 BlockSize() const { return fBlockSize; } + uint32 Size() const { return fSize; } + uint32 BlockSize() const { return fBlockSize; } - void SetHintMaskAt(uint32 x, uint32 y, uint32 hintMask); - uint32 HintMaskAt(uint32 x, uint32 y) const; + void SetHintMaskAt(uint32 x, uint32 y, + uint32 hintMask); + uint32 HintMaskAt(uint32 x, uint32 y) const; - void SetValidMaskAt(uint32 x, uint32 y, uint32 validMask); - uint32 ValidMaskAt(uint32 x, uint32 y) const; + void SetValidMaskAt(uint32 x, uint32 y, + uint32 validMask); + uint32 ValidMaskAt(uint32 x, uint32 y) const; - void SetFlagsAt(uint32 x, uint32 y, uint32 flags); - uint32 FlagsAt(uint32 x, uint32 y) const; + void SetFlagsAt(uint32 x, uint32 y, uint32 flags); + uint32 FlagsAt(uint32 x, uint32 y) const; - void SetValueAt(uint32 x, uint32 y, uint32 value, bool setSolved = false); - uint32 ValueAt(uint32 x, uint32 y) const; + void SetValueAt(uint32 x, uint32 y, uint32 value, + bool setSolved = false); + uint32 ValueAt(uint32 x, uint32 y) const; - void Dump(); + void Dump(); private: struct field { @@ -61,16 +64,19 @@ private: uint32 value; }; - bool _ValidValueAt(uint32 x, uint32 y) const; - void _ComputeValidMask(uint32 x, uint32 y, bool setSolved); - void _UpdateValidMaskChanged(uint32 x, uint32 y, bool setSolved); - const field& _FieldAt(uint32 x, uint32 y) const; - field& _FieldAt(uint32 x, uint32 y); + bool _ValidValueAt(uint32 x, uint32 y) const; + void _ComputeValidMask(uint32 x, uint32 y, + bool setSolved); + void _UpdateValidMaskChanged(uint32 x, uint32 y, + bool setSolved); + const field& _FieldAt(uint32 x, uint32 y) const; + field& _FieldAt(uint32 x, uint32 y); - uint32 fSize; - uint32 fBlockSize; - uint32 fMaxMask; - field* fFields; +private: + uint32 fSize; + uint32 fBlockSize; + uint32 fMaxMask; + field* fFields; }; From d6e44c9c822d666923f1af3e30cd63e65a64e61c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Wed, 16 May 2012 02:05:09 +0200 Subject: [PATCH 10/39] If all fields for a specific value are set, mark it. * In this case, the value is drawn a bit less intense than incomplete values. * Make the keyboard focus background color depend on the actual background color. * No longer allow to drag remove random hint values after removing a value from a field. --- src/apps/sudoku/SudokuField.cpp | 15 ++++++++++++++ src/apps/sudoku/SudokuField.h | 1 + src/apps/sudoku/SudokuView.cpp | 36 ++++++++++++++++++++++----------- 3 files changed, 40 insertions(+), 12 deletions(-) diff --git a/src/apps/sudoku/SudokuField.cpp b/src/apps/sudoku/SudokuField.cpp index 62a3ddcd54..a139d473b9 100644 --- a/src/apps/sudoku/SudokuField.cpp +++ b/src/apps/sudoku/SudokuField.cpp @@ -251,6 +251,21 @@ SudokuField::IsEmpty() const } +bool +SudokuField::IsValueCompleted(uint32 value) const +{ + uint32 count = 0; + for (uint32 y = 0; y < fSize; y++) { + for (uint32 x = 0; x < fSize; x++) { + if (ValueAt(x, y) == value) + count++; + } + } + + return count == Size(); +} + + void SudokuField::SetHintMaskAt(uint32 x, uint32 y, uint32 hintMask) { diff --git a/src/apps/sudoku/SudokuField.h b/src/apps/sudoku/SudokuField.h index f16b3f6488..2b0bbf6fe9 100644 --- a/src/apps/sudoku/SudokuField.h +++ b/src/apps/sudoku/SudokuField.h @@ -33,6 +33,7 @@ public: bool IsSolved() const; bool IsEmpty() const; + bool IsValueCompleted(uint32 value) const; uint32 Size() const { return fSize; } uint32 BlockSize() const { return fBlockSize; } diff --git a/src/apps/sudoku/SudokuView.cpp b/src/apps/sudoku/SudokuView.cpp index b34b1ce6bf..653316241f 100644 --- a/src/apps/sudoku/SudokuView.cpp +++ b/src/apps/sudoku/SudokuView.cpp @@ -814,21 +814,30 @@ SudokuView::MouseDown(BPoint where) | B_TERTIARY_MOUSE_BUTTON)) != 0) { // double click or other buttons set a value if ((fField->FlagsAt(x, y) & kInitialValue) == 0) { + bool wasCompleted; if (fField->ValueAt(x, y) > 0) { + value = fField->ValueAt(x, y) - 1; + wasCompleted = fField->IsValueCompleted(value + 1); + fField->SetValueAt(x, y, 0); fShowHintX = x; fShowHintY = y; } else { + wasCompleted = fField->IsValueCompleted(value + 1); + fField->SetValueAt(x, y, value + 1); BMessenger(this).SendMessage(kMsgCheckSolved); + + // allow dragging to remove the hint from other fields + fLastHintValueSet = false; + fLastHintValue = value; + fLastField = field; } - _InvalidateField(x, y); - - // allow dragging to remove the hint from other fields - fLastHintValueSet = false; - fLastHintValue = value; - fLastField = field; + if (wasCompleted != fField->IsValueCompleted(value + 1)) + Invalidate(); + else + _InvalidateField(x, y); } return; } @@ -1204,8 +1213,8 @@ SudokuView::Draw(BRect /*updateRect*/) || (fShowKeyboardFocus && x == fKeyboardX && y == fKeyboardY)) && (fField->FlagsAt(x, y) & kInitialValue) == 0) { - //SetLowColor(tint_color(ViewColor(), B_DARKEN_1_TINT)); - SetLowColor(255, 255, 210); + // TODO: make color more intense + SetLowColor(tint_color(fBackgroundColor, B_DARKEN_2_TINT)); FillRect(_Frame(x, y), B_SOLID_LOW); } else { SetLowColor(fBackgroundColor); @@ -1222,13 +1231,16 @@ SudokuView::Draw(BRect /*updateRect*/) } SetFont(&fFieldFont); - if (fField->FlagsAt(x, y) & kInitialValue) + if ((fField->FlagsAt(x, y) & kInitialValue) != 0) SetHighColor(0, 0, 0); else { if ((fHintFlags & kMarkInvalid) == 0 - || fField->ValidMaskAt(x, y) & (1UL << (value - 1))) - SetHighColor(0, 0, 200); - else + || fField->ValidMaskAt(x, y) & (1UL << (value - 1))) { + if (fField->IsValueCompleted(value)) + SetHighColor(60, 60, 150); + else + SetHighColor(0, 0, 220); + } else SetHighColor(200, 0, 0); } From 712fdb70b2f8914380c0cd31245653bf76acc2db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Wed, 16 May 2012 20:33:36 +0200 Subject: [PATCH 11/39] Style cleanup. --- src/apps/sudoku/SudokuView.h | 164 +++++++++++++++++++---------------- 1 file changed, 91 insertions(+), 73 deletions(-) diff --git a/src/apps/sudoku/SudokuView.h b/src/apps/sudoku/SudokuView.h index 03fd8e7317..70b67c7041 100644 --- a/src/apps/sudoku/SudokuView.h +++ b/src/apps/sudoku/SudokuView.h @@ -1,5 +1,5 @@ /* - * Copyright 2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Copyright 2007-2012, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. */ #ifndef SUDOKU_VIEW_H @@ -9,6 +9,7 @@ #include #include + class BDataIO; class SudokuField; struct entry_ref; @@ -27,99 +28,115 @@ enum { kExportAsPicture }; + class SudokuView : public BView { public: - SudokuView(BRect frame, const char* name, const BMessage& settings, - uint32 resizingMode); - SudokuView(BMessage* archive); - virtual ~SudokuView(); + SudokuView(BRect frame, const char* name, + const BMessage& settings, + uint32 resizingMode); + SudokuView(BMessage* archive); + virtual ~SudokuView(); - virtual status_t Archive(BMessage* into, bool deep = true) const; - static BArchivable* Instantiate(BMessage* archive); - void InitObject(const BMessage* archive); + virtual status_t Archive(BMessage* into, bool deep = true) const; + static BArchivable* Instantiate(BMessage* archive); + void InitObject(const BMessage* archive); - status_t SaveState(BMessage& state) const; + status_t SaveState(BMessage& state) const; - status_t SetTo(entry_ref& ref); - status_t SetTo(const char* data); - status_t SetTo(SudokuField* field); + status_t SetTo(entry_ref& ref); + status_t SetTo(const char* data); + status_t SetTo(SudokuField* field); - status_t SaveTo(entry_ref& ref, uint32 as = kExportAsText); - status_t SaveTo(BDataIO &to, uint32 as = kExportAsText); - - status_t CopyToClipboard(); + status_t SaveTo(entry_ref& ref, + uint32 as = kExportAsText); + status_t SaveTo(BDataIO &to, uint32 as = kExportAsText); - void ClearChanged(); - void ClearAll(); + status_t CopyToClipboard(); - void SetHintFlags(uint32 flags); - uint32 HintFlags() const { return fHintFlags; } + void ClearChanged(); + void ClearAll(); - SudokuField* Field() { return fField; } + void SetHintFlags(uint32 flags); + uint32 HintFlags() const { return fHintFlags; } - void SetEditable(bool editable); - bool Editable() const { return fEditable; } + SudokuField* Field() { return fField; } - bool CanUndo() { return !fUndos.IsEmpty(); } - bool CanRedo() { return !fRedos.IsEmpty(); } - void Undo(); - void Redo(); + void SetEditable(bool editable); + bool Editable() const { return fEditable; } + + bool CanUndo() { return !fUndos.IsEmpty(); } + bool CanRedo() { return !fRedos.IsEmpty(); } + void Undo(); + void Redo(); protected: - virtual void AttachedToWindow(); + virtual void AttachedToWindow(); - virtual void FrameResized(float width, float height); - virtual void MouseDown(BPoint where); - virtual void MouseMoved(BPoint where, uint32 transit, - const BMessage* dragMessage); - virtual void KeyDown(const char *bytes, int32 numBytes); + virtual void FrameResized(float width, float height); + virtual void MouseDown(BPoint where); + virtual void MouseMoved(BPoint where, uint32 transit, + const BMessage* dragMessage); + virtual void KeyDown(const char *bytes, int32 numBytes); - virtual void MessageReceived(BMessage* message); + virtual void MessageReceived(BMessage* message); - virtual void Draw(BRect updateRect); + virtual void Draw(BRect updateRect); private: - status_t _FilterString(const char* data, size_t dataLength, char* buffer, - uint32& out, bool& ignore); - void _SetText(char* text, uint32 value); - char _BaseCharacter(); - bool _ValidCharacter(char c); - BPoint _LeftTop(uint32 x, uint32 y); - BRect _Frame(uint32, uint32 y); - void _InvalidateHintField(uint32 x, uint32 y, uint32 hintX, uint32 hintY); - void _InvalidateField(uint32 x, uint32 y); - void _InvalidateKeyboardFocus(uint32 x, uint32 y); - void _InsertKey(char rawKey, int32 modifiers); - void _RemoveHint(); - bool _GetHintFieldFor(BPoint where, uint32 x, uint32 y, - uint32& hintX, uint32& hintY); - bool _GetFieldFor(BPoint where, uint32& x, uint32& y); - void _FitFont(BFont& font, float width, float height); - void _DrawKeyboardFocus(); - void _DrawHints(uint32 x, uint32 y); - void _UndoRedo(BObjectList& undos, BObjectList& redos); - void _PushUndo(); + status_t _FilterString(const char* data, + size_t dataLength, char* buffer, + uint32& out, bool& ignore); + void _SetText(char* text, uint32 value); + char _BaseCharacter(); + bool _ValidCharacter(char c); + BPoint _LeftTop(uint32 x, uint32 y); + BRect _Frame(uint32, uint32 y); + void _InvalidateHintField(uint32 x, uint32 y, + uint32 hintX, uint32 hintY); + void _InvalidateField(uint32 x, uint32 y); + void _InvalidateKeyboardFocus(uint32 x, uint32 y); + void _InsertKey(char rawKey, int32 modifiers); + void _RemoveHint(); + bool _GetHintFieldFor(BPoint where, uint32 x, + uint32 y, uint32& hintX, uint32& hintY); + bool _GetFieldFor(BPoint where, uint32& x, + uint32& y); + void _FitFont(BFont& font, float width, + float height); + void _DrawKeyboardFocus(); + void _DrawHints(uint32 x, uint32 y); + void _UndoRedo(BObjectList& undos, + BObjectList& redos); + void _PushUndo(); - rgb_color fBackgroundColor; - SudokuField* fField; - BObjectList fUndos; - BObjectList fRedos; - uint32 fBlockSize; - float fWidth, fHeight, fBaseline; - BFont fFieldFont; - BFont fHintFont; - float fHintHeight, fHintWidth, fHintBaseline; - uint32 fShowHintX, fShowHintY; - uint32 fLastHintValue; - bool fLastHintValueSet; - uint32 fLastField; - uint32 fKeyboardX, fKeyboardY; - uint32 fHintFlags; - bool fShowKeyboardFocus; - bool fShowCursor; - bool fEditable; +private: + rgb_color fBackgroundColor; + SudokuField* fField; + BObjectList fUndos; + BObjectList fRedos; + uint32 fBlockSize; + float fWidth; + float fHeight; + float fBaseline; + BFont fFieldFont; + BFont fHintFont; + float fHintHeight; + float fHintWidth; + float fHintBaseline; + uint32 fShowHintX; + uint32 fShowHintY; + uint32 fLastHintValue; + bool fLastHintValueSet; + uint32 fLastField; + uint32 fKeyboardX; + uint32 fKeyboardY; + uint32 fHintFlags; + bool fShowKeyboardFocus; + bool fShowCursor; + bool fEditable; }; + static const uint32 kMsgSudokuSolved = 'susl'; static const uint32 kMsgSolveSudoku = 'slvs'; static const uint32 kMsgSolveSingle = 'slsg'; @@ -127,4 +144,5 @@ static const uint32 kMsgSolveSingle = 'slsg'; // you can observe these: static const int32 kUndoRedoChanged = 'unre'; + #endif // SUDOKU_VIEW_H From 0084fa520924353948934c0dab7d6a10d9da96fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Wed, 30 May 2012 23:32:59 +0200 Subject: [PATCH 12/39] Reverted the rounded buttons again. * Following the previous discussion on the mailing list and Stippi's final mail. * I tried to get used to it in the last couple of weeks, but I think it just looks out of place, and not good either. --- src/apps/deskcalc/CalcView.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/apps/deskcalc/CalcView.cpp b/src/apps/deskcalc/CalcView.cpp index f5b13afe2d..bab5c923ad 100644 --- a/src/apps/deskcalc/CalcView.cpp +++ b/src/apps/deskcalc/CalcView.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2006-2011, Haiku, Inc. All rights reserved. + * Copyright 2006-2012, Haiku, Inc. All rights reserved. * Copyright 1997, 1998 R3 Software Ltd. All Rights Reserved. * Distributed under the terms of the MIT License. * @@ -9,6 +9,7 @@ * Philippe Saint-Pierre, stpere@gmail.com */ + #include "CalcView.h" #include @@ -435,10 +436,10 @@ CalcView::Draw(BRect updateRect) flags |= BControlLook::B_IGNORE_OUTLINE; be_control_look->DrawButtonFrame(this, frame, updateRect, - 6.0f, fBaseColor, fBaseColor, flags); + fBaseColor, fBaseColor, flags); be_control_look->DrawButtonBackground(this, frame, updateRect, - 6.0f, fBaseColor, flags); + fBaseColor, flags); be_control_look->DrawLabel(this, key->label, frame, updateRect, fBaseColor, flags, BAlignment(B_ALIGN_HORIZONTAL_CENTER, From 264aaaeeb5a5e49dbc6bdc399824786ea1d8fea3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Thu, 31 May 2012 01:04:09 +0200 Subject: [PATCH 13/39] Sam460ex: force using hardware floating point * our current gcc can't be built with multilib for ppc anyway, * this allows going further on real hardware, though dprintf() sends wrong data to the serial port. --- build/jam/board/sam460ex/BoardSetup | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/build/jam/board/sam460ex/BoardSetup b/build/jam/board/sam460ex/BoardSetup index 45b1c9372c..40884c79dd 100644 --- a/build/jam/board/sam460ex/BoardSetup +++ b/build/jam/board/sam460ex/BoardSetup @@ -28,8 +28,10 @@ HAIKU_BOARD_LOADER_STACK_BASE = 0x02000000 ; # gcc flags for the specific cpu # -HAIKU_KERNEL_CCFLAGS += -mcpu=440 -mtune=440 -msoft-float ; -HAIKU_KERNEL_C++FLAGS += -mcpu=440 -mtune=440 -msoft-float ; -HAIKU_CCFLAGS += -mcpu=440 -mtune=440 -msoft-float ; -HAIKU_C++FLAGS += -mcpu=440 -mtune=440 -msoft-float ; +HAIKU_KERNEL_PIC_CCFLAGS += -mcpu=440fp -mtune=440fp ; +HAIKU_KERNEL_PIC_C++FLAGS += -mcpu=440fp -mtune=440fp ; +HAIKU_KERNEL_CCFLAGS += -mcpu=440fp -mtune=440fp ; +HAIKU_KERNEL_C++FLAGS += -mcpu=440fp -mtune=440fp ; +HAIKU_CCFLAGS += -mcpu=440fp -mtune=440fp ; +HAIKU_C++FLAGS += -mcpu=440fp -mtune=440fp ; From f0aca319b9e65ad57ddfff45bc7076f7946f49b7 Mon Sep 17 00:00:00 2001 From: Alexander von Gluck IV Date: Thu, 31 May 2012 19:14:34 -0500 Subject: [PATCH 14/39] amdcpuid: A small tool for OS.h * Takes an AMD CPUID and converts it to a number for OS.h * Splits on family 0xF as per AMD recommendation --- src/tools/amdcpuid.c | 94 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 src/tools/amdcpuid.c diff --git a/src/tools/amdcpuid.c b/src/tools/amdcpuid.c new file mode 100644 index 0000000000..ef5ec6686f --- /dev/null +++ b/src/tools/amdcpuid.c @@ -0,0 +1,94 @@ +/* + * Copyright 2012 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexander von Gluck, kallisti5@unixzen.com + */ + +/* + * Pass an AMD CPUID in hex, and get out a CPUID for OS.h + */ + + +#include +#include +#include + + +#define AMDCPU 0x1100 + +#define EXT_FAMILY_MASK 0xF00000 +#define EXT_MODEL_MASK 0x0F0000 +#define FAMILY_MASK 0x000F00 +#define MODEL_MASK 0x0000F0 +#define STEPPING_MASK 0x00000F + + +// Converts a hexadecimal string to integer +static int xtoi(const char* xs, unsigned int* result) +{ + size_t szlen = strlen(xs); + int i, xv, fact; + + if (szlen > 0) { + // Converting more than 32bit hexadecimal value? + if (szlen>8) return 2; // exit + + // Begin conversion here + *result = 0; + fact = 1; + + // Run until no more character to convert + for (i = szlen - 1; i>=0 ;i--) { + if (isxdigit(*(xs+i))) { + if (*(xs+i)>=97) { + xv = ( *(xs+i) - 97) + 10; + } else if ( *(xs+i) >= 65) { + xv = (*(xs+i) - 65) + 10; + } else { + xv = *(xs+i) - 48; + } + *result += (xv * fact); + fact *= 16; + } else { + // Conversion was abnormally terminated + // by non hexadecimal digit, hence + // returning only the converted with + // an error value 4 (illegal hex character) + return 4; + } + } + } + + // Nothing to convert + return 1; +} + + +int +main(int argc, char *argv[]) +{ + if (argc != 2) { + printf("Provide the AMD cpuid in hex, and you will get how we id it\n"); + printf("usage: amdcpuid \n"); + return 1; + } + + unsigned int cpuid; + xtoi(argv[1], &cpuid); + + printf("cpuid: 0x%X\n", cpuid); + + unsigned int extFam = (cpuid & EXT_FAMILY_MASK) >> 20; + unsigned int extMod = (cpuid & EXT_MODEL_MASK) >> 16; + unsigned int family = (cpuid & FAMILY_MASK) >> 8; + unsigned int model = (cpuid & MODEL_MASK) >> 4; + + if (family == 0xF) + printf("model: 0x%lX\n", extFam + (extMod << 4) + model + 0x1100); + else + printf("model: 0x%lX\n", (family << 4) + model + 0x1100); + + return 0; +} From c84fd0f0fecfe6a153d57e7e9aa67206712b1b81 Mon Sep 17 00:00:00 2001 From: Alexander von Gluck IV Date: Thu, 31 May 2012 23:57:53 -0500 Subject: [PATCH 15/39] amdcpuid: Redo how we store amd cpuid's * Ran out of space, so we do AMD chips as VVFFMM * Longer family and model masks work * Plug in any raw hex AMD CPUID and get back Haiku format --- src/tools/amdcpuid.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/tools/amdcpuid.c b/src/tools/amdcpuid.c index ef5ec6686f..9c2500e9d6 100644 --- a/src/tools/amdcpuid.c +++ b/src/tools/amdcpuid.c @@ -16,7 +16,7 @@ #include -#define AMDCPU 0x1100 +#define AMD_VENDOR 0x110000 #define EXT_FAMILY_MASK 0xF00000 #define EXT_MODEL_MASK 0x0F0000 @@ -84,11 +84,26 @@ main(int argc, char *argv[]) unsigned int extMod = (cpuid & EXT_MODEL_MASK) >> 16; unsigned int family = (cpuid & FAMILY_MASK) >> 8; unsigned int model = (cpuid & MODEL_MASK) >> 4; + unsigned int stepping = (cpuid & STEPPING_MASK); - if (family == 0xF) - printf("model: 0x%lX\n", extFam + (extMod << 4) + model + 0x1100); - else - printf("model: 0x%lX\n", (family << 4) + model + 0x1100); + unsigned int amdFamily = 0; + unsigned int amdModel = 0; + if (family == 0xF) { + amdFamily = extFam + family; + amdModel = (extMod << 4) + model; + } else { + amdFamily = family; + amdModel = model; + } + + // Haiku AMD cpuid format: VVFFMM + unsigned int amdHaiku + = AMD_VENDOR + (amdFamily << 8) + amdModel; + + printf("family: 0x%lX\n", amdFamily); + printf("model: 0x%lX\n", amdModel); + printf("stepping: 0x%lX\n", stepping); + printf("Haiku CPUID: 0x%lX\n", amdHaiku); return 0; } From d995d3c634421f74061bcd6225e3ee9fb25f7194 Mon Sep 17 00:00:00 2001 From: Alexander von Gluck IV Date: Fri, 1 Jun 2012 11:01:29 -0500 Subject: [PATCH 16/39] intelcpuid: A small tool for OS.h * Takes an Intel CPUID and converts it to a number for OS.h --- src/tools/intelcpuid.c | 96 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 src/tools/intelcpuid.c diff --git a/src/tools/intelcpuid.c b/src/tools/intelcpuid.c new file mode 100644 index 0000000000..44e3e4c926 --- /dev/null +++ b/src/tools/intelcpuid.c @@ -0,0 +1,96 @@ +/* + * Copyright 2012 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexander von Gluck, kallisti5@unixzen.com + */ + +/* + * Pass an Intel CPUID in hex, and get out a CPUID for OS.h + */ + + +#include +#include +#include + + +#define INTEL_VENDOR 0x100000 + +#define EXT_FAMILY_MASK 0xF00000 +#define EXT_MODEL_MASK 0x0F0000 +#define FAMILY_MASK 0x000F00 +#define MODEL_MASK 0x0000F0 +#define STEPPING_MASK 0x00000F + + +// Converts a hexadecimal string to integer +static int xtoi(const char* xs, unsigned int* result) +{ + size_t szlen = strlen(xs); + int i, xv, fact; + + if (szlen > 0) { + // Converting more than 32bit hexadecimal value? + if (szlen>8) return 2; // exit + + // Begin conversion here + *result = 0; + fact = 1; + + // Run until no more character to convert + for (i = szlen - 1; i>=0 ;i--) { + if (isxdigit(*(xs+i))) { + if (*(xs+i)>=97) { + xv = ( *(xs+i) - 97) + 10; + } else if ( *(xs+i) >= 65) { + xv = (*(xs+i) - 65) + 10; + } else { + xv = *(xs+i) - 48; + } + *result += (xv * fact); + fact *= 16; + } else { + // Conversion was abnormally terminated + // by non hexadecimal digit, hence + // returning only the converted with + // an error value 4 (illegal hex character) + return 4; + } + } + } + + // Nothing to convert + return 1; +} + + +int +main(int argc, char *argv[]) +{ + if (argc != 2) { + printf("Provide the Intel cpuid in hex, and you will get how we id it\n"); + printf("usage: intelcpuid \n"); + return 1; + } + + unsigned int cpuid; + xtoi(argv[1], &cpuid); + + printf("cpuid: 0x%X\n", cpuid); + + unsigned int extFam = (cpuid & EXT_FAMILY_MASK) >> 20; + unsigned int extMod = (cpuid & EXT_MODEL_MASK) >> 16; + unsigned int family = (cpuid & FAMILY_MASK) >> 8; + unsigned int model = (cpuid & MODEL_MASK) >> 4; + unsigned int stepping = (cpuid & STEPPING_MASK); + + // Haiku INTEL cpuid format: VVEFEM + unsigned int intelHaiku = INTEL_VENDOR + ((extFam & 0xF) << 12) + + (family << 8) + (extMod << 4) + model; + + printf("Haiku CPUID: 0x%lX\n", intelHaiku); + + return 0; +} From 87a8b1c97bba3fb7ad49f461d7362b706e52f353 Mon Sep 17 00:00:00 2001 From: Fredrik Modeen Date: Fri, 1 Jun 2012 22:29:26 +0200 Subject: [PATCH 17/39] change wlan iwp2100 to use iprowifi2100 and the right firmware, should fix Ticket #7938 and #7898 --- build/jam/HaikuImage | 2 +- data/bin/install-wifi-firmwares.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/jam/HaikuImage b/build/jam/HaikuImage index 2b75b2e144..9f25d8d385 100644 --- a/build/jam/HaikuImage +++ b/build/jam/HaikuImage @@ -181,7 +181,7 @@ SYSTEM_ADD_ONS_DRIVERS_NET = $(X86_ONLY)3com $(X86_ONLY)atheros813x # WLAN drivers $(X86_ONLY)aironetwifi $(X86_ONLY)atheroswifi $(X86_ONLY)broadcom43xx - $(X86_ONLY)ipw2100 $(X86_ONLY)iprowifi2200 $(X86_ONLY)iprowifi3945 + $(X86_ONLY)iprowifi2100 $(X86_ONLY)iprowifi2200 $(X86_ONLY)iprowifi3945 $(X86_ONLY)iprowifi4965 $(X86_ONLY)marvell88w8363 $(X86_ONLY)marvell88w8335 $(X86_ONLY)ralink2860 $(X86_ONLY)ralinkwifi $(X86_ONLY)wavelanwifi diff --git a/data/bin/install-wifi-firmwares.sh b/data/bin/install-wifi-firmwares.sh index c3f313988b..f931962147 100755 --- a/data/bin/install-wifi-firmwares.sh +++ b/data/bin/install-wifi-firmwares.sh @@ -175,7 +175,7 @@ function PostFirmwareInstallation() function InstallIpw2100() { - driver='ipw2100' + driver='iprowifi2100' PreFirmwareInstallation # Extract contents. From 983f0b53d992d05592f757076b85888a7ce1f365 Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Fri, 1 Jun 2012 17:24:27 -0400 Subject: [PATCH 18/39] Add Gerald Zajac's Intel 810 driver to the image. --- build/jam/HaikuImage | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build/jam/HaikuImage b/build/jam/HaikuImage index 9f25d8d385..ffc8d7ea74 100644 --- a/build/jam/HaikuImage +++ b/build/jam/HaikuImage @@ -121,6 +121,7 @@ SYSTEM_ADD_ONS_ACCELERANTS = $(X86_ONLY)radeon.accelerant $(X86_ONLY)ati.accelerant $(X86_ONLY)3dfx.accelerant $(X86_ONLY)radeon_hd.accelerant + $(X86_ONLY)intel_810.accelerant #$(X86_ONLY)via.accelerant #$(X86_ONLY)vmware.accelerant ; @@ -168,6 +169,7 @@ SYSTEM_ADD_ONS_DRIVERS_GRAPHICS = $(X86_ONLY)radeon $(X86_ONLY)nvidia $(X86_ONLY)neomagic $(X86_ONLY)matrox $(X86_ONLY)intel_extreme $(X86_ONLY)s3 $(X86_ONLY)vesa #$(X86_ONLY)via #$(X86_ONLY)vmware $(X86_ONLY)ati $(X86_ONLY)3dfx $(X86_ONLY)radeon_hd + $(X86_ONLY)intel_810 ; SYSTEM_ADD_ONS_DRIVERS_MIDI = emuxki ice1712 usb_midi ; SYSTEM_ADD_ONS_DRIVERS_NET = $(X86_ONLY)3com $(X86_ONLY)atheros813x From 68a593ba2a5fe1a9a60ca527241a18d3a0e6e1a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sat, 2 Jun 2012 01:20:07 +0200 Subject: [PATCH 19/39] Sam460ex: Change load address for debugging * Change haiku_loader load address to leave U-Boot's exceptions vector for easier debugging. --- build/jam/board/sam460ex/BoardSetup | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/build/jam/board/sam460ex/BoardSetup b/build/jam/board/sam460ex/BoardSetup index 40884c79dd..1f0b3369b0 100644 --- a/build/jam/board/sam460ex/BoardSetup +++ b/build/jam/board/sam460ex/BoardSetup @@ -11,9 +11,11 @@ HAIKU_BOOT_PLATFORM = u-boot ; # # load address for haiku_loader -HAIKU_BOARD_LOADER_BASE = 0x00000000 ; +# HAIKU_BOARD_LOADER_BASE = 0x00000000 ; +# for debugging: +HAIKU_BOARD_LOADER_BASE = 0x02000000 ; # entry points (raw binary, and netbsd loader emulation) -HAIKU_BOARD_LOADER_ENTRY_LINUX = 0x00000000 ; +HAIKU_BOARD_LOADER_ENTRY_LINUX = 0x02000000 ; HAIKU_BOARD_LOADER_ENTRY = $(HAIKU_BOARD_LOADER_ENTRY_LINUX) ; HAIKU_BOARD_LOADER_FAKE_OS = linux ; From b837149e73aeeb48841f2c09f82a5bd2bcb1b05a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sat, 2 Jun 2012 01:25:53 +0200 Subject: [PATCH 20/39] Sam460ex: Add cpu type and model defines to board_config.h * we need this in arch_cpu.cpp in the bootloader. --- headers/private/kernel/arch/ppc/board/sam460ex/board_config.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/headers/private/kernel/arch/ppc/board/sam460ex/board_config.h b/headers/private/kernel/arch/ppc/board/sam460ex/board_config.h index aefec5d6ce..7aff55fb66 100644 --- a/headers/private/kernel/arch/ppc/board/sam460ex/board_config.h +++ b/headers/private/kernel/arch/ppc/board/sam460ex/board_config.h @@ -11,6 +11,9 @@ #define BOARD_NAME_PRETTY "ACube Sam460ex" +#define BOARD_CPU_TYPE_PPC440 1 +#define BOARD_CPU_PPC460EX 1 + // UART Settings // TODO: use the FDT instead of hardcoding #define BOARD_UART1_BASE 0xef600300 From cce9d8cf89c7ce155c9e794579a89478661d180a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sat, 2 Jun 2012 01:30:48 +0200 Subject: [PATCH 21/39] U-Boot PPC: Enable ppc440 FPU correctly * On ppc440, the FPU is implemented as an Auxiliary Processing Unit, we must therefore enable sending commands to it, in addition to setting the MSR bit. --- .../boot/platform/u-boot/arch/ppc/arch_cpu.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/system/boot/platform/u-boot/arch/ppc/arch_cpu.cpp b/src/system/boot/platform/u-boot/arch/ppc/arch_cpu.cpp index 09e1e2f862..5ea5245fb3 100644 --- a/src/system/boot/platform/u-boot/arch/ppc/arch_cpu.cpp +++ b/src/system/boot/platform/u-boot/arch/ppc/arch_cpu.cpp @@ -8,6 +8,7 @@ #include "cpu.h" +#include "board_config.h" #include #include @@ -44,7 +45,18 @@ check_cpu_features() { uint32 msr; - // we do need an FPU +#if BOARD_CPU_TYPE_PPC440 + // the FPU is implemented as an Auxiliary Processing Unit, + // so we must enable transfers by setting the DAPUIB bit to 0 + asm volatile( + "mfccr0 %%r3\n" + "\tlis %%r4,~(1<<(20-16))\n" + "\tand %%r3,%%r3,%%r4\n" + "\tmtccr0 %%r3" + : : : "r3", "r4"); +#endif + + // we do need an FPU for vsnprintf to work // on Sam460ex at least U-Boot doesn't enable the FPU for us msr = get_msr(); msr |= MSR_FP_AVAILABLE; From dc09611aad3a8c4b17c632703051ac8d64c96efd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sat, 2 Jun 2012 13:46:45 +0200 Subject: [PATCH 22/39] U-Boot: move gFDT declaration to shell.S * this avoids it falling into the BSS section which we clear quite late, and allows setting it from asm code if needed. --- src/system/boot/platform/u-boot/arch/arm/shell.S | 3 +++ src/system/boot/platform/u-boot/arch/ppc/shell.S | 3 +++ src/system/boot/platform/u-boot/start.cpp | 6 +++--- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/system/boot/platform/u-boot/arch/arm/shell.S b/src/system/boot/platform/u-boot/arch/arm/shell.S index 4e6274cc12..660fe2bbf8 100644 --- a/src/system/boot/platform/u-boot/arch/arm/shell.S +++ b/src/system/boot/platform/u-boot/arch/arm/shell.S @@ -86,4 +86,7 @@ SYMBOL(gUBootOS): // .byte 0 .long 0 SYMBOL_END(gUBootOS) +SYMBOL(gFDT): + .long 0 +SYMBOL_END(gFDT) diff --git a/src/system/boot/platform/u-boot/arch/ppc/shell.S b/src/system/boot/platform/u-boot/arch/ppc/shell.S index 3007373c89..f7df58639e 100644 --- a/src/system/boot/platform/u-boot/arch/ppc/shell.S +++ b/src/system/boot/platform/u-boot/arch/ppc/shell.S @@ -59,4 +59,7 @@ SYMBOL(gUBootOS): // .byte 0 .long 0 SYMBOL_END(gUBootOS) +SYMBOL(gFDT): + .long 0 +SYMBOL_END(gFDT) diff --git a/src/system/boot/platform/u-boot/start.cpp b/src/system/boot/platform/u-boot/start.cpp index 79dc482406..9b87c906f4 100644 --- a/src/system/boot/platform/u-boot/start.cpp +++ b/src/system/boot/platform/u-boot/start.cpp @@ -52,11 +52,11 @@ extern "C" int start_raw(int argc, const char **argv); extern "C" void dump_uimage(struct image_header *image); // declared in shell.S +// those are initialized to NULL but not in the BSS extern struct image_header *gUImage; extern uboot_gd *gUBootGlobalData; extern uint32 gUBootOS; - -void * gFDT = NULL; +extern void *gFDT; static uint32 sBootOptions; @@ -184,7 +184,7 @@ start_raw(int argc, const char **argv) dprintf("argc = %d\n", argc); for (i = 0; i < argc; i++) dprintf("argv[%d] @%lx = '%s'\n", i, (uint32)argv[i], argv[i]); - dprintf("os: %d\n", gUBootOS); + dprintf("os: %d\n", (int)gUBootOS); dprintf("gd @ %p\n", gUBootGlobalData); dprintf("gd->bd @ %p\n", gUBootGlobalData->bd); //dprintf("fb_base %p\n", (void*)gUBootGlobalData->fb_base); From 411272adfd60dcab0a42879cc617b59d9c333ca3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Sun, 3 Jun 2012 22:19:51 +0200 Subject: [PATCH 23/39] Work in progress on xHCI bus driver * added a thread to handle events, locking wasn't easy in an interrupt handler * the td struct can now track several buffers instead of just one. * use Transfer::Data*() instead of Vector*() for the time being until support for fragmented transfers is done * added CreateDescriptorChain, WriteDescriptorChain and ReadDescriptorChain, chained tds not working yet though. * added a mutex lock per enabled endpoint, lock when touching the endpoint transfer ring. * correctly configure interval and average trb length for endpoint contexts. * interrupt transfers seem to work on real hardware * xhci qemu driver doesn't advance ring dequeue pointers on link trbs, thus accessing freed trbs that could already be reused, leading to crash. --- src/add-ons/kernel/busses/usb/xhci.cpp | 460 ++++++++++++++---- src/add-ons/kernel/busses/usb/xhci.h | 29 +- src/add-ons/kernel/busses/usb/xhci_hardware.h | 3 +- 3 files changed, 383 insertions(+), 109 deletions(-) diff --git a/src/add-ons/kernel/busses/usb/xhci.cpp b/src/add-ons/kernel/busses/usb/xhci.cpp index 2348264e3f..303e165d48 100644 --- a/src/add-ons/kernel/busses/usb/xhci.cpp +++ b/src/add-ons/kernel/busses/usb/xhci.cpp @@ -124,6 +124,8 @@ XHCI::XHCI(pci_info *info, Stack *stack) fPortCount(0), fSlotCount(0), fScratchpadCount(0), + fEventSem(-1), + fEventThread(-1), fEventIdx(0), fCmdIdx(0), fEventCcs(1), @@ -233,7 +235,8 @@ XHCI::XHCI(pci_info *info, Stack *stack) fCmdCompSem = create_sem(0, "XHCI Command Complete"); fFinishTransfersSem = create_sem(0, "XHCI Finish Transfers"); - if (fFinishTransfersSem < B_OK || fCmdCompSem < B_OK) { + fEventSem = create_sem(0, "XHCI Event"); + if (fFinishTransfersSem < B_OK || fCmdCompSem < B_OK || fEventSem < B_OK) { TRACE_ERROR("failed to create semaphores\n"); return; } @@ -243,6 +246,11 @@ XHCI::XHCI(pci_info *info, Stack *stack) B_NORMAL_PRIORITY, (void *)this); resume_thread(fFinishThread); + // create finisher service thread + fEventThread = spawn_kernel_thread(EventThread, "xhci event thread", + B_NORMAL_PRIORITY, (void *)this); + resume_thread(fEventThread); + // Install the interrupt handler TRACE("installing interrupt handler\n"); install_io_interrupt_handler(fPCIInfo->u.h0.interrupt_line, @@ -267,12 +275,14 @@ XHCI::~XHCI() fStopThreads = true; delete_sem(fCmdCompSem); delete_sem(fFinishTransfersSem); + delete_sem(fEventSem); delete_area(fRegisterArea); delete_area(fErstArea); for (uint32 i = 0; i < fScratchpadCount; i++) delete_area(fScratchpadArea[i]); delete_area(fDcbaArea); wait_for_thread(fFinishThread, &result); + wait_for_thread(fEventThread, &result); put_module(B_PCI_MODULE_NAME); } @@ -485,7 +495,7 @@ XHCI::SubmitControlRequest(Transfer *transfer) usb_request_data *requestData = transfer->RequestData(); bool directionIn = (requestData->RequestType & USB_REQTYPE_DEVICE_IN) != 0; - TRACE("SubmitControlRequest()\n"); + TRACE("SubmitControlRequest() length %d\n", requestData->Length); xhci_td *setupDescriptor = CreateDescriptor(requestData->Length); @@ -505,7 +515,7 @@ XHCI::SubmitControlRequest(Transfer *transfer) if (requestData->Length > 0) { // set DataStage if any - setupDescriptor->trbs[index].qwtrb0 = setupDescriptor->buffer_phy; + setupDescriptor->trbs[index].qwtrb0 = setupDescriptor->buffer_phy[0]; setupDescriptor->trbs[index].dwtrb2 = TRB_2_IRQ(0) | TRB_2_BYTES(requestData->Length) | TRB_2_TD_SIZE(transfer->VectorCount()); @@ -522,7 +532,7 @@ XHCI::SubmitControlRequest(Transfer *transfer) | ((directionIn && requestData->Length > 0) ? 0 : TRB_3_DIR_IN) | TRB_3_IOC_BIT | TRB_3_CYCLE_BIT; - setupDescriptor->last_used = index; + setupDescriptor->trb_count = index + 1; xhci_endpoint *endpoint = (xhci_endpoint *)pipe->ControllerCookie(); uint8 id = XHCI_ENDPOINT_ID(pipe); @@ -542,33 +552,41 @@ XHCI::SubmitControlRequest(Transfer *transfer) status_t XHCI::SubmitNormalRequest(Transfer *transfer) { - TRACE("SubmitNormalRequest()\n"); + TRACE("SubmitNormalRequest() length %ld\n", transfer->DataLength()); Pipe *pipe = transfer->TransferPipe(); - bool directionIn = (pipe->Direction() == Pipe::In); - - xhci_td *normalDescriptor = CreateDescriptor(transfer->VectorLength()); - - // set NormalStage - uint8 index = 0; - normalDescriptor->trbs[index].qwtrb0 = normalDescriptor->buffer_phy; - normalDescriptor->trbs[index].dwtrb2 = TRB_2_IRQ(0) - | TRB_2_BYTES(transfer->VectorLength()) - | TRB_2_TD_SIZE(transfer->VectorCount()); - normalDescriptor->trbs[index].dwtrb3 = TRB_3_TYPE(TRB_TYPE_NORMAL) - | TRB_3_CYCLE_BIT | TRB_3_IOC_BIT; - - if (!directionIn) { - memcpy(normalDescriptor->buffer_log, - (uint8 *)transfer->Vector()[0].iov_base, transfer->VectorLength()); - } - normalDescriptor->last_used = index; - - xhci_endpoint *endpoint = (xhci_endpoint *)pipe->ControllerCookie(); uint8 id = XHCI_ENDPOINT_ID(pipe); if (id >= XHCI_MAX_ENDPOINTS) return B_BAD_VALUE; - normalDescriptor->transfer = transfer; - _LinkDescriptorForPipe(normalDescriptor, endpoint); + bool directionIn = (pipe->Direction() == Pipe::In); + + xhci_td *descriptor = CreateDescriptorChain(transfer->DataLength()); + descriptor->trb_count = descriptor->buffer_count; + + // set NormalStage + uint8 index; + for (index = 0; index < descriptor->buffer_count; index++) { + descriptor->trbs[index].qwtrb0 = descriptor->buffer_phy[index]; + descriptor->trbs[index].dwtrb2 = TRB_2_IRQ(0) + | TRB_2_BYTES(descriptor->buffer_size[index]) + | TRB_2_TD_SIZE(descriptor->trb_count); + descriptor->trbs[index].dwtrb3 = TRB_3_TYPE(TRB_TYPE_NORMAL) + | TRB_3_CYCLE_BIT; + } + if (descriptor->trb_count > 0) + descriptor->trbs[index - 1].dwtrb3 |= TRB_3_IOC_BIT; + + if (!directionIn) { + TRACE("copying out iov count %ld\n", transfer->VectorCount()); + WriteDescriptorChain(descriptor, transfer->Vector(), + transfer->VectorCount()); + } + /* memcpy(descriptor->buffer_log[index], + (uint8 *)transfer->Vector()[index].iov_base, transfer->VectorLength()); + }*/ + + xhci_endpoint *endpoint = (xhci_endpoint *)pipe->ControllerCookie(); + descriptor->transfer = transfer; + _LinkDescriptorForPipe(descriptor, endpoint); TRACE("SubmitNormalRequest() request linked\n"); @@ -682,6 +700,52 @@ XHCI::AddTo(Stack *stack) } +xhci_td * +XHCI::CreateDescriptorChain(size_t bufferSize) +{ + size_t packetSize = B_PAGE_SIZE * 16; + int32 trbCount = (bufferSize + packetSize - 1) / packetSize; + // keep one trb for linking + int32 tdCount = (trbCount + XHCI_MAX_TRBS_PER_TD - 2) / (XHCI_MAX_TRBS_PER_TD - 1); + + xhci_td *first = NULL; + xhci_td *last = NULL; + for (int32 i = 0; i < tdCount; i++) { + xhci_td *descriptor = CreateDescriptor(0); + if (!descriptor) { + //FreeDescriptorChain(firstDescriptor); + return NULL; + } else if (first == NULL) + first = descriptor; + + uint8 trbs = min_c(trbCount, XHCI_MAX_TRBS_PER_TD); + TRACE("CreateDescriptorChain trbs %d for td %ld\n", trbs, i); + for (int j = 0; j < trbs; j++) { + if (fStack->AllocateChunk(&descriptor->buffer_log[j], + (void **)&descriptor->buffer_phy[j], + min_c(packetSize, bufferSize)) < B_OK) { + TRACE_ERROR("unable to allocate space for the buffer (size %ld)\n", + bufferSize); + return NULL; + } + + descriptor->buffer_size[j] = min_c(packetSize, bufferSize); + bufferSize -= descriptor->buffer_size[j]; + TRACE("CreateDescriptorChain allocated %ld for trb %d\n", + descriptor->buffer_size[j], j); + } + + descriptor->buffer_count = trbs; + trbCount -= trbs; + if (last != NULL) + last->next = descriptor; + last = descriptor; + } + + return first; +} + + xhci_td * XHCI::CreateDescriptor(size_t bufferSize) { @@ -695,15 +759,17 @@ XHCI::CreateDescriptor(size_t bufferSize) } result->this_phy = (addr_t)physicalAddress; - result->buffer_size = bufferSize; + result->buffer_size[0] = bufferSize; + result->trb_count = 0; + result->buffer_count = 1; if (bufferSize <= 0) { - result->buffer_log = NULL; - result->buffer_phy = 0; + result->buffer_log[0] = NULL; + result->buffer_phy[0] = 0; return result; } - if (fStack->AllocateChunk(&result->buffer_log, - (void **)&result->buffer_phy, bufferSize) < B_OK) { + if (fStack->AllocateChunk(&result->buffer_log[0], + (void **)&result->buffer_phy[0], bufferSize) < B_OK) { TRACE_ERROR("unable to allocate space for the buffer (size %ld)\n", bufferSize); fStack->FreeChunk(result, (void *)result->this_phy, sizeof(xhci_td)); @@ -720,9 +786,13 @@ XHCI::FreeDescriptor(xhci_td *descriptor) if (!descriptor) return; - if (descriptor->buffer_log) { - fStack->FreeChunk(descriptor->buffer_log, - (void *)descriptor->buffer_phy, descriptor->buffer_size); + for (int i = 0; i < descriptor->buffer_count; i++) { + if (descriptor->buffer_size[i] == 0) + continue; + TRACE("FreeDescriptor buffer %d buffer_size %ld\n", i, + descriptor->buffer_size[i]); + fStack->FreeChunk(descriptor->buffer_log[i], + (void *)descriptor->buffer_phy[i], descriptor->buffer_size[i]); } fStack->FreeChunk(descriptor, (void *)descriptor->this_phy, @@ -730,6 +800,116 @@ XHCI::FreeDescriptor(xhci_td *descriptor) } +size_t +XHCI::WriteDescriptorChain(xhci_td *descriptor, iovec *vector, + size_t vectorCount) +{ + xhci_td *current = descriptor; + uint8 trbIndex = 0; + size_t actualLength = 0; + uint8 vectorIndex = 0; + size_t vectorOffset = 0; + size_t bufferOffset = 0; + + while (current != NULL) { + if (current->buffer_log == NULL) + break; + + while (true) { + size_t length = min_c(current->buffer_size[trbIndex] - bufferOffset, + vector[vectorIndex].iov_len - vectorOffset); + + TRACE("copying %ld bytes to bufferOffset %ld from" + " vectorOffset %ld at index %d of %ld\n", length, bufferOffset, + vectorOffset, vectorIndex, vectorCount); + memcpy((uint8 *)current->buffer_log[trbIndex] + bufferOffset, + (uint8 *)vector[vectorIndex].iov_base + vectorOffset, length); + + actualLength += length; + vectorOffset += length; + bufferOffset += length; + + if (vectorOffset >= vector[vectorIndex].iov_len) { + if (++vectorIndex >= vectorCount) { + TRACE("wrote descriptor chain (%ld bytes, no more vectors)\n", + actualLength); + return actualLength; + } + + vectorOffset = 0; + } + + if (bufferOffset >= current->buffer_size[trbIndex]) { + if (++trbIndex >= current->buffer_count) + break; + bufferOffset = 0; + } + } + + current = current->next; + trbIndex = 0; + } + + TRACE("wrote descriptor chain (%ld bytes)\n", actualLength); + return actualLength; +} + + +size_t +XHCI::ReadDescriptorChain(xhci_td *descriptor, iovec *vector, + size_t vectorCount) +{ + xhci_td *current = descriptor; + uint8 trbIndex = 0; + size_t actualLength = 0; + uint8 vectorIndex = 0; + size_t vectorOffset = 0; + size_t bufferOffset = 0; + + while (current != NULL) { + if (current->buffer_log == NULL) + break; + + while (true) { + size_t length = min_c(current->buffer_size[trbIndex] - bufferOffset, + vector[vectorIndex].iov_len - vectorOffset); + + TRACE("copying %ld bytes to vectorOffset %ld from" + " bufferOffset %ld at index %d of %ld\n", length, vectorOffset, + bufferOffset, vectorIndex, vectorCount); + memcpy((uint8 *)vector[vectorIndex].iov_base + vectorOffset, + (uint8 *)current->buffer_log[trbIndex] + bufferOffset, length); + + actualLength += length; + vectorOffset += length; + bufferOffset += length; + + if (vectorOffset >= vector[vectorIndex].iov_len) { + if (++vectorIndex >= vectorCount) { + TRACE("read descriptor chain (%ld bytes, no more vectors)\n", + actualLength); + return actualLength; + } + + vectorOffset = 0; + } + + if (bufferOffset >= current->buffer_size[trbIndex]) { + if (++trbIndex >= current->buffer_count) + break; + bufferOffset = 0; + } + } + + current = current->next; + trbIndex = 0; + } + + TRACE("read descriptor chain (%ld bytes)\n", actualLength); + return actualLength; +} + + Device * XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 hubPort, usb_speed speed) @@ -768,6 +948,7 @@ XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 hubPort, return NULL; } + memset(device->input_ctx, 0, sizeof(*device->input_ctx)); device->input_ctx->input.dropFlags = 0; device->input_ctx->input.addFlags = 3; @@ -825,6 +1006,7 @@ XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 hubPort, delete_area(device->input_ctx_area); return NULL; } + memset(device->device_ctx, 0, sizeof(*device->device_ctx)); device->trb_area = fStack->AllocateArea((void **)&device->trbs, (void**)&device->trb_addr, sizeof(*device->trbs), "XHCI endpoint trbs"); @@ -862,7 +1044,7 @@ XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 hubPort, // configure the Control endpoint 0 (type 4) if (ConfigureEndpoint(slot, 0, 4, device->trb_addr, 0, 1, 1, 0, - maxPacketSize, maxPacketSize) != B_OK) { + maxPacketSize, maxPacketSize, speed) != B_OK) { TRACE_ERROR("unable to configure default control endpoint\n"); return NULL; } @@ -873,6 +1055,7 @@ XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 hubPort, device->endpoints[0].used = 0; device->endpoints[0].current = 0; device->endpoints[0].trb_addr = device->trb_addr; + mutex_init(&device->endpoints[0].lock, "xhci endpoint lock"); // device should get to addressed state (bsr = 0) if (SetAddress(device->input_ctx_addr, false, slot) != B_OK) { @@ -974,6 +1157,13 @@ XHCI::_InsertEndpointForPipe(Pipe *pipe) return B_BAD_VALUE; if (id > 0) { + if (SLOT_0_NUM_ENTRIES_GET(device->device_ctx->slot.dwslot0) == 1) { + device->input_ctx->slot.dwslot0 &= ~(SLOT_0_NUM_ENTRIES(0x1f)); + device->input_ctx->slot.dwslot0 |= + SLOT_0_NUM_ENTRIES(XHCI_MAX_ENDPOINTS - 1); + EvaluateContext(device->input_ctx_addr, device->slot); + } + device->endpoints[id].device = device; device->endpoints[id].trbs = device->trbs + id * XHCI_MAX_TRANSFERS; @@ -981,6 +1171,7 @@ XHCI::_InsertEndpointForPipe(Pipe *pipe) device->endpoints[id].used = 0; device->endpoints[id].trb_addr = device->trb_addr + id * XHCI_MAX_TRANSFERS * sizeof(xhci_trb); + mutex_init(&device->endpoints[id].lock, "xhci endpoint lock"); TRACE("_InsertEndpointForPipe trbs device %p endpoint %p\n", device->trbs, device->endpoints[id].trbs); @@ -1013,7 +1204,8 @@ XHCI::_InsertEndpointForPipe(Pipe *pipe) if (ConfigureEndpoint(device->slot, id, type, device->endpoints[id].trb_addr, pipe->Interval(), - 1, 1, 0, pipe->MaxPacketSize(), pipe->MaxPacketSize()) != B_OK) { + 1, 1, 0, pipe->MaxPacketSize(), pipe->MaxPacketSize(), + usbDevice->Speed()) != B_OK) { TRACE_ERROR("unable to configure endpoint\n"); return B_ERROR; } @@ -1021,10 +1213,16 @@ XHCI::_InsertEndpointForPipe(Pipe *pipe) EvaluateContext(device->input_ctx_addr, device->slot); ConfigureEndpoint(device->input_ctx_addr, false, device->slot); - device->state = XHCI_STATE_CONFIGURED; + TRACE("device: address 0x%x state 0x%lx\n", device->address, + SLOT_3_SLOT_STATE_GET(device->device_ctx->slot.dwslot3)); + TRACE("endpoint[0] state 0x%lx\n", + ENDPOINT_0_STATE_GET(device->device_ctx->endpoints[0].dwendpoint0)); + TRACE("endpoint[%d] state 0x%lx\n", id, + ENDPOINT_0_STATE_GET(device->device_ctx->endpoints[id].dwendpoint0)); + device->state = XHCI_STATE_CONFIGURED; } pipe->SetControllerCookie(&device->endpoints[id]); - + TRACE("_InsertEndpointForPipe for pipe %p at id %d\n", pipe, id); return B_OK; @@ -1046,6 +1244,7 @@ status_t XHCI::_LinkDescriptorForPipe(xhci_td *descriptor, xhci_endpoint *endpoint) { TRACE("_LinkDescriptorForPipe\n"); + MutexLocker endpointLocker(endpoint->lock); if (endpoint->used >= XHCI_MAX_TRANSFERS) return B_BAD_VALUE; @@ -1062,11 +1261,10 @@ XHCI::_LinkDescriptorForPipe(xhci_td *descriptor, xhci_endpoint *endpoint) TRACE("_LinkDescriptorForPipe current %d, next %d\n", current, next); // compute next link - uint8 lastUsed = descriptor->last_used; addr_t addr = endpoint->trb_addr + next * sizeof(struct xhci_trb); - descriptor->trbs[lastUsed + 1].qwtrb0 = addr; - descriptor->trbs[lastUsed + 1].dwtrb2 = TRB_2_IRQ(0); - descriptor->trbs[lastUsed + 1].dwtrb3 = TRB_3_TYPE(TRB_TYPE_LINK) + descriptor->trbs[descriptor->trb_count].qwtrb0 = addr; + descriptor->trbs[descriptor->trb_count].dwtrb2 = TRB_2_IRQ(0); + descriptor->trbs[descriptor->trb_count].dwtrb3 = TRB_3_TYPE(TRB_TYPE_LINK) | TRB_3_IOC_BIT | TRB_3_CYCLE_BIT; endpoint->trbs[next].qwtrb0 = 0; @@ -1092,6 +1290,7 @@ status_t XHCI::_UnlinkDescriptorForPipe(xhci_td *descriptor, xhci_endpoint *endpoint) { TRACE("_UnlinkDescriptorForPipe\n"); + MutexLocker endpointLocker(endpoint->lock); endpoint->used--; if (descriptor == endpoint->td_head) { endpoint->td_head = descriptor->next; @@ -1115,7 +1314,7 @@ XHCI::_UnlinkDescriptorForPipe(xhci_td *descriptor, xhci_endpoint *endpoint) status_t XHCI::ConfigureEndpoint(uint8 slot, uint8 number, uint8 type, uint64 ringAddr, uint16 interval, uint8 maxPacketCount, uint8 mult, uint8 fpsShift, uint16 maxPacketSize, - uint16 maxFrameSize) + uint16 maxFrameSize, usb_speed speed) { struct xhci_device *device = &fDevices[slot]; struct xhci_endpoint_ctx *endpoint = &device->input_ctx->endpoints[number]; @@ -1127,6 +1326,26 @@ XHCI::ConfigureEndpoint(uint8 slot, uint8 number, uint8 type, uint64 ringAddr, u endpoint->dwendpoint0 = ENDPOINT_0_STATE(0) | ENDPOINT_0_MAXPSTREAMS(0); // add mult for isochronous and interrupt types + switch (speed) { + case USB_SPEED_LOWSPEED: + case USB_SPEED_FULLSPEED: + fpsShift += 3; + break; + default: + break; + } + switch (type) { + case 1: + case 5: + if (fpsShift > 3) + fpsShift--; + case 3: + case 7: + endpoint->dwendpoint0 |= ENDPOINT_0_INTERVAL(fpsShift); + break; + default: + break; + } // add interval endpoint->dwendpoint1 = ENDPOINT_1_EPTYPE(type) | ENDPOINT_1_MAXBURST(maxPacketCount) @@ -1142,9 +1361,11 @@ XHCI::ConfigureEndpoint(uint8 slot, uint8 number, uint8 type, uint64 ringAddr, u case 3: case 5: case 7: - endpoint->dwendpoint4 = ENDPOINT_4_AVGTRBLENGTH(maxFrameSize) - | ENDPOINT_4_MAXESITPAYLOAD(maxFrameSize); + endpoint->dwendpoint4 = ENDPOINT_4_AVGTRBLENGTH(min_c(maxFrameSize, + B_PAGE_SIZE)) | ENDPOINT_4_MAXESITPAYLOAD(maxFrameSize); break; + default: + endpoint->dwendpoint4 = ENDPOINT_4_AVGTRBLENGTH(B_PAGE_SIZE); } TRACE("endpoint 0x%lx 0x%lx 0x%llx 0x%lx\n", endpoint->dwendpoint0, @@ -1406,55 +1627,8 @@ XHCI::Interrupt() } TRACE("Event Interrupt\n"); - uint16 i = fEventIdx; - uint8 j = fEventCcs; - uint8 t = 2; - - while (1) { - temp = fEventRing[i].dwtrb3; - uint8 k = (temp & TRB_3_CYCLE_BIT) ? 1 : 0; - if (j != k) - break; - - uint8 event = TRB_3_TYPE_GET(temp); - - TRACE("event[%u] = %u (0x%016llx 0x%08lx 0x%08lx)\n", i, event, - fEventRing[i].qwtrb0, fEventRing[i].dwtrb2, fEventRing[i].dwtrb3); - switch (event) { - case TRB_TYPE_COMMAND_COMPLETION: - HandleCmdComplete(&fEventRing[i]); - result = B_INVOKE_SCHEDULER; - break; - case TRB_TYPE_TRANSFER: - HandleTransferComplete(&fEventRing[i]); - result = B_INVOKE_SCHEDULER; - break; - case TRB_TYPE_PORT_STATUS_CHANGE: - TRACE("port change detected\n"); - break; - default: - TRACE_ERROR("Unhandled event = %u\n", event); - break; - } - - i++; - if (i == XHCI_MAX_EVENTS) { - i = 0; - j ^= 1; - if (!--t) - break; - } - } - - fEventIdx = i; - fEventCcs = j; - - uint64 addr = fErst->rs_addr + i * sizeof(xhci_trb); - addr |= ERST_EHB; - WriteRunReg32(XHCI_ERDP_LO(0), (uint32)addr); - WriteRunReg32(XHCI_ERDP_HI(0), (uint32)(addr >> 32)); - - return result; + release_sem_etc(fEventSem, 1, B_DO_NOT_RESCHEDULE); + return B_INVOKE_SCHEDULER; } @@ -1552,8 +1726,10 @@ XHCI::HandleTransferComplete(xhci_trb *trb) _UnlinkDescriptorForPipe(td, endpoint); // add descriptor to finished list (to be processed and freed) + Lock(); td->next = fFinishedHead; fFinishedHead = td; + Unlock(); release_sem(fFinishTransfersSem); break; } @@ -1735,6 +1911,76 @@ XHCI::ResetDevice(uint8 slot) } +int32 +XHCI::EventThread(void* data) +{ + ((XHCI *)data)->CompleteEvents(); + return B_OK; +} + + +void +XHCI::CompleteEvents() +{ + while (!fStopThreads) { + if (acquire_sem(fEventSem) < B_OK) + continue; + + // eat up sems that have been released by multiple interrupts + int32 semCount = 0; + get_sem_count(fEventSem, &semCount); + if (semCount > 0) + acquire_sem_etc(fEventSem, semCount, B_RELATIVE_TIMEOUT, 0); + + uint16 i = fEventIdx; + uint8 j = fEventCcs; + uint8 t = 2; + + while (1) { + uint32 temp = fEventRing[i].dwtrb3; + uint8 k = (temp & TRB_3_CYCLE_BIT) ? 1 : 0; + if (j != k) + break; + + uint8 event = TRB_3_TYPE_GET(temp); + + TRACE("event[%u] = %u (0x%016llx 0x%08lx 0x%08lx)\n", i, event, + fEventRing[i].qwtrb0, fEventRing[i].dwtrb2, fEventRing[i].dwtrb3); + switch (event) { + case TRB_TYPE_COMMAND_COMPLETION: + HandleCmdComplete(&fEventRing[i]); + break; + case TRB_TYPE_TRANSFER: + HandleTransferComplete(&fEventRing[i]); + break; + case TRB_TYPE_PORT_STATUS_CHANGE: + TRACE("port change detected\n"); + break; + default: + TRACE_ERROR("Unhandled event = %u\n", event); + break; + } + + i++; + if (i == XHCI_MAX_EVENTS) { + i = 0; + j ^= 1; + if (!--t) + break; + } + } + + fEventIdx = i; + fEventCcs = j; + + uint64 addr = fErst->rs_addr + i * sizeof(xhci_trb); + addr |= ERST_EHB; + WriteRunReg32(XHCI_ERDP_LO(0), (uint32)addr); + WriteRunReg32(XHCI_ERDP_HI(0), (uint32)(addr >> 32)); + } +} + + int32 XHCI::FinishThread(void* data) { @@ -1756,28 +2002,40 @@ XHCI::FinishTransfers() if (semCount > 0) acquire_sem_etc(fFinishTransfersSem, semCount, B_RELATIVE_TIMEOUT, 0); + Lock(); TRACE("finishing transfers\n"); while (fFinishedHead != NULL) { xhci_td* td = fFinishedHead; fFinishedHead = td->next; td->next = NULL; + Unlock(); Transfer* transfer = td->transfer; bool directionIn = (transfer->TransferPipe()->Direction() != Pipe::Out); usb_request_data *requestData = transfer->RequestData(); - + // TODO check event status_t callbackStatus = B_OK; size_t actualLength = requestData ? requestData->Length - : transfer->VectorLength(); - if (directionIn) { - memcpy((uint8 *)transfer->Vector()[0].iov_base, - td->buffer_log, actualLength); + : transfer->DataLength(); + TRACE("finishing transfer td %p\n", td); + if (directionIn && actualLength > 0) { + if (requestData) { + TRACE("copying in data %d bytes\n", requestData->Length); + memcpy((uint8 *)transfer->Vector()[0].iov_base, + td->buffer_log[0], requestData->Length); + } else { + TRACE("copying in iov count %ld\n", transfer->VectorCount()); + ReadDescriptorChain(td, transfer->Vector(), + transfer->VectorCount()); + } } transfer->Finished(callbackStatus, actualLength); - + FreeDescriptor(td); + Lock(); } + Unlock(); } } diff --git a/src/add-ons/kernel/busses/usb/xhci.h b/src/add-ons/kernel/busses/usb/xhci.h index 0fa92eba87..0983aa84b2 100644 --- a/src/add-ons/kernel/busses/usb/xhci.h +++ b/src/add-ons/kernel/busses/usb/xhci.h @@ -33,16 +33,17 @@ enum xhci_state { typedef struct xhci_td { - struct xhci_trb trbs[18]; + struct xhci_trb trbs[XHCI_MAX_TRBS_PER_TD]; - addr_t buffer_phy; - addr_t this_phy; // A physical pointer to this address - void *buffer_log; // Pointer to the logical buffer - size_t buffer_size; // Size of the buffer + addr_t this_phy; // A physical pointer to this address + addr_t buffer_phy[XHCI_MAX_TRBS_PER_TD]; + void *buffer_log[XHCI_MAX_TRBS_PER_TD]; // Pointer to the logical buffer + size_t buffer_size[XHCI_MAX_TRBS_PER_TD]; // Size of the buffer + uint8 buffer_count; struct xhci_td *next; - uint8 last_used; Transfer *transfer; + uint8 trb_count; } xhci_td __attribute__((__aligned__(16))); @@ -53,6 +54,7 @@ typedef struct xhci_endpoint { addr_t trb_addr; uint8 used; uint8 current; + mutex lock; } xhci_endpoint; @@ -99,7 +101,8 @@ public: uint8 type, uint64 ringAddr, uint16 interval, uint8 maxPacketCount, uint8 mult, uint8 fpsShift, - uint16 maxPacketSize, uint16 maxFrameSize); + uint16 maxPacketSize, uint16 maxFrameSize, + usb_speed speed); virtual void FreeDevice(Device *device); status_t _InsertEndpointForPipe(Pipe *pipe); @@ -125,14 +128,24 @@ private: static int32 InterruptHandler(void *data); int32 Interrupt(); + // Event management + static int32 EventThread(void *data); + void CompleteEvents(); + // Transfer management static int32 FinishThread(void *data); void FinishTransfers(); // Descriptor xhci_td * CreateDescriptor(size_t bufferSize); + xhci_td * CreateDescriptorChain(size_t bufferSize); void FreeDescriptor(xhci_td *descriptor); + size_t WriteDescriptorChain(xhci_td *descriptor, + iovec *vector, size_t vectorCount); + size_t ReadDescriptorChain(xhci_td *descriptor, + iovec *vector, size_t vectorCount); + status_t _LinkDescriptorForPipe(xhci_td *descriptor, xhci_endpoint *endpoint); status_t _UnlinkDescriptorForPipe(xhci_td *descriptor, @@ -230,6 +243,8 @@ private: // Devices struct xhci_device fDevices[XHCI_MAX_DEVICES]; + sem_id fEventSem; + thread_id fEventThread; uint16 fEventIdx; uint16 fCmdIdx; uint8 fEventCcs; diff --git a/src/add-ons/kernel/busses/usb/xhci_hardware.h b/src/add-ons/kernel/busses/usb/xhci_hardware.h index 82fffafe8c..ebd3d43ac3 100644 --- a/src/add-ons/kernel/busses/usb/xhci_hardware.h +++ b/src/add-ons/kernel/busses/usb/xhci_hardware.h @@ -266,13 +266,14 @@ #define XHCI_MAX_SCRATCHPADS 32 #define XHCI_MAX_DEVICES 128 #define XHCI_MAX_TRANSFERS 4 +#define XHCI_MAX_TRBS_PER_TD 18 struct xhci_trb { uint64 qwtrb0; uint32 dwtrb2; uint32 dwtrb3; -} __attribute__((__aligned__(4)));; +} __attribute__((__aligned__(4))); struct xhci_segment { From 931b441f6388b776d8d5f10058425b3fccbdd6c9 Mon Sep 17 00:00:00 2001 From: Humdinger Date: Mon, 4 Jun 2012 14:51:14 +0200 Subject: [PATCH 24/39] Added info on configuring GRUB via os-prober, see #8578. --- src/apps/installer/InstallerApp.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/apps/installer/InstallerApp.cpp b/src/apps/installer/InstallerApp.cpp index 1627714162..d7d7d4baa8 100644 --- a/src/apps/installer/InstallerApp.cpp +++ b/src/apps/installer/InstallerApp.cpp @@ -130,6 +130,14 @@ InstallerApp::ReadyToRun() "differently.\n\n\n"); infoText << B_TRANSLATE( "2.1) GRUB 1\n"); + infoText << B_TRANSLATE( + "Starting with os-prober v1.44 (e.g. in Ubuntu 11.04 or later), Haiku " + "should be recognized out of the box. To add Haiku to the GRUB menu, " + "open a Terminal and enter:\n\n"); + infoText << B_TRANSLATE( + "\tsudo update-grub\n\n\n"); + infoText << B_TRANSLATE( + "2.2) GRUB 1\n"); infoText << B_TRANSLATE( "Configure your /boot/grub/menu.lst by launching your favorite " "editor from a Terminal like this:\n\n"); @@ -163,7 +171,7 @@ InstallerApp::ReadyToRun() infoText << B_TRANSLATE( "You can see the correct partition in GParted for example.\n\n\n"); infoText << B_TRANSLATE( - "2.2) GRUB 2\n"); + "2.3) GRUB 2\n"); infoText << B_TRANSLATE( "Newer versions of GRUB use an extra configuration file to add " "custom entries to the boot menu. To add them to the top, you have " @@ -213,8 +221,8 @@ InstallerApp::ReadyToRun() "\tsudo update-grub\n\n\n"); infoText << B_TRANSLATE( "3) When you successfully boot into Haiku for the first time, make " - "sure to read our \"Welcome\" documentation, there is a link on the " - "Desktop.\n\n"); + "sure to read our \"Welcome\" and \"Userguide\" documentation. There " + "are links on the Desktop and in WebPositive's bookmarks.\n\n"); infoText << B_TRANSLATE( "Have fun and thanks a lot for trying out Haiku! We hope you like it!"); From 76f066c2a103c6e018f0ecb475aaadfa37f6c087 Mon Sep 17 00:00:00 2001 From: Humdinger Date: Mon, 4 Jun 2012 15:35:28 +0200 Subject: [PATCH 25/39] Newly built Beam package fixes ticket #8611 --- build/jam/OptionalPackages | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/jam/OptionalPackages b/build/jam/OptionalPackages index c20f5e8169..d612b8ed9e 100644 --- a/build/jam/OptionalPackages +++ b/build/jam/OptionalPackages @@ -209,8 +209,8 @@ if [ IsOptionalHaikuImagePackageAdded Beam ] { } else if $(HAIKU_GCC_VERSION[1]) >= 4 && ! $(isHybridBuild) { Echo "No optional package Beam available for gcc4" ; } else { - InstallOptionalHaikuImagePackage Beam-1.2alpha-x86-gcc2-2010-04-29.zip - : $(baseURL)/Beam-1.2alpha-x86-gcc2-2010-04-29.zip ; + InstallOptionalHaikuImagePackage Beam-1.2alpha-x86-gcc2-2012-06-04.zip + : $(baseURL)/Beam-1.2alpha-x86-gcc2-2012-06-04.zip ; AddSymlinkToHaikuImage home config settings deskbar Applications : /boot/apps/Beam/Beam ; } From bd12d75f964cdfcda2938aedb88b39a73aa35f0c Mon Sep 17 00:00:00 2001 From: Alexander von Gluck IV Date: Mon, 4 Jun 2012 12:34:36 -0500 Subject: [PATCH 26/39] cpuid: consolidate tools to one tool * Don't move vendor mask * Place extended cpu info before vendor *if* amd cpu family == 0xF --- src/tools/amdcpuid.c | 109 ------------------------ src/tools/{intelcpuid.c => cpuidtool.c} | 33 ++++--- 2 files changed, 22 insertions(+), 120 deletions(-) delete mode 100644 src/tools/amdcpuid.c rename src/tools/{intelcpuid.c => cpuidtool.c} (69%) diff --git a/src/tools/amdcpuid.c b/src/tools/amdcpuid.c deleted file mode 100644 index 9c2500e9d6..0000000000 --- a/src/tools/amdcpuid.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2012 Haiku, Inc. All rights reserved. - * Distributed under the terms of the MIT License. - * - * Authors: - * Alexander von Gluck, kallisti5@unixzen.com - */ - -/* - * Pass an AMD CPUID in hex, and get out a CPUID for OS.h - */ - - -#include -#include -#include - - -#define AMD_VENDOR 0x110000 - -#define EXT_FAMILY_MASK 0xF00000 -#define EXT_MODEL_MASK 0x0F0000 -#define FAMILY_MASK 0x000F00 -#define MODEL_MASK 0x0000F0 -#define STEPPING_MASK 0x00000F - - -// Converts a hexadecimal string to integer -static int xtoi(const char* xs, unsigned int* result) -{ - size_t szlen = strlen(xs); - int i, xv, fact; - - if (szlen > 0) { - // Converting more than 32bit hexadecimal value? - if (szlen>8) return 2; // exit - - // Begin conversion here - *result = 0; - fact = 1; - - // Run until no more character to convert - for (i = szlen - 1; i>=0 ;i--) { - if (isxdigit(*(xs+i))) { - if (*(xs+i)>=97) { - xv = ( *(xs+i) - 97) + 10; - } else if ( *(xs+i) >= 65) { - xv = (*(xs+i) - 65) + 10; - } else { - xv = *(xs+i) - 48; - } - *result += (xv * fact); - fact *= 16; - } else { - // Conversion was abnormally terminated - // by non hexadecimal digit, hence - // returning only the converted with - // an error value 4 (illegal hex character) - return 4; - } - } - } - - // Nothing to convert - return 1; -} - - -int -main(int argc, char *argv[]) -{ - if (argc != 2) { - printf("Provide the AMD cpuid in hex, and you will get how we id it\n"); - printf("usage: amdcpuid \n"); - return 1; - } - - unsigned int cpuid; - xtoi(argv[1], &cpuid); - - printf("cpuid: 0x%X\n", cpuid); - - unsigned int extFam = (cpuid & EXT_FAMILY_MASK) >> 20; - unsigned int extMod = (cpuid & EXT_MODEL_MASK) >> 16; - unsigned int family = (cpuid & FAMILY_MASK) >> 8; - unsigned int model = (cpuid & MODEL_MASK) >> 4; - unsigned int stepping = (cpuid & STEPPING_MASK); - - unsigned int amdFamily = 0; - unsigned int amdModel = 0; - if (family == 0xF) { - amdFamily = extFam + family; - amdModel = (extMod << 4) + model; - } else { - amdFamily = family; - amdModel = model; - } - - // Haiku AMD cpuid format: VVFFMM - unsigned int amdHaiku - = AMD_VENDOR + (amdFamily << 8) + amdModel; - - printf("family: 0x%lX\n", amdFamily); - printf("model: 0x%lX\n", amdModel); - printf("stepping: 0x%lX\n", stepping); - printf("Haiku CPUID: 0x%lX\n", amdHaiku); - - return 0; -} diff --git a/src/tools/intelcpuid.c b/src/tools/cpuidtool.c similarity index 69% rename from src/tools/intelcpuid.c rename to src/tools/cpuidtool.c index 44e3e4c926..b7837e832b 100644 --- a/src/tools/intelcpuid.c +++ b/src/tools/cpuidtool.c @@ -16,8 +16,6 @@ #include -#define INTEL_VENDOR 0x100000 - #define EXT_FAMILY_MASK 0xF00000 #define EXT_MODEL_MASK 0x0F0000 #define FAMILY_MASK 0x000F00 @@ -69,14 +67,14 @@ static int xtoi(const char* xs, unsigned int* result) int main(int argc, char *argv[]) { - if (argc != 2) { - printf("Provide the Intel cpuid in hex, and you will get how we id it\n"); - printf("usage: intelcpuid \n"); + if (argc != 3) { + printf("Provide the cpuid in hex, and you will get how we id it\n"); + printf("usage: cpuidhaiku \n"); return 1; } - unsigned int cpuid; - xtoi(argv[1], &cpuid); + unsigned int cpuid = 0; + xtoi(argv[2], &cpuid); printf("cpuid: 0x%X\n", cpuid); @@ -86,11 +84,24 @@ main(int argc, char *argv[]) unsigned int model = (cpuid & MODEL_MASK) >> 4; unsigned int stepping = (cpuid & STEPPING_MASK); - // Haiku INTEL cpuid format: VVEFEM - unsigned int intelHaiku = INTEL_VENDOR + ((extFam & 0xF) << 12) - + (family << 8) + (extMod << 4) + model; + unsigned int cpuidHaiku; + if (strncmp(argv[1], "AMD", 3) == 0) { + if (family == 0xF) { + cpuidHaiku = (extFam << 20) + (extMod << 16) + + (family << 4) + model; + } else + cpuidHaiku = (family << 4) + model; + cpuidHaiku += 0x1100; // AMD vendor id + } else if (strncmp(argv[1], "INTEL", 5) == 0) { + cpuidHaiku = (extFam << 20) + (extMod << 16) + + (family << 4) + model; + cpuidHaiku += 0x1000; // Intel vendor id + } else { + printf("Vendor should be AMD or INTEL\n"); + return 1; + } - printf("Haiku CPUID: 0x%lX\n", intelHaiku); + printf("Haiku CPUID: 0x%lx\n", cpuidHaiku); return 0; } From 548b1a49889120dd46ef01d133a44b69d7659218 Mon Sep 17 00:00:00 2001 From: Alexander von Gluck IV Date: Mon, 4 Jun 2012 14:11:43 -0500 Subject: [PATCH 27/39] cpuid: Rework AMD CPUID numbers * If family is 0xF, we grab extended family and model like Intel does * Idenfify AMD cpu's more correctly --- headers/os/kernel/OS.h | 89 ++++++++++++------- headers/private/shared/cpu_type.h | 51 +++++++++-- .../kernel/arch/x86/arch_system_info.cpp | 12 +-- 3 files changed, 108 insertions(+), 44 deletions(-) diff --git a/headers/os/kernel/OS.h b/headers/os/kernel/OS.h index 383f857e9c..1f921f98ed 100644 --- a/headers/os/kernel/OS.h +++ b/headers/os/kernel/OS.h @@ -494,7 +494,7 @@ typedef enum cpu_types { B_CPU_INTEL_PENTIUM_M = 0x1069, B_CPU_INTEL_PENTIUM_III_XEON = 0x106a, B_CPU_INTEL_PENTIUM_III_MODEL_11 = 0x106b, - B_CPU_INTEL_ATOM = 0x1106c, + B_CPU_INTEL_ATOM = 0x1106c, B_CPU_INTEL_PENTIUM_M_MODEL_13 = 0x106d, /* Dothan */ B_CPU_INTEL_PENTIUM_CORE, B_CPU_INTEL_PENTIUM_CORE_2, @@ -513,15 +513,14 @@ typedef enum cpu_types { /* AMD */ - /* Checked with "AMD Processor Recognition Application Note" - * (Table 3) - * 20734.pdf - */ + // AMD Processor Recognition Application Note B_CPU_AMD_x86 = 0x1100, + + // Family 5h B_CPU_AMD_K5_MODEL_0 = 0x1150, - B_CPU_AMD_K5_MODEL_1, - B_CPU_AMD_K5_MODEL_2, - B_CPU_AMD_K5_MODEL_3, + B_CPU_AMD_K5_MODEL_1 = 0x1151, + B_CPU_AMD_K5_MODEL_2 = 0x1152, + B_CPU_AMD_K5_MODEL_3 = 0x1153, B_CPU_AMD_K6_MODEL_6 = 0x1156, B_CPU_AMD_K6_MODEL_7 = 0x1157, B_CPU_AMD_K6_MODEL_8 = 0x1158, @@ -530,42 +529,70 @@ typedef enum cpu_types { B_CPU_AMD_K6_III = 0x1159, B_CPU_AMD_K6_III_MODEL_13 = 0x115d, + B_CPU_AMD_GEODE_LX = 0x115a, + + // Family 6h B_CPU_AMD_ATHLON_MODEL_1 = 0x1161, B_CPU_AMD_ATHLON_MODEL_2 = 0x1162, B_CPU_AMD_DURON = 0x1163, B_CPU_AMD_ATHLON_THUNDERBIRD = 0x1164, - B_CPU_AMD_ATHLON_XP = 0x1166, - B_CPU_AMD_ATHLON_XP_MODEL_7, - B_CPU_AMD_ATHLON_XP_MODEL_8, + B_CPU_AMD_ATHLON_XP_MODEL_6 = 0x1166, + B_CPU_AMD_ATHLON_XP_MODEL_7 = 0x1167, + B_CPU_AMD_ATHLON_XP_MODEL_8 = 0x1168, B_CPU_AMD_ATHLON_XP_MODEL_10 = 0x116a, /* Barton */ - B_CPU_AMD_SEMPRON_MODEL_8 = B_CPU_AMD_ATHLON_XP_MODEL_8, - B_CPU_AMD_SEMPRON_MODEL_10 = B_CPU_AMD_ATHLON_XP_MODEL_10, - - /* According to "Revision Guide for AMD Family 10h - * Processors" (41322.pdf) - */ - B_CPU_AMD_PHENOM = 0x11f2, - - /* According to "Revision guide for AMD Athlon 64 - * and AMD Opteron Processors" (25759.pdf) - */ + // Family fh B_CPU_AMD_ATHLON_64_MODEL_3 = 0x11f3, - B_CPU_AMD_ATHLON_64_MODEL_4, - B_CPU_AMD_ATHLON_64_MODEL_5, - B_CPU_AMD_PHENOM_II = B_CPU_AMD_ATHLON_64_MODEL_4, - B_CPU_AMD_OPTERON = B_CPU_AMD_ATHLON_64_MODEL_5, - B_CPU_AMD_ATHLON_64_FX = B_CPU_AMD_ATHLON_64_MODEL_5, + B_CPU_AMD_ATHLON_64_MODEL_4 = 0x11f4, B_CPU_AMD_ATHLON_64_MODEL_7 = 0x11f7, - B_CPU_AMD_ATHLON_64_MODEL_8, + B_CPU_AMD_ATHLON_64_MODEL_8 = 0x11f8, B_CPU_AMD_ATHLON_64_MODEL_11 = 0x11fb, - B_CPU_AMD_ATHLON_64_MODEL_12, + B_CPU_AMD_ATHLON_64_MODEL_12 = 0x11fc, B_CPU_AMD_ATHLON_64_MODEL_14 = 0x11fe, - B_CPU_AMD_ATHLON_64_MODEL_15, + B_CPU_AMD_ATHLON_64_MODEL_15 = 0x11ff, + B_CPU_AMD_ATHLON_64_MODEL_20 = 0x111f4, + B_CPU_AMD_ATHLON_64_MODEL_23 = 0x111f7, + B_CPU_AMD_ATHLON_64_MODEL_24 = 0x111f8, + B_CPU_AMD_ATHLON_64_MODEL_27 = 0x111fb, + B_CPU_AMD_ATHLON_64_MODEL_28 = 0x111fc, + B_CPU_AMD_ATHLON_64_MODEL_31 = 0x111ff, + B_CPU_AMD_ATHLON_64_MODEL_35 = 0x211f3, + B_CPU_AMD_ATHLON_64_MODEL_43 = 0x211fb, + B_CPU_AMD_ATHLON_64_MODEL_44 = 0x211fc, + B_CPU_AMD_ATHLON_64_MODEL_47 = 0x211ff, + B_CPU_AMD_ATHLON_64_MODEL_63 = 0x311ff, + B_CPU_AMD_ATHLON_64_MODEL_79 = 0x411ff, + B_CPU_AMD_ATHLON_64_MODEL_95 = 0x511ff, + B_CPU_AMD_ATHLON_64_MODEL_127 = 0x711ff, - B_CPU_AMD_GEODE_LX = 0x115a, + B_CPU_AMD_OPTERON_MODEL_5 = 0x11f5, + B_CPU_AMD_OPTERON_MODEL_21 = 0x111f5, + B_CPU_AMD_OPTERON_MODEL_33 = 0x211f1, + B_CPU_AMD_OPTERON_MODEL_37 = 0x211f5, + B_CPU_AMD_OPTERON_MODEL_39 = 0x211f7, + + B_CPU_AMD_TURION_64_MODEL_36 = 0x211f4, + B_CPU_AMD_TURION_64_MODEL_76 = 0x411fc, + B_CPU_AMD_TURION_64_MODEL_104 = 0x611f8, + + // Family 10h + B_CPU_AMD_PHENOM_MODEL_2 = 0x1011f2, + B_CPU_AMD_PHENOM_II_MODEL_4 = 0x1011f4, + B_CPU_AMD_PHENOM_II_MODEL_5 = 0x1011f5, + B_CPU_AMD_PHENOM_II_MODEL_6 = 0x1011f6, + B_CPU_AMD_PHENOM_II_MODEL_10 = 0x1011fa, + + // Family 12h + B_CPU_AMD_A_SERIES = 0x3011f1, + + // Family 14h + B_CPU_AMD_C_SERIES = 0x5011f1, + B_CPU_AMD_E_SERIES = 0x5011f2, + + // Family 15h + B_CPU_AMD_FX_SERIES = 0x6011f1, /* Bulldozer */ /* VIA/Cyrix */ B_CPU_CYRIX_x86 = 0x1200, diff --git a/headers/private/shared/cpu_type.h b/headers/private/shared/cpu_type.h index c3a7fb9cf8..2c1f7c6f77 100644 --- a/headers/private/shared/cpu_type.h +++ b/headers/private/shared/cpu_type.h @@ -232,33 +232,70 @@ get_cpu_model_string(system_info *info) case B_CPU_AMD_K6_III: case B_CPU_AMD_K6_III_MODEL_13: return "K6-III"; + case B_CPU_AMD_GEODE_LX: + return "Geode LX"; case B_CPU_AMD_ATHLON_MODEL_1: case B_CPU_AMD_ATHLON_MODEL_2: case B_CPU_AMD_ATHLON_THUNDERBIRD: return "Athlon"; - case B_CPU_AMD_ATHLON_XP: + case B_CPU_AMD_ATHLON_XP_MODEL_6: + case B_CPU_AMD_ATHLON_XP_MODEL_7: case B_CPU_AMD_ATHLON_XP_MODEL_8: case B_CPU_AMD_ATHLON_XP_MODEL_10: return "Athlon XP"; case B_CPU_AMD_DURON: - case B_CPU_AMD_ATHLON_XP_MODEL_7: return "Duron"; case B_CPU_AMD_ATHLON_64_MODEL_3: + case B_CPU_AMD_ATHLON_64_MODEL_4: case B_CPU_AMD_ATHLON_64_MODEL_7: case B_CPU_AMD_ATHLON_64_MODEL_8: case B_CPU_AMD_ATHLON_64_MODEL_11: case B_CPU_AMD_ATHLON_64_MODEL_12: case B_CPU_AMD_ATHLON_64_MODEL_14: case B_CPU_AMD_ATHLON_64_MODEL_15: + case B_CPU_AMD_ATHLON_64_MODEL_20: + case B_CPU_AMD_ATHLON_64_MODEL_23: + case B_CPU_AMD_ATHLON_64_MODEL_24: + case B_CPU_AMD_ATHLON_64_MODEL_27: + case B_CPU_AMD_ATHLON_64_MODEL_28: + case B_CPU_AMD_ATHLON_64_MODEL_31: + case B_CPU_AMD_ATHLON_64_MODEL_35: + case B_CPU_AMD_ATHLON_64_MODEL_43: + case B_CPU_AMD_ATHLON_64_MODEL_44: + case B_CPU_AMD_ATHLON_64_MODEL_47: + case B_CPU_AMD_ATHLON_64_MODEL_63: + case B_CPU_AMD_ATHLON_64_MODEL_79: + case B_CPU_AMD_ATHLON_64_MODEL_95: + case B_CPU_AMD_ATHLON_64_MODEL_127: return "Athlon 64"; - case B_CPU_AMD_OPTERON: + case B_CPU_AMD_OPTERON_MODEL_5: + case B_CPU_AMD_OPTERON_MODEL_21: + case B_CPU_AMD_OPTERON_MODEL_33: + case B_CPU_AMD_OPTERON_MODEL_37: + case B_CPU_AMD_OPTERON_MODEL_39: return "Opteron"; - case B_CPU_AMD_PHENOM: + case B_CPU_AMD_TURION_64_MODEL_36: + case B_CPU_AMD_TURION_64_MODEL_76: + case B_CPU_AMD_TURION_64_MODEL_104: + return "Turion 64"; + case B_CPU_AMD_PHENOM_MODEL_2: return "Phenom"; - case B_CPU_AMD_PHENOM_II: + case B_CPU_AMD_PHENOM_II_MODEL_4: + case B_CPU_AMD_PHENOM_II_MODEL_5: + case B_CPU_AMD_PHENOM_II_MODEL_6: + case B_CPU_AMD_PHENOM_II_MODEL_10: + get_cpuid_model_string(cpuidName); + if (strcasestr(cpuidName, "Athlon") != NULL) + return "Athlon II"; return "Phenom II"; - case B_CPU_AMD_GEODE_LX: - return "Geode LX"; + case B_CPU_AMD_A_SERIES: + return "A-Series"; + case B_CPU_AMD_C_SERIES: + return "C-Series"; + case B_CPU_AMD_E_SERIES: + return "E-Series"; + case B_CPU_AMD_FX_SERIES: + return "FX-Series"; /* Transmeta */ case B_CPU_TRANSMETA_CRUSOE: diff --git a/src/system/kernel/arch/x86/arch_system_info.cpp b/src/system/kernel/arch/x86/arch_system_info.cpp index 5fe4d8c7ba..3f2eb22ceb 100644 --- a/src/system/kernel/arch/x86/arch_system_info.cpp +++ b/src/system/kernel/arch/x86/arch_system_info.cpp @@ -117,16 +117,16 @@ arch_system_info_init(struct kernel_args *args) } if (base != B_CPU_x86) { - if (base == B_CPU_INTEL_x86) { + if (base == B_CPU_INTEL_x86 + || (base == B_CPU_AMD_x86 && cpu->arch.family == 0xF)) { model = (cpu->arch.extended_family << 20) + (cpu->arch.extended_model << 16) + (cpu->arch.family << 4) + cpu->arch.model; } else { - model = (cpu->arch.family << 4) + - cpu->arch.model; - // There isn't much useful information yet in the extended - // family and extended model fields of AMD processors - // and is probably undefined for others + model = (cpu->arch.family << 4) + + cpu->arch.model; + // Isn't much useful extended family and model information + // yet on other processors. } } From 966df2f98b509218c8743d9b468bb0929e6aa00f Mon Sep 17 00:00:00 2001 From: Alexander von Gluck IV Date: Mon, 4 Jun 2012 11:05:36 -0500 Subject: [PATCH 28/39] cpuidtool: Style cleanup --- src/tools/cpuidtool.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/tools/cpuidtool.c b/src/tools/cpuidtool.c index b7837e832b..570fd79be9 100644 --- a/src/tools/cpuidtool.c +++ b/src/tools/cpuidtool.c @@ -7,12 +7,12 @@ */ /* - * Pass an Intel CPUID in hex, and get out a CPUID for OS.h + * Pass a standard CPUID in hex, and get out a CPUID for OS.h */ -#include #include +#include #include @@ -24,29 +24,33 @@ // Converts a hexadecimal string to integer -static int xtoi(const char* xs, unsigned int* result) +static int +xtoi(const char* xs, unsigned int* result) { size_t szlen = strlen(xs); - int i, xv, fact; + int i; + int xv; + int fact; if (szlen > 0) { // Converting more than 32bit hexadecimal value? - if (szlen>8) return 2; // exit + if (szlen > 8) + return 2; // Begin conversion here *result = 0; fact = 1; // Run until no more character to convert - for (i = szlen - 1; i>=0 ;i--) { - if (isxdigit(*(xs+i))) { - if (*(xs+i)>=97) { - xv = ( *(xs+i) - 97) + 10; - } else if ( *(xs+i) >= 65) { - xv = (*(xs+i) - 65) + 10; - } else { - xv = *(xs+i) - 48; - } + for (i = szlen - 1; i>=0; i--) { + if (isxdigit(*(xs + i))) { + if (*(xs + i) >= 97) + xv = (*(xs + i) - 97) + 10; + else if (*(xs + i) >= 65) + xv = (*(xs + i) - 65) + 10; + else + xv = *(xs + i) - 48; + *result += (xv * fact); fact *= 16; } else { From 75d1324b9160367ffeffb7e228c530dd94bcfc42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Tue, 5 Jun 2012 21:55:41 +0200 Subject: [PATCH 29/39] ntfs: fix double free #8484 --- src/add-ons/kernel/file_systems/ntfs/fs_func.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/add-ons/kernel/file_systems/ntfs/fs_func.c b/src/add-ons/kernel/file_systems/ntfs/fs_func.c index 4d1ddd267b..aee6569949 100644 --- a/src/add-ons/kernel/file_systems/ntfs/fs_func.c +++ b/src/add-ons/kernel/file_systems/ntfs/fs_func.c @@ -965,8 +965,6 @@ fs_create(fs_volume *_vol, fs_vnode *_dir, const char *name, int omode, result = errno; } - free(uname); - exit: if (result >= B_OK) *_cookie = cookie; From bea2387b6886201c5eebd41f4a2967e593c2a883 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Fri, 1 Jun 2012 23:29:44 +0200 Subject: [PATCH 30/39] Made constants static, coding style cleanup. --- src/kits/interface/Dragger.cpp | 113 +++++++++++++++++---------------- 1 file changed, 58 insertions(+), 55 deletions(-) diff --git a/src/kits/interface/Dragger.cpp b/src/kits/interface/Dragger.cpp index 9b37ca32dd..37f92d68db 100644 --- a/src/kits/interface/Dragger.cpp +++ b/src/kits/interface/Dragger.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2009, Haiku. + * Copyright 2001-2012, Haiku. * Distributed under the terms of the MIT License. * * Authors: @@ -8,6 +8,7 @@ * Alexandre Deckner (alex@zappotek.com) */ + //! BDragger represents a replicant "handle". @@ -45,10 +46,10 @@ using BPrivate::gSystemCatalog; #define B_TRANSLATE(str) \ gSystemCatalog.GetString(B_TRANSLATE_MARK(str), "Dragger") -const uint32 kMsgDragStarted = 'Drgs'; -const unsigned char -kHandBitmap[] = { +static const uint32 kMsgDragStarted = 'Drgs'; + +static const unsigned char kHandBitmap[] = { 255, 255, 0, 0, 0, 255, 255, 255, 255, 255, 0, 131, 131, 0, 255, 255, 0, 0, 0, 0, 131, 131, 0, 0, @@ -112,8 +113,9 @@ DraggerManager* DraggerManager::sDefaultInstance = NULL; } // unnamed namespace -BDragger::BDragger(BRect bounds, BView *target, uint32 rmask, uint32 flags) - : BView(bounds, "_dragger_", rmask, flags), +BDragger::BDragger(BRect bounds, BView* target, uint32 resizeMask, uint32 flags) + : + BView(bounds, "_dragger_", resizeMask, flags), fTarget(target), fRelation(TARGET_UNKNOWN), fShelf(NULL), @@ -127,8 +129,9 @@ BDragger::BDragger(BRect bounds, BView *target, uint32 rmask, uint32 flags) } -BDragger::BDragger(BMessage *data) - : BView(data), +BDragger::BDragger(BMessage* data) + : + BView(data), fTarget(NULL), fRelation(TARGET_UNKNOWN), fShelf(NULL), @@ -138,16 +141,16 @@ BDragger::BDragger(BMessage *data) fPopUpIsCustom(false), fPopUp(NULL) { - data->FindInt32("_rel", (int32 *)&fRelation); + data->FindInt32("_rel", (int32*)&fRelation); _InitData(); BMessage popupMsg; if (data->FindMessage("_popup", &popupMsg) == B_OK) { - BArchivable *archivable = instantiate_object(&popupMsg); + BArchivable* archivable = instantiate_object(&popupMsg); if (archivable) { - fPopUp = dynamic_cast(archivable); + fPopUp = dynamic_cast(archivable); fPopUpIsCustom = true; } } @@ -162,7 +165,7 @@ BDragger::~BDragger() BArchivable * -BDragger::Instantiate(BMessage *data) +BDragger::Instantiate(BMessage* data) { if (validate_instantiation(data, "BDragger")) return new BDragger(data); @@ -171,7 +174,7 @@ BDragger::Instantiate(BMessage *data) status_t -BDragger::Archive(BMessage *data, bool deep) const +BDragger::Archive(BMessage* data, bool deep) const { status_t ret = BView::Archive(data, deep); if (ret != B_OK) @@ -179,15 +182,16 @@ BDragger::Archive(BMessage *data, bool deep) const BMessage popupMsg; - if (fPopUp && fPopUpIsCustom) { + if (fPopUp != NULL && fPopUpIsCustom) { bool windowLocked = fPopUp->Window()->Lock(); ret = fPopUp->Archive(&popupMsg, deep); - if (windowLocked) + if (windowLocked) { fPopUp->Window()->Unlock(); // TODO: Investigate, in some (rare) occasions the menu window // has already been unlocked + } if (ret == B_OK) ret = data->AddMessage("_popup", &popupMsg); @@ -229,8 +233,8 @@ BDragger::Draw(BRect update) { BRect bounds(Bounds()); - if (AreDraggersDrawn() && (!fShelf || fShelf->AllowsDragging())) { - if (Parent() && (Parent()->Flags() & B_DRAW_ON_CHILDREN) == 0) { + if (AreDraggersDrawn() && (fShelf == NULL || fShelf->AllowsDragging())) { + if (Parent() != NULL && (Parent()->Flags() & B_DRAW_ON_CHILDREN) == 0) { uint32 flags = Parent()->Flags(); Parent()->SetFlags(flags | B_DRAW_ON_CHILDREN); Parent()->Draw(Frame() & ConvertToParent(update)); @@ -248,7 +252,7 @@ BDragger::Draw(BRect update) // TODO: should draw it differently ? } } else if (IsVisibilityChanging()) { - if (Parent()) { + if (Parent() != NULL) { if ((Parent()->Flags() & B_DRAW_ON_CHILDREN) == 0) { uint32 flags = Parent()->Flags(); Parent()->SetFlags(flags | B_DRAW_ON_CHILDREN); @@ -266,13 +270,13 @@ BDragger::Draw(BRect update) void BDragger::MouseDown(BPoint where) { - if (!fTarget || !AreDraggersDrawn()) + if (fTarget == NULL || !AreDraggersDrawn()) return; uint32 buttons; - Window()->CurrentMessage()->FindInt32("buttons", (int32 *)&buttons); + Window()->CurrentMessage()->FindInt32("buttons", (int32*)&buttons); - if (fShelf != NULL && (buttons & B_SECONDARY_MOUSE_BUTTON)) + if (fShelf != NULL && (buttons & B_SECONDARY_MOUSE_BUTTON) != 0) _ShowPopUp(fTarget, where); } @@ -285,14 +289,14 @@ BDragger::MouseUp(BPoint point) void -BDragger::MouseMoved(BPoint point, uint32 code, const BMessage *msg) +BDragger::MouseMoved(BPoint point, uint32 code, const BMessage* msg) { BView::MouseMoved(point, code, msg); } void -BDragger::MessageReceived(BMessage *msg) +BDragger::MessageReceived(BMessage* msg) { switch (msg->what) { case B_TRASH_TARGET: @@ -316,7 +320,8 @@ BDragger::MessageReceived(BMessage *msg) Flush(); fTransition = false; } else { - if ((fShelf && (fShelf->AllowsDragging() && AreDraggersDrawn())) + if ((fShelf != NULL && fShelf->AllowsDragging() + && AreDraggersDrawn()) || AreDraggersDrawn()) { Show(); } else @@ -332,25 +337,22 @@ BDragger::MessageReceived(BMessage *msg) fTarget->Archive(&archive); else if (fRelation == TARGET_IS_CHILD) Archive(&archive); - else { - if (fTarget->Archive(&archive)) { - BMessage archivedSelf(B_ARCHIVED_OBJECT); + else if (fTarget->Archive(&archive)) { + BMessage archivedSelf(B_ARCHIVED_OBJECT); - if (Archive(&archivedSelf)) - archive.AddMessage("__widget", &archivedSelf); - } + if (Archive(&archivedSelf)) + archive.AddMessage("__widget", &archivedSelf); } archive.AddInt32("be:actions", B_TRASH_TARGET); BPoint offset; drawing_mode mode; - BBitmap *bitmap = DragBitmap(&offset, &mode); + BBitmap* bitmap = DragBitmap(&offset, &mode); if (bitmap != NULL) DragMessage(&archive, bitmap, mode, offset, this); else { - DragMessage(&archive, - ConvertFromScreen(fTarget->ConvertToScreen(fTarget->Bounds())), - this); + DragMessage(&archive, ConvertFromScreen( + fTarget->ConvertToScreen(fTarget->Bounds())), this); } } break; @@ -543,7 +545,7 @@ BDragger::AllDetached() status_t -BDragger::SetPopUp(BPopUpMenu *menu) +BDragger::SetPopUp(BPopUpMenu* menu) { if (menu != NULL && menu != fPopUp) { delete fPopUp; @@ -555,11 +557,11 @@ BDragger::SetPopUp(BPopUpMenu *menu) } -BPopUpMenu * +BPopUpMenu* BDragger::PopUp() const { if (fPopUp == NULL && fTarget) - const_cast(this)->_BuildDefaultPopUp(); + const_cast(this)->_BuildDefaultPopUp(); return fPopUp; } @@ -572,15 +574,15 @@ BDragger::InShelf() const } -BView * +BView* BDragger::Target() const { return fTarget; } -BBitmap * -BDragger::DragBitmap(BPoint *offset, drawing_mode *mode) +BBitmap* +BDragger::DragBitmap(BPoint* offset, drawing_mode* mode) { return NULL; } @@ -598,8 +600,8 @@ void BDragger::_ReservedDragger3() {} void BDragger::_ReservedDragger4() {} -BDragger & -BDragger::operator=(const BDragger &) +BDragger& +BDragger::operator=(const BDragger&) { return *this; } @@ -663,7 +665,7 @@ BDragger::_RemoveFromList() status_t BDragger::_DetermineRelationship() { - if (fTarget) { + if (fTarget != NULL) { if (fTarget == Parent()) fRelation = TARGET_IS_PARENT; else if (fTarget == ChildAt(0)) @@ -680,11 +682,12 @@ BDragger::_DetermineRelationship() } if (fRelation == TARGET_IS_PARENT) { - BRect bounds (Frame()); - BRect parentBounds (Parent()->Bounds()); - if (!parentBounds.Contains(bounds)) + BRect bounds(Frame()); + BRect parentBounds(Parent()->Bounds()); + if (!parentBounds.Contains(bounds)) { MoveTo(parentBounds.right - bounds.Width(), parentBounds.bottom - bounds.Height()); + } } return B_OK; @@ -692,14 +695,14 @@ BDragger::_DetermineRelationship() status_t -BDragger::_SetViewToDrag(BView *target) +BDragger::_SetViewToDrag(BView* target) { if (target->Window() != Window()) return B_ERROR; fTarget = target; - if (Window()) + if (Window() != NULL) _DetermineRelationship(); return B_OK; @@ -707,7 +710,7 @@ BDragger::_SetViewToDrag(BView *target) void -BDragger::_SetShelf(BShelf *shelf) +BDragger::_SetShelf(BShelf* shelf) { fShelf = shelf; } @@ -731,13 +734,13 @@ BDragger::_BuildDefaultPopUp() fPopUp = new BPopUpMenu("Shelf", false, false, B_ITEMS_IN_COLUMN); // About - BMessage *msg = new BMessage(B_ABOUT_REQUESTED); + BMessage* msg = new BMessage(B_ABOUT_REQUESTED); - const char *name = fTarget->Name(); - if (name) + const char* name = fTarget->Name(); + if (name != NULL) msg->AddString("target", name); - BString about(B_TRANSLATE("About %app"B_UTF8_ELLIPSIS)); + BString about(B_TRANSLATE("About %app" B_UTF8_ELLIPSIS)); about.ReplaceFirst("%app", name); fPopUp->AddItem(new BMenuItem(about.String(), msg)); @@ -748,11 +751,11 @@ BDragger::_BuildDefaultPopUp() void -BDragger::_ShowPopUp(BView *target, BPoint where) +BDragger::_ShowPopUp(BView* target, BPoint where) { BPoint point = ConvertToScreen(where); - if (!fPopUp && fTarget) + if (fPopUp == NULL && fTarget != NULL) _BuildDefaultPopUp(); fPopUp->SetTargetForItems(fTarget); From 0ba36860ad2973704cf0e53e5a37f944882261de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Wed, 6 Jun 2012 00:34:51 +0200 Subject: [PATCH 31/39] Added a few convenience methods. --- src/apps/sudoku/SudokuField.cpp | 23 ++++++++++++++++++++++- src/apps/sudoku/SudokuField.h | 3 +++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/apps/sudoku/SudokuField.cpp b/src/apps/sudoku/SudokuField.cpp index a139d473b9..f1ff6bc89b 100644 --- a/src/apps/sudoku/SudokuField.cpp +++ b/src/apps/sudoku/SudokuField.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2007-2010, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2007-2012, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. */ @@ -280,6 +280,13 @@ SudokuField::HintMaskAt(uint32 x, uint32 y) const } +bool +SudokuField::HasHint(uint32 x, uint32 y, uint32 value) const +{ + return (_FieldAt(x, y).hint_mask & (1UL << (value - 1))) != 0; +} + + void SudokuField::SetValidMaskAt(uint32 x, uint32 y, uint32 validMask) { @@ -294,6 +301,13 @@ SudokuField::ValidMaskAt(uint32 x, uint32 y) const } +bool +SudokuField::IsValid(uint32 x, uint32 y, uint32 value) const +{ + return (_FieldAt(x, y).valid_mask & (1UL << (value - 1))) != 0; +} + + void SudokuField::SetFlagsAt(uint32 x, uint32 y, uint32 flags) { @@ -308,6 +322,13 @@ SudokuField::FlagsAt(uint32 x, uint32 y) const } +bool +SudokuField::IsInitialValue(uint32 x, uint32 y) const +{ + return (_FieldAt(x, y).flags & kInitialValue) != 0; +} + + void SudokuField::SetValueAt(uint32 x, uint32 y, uint32 value, bool setSolved) { diff --git a/src/apps/sudoku/SudokuField.h b/src/apps/sudoku/SudokuField.h index 2b0bbf6fe9..ace2647818 100644 --- a/src/apps/sudoku/SudokuField.h +++ b/src/apps/sudoku/SudokuField.h @@ -41,13 +41,16 @@ public: void SetHintMaskAt(uint32 x, uint32 y, uint32 hintMask); uint32 HintMaskAt(uint32 x, uint32 y) const; + bool HasHint(uint32 x, uint32 y, uint32 value) const; void SetValidMaskAt(uint32 x, uint32 y, uint32 validMask); uint32 ValidMaskAt(uint32 x, uint32 y) const; + bool IsValid(uint32 x, uint32 y, uint32 value) const; void SetFlagsAt(uint32 x, uint32 y, uint32 flags); uint32 FlagsAt(uint32 x, uint32 y) const; + bool IsInitialValue(uint32 x, uint32 y) const; void SetValueAt(uint32 x, uint32 y, uint32 value, bool setSolved = false); From 2996f648811ca6080e109ac744709ef294eb1598 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Wed, 6 Jun 2012 00:35:51 +0200 Subject: [PATCH 32/39] Implemented a value hint, changed colors. * When you press on a value, that value will be shown with a highlighted background across the board until another value is set. * Changed the colors to those from the Haiku logo rather than the BeOS logo. This makes it a bit more colorful which one might need to get used to -- comments welcome. --- src/apps/sudoku/SudokuView.cpp | 142 ++++++++++++++++++++++++--------- src/apps/sudoku/SudokuView.h | 5 ++ 2 files changed, 111 insertions(+), 36 deletions(-) diff --git a/src/apps/sudoku/SudokuView.cpp b/src/apps/sudoku/SudokuView.cpp index 653316241f..849c5e51ac 100644 --- a/src/apps/sudoku/SudokuView.cpp +++ b/src/apps/sudoku/SudokuView.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2007-2010, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2007-2012, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. */ @@ -28,9 +28,17 @@ #include -const uint32 kMsgCheckSolved = 'chks'; +static const uint32 kMsgCheckSolved = 'chks'; -const uint32 kStrongLineSize = 2; +static const uint32 kStrongLineSize = 2; + +static const rgb_color kBackgroundColor = {255, 255, 240}; +static const rgb_color kHintColor = {255, 115, 0}; +static const rgb_color kValueColor = {0, 91, 162}; +static const rgb_color kValueCompletedColor = {55, 140, 35}; +static const rgb_color kInvalidValueColor = {200, 0, 0}; +static const rgb_color kValueHintBackgroundColor = {255, 215, 127}; +static const rgb_color kHintValueHintBackgroundColor = {255, 235, 185}; extern const char* kSignature; @@ -103,6 +111,7 @@ SudokuView::InitObject(const BMessage* archive) { fField = NULL; fShowHintX = ~0UL; + fValueHintValue = ~0UL; fLastHintValue = ~0UL; fLastField = ~0UL; fKeyboardX = 0; @@ -131,9 +140,8 @@ SudokuView::InitObject(const BMessage* archive) SetViewColor(B_TRANSPARENT_COLOR); // to avoid flickering - rgb_color color = { 255, 255, 240 }; - fBackgroundColor = color; - SetLowColor(color); + fBackgroundColor = kBackgroundColor; + SetLowColor(fBackgroundColor); FrameResized(0, 0); } @@ -212,6 +220,7 @@ SudokuView::SetTo(entry_ref& ref) _PushUndo(); status = fField->SetTo(_BaseCharacter(), buffer); + fValueHintValue = ~0UL; Invalidate(); fclose(file); return status; @@ -234,6 +243,7 @@ SudokuView::SetTo(const char* data) _PushUndo(); status = fField->SetTo(_BaseCharacter(), buffer); + fValueHintValue = ~0UL; Invalidate(); return status; } @@ -250,6 +260,7 @@ SudokuView::SetTo(SudokuField* field) fField = field; fBlockSize = fField->BlockSize(); + fValueHintValue = ~0UL; FrameResized(0, 0); Invalidate(); return B_OK; @@ -377,7 +388,7 @@ SudokuView::SaveTo(BDataIO& stream, uint32 exportAs) text << "\n "; - } else if (fField->FlagsAt(x, y) & kInitialValue) { + } else if (fField->IsInitialValue(x, y)) { text << "\n"; @@ -543,7 +554,7 @@ SudokuView::ClearChanged() for (uint32 y = 0; y < fField->Size(); y++) { for (uint32 x = 0; x < fField->Size(); x++) { - if ((fField->FlagsAt(x, y) & kInitialValue) == 0) + if (!fField->IsInitialValue(x, y)) fField->SetValueAt(x, y, 0); } } @@ -612,8 +623,9 @@ SudokuView::FrameResized(float /*width*/, float /*height*/) // font for numbers uint32 size = fField->Size(); - fWidth = (Bounds().Width() - kStrongLineSize * (fBlockSize - 1)) / size; - fHeight = (Bounds().Height() - kStrongLineSize * (fBlockSize - 1)) / size; + fWidth = (Bounds().Width() + 2 - kStrongLineSize * (fBlockSize - 1)) / size; + fHeight = (Bounds().Height() + 2 - kStrongLineSize * (fBlockSize - 1)) + / size; _FitFont(fFieldFont, fWidth - 2, fHeight - 2); font_height fontHeight; @@ -641,8 +653,8 @@ SudokuView::FrameResized(float /*width*/, float /*height*/) BPoint SudokuView::_LeftTop(uint32 x, uint32 y) { - return BPoint(x * fWidth + x / fBlockSize * kStrongLineSize + 1, - y * fHeight + y / fBlockSize * kStrongLineSize + 1); + return BPoint(x * fWidth - 1 + x / fBlockSize * kStrongLineSize + 1, + y * fHeight - 1 + y / fBlockSize * kStrongLineSize + 1); } @@ -678,6 +690,22 @@ SudokuView::_InvalidateField(uint32 x, uint32 y) } +void +SudokuView::_InvalidateValue(uint32 value, bool invalidateHint, + uint32 fieldX, uint32 fieldY) +{ + for (uint32 y = 0; y < fField->Size(); y++) { + for (uint32 x = 0; x < fField->Size(); x++) { + if (fField->ValueAt(x, y) == value || (x == fieldX && y == fieldY)) + Invalidate(_Frame(x, y)); + else if (invalidateHint && fField->ValueAt(x, y) == 0 + && fField->HasHint(x, y, value)) + Invalidate(_Frame(x, y)); + } + } +} + + void SudokuView::_InvalidateKeyboardFocus(uint32 x, uint32 y) { @@ -723,6 +751,22 @@ SudokuView::_GetFieldFor(BPoint where, uint32& x, uint32& y) } +void +SudokuView::_SetValueHintValue(uint32 value) +{ + if (value == fValueHintValue) + return; + + if (fValueHintValue != ~0UL) + _InvalidateValue(fValueHintValue, true); + + fValueHintValue = value; + + if (fValueHintValue != ~0UL) + _InvalidateValue(fValueHintValue, true); +} + + void SudokuView::_RemoveHint() { @@ -801,6 +845,15 @@ SudokuView::MouseDown(BPoint where) Looper()->CurrentMessage()->FindInt32("clicks", &clicks); } + if (buttons == B_PRIMARY_MOUSE_BUTTON && clicks == 1) { + uint32 value = fField->ValueAt(x, y); + if (value != 0) { + // Toggle value hint + _SetValueHintValue(fValueHintValue == value ? ~0UL : value); + return; + } + } + uint32 hintX, hintY; if (!_GetHintFieldFor(where, x, y, hintX, hintY)) return; @@ -813,9 +866,10 @@ SudokuView::MouseDown(BPoint where) || (buttons & (B_SECONDARY_MOUSE_BUTTON | B_TERTIARY_MOUSE_BUTTON)) != 0) { // double click or other buttons set a value - if ((fField->FlagsAt(x, y) & kInitialValue) == 0) { + if (!fField->IsInitialValue(x, y)) { bool wasCompleted; if (fField->ValueAt(x, y) > 0) { + // Remove value value = fField->ValueAt(x, y) - 1; wasCompleted = fField->IsValueCompleted(value + 1); @@ -823,6 +877,7 @@ SudokuView::MouseDown(BPoint where) fShowHintX = x; fShowHintY = y; } else { + // Set value wasCompleted = fField->IsValueCompleted(value + 1); fField->SetValueAt(x, y, value + 1); @@ -834,8 +889,11 @@ SudokuView::MouseDown(BPoint where) fLastField = field; } + if (value + 1 != fValueHintValue) + _SetValueHintValue(~0UL); + if (wasCompleted != fField->IsValueCompleted(value + 1)) - Invalidate(); + _InvalidateValue(value + 1, false, x, y); else _InvalidateField(x, y); } @@ -852,7 +910,12 @@ SudokuView::MouseDown(BPoint where) hintMask &= ~valueMask; fField->SetHintMaskAt(x, y, hintMask); - _InvalidateHintField(x, y, hintX, hintY); + + if (value + 1 != fValueHintValue) { + _SetValueHintValue(~0UL); + _InvalidateHintField(x, y, hintX, hintY); + } else + _InvalidateField(x, y); fLastHintValue = value; fLastField = field; @@ -879,8 +942,9 @@ SudokuView::MouseMoved(BPoint where, uint32 transit, fKeyboardX = x; fKeyboardY = y; } + if (!isField - || (fField->FlagsAt(x, y) & kInitialValue) != 0 + || fField->IsInitialValue(x, y) || (!fShowCursor && fField->ValueAt(x, y) != 0)) { _RemoveHint(); return; @@ -919,7 +983,7 @@ void SudokuView::_InsertKey(char rawKey, int32 modifiers) { if (!fEditable || !_ValidCharacter(rawKey) - || (fField->FlagsAt(fKeyboardX, fKeyboardY) & kInitialValue) != 0) + || fField->IsInitialValue(fKeyboardX, fKeyboardY)) return; uint32 value = rawKey - _BaseCharacter(); @@ -1144,9 +1208,12 @@ SudokuView::_DrawHints(uint32 x, uint32 y) for (uint32 j = 0; j < fBlockSize; j++) { for (uint32 i = 0; i < fBlockSize; i++) { uint32 value = j * fBlockSize + i; - if (hintMask & (1UL << value)) - SetHighColor(200, 0, 0); - else { + if (hintMask & (1UL << value)) { +// if (value + 1 == fValueHintValue) +// SetHighColor(kValueHintBackgroundColor); +// else + SetHighColor(kHintColor); + }else { if (!showAll) continue; @@ -1170,18 +1237,14 @@ SudokuView::_DrawHints(uint32 x, uint32 y) void SudokuView::Draw(BRect /*updateRect*/) { - // draw one pixel border otherwise not covered - // by lines and fields - SetLowColor(fBackgroundColor); - StrokeRect(Bounds(), B_SOLID_LOW); - // draw lines uint32 size = fField->Size(); + SetLowColor(fBackgroundColor); SetHighColor(0, 0, 0); - float width = fWidth; + float width = fWidth - 1; for (uint32 x = 1; x < size; x++) { if (x % fBlockSize == 0) { FillRect(BRect(width, 0, width + kStrongLineSize, @@ -1193,7 +1256,7 @@ SudokuView::Draw(BRect /*updateRect*/) width += fWidth; } - float height = fHeight; + float height = fHeight - 1; for (uint32 y = 1; y < size; y++) { if (y % fBlockSize == 0) { FillRect(BRect(0, height, Bounds().Width(), @@ -1209,39 +1272,46 @@ SudokuView::Draw(BRect /*updateRect*/) for (uint32 y = 0; y < size; y++) { for (uint32 x = 0; x < size; x++) { + uint32 value = fField->ValueAt(x, y); + + rgb_color backgroundColor = fBackgroundColor; + if (value == fValueHintValue) + backgroundColor = kValueHintBackgroundColor; + else if (value == 0 && fField->HasHint(x, y, fValueHintValue)) + backgroundColor = kHintValueHintBackgroundColor; + if (((fShowCursor && x == fShowHintX && y == fShowHintY) || (fShowKeyboardFocus && x == fKeyboardX && y == fKeyboardY)) - && (fField->FlagsAt(x, y) & kInitialValue) == 0) { + && !fField->IsInitialValue(x, y)) { // TODO: make color more intense - SetLowColor(tint_color(fBackgroundColor, B_DARKEN_2_TINT)); + SetLowColor(tint_color(backgroundColor, B_DARKEN_2_TINT)); FillRect(_Frame(x, y), B_SOLID_LOW); } else { - SetLowColor(fBackgroundColor); + SetLowColor(backgroundColor); FillRect(_Frame(x, y), B_SOLID_LOW); } if (fShowKeyboardFocus && x == fKeyboardX && y == fKeyboardY) _DrawKeyboardFocus(); - uint32 value = fField->ValueAt(x, y); if (value == 0) { _DrawHints(x, y); continue; } SetFont(&fFieldFont); - if ((fField->FlagsAt(x, y) & kInitialValue) != 0) + if (fField->IsInitialValue(x, y)) SetHighColor(0, 0, 0); else { if ((fHintFlags & kMarkInvalid) == 0 - || fField->ValidMaskAt(x, y) & (1UL << (value - 1))) { + || fField->IsValid(x, y, value)) { if (fField->IsValueCompleted(value)) - SetHighColor(60, 60, 150); + SetHighColor(kValueCompletedColor); else - SetHighColor(0, 0, 220); + SetHighColor(kValueColor); } else - SetHighColor(200, 0, 0); + SetHighColor(kInvalidValueColor); } char text[2]; diff --git a/src/apps/sudoku/SudokuView.h b/src/apps/sudoku/SudokuView.h index 70b67c7041..59532fbee6 100644 --- a/src/apps/sudoku/SudokuView.h +++ b/src/apps/sudoku/SudokuView.h @@ -94,8 +94,12 @@ private: void _InvalidateHintField(uint32 x, uint32 y, uint32 hintX, uint32 hintY); void _InvalidateField(uint32 x, uint32 y); + void _InvalidateValue(uint32 value, + bool invalidateHint = false, + uint32 x = ~0UL, uint32 y = ~0UL); void _InvalidateKeyboardFocus(uint32 x, uint32 y); void _InsertKey(char rawKey, int32 modifiers); + void _SetValueHintValue(uint32 value); void _RemoveHint(); bool _GetHintFieldFor(BPoint where, uint32 x, uint32 y, uint32& hintX, uint32& hintY); @@ -127,6 +131,7 @@ private: uint32 fShowHintY; uint32 fLastHintValue; bool fLastHintValueSet; + uint32 fValueHintValue; uint32 fLastField; uint32 fKeyboardX; uint32 fKeyboardY; From 7c8e561489a7c3b66094fc7fe704c14f0992f09e Mon Sep 17 00:00:00 2001 From: Alexander von Gluck IV Date: Wed, 6 Jun 2012 12:35:12 -0500 Subject: [PATCH 33/39] ATA: Display trim support of ata disk --- src/add-ons/kernel/busses/scsi/ahci/ahci_port.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/add-ons/kernel/busses/scsi/ahci/ahci_port.cpp b/src/add-ons/kernel/busses/scsi/ahci/ahci_port.cpp index 4d4f7be282..74b042bfb6 100644 --- a/src/add-ons/kernel/busses/scsi/ahci/ahci_port.cpp +++ b/src/add-ons/kernel/busses/scsi/ahci/ahci_port.cpp @@ -640,7 +640,9 @@ AHCIPort::ScsiInquiry(scsi_ccb *request) TRACE("model number: %s\n", modelNumber); TRACE("serial number: %s\n", serialNumber); - TRACE("firmware rev.: %s\n", firmwareRev); + TRACE("firmware rev.: %s\n", firmwareRev); + TRACE("trim support: %s\n", + ataData.data_set_management_support ? "yes" : "no"); if (sg_memcpy(request->sg_list, request->sg_count, &scsiData, sizeof(scsiData)) < B_OK) { From 7c5d8dd2a860071f70dfe0492d38eac3b1009ee4 Mon Sep 17 00:00:00 2001 From: Alexander von Gluck IV Date: Thu, 7 Jun 2012 11:52:25 -0500 Subject: [PATCH 34/39] mesa-o-matic: Fix bug exposed by new Mesa build * While we want to exclude include/GL (because we get the whole directory) we also exclude include/GLES2 which gets picked up in newer Mesa code * Add a slash on the end of the grep to make sure we omit *just* include/GL --- 3rdparty/mesa/mesa-o-matic.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rdparty/mesa/mesa-o-matic.sh b/3rdparty/mesa/mesa-o-matic.sh index a6d823a257..fb0da48ac7 100755 --- a/3rdparty/mesa/mesa-o-matic.sh +++ b/3rdparty/mesa/mesa-o-matic.sh @@ -81,7 +81,7 @@ do for y in $( echo "$HEADERS_RAW" | cut -d':' -f2 | sed 's/\\//g' | tr -d '\n' ) do - CLEAN_HEADER=$( echo "$y" | grep -v "include/GL" ) + CLEAN_HEADER=$( echo "$y" | grep -v "include/GL/" ) ZIP_HEADERS="$ZIP_HEADERS $CLEAN_HEADER" done done From b069fa30d9a571f2601dd58c0d812c1b4584da7e Mon Sep 17 00:00:00 2001 From: Alexander von Gluck IV Date: Thu, 7 Jun 2012 11:53:51 -0500 Subject: [PATCH 35/39] mesa: Update rtasm fix to work with latest mainline Mesa --- 3rdparty/mesa/Mesa-8.1devel-rtasmfix.diff | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/3rdparty/mesa/Mesa-8.1devel-rtasmfix.diff b/3rdparty/mesa/Mesa-8.1devel-rtasmfix.diff index 27bd42302d..ddeab72abd 100644 --- a/3rdparty/mesa/Mesa-8.1devel-rtasmfix.diff +++ b/3rdparty/mesa/Mesa-8.1devel-rtasmfix.diff @@ -1,14 +1,14 @@ diff --git a/src/mesa/sources.mak b/src/mesa/sources.mak -index c746b8a..09dc5f5 100644 +index 63fbf58..5530230 100644 --- a/src/mesa/sources.mak +++ b/src/mesa/sources.mak -@@ -276,7 +276,6 @@ ASM_C_SOURCES = \ - x86/x86_xform.c \ - x86/3dnow.c \ - x86/sse.c \ -- x86/rtasm/x86sse.c \ - sparc/sparc.c \ - x86-64/x86-64.c +@@ -277,7 +277,6 @@ ASM_C_FILES = \ + $(SRCDIR)/x86/x86_xform.c \ + $(SRCDIR)/x86/3dnow.c \ + $(SRCDIR)/x86/sse.c \ +- $(SRCDIR)/x86/rtasm/x86sse.c \ + $(SRCDIR)/sparc/sparc.c \ + $(SRCDIR)/x86-64/x86-64.c diff --git a/src/mesa/tnl/t_vertex_sse.c b/src/mesa/tnl/t_vertex_sse.c index e0141c3..1afaf78 100644 From b18a4c60739740b6c31ee37140bb64e1b56e3ec3 Mon Sep 17 00:00:00 2001 From: Alexander von Gluck IV Date: Thu, 7 Jun 2012 12:05:53 -0500 Subject: [PATCH 36/39] mesa: Update Mesa optional package to latest mainline mesa --- build/jam/OptionalBuildFeatures | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/jam/OptionalBuildFeatures b/build/jam/OptionalBuildFeatures index 350a781260..789c4e908e 100644 --- a/build/jam/OptionalBuildFeatures +++ b/build/jam/OptionalBuildFeatures @@ -177,8 +177,8 @@ if $(TARGET_ARCH) = x86 { local galliumObjects ; local zipFile ; if $(HAIKU_GCC_VERSION[1]) >= 4 { - HAIKU_MESA_FILE = mesa-8.1devel-x86-gcc4-2012-03-30.zip ; - #HAIKU_MESA_FILE = mesa-8.0develdbg-x86-gcc4-2012-02-20.zip ; + HAIKU_MESA_FILE = mesa-8.1devel-x86-gcc4-2012-06-07.zip ; + #HAIKU_MESA_FILE = mesa-8.1develdbg-x86-gcc4-2012-06-07.zip ; glslObject = lib.haiku/libglsl.a ; galliumObjects = lib.haiku/libgallium.a ; } else { From 581f28eb9b5821a3de816a7d1c795f218d2e4fd9 Mon Sep 17 00:00:00 2001 From: Alexander von Gluck IV Date: Thu, 7 Jun 2012 15:00:13 -0700 Subject: [PATCH 37/39] ahci: Add pretty name to AHCI devices * Naming is a little rough, but I can't think of anything better. * Two less "Unknown Devices" in Device application --- src/add-ons/kernel/busses/scsi/ahci/ahci.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/add-ons/kernel/busses/scsi/ahci/ahci.c b/src/add-ons/kernel/busses/scsi/ahci/ahci.c index 0aeccc788e..aa9e0e33d4 100644 --- a/src/add-ons/kernel/busses/scsi/ahci/ahci.c +++ b/src/add-ons/kernel/busses/scsi/ahci/ahci.c @@ -14,6 +14,8 @@ #define AHCI_ID_GENERATOR "ahci/id" #define AHCI_ID_ITEM "ahci/id" +#define AHCI_BRIDGE_PRETTY_NAME "AHCI Bridge" +#define AHCI_CONTROLLER_PRETTY_NAME "AHCI Controller" const device_info kSupportedDevices[] = { @@ -171,6 +173,8 @@ register_sim(device_node *parent) device_attr attrs[] = { { B_DEVICE_FIXED_CHILD, B_STRING_TYPE, { string: SCSI_FOR_SIM_MODULE_NAME }}, + { B_DEVICE_PRETTY_NAME, B_STRING_TYPE, + { string: AHCI_CONTROLLER_PRETTY_NAME }}, { SCSI_DESCRIPTION_CONTROLLER_NAME, B_STRING_TYPE, { string: AHCI_DEVICE_MODULE_NAME }}, @@ -260,6 +264,8 @@ ahci_register_device(device_node *parent) device_attr attrs[] = { { SCSI_DEVICE_MAX_TARGET_COUNT, B_UINT32_TYPE, { ui32: 33 }}, + { B_DEVICE_PRETTY_NAME, B_STRING_TYPE, + { string: AHCI_BRIDGE_PRETTY_NAME }}, // DMA properties // data must be word-aligned; From e5cca9b6cf520d6bd4f27b6a131efadc08780ddf Mon Sep 17 00:00:00 2001 From: Ryan Leavengood Date: Fri, 8 Jun 2012 23:23:50 -0400 Subject: [PATCH 38/39] Add Team Monitor shortcuts for kill and quit. Fixes ticket #8561. --- .../input_server/devices/keyboard/TeamMonitorWindow.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/add-ons/input_server/devices/keyboard/TeamMonitorWindow.cpp b/src/add-ons/input_server/devices/keyboard/TeamMonitorWindow.cpp index 03ddd51ec7..6941391d82 100644 --- a/src/add-ons/input_server/devices/keyboard/TeamMonitorWindow.cpp +++ b/src/add-ons/input_server/devices/keyboard/TeamMonitorWindow.cpp @@ -227,6 +227,10 @@ TeamMonitorWindow::TeamMonitorWindow() AddShortcut('T', B_COMMAND_KEY | B_OPTION_KEY, new BMessage(kMsgLaunchTerminal)); + AddShortcut('K', B_COMMAND_KEY | B_OPTION_KEY, + new BMessage(TM_KILL_APPLICATION)); + AddShortcut('Q', B_COMMAND_KEY | B_OPTION_KEY, + new BMessage(TM_QUIT_APPLICATION)); AddShortcut('W', B_COMMAND_KEY, new BMessage(B_QUIT_REQUESTED)); gLocalizedNamePreferred From 88495a828e19800f6046f14ee0fc413cd2520c57 Mon Sep 17 00:00:00 2001 From: Ryan Leavengood Date: Fri, 8 Jun 2012 23:24:57 -0400 Subject: [PATCH 39/39] Focus the Team Monitor list view when the window shows. This allows immediate use of the arrow keys to navigate the list. Fixes ticket #8564. --- src/add-ons/input_server/devices/keyboard/TeamMonitorWindow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/add-ons/input_server/devices/keyboard/TeamMonitorWindow.cpp b/src/add-ons/input_server/devices/keyboard/TeamMonitorWindow.cpp index 6941391d82..80984041ea 100644 --- a/src/add-ons/input_server/devices/keyboard/TeamMonitorWindow.cpp +++ b/src/add-ons/input_server/devices/keyboard/TeamMonitorWindow.cpp @@ -416,6 +416,8 @@ TeamMonitorWindow::UpdateList() } fRestartButton->SetEnabled(!desktopRunning); + + fListView->MakeFocus(); }