Commit 7ee06481 authored by Jeffrey Lee's avatar Jeffrey Lee Committed by ROOL
Browse files

Support 64bit physical addresses

If the SATA controller supports 64bit addresses, and the OS reports that
there's RAM above the 4GB physical barrier, use the 64bit phys addr
version of OS_Memory 19 for DMA preparation / log->phys conversion.

Version 0.11. Tagged as 'SATADriver-0_11'
parent e99dc06f
/* (0.10) /* (0.11)
* *
* This file is automatically maintained by srccommit, do not edit manually. * This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1.
* *
*/ */
#define Module_MajorVersion_CMHG 0.10 #define Module_MajorVersion_CMHG 0.11
#define Module_MinorVersion_CMHG #define Module_MinorVersion_CMHG
#define Module_Date_CMHG 02 Dec 2018 #define Module_Date_CMHG 02 Jun 2021
#define Module_MajorVersion "0.10" #define Module_MajorVersion "0.11"
#define Module_Version 10 #define Module_Version 11
#define Module_MinorVersion "" #define Module_MinorVersion ""
#define Module_Date "02 Dec 2018" #define Module_Date "02 Jun 2021"
#define Module_ApplicationDate "02-Dec-18" #define Module_ApplicationDate "02-Jun-21"
#define Module_ComponentName "SATADriver" #define Module_ComponentName "SATADriver"
#define Module_ComponentPath "cddl/RiscOS/Sources/HWSupport/ATA/SATADriver"
#define Module_FullVersion "0.10" #define Module_FullVersion "0.11"
#define Module_HelpVersion "0.10 (02 Dec 2018)" #define Module_HelpVersion "0.11 (02 Jun 2021)"
#define Module_LibraryVersionInfo "0:10" #define Module_LibraryVersionInfo "0:11"
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "swis.h" #include "swis.h"
#include "Global/HALEntries.h" #include "Global/HALEntries.h"
#include "Global/OSMisc.h"
#include "Interface/ATA.h" #include "Interface/ATA.h"
#include "Interface/AHCIDevice.h" #include "Interface/AHCIDevice.h"
#include "SyncLib/synclib.h" #include "SyncLib/synclib.h"
...@@ -83,8 +84,15 @@ void device_added(ahcidevice_t *dev) ...@@ -83,8 +84,15 @@ void device_added(ahcidevice_t *dev)
hba->ghc |= GHC_HR; hba->ghc |= GHC_HR;
do; while (hba->ghc & GHC_HR); do; while (hba->ghc & GHC_HR);
/* Initialise port data structures */ /* Should we use 64bit physical addresses/APIs? */
_kernel_oserror *e = NULL; _kernel_oserror *e = NULL;
uint32_t platfeat=0;
e = _swix(OS_PlatformFeatures,_IN(0)|_OUT(0),OSPlatformFeatures_ReadCodeFeatures,&platfeat);
g_phys64 = (hba->cap & CAP_S64A) /* Controller supports 64bit addresses */
&& (e == NULL) && (platfeat & CPUFlag_HighRAM); /* Machine has RAM beyond the 32bit limit (guarantees 64bit APIs supported) */
/* N.B. I/O regions may exist beyond the 32bit phys addr limit, but those are irrelevant, since we always use bounce buffers for filesystem access to I/O regions */
/* Initialise port data structures */
for (uint32_t porti = 0; e == NULL && porti < 32; porti++) for (uint32_t porti = 0; e == NULL && porti < 32; porti++)
{ {
if (hba->pi & (1u<<porti)) if (hba->pi & (1u<<porti))
...@@ -101,27 +109,28 @@ void device_added(ahcidevice_t *dev) ...@@ -101,27 +109,28 @@ void device_added(ahcidevice_t *dev)
/* Allocate locked-down RAM pages for communication with the AHCI. */ /* Allocate locked-down RAM pages for communication with the AHCI. */
{ {
/* This only writes to the low half of command_list_phy, but that's fine since (a) PCI_RAMAlloc only uses 32bit physical addresses, and (b) we've zero-initialised all of 'port' */
e = _swix(PCI_RAMAlloc, _INR(0,2) | _OUTR(0,1), e = _swix(PCI_RAMAlloc, _INR(0,2) | _OUTR(0,1),
MAX_COMMAND_SLOTS * sizeof (ahci_command_hdr_t), AHCI_COMMAND_HDR_ALIGN, 0, MAX_COMMAND_SLOTS * sizeof (ahci_command_hdr_t), AHCI_COMMAND_HDR_ALIGN, 0,
&port->command_list, &port->command_list_phy); &port->command_list, (uint32_t *) &port->command_list_phy);
} }
if (!e) if (!e)
{ {
e = _swix(PCI_RAMAlloc, _INR(0,2) | _OUTR(0,1), e = _swix(PCI_RAMAlloc, _INR(0,2) | _OUTR(0,1),
sizeof (ahci_command_table_t) + AHCI_MAX_PRDT_ENTRIES * sizeof (ahci_prdt_entry_t), AHCI_COMMAND_TABLE_ALIGN, 0, sizeof (ahci_command_table_t) + AHCI_MAX_PRDT_ENTRIES * sizeof (ahci_prdt_entry_t), AHCI_COMMAND_TABLE_ALIGN, 0,
&port->command_table, &port->command_table_phy); &port->command_table, (uint32_t *) &port->command_table_phy);
} }
if (!e) if (!e)
{ {
e = _swix(PCI_RAMAlloc, _INR(0,2) | _OUTR(0,1), e = _swix(PCI_RAMAlloc, _INR(0,2) | _OUTR(0,1),
BOUNCE_BUFFER_SIZE, BOUNCE_BUFFER_SIZE, 0, BOUNCE_BUFFER_SIZE, BOUNCE_BUFFER_SIZE, 0,
&port->bounce_buffer, &port->bounce_buffer_phy); &port->bounce_buffer, (uint32_t *) &port->bounce_buffer_phy);
} }
if (!e) if (!e)
{ {
e = _swix(PCI_RAMAlloc, _INR(0,2) | _OUTR(0,1), e = _swix(PCI_RAMAlloc, _INR(0,2) | _OUTR(0,1),
MAX_RECEIVED_FIS_SLOTS * sizeof (ahci_received_fis_t), AHCI_RECEIVED_FIS_ALIGN, 0, MAX_RECEIVED_FIS_SLOTS * sizeof (ahci_received_fis_t), AHCI_RECEIVED_FIS_ALIGN, 0,
&port->received_fis, &port->received_fis_phy); &port->received_fis, (uint32_t *) &port->received_fis_phy);
} }
if (!e) if (!e)
{ {
......
...@@ -31,5 +31,6 @@ ...@@ -31,5 +31,6 @@
ahci_t g_ahci; ahci_t g_ahci;
spinrwlock_t g_ahci_lock = SPINRW_INITIALISER; spinrwlock_t g_ahci_lock = SPINRW_INITIALISER;
bool g_phys64;
uint32_t g_message_fd[4]; uint32_t g_message_fd[4];
void *g_module_pw; void *g_module_pw;
...@@ -105,10 +105,11 @@ static void scatter_consume(scatter_walker_t *walker, size_t bytes) ...@@ -105,10 +105,11 @@ static void scatter_consume(scatter_walker_t *walker, size_t bytes)
* *
* In: * In:
* R9 -> scatter walker * R9 -> scatter walker
* Out: * Out: (32bit) (64bit)
* R0 = log addr * R0 = log addr log addr low
* R1 = length * R1 = length log addr high (0)
* R2 = flags * R2 = flags flags
* R3 = length
*/ */
_kernel_oserror *mem19_in_handler(_kernel_swi_regs *r, void *pw) _kernel_oserror *mem19_in_handler(_kernel_swi_regs *r, void *pw)
{ {
...@@ -118,10 +119,12 @@ _kernel_oserror *mem19_in_handler(_kernel_swi_regs *r, void *pw) ...@@ -118,10 +119,12 @@ _kernel_oserror *mem19_in_handler(_kernel_swi_regs *r, void *pw)
/* Work out how much of current chunk we can return */ /* Work out how much of current chunk we can return */
scatter_t chunk = scatter_current_chunk(walker); scatter_t chunk = scatter_current_chunk(walker);
int len_reg = (g_phys64 ? 3 : 1);
r->r[2] = 0; r->r[2] = 0;
if (chunk.length == 0) if (chunk.length == 0)
{ {
r->r[1] = 0; r->r[len_reg] = 0;
return NULL; return NULL;
} }
...@@ -152,24 +155,35 @@ _kernel_oserror *mem19_in_handler(_kernel_swi_regs *r, void *pw) ...@@ -152,24 +155,35 @@ _kernel_oserror *mem19_in_handler(_kernel_swi_regs *r, void *pw)
scatter_consume(walker, chunk.length); scatter_consume(walker, chunk.length);
r->r[0] = (int) chunk.address; r->r[0] = (int) chunk.address;
r->r[1] = chunk.length; r->r[1] = 0;
r->r[len_reg] = chunk.length;
return NULL; return NULL;
} }
/* Receive address translation + bounce buffer usage information for a block /* Receive address translation + bounce buffer usage information for a block
* of memory * of memory
* *
* In: * In: (32bit) (64bit)
* R0 = log addr * R0 = log addr log addr
* R1 = phys addr * R1 = phys addr phys addr (low)
* R2 = length * R2 = length phys addr (high)
* R3 = flags * R3 = flags flags
* R9 -> scatter walker * R4 = length
* R9 -> scatter walker scatter walker
*/ */
_kernel_oserror *mem19_out_handler(_kernel_swi_regs *r, void *pw) _kernel_oserror *mem19_out_handler(_kernel_swi_regs *r, void *pw)
{ {
paddr_t phys = r->r[1]; paddr_t phys = (uint32_t) r->r[1];
size_t length = r->r[2]; size_t length;
if (g_phys64)
{
phys |= ((uint64_t) r->r[2])<<32;
length = r->r[4];
}
else
{
length = r->r[2];
}
bool bounce = r->r[3] & DMAPrep_UseBounceBuffer; bool bounce = r->r[3] & DMAPrep_UseBounceBuffer;
mem19_ctx_t *ctx = (mem19_ctx_t *) r->r[9]; mem19_ctx_t *ctx = (mem19_ctx_t *) r->r[9];
ahci_prdt_entry_t *prdt = &ctx->op->prdt[ctx->prdt_index]; ahci_prdt_entry_t *prdt = &ctx->op->prdt[ctx->prdt_index];
...@@ -253,7 +267,7 @@ dmaprep_result_t dmaprep_prep(ahciop_t *op, ataop_block_t *b, scatter_t *scat, a ...@@ -253,7 +267,7 @@ dmaprep_result_t dmaprep_prep(ahciop_t *op, ataop_block_t *b, scatter_t *scat, a
else else
{ {
res.e = _swix(OS_Memory,_INR(0,5), res.e = _swix(OS_Memory,_INR(0,5),
OSMemReason_DMAPrep | (dmawrite ? DMAPrep_Write : 0), OSMemReason_DMAPrep | (dmawrite ? DMAPrep_Write : 0) | (g_phys64 ? DMAPrep_Phys64 : 0),
g_module_pw, g_module_pw,
&ctx.walker, &ctx.walker,
mem19_in_veneer, mem19_in_veneer,
...@@ -359,7 +373,7 @@ static void complete_internal(ahciop_t *op, uint8_t *bounce_buffer, paddr_t boun ...@@ -359,7 +373,7 @@ static void complete_internal(ahciop_t *op, uint8_t *bounce_buffer, paddr_t boun
.scat = op->list, .scat = op->list,
}; };
_swix(OS_Memory,_INR(0,3), _swix(OS_Memory,_INR(0,3),
OSMemReason_DMAPrep | ((op->description_info & COMMANDHDR_W) ? 0 : DMAPrep_Write) | DMAPrep_End, OSMemReason_DMAPrep | ((op->description_info & COMMANDHDR_W) ? 0 : DMAPrep_Write) | (g_phys64 ? DMAPrep_Phys64 : 0) | DMAPrep_End,
g_module_pw, g_module_pw,
&walker, &walker,
mem19_in_veneer); mem19_in_veneer);
......
...@@ -103,7 +103,7 @@ ...@@ -103,7 +103,7 @@
/* Types */ /* Types */
/** Physical address as defined by RISC OS APIs. */ /** Physical address as defined by RISC OS APIs. */
typedef uint32_t paddr_t; /* Possibly not for much longer though */ typedef uint64_t paddr_t;
/** Scatter list entry */ /** Scatter list entry */
typedef struct typedef struct
...@@ -327,6 +327,8 @@ atapacketop_control_t; ...@@ -327,6 +327,8 @@ atapacketop_control_t;
extern ahci_t g_ahci; extern ahci_t g_ahci;
/** Lock for the AHCI controller (or list/aray of same when multiple are supported) */ /** Lock for the AHCI controller (or list/aray of same when multiple are supported) */
extern spinrwlock_t g_ahci_lock; extern spinrwlock_t g_ahci_lock;
/** True if we should use 64bit physical addresses (supported/required by RISC OS *and* supported by AHCI controller) */
extern bool g_phys64;
/** MessageTrans descriptor for our Messages file */ /** MessageTrans descriptor for our Messages file */
extern uint32_t g_message_fd[4]; extern uint32_t g_message_fd[4];
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment