Skip to content

Commit 1dce0b4

Browse files
authored
[MERGE] Adding possibility to use shared atomic counter for IOp ack & to access register through PCIe BAR0 (#10)
* [FEAT] adds ability to use shared atomic through mmap to send ack * [FEAT] update AMI driver to allow mmap of PF0 BAR0 from user application * [CHORE] ami driver is compatible with backend not using BAR0 registers or shared_atomic_cnt so moving to its version 3.1.1
1 parent e55d02d commit 1dce0b4

8 files changed

Lines changed: 88 additions & 23 deletions

File tree

sw/AMI/driver/amc_proxy.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
#include "ami_program.h" /* Need some #defines from here */
2020
#include "ami_iop_ack_proc.h"
2121

22-
extern wait_queue_head_t wait_iop_q;
2322
/*****************************************************************************/
2423
/* Defines */
2524
/*****************************************************************************/
@@ -854,14 +853,12 @@ static int complete_response_thread(void *data)
854853
PR_DBG("iopAck[%d] = 0x%x", i, iop_ack_table[i]);
855854
}
856855
atomic_add(iop_ack_table_size, iop_ack_cnt_atomic);
857-
PR_DBG("Add %d to iop_ack_cnt_atomic to %d", iop_ack_table_size, atomic_read(iop_ack_cnt_atomic));
858856

859857
// Acknowledge queue consumption
860858
ackq_tail += ackq_used_words;
861859
iowrite32(ackq_tail, amc_proxy_inst->amc_ctrl_ctxt->gcq_payload_base_virt_addr + AMC_IOPACK_ADDR_TAIL);
862-
// signaling ami_top that waiting reader can be woken
863-
wake_up(&wait_iop_q);
864860
kfree(iopAck);
861+
PR_INFO("added %d to iop_ack_cnt_atomic of device %d", iop_ack_table_size, cdev_num);
865862
}
866863

867864
/* Check if a stop has been requested */

sw/AMI/driver/ami.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#include <linux/printk.h>
1212

1313
/* Meta Information */
14-
#define MDL_VERSION "3.1.0-zama"
14+
#define MDL_VERSION "3.1.1-zama"
1515
#define MDL_DESCRIPTION "AVED Management Interface (AMI) is used to manage AVED-based devices through PCIe"
1616
#define MDL_AUTHOR "AMD, Inc."
1717
#define MDL_RELDATE "2023"

sw/AMI/driver/ami_cdev.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,45 @@ int dev_close(struct inode *inode, struct file *filp)
8686
return 0;
8787
}
8888

89+
int dev_mmap(struct file *filp, struct vm_area_struct *vma)
90+
{
91+
struct pf_dev_struct *pf_dev = NULL;
92+
93+
pf_dev = filp->private_data;
94+
95+
/* Check device data */
96+
if (!pf_dev) {
97+
PR_ERR("dev_mmap: unable to find card");
98+
return -ENODEV;
99+
}
100+
// 1. Get the physical address of BAR0 (stored in your pdev struct)
101+
unsigned long phys_addr = pci_resource_start(pf_dev->pci, 0);
102+
unsigned long size = vma->vm_end - vma->vm_start;
103+
unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
104+
105+
PR_INFO("mmap BAR0 phys_addr 0x%lx size 0x%lx on 0x%lx", phys_addr + offset, size, vma->vm_start);
106+
107+
// 2. Safety Check: Ensure user isn't asking for more than the BAR size
108+
unsigned long bar_len = pci_resource_len(pf_dev->pci, 0);
109+
if (offset + size > bar_len) {
110+
PR_ERR("dev_mmap failed because offset 0x%lx + size 0x%lx goes beyond bar size 0x%lx", offset, size, bar_len);
111+
return -EINVAL;
112+
}
113+
114+
// 3. Mark the memory as "uncached" (Crucial for hardware registers!)
115+
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
116+
117+
if (remap_pfn_range(vma,
118+
vma->vm_start, // User virtual address start
119+
(phys_addr + offset) >> PAGE_SHIFT, // Physical PFN (addr / 4096)
120+
size, // Size
121+
vma->vm_page_prot)) { // Protection flags
122+
return -EAGAIN;
123+
}
124+
125+
return 0;
126+
}
127+
89128
/*
90129
* This function will be called when we use IOCTL with command on the Device file
91130
*/

sw/AMI/driver/ami_cdev.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ struct drv_cdev_struct {
259259
/* Standard Linux callbacks */
260260
int dev_open(struct inode *inode, struct file *filp);
261261
int dev_close(struct inode *inode, struct file *filp);
262+
int dev_mmap(struct file *filp, struct vm_area_struct *vma);
262263
long dev_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
263264

264265
/**

sw/AMI/driver/ami_driver_version.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
#ifndef _AMI_DRIVER_VERSION_H_
66
#define _AMI_DRIVER_VERSION_H_
77

8-
#define GIT_TAG "3.0.0"
8+
#define GIT_TAG "3.1.1"
99
#define GIT_TAG_VER_MAJOR (3)
10-
#define GIT_TAG_VER_MINOR (0)
11-
#define GIT_TAG_VER_PATCH (0)
10+
#define GIT_TAG_VER_MINOR (1)
11+
#define GIT_TAG_VER_PATCH (1)
1212
#define GIT_TAG_VER_DEV_COMMITS (0)
1313

1414
#define GIT_HASH "0bab29e568f64a25f17425c0ffd1c0e89609b6d1"

sw/AMI/driver/ami_iop_ack_proc.c

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
#define PROC_FILENAME_MAXLENGTH 20
1111

1212
static ack_proc_file *ack_proc_file_list = NULL;
13-
/* Queue of processes who want data */
14-
DECLARE_WAIT_QUEUE_HEAD(wait_iop_q);
1513
/* Queue of processes who want our file */
1614
static DECLARE_WAIT_QUEUE_HEAD(waitq);
1715

@@ -154,9 +152,40 @@ static int ami_close(struct inode *inode, struct file *file)
154152
return 0; /* success */
155153
}
156154

155+
static int ami_mmap(struct file *file, struct vm_area_struct *vma) {
156+
unsigned long pfn;
157+
ack_proc_file *read_apf=NULL;
158+
159+
if (file == NULL) {
160+
PR_ERR("ami_mmap: file* %p is NULL", file);
161+
return -ENODEV;
162+
}
163+
164+
read_apf = find_ack_proc_file_by_file(file);
165+
if (read_apf == NULL) {
166+
PR_ERR("ami_mmap: Ack file corresponding to file* %p not found", file);
167+
return -EINVAL;
168+
}
169+
// Get Physical Frame Number (PFN) of our allocated page
170+
pfn = virt_to_phys(read_apf) >> PAGE_SHIFT;
171+
172+
if ((vma->vm_end - vma->vm_start) > PAGE_SIZE) {
173+
PR_ERR("ami_mmap: mmap request bigger than a page rejected");
174+
return -EINVAL;
175+
}
176+
// Map it to user space
177+
if (remap_pfn_range(vma, vma->vm_start, pfn,
178+
PAGE_SIZE, vma->vm_page_prot)) {
179+
return -EAGAIN;
180+
}
181+
182+
return 0;
183+
}
184+
157185
static const struct proc_ops file_ops_4_ami_proc_file = {
158186
.proc_read = ami_output, /* "read" from the file */
159187
.proc_write = NULL, /* "write" to the file */
188+
.proc_mmap = ami_mmap,
160189
.proc_open = ami_open, /* called when the /proc file is opened */
161190
.proc_release = ami_close, /* called when it's closed */
162191
.proc_lseek = noop_llseek, /* return file->f_pos */
@@ -178,7 +207,8 @@ int create_proc_file(unsigned dev_index)
178207
proc_set_size(ami_proc_file, 80);
179208
proc_set_user(ami_proc_file, GLOBAL_ROOT_UID, GLOBAL_ROOT_GID);
180209

181-
new_ack_proc_file = kzalloc(sizeof(struct ack_proc_file), GFP_KERNEL);
210+
unsigned long page_addr = get_zeroed_page(GFP_KERNEL);
211+
new_ack_proc_file = (ack_proc_file*) page_addr;
182212
new_ack_proc_file->minor_cdev_number = dev_index;
183213
new_ack_proc_file->ami_proc_file = ami_proc_file;
184214
atomic_set(&new_ack_proc_file->iop_ack_cnt_atomic, 0);
@@ -216,8 +246,12 @@ unsigned remove_ack_proc_file_by_cdevn(unsigned target_minor_cdev_number) {
216246
prev_apf->next = current_apf->next;
217247
}
218248

249+
if (current_apf->ami_proc_file) {
250+
proc_remove(current_apf->ami_proc_file);
251+
current_apf->ami_proc_file = NULL;
252+
}
219253
PR_INFO("Removed /proc node with minor_cdev_number: %u", current_apf->minor_cdev_number);
220-
kfree(current_apf);
254+
free_page((unsigned long)current_apf);
221255
return 0;
222256
}
223257

@@ -279,17 +313,10 @@ ack_proc_file* find_ack_proc_file_by_file(struct file *file) {
279313

280314
int delete_proc_file(unsigned dev_index)
281315
{
282-
char proc_filename[PROC_FILENAME_MAXLENGTH];
283-
284316
if (remove_ack_proc_file_by_cdevn(dev_index)) {
285317
// the proc file to delete has not been found
286318
return 1;
287319
}
288320

289-
snprintf(proc_filename,PROC_FILENAME_MAXLENGTH,"%s_%d",PROC_ENTRY_FILENAME, dev_index);
290-
291-
remove_proc_entry(proc_filename, NULL);
292-
PR_INFO("/proc/%s removed\n", proc_filename);
293-
294321
return 0;
295322
}

sw/AMI/driver/ami_iop_ack_proc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@
2020
#define MESSAGE_LENGTH 80
2121

2222
typedef struct ack_proc_file {
23+
atomic_t iop_ack_cnt_atomic;
2324
unsigned int minor_cdev_number;
2425
struct proc_dir_entry *ami_proc_file;
25-
atomic_t iop_ack_cnt_atomic;
2626
atomic_t in_use;
2727
struct ack_proc_file *next;
2828
} ack_proc_file;

sw/AMI/driver/ami_top.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,11 @@ void pcie_device_remove(struct pci_dev *dev);
7171
int register_driver_pcie(void);
7272

7373
static struct file_operations dev_fops = {
74-
.owner = THIS_MODULE,
75-
.open = dev_open,
76-
.release = dev_close,
74+
.owner = THIS_MODULE,
75+
.open = dev_open,
76+
.release = dev_close,
7777
.unlocked_ioctl = dev_unlocked_ioctl,
78+
.mmap = dev_mmap,
7879
};
7980

8081
int register_driver_kernel(void)

0 commit comments

Comments
 (0)