From 16307934faf5d843947d6eeae50c8e602aba5f85 Mon Sep 17 00:00:00 2001 From: Alexander von Gluck IV Date: Tue, 22 May 2012 09:51:52 -0500 Subject: [PATCH 01/62] rPi: Fix missing % --- src/system/boot/platform/raspberrypi_arm/mmu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/system/boot/platform/raspberrypi_arm/mmu.cpp b/src/system/boot/platform/raspberrypi_arm/mmu.cpp index f01bacc40a..aa486f265c 100644 --- a/src/system/boot/platform/raspberrypi_arm/mmu.cpp +++ b/src/system/boot/platform/raspberrypi_arm/mmu.cpp @@ -242,7 +242,7 @@ static uint32 * get_next_page_table(uint32 type) { TRACE("%s: sNextPageTableAddress %p, kPageTableRegionEnd %p, " - "type 0x" B_PRIX32 "\n", __func__, sNextPageTableAddress, + "type 0x%" B_PRIX32 "\n", __func__, sNextPageTableAddress, kPageTableRegionEnd, type); size_t size = 0; From 361ec26f1029f32f21641431c135e12dac68d1d4 Mon Sep 17 00:00:00 2001 From: Alexander von Gluck IV Date: Thu, 24 May 2012 05:48:10 -0500 Subject: [PATCH 02/62] rPi MMU: Cleanup, add gPeripheralBase * gPeripheralBase keeps track of the device peripherals before and after mmu_init * Add ability to disable mmu for troubleshooting * Remove static FB_BASE, we actually don't know where the FB is yet. (depends on firmware used) --- headers/private/kernel/arch/arm/bcm2708.h | 4 +- .../boot/platform/raspberrypi_arm/mmu.cpp | 37 +++++++++++++------ .../boot/platform/raspberrypi_arm/serial.cpp | 7 ++-- .../boot/platform/raspberrypi_arm/start.c | 6 ++- 4 files changed, 34 insertions(+), 20 deletions(-) diff --git a/headers/private/kernel/arch/arm/bcm2708.h b/headers/private/kernel/arch/arm/bcm2708.h index 740837224b..e124ae6aa7 100644 --- a/headers/private/kernel/arch/arm/bcm2708.h +++ b/headers/private/kernel/arch/arm/bcm2708.h @@ -62,9 +62,7 @@ // SMI Base #define USB_BASE 0x980000 // USB Controller, 15.2, page 202 -#define FB_BASE 0x000000 - // Fake frame buffer -#define FB_SIZE SIZE_4K +// FB_BASE will depend on memory split // 7.5, page 112 diff --git a/src/system/boot/platform/raspberrypi_arm/mmu.cpp b/src/system/boot/platform/raspberrypi_arm/mmu.cpp index aa486f265c..b80ad8b79f 100644 --- a/src/system/boot/platform/raspberrypi_arm/mmu.cpp +++ b/src/system/boot/platform/raspberrypi_arm/mmu.cpp @@ -40,9 +40,14 @@ // You also need to define ENABLE_SERIAL in serial.cpp // for output to work. +//#define DEBUG_DISABLE_MMU + + extern uint8 __stack_start; extern uint8 __stack_end; +extern addr_t gPeripheralBase; + /* *defines a block in memory @@ -60,6 +65,7 @@ struct memblock { static struct memblock LOADER_MEMORYMAP[] = { + // We map this first so we can always find peripherals { "devices", PERIPHERAL_BASE, @@ -114,20 +120,20 @@ static struct memblock LOADER_MEMORYMAP[] = { //static const uint32 kDefaultPageTableFlags = MMU_FLAG_READWRITE; // not cached not buffered, R/W -static const size_t kMaxKernelSize = 0x200000; // 2 MB for the kernel +static const size_t kMaxKernelSize = 0x200000; // 2 MB for the kernel -static addr_t sNextPhysicalAddress = 0; //will be set by mmu_init +static addr_t sNextPhysicalAddress = 0; // will be set by mmu_init static addr_t sNextVirtualAddress = KERNEL_BASE + kMaxKernelSize; static addr_t sMaxVirtualAddress = KERNEL_BASE + kMaxKernelSize; static addr_t sNextPageTableAddress = 0; -//the page directory is in front of the pagetable +// the page directory is in front of the pagetable static uint32 kPageTableRegionEnd = 0; // working page directory and page table static uint32 *sPageDirectory = 0 ; -//page directory has to be on a multiple of 16MB for -//some arm processors +// page directory has to be on a multiple of 16MB for +// some arm processors static addr_t @@ -141,11 +147,13 @@ get_next_virtual_address(size_t size) static addr_t -get_next_virtual_address_alligned (size_t size, uint32 mask) +get_next_virtual_address_alligned(size_t size, uint32 mask) { - addr_t address = (sNextVirtualAddress) & mask; + addr_t address = sNextVirtualAddress & mask; sNextVirtualAddress = address + size; + TRACE("%s: %p\n", __func__, (void*)address); + return address; } @@ -190,7 +198,7 @@ get_next_physical_page(size_t pagesize) void mmu_set_TTBR(uint32 ttb) { - TRACE("%s: Set Translation Table Base to 0x%lx\n", __func__); + TRACE("%s: Set Translation Table Base to 0x%" B_PRIx32 "\n", __func__, ttb); ttb &= 0xffffc000; asm volatile("MRC p15, 0, %[adr], c2, c0, 0"::[adr] "r" (ttb)); } @@ -233,7 +241,8 @@ mmu_write_C1(uint32 value) void mmu_write_DACR(uint32 value) { - TRACE("%s: Set Domain Access Register to 0x%lx\n", __func__); + TRACE("%s: Set Domain Access Register to 0x%" B_PRIx32 "\n", + __func__, value); asm volatile("MCR p15, 0, %[c1in], c3, c0, 0"::[c1in] "r" (value)); } @@ -242,7 +251,7 @@ static uint32 * get_next_page_table(uint32 type) { TRACE("%s: sNextPageTableAddress %p, kPageTableRegionEnd %p, " - "type 0x%" B_PRIX32 "\n", __func__, sNextPageTableAddress, + "type 0x%" B_PRIx32 "\n", __func__, sNextPageTableAddress, kPageTableRegionEnd, type); size_t size = 0; @@ -289,7 +298,7 @@ init_page_directory() sPageDirectory[i] = 0; uint32 *pageTable = NULL; - for (uint32 i = 0; i < ARRAY_SIZE(LOADER_MEMORYMAP);i++) { + for (uint32 i = 0; i < ARRAY_SIZE(LOADER_MEMORYMAP); i++) { pageTable = get_next_page_table(MMU_L1_TYPE_COARSE); TRACE("BLOCK: %s START: %lx END %lx\n", LOADER_MEMORYMAP[i].name, @@ -328,12 +337,16 @@ init_page_directory() // TLB Flush mmu_flush_TLB(); - // Set domain access register + // Set domain access register, manager access to all mmu_write_DACR(0xFFFFFFFF); + #ifndef DEBUG_DISABLE_MMU TRACE("%s: Enable MMU...\n", __func__); mmu_write_C1(mmu_read_C1() | 0x1); + gPeripheralBase = sNextVirtualAddress; + #endif + TRACE("%s: Complete\n", __func__); } diff --git a/src/system/boot/platform/raspberrypi_arm/serial.cpp b/src/system/boot/platform/raspberrypi_arm/serial.cpp index b97d0b7a6a..c64f45bdad 100644 --- a/src/system/boot/platform/raspberrypi_arm/serial.cpp +++ b/src/system/boot/platform/raspberrypi_arm/serial.cpp @@ -23,6 +23,7 @@ DebugUART *gUART; static bool sSerialEnabled = false; +extern addr_t gPeripheralBase; static void @@ -88,10 +89,8 @@ serial_cleanup(void) extern "C" void serial_init(void) { - addr_t uart0 = mmu_map_physical_memory(PERIPHERAL_BASE + BOARD_UART_DEBUG, - 0x00004000, kDefaultPageFlags); - - gUART = arch_get_uart_pl011(uart0, BOARD_UART_CLOCK); + gUART = arch_get_uart_pl011(gPeripheralBase + BOARD_UART_DEBUG, + BOARD_UART_CLOCK); gUART->InitEarly(); gUART->InitPort(9600); diff --git a/src/system/boot/platform/raspberrypi_arm/start.c b/src/system/boot/platform/raspberrypi_arm/start.c index 6b3de48b38..8887e34276 100644 --- a/src/system/boot/platform/raspberrypi_arm/start.c +++ b/src/system/boot/platform/raspberrypi_arm/start.c @@ -37,6 +37,9 @@ extern uint8 __stack_end; extern int main(stage2_args *args); void _start(void); +// Adjusted during mmu_init +addr_t gPeripheralBase = PERIPHERAL_BASE; + static void clear_bss(void) @@ -112,8 +115,9 @@ pi_start(void) gpio_init(); // Flick on "OK" led, use pre-mmu firmware base - gpio_write(PERIPHERAL_BASE + GPIO_BASE, 16, 0); + gpio_write(gPeripheralBase + GPIO_BASE, 16, 0); + // To debug mmu, enable serial_init above me! mmu_init(); serial_init(); From 9b2efb1ad5aac036f622dd71e677b6f876a1e0da Mon Sep 17 00:00:00 2001 From: Alexander von Gluck IV Date: Thu, 24 May 2012 06:17:22 -0500 Subject: [PATCH 03/62] rPi Console: Fix console vt100 calls * Use correct clear screen escape codes * Use correct set cursor location escape codes * Use correct set color escape codes --- .../boot/platform/raspberrypi_arm/console.cpp | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/system/boot/platform/raspberrypi_arm/console.cpp b/src/system/boot/platform/raspberrypi_arm/console.cpp index 5a12a31bf8..a3c7f1f2e6 100644 --- a/src/system/boot/platform/raspberrypi_arm/console.cpp +++ b/src/system/boot/platform/raspberrypi_arm/console.cpp @@ -98,38 +98,41 @@ VTConsole::VTConsole() void VTConsole::ClearScreen() { - WriteAt(NULL, 0LL, "\033E", 2); + WriteAt(NULL, 0LL, "\033[2J", 4); } void VTConsole::SetCursor(int32 x, int32 y) { - char buff[] = "\033Y "; + char buffer[8]; x = MIN(79, MAX(0, x)); y = MIN(24, MAX(0, y)); - buff[3] += (char)x; - buff[2] += (char)y; - WriteAt(NULL, 0LL, buff, 4); + int len = snprintf(buffer, sizeof(buffer), + "\033[%" B_PRId32 ";%" B_PRId32 "H", y, x); + WriteAt(NULL, 0LL, buffer, len); } void VTConsole::SetColor(int32 foreground, int32 background) { + return; static const char cmap[] = { - 15, 4, 2, 6, 1, 5, 3, 7, - 8, 12, 10, 14, 9, 13, 11, 0 }; - char buff[] = "\033b \033c "; + 0, 4, 2, 6, 1, 5, 3, 7 }; + char buffer[12]; - if (foreground < 0 && foreground >= 16) + if (foreground < 0 && foreground >= 8) return; - if (background < 0 && background >= 16) + if (background < 0 && background >= 8) return; - buff[2] += cmap[foreground]; - buff[5] += cmap[background]; - WriteAt(NULL, 0LL, buff, 6); + // We assume normal display attributes here + int len = snprintf(buffer, sizeof(buffer), + "\033[#0;3%" B_PRId32 ";4%" B_PRId32 "m", + cmap[foreground], cmap[background]); + + WriteAt(NULL, 0LL, buffer, len); } From 134ef79db008e22b357f9a81340cdccbe1377fbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Thu, 24 May 2012 21:15:46 +0200 Subject: [PATCH 04/62] U-Boot: add some sections to the ppc ldscript * it seems ld creates most of them anyway, taken from the openfirmware script. --- src/system/ldscripts/ppc/boot_loader_u-boot.ld | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/system/ldscripts/ppc/boot_loader_u-boot.ld b/src/system/ldscripts/ppc/boot_loader_u-boot.ld index 61649d0c60..5e29f69c6a 100644 --- a/src/system/ldscripts/ppc/boot_loader_u-boot.ld +++ b/src/system/ldscripts/ppc/boot_loader_u-boot.ld @@ -15,13 +15,16 @@ SECTIONS __ctor_end = .; .rodata : { *(.rodata .rodata.*) } + .sdata2 : { *(.sdata2) } /* writable data */ . = ALIGN(0x1000); __data_start = .; .data : { *(.data .gnu.linkonce.d.*) } .data.rel.ro : { *(.data.rel.ro.local .data.rel.ro*) } + .data.rel.local : { *(.data.rel.local*) } .got : { *(.got .got2) } + .sdata : { *(.sdata .sdata.* .gnu.linkonce.s.*) } /* uninitialized data (in same segment as writable data) */ __bss_start = .; From 6ca4ac0978ea0ac800eb80ca9a74e39530ad8607 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Thu, 24 May 2012 21:16:56 +0200 Subject: [PATCH 05/62] PPC: Add some kernel asm helpers to the bootloader * get/set_msr() will be useful for U-Boot. --- src/system/boot/arch/ppc/Jamfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/system/boot/arch/ppc/Jamfile b/src/system/boot/arch/ppc/Jamfile index c2b817b54c..62c625ed71 100644 --- a/src/system/boot/arch/ppc/Jamfile +++ b/src/system/boot/arch/ppc/Jamfile @@ -19,13 +19,14 @@ KernelMergeObject boot_arch_$(TARGET_ARCH).o : debug_uart_8250.cpp arch_uart_8250.cpp arch_elf.cpp + arch_cpu_asm.S : # additional flags : $(kernelArchObjects) $(kernelLibArchObjects) ; -SEARCH on [ FGristFiles arch_elf.cpp arch_uart_8250.cpp ] +SEARCH on [ FGristFiles arch_elf.cpp arch_uart_8250.cpp arch_cpu_asm.S ] = [ FDirName $(HAIKU_TOP) src system kernel arch $(TARGET_ARCH) ] ; SEARCH on [ FGristFiles debug_uart_8250.cpp ] From 3bd0ac4aa39e077d335e787dbe7a8dc0c04f247d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Thu, 24 May 2012 21:18:24 +0200 Subject: [PATCH 06/62] PPC: Add eioio as barrier for the UART class * probably unneeded but it shouldn't harm. --- src/system/kernel/arch/ppc/arch_uart_8250.cpp | 32 +++++++++++++++++-- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/src/system/kernel/arch/ppc/arch_uart_8250.cpp b/src/system/kernel/arch/ppc/arch_uart_8250.cpp index 5a10f50636..15894de3b2 100644 --- a/src/system/kernel/arch/ppc/arch_uart_8250.cpp +++ b/src/system/kernel/arch/ppc/arch_uart_8250.cpp @@ -5,15 +5,41 @@ #include #include +#include #include -// we shouldn't need special setup, we use plain MMIO. +class ArchUART8250 : public DebugUART8250 { +public: + ArchUART8250(addr_t base, int64 clock); + ~ArchUART8250(); + + virtual void Barrier(); +}; + + +ArchUART8250::ArchUART8250(addr_t base, int64 clock) + : DebugUART8250(base, clock) +{ +} + + +ArchUART8250::~ArchUART8250() +{ +} + + +void +ArchUART8250::Barrier() +{ + eieio(); +} + DebugUART8250 *arch_get_uart_8250(addr_t base, int64 clock) { - static char buffer[sizeof(DebugUART8250)]; - DebugUART8250 *uart = new(buffer) DebugUART8250(base, clock); + static char buffer[sizeof(ArchUART8250)]; + ArchUART8250 *uart = new(buffer) ArchUART8250(base, clock); return uart; } From 037f252fd0dd3e85ebf9eaceee58b1a5ce73ca0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Thu, 24 May 2012 21:27:37 +0200 Subject: [PATCH 07/62] U-Boot: split cpu.cpp into arch-specific and common parts * the common part should try to use the U-Boot API when found. * the arch part can make use of cpu features (like timer register) * the ppc code enables the FPU in the MSR, since it's used by vsnprintf(), which at least saves one FP register in its prologue. --- .../boot/platform/u-boot/arch/arm/Jamfile | 2 +- .../platform/u-boot/arch/arm/arch_cpu.cpp | 84 ++++++++++++++++ .../boot/platform/u-boot/arch/ppc/Jamfile | 2 +- .../platform/u-boot/arch/ppc/arch_cpu.cpp | 97 +++++++++++++++++++ src/system/boot/platform/u-boot/cpu.cpp | 36 ++----- src/system/boot/platform/u-boot/cpu.h | 2 + 6 files changed, 194 insertions(+), 29 deletions(-) create mode 100644 src/system/boot/platform/u-boot/arch/arm/arch_cpu.cpp create mode 100644 src/system/boot/platform/u-boot/arch/ppc/arch_cpu.cpp diff --git a/src/system/boot/platform/u-boot/arch/arm/Jamfile b/src/system/boot/platform/u-boot/arch/arm/Jamfile index a81e46bc90..f8b00e7826 100644 --- a/src/system/boot/platform/u-boot/arch/arm/Jamfile +++ b/src/system/boot/platform/u-boot/arch/arm/Jamfile @@ -15,7 +15,7 @@ KernelMergeObject boot_platform_u-boot_arm.o : #arch_mmu.cpp #arch_cpu_asm.S arch_start_kernel.S - #cpu.cpp + arch_cpu.cpp #mmu.cpp : -fno-pic ; diff --git a/src/system/boot/platform/u-boot/arch/arm/arch_cpu.cpp b/src/system/boot/platform/u-boot/arch/arm/arch_cpu.cpp new file mode 100644 index 0000000000..676191803d --- /dev/null +++ b/src/system/boot/platform/u-boot/arch/arm/arch_cpu.cpp @@ -0,0 +1,84 @@ +/* + * Copyright 2004-2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Distributed under the terms of the MIT License. + * + * calculate_cpu_conversion_factor() was written by Travis Geiselbrecht and + * licensed under the NewOS license. + */ + + +#include "cpu.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +//#define TRACE_CPU +#ifdef TRACE_CPU +# define TRACE(x) dprintf x +#else +# define TRACE(x) ; +#endif + +//uint32 gTimeConversionFactor; + + +static void +calculate_cpu_conversion_factor() +{ + #warning U-Boot:TODO! +} + + +static status_t +check_cpu_features() +{ + + #warning U-Boot:TODO! + return B_OK; +} + + +// #pragma mark - + + +extern "C" void +arch_spin(bigtime_t microseconds) +{ + for(bigtime_t i=0;i +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +//#define TRACE_CPU +#ifdef TRACE_CPU +# define TRACE(x) dprintf x +#else +# define TRACE(x) ; +#endif + +//uint32 gTimeConversionFactor; + + +static void +calculate_cpu_conversion_factor() +{ + #warning U-Boot:TODO! +} + + +static status_t +check_cpu_features() +{ + uint32 msr; + + // we do need an FPU + // on Sam460ex at least U-Boot doesn't enable the FPU for us + msr = get_msr(); + msr |= MSR_FP_AVAILABLE; + msr = set_msr(msr); + + if ((msr & MSR_FP_AVAILABLE) == 0) { + // sadly panic uses vsnprintf which fails without FPU anyway + panic("no FPU!"); + return B_ERROR; + } + + return B_OK; +} + + +// #pragma mark - + + +extern "C" void +arch_spin(bigtime_t microseconds) +{ + for(bigtime_t i=0;i Date: Thu, 24 May 2012 08:51:41 -0500 Subject: [PATCH 08/62] rPi console: Implement console_wait_for_key --- src/system/boot/platform/raspberrypi_arm/console.cpp | 5 +---- src/system/boot/platform/raspberrypi_arm/serial.h | 5 ++++- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/system/boot/platform/raspberrypi_arm/console.cpp b/src/system/boot/platform/raspberrypi_arm/console.cpp index a3c7f1f2e6..31cc7f286c 100644 --- a/src/system/boot/platform/raspberrypi_arm/console.cpp +++ b/src/system/boot/platform/raspberrypi_arm/console.cpp @@ -209,12 +209,9 @@ console_hide_cursor(void) int console_wait_for_key(void) { - #warning IMPLEMENT console_wait_for_key - #if 0 union key key; + key.ax = serial_getc(true); return key.code.ascii; - #endif - return 0; } diff --git a/src/system/boot/platform/raspberrypi_arm/serial.h b/src/system/boot/platform/raspberrypi_arm/serial.h index 6004f5a9a1..d9c13e287e 100644 --- a/src/system/boot/platform/raspberrypi_arm/serial.h +++ b/src/system/boot/platform/raspberrypi_arm/serial.h @@ -15,10 +15,13 @@ extern "C" { extern void serial_init(void); extern void serial_cleanup(void); -extern void serial_puts(const char *string, size_t size); extern void serial_disable(void); extern void serial_enable(void); +extern void serial_puts(const char *string, size_t size); +extern int serial_getc(bool wait); + + #ifdef __cplusplus } #endif From 13480221336e68db760e7972172254eb6bbb9743 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Thu, 24 May 2012 21:53:38 +0200 Subject: [PATCH 09/62] PPC: Move asm helpers to U-Boot arch Jamfile * the OpenFirmware arch/ppc/Jamfile already has it, so move it to avoid duplicated symbols. --- src/system/boot/arch/ppc/Jamfile | 3 +-- src/system/boot/platform/u-boot/arch/ppc/Jamfile | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/system/boot/arch/ppc/Jamfile b/src/system/boot/arch/ppc/Jamfile index 62c625ed71..c2b817b54c 100644 --- a/src/system/boot/arch/ppc/Jamfile +++ b/src/system/boot/arch/ppc/Jamfile @@ -19,14 +19,13 @@ KernelMergeObject boot_arch_$(TARGET_ARCH).o : debug_uart_8250.cpp arch_uart_8250.cpp arch_elf.cpp - arch_cpu_asm.S : # additional flags : $(kernelArchObjects) $(kernelLibArchObjects) ; -SEARCH on [ FGristFiles arch_elf.cpp arch_uart_8250.cpp arch_cpu_asm.S ] +SEARCH on [ FGristFiles arch_elf.cpp arch_uart_8250.cpp ] = [ FDirName $(HAIKU_TOP) src system kernel arch $(TARGET_ARCH) ] ; SEARCH on [ FGristFiles debug_uart_8250.cpp ] diff --git a/src/system/boot/platform/u-boot/arch/ppc/Jamfile b/src/system/boot/platform/u-boot/arch/ppc/Jamfile index 793ca7796f..c8c7e1b791 100644 --- a/src/system/boot/platform/u-boot/arch/ppc/Jamfile +++ b/src/system/boot/platform/u-boot/arch/ppc/Jamfile @@ -13,7 +13,7 @@ KernelMergeObject boot_platform_u-boot_ppc.o : shell.S #arch_mmu.cpp - #arch_cpu_asm.S + arch_cpu_asm.S arch_start_kernel.S arch_cpu.cpp #mmu.cpp From b7aa0a94ff7d495bdb300508bf0a34b8072827fb Mon Sep 17 00:00:00 2001 From: Alexander von Gluck IV Date: Thu, 24 May 2012 10:25:52 -0500 Subject: [PATCH 10/62] ARM platform: Undo change to MMU page table assignment * While the baremetal arm book I have says mrc, it breaks verdex and doesn't work on the Pi. * Moving the page table address to the p15 coprocessor makes more logical sense anyway... i think mrc was a typo. --- src/system/boot/platform/raspberrypi_arm/mmu.cpp | 2 +- src/system/boot/platform/u-boot/mmu.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/system/boot/platform/raspberrypi_arm/mmu.cpp b/src/system/boot/platform/raspberrypi_arm/mmu.cpp index b80ad8b79f..bf1d3d6c2f 100644 --- a/src/system/boot/platform/raspberrypi_arm/mmu.cpp +++ b/src/system/boot/platform/raspberrypi_arm/mmu.cpp @@ -200,7 +200,7 @@ mmu_set_TTBR(uint32 ttb) { TRACE("%s: Set Translation Table Base to 0x%" B_PRIx32 "\n", __func__, ttb); ttb &= 0xffffc000; - asm volatile("MRC p15, 0, %[adr], c2, c0, 0"::[adr] "r" (ttb)); + asm volatile("MCR p15, 0, %[adr], c2, c0, 0"::[adr] "r" (ttb)); } diff --git a/src/system/boot/platform/u-boot/mmu.cpp b/src/system/boot/platform/u-boot/mmu.cpp index 60891dcfdd..bab74229fd 100644 --- a/src/system/boot/platform/u-boot/mmu.cpp +++ b/src/system/boot/platform/u-boot/mmu.cpp @@ -205,7 +205,7 @@ void mmu_set_TTBR(uint32 ttb) { ttb &= 0xffffc000; - asm volatile("MRC p15, 0, %[adr], c2, c0, 0"::[adr] "r" (ttb)); + asm volatile("MCR p15, 0, %[adr], c2, c0, 0"::[adr] "r" (ttb)); } From 936b7fe4331f2dbfe63697bd90e29ce23fb828c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Fri, 25 May 2012 01:40:31 +0200 Subject: [PATCH 11/62] Fixed a possible FD leak, CID 702009. --- src/add-ons/disk_systems/bfs/BFSAddOn.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/add-ons/disk_systems/bfs/BFSAddOn.cpp b/src/add-ons/disk_systems/bfs/BFSAddOn.cpp index e0ca448e4e..b33c828a77 100644 --- a/src/add-ons/disk_systems/bfs/BFSAddOn.cpp +++ b/src/add-ons/disk_systems/bfs/BFSAddOn.cpp @@ -230,6 +230,8 @@ BFSPartitionHandle::Repair(bool checkOnly) if (fd < 0) return errno; + FileDescriptorCloser closer(fd); + struct check_control result; memset(&result, 0, sizeof(result)); result.magic = BFS_IOCTL_CHECK_MAGIC; @@ -295,12 +297,8 @@ BFSPartitionHandle::Repair(bool checkOnly) } // stop checking - if (ioctl(fd, BFS_IOCTL_STOP_CHECKING, &result, sizeof(result)) != 0) { - close(fd); + if (ioctl(fd, BFS_IOCTL_STOP_CHECKING, &result, sizeof(result)) != 0) return errno; - } - - close(fd); printf(" %" B_PRIu64 " nodes checked,\n\t%" B_PRIu64 " blocks not " "allocated,\n\t%" B_PRIu64 " blocks already set,\n\t%" B_PRIu64 From 85136facdeaac7df6ae1f0b4f2dbfb3550ded245 Mon Sep 17 00:00:00 2001 From: John Scipione Date: Thu, 24 May 2012 21:38:25 -0400 Subject: [PATCH 12/62] Fix formatting bug in Deskcalc. Calculations that take up the full width of the Deskcalc window sometimes scroll the result over showing you only the tail end. This is because the horizontal inset makes the area too small to fit the result. Removing this horizontal inset means that the result will always fit in the space provided, and Deskcalc will recalculate to fit, but it also means that the result always starts at the leftmost side of the textarea, a fair tradeoff. --- src/apps/deskcalc/CalcView.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/deskcalc/CalcView.cpp b/src/apps/deskcalc/CalcView.cpp index 625034e748..f5b13afe2d 100644 --- a/src/apps/deskcalc/CalcView.cpp +++ b/src/apps/deskcalc/CalcView.cpp @@ -693,7 +693,7 @@ CalcView::FrameResized(float width, float height) frame.OffsetTo(B_ORIGIN); float inset = (frame.Height() - fExpressionTextView->LineHeight(0)) / 2; - frame.InsetBy(inset, inset); + frame.InsetBy(0, inset); fExpressionTextView->SetTextRect(frame); Invalidate(); } From 028ad0311cbf31c75dfa6da3f7f912a98969ce14 Mon Sep 17 00:00:00 2001 From: Adrien Destugues - PulkoMandy Date: Sun, 27 May 2012 08:42:33 +0200 Subject: [PATCH 13/62] Fix collecting of ifdef dependant strings Following some recent changes, the collection of strings does not use B_COLLECTING_CATKEYS define anymore. Adjust the code to use B_TRANSLATE_MARK_VOID instead, leading to the same result (string is added to catalog, but not used) --- .../outbound_protocols/smtp/ConfigView.cpp | 14 ++++++------- src/apps/deskbar/DeskbarMenu.cpp | 21 ++++++------------- 2 files changed, 12 insertions(+), 23 deletions(-) diff --git a/src/add-ons/mail_daemon/outbound_protocols/smtp/ConfigView.cpp b/src/add-ons/mail_daemon/outbound_protocols/smtp/ConfigView.cpp index 6024b56eb2..888c45118b 100644 --- a/src/add-ons/mail_daemon/outbound_protocols/smtp/ConfigView.cpp +++ b/src/add-ons/mail_daemon/outbound_protocols/smtp/ConfigView.cpp @@ -43,16 +43,14 @@ SMTPConfigView::SMTPConfigView(MailAddonSettings& settings, #endif ) { -#if defined(USE_SSL) || defined(B_COLLECTING_CATKEYS) - static const char* kUnencryptedStr = B_TRANSLATE_MARK("Unencrypted"); - static const char* kSSLStr = B_TRANSLATE_MARK("SSL"); - static const char* kSTARTTLSStr = B_TRANSLATE_MARK("STARTTLS"); -#endif + B_TRANSLATE_MARK_VOID("Unencrypted"); + B_TRANSLATE_MARK_VOID("SSL"); + B_TRANSLATE_MARK_VOID("STARTTLS"); #ifdef USE_SSL - AddFlavor(B_TRANSLATE_NOCOLLECT(kUnencryptedStr)); - AddFlavor(B_TRANSLATE(kSSLStr)); - AddFlavor(B_TRANSLATE(kSTARTTLSStr)); + AddFlavor(B_TRANSLATE_NOCOLLECT("Unencrypted")); + AddFlavor(B_TRANSLATE("SSL")); + AddFlavor(B_TRANSLATE("STARTTLS")); #endif AddAuthMethod(B_TRANSLATE("None"), false); diff --git a/src/apps/deskbar/DeskbarMenu.cpp b/src/apps/deskbar/DeskbarMenu.cpp index bd0bd65b1d..04d51fbb6f 100644 --- a/src/apps/deskbar/DeskbarMenu.cpp +++ b/src/apps/deskbar/DeskbarMenu.cpp @@ -253,21 +253,14 @@ TDeskbarMenu::AddStandardDeskbarMenuItems() // One of them is used if HAIKU_DISTRO_COMPATIBILITY_OFFICIAL, and the other if // not. However, we want both of them to end up in the catalog, so we have to // make them visible to collectcatkeys in either case. -#if defined(B_COLLECTING_CATKEYS)||defined(HAIKU_DISTRO_COMPATIBILITY_OFFICIAL) - static const char* kAboutHaikuMenuItemStr = B_TRANSLATE_MARK( - "About Haiku"); -#endif - -#if defined(B_COLLECTING_CATKEYS)||!defined(HAIKU_DISTRO_COMPATIBILITY_OFFICIAL) - static const char* kAboutThisSystemMenuItemStr = B_TRANSLATE_MARK( - "About this system"); -#endif +B_TRANSLATE_MARK_VOID("About Haiku") +B_TRANSLATE_MARK_VOID("About this system") item = new BMenuItem( #ifdef HAIKU_DISTRO_COMPATIBILITY_OFFICIAL - B_TRANSLATE_NOCOLLECT(kAboutHaikuMenuItemStr) + B_TRANSLATE_NOCOLLECT("About Haiku") #else - B_TRANSLATE_NOCOLLECT(kAboutThisSystemMenuItemStr) + B_TRANSLATE_NOCOLLECT("About this system") #endif , new BMessage(kShowSplash)); item->SetEnabled(!dragging); @@ -316,13 +309,11 @@ TDeskbarMenu::AddStandardDeskbarMenuItems() item->SetEnabled(!dragging); shutdownMenu->AddItem(item); -#if defined(APM_SUPPORT) || defined(B_COLLECTING_CATKEYS) - static const char* kSuspendMenuItemStr = B_TRANSLATE_MARK("Suspend"); -#endif + B_TRANSLATE_MARK_VOID("Suspend"); #ifdef APM_SUPPORT if (_kapm_control_(APM_CHECK_ENABLED) == B_OK) { - item = new BMenuItem(B_TRANSLATE_NOCOLLECT(kSuspendMenuItemStr), + item = new BMenuItem(B_TRANSLATE_NOCOLLECT("Suspend"), new BMessage(kSuspendSystem)); item->SetEnabled(!dragging); shutdownMenu->AddItem(item); From c2d1fc4ffa7236283061c6358c31f9067c672ca6 Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Sun, 27 May 2012 21:46:50 -0400 Subject: [PATCH 14/62] 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 15/62] 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 16/62] 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 17/62] 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 18/62] 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 19/62] 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 20/62] 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 21/62] 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 22/62] 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 23/62] 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 24/62] 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 25/62] 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 26/62] 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 27/62] 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 28/62] 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 29/62] 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 30/62] 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 31/62] 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 32/62] 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 33/62] 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 34/62] 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 35/62] 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 36/62] 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 37/62] 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 38/62] 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 39/62] 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 40/62] 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 41/62] 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 42/62] 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 43/62] 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 44/62] 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 45/62] 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 46/62] 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 47/62] 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 48/62] 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 49/62] 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 50/62] 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 51/62] 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 52/62] 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(); } From 131161928c79fdf5e4e3651ec01f496740602bb7 Mon Sep 17 00:00:00 2001 From: Humdinger Date: Fri, 8 Jun 2012 10:43:02 +0200 Subject: [PATCH 53/62] Small correction to heading 2.1 in Installer text --- src/apps/installer/InstallerApp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/installer/InstallerApp.cpp b/src/apps/installer/InstallerApp.cpp index d7d7d4baa8..431ea2507a 100644 --- a/src/apps/installer/InstallerApp.cpp +++ b/src/apps/installer/InstallerApp.cpp @@ -129,7 +129,7 @@ InstallerApp::ReadyToRun() "menu. Depending on what version of GRUB you use, this is done " "differently.\n\n\n"); infoText << B_TRANSLATE( - "2.1) GRUB 1\n"); + "2.1) GRUB (since os-prober v1.44)\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, " From 20b3f78f8d7e5a2df62aa59c7e15bc5ffd7431ab Mon Sep 17 00:00:00 2001 From: Ryan Leavengood Date: Sat, 9 Jun 2012 16:41:13 -0400 Subject: [PATCH 54/62] Draw the chosen color next to the name of system colors. I copied BStringItem::Draw then modified it. I couldn't find a clean way of doing it otherwise, since the color box drawing needs to occur between the selection and text drawing, and the text needs to be offset while the selection shouldn't be. --- src/preferences/appearance/APRView.cpp | 14 +++- src/preferences/appearance/ColorWhichItem.cpp | 65 +++++++++++++++++-- src/preferences/appearance/ColorWhichItem.h | 13 +++- 3 files changed, 83 insertions(+), 9 deletions(-) diff --git a/src/preferences/appearance/APRView.cpp b/src/preferences/appearance/APRView.cpp index 32533af441..33b59d5d3a 100644 --- a/src/preferences/appearance/APRView.cpp +++ b/src/preferences/appearance/APRView.cpp @@ -70,6 +70,8 @@ APRView::APRView(const char* name) } #endif + LoadSettings(); + // Set up list of color attributes fAttrList = new BListView("AttributeList", B_SINGLE_SELECTION_LIST); @@ -80,7 +82,8 @@ APRView::APRView(const char* name) const ColorDescription& description = *get_color_description(i); const char* text = B_TRANSLATE_NOCOLLECT(description.text); color_which which = description.which; - fAttrList->AddItem(new ColorWhichItem(text, which)); + fAttrList->AddItem(new ColorWhichItem(text, which, + fCurrentSet.GetColor(which))); } BRect wellrect(0, 0, 50, 50); @@ -122,7 +125,6 @@ APRView::AttachedToWindow() fAttrList->SetTarget(this); fColorWell->SetTarget(this); - LoadSettings(); fAttrList->Select(0); } @@ -246,6 +248,14 @@ void APRView::_UpdateControls() { rgb_color color = fCurrentSet.GetColor(fWhich); + + int32 currentIndex = fAttrList->CurrentSelection(); + ColorWhichItem *item = (ColorWhichItem*) fAttrList->ItemAt(currentIndex); + if (item != NULL) { + item->SetColor(color); + fAttrList->InvalidateItem(currentIndex); + } + fPicker->SetValue(color); fColorWell->SetColor(color); fColorWell->Invalidate(); diff --git a/src/preferences/appearance/ColorWhichItem.cpp b/src/preferences/appearance/ColorWhichItem.cpp index 6c14349aac..23edda4f6d 100644 --- a/src/preferences/appearance/ColorWhichItem.cpp +++ b/src/preferences/appearance/ColorWhichItem.cpp @@ -5,19 +5,76 @@ * Authors: * DarkWyrm (darkwyrm@earthlink.net) * Rene Gollent (rene@gollent.com) + * Ryan Leavengood */ + + #include "ColorWhichItem.h" + #include -ColorWhichItem::ColorWhichItem(const char* text, color_which which) - : BStringItem(text, 0, false) - , colorWhich(which) + +ColorWhichItem::ColorWhichItem(const char* text, color_which which, + rgb_color color) + : + BStringItem(text, 0, false), + fColorWhich(which), + fColor(color) { } + +void +ColorWhichItem::DrawItem(BView *owner, BRect frame, bool complete) +{ + rgb_color highColor = owner->HighColor(); + rgb_color lowColor = owner->LowColor(); + + if (IsSelected() || complete) { + if (IsSelected()) { + owner->SetHighColor(tint_color(lowColor, B_DARKEN_2_TINT)); + owner->SetLowColor(owner->HighColor()); + } else + owner->SetHighColor(lowColor); + + owner->FillRect(frame); + } + + rgb_color black = {0, 0, 0, 255}; + + BRect colorRect(frame); + colorRect.InsetBy(2, 2); + colorRect.right = colorRect.left + colorRect.Height(); + owner->SetHighColor(fColor); + owner->FillRect(colorRect); + owner->SetHighColor(black); + owner->StrokeRect(colorRect); + + owner->MovePenTo(frame.left + colorRect.Width() + 8, frame.top + + BaselineOffset()); + + if (!IsEnabled()) + owner->SetHighColor(tint_color(black, B_LIGHTEN_2_TINT)); + else + owner->SetHighColor(black); + + owner->DrawString(Text()); + + owner->SetHighColor(highColor); + owner->SetLowColor(lowColor); +} + + color_which ColorWhichItem::ColorWhich(void) { - return colorWhich; + return fColorWhich; +} + + +void +ColorWhichItem::SetColor(rgb_color color) +{ + fColor = color; } diff --git a/src/preferences/appearance/ColorWhichItem.h b/src/preferences/appearance/ColorWhichItem.h index 2d2319e760..abc5853719 100644 --- a/src/preferences/appearance/ColorWhichItem.h +++ b/src/preferences/appearance/ColorWhichItem.h @@ -5,22 +5,29 @@ * Authors: * DarkWyrm * Rene Gollent (rene@gollent.com) + * Ryan Leavengood */ + + #ifndef COLORWHICH_ITEM_H #define COLORWHICH_ITEM_H #include #include +#include class ColorWhichItem : public BStringItem { public: - ColorWhichItem(const char* text, color_which which); + ColorWhichItem(const char* text, color_which which, rgb_color color); - color_which ColorWhich(void); + virtual void DrawItem(BView *owner, BRect frame, bool complete); + color_which ColorWhich(void); + void SetColor(rgb_color color); private: - color_which colorWhich; + color_which fColorWhich; + rgb_color fColor; }; #endif From 70a5df3878c7778c8342a268f62176f15245ab35 Mon Sep 17 00:00:00 2001 From: Ryan Leavengood Date: Sat, 9 Jun 2012 22:27:29 -0400 Subject: [PATCH 55/62] Use the correct color for the tab border for inactive windows. Before this the active window border color was used, resulting in ugly inactive window tabs if the active and inactive border colors were quite different. This was not noticed before because the defaults are two very similar grays. --- src/servers/app/decorator/DefaultDecorator.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/servers/app/decorator/DefaultDecorator.cpp b/src/servers/app/decorator/DefaultDecorator.cpp index 05e693d782..4e1b245724 100644 --- a/src/servers/app/decorator/DefaultDecorator.cpp +++ b/src/servers/app/decorator/DefaultDecorator.cpp @@ -1490,17 +1490,21 @@ DefaultDecorator::GetComponentColors(Component component, uint8 highlight, DefaultDecorator::Tab* tab = static_cast(_tab); switch (component) { case COMPONENT_TAB: - _colors[COLOR_TAB_FRAME_LIGHT] - = tint_color(kFocusFrameColor, B_DARKEN_2_TINT); - _colors[COLOR_TAB_FRAME_DARK] - = tint_color(kFocusFrameColor, B_DARKEN_3_TINT); if (tab && tab->buttonFocus) { + _colors[COLOR_TAB_FRAME_LIGHT] + = tint_color(kFocusFrameColor, B_DARKEN_2_TINT); + _colors[COLOR_TAB_FRAME_DARK] + = tint_color(kFocusFrameColor, B_DARKEN_3_TINT); _colors[COLOR_TAB] = kFocusTabColor; _colors[COLOR_TAB_LIGHT] = kFocusTabColorLight; _colors[COLOR_TAB_BEVEL] = kFocusTabColorBevel; _colors[COLOR_TAB_SHADOW] = kFocusTabColorShadow; _colors[COLOR_TAB_TEXT] = kFocusTextColor; } else { + _colors[COLOR_TAB_FRAME_LIGHT] + = tint_color(kNonFocusFrameColor, B_DARKEN_2_TINT); + _colors[COLOR_TAB_FRAME_DARK] + = tint_color(kNonFocusFrameColor, B_DARKEN_3_TINT); _colors[COLOR_TAB] = kNonFocusTabColor; _colors[COLOR_TAB_LIGHT] = kNonFocusTabColorLight; _colors[COLOR_TAB_BEVEL] = kNonFocusTabColorBevel; From 585d44f283e2d07d855f18b2f0573a4243b33844 Mon Sep 17 00:00:00 2001 From: Ryan Leavengood Date: Sun, 10 Jun 2012 00:14:21 -0400 Subject: [PATCH 56/62] Improve the workspace view tab rendering. Before this the height and width of the tab would jump around as the window was moved. In addition there was an off-by-one error which caused right-aligned tabs to not be drawn right (as reported in ticket #4615, which this fixes.) --- src/servers/app/WorkspacesView.cpp | 34 +++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/src/servers/app/WorkspacesView.cpp b/src/servers/app/WorkspacesView.cpp index a475aad31a..60df6d8cb1 100644 --- a/src/servers/app/WorkspacesView.cpp +++ b/src/servers/app/WorkspacesView.cpp @@ -214,18 +214,32 @@ WorkspacesView::_DrawWindow(DrawingEngine* drawingEngine, _DarkenColor(white); } - if (tabFrame.left < frame.left) - tabFrame.left = frame.left; - if (tabFrame.right >= frame.right) - tabFrame.right = frame.right - 1; + if (tabFrame.Height() > 0 && tabFrame.Width() > 0) { + float width = tabFrame.Width(); + if (tabFrame.left < frame.left) { + // Shift the tab right + tabFrame.left = frame.left; + tabFrame.right = tabFrame.left + width; + } + if (tabFrame.right > frame.right) { + // Shift the tab left + tabFrame.right = frame.right; + tabFrame.left = tabFrame.right - width; + } - tabFrame.bottom = frame.top - 1; - tabFrame.top = min_c(tabFrame.top, tabFrame.bottom); - tabFrame = tabFrame & workspaceFrame; + if (tabFrame.Height() > 0 && tabFrame.bottom >= tabFrame.top) { + // Shift the tab up + float tabHeight = tabFrame.Height(); + tabFrame.bottom = frame.top - 1; + tabFrame.top = tabFrame.bottom - tabHeight; + } - if (decorator != NULL && tabFrame.IsValid()) { - drawingEngine->FillRect(tabFrame, tabColor); - backgroundRegion.Exclude(tabFrame); + tabFrame = tabFrame & workspaceFrame; + + if (decorator != NULL && tabFrame.IsValid()) { + drawingEngine->FillRect(tabFrame, tabColor); + backgroundRegion.Exclude(tabFrame); + } } drawingEngine->StrokeRect(frame, frameColor); From b9d90cb1096895940bd9ae15b1d816e4327edd38 Mon Sep 17 00:00:00 2001 From: Ryan Leavengood Date: Sun, 10 Jun 2012 00:21:06 -0400 Subject: [PATCH 57/62] Remove superfluous check for Height() since it is checked above --- src/servers/app/WorkspacesView.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/servers/app/WorkspacesView.cpp b/src/servers/app/WorkspacesView.cpp index 60df6d8cb1..578775d8ac 100644 --- a/src/servers/app/WorkspacesView.cpp +++ b/src/servers/app/WorkspacesView.cpp @@ -227,7 +227,7 @@ WorkspacesView::_DrawWindow(DrawingEngine* drawingEngine, tabFrame.left = tabFrame.right - width; } - if (tabFrame.Height() > 0 && tabFrame.bottom >= tabFrame.top) { + if (tabFrame.bottom >= tabFrame.top) { // Shift the tab up float tabHeight = tabFrame.Height(); tabFrame.bottom = frame.top - 1; From 9609fb5050b23018d4d809f2f37ffcb6cbe04860 Mon Sep 17 00:00:00 2001 From: Ryan Leavengood Date: Sun, 10 Jun 2012 00:23:51 -0400 Subject: [PATCH 58/62] Double scrollbar thumbs have returned!!! Let the flamewar begin. --- src/servers/app/DesktopSettings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/servers/app/DesktopSettings.cpp b/src/servers/app/DesktopSettings.cpp index d4378d3532..f12b1484f8 100644 --- a/src/servers/app/DesktopSettings.cpp +++ b/src/servers/app/DesktopSettings.cpp @@ -57,7 +57,7 @@ DesktopSettingsPrivate::_SetDefaults() // init scrollbar info fScrollBarInfo.proportional = true; - fScrollBarInfo.double_arrows = false; + fScrollBarInfo.double_arrows = true; fScrollBarInfo.knob = 1; // look of the knob (R5: (0, 1, 2), 1 = default) fScrollBarInfo.min_knob_size = 15; From 163cd4bf53064ff57a1feadc14f04d7c09fc8efc Mon Sep 17 00:00:00 2001 From: Philippe Saint-Pierre Date: Sun, 10 Jun 2012 16:57:45 -0400 Subject: [PATCH 59/62] Prevent ressource leak in time preferences (ntp update) CID 702055. --- src/preferences/time/ntp.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/preferences/time/ntp.cpp b/src/preferences/time/ntp.cpp index 7ee56be4a1..167ef2ca4b 100644 --- a/src/preferences/time/ntp.cpp +++ b/src/preferences/time/ntp.cpp @@ -153,6 +153,7 @@ ntp_update_time(const char* hostname, const char** errorString, 0, (struct sockaddr *)&address, sizeof(address)) < 0) { *errorString = B_TRANSLATE("Sending request failed"); *errorCode = errno; + close(connection); return B_ERROR; } @@ -168,6 +169,7 @@ ntp_update_time(const char* hostname, const char** errorString, if (select(connection + 1, &waitForReceived, NULL, NULL, &timeout) <= 0) { *errorString = B_TRANSLATE("Waiting for answer failed"); *errorCode = errno; + close(connection); return B_ERROR; } From 372863638f6eb692e597c69b6677e2312a7ee600 Mon Sep 17 00:00:00 2001 From: Alexander von Gluck IV Date: Fri, 8 Jun 2012 08:48:21 -0700 Subject: [PATCH 60/62] scsi: Add write same SCSI operation * Will be used for TRIM --- headers/private/drivers/scsi_cmds.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/headers/private/drivers/scsi_cmds.h b/headers/private/drivers/scsi_cmds.h index 2baabdd2eb..1e1a47ccbd 100644 --- a/headers/private/drivers/scsi_cmds.h +++ b/headers/private/drivers/scsi_cmds.h @@ -196,6 +196,7 @@ #define SCSI_OP_READ_16 0x88 #define SCSI_OP_WRITE_16 0x8a #define SCSI_OP_VERIFY_16 0x8f +#define SCSI_OP_WRITE_SAME_16 0x93 #define SCSI_OP_SERVICE_ACTION_IN 0x9e #define SCSI_OP_SERVICE_ACTION_OUT 0x9f #define SCSI_OP_MOVE_MEDIUM 0xa5 @@ -435,6 +436,28 @@ typedef struct scsi_cmd_rw_16 { } _PACKED scsi_cmd_rw_16; +// WRITE SAME (16) + +typedef struct scsi_cmd_wsame_16 { + uint8 opcode; + LBITFIELD8_6( + _res1_0 : 1, + lb_data : 1, + pb_data : 1, + unmap : 1, + _res1_4 : 1, + write_protect : 3 + ); + uint64 lba; + uint32 length; + LBITFIELD8_2( + group_number : 5, + _res14_5 : 3 + ); + uint8 control; +} _PACKED scsi_cmd_wsame_16; + + // REQUEST SENSE typedef struct scsi_cmd_request_sense { From b937bd211c37af1cbd71f58ab0b1f272020f1103 Mon Sep 17 00:00:00 2001 From: Alexander von Gluck IV Date: Fri, 8 Jun 2012 09:18:31 -0700 Subject: [PATCH 61/62] ahci: Initial TRIM work * Since ahci devices are emulated as scsi, we use the SAS style TRIM call (unmap in scsi write same) * This prevents the need for special, one off trim calls. * We don't perform the TRIM just yet, just laying the goundwork for the request. --- .../kernel/busses/scsi/ahci/ahci_port.cpp | 32 +++++++++++++++++-- .../kernel/busses/scsi/ahci/ahci_port.h | 1 + 2 files changed, 30 insertions(+), 3 deletions(-) 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 74b042bfb6..9b6da859d3 100644 --- a/src/add-ons/kernel/busses/scsi/ahci/ahci_port.cpp +++ b/src/add-ons/kernel/busses/scsi/ahci/ahci_port.cpp @@ -50,7 +50,8 @@ AHCIPort::AHCIPort(AHCIController *controller, int index) fIsATAPI(false), fTestUnitReadyActive(false), fResetPort(false), - fError(false) + fError(false), + fTrim(false) { B_INITIALIZE_SPINLOCK(&fSpinlock); fRequestSem = create_sem(1, "ahci request"); @@ -613,6 +614,7 @@ AHCIPort::ScsiInquiry(scsi_ccb *request) fUse48BitCommands = lba && lba48; fSectorSize = 512; fSectorCount = !(lba || sectors) ? 0 : lba48 ? sectors48 : sectors; + fTrim = ataData.data_set_management_support; TRACE("lba %d, lba48 %d, fUse48BitCommands %d, sectors %lu, " "sectors48 %llu, size %llu\n", lba, lba48, fUse48BitCommands, sectors, sectors48, @@ -641,8 +643,7 @@ AHCIPort::ScsiInquiry(scsi_ccb *request) TRACE("model number: %s\n", modelNumber); TRACE("serial number: %s\n", serialNumber); TRACE("firmware rev.: %s\n", firmwareRev); - TRACE("trim support: %s\n", - ataData.data_set_management_support ? "yes" : "no"); + TRACE("trim support: %s\n", fTrim ? "yes" : "no"); if (sg_memcpy(request->sg_list, request->sg_count, &scsiData, sizeof(scsiData)) < B_OK) { @@ -960,6 +961,31 @@ AHCIPort::ScsiExecuteRequest(scsi_ccb *request) } break; } + case SCSI_OP_WRITE_SAME_16: + { + scsi_cmd_wsame_16 *cmd = (scsi_cmd_wsame_16 *)request->cdb; + + // SCSI unmap is used for trim, otherwise we don't support it + if (!cmd->unmap) { + TRACE("%s port %d: unsupported request opcode 0x%02x\n", + __func__, fIndex, request->cdb[0]); + request->subsys_status = SCSI_REQ_ABORTED; + gSCSI->finished(request, 1); + break; + } + + if (!fTrim) { + // Drive doesn't support trim (or atapi) + // Just say it was successful and quit + request->subsys_status = SCSI_REQ_CMP; + } else { + TRACE("%s unimplemented: TRIM call\n", __func__); + // TODO: Make Serial ATA (sata_request?) trim call here. + request->subsys_status = SCSI_REQ_ABORTED; + } + gSCSI->finished(request, 1); + break; + } default: TRACE("AHCIPort::ScsiExecuteRequest port %d unsupported request " "opcode 0x%02x\n", fIndex, request->cdb[0]); diff --git a/src/add-ons/kernel/busses/scsi/ahci/ahci_port.h b/src/add-ons/kernel/busses/scsi/ahci/ahci_port.h index 97814584e7..42b8e6bd00 100644 --- a/src/add-ons/kernel/busses/scsi/ahci/ahci_port.h +++ b/src/add-ons/kernel/busses/scsi/ahci/ahci_port.h @@ -70,6 +70,7 @@ private: bool fTestUnitReadyActive; bool fResetPort; bool fError; + bool fTrim; volatile fis * fFIS; volatile command_list_entry * fCommandList; From 30e7dbeb72799820bec7143fff2da0e16ab3986b Mon Sep 17 00:00:00 2001 From: Ryan Leavengood Date: Sun, 10 Jun 2012 23:09:31 -0400 Subject: [PATCH 62/62] Save and load scrollbar settings in app_server. Added to the appearance settings since menu info was already there. --- src/servers/app/DesktopSettings.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/servers/app/DesktopSettings.cpp b/src/servers/app/DesktopSettings.cpp index f12b1484f8..c983c69ad0 100644 --- a/src/servers/app/DesktopSettings.cpp +++ b/src/servers/app/DesktopSettings.cpp @@ -225,6 +225,7 @@ DesktopSettingsPrivate::_Load() BMessage settings; status = settings.Unflatten(&file); if (status == B_OK) { + // menus float fontSize; if (settings.FindFloat("font size", &fontSize) == B_OK) fMenuInfo.font_size = fontSize; @@ -255,6 +256,24 @@ DesktopSettingsPrivate::_Load() fMenuInfo.triggers_always_shown = triggersAlwaysShown; } + // scrollbars + bool proportional; + if (settings.FindBool("proportional", &proportional) == B_OK) + fScrollBarInfo.proportional = proportional; + + bool doubleArrows; + if (settings.FindBool("double arrows", &doubleArrows) == B_OK) + fScrollBarInfo.double_arrows = doubleArrows; + + int32 knob; + if (settings.FindInt32("knob", &knob) == B_OK) + fScrollBarInfo.knob = knob; + + int32 minKnobSize; + if (settings.FindInt32("min knob size", &minKnobSize) == B_OK) + fScrollBarInfo.min_knob_size = minKnobSize; + + // subpixel font rendering bool subpix; if (settings.FindBool("subpixel antialiasing", &subpix) == B_OK) gSubpixelAntialiasing = subpix; @@ -271,6 +290,7 @@ DesktopSettingsPrivate::_Load() gSubpixelOrderingRGB = subpixelOrdering; } + // colors for (int32 i = 0; i < kNumColors; i++) { char colorName[12]; snprintf(colorName, sizeof(colorName), "color%ld", @@ -407,6 +427,11 @@ DesktopSettingsPrivate::Save(uint32 mask) settings.AddBool("triggers always shown", fMenuInfo.triggers_always_shown); + settings.AddBool("proportional", fScrollBarInfo.proportional); + settings.AddBool("double arrows", fScrollBarInfo.double_arrows); + settings.AddInt32("knob", fScrollBarInfo.knob); + settings.AddInt32("min knob size", fScrollBarInfo.min_knob_size); + settings.AddBool("subpixel antialiasing", gSubpixelAntialiasing); settings.AddInt8("subpixel average weight", gSubpixelAverageWeight); settings.AddBool("subpixel ordering", gSubpixelOrderingRGB);