Merge branch 'master' into x86_64
This commit is contained in:
+8
-8
@@ -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
|
||||
|
||||
Vendored
+1
-1
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 ;
|
||||
}
|
||||
|
||||
@@ -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 ;
|
||||
|
||||
|
||||
@@ -175,7 +175,7 @@ function PostFirmwareInstallation()
|
||||
|
||||
function InstallIpw2100()
|
||||
{
|
||||
driver='ipw2100'
|
||||
driver='iprowifi2100'
|
||||
PreFirmwareInstallation
|
||||
|
||||
# Extract contents.
|
||||
|
||||
+58
-31
@@ -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,
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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 ;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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!");
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
@@ -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 ";
|
||||
} 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];
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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[] =
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 = .;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user