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 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 diff --git a/build/jam/HaikuImage b/build/jam/HaikuImage index 2b75b2e144..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 @@ -181,7 +183,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/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 { 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 ; } diff --git a/build/jam/board/sam460ex/BoardSetup b/build/jam/board/sam460ex/BoardSetup index 45b1c9372c..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 ; @@ -28,8 +30,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 ; 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. 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/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 { diff --git a/headers/private/graphics/intel_810/DriverInterface.h b/headers/private/graphics/intel_810/DriverInterface.h new file mode 100644 index 0000000000..1bae923655 --- /dev/null +++ b/headers/private/graphics/intel_810/DriverInterface.h @@ -0,0 +1,108 @@ +/* + * 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 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 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 + 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; // serializing access to the acceleration engine +}; + + +#endif // DRIVERINTERFACE_H 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/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, 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 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/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..0d4b4959f2 --- /dev/null +++ b/src/add-ons/accelerants/intel_810/accelerant.cpp @@ -0,0 +1,235 @@ +/* + * 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..bee07d1c02 --- /dev/null +++ b/src/add-ons/accelerants/intel_810/accelerant.h @@ -0,0 +1,113 @@ +/* + * 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..df2735a6af --- /dev/null +++ b/src/add-ons/accelerants/intel_810/engine.cpp @@ -0,0 +1,82 @@ +/* + * 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..3bd4481301 --- /dev/null +++ b/src/add-ons/accelerants/intel_810/hooks.cpp @@ -0,0 +1,86 @@ +/* + * 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..71c2714fc4 --- /dev/null +++ b/src/add-ons/accelerants/intel_810/i810_init.cpp @@ -0,0 +1,69 @@ +/* + * 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..a09fcb871f --- /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..7668ffd531 --- /dev/null +++ b/src/add-ons/accelerants/intel_810/i810_regs.h @@ -0,0 +1,173 @@ +/* + * 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..cfd3399621 --- /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..f56ad1f1cb --- /dev/null +++ b/src/add-ons/accelerants/intel_810/mode.cpp @@ -0,0 +1,333 @@ +/* + * 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; // 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/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 diff --git a/src/add-ons/input_server/devices/keyboard/TeamMonitorWindow.cpp b/src/add-ons/input_server/devices/keyboard/TeamMonitorWindow.cpp index 03ddd51ec7..80984041ea 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 @@ -412,6 +416,8 @@ TeamMonitorWindow::UpdateList() } fRestartButton->SetEnabled(!desktopRunning); + + fListView->MakeFocus(); } 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; 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..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, @@ -640,7 +642,8 @@ 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", fTrim ? "yes" : "no"); if (sg_memcpy(request->sg_list, request->sg_count, &scsiData, sizeof(scsiData)) < B_OK) { @@ -958,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; 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 { 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..eddd81d017 --- /dev/null +++ b/src/add-ons/kernel/drivers/graphics/intel_810/driver.cpp @@ -0,0 +1,670 @@ +/* + * 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; // how many times device has been opened + int32 flags; + 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 + 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; +} 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; 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/debugger/dwarf/DwarfFile.cpp b/src/apps/debugger/dwarf/DwarfFile.cpp index 647edbb393..49b5a9c6da 100644 --- a/src/apps/debugger/dwarf/DwarfFile.cpp +++ b/src/apps/debugger/dwarf/DwarfFile.cpp @@ -350,16 +350,26 @@ 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 && 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; } + + 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"); 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..bb8ca25c42 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,38 @@ 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); + fSourcePathView->SetText(truncatedText); + } else + fSourcePathView->SetText(sourceText); +} + + void TeamWindow::_ScrollToActiveFunction() { @@ -1183,34 +1216,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); 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); diff --git a/src/apps/deskcalc/CalcView.cpp b/src/apps/deskcalc/CalcView.cpp index 625034e748..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, @@ -693,7 +694,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(); } diff --git a/src/apps/installer/InstallerApp.cpp b/src/apps/installer/InstallerApp.cpp index 1627714162..431ea2507a 100644 --- a/src/apps/installer/InstallerApp.cpp +++ b/src/apps/installer/InstallerApp.cpp @@ -129,7 +129,15 @@ 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, " + "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!"); diff --git a/src/apps/sudoku/SudokuField.cpp b/src/apps/sudoku/SudokuField.cpp index 62a3ddcd54..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. */ @@ -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) { @@ -265,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) { @@ -279,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) { @@ -293,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 bd270e30bb..ace2647818 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,46 @@ 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; + bool IsValueCompleted(uint32 value) 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; + bool HasHint(uint32 x, uint32 y, uint32 value) 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; + bool IsValid(uint32 x, uint32 y, uint32 value) 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; + bool IsInitialValue(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 +68,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; }; diff --git a/src/apps/sudoku/SudokuView.cpp b/src/apps/sudoku/SudokuView.cpp index b34b1ce6bf..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,22 +866,36 @@ 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); + fField->SetValueAt(x, y, 0); fShowHintX = x; fShowHintY = y; } else { + // Set value + 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); + if (value + 1 != fValueHintValue) + _SetValueHintValue(~0UL); - // allow dragging to remove the hint from other fields - fLastHintValueSet = false; - fLastHintValue = value; - fLastField = field; + if (wasCompleted != fField->IsValueCompleted(value + 1)) + _InvalidateValue(value + 1, false, x, y); + else + _InvalidateField(x, y); } return; } @@ -843,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; @@ -870,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; @@ -910,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(); @@ -1135,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; @@ -1161,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, @@ -1184,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(), @@ -1200,36 +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) { - //SetLowColor(tint_color(ViewColor(), B_DARKEN_1_TINT)); - SetLowColor(255, 255, 210); + && !fField->IsInitialValue(x, y)) { + // TODO: make color more intense + 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) + if (fField->IsInitialValue(x, y)) SetHighColor(0, 0, 0); else { if ((fHintFlags & kMarkInvalid) == 0 - || fField->ValidMaskAt(x, y) & (1UL << (value - 1))) - SetHighColor(0, 0, 200); - else - SetHighColor(200, 0, 0); + || fField->IsValid(x, y, value)) { + if (fField->IsValueCompleted(value)) + SetHighColor(kValueCompletedColor); + else + SetHighColor(kValueColor); + } else + SetHighColor(kInvalidValueColor); } char text[2]; diff --git a/src/apps/sudoku/SudokuView.h b/src/apps/sudoku/SudokuView.h index 03fd8e7317..59532fbee6 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,120 @@ 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 _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); + 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 fValueHintValue; + 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 +149,5 @@ static const uint32 kMsgSolveSingle = 'slsg'; // you can observe these: static const int32 kUndoRedoChanged = 'unre'; + #endif // SUDOKU_VIEW_H 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); 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[] = 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 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; } diff --git a/src/servers/app/DesktopSettings.cpp b/src/servers/app/DesktopSettings.cpp index d4378d3532..c983c69ad0 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; @@ -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); diff --git a/src/servers/app/WorkspacesView.cpp b/src/servers/app/WorkspacesView.cpp index a475aad31a..578775d8ac 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.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); 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; diff --git a/src/system/boot/platform/raspberrypi_arm/console.cpp b/src/system/boot/platform/raspberrypi_arm/console.cpp index 5a12a31bf8..31cc7f286c 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); } @@ -206,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/mmu.cpp b/src/system/boot/platform/raspberrypi_arm/mmu.cpp index f01bacc40a..bf1d3d6c2f 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,9 +198,9 @@ 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)); + asm volatile("MCR 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/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 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(); diff --git a/src/system/boot/platform/u-boot/arch/arm/Jamfile b/src/system/boot/platform/u-boot/arch/arm/Jamfile index 2bf09c10e5..fdfbaa96c0 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 @@ BootMergeObject 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; + +#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; + 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;ibd @ %p\n", gUBootGlobalData->bd); //dprintf("fb_base %p\n", (void*)gUBootGlobalData->fb_base); 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; } 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. } } 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 = .; diff --git a/src/tools/cpuidtool.c b/src/tools/cpuidtool.c new file mode 100644 index 0000000000..570fd79be9 --- /dev/null +++ b/src/tools/cpuidtool.c @@ -0,0 +1,111 @@ +/* + * Copyright 2012 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexander von Gluck, kallisti5@unixzen.com + */ + +/* + * Pass a standard CPUID in hex, and get out a CPUID for OS.h + */ + + +#include +#include +#include + + +#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; + int xv; + int fact; + + if (szlen > 0) { + // Converting more than 32bit hexadecimal value? + 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; + + *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 != 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 = 0; + xtoi(argv[2], &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 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", cpuidHaiku); + + return 0; +}