sdhci(4)
driver, what is directly stated on the manual page (and later confirmed by reading the source code).
dmesg
and pciconf -lv
mailing lists and forums, pciconf -lv
trackers (for example, OpenBSD PR i386 / 5843), but no one has offered a solution. Moreover, having actually put an end to the question, Alexander Motin, the author of the sdhci(4)
driver, wrote on the forum in 2010 that the TI did not give documentation for the chip, which means that if the manufacturer configured the chip incorrectly, and setting it up via BIOS is not provided, do something difficult. In turn, Theo de Raadt closed down i386 / 5843 with the words: “We do what we can. This undoubted bit undocumented bits. We've strugged before to find this information, and failed. If you can find some documentation, we would be thrilled. "
sdhci(4)
or even to sport the whole driver. First of all, I looked at the list of supported PCI vendor / device ids in order to compare it with “our” driver. It turned out to be small:
$ cat linux/pci_ids.h #define PCI_VENDOR_ID_TI 0x104c #define PCI_DEVICE_ID_TI_XX21_XX11_FM 0x8033 #define PCI_DEVICE_ID_TI_XX12_FM 0x803b #define PCI_DEVICE_ID_TI_XX20_FM 0xac8f
pciconf -lv
on my laptop (chip = 0x8033 104c):
none3@pci0:6:7:3: class=0x018000 card=0x83191033 chip=0x8033104c rev=0x00 hdr=0x00 vendor = 'Texas Instruments (TI)' device = 'PCIxx11/21 Integrated FlashMedia Controller' class = mass storage
sdhci.c
(FreeBSD):
static const struct sdhci_device { uint32_t model; uint16_t subvendor; char *desc; u_int quirks; } sdhci_devices[] = { { 0x08221180, 0xffff, "RICOH R5C822 SD", SDHCI_QUIRK_FORCE_DMA }, { 0xe8221180, 0xffff, "RICOH SD", SDHCI_QUIRK_FORCE_DMA }, { 0xe8231180, 0xffff, "RICOH R5CE823 SD", SDHCI_QUIRK_LOWER_FREQUENCY }, { 0x8034104c, 0xffff, "TI XX21/XX11 SD", SDHCI_QUIRK_FORCE_DMA },
none1@pci0:6:7:0: class=0x060700 card=0x83191033 chip=0x8031104c rev=0x00 hdr=0x02 vendor = 'Texas Instruments (TI)' device = 'PCIxx21/x515 Cardbus Controller' class = bridge subclass = PCI-CardBus none2@pci0:6:7:2: class=0x0c0010 card=0x83191033 chip=0x8032104c rev=0x00 hdr=0x00 vendor = 'Texas Instruments (TI)' device = 'OHCI Compliant IEEE-1394 FireWire Controller' class = serial bus subclass = FireWire
pciconf(8)
utility tells us about the PCI configuration space “head” (zero) function of the chip, that is, in the terminology of FreeBSD, the pci0:6:7:0
selector. For the sake of brevity, I will not give a dump of all 256 bytes, and I will confine myself only to those of interest to us, at offset 86h:
# pciconf -rb pci0:6:7:0 0x86 d3
Debug
object that the operating system must “convey” to the user. In FreeBSD, the system variable debug.acpi.enable_debug_objects
is responsible for this, which must be set to one:
# sysctl debug.acpi.enable_debug_objects=1 debug.acpi.enable_debug_objects: 0 -> 1
Debug
, and the FreeBSD kernel will output them to the console. It remains to figure out how to get ACPI to issue information of interest to us on demand. To begin, let us sdampim and disassemble the DSDT of the laptop, and study it:
# acpidump -dt > s950.asl
Method (_Q0C, 0, NotSerialized) { If (\_SB.PCI0.PEGA) { \_SB.PCI0.PEGP.VGA.SWIH () } Else { Store (0x01, TLST) HKDS (0x0A) } }
\_SB.PCI0.PEGP.VGA.SWIH
method called, and its name hints that this is some kind of display switching. On the keyboard of many laptops, one of the function keys in combination with the Fn-modifier switches the video output from the internal display to the external one. On my "versa" this is F3. Let's try to modify the method code as follows:
Method (_Q0C, 0, NotSerialized) { + Store ("Fn-F3 pressed", Debug) If (\_SB.PCI0.PEGA) {
# iasl s950-patched.asl Intel ACPI Component Architecture ASL Optimizing Compiler version 20101013-32 Copyright (c) 2000 - 2010 Intel Corporation ASL Input: s950-patched.asl - 7749 lines, 280987 bytes, 2840 keywords AML Output: /tmp/acpidump.aml - 24863 bytes, 640 named objects, 2200 executable opcodes Compilation complete. 0 Errors, 0 Warnings, 0 Remarks, 958 Optimizations # cp /tmp/acpidump.aml /root/s950-patched.aml
/boot/loader.conf
add /boot/loader.conf
following lines to / boot / /boot/loader.conf
:
acpi_dsdt_load="YES" acpi_dsdt_name="/root/s950-patched.aml"
OperationRegion (PCIC, PCI_Config, 0x00, 256) Field (PCIC, AnyAcc, NoLock, Preserve) { Offset (0x86), // General Control Register 86h TLA, 2, // Top level arbitration SCSP, 1, // SmartCard socket power OHCI, 1, // Disable OHCI 1394 controller function SKTB, 1, // Disable CardBus socket B FM, 1, // Disable FlashMedia function SD, 1, // Disable SD host controller function SC, 1, // Disable SmartCard function }
OperationRegion
, but only the one that interests us, and not to allocate individual bits in the configuration register:
OperationRegion (PCIC, PCI_Config, 0x86, 0x01) Field (PCIC, AnyAcc, NoLock, Preserve) { GCR0, 8, // General Control Register (Byte 0) }
Device
keyword (paragraph 19.5.30, p. 735); the aggregate of all devices is a sort of tree. So, all PCI devices are most often inside the \_SB.PCI0
device space, which corresponds to the root PCI bus (usually there is one such bus, but theoretically they can be up to 256 in one PCI domain).
pciconf -lv
?) Function = 0, device = 7, bus = 6. That is, the device, apparently, should look something like this:
Device (XX11) { Name (_ADR, 0x00070000) // pci0:6:7:0 }
dmesg
):
$ dmesg | grep pci6 pci6: <ACPI PCI bus> on pcib4 pci6: <bridge, PCI-CardBus> at device 7.0 (no driver attached) pci6: <serial bus, FireWire> at device 7.2 (no driver attached) pci6: <mass storage> at device 7.3 (no driver attached) pci6: <network> at device 8.0 (no driver attached) $ dmesg | grep pcib4 pcib4: <ACPI PCI-PCI bridge> at device 30.0 on pci0 pci6: <ACPI PCI bus> on pcib4
pci6
is an additional, “virtual” bus on a PCI-PCI bridge. She got number 6 (as well as 4 for the bridge) because FreeBSD distributed the devices that way. Inside the DSDT, of course, there are no six tires and four bridges. Bridge - Device (PCIB)
- there is exactly one, as expected. Fully our description should look like this (I give a short version, without decomposing the register into separate bits):
Scope (\_SB.PCI0.PCIB) { Device (XX11) { Name (_ADR, 0x00070000) // pci0:6:7:0 OperationRegion (PCIC, PCI_Config, 0x86, 0x01) Field (PCIC, AnyAcc, NoLock, Preserve) { GCR0, 8, } } }
_Q0C
method _Q0C
something more meaningful:
Method (_Q0C, 0, NotSerialized) { + Store (Concatenate("GCR0 = 0x", \_SB.PCI0.PCIB.XX11.GCR0), Debug) If (\_SB.PCI0.PEGA) {
pciconf(8)
:
_INI
(Section 6.5.1, p. 349). Let's add the following code to our device:
Method (_INI) { Store (0xB3, GCR0) /* : Store (0x01, FM) Store (0x00, SD) */ }
/root/s950-patched.aml
, reboot again. We look at
pciconf -lv
, but 0x803 4 104c (SD Host) appeared. Load the necessary kernel modules, insert the card and try to mount it:
# kldload sdhci mmc mmcsd # ls /dev/mmcsd0* /dev/mmcsd0 /dev/mmcsd0s1 # mount -t msdosfs /dev/mmcsd0s1 /mnt/tmp # ls /mnt/tmp/DCIM/100CANON IMG_0403.JPG IMG_0424.JPG IMG_0450.JPG IMG_0494.JPG IMG_0515.JPG IMG_0406.JPG IMG_0425.JPG IMG_0451.JPG IMG_0498.JPG IMG_0517.JPG IMG_0407.JPG IMG_0427.JPG IMG_0452.JPG IMG_0499.JPG IMG_0518.JPG IMG_0409.JPG IMG_0429.JPG IMG_0453.JPG IMG_0500.JPG IMG_0520.JPG IMG_0410.JPG IMG_0430.JPG IMG_0467.JPG IMG_0501.JPG IMG_0522.JPG IMG_0412.JPG IMG_0439.JPG IMG_0473.JPG IMG_0506.JPG IMG_0525.JPG IMG_0413.JPG IMG_0440.JPG IMG_0474.JPG IMG_0507.JPG IMG_0526.JPG IMG_0414.JPG IMG_0445.JPG IMG_0475.JPG IMG_0508.JPG IMG_0534.JPG IMG_0415.JPG IMG_0447.JPG IMG_0478.JPG IMG_0510.JPG IMG_0535.JPG IMG_0421.JPG IMG_0448.JPG IMG_0492.JPG IMG_0512.JPG IMG_0537.JPG IMG_0423.JPG IMG_0449.JPG IMG_0493.JPG IMG_0514.JPG IMG_0538.JPG # tar cf /dev/null /mnt/tmp/DCIM/100CANON ; echo $? tar: Removing leading '/' from member names 0
Source: https://habr.com/ru/post/150887/