platform: msm_shared: Correct invalidate cache actions
When invalidate cache, address and size must be aligned
to CACHE_LINE, if not, the arch_invalidate_cache_range
api itself will do the alignment, that may cause valid
data lost which is not yet cleaned to cache.
So correct invalidate cache actions by use CACHE_LINE
aligned address and size explicitly. Use memalign,
STACKBUF_DMA_ALIGN or BUF_DMA_ALIGN to alloc space
which will used for cache invalidate and have the size
alloc Round to CACHE_LINE.
Change-Id: I30c3f101481fd259c631c48501988fd403a8627b
diff --git a/platform/msm_shared/rpm-smd.c b/platform/msm_shared/rpm-smd.c
index f7dd3fa..982586a 100644
--- a/platform/msm_shared/rpm-smd.c
+++ b/platform/msm_shared/rpm-smd.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2015, 2018, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -118,7 +118,6 @@
resp = (rpm_ack_msg *)response;
- arch_invalidate_cache_range((addr_t)resp, sizeof(rpm_gen_hdr));
if(resp->hdr.type == RPM_CMD_MAGIC && resp->hdr.len == ACK_MSG_LENGTH)
{
diff --git a/platform/msm_shared/rpmb/rpmb_listener.c b/platform/msm_shared/rpmb/rpmb_listener.c
index 480a235..07b71b8 100644
--- a/platform/msm_shared/rpmb/rpmb_listener.c
+++ b/platform/msm_shared/rpmb/rpmb_listener.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2015, 2018, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -29,6 +29,7 @@
#include <rpmb.h>
#include <rpmb_listener.h>
#include <qseecom_lk_api.h>
+#include <stdlib.h>
#define RPMB_LSTNR_VERSION_2 0x2
@@ -107,7 +108,7 @@
struct tz_rpmb_rw_req *req_p = (struct tz_rpmb_rw_req *)buf;
struct tz_rpmb_rw_resp *resp_p = NULL;
uint32_t *req_buf = buf + req_p->req_buff_offset;
- uint32_t *resp_buf = buf + sizeof(struct tz_rpmb_rw_resp);
+ uint32_t *resp_buf = buf + ROUNDUP(sizeof(struct tz_rpmb_rw_resp), CACHE_LINE);
resp_p = (struct tz_rpmb_rw_resp *) buf;
@@ -132,7 +133,7 @@
ASSERT(0);
};
- resp_p->res_buff_offset = sizeof(struct tz_rpmb_rw_resp);
+ resp_p->res_buff_offset = ROUNDUP(sizeof(struct tz_rpmb_rw_resp), CACHE_LINE);
resp_p->cmd_id = req_p->cmd_id;
}
diff --git a/platform/msm_shared/smd.c b/platform/msm_shared/smd.c
index 166ceea..758947c 100644
--- a/platform/msm_shared/smd.c
+++ b/platform/msm_shared/smd.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2015, 2018, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -38,6 +38,7 @@
#include <reg.h>
#include <malloc.h>
#include <bits.h>
+#include <stdlib.h>
#define SMD_CHANNEL_ACCESS_RETRY 1000000
@@ -192,7 +193,7 @@
while(len)
{
- *dest++ = *src++;
+ writel(*src++, dest++);
write_index += 4;
len -= 4;
@@ -217,7 +218,7 @@
while(len)
{
- *dest++ = *src++;
+ *dest++ = readl(src++);
read_index += 4;
len -= 4;
@@ -245,6 +246,7 @@
ASSERT(0);
}
+ arch_invalidate_cache_range((addr_t) ch->port_info, ROUNDUP(size, CACHE_LINE));
if(!ch->port_info->ch1.DTR_DSR)
{
dprintf(CRITICAL,"%s: DTR is off\n", __func__);
@@ -252,31 +254,26 @@
}
/* Wait until the data updated in the smd buffer is equal to smd packet header*/
- while ((ch->port_info->ch1.write_index - ch->port_info->ch1.read_index) < sizeof(smd_pkt_hdr))
- {
+ do {
/* Get the update info from memory */
- arch_invalidate_cache_range((addr_t) ch->port_info, size);
- }
+ arch_invalidate_cache_range((addr_t) ch->port_info, ROUNDUP(size, CACHE_LINE));
+ } while ((ch->port_info->ch1.write_index - ch->port_info->ch1.read_index) < sizeof(smd_pkt_hdr));
/* Copy the smd buffer to local buf */
memcpy_from_fifo(ch, (uint32_t *)&smd_hdr, sizeof(smd_hdr));
- arch_invalidate_cache_range((addr_t)&smd_hdr, sizeof(smd_hdr));
*len = smd_hdr.pkt_size;
/* Wait on the data being updated in SMEM before returing the response */
- while ((ch->port_info->ch1.write_index - ch->port_info->ch1.read_index) < smd_hdr.pkt_size)
- {
+ do {
/* Get the update info from memory */
- arch_invalidate_cache_range((addr_t) ch->port_info, size);
- }
+ arch_invalidate_cache_range((addr_t) ch->port_info, ROUNDUP(size, CACHE_LINE));
+ } while ((ch->port_info->ch1.write_index - ch->port_info->ch1.read_index) < smd_hdr.pkt_size);
/* We are good to return the response now */
memcpy_from_fifo(ch, response, smd_hdr.pkt_size);
- arch_invalidate_cache_range((addr_t)response, smd_hdr.pkt_size);
-
}
void smd_signal_read_complete(smd_channel_info_t *ch, uint32_t len)
@@ -418,12 +415,8 @@
static void flush_smd_channel_entries()
{
- int i = 0;
- for(i = 0; i< SMEM_NUM_SMD_STREAM_CHANNELS; i++)
- {
- arch_invalidate_cache_range((addr_t)&smd_channel_alloc_entry[i],
- sizeof(smd_channel_alloc_entry_t));
- }
+ arch_invalidate_cache_range((addr_t)smd_channel_alloc_entry,
+ SMD_CHANNEL_ALLOC_MAX);
}
enum handler_return smd_irq_handler(void* data)
diff --git a/platform/msm_shared/usb30_dwc.c b/platform/msm_shared/usb30_dwc.c
index 564d1c9..60c5f86 100644
--- a/platform/msm_shared/usb30_dwc.c
+++ b/platform/msm_shared/usb30_dwc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2015, 2018, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -587,7 +587,7 @@
ASSERT(num_of_trb);
/* invalidate trb data before reading */
- arch_invalidate_cache_range((addr_t) trb, sizeof(dwc_trb_t)*num_of_trb);
+ arch_invalidate_cache_range((addr_t) trb, ROUNDUP(sizeof(dwc_trb_t)*num_of_trb, CACHE_LINE));
while (num_of_trb)
{
@@ -716,7 +716,7 @@
uint8_t *data = dev->setup_pkt; /* setup pkt data */
/* invalidate any cached setup data before reading */
- arch_invalidate_cache_range((addr_t) data, DWC_SETUP_PKT_LEN);
+ arch_invalidate_cache_range((addr_t) data, ROUNDUP(DWC_SETUP_PKT_LEN, CACHE_LINE));
/* call setup handler */
ret = dev->setup_handler(dev->setup_context, data);
@@ -1899,7 +1899,7 @@
/* flush the trb data to main memory */
arch_clean_invalidate_cache_range((addr_t) ep->trb,
- sizeof(dwc_trb_t)*ep->trb_queued);
+ ROUNDUP(sizeof(dwc_trb_t)*ep->trb_queued, CACHE_LINE));
DBG("\n Starting new xfer on ep_phy_num = %d TRB_QUEUED = %d \n",
ep_phy_num, ep->trb_queued);
diff --git a/platform/msm_shared/usb30_dwc_hw.c b/platform/msm_shared/usb30_dwc_hw.c
index 2ca1a54..04d896e 100644
--- a/platform/msm_shared/usb30_dwc_hw.c
+++ b/platform/msm_shared/usb30_dwc_hw.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013,2015 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013, 2015, 2018 The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -490,11 +490,9 @@
/* get event buffer for this device */
buf = dev->event_buf.buf;
- /* invalidate cached event buf data */
- arch_invalidate_cache_range((addr_t) (buf + dev->event_buf.index), 4);
-
+ arch_invalidate_cache_range((addr_t)buf, dev->event_buf.buf_size);
/* read next event */
- *event = buf[dev->event_buf.index];
+ *event = readl(buf + dev->event_buf.index);
event_size += 4;
dwc_event_update_index(&dev->event_buf.index, dev->event_buf.max_index);
@@ -511,17 +509,11 @@
if( DWC_EVENT_IS_DEVICE_EVENT(*event) &
(DWC_EVENT_DEVICE_EVENT_ID(*event) == DWC_EVENT_DEVICE_EVENT_ID_VENDOR_DEVICE_TEST_LMP))
{
- /* invalidate cached event buf data */
- arch_invalidate_cache_range((addr_t) (buf + dev->event_buf.index), 4);
-
- *(event + 1) = buf[dev->event_buf.index];
+ *(event + 1) = readl(buf + dev->event_buf.index);
event_size += 4;
dwc_event_update_index(&dev->event_buf.index, dev->event_buf.buf_size);
- /* invalidate cached event buf data */
- arch_invalidate_cache_range((addr_t) (buf + dev->event_buf.index), 4);
-
- *(event + 1) = buf[dev->event_buf.index];
+ *(event + 1) = readl(buf + dev->event_buf.index);
event_size += 4;
dwc_event_update_index(&dev->event_buf.index, dev->event_buf.buf_size);
}