Merge branch 'master' into x86_64

This commit is contained in:
Alex Smith
2012-06-11 12:01:35 +01:00
80 changed files with 4036 additions and 556 deletions
+8 -8
View File
@@ -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
+1 -1
View File
@@ -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
+3 -1
View File
@@ -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
+2 -2
View File
@@ -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 {
+2 -2
View File
@@ -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 ;
}
+10 -6
View File
@@ -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 ;
+1 -1
View File
@@ -175,7 +175,7 @@ function PostFirmwareInstallation()
function InstallIpw2100()
{
driver='ipw2100'
driver='iprowifi2100'
PreFirmwareInstallation
# Extract contents.
+58 -31
View File
@@ -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,
+23
View File
@@ -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 {
@@ -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 <Accelerant.h>
#include <GraphicsDefs.h>
#include <Drivers.h>
#include <edid.h>
// 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
+1 -3
View File
@@ -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
@@ -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,
@@ -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
+44 -7
View File
@@ -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:
+1
View File
@@ -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 ;
+19
View File
@@ -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
;
@@ -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 <errno.h>
#include <string.h>
#include <unistd.h>
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;
}
@@ -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
@@ -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;
}
@@ -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
}
@@ -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;
}
@@ -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);
}
@@ -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 <create_display_modes.h> // common accelerant header file
#include <math.h>
#include <unistd.h>
// 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;
}
}
@@ -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__
@@ -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;
}
+333
View File
@@ -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 <create_display_modes.h> // common accelerant header file
#include <string.h>
#include <unistd.h>
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__
+3 -5
View File
@@ -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
@@ -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();
}
@@ -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;
@@ -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]);
@@ -70,6 +70,7 @@ private:
bool fTestUnitReadyActive;
bool fResetPort;
bool fError;
bool fTrim;
volatile fis * fFIS;
volatile command_list_entry * fCommandList;
+359 -101
View File
@@ -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();
}
}
+22 -7
View File
@@ -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;
@@ -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 {
@@ -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 ;
@@ -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
;
@@ -0,0 +1,670 @@
/*
* Copyright 2007-2012 Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT license.
*
* Authors:
* Gerald Zajac
*/
#include <AGP.h>
#include <KernelExport.h>
#include <PCI.h>
#include <malloc.h>
#include <stdio.h>
#include <string.h>
#include <graphic_driver.h>
#include <boot_item.h>
#include <arch/x86/vm86.h>
#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;
}
@@ -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;
@@ -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);
+19 -9
View File
@@ -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");
@@ -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<SourceCode> sourceCodeReference(sourceCode);
locker.Unlock();
@@ -132,6 +132,7 @@ private:
void _SetActiveSourceCode(SourceCode* sourceCode);
void _UpdateCpuState();
void _UpdateRunButtons();
void _UpdateSourcePathState();
void _ScrollToActiveFunction();
void _HandleThreadStateChanged(thread_id threadID);
+6 -15
View File
@@ -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);
+5 -4
View File
@@ -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 <stdlib.h>
@@ -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();
}
+12 -4
View File
@@ -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!");
+37 -1
View File
@@ -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)
{
+43 -33
View File
@@ -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;
};
+123 -41
View File
@@ -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 <String.h>
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 << "<td width=\"" << divider << "\" ";
text << "class=\"sudoku sudoku_empty " << style;
text << "\">\n&nbsp;";
} else if (fField->FlagsAt(x, y) & kInitialValue) {
} else if (fField->IsInitialValue(x, y)) {
text << "<td width=\"" << divider << "\" ";
text << "class=\"sudoku sudoku_initial " << style
<< "\">\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];
+96 -73
View File
@@ -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 <View.h>
#include <ObjectList.h>
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<BMessage>& undos, BObjectList<BMessage>& 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<BMessage>& undos,
BObjectList<BMessage>& redos);
void _PushUndo();
rgb_color fBackgroundColor;
SudokuField* fField;
BObjectList<BMessage> fUndos;
BObjectList<BMessage> 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<BMessage> fUndos;
BObjectList<BMessage> 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
+58 -55
View File
@@ -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<BPopUpMenu *>(archivable);
fPopUp = dynamic_cast<BPopUpMenu*>(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<BDragger *>(this)->_BuildDefaultPopUp();
const_cast<BDragger*>(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);
+1 -1
View File
@@ -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 {
+6 -1
View File
@@ -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;
+7 -2
View File
@@ -84,7 +84,7 @@ OpenWithContainerWindow::OpenWithContainerWindow(BMessage *entriesToOpen,
{
AutoLock<BWindow> 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());
}
+1 -1
View File
@@ -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[] =
+12 -2
View File
@@ -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();
+61 -4
View File
@@ -5,19 +5,76 @@
* Authors:
* DarkWyrm (darkwyrm@earthlink.net)
* Rene Gollent (rene@gollent.com)
* Ryan Leavengood <leavengood@gmail.com>
*/
#include "ColorWhichItem.h"
#include <stdio.h>
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;
}
+10 -3
View File
@@ -5,22 +5,29 @@
* Authors:
* DarkWyrm <bpmagic@columbus.rr.com>
* Rene Gollent (rene@gollent.com)
* Ryan Leavengood <leavengood@gmail.com>
*/
#ifndef COLORWHICH_ITEM_H
#define COLORWHICH_ITEM_H
#include <InterfaceDefs.h>
#include <ListItem.h>
#include <View.h>
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
+2
View File
@@ -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;
}
+26 -1
View File
@@ -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);
+24 -10
View File
@@ -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);
@@ -1490,17 +1490,21 @@ DefaultDecorator::GetComponentColors(Component component, uint8 highlight,
DefaultDecorator::Tab* tab = static_cast<DefaultDecorator::Tab*>(_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;
@@ -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;
}
@@ -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__);
}
@@ -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);
@@ -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
@@ -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();
@@ -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
;
@@ -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 <OS.h>
#include <boot/platform.h>
#include <boot/stdio.h>
#include <boot/kernel_args.h>
#include <boot/stage2.h>
#include <arch/cpu.h>
#include <arch_kernel.h>
#include <arch_system_info.h>
#include <string.h>
//#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<microseconds;i=i+1)
{
/*
asm volatile ("mov r0,r0");
asm volatile ("mov r0,r0");
*/
}
#warning U-Boot:ARM:TODO!!
}
extern "C" status_t
boot_arch_cpu_init(void)
{
status_t err = check_cpu_features();
if (err != B_OK) {
panic("You need a Pentium or higher in order to boot!\n");
return err;
}
calculate_cpu_conversion_factor();
gKernelArgs.num_cpus = 1;
// this will eventually be corrected later on
return B_OK;
}
@@ -86,4 +86,7 @@ SYMBOL(gUBootOS):
// .byte 0
.long 0
SYMBOL_END(gUBootOS)
SYMBOL(gFDT):
.long 0
SYMBOL_END(gFDT)
@@ -13,9 +13,9 @@ BootMergeObject boot_platform_u-boot_ppc.o :
shell.S
#arch_mmu.cpp
#arch_cpu_asm.S
arch_cpu_asm.S
arch_start_kernel.S
#cpu.cpp
arch_cpu.cpp
#mmu.cpp
: -fno-pic
;
@@ -0,0 +1,109 @@
/*
* 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 "board_config.h"
#include <OS.h>
#include <boot/platform.h>
#include <boot/stdio.h>
#include <boot/kernel_args.h>
#include <boot/stage2.h>
#include <arch/cpu.h>
#include <arch/ppc/arch_cpu.h>
#include <arch_kernel.h>
#include <arch_system_info.h>
#include <string.h>
//#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;i<microseconds;i=i+1)
{
/*
asm volatile ("mov r0,r0");
asm volatile ("mov r0,r0");
*/
}
#warning U-Boot:PPC:TODO!!
}
extern "C" status_t
boot_arch_cpu_init(void)
{
status_t err = check_cpu_features();
if (err != B_OK) {
panic("You need a Pentium or higher in order to boot!\n");
return err;
}
calculate_cpu_conversion_factor();
gKernelArgs.num_cpus = 1;
// this will eventually be corrected later on
return B_OK;
}
@@ -59,4 +59,7 @@ SYMBOL(gUBootOS):
// .byte 0
.long 0
SYMBOL_END(gUBootOS)
SYMBOL(gFDT):
.long 0
SYMBOL_END(gFDT)
+9 -27
View File
@@ -28,31 +28,13 @@
# 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
spin(bigtime_t microseconds)
{
#warning U-Boot:TODO!!
// TODO: use API if available
for(bigtime_t i=0;i<microseconds;i=i+1)
{
/*
@@ -60,19 +42,19 @@ spin(bigtime_t microseconds)
asm volatile ("mov r0,r0");
*/
}
#warning U-Boot:TODO!!
// fallback to arch-specific code
//arch_spin(microseconds);
}
extern "C" void
cpu_init()
{
if (check_cpu_features() != B_OK)
panic("You need a Pentium or higher in order to boot!\n");
calculate_cpu_conversion_factor();
gKernelArgs.num_cpus = 1;
// this will eventually be corrected later on
if (boot_arch_cpu_init() != B_OK)
panic("You need a 6502 or higher in order to boot!\n");
}
+2
View File
@@ -13,6 +13,8 @@
extern "C" {
#endif
extern void arch_spin(bigtime_t microseconds);
extern status_t boot_arch_cpu_init(void);
extern void cpu_init(void);
#ifdef __cplusplus
+1 -1
View File
@@ -205,7 +205,7 @@ void
mmu_set_TTBR(uint32 ttb)
{
ttb &= 0xffffc000;
asm volatile("MRC p15, 0, %[adr], c2, c0, 0"::[adr] "r" (ttb));
asm volatile("MCR p15, 0, %[adr], c2, c0, 0"::[adr] "r" (ttb));
}
+3 -3
View File
@@ -52,11 +52,11 @@ extern "C" int start_raw(int argc, const char **argv);
extern "C" void dump_uimage(struct image_header *image);
// declared in shell.S
// those are initialized to NULL but not in the BSS
extern struct image_header *gUImage;
extern uboot_gd *gUBootGlobalData;
extern uint32 gUBootOS;
void * gFDT = NULL;
extern void *gFDT;
static uint32 sBootOptions;
@@ -184,7 +184,7 @@ start_raw(int argc, const char **argv)
dprintf("argc = %d\n", argc);
for (i = 0; i < argc; i++)
dprintf("argv[%d] @%lx = '%s'\n", i, (uint32)argv[i], argv[i]);
dprintf("os: %d\n", gUBootOS);
dprintf("os: %d\n", (int)gUBootOS);
dprintf("gd @ %p\n", gUBootGlobalData);
dprintf("gd->bd @ %p\n", gUBootGlobalData->bd);
//dprintf("fb_base %p\n", (void*)gUBootGlobalData->fb_base);
+29 -3
View File
@@ -5,15 +5,41 @@
#include <debug.h>
#include <arch/generic/debug_uart_8250.h>
#include <arch/ppc/arch_cpu.h>
#include <new>
// 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;
}
@@ -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.
}
}
@@ -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 = .;
+111
View File
@@ -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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#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 <AMD|INTEL> <cpuid_hex>\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;
}