Update SDHCI and device driver docs
Change-Id: Ic64b501b7166dd718aaf12412833f912e23bc6bf Reviewed-on: https://review.haiku-os.org/c/967 Reviewed-by: waddlesplash <waddlesplash@gmail.com>
This commit is contained in:
parent
122efe3a12
commit
8b6f4cb290
@ -240,9 +240,16 @@ omitted.</p>
|
||||
the ISA bus. Since it doesn't know anything about its children, it does not
|
||||
publish any child nodes, instead, it will just specify the
|
||||
B_FIND_MULTIPLE_CHILDREN and B_FIND_CHILD_ON_DEMAND flags for its device node.
|
||||
Since there are no additional informations about this bus, the device manager
|
||||
Since there is no additional information about this bus, the device manager
|
||||
will assume a simple bus, and will try to find drivers on demand only.</p>
|
||||
|
||||
<h2>The generic bus</h2>
|
||||
|
||||
Some devices are not tied to a specific bus. This is the case for all drivers
|
||||
that do not relate to a physical device: /dev/null, /dev/zero, /dev/random,
|
||||
etc.
|
||||
|
||||
A "generic" bus has been added, and these drivers can attach to it.
|
||||
|
||||
<h2>6. Open Issues</h2>
|
||||
|
||||
@ -254,11 +261,6 @@ parts just haven't been written yet.
|
||||
|
||||
<h4>6.2. Unpublishing</h4>
|
||||
|
||||
<h4>6.3. listdev functionality</h4>
|
||||
|
||||
The "listdev" command has been removed from the image, and it is currently not
|
||||
functional anymore.
|
||||
|
||||
<h4>6.4. Versioning</h4>
|
||||
|
||||
<p>The way the device manager works, it makes versioning of modules (which are
|
||||
|
@ -1,24 +1,28 @@
|
||||
# SDHCI MMC Driver
|
||||
This driver project is a part of GSoC'18 and is aimed at providing support for PCI devices with class 8 and subclass 5 over x86 architecture. This document will make you familiar with the [code produced during GSoC](https://review.haiku-os.org/#/c/haiku/+/318/), loading and testing the driver(including hardware emulation), insight into the code and future tasks.
|
||||
|
||||
For detailed explanations about the project, you can refer the [weekly reports](https://www.haiku-os.org/blog/krish_iyer) and comment issues if any. For this project we have referred [SD Host Controller Spec Version 1.00](https://www.sdcard.org/downloads/pls/pdf/index.php?p=PartA2_SD_Host_Controller_Simplified_Specification_Ver1.00.jpg&f=PartA2_SD_Host_Controller_Simplified_Specification_Ver1.00.pdf&e=EN_A2100) and [Physical Layer Spec Version 1.10](https://www.sdcard.org/downloads/pls/pdf/index.php?p=Part1_Physical_Layer_Simplified_Specification_Ver1.10.jpg&f=Part1_Physical_Layer_Simplified_Specification_Ver1.10.pdf&e=EN_P1110).
|
||||
This driver project is a part of GSoC'18 and is aimed at providing support for
|
||||
PCI devices with class 8 and subclass 5 over x86 architecture. This document
|
||||
will make you familiar with the [code produced during GSoC](https://review.haiku-os.org/#/c/haiku/+/318/),
|
||||
loading and testing the driver(including hardware emulation), insight into the
|
||||
code and future tasks.
|
||||
|
||||
For detailed explanations about the project, you can refer the
|
||||
[weekly reports](https://www.haiku-os.org/blog/krish_iyer) and comment issues
|
||||
if any. For this project we have referred [SD Host Controller Spec Version 1.00](https://www.sdcard.org/downloads/pls/pdf/index.php?p=PartA2_SD_Host_Controller_Simplified_Specification_Ver1.00.jpg&f=PartA2_SD_Host_Controller_Simplified_Specification_Ver1.00.pdf&e=EN_A2100)
|
||||
and [Physical Layer Spec Version 1.10](https://www.sdcard.org/downloads/pls/pdf/index.php?p=Part1_Physical_Layer_Simplified_Specification_Ver1.10.jpg&f=Part1_Physical_Layer_Simplified_Specification_Ver1.10.pdf&e=EN_P1110).
|
||||
|
||||
## Loading and testing the driver
|
||||
### Emulating the hardware
|
||||
|
||||
We will emulate a SDHC device using qemu as all system may not have the device. These days systems provide transfer to SD/ MMC card over USB. The document will not instruct you on how to build haiku but you can refer the link to [compile and build the haiku images](https://www.haiku-os.org/guides/building/) or the [week #1 and #2](https://www.haiku-os.org/blog/krish_iyer/2018-05-06_gsoc_2018_sdhci_mmc_driver_week_1_and_2/) project report will also work. You can also cherry pick changes from another [ticket](https://review.haiku-os.org/#/c/haiku/+/448/)
|
||||
We will emulate a SDHC device using qemu as all system may not have the device.
|
||||
These days systems provide transfer to SD/ MMC card over USB. The document will
|
||||
not instruct you on how to build haiku but you can refer the link to
|
||||
[compile and build the haiku images](https://www.haiku-os.org/guides/building/)
|
||||
or the [week #1 and #2](https://www.haiku-os.org/blog/krish_iyer/2018-05-06_gsoc_2018_sdhci_mmc_driver_week_1_and_2/)
|
||||
project report will also work.
|
||||
|
||||
After building the image, we will emulate the hardware and host haiku on top of that.
|
||||
#### Installing Qemu
|
||||
apt-get install qemu
|
||||
#### Creating Virtual Harddrive
|
||||
qemu-img create haiku-vm.img 10G
|
||||
#### Booting OS in virtual drive
|
||||
Note: if you generated a raw image during build then creating virtual hard drive and booting the OS in hard drive is not required.
|
||||
|
||||
qemu-system-x86_64 -boot d -cdrom haiku/generated.x86_64/haiku-nightly-anyboot.iso -m 512 -hda haiku-vm.img
|
||||
#### Hosting Haiku on x86
|
||||
qemu-system-x86_64 haiku-vm.img
|
||||
#### Emulation
|
||||
For emulating a sdhci-pci device
|
||||
|
||||
@ -26,32 +30,11 @@ For emulating a sdhci-pci device
|
||||
qemu-system-x86_64 ~/haiku/generated.x86_64/haiku.image -hdd haiku_drive_2.img -device sdhci-pci -device sd-card,drive=mydrive -drive if=sd,index=0,file=sd.img,format=raw,id=mydrive -m 512M -enable-kvm
|
||||
|
||||
### Testing and loading the driver
|
||||
Note: This project's code has already been merged but currently disabled because it's not useful en user currently. In order to add binary to kernel and load it, we need to mention the package in build files.
|
||||
The code is merged but not part of the default build
|
||||
because it's not useful for end users currently. In order to add the drivers
|
||||
to the image and load them, we need to adjust some buildfiles.
|
||||
|
||||
##### :*build/jam/images/definitions/minimum*
|
||||
|
||||
In SYSTEM_ADD_ONS_BUS_MANAGERS and add following line under that.
|
||||
|
||||
mmc_bus
|
||||
##### :*haiku/build/jam/packages/Haiku*
|
||||
Under # modules add
|
||||
|
||||
AddFilesToPackage add-ons kernel busses mmc : sdhci_pci ;
|
||||
Under # boot module links
|
||||
|
||||
sdhci_pci
|
||||
Under # drivers add
|
||||
|
||||
AddNewDriversToPackage disk mmc : mmc_disk ;
|
||||
Above following code in the build files will include your module, in order to build with the kernel you need to execute
|
||||
|
||||
cd generated.x86_64
|
||||
jam -q update-image kernel sdhci_pci mmc_disk mmc_bus
|
||||
Now host haiku with sdhci-pci device, open the terminal and execute following commands:
|
||||
Note: Don't worry if you don't understand the log output of the commands.
|
||||
|
||||
cat /var/log/syslog | grep "sdhci_pci\|mmc_bus\|mmc_disk"
|
||||
If you are able to see some output of above-mentioned command then it means that you have successfully loaded the driver.
|
||||
The required changes are in [this changeset](https://review.haiku-os.org/c/haiku/+/448/8).
|
||||
|
||||
## Insight into the code and future tasks
|
||||
### Directory and files where all the code related to the project resides
|
||||
@ -76,34 +59,117 @@ If you are able to see some output of above-mentioned command then it means that
|
||||
* src/system/kernel/device_manager
|
||||
* device_manager.cpp
|
||||
### Insight into the code
|
||||
#### MMC Bus
|
||||
So there's some called PCI bus and it something which was developed in order to manage the load on the CPU and easy for the CPU to manage the devices. Now our controller, SDHC will be plugged to the PCI bus, also which has the control over card. Now the first job will be finding the controller form PCI bus from all the devices connected. Every device is a node which has certain info about the device. So we need to get the PCI bus node(parent node) and get the device and register another node which will be called a child node or MMC bus. So if suppose I have another driver which get data from MMC bus and register another node then in that case MMC bus will be a parent node and the node I will be registering with the information will be the child node.
|
||||
#### MMC Bus management overview
|
||||
|
||||
So **supports_device()** will do that job of finding the device of particular class and subclass. Now with **register_child_devices()** we will register the bus node and attach certain info like slot info etc. Now that we have a bus, we can read number of slots and map the register set for each one of them, these register will help us to operate the controller and drive the card. We mapped the register using MMUIO method where we take register address form physical memory and assign to virtual one. In order to do that we have declared structure(*struct registers*) with no zero padding so that mapping will be precise.
|
||||
The device tree for MMC support looks like this:
|
||||
|
||||
After we mapped the registers, resetting the register sets confirmed that register mapping is functional. We have then declared functions for setting up the clock, reset etc.
|
||||
* PCI bus manager
|
||||
* (other PCI devices)
|
||||
* SDHCI controller
|
||||
* SDHCI bus
|
||||
* MMC bus manager
|
||||
* MMC device
|
||||
* mmc\_disk device
|
||||
* MMC device
|
||||
* (other SDIO driver)
|
||||
* MMC bus manager (second MMC bus)
|
||||
* MMC device
|
||||
* mmc\_disk device
|
||||
|
||||
static void sdhci_register_dump(uint8_t, struct registers*);
|
||||
static void sdhci_reset(struct registers*);
|
||||
static void sdhci_set_clock(struct registers*, uint16_t);
|
||||
static void sdhci_set_power(struct registers*);
|
||||
static void sdhci_stop_clock(struct registers*);
|
||||
After this much we need to setup a interrupt handler which will call a function in the driver when something occurs
|
||||
At the first level, the PCI bus manager publishes a device node for each device
|
||||
found. One of them is our SDHCI controller, identified either by the PCI device
|
||||
class and subclass, or for not completely SDHCI compatible device, by the
|
||||
device and vendor IDs.
|
||||
|
||||
The SDHCI bus driver attaches to this device and publishes his own node. It
|
||||
then scans the device and publishes an MMC bus node for each slot (there may
|
||||
be multiple SD slots attached to a single PCI controller).
|
||||
|
||||
The MMC bus manager then attach to each of these slots, and send the appropriate
|
||||
commands for enumerating the SD cards (there may be multiple cards in a "slot"),
|
||||
and publishes a device node for each of them. Finally, the mmc\_disk driver can
|
||||
bind itself to one of these device nodes, and publish the corresponding disk
|
||||
node, which is also be made available in /dev/disk/mmc.
|
||||
|
||||
Currently the mmc bus does not publish anything in the devfs, but this could be
|
||||
added if sending raw SD/MMC commands to SD cards from userland is considered
|
||||
desirable.
|
||||
|
||||
#### SDHCI driver
|
||||
|
||||
The SDHCI driver is the lowest level of the MMC stack. It provides abstraction
|
||||
of the SDHCI device. Later on, different way to access an SD bus may be added,
|
||||
for example for ARM devices which decided to use a different register interface.
|
||||
|
||||
The entry point is as usual **supports\_device()**. This method is called only
|
||||
for devices which may be SDHCI controllers, thanks to filtering done in the
|
||||
device manager to probe only the relevant devices. The probing is done on-demand,
|
||||
currently when the system is enumerating /dev/disk in the devfs. Later on, when
|
||||
we have SDIO support, probing will also be triggered in other cases.
|
||||
|
||||
The function identifies the device by checking the class and subclass, as well
|
||||
as a limited set of hardcoded PCI device and vendor IDs for devices that do not
|
||||
use the assigned subclass.
|
||||
|
||||
Once a compatible device is found, **register\_child\_devices()** is used to
|
||||
publish device nodes for each slot to be controlled by the mmc bus manager.
|
||||
The registers for each device are mapped into virtual memory, using the
|
||||
information from the PCI bar registers. **struct registers** is defined so that
|
||||
it matches the register layout, and provide a little abstraction to raw register
|
||||
access.
|
||||
|
||||
An SdhciBus object is created to manage each of these busses at the SDHCI level.
|
||||
It will be responsible for executing SD commands on that bus, and dealing with
|
||||
the resulting interrupts.
|
||||
|
||||
status_t sdhci_generic_interrupt(void*);
|
||||
#### The Bus Manager
|
||||
We need something to take up the job of certain tasks like data transfer and return back to driver when job is done. Class was a ideal tool for us because as soon as the job is done we no longer any of the data which stays with the variable, we have destructor for deleting the object.
|
||||
|
||||
It is not linked for time being but will be useful at the time of data transfer etc.
|
||||
The MMC bus manager manages the MMC bus (duh). Its tasks are:
|
||||
|
||||
* enumerating SD cards on the bus
|
||||
* assigning RCAs to the cards for identifying them when sending commands
|
||||
* setting the bus clock speed according to what the cards can handle
|
||||
* remember which SD card is currently active (CMD7)
|
||||
* manage cards state
|
||||
* publish device nodes for each card
|
||||
|
||||
#### Disk Driver
|
||||
So it's main job is to publish slots somewhere like /dev/mmc/.. So after disk gets published, we can mount the device and do transfer function on the memory device(SD/ MMC).
|
||||
|
||||
#### Hardcoding the driver
|
||||
In order to make the driver loadable and to tell the kernel that we really has built the support for a particular device, we need to mention the class and location of the driver module to the device_manager.
|
||||
The disk driver is attached to devices implementing SDSC or SDHC/SDXC commands.
|
||||
There will be other drivers for non-storage (SDIO) cards.
|
||||
|
||||
To help with this, the MMC bus manager provides the device with the information
|
||||
it gathered while initializing the device. According to the commands recognized
|
||||
by the card during the initialization sequence, it's possible to know if it's
|
||||
SDSC, SDHC/SDXC, or something else (SDIO, legacy MMC, etc).
|
||||
|
||||
The disk driver publishes devfs entries in /dev/disk/mmc and implements the
|
||||
usual interface for disk devices. From this point on, the device can be used
|
||||
just like any other mass storage device.
|
||||
|
||||
#### Getting everything loaded
|
||||
|
||||
The device manager is not completely implemented yet. As a result, some
|
||||
decisions about which drivers to load are hardcoded in device\_manager.cpp.
|
||||
|
||||
It has been adjusted to handover SDHCI devices to the MMC bus. Whenever a
|
||||
"disk" device is requested, the MMC busses are searched, which results in
|
||||
loading the SDHCI driver and probing for SD cards. When we get support for
|
||||
other types of SDIO devices, we will need to adjust the device manager to
|
||||
probe the SDHCI bus when these type of devices are requested, too.
|
||||
|
||||
|
||||
### Tasks to be completed
|
||||
We have to get the response from the card of commands which controller issues. We have tried a lot and looked into more deeper aspect but nothing worked, I am sure we have really missed something. The detailed report on responses and testing will found in last few weeks report.
|
||||
|
||||
Once we get the response from the card, we can complete the power sequence and so does other sequence which are mentioned in [third phase outline](https://www.haiku-os.org/blog/krish_iyer/2018-07-12_gsoc_2018_sdhci_mmc_driver_third_phase_plan/).
|
||||
The SDHCI driver is able to send and receive commands. However it does not
|
||||
handle card insertion and removal interrupts yet, so the card must be already
|
||||
inserted when the driver is loaded.
|
||||
|
||||
If you find it difficult to understand the driver development and it's functioning and role, please refer *docs/develop/kernel/device_manager_introduction.html*
|
||||
As a proof of concept, the initialization sequence has been implemented up
|
||||
until assigning an RCA to a single card (SDHC only).
|
||||
|
||||
Once we get everything in place at the mmc bus level, we can proceed as
|
||||
documented in the GSoC project [third phase outline](https://www.haiku-os.org/blog/krish_iyer/2018-07-12_gsoc_2018_sdhci_mmc_driver_third_phase_plan/).
|
||||
|
||||
If you find it difficult to understand the driver development and it's
|
||||
functioning and role, please refer *docs/develop/kernel/device_manager_introduction.html*
|
||||
|
Loading…
Reference in New Issue
Block a user