Доступ к указателям на память в аппаратных регистрах

Я работаю над улучшением стандартного драйвера ahci, предоставляемого в Linux, для выполнения некоторых необходимых задач. Я пытаюсь выдать команды AHCI HBA для обработки жесткого диска. Однако всякий раз, когда я это делаю, моя система блокируется и перезагружается. Попытка объяснить процесс выдачи команды на накопитель AHCI далека от этого вопроса. При необходимости, обратитесь к этой ссылке для полного обсуждения (процесс довольно определен во всем, потому что есть несколько частей, однако, у ch 4 есть необходимые структуры данных).

По сути, каждый записывает соответствующие структуры в области памяти, определенные либо BIOS, либо ОС. Первая область памяти, в которую я должен записать, - это базовый адрес списка команд, содержащийся в регистре PxCLB (и PxCLBU, если применяется 64-битная адресация). Моя система 64-битная, и поэтому я пытаюсь получить оба 32-битных регистра. Мой код по сути это:

void __iomem * pbase = ahci_port_base(ap);
u32 __iomem *temp = (u32*)(pbase + PORT_LST_ADDR);
struct ahci_cmd_hdr *cmd_hdr = NULL;

cmd_hdr = (struct ahci_cmd_hdr*)(u64)
    ((u64)(*(temp + PORT_LST_ADDR_HI)) << 32 | *temp);

pr_info("%s:%d cmd_list is %p\n", __func__, __LINE__, cmd_hdr);
// problems with this next line, makes the system reboot
//pr_info("%s:%d cl[0]:0x%08x\n", __func__, __LINE__, cmd_hdr->opts);

Функция ahci_port_base() находится в драйвере ahci (по крайней мере, для CentOS 6.x). По сути, он возвращает правильный адрес для этого порта в области памяти AHCI. PORT_LST_ADDR и PORT_LST_ADDR_HI - оба макроса, определенные в этом драйвере. Адрес, который я получаю после получения как старшего, так и младшего адресов, обычно выглядит как 0x0000000037900000. Этот адрес памяти находится в пространстве, которое я не могу просто разыменовать?

В данный момент я бью себя об стену, потому что эта ссылка показывает, что, по сути, так и происходит.

1 ответ

Решение

Адрес, который я получаю после получения как старшего, так и младшего адресов, обычно выглядит как 0x0000000037900000. Этот адрес памяти находится в пространстве, которое я не могу просто разыменовать?

Да, вы правы - это адрес шины, и вы не можете просто разыменовать его, потому что подкачка включена. (Вы не должны просто разыменовывать iomapped адреса - вы должны использовать readl() / writel() для тех, но поломка здесь более тонкая).

Похоже, правильный способ доступа к ahci_cmd_hdr в этом драйвере есть:

struct ahci_port_priv *pp = ap->private_data;
cmd_hdr = pp->cmd_slot;
Другие вопросы по тегам