first and last commit

This commit is contained in:
Chris Nutter committed 2023-07-08 13:03:17 -07:00
commit 1bf4efd552
2612 files changed
+636500

No files matched your search

+369
View File
@@ -0,0 +1,369 @@
/*
* Copyright (C) 2012-2013 Apple Inc. All rights reserved.
*
* This document is the property of Apple Inc.
* It is considered confidential and proprietary.
*
* This document may not be reproduced or transmitted in any form,
* in whole or in part, without the express written permission of
* Apple Inc.
*/
#include <debug.h>
#include <arch/arm/arm.h>
#include <drivers/dart.h>
#include <platform/soc/hwregbase.h>
#include <sys.h>
#include "dart_regs.h"
#if DART_PAGE_SIZE != DART_TT_PGSIZE
#error "The generic header's idea of the page size doesn't agree with this driver"
#endif
typedef uint64_t dart_ent;
typedef struct dart_l2_tt {
dart_ent *tt_base;
uintptr_t tt_phys;
dart_ent *l3_tt_bases[DART_TTE_PGENTRIES];
} dart_l2_tt_t;
typedef struct dart {
uintptr_t regs;
dart_l2_tt_t *l2_tts[DART_NUM_TTBR];
dart_iovm_addr_t addr_mask;
} dart_t;
dart_t darts[NUM_DARTS];
static void *alloc_tt_page(void)
{
void *result;
result = memalign(DART_TT_PGSIZE, DART_TT_PGSIZE);
bzero(result, DART_TT_PGSIZE);
return result;
}
static void flush_tlb(dart_t *dart)
{
arm_memory_barrier();
// Flush SID 0
rDART_TLB_OP(dart->regs) = DART_TLB_OP_FLUSH | DART_TLB_OP_SID_MASK0;
while(rDART_TLB_OP(dart->regs) & DART_TLB_OP_BUSY)
;
}
// Clear out any L3 entries in the DART so that nothing is mapped into IO virtual
// space. Don't clear out the mappings at the L2 level, just at L3. The DART
// doesn't support block mappings, so L2 entries can never cause a mapping
// without a subsequent L3 entry.
static void clear_mappings(dart_t *dart)
{
unsigned int i, j;
dart_l2_tt_t *l2_tt;
dart_ent *l3_tt_base;
for (i = 0; i < DART_NUM_TTBR; i++) {
l2_tt = dart->l2_tts[i];
if (l2_tt == NULL)
continue;
for (j = 0; j < DART_TTE_PGENTRIES; j++) {
l3_tt_base = l2_tt->l3_tt_bases[j];
if (l3_tt_base != NULL)
memset(l3_tt_base, 0, DART_TT_PGSIZE);
}
}
}
void dart_init(unsigned int dart_id)
{
dart_t *dart;
uint32_t reg;
ASSERT(dart_id < NUM_DARTS);
dart = &darts[dart_id];
switch (dart_id)
{
#ifdef DART0_BASE_ADDR
case 0:
dart->regs = DART0_BASE_ADDR;
dart->addr_mask = DART0_ADDR_MASK;
break;
#endif
#ifdef DART1_BASE_ADDR
case 1:
dart->regs = DART1_BASE_ADDR;
dart->addr_mask = DART1_ADDR_MASK;
break;
#endif
#ifdef DART2_BASE_ADDR
case 2:
dart->regs = DART2_BASE_ADDR;
dart->addr_mask = DART2_ADDR_MASK;
break;
#endif
#ifdef DART3_BASE_ADDR
case 3:
dart->regs = DART3_BASE_ADDR;
dart->addr_mask = DART3_ADDR_MASK;
break;
#endif
default:
panic("Unknown DART index %d", dart_id);
break;
}
// If the DART has previously been initialized, we need to clear out all mappings
// This will be a quick no-op if the DART hasn't been initialized
clear_mappings(dart);
// If for some reason translation gets disabled, bypass to an invalid
// address instead of DRAM
rDART_BYPASS_ADDR(dart->regs) = 0;
rDART_DIAG_BOGUS_ACCESS(dart->regs) = ERR_REFLECTION_BASE_ADDR >> 12;
// Tunables
rDART_DIAG_CONFIG(dart->regs) |= DART_DIAG_CONFIG_PTE_FETCH_PROMOTE_QOS;
reg = rDART_FETCH_REQ_CONFIG(dart->regs);
reg &= ~DART_FETCH_REQ_CONFIG_STE(0xf);
reg |= DART_FETCH_REQ_CONFIG_STE(0x3);
reg &= ~DART_FETCH_REQ_CONFIG_PTE(0xf);
reg |= DART_FETCH_REQ_CONFIG_PTE(0x3);
reg &= ~DART_FETCH_REQ_CONFIG_PTE_PREFETCH(0xf);
reg |= DART_FETCH_REQ_CONFIG_PTE_PREFETCH(0xe);
rDART_FETCH_REQ_CONFIG(dart->regs) = reg;
// Restore TTBRs if we were previously enabled, otherwise initialize
// all the TTBRs to 0
dart_enable_translation(dart_id);
// Enable translation and exceptions for SID 0
rDART_CONFIG(dart->regs) = 0x80;
}
/* Disables all TTBRs and flushes the TLB, but leaves translation enabled. This will
* make sure that all translation attempts result in an error. If we disabled translation,
* all translation attempts would go to the bypass address, which is not what we want */
void dart_disable_translation(unsigned int dart_id)
{
dart_t *dart;
int i;
ASSERT(dart_id < NUM_DARTS);
dart = &darts[dart_id];
for (i = 0; i < DART_NUM_TTBR; i++)
rDART_TTBR(dart->regs, i) = 0;
flush_tlb(dart);
}
/* Re-enables mappings that were previously created with dart_map_page_range by reprogramming
* the DART's TTBRs with the previously created translation tables */
void dart_enable_translation(unsigned int dart_id)
{
uint32_t i;
uint32_t ttbr;
dart_t *dart;
dart_l2_tt_t *l2_tt;
ASSERT(dart_id < NUM_DARTS);
dart = &darts[dart_id];
for (i = 0; i < DART_NUM_TTBR; i++) {
l2_tt = dart->l2_tts[i];
if (l2_tt == NULL) {
ttbr = 0;
} else {
ttbr = (l2_tt->tt_phys >> DART_TTBR_SHIFT) | DART_TTBR_VALID;
}
rDART_TTBR(dart->regs, i) = ttbr;
}
flush_tlb(dart);
}
void dart_map_page_range(unsigned int dart_id, uintptr_t paddr, dart_iovm_addr_t vaddr, uint32_t pages, bool write_protect)
{
uint32_t ttbr;
uint32_t i;
dart_iovm_addr_t page_vaddr;
uintptr_t page_paddr;
dart_ent ent;
dart_t *dart;
ASSERT(dart_id < NUM_DARTS);
dart = &darts[dart_id];
ASSERT((vaddr & DART_TT_L3_OFFMASK) == 0);
ASSERT((paddr & DART_TT_L3_OFFMASK) == 0);
page_vaddr = vaddr & dart->addr_mask;
page_paddr = paddr;
dprintf(DEBUG_SPEW, "dart%d: mapped 0x%04x pages at iovm 0x%08x to phys %p\n", dart_id, pages, vaddr, (void *)paddr);
for (i = 0; i < pages; i++) {
uint32_t l1_index = (page_vaddr & DART_TT_L1_INDEX_MASK) >> DART_TT_L1_SHIFT;
uint32_t l2_index = (page_vaddr & DART_TT_L2_INDEX_MASK) >> DART_TT_L2_SHIFT;
uint32_t l3_index = (page_vaddr & DART_TT_L3_INDEX_MASK) >> DART_TT_L3_SHIFT;
dart_l2_tt_t *l2_tt;
dart_ent *l3_tt;
if (dart->l2_tts[l1_index] == NULL) {
dart_ent *new_tt;
uintptr_t new_tt_phys;
new_tt = alloc_tt_page();
new_tt_phys = mem_static_map_physical((uintptr_t)new_tt);
dart->l2_tts[l1_index] = calloc(1, sizeof(dart_l2_tt_t));
dart->l2_tts[l1_index]->tt_base = new_tt;
dart->l2_tts[l1_index]->tt_phys = new_tt_phys;
ttbr = (new_tt_phys >> DART_TTBR_SHIFT) | DART_TTBR_VALID;
rDART_TTBR(dart->regs, l1_index) = ttbr;
}
l2_tt = dart->l2_tts[l1_index];
if (l2_tt->l3_tt_bases[l2_index] == NULL) {
dart_ent *new_tt = alloc_tt_page();
l2_tt->l3_tt_bases[l2_index] = new_tt;
ent = ((uintptr_t)mem_static_map_physical((uintptr_t)new_tt)) | DART_TTE_TABLE | DART_TTE_VALID;
l2_tt->tt_base[l2_index] = ent;
}
l3_tt = l2_tt->l3_tt_bases[l2_index];
RELEASE_ASSERT(l3_tt[l3_index] == 0);
ent = page_paddr | DART_PTE_WRPROT(write_protect) | DART_PTE_TYPE_VALID;
l3_tt[l3_index] = ent;
page_vaddr += DART_TT_L3_SIZE;
page_paddr += DART_TT_L3_SIZE;
}
flush_tlb(dart);
}
void dart_unmap_page_range(unsigned int dart_id, dart_iovm_addr_t vaddr, uint32_t pages)
{
uint32_t i;
dart_iovm_addr_t page_vaddr;
dart_t *dart;
ASSERT(dart_id < NUM_DARTS);
dart = &darts[dart_id];
ASSERT((vaddr & DART_TT_L3_OFFMASK) == 0);
dprintf(DEBUG_SPEW, "dart%d: unmapped 0x%04x pages at iovm 0x%08x\n", dart_id, pages, vaddr);
page_vaddr = vaddr & dart->addr_mask;
for (i = 0; i < pages; i++) {
uint32_t l1_index = (page_vaddr & DART_TT_L1_INDEX_MASK) >> DART_TT_L1_SHIFT;
uint32_t l2_index = (page_vaddr & DART_TT_L2_INDEX_MASK) >> DART_TT_L2_SHIFT;
uint32_t l3_index = (page_vaddr & DART_TT_L3_INDEX_MASK) >> DART_TT_L3_SHIFT;
dart_l2_tt_t *l2_tt;
dart_ent *l3_tt;
l2_tt = dart->l2_tts[l1_index];
RELEASE_ASSERT(l2_tt != NULL);
l3_tt = l2_tt->l3_tt_bases[l2_index];
RELEASE_ASSERT(l3_tt != NULL);
l3_tt[l3_index] = 0;
page_vaddr += DART_TT_L3_SIZE;
}
flush_tlb(dart);
}
void dart_write_protect_page_range(unsigned int dart_id, dart_iovm_addr_t vaddr, uint32_t pages, bool write_protect)
{
uint32_t i;
dart_iovm_addr_t page_vaddr;
dart_ent ent;
dart_t *dart;
ASSERT(dart_id < NUM_DARTS);
dart = &darts[dart_id];
ASSERT((vaddr & DART_TT_L3_OFFMASK) == 0);
page_vaddr = vaddr;
for (i = 0; i < pages; i++) {
uint32_t l1_index = (page_vaddr & DART_TT_L1_INDEX_MASK) >> DART_TT_L1_SHIFT;
uint32_t l2_index = (page_vaddr & DART_TT_L2_INDEX_MASK) >> DART_TT_L2_SHIFT;
uint32_t l3_index = (page_vaddr & DART_TT_L3_INDEX_MASK) >> DART_TT_L3_SHIFT;
dart_l2_tt_t *l2_tt;
dart_ent *l3_tt;
l2_tt = dart->l2_tts[l1_index];
RELEASE_ASSERT(l2_tt != NULL);
l3_tt = l2_tt->l3_tt_bases[l2_index];
RELEASE_ASSERT(l3_tt != NULL);
ent = l3_tt[l3_index];
ent &= DART_PTE_PAGE_MASK;
ent |= DART_PTE_WRPROT(write_protect);
l3_tt[l3_index] = ent;
page_vaddr += DART_TT_L3_SIZE;
}
flush_tlb(dart);
}
// Verifies that all mappings have been removed from the DART. This is used
// to verify that drivers aren't leaking mappings, as leaked mappings could
// lead to a security hole
void dart_assert_unmapped(unsigned int dart_id)
{
dart_t *dart;
unsigned int i, j, k;
dart_l2_tt_t *l2_tt;
dart_ent *l3_tt_base;
ASSERT(dart_id < NUM_DARTS);
dart = &darts[dart_id];
for (i = 0; i < DART_NUM_TTBR; i++) {
// If the driver isn't tracking an L2 table under the given TTBR,
// then, the TTBR needs to be 0
l2_tt = dart->l2_tts[i];
if (l2_tt == NULL) {
RELEASE_ASSERT(rDART_TTBR(dart->regs, i) == 0);
continue;
}
// For each L2 table, verify each entry is either 0 or points
// to an L3 table filled with 0s
for (j = 0; j < DART_TTE_PGENTRIES; j++) {
l3_tt_base = l2_tt->l3_tt_bases[j];
if (l3_tt_base != NULL) {
for (k = 0; k < DART_TTE_PGENTRIES; k++) {
RELEASE_ASSERT(l3_tt_base[k] == 0);
}
} else {
RELEASE_ASSERT(l2_tt->tt_base[j] == 0);
}
}
}
}
+117
View File
@@ -0,0 +1,117 @@
/*
* Copyright (C) 2012 Apple Inc. All rights reserved.
*
* This document is the property of Apple Inc.
* It is considered confidential and proprietary.
*
* This document may not be reproduced or transmitted in any form,
* in whole or in part, without the express written permission of
* Apple Inc.
*/
#ifndef DART_REGS_H
#define DART_REGS_H
#define DART_TT_PGSIZE 4096
#define DART_TTE_SHIFT 3
#define DART_TTE_PGENTRIES (DART_TT_PGSIZE >> DART_TTE_SHIFT)
#define DART_TTE_VALID (1 << 0)
#define DART_TTE_TABLE (1 << 1)
#define DART_NUM_TTBR 4
#define DART_NUM_SID 4
#define rDART_TLB_OP(base) (*(volatile uint32_t *)((base) + 0x00))
#define rDART_CONFIG(base) (*(volatile uint32_t *)((base) + 0x0c))
#define rDART_DIAG_CONFIG(base) (*(volatile uint32_t *)((base) + 0x20))
#define rDART_DIAG_BOGUS_ACCESS(base) (*(volatile uint32_t *)((base) + 0x24))
#define rDART_BYPASS_ADDR(base) (*(volatile uint32_t *)((base) + 0x2c))
#define rDART_FETCH_REQ_CONFIG(base) (*(volatile uint32_t *)((base) + 0x30))
#define rDART_TTBR(base, idx) (*(volatile uint32_t *)((base) + 0x40 + 4 * (idx)))
#define DART_TLB_OP_FLUSH (2)
#define DART_TLB_OP_BUSY (1 << 3)
#define DART_TLB_OP_SID_MASK0 (1 << 8)
#define DART_TLB_OP_SID_MASK1 (1 << 9)
#define DART_TLB_OP_SID_MASK2 (1 << 10)
#define DART_TLB_OP_SID_MASK3 (1 << 11)
#define DART_DIAG_CONFIG_PTE_FETCH_PROMOTE_QOS (1 << 8)
#define DART_FETCH_REQ_CONFIG_STE(x) (((x) & 0xf) << 0)
#define DART_FETCH_REQ_CONFIG_PTE(x) (((x) & 0xf) << 8)
#define DART_FETCH_REQ_CONFIG_PTE_PREFETCH(x) (((x) & 0xf) << 16)
#define DART_TTBR_VALID (1 << 31)
#define DART_TTBR_SHIFT (12)
/*
* L1 Translation table (stored in registers)
*
* There are DART_NUM_TTBR entries in the L1 table
* DART_NUM_TTBR entries of 1GB (2^30) of address space.
*/
#define DART_TT_L1_SIZE 0x0000000040000000ULL /* size of area covered by a tte */
#define DART_TT_L1_OFFMASK 0x000000003fffffffULL /* offset within an L2 entry */
#define DART_TT_L1_SHIFT 30
#define DART_TT_L1_INDEX_MASK 0x0000000070000000ULL /* mask for getting index in L1 table from virtual address */
/*
* L2 Translation table
*
* Each translation table is 4KB
* 512 64-bit entries of 2MB (2^21) of address space.
*/
#define DART_TT_L2_SIZE 0x0000000000200000ULL /* size of area covered by a tte */
#define DART_TT_L2_OFFMASK 0x00000000001fffffULL /* offset within an L2 entry */
#define DART_TT_L2_SHIFT 21 /* page descriptor shift */
#define DART_TT_L2_INDEX_MASK 0x000000003fe00000ULL /* mask for getting index in L2 table from virtual address */
/*
* L3 Translation table
*
* Each translation table is 4KB
* 512 64-bit entries of 4KB (2^12) of address space.
*/
#define DART_TT_L3_SIZE 0x0000000000001000ULL /* size of area covered by a tte */
#define DART_TT_L3_OFFMASK 0x0000000000000fffULL /* offset within L3 PTE */
#define DART_TT_L3_SHIFT 12 /* page descriptor shift */
#define DART_TT_L3_INDEX_MASK 0x00000000001ff000ULL /* mask for page descriptor index */
/*
* L3 Page table entries
*
* The following page table entry types are possible:
*
* fault page entry
* 63 2 0
* +------------------------------+--+
* | ignored |00|
* +------------------------------+--+
*
*
* 63 52 51 36 35 12 11 8 7 6 2 1 0
* +-----+------+----------------------+-----+-+-----+-+-+
* | ign | zero | OutputAddress[35:12] | ign |W| ign |1|V|
* +-----+------+----------------------+-----+-+-----+-+-+
*
* where:
* 'W' Write orotect bit
* 'V' Valid bit
*/
#define DART_PTE_SHIFT 3
#define DART_PTE_PGENTRIES (DART_TT_PGSIZE >> DART_PTE_SHIFT)
#define DART_PTE_EMPTY 0x0000000000000000ULL /* unasigned - invalid entry */
#define DART_PTE_TYPE_VALID 0x0000000000000003ULL /* valid L3 entry: includes bit #1 (counterintuitively) */
#define DART_PTE_PAGE_MASK 0x0000FFFFFFFFF000ULL /* mask for 4KB page */
#define DART_PTE_PAGE_SHIFT 12 /* page shift for 4KB page */
#define DART_PTE_WRPROT(enable) ((enable) ? (1 << 7) : 0) /* write protect */
#endif // DART_REGS_H
+16
View File
@@ -0,0 +1,16 @@
# Copyright (C) 2012 Apple Inc. All rights reserved.
#
# This document is the property of Apple Inc.
# It is considered confidential and proprietary.
#
# This document may not be reproduced or transmitted in any form,
# in whole or in part, without the express written permission of
# Apple Inc.
#
LOCAL_DIR := $(GET_LOCAL_DIR)
OPTIONS += \
WITH_HW_DART=1
ALL_OBJS += \
$(LOCAL_DIR)/dart.o