Re: [PATCH v4 1/1] cxl/vendor: SK hynix Niagara Multi-Headed SLD Device

2023-09-20 Thread Gregory Price
On Wed, Sep 20, 2023 at 01:46:18PM +0100, Jonathan Cameron wrote:
> On Mon, 18 Sep 2023 13:36:56 -0400
> Gregory Price  wrote:
> 
> > Create a new device to emulate the SK hynix Niagara MHSLD platform.
> > 
> 
> Hi Gregory,
> 
> Seems this doesn't drop in directly on top of the rest of v3.
> The mhd_access_valid check has moved from being a class thing to
> an instance thing.
> 
> So for now I've reverted that bit in my local tree and will probably
> push out later.  Whilst here, some trivial formatting stuff inline
> that I was carrying.
> 
> Thanks,
> 
> Jonathan
> 

BAH! It seems i've edited an old version of the commit!

Disregard *facepalm*, I will send a new one today.

~Gregory



Re: [PATCH v4 1/1] cxl/vendor: SK hynix Niagara Multi-Headed SLD Device

2023-09-20 Thread Jonathan Cameron via
On Mon, 18 Sep 2023 13:36:56 -0400
Gregory Price  wrote:

> Create a new device to emulate the SK hynix Niagara MHSLD platform.
> 
> This device has custom CCI commands that allow for applying isolation
> to each memory block between hosts. This enables an early form of
> dynamic capacity, whereby the NUMA node maps the entire region, but
> the host is responsible for asking the device which memory blocks
> are allocated to it, and therefore may be onlined.
> 
> To instantiate:
> 
> -device 
> cxl-skh-niagara,cxl-type3,bus=rp0,volatile-memdev=mem0,id=cxl-mem0,sn=6,mhd-head=0,mhd-shmid=15
> 
> The linux kernel will require raw CXL commands enabled to allow for
> passing through of Niagara CXL commands via the CCI mailbox.
> 
> The Niagara MH-SLD has a shared memory region that must be initialized
> using the 'init_niagara' tool located in the vendor subdirectory
> 
> usage: init_niagara
> heads : number of heads on the device
> sections  : number of sections
> section_size  : size of a section in 128mb increments
> shmid : shmid produced by ipcmk
> 
> Example:
> $shmid1=ipcmk -M 131072
> ./init_niagara 4 32 1 $shmid1
> 
> Signed-off-by: Gregory Price 
> Signed-off-by: Junhee Ryu 
> Signed-off-by: Kwangjin Ko 

Hi Gregory,

Seems this doesn't drop in directly on top of the rest of v3.
The mhd_access_valid check has moved from being a class thing to
an instance thing.

So for now I've reverted that bit in my local tree and will probably
push out later.  Whilst here, some trivial formatting stuff inline
that I was carrying.

Thanks,

Jonathan

> diff --git a/hw/cxl/vendor/skhynix/skhynix_niagara.c 
> b/hw/cxl/vendor/skhynix/skhynix_niagara.c
> new file mode 100644
> index 00..88e53cc6cc
> --- /dev/null
> +++ b/hw/cxl/vendor/skhynix/skhynix_niagara.c

...

> +static void niagara_alloc_build_output(NiagaraAllocOutput *output,
> +   size_t *len_out,
> +   uint32_t *section_ids,
> +   uint32_t section_count)
> +{
> +uint32_t extents;
> +uint32_t previous;
> +uint32_t i;
> +
> +/* Build the output */
> +output->section_count = section_count;
> +extents = 0;
> +previous = 0;
> +for (i = 0; i < section_count; i++) {
> +if (i == 0) {
> +/* start the first extent */
> +output->extents[extents].start_section_id = section_ids[i];
> +output->extents[extents].section_count = 1;
> +extents++;
> +} else if (section_ids[i] == (previous + 1)) {
> +/* increment the current extent */
> +output->extents[extents - 1].section_count++;
> +} else {
> +/* start a new extent */
> +output->extents[extents].start_section_id = section_ids[i];
> +output->extents[extents].section_count = 1;
> +extents++;
> +}
> +previous = section_ids[i];
> +}
> +output->extent_count = extents;
> +*len_out = (8 + (16 * extents));

Too many brackets.

> +return;
> +}

...

> +static CXLRetCode cmd_niagara_get_section_map(const struct cxl_cmd *cmd,
> +  uint8_t *payload_in,
> +  size_t len_in,
> +  uint8_t *payload_out,
> +  size_t *len_out,
> +  CXLCCI *cci)
> +{
> +CXLNiagaraState *s = CXL_NIAGARA(cci->d);
> +NiagaraSharedState *nss = s->mhd_state;
> +NiagaraGetSectionMapInput *input = (void *)payload_in;
> +NiagaraGetSectionMapOutput *output = (void *)payload_out;
> +uint32_t *sections = >sections[0];
> +uint8_t query_type = input->query_type;
> +uint32_t i;
> +uint32_t bytes;
> +
> +if ((query_type != NIAGARA_GSM_QUERY_FREE) &&
> +(query_type != NIAGARA_GSM_QUERY_ALLOCATED)) {
> +return CXL_MBOX_INVALID_INPUT;
> +}
> +
> +output->ttl_section_count = nss->total_sections;
> +output->qry_section_count = 0;
> +bytes = (output->ttl_section_count / 8);
> +if (output->ttl_section_count % 8) {
> +bytes += 1;
> +}
> +
> +for (i = 0; i < bytes; i++) {
> +output->bitset[i] = 0x0;
> +}
> +
> +/* Iterate the the section list and check the bits */
> +for (i = 0; (i < nss->total_sections); i++) {
> +uint32_t section = sections[i];
> +
> +if (((query_type == NIAGARA_GSM_QUERY_FREE) && (!section)) ||
> +((query_type == NIAGARA_GSM_QUERY_ALLOCATED) &&
> + (section & (1 << s->mhd_head {
> +uint32_t byte = i / 8;
> +uint8_t bit = (1 << (i % 8));
Too many brackets

> +
> +output->bitset[byte] |= bit;
> +output->qry_section_count++;
> +}
> +}
> +
> +*len_out = (8 + 

[PATCH v4 1/1] cxl/vendor: SK hynix Niagara Multi-Headed SLD Device

2023-09-18 Thread Gregory Price
Create a new device to emulate the SK hynix Niagara MHSLD platform.

This device has custom CCI commands that allow for applying isolation
to each memory block between hosts. This enables an early form of
dynamic capacity, whereby the NUMA node maps the entire region, but
the host is responsible for asking the device which memory blocks
are allocated to it, and therefore may be onlined.

To instantiate:

-device 
cxl-skh-niagara,cxl-type3,bus=rp0,volatile-memdev=mem0,id=cxl-mem0,sn=6,mhd-head=0,mhd-shmid=15

The linux kernel will require raw CXL commands enabled to allow for
passing through of Niagara CXL commands via the CCI mailbox.

The Niagara MH-SLD has a shared memory region that must be initialized
using the 'init_niagara' tool located in the vendor subdirectory

usage: init_niagara
heads : number of heads on the device
sections  : number of sections
section_size  : size of a section in 128mb increments
shmid : shmid produced by ipcmk

Example:
$shmid1=ipcmk -M 131072
./init_niagara 4 32 1 $shmid1

Signed-off-by: Gregory Price 
Signed-off-by: Junhee Ryu 
Signed-off-by: Kwangjin Ko 
---
 hw/cxl/Kconfig  |   6 +
 hw/cxl/meson.build  |   2 +
 hw/cxl/vendor/Kconfig   |   1 +
 hw/cxl/vendor/meson.build   |   1 +
 hw/cxl/vendor/skhynix/.gitignore|   1 +
 hw/cxl/vendor/skhynix/Kconfig   |   4 +
 hw/cxl/vendor/skhynix/init_niagara.c|  99 +
 hw/cxl/vendor/skhynix/meson.build   |   3 +
 hw/cxl/vendor/skhynix/skhynix_niagara.c | 516 
 hw/cxl/vendor/skhynix/skhynix_niagara.h | 162 
 10 files changed, 795 insertions(+)
 create mode 100644 hw/cxl/vendor/Kconfig
 create mode 100644 hw/cxl/vendor/meson.build
 create mode 100644 hw/cxl/vendor/skhynix/.gitignore
 create mode 100644 hw/cxl/vendor/skhynix/Kconfig
 create mode 100644 hw/cxl/vendor/skhynix/init_niagara.c
 create mode 100644 hw/cxl/vendor/skhynix/meson.build
 create mode 100644 hw/cxl/vendor/skhynix/skhynix_niagara.c
 create mode 100644 hw/cxl/vendor/skhynix/skhynix_niagara.h

diff --git a/hw/cxl/Kconfig b/hw/cxl/Kconfig
index c9b2e46bac..88022008c7 100644
--- a/hw/cxl/Kconfig
+++ b/hw/cxl/Kconfig
@@ -1,6 +1,12 @@
+source vendor/Kconfig
+
 config CXL
 bool
 default y if PCI_EXPRESS
 
+config CXL_VENDOR
+bool
+default y
+
 config I2C_MCTP_CXL
 bool
diff --git a/hw/cxl/meson.build b/hw/cxl/meson.build
index 1393821fc4..e8c8c1355a 100644
--- a/hw/cxl/meson.build
+++ b/hw/cxl/meson.build
@@ -15,3 +15,5 @@ system_ss.add(when: 'CONFIG_CXL',
 system_ss.add(when: 'CONFIG_I2C_MCTP_CXL', if_true: files('i2c_mctp_cxl.c'))
 
 system_ss.add(when: 'CONFIG_ALL', if_true: files('cxl-host-stubs.c'))
+
+subdir('vendor')
diff --git a/hw/cxl/vendor/Kconfig b/hw/cxl/vendor/Kconfig
new file mode 100644
index 00..aa23bb051b
--- /dev/null
+++ b/hw/cxl/vendor/Kconfig
@@ -0,0 +1 @@
+source skhynix/Kconfig
diff --git a/hw/cxl/vendor/meson.build b/hw/cxl/vendor/meson.build
new file mode 100644
index 00..12db8991f1
--- /dev/null
+++ b/hw/cxl/vendor/meson.build
@@ -0,0 +1 @@
+subdir('skhynix')
diff --git a/hw/cxl/vendor/skhynix/.gitignore b/hw/cxl/vendor/skhynix/.gitignore
new file mode 100644
index 00..6d96de38ea
--- /dev/null
+++ b/hw/cxl/vendor/skhynix/.gitignore
@@ -0,0 +1 @@
+init_niagara
diff --git a/hw/cxl/vendor/skhynix/Kconfig b/hw/cxl/vendor/skhynix/Kconfig
new file mode 100644
index 00..382fa0cd6c
--- /dev/null
+++ b/hw/cxl/vendor/skhynix/Kconfig
@@ -0,0 +1,4 @@
+config CXL_SKHYNIX_NIAGARA
+bool
+depends on CXL_MEM_DEVICE
+default y if CXL_VENDOR
diff --git a/hw/cxl/vendor/skhynix/init_niagara.c 
b/hw/cxl/vendor/skhynix/init_niagara.c
new file mode 100644
index 00..2c189dc33c
--- /dev/null
+++ b/hw/cxl/vendor/skhynix/init_niagara.c
@@ -0,0 +1,99 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Copyright (c) 2023 MemVerge Inc.
+ * Copyright (c) 2023 SK hynix Inc.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct niagara_state {
+uint8_t nr_heads;
+uint8_t nr_lds;
+uint8_t ldmap[65536];
+uint32_t total_sections;
+uint32_t free_sections;
+uint32_t section_size;
+uint32_t sections[];
+};
+
+int main(int argc, char *argv[])
+{
+int shmid = 0;
+uint32_t sections = 0;
+uint32_t section_size = 0;
+uint32_t heads = 0;
+struct niagara_state *niagara_state = NULL;
+size_t state_size;
+uint8_t i;
+
+if (argc != 5) {
+printf("usage: init_niagara
\n"
+"\theads : number of heads on the device\n"
+"\tsections  : number of sections\n"
+"\tsection_size  : size of a section in 128mb increments\n"
+"\tshmid : /tmp/mytoken.tmp\n\n"
+"It is recommended your shared memory