mirror of
https://gitlab.com/qemu-project/openbios.git
synced 2024-02-13 08:34:06 +08:00
Switch sparc64 to ofmem (Igor Kovalenko)
Initialize ofmem at startup. Switch malloc/realloc/free to use ofmem. Implement runtime migration of startup mappings to ofmem. Implement mmu miss handlers to install tlb entries based on ofmem translations list. git-svn-id: svn://coreboot.org/openbios/trunk/openbios-devel@517 f158a5a8-5612-0410-a976-696ce0be7e32
This commit is contained in:
@@ -34,32 +34,19 @@ int printk( const char *fmt, ... )
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MEMSIZE ((128 + 256 + 512) * 1024)
|
|
||||||
static char memory[MEMSIZE];
|
|
||||||
static void *memptr=memory;
|
|
||||||
static int memsize=MEMSIZE;
|
|
||||||
|
|
||||||
|
|
||||||
void *malloc(int size)
|
void *malloc(int size)
|
||||||
{
|
{
|
||||||
void *ret=(void *)0;
|
return ofmem_malloc(size);
|
||||||
|
}
|
||||||
|
|
||||||
if( !size )
|
void* realloc( void *ptr, size_t size )
|
||||||
return NULL;
|
{
|
||||||
|
return ofmem_realloc(ptr, size);
|
||||||
size = (size + 7) & ~7;
|
|
||||||
|
|
||||||
if(memsize>=size) {
|
|
||||||
memsize-=size;
|
|
||||||
ret=memptr;
|
|
||||||
memptr = (void *)((unsigned long)memptr + size);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void free(void *ptr)
|
void free(void *ptr)
|
||||||
{
|
{
|
||||||
/* Nothing yet */
|
ofmem_free(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PAGE_SIZE_4M (4 * 1024 * 1024)
|
#define PAGE_SIZE_4M (4 * 1024 * 1024)
|
||||||
@@ -84,50 +71,44 @@ mmu_close(void)
|
|||||||
|
|
||||||
void ofmem_walk_boot_map(translation_entry_cb cb)
|
void ofmem_walk_boot_map(translation_entry_cb cb)
|
||||||
{
|
{
|
||||||
}
|
unsigned long phys, virt, size, mode, data, mask;
|
||||||
|
|
||||||
static int
|
|
||||||
spitfire_translate(unsigned long virt, unsigned long *p_phys,
|
|
||||||
unsigned long *p_data, unsigned long *p_size)
|
|
||||||
{
|
|
||||||
unsigned long phys, tag, data, mask, size;
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
for (i = 0; i < 64; i++) {
|
for (i = 0; i < 64; i++) {
|
||||||
data = spitfire_get_dtlb_data(i);
|
data = spitfire_get_dtlb_data(i);
|
||||||
if (data & 0x8000000000000000ULL) { // Valid entry?
|
if (data & SPITFIRE_TTE_VALID) {
|
||||||
switch ((data >> 61) & 3) {
|
switch ((data >> 61) & 3) {
|
||||||
default:
|
default:
|
||||||
case 0x0: // 8k
|
case 0x0: /* 8k */
|
||||||
mask = 0xffffffffffffe000ULL;
|
mask = 0xffffffffffffe000ULL;
|
||||||
size = PAGE_SIZE_8K;
|
size = PAGE_SIZE_8K;
|
||||||
break;
|
break;
|
||||||
case 0x1: // 64k
|
case 0x1: /* 64k */
|
||||||
mask = 0xffffffffffff0000ULL;
|
mask = 0xffffffffffff0000ULL;
|
||||||
size = PAGE_SIZE_64K;
|
size = PAGE_SIZE_64K;
|
||||||
break;
|
break;
|
||||||
case 0x2: // 512k
|
case 0x2: /* 512k */
|
||||||
mask = 0xfffffffffff80000ULL;
|
mask = 0xfffffffffff80000ULL;
|
||||||
size = PAGE_SIZE_512K;
|
size = PAGE_SIZE_512K;
|
||||||
break;
|
break;
|
||||||
case 0x3: // 4M
|
case 0x3: /* 4M */
|
||||||
mask = 0xffffffffffc00000ULL;
|
mask = 0xffffffffffc00000ULL;
|
||||||
size = PAGE_SIZE_4M;
|
size = PAGE_SIZE_4M;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tag = spitfire_get_dtlb_tag(i);
|
|
||||||
if ((virt & mask) == (tag & mask)) {
|
virt = spitfire_get_dtlb_tag(i);
|
||||||
phys = data & mask & 0x000001fffffff000ULL;
|
virt &= mask;
|
||||||
phys |= virt & ~mask;
|
|
||||||
*p_phys = phys;
|
/* extract 41bit physical address */
|
||||||
*p_data = data & 0xfff;
|
phys = data & 0x000001fffffff000ULL;
|
||||||
*p_size = size;
|
phys &= mask;
|
||||||
return -1;
|
|
||||||
}
|
mode = data & 0xfff;
|
||||||
|
|
||||||
|
cb(phys, virt, size, mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -137,18 +118,21 @@ spitfire_translate(unsigned long virt, unsigned long *p_phys,
|
|||||||
static void
|
static void
|
||||||
mmu_translate(void)
|
mmu_translate(void)
|
||||||
{
|
{
|
||||||
unsigned long virt, phys, data, size;
|
ucell virt, phys, mode;
|
||||||
|
|
||||||
virt = POP();
|
virt = POP();
|
||||||
|
|
||||||
if (spitfire_translate(virt, &phys, &data, &size)) {
|
phys = ofmem_translate(virt, &mode);
|
||||||
PUSH(phys & 0xffffffff);
|
|
||||||
PUSH(phys >> 32);
|
if (phys != -1UL) {
|
||||||
PUSH(data);
|
PUSH(phys & 0xffffffff);
|
||||||
PUSH(-1);
|
PUSH(phys >> 32);
|
||||||
return;
|
PUSH(mode);
|
||||||
|
PUSH(-1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PUSH(0);
|
||||||
}
|
}
|
||||||
PUSH(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -218,13 +202,15 @@ itlb_load(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
map_pages(unsigned long virt, unsigned long size, unsigned long phys,
|
map_pages(unsigned long phys, unsigned long virt,
|
||||||
unsigned long mode)
|
unsigned long size, unsigned long mode)
|
||||||
{
|
{
|
||||||
unsigned long tte_data, currsize;
|
unsigned long tte_data, currsize;
|
||||||
|
|
||||||
size = (size + PAGE_MASK_8K) & ~PAGE_MASK_8K;
|
/* aligned to 8k page */
|
||||||
while (size >= PAGE_SIZE_8K) {
|
size = (size + PAGE_MASK_8K) & ~PAGE_MASK_8K;
|
||||||
|
|
||||||
|
while (size > 0) {
|
||||||
currsize = size;
|
currsize = size;
|
||||||
if (currsize >= PAGE_SIZE_4M &&
|
if (currsize >= PAGE_SIZE_4M &&
|
||||||
(virt & PAGE_MASK_4M) == 0 &&
|
(virt & PAGE_MASK_4M) == 0 &&
|
||||||
@@ -248,8 +234,9 @@ map_pages(unsigned long virt, unsigned long size, unsigned long phys,
|
|||||||
|
|
||||||
tte_data |= phys | mode | SPITFIRE_TTE_VALID;
|
tte_data |= phys | mode | SPITFIRE_TTE_VALID;
|
||||||
|
|
||||||
dtlb_load2(virt, tte_data);
|
|
||||||
itlb_load2(virt, tte_data);
|
itlb_load2(virt, tte_data);
|
||||||
|
dtlb_load2(virt, tte_data);
|
||||||
|
|
||||||
size -= currsize;
|
size -= currsize;
|
||||||
phys += currsize;
|
phys += currsize;
|
||||||
virt += currsize;
|
virt += currsize;
|
||||||
@@ -268,7 +255,7 @@ void ofmem_map_pages(ucell phys, ucell virt, ucell size, ucell mode)
|
|||||||
static void
|
static void
|
||||||
mmu_map(void)
|
mmu_map(void)
|
||||||
{
|
{
|
||||||
unsigned long virt, size, mode, phys;
|
ucell virt, size, mode, phys;
|
||||||
|
|
||||||
mode = POP();
|
mode = POP();
|
||||||
size = POP();
|
size = POP();
|
||||||
@@ -276,7 +263,8 @@ mmu_map(void)
|
|||||||
phys = POP();
|
phys = POP();
|
||||||
phys <<= 32;
|
phys <<= 32;
|
||||||
phys |= POP();
|
phys |= POP();
|
||||||
map_pages(virt, size, phys, mode);
|
|
||||||
|
ofmem_map(phys, virt, size, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -294,22 +282,19 @@ dtlb_demap(unsigned long vaddr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
unmap_pages(unsigned long virt, unsigned long size)
|
unmap_pages(ucell virt, ucell size)
|
||||||
{
|
{
|
||||||
unsigned long phys, data;
|
ucell va;
|
||||||
|
|
||||||
unsigned long currsize;
|
/* align address to 8k */
|
||||||
|
virt &= ~PAGE_MASK_8K;
|
||||||
|
|
||||||
// align size
|
/* align size to 8k */
|
||||||
size = (size + PAGE_MASK_8K) & ~PAGE_MASK_8K;
|
size = (size + PAGE_MASK_8K) & ~PAGE_MASK_8K;
|
||||||
|
|
||||||
while (spitfire_translate(virt, &phys, &data, &currsize)) {
|
for (va = virt; va < virt + size; va += PAGE_SIZE_8K) {
|
||||||
|
itlb_demap(va);
|
||||||
itlb_demap(virt & ~0x1fffULL);
|
dtlb_demap(va);
|
||||||
dtlb_demap(virt & ~0x1fffULL);
|
|
||||||
|
|
||||||
size -= currsize;
|
|
||||||
virt += currsize;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -325,11 +310,11 @@ void ofmem_unmap_pages(ucell virt, ucell size)
|
|||||||
static void
|
static void
|
||||||
mmu_unmap(void)
|
mmu_unmap(void)
|
||||||
{
|
{
|
||||||
unsigned long virt, size;
|
ucell virt, size;
|
||||||
|
|
||||||
size = POP();
|
size = POP();
|
||||||
virt = POP();
|
virt = POP();
|
||||||
unmap_pages(virt, size);
|
ofmem_unmap(virt, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -339,13 +324,23 @@ mmu_unmap(void)
|
|||||||
static void
|
static void
|
||||||
mmu_claim(void)
|
mmu_claim(void)
|
||||||
{
|
{
|
||||||
unsigned long virt, size, align;
|
ucell virt=-1UL, size, align;
|
||||||
|
|
||||||
align = POP();
|
align = POP();
|
||||||
size = POP();
|
size = POP();
|
||||||
virt = POP();
|
if (!align) {
|
||||||
printk("claim virt = %lx size = %lx align = %lx\n", virt, size, align);
|
virt = POP();
|
||||||
PUSH(virt); // XXX
|
}
|
||||||
|
|
||||||
|
printk("claim virt=" FMT_ucellx " size=" FMT_ucellx " align=" FMT_ucellx
|
||||||
|
"\n",
|
||||||
|
virt, size, align);
|
||||||
|
|
||||||
|
virt = ofmem_claim_virt(virt, size, align);
|
||||||
|
|
||||||
|
printk("claimed virt=" FMT_ucellx "\n", virt);
|
||||||
|
|
||||||
|
PUSH(virt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -355,14 +350,63 @@ mmu_claim(void)
|
|||||||
static void
|
static void
|
||||||
mmu_release(void)
|
mmu_release(void)
|
||||||
{
|
{
|
||||||
unsigned long virt, size;
|
ucell virt, size;
|
||||||
|
|
||||||
size = POP();
|
size = POP();
|
||||||
virt = POP();
|
virt = POP();
|
||||||
printk("release virt = %lx size = %lx\n", virt, size);
|
printk("release virt=" FMT_ucellx " size=" FMT_ucellx "\n", virt, size);
|
||||||
// XXX
|
|
||||||
|
ofmem_release(virt, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ( phys size align --- base ) */
|
||||||
|
static void
|
||||||
|
mem_claim( void )
|
||||||
|
{
|
||||||
|
ucell phys=-1UL, size, align;
|
||||||
|
|
||||||
|
align = POP();
|
||||||
|
size = POP();
|
||||||
|
if (!align) {
|
||||||
|
phys = POP();
|
||||||
|
phys <<= 32;
|
||||||
|
phys |= POP();
|
||||||
|
}
|
||||||
|
|
||||||
|
printk("mem_claim phys=" FMT_ucellx " size=" FMT_ucellx
|
||||||
|
" align=" FMT_ucellx "\n",
|
||||||
|
phys, size, align);
|
||||||
|
|
||||||
|
phys = ofmem_claim_phys(phys, size, align);
|
||||||
|
|
||||||
|
printk("ofmem_claim_phys result phys=" FMT_ucellx "\n", phys);
|
||||||
|
|
||||||
|
ofmem_map(phys, phys, size, -1);
|
||||||
|
|
||||||
|
PUSH(phys >> 32);
|
||||||
|
PUSH(phys & 0xffffffffUL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ( phys size --- ) */
|
||||||
|
static void
|
||||||
|
mem_release( void )
|
||||||
|
{
|
||||||
|
ucell phys, size;
|
||||||
|
|
||||||
|
size = POP();
|
||||||
|
phys = POP();
|
||||||
|
printk("release virt=" FMT_ucellx " size=" FMT_ucellx "\n", phys, size);
|
||||||
|
|
||||||
|
ofmem_release(phys, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
DECLARE_NODE(memory, INSTALL_OPEN, 0, "/memory");
|
||||||
|
|
||||||
|
NODE_METHODS( memory ) = {
|
||||||
|
{ "claim", mem_claim },
|
||||||
|
{ "release", mem_release },
|
||||||
|
};
|
||||||
|
|
||||||
DECLARE_UNNAMED_NODE(mmu, INSTALL_OPEN, 0);
|
DECLARE_UNNAMED_NODE(mmu, INSTALL_OPEN, 0);
|
||||||
|
|
||||||
NODE_METHODS(mmu) = {
|
NODE_METHODS(mmu) = {
|
||||||
@@ -381,7 +425,10 @@ void ob_mmu_init(const char *cpuname, uint64_t ram_size)
|
|||||||
{
|
{
|
||||||
char nodebuff[256];
|
char nodebuff[256];
|
||||||
|
|
||||||
// MMU node
|
/* memory node */
|
||||||
|
REGISTER_NODE_METHODS(memory, "/memory");
|
||||||
|
|
||||||
|
/* MMU node */
|
||||||
snprintf(nodebuff, sizeof(nodebuff), "/%s", cpuname);
|
snprintf(nodebuff, sizeof(nodebuff), "/%s", cpuname);
|
||||||
push_str(nodebuff);
|
push_str(nodebuff);
|
||||||
fword("find-device");
|
fword("find-device");
|
||||||
@@ -397,6 +444,8 @@ void ob_mmu_init(const char *cpuname, uint64_t ram_size)
|
|||||||
|
|
||||||
REGISTER_NODE_METHODS(mmu, nodebuff);
|
REGISTER_NODE_METHODS(mmu, nodebuff);
|
||||||
|
|
||||||
|
ofmem_register(find_dev("/memory"), find_dev("/virtual-memory"));
|
||||||
|
|
||||||
push_str("/chosen");
|
push_str("/chosen");
|
||||||
fword("find-device");
|
fword("find-device");
|
||||||
|
|
||||||
@@ -409,7 +458,7 @@ void ob_mmu_init(const char *cpuname, uint64_t ram_size)
|
|||||||
push_str("/memory");
|
push_str("/memory");
|
||||||
fword("find-device");
|
fword("find-device");
|
||||||
|
|
||||||
// All memory: 0 to RAM_size
|
/* All memory: 0 to RAM_size */
|
||||||
PUSH(0);
|
PUSH(0);
|
||||||
fword("encode-int");
|
fword("encode-int");
|
||||||
PUSH(0);
|
PUSH(0);
|
||||||
@@ -424,108 +473,6 @@ void ob_mmu_init(const char *cpuname, uint64_t ram_size)
|
|||||||
push_str("reg");
|
push_str("reg");
|
||||||
fword("property");
|
fword("property");
|
||||||
|
|
||||||
// Available memory: 0 to va2pa(_start)
|
|
||||||
PUSH(0);
|
|
||||||
fword("encode-int");
|
|
||||||
PUSH(0);
|
|
||||||
fword("encode-int");
|
|
||||||
fword("encode+");
|
|
||||||
PUSH((va2pa((unsigned long)&_data) - 8192) >> 32);
|
|
||||||
fword("encode-int");
|
|
||||||
fword("encode+");
|
|
||||||
PUSH((va2pa((unsigned long)&_data) - 8192) & 0xffffffff);
|
|
||||||
fword("encode-int");
|
|
||||||
fword("encode+");
|
|
||||||
push_str("available");
|
|
||||||
fword("property");
|
|
||||||
|
|
||||||
// XXX
|
|
||||||
// Translations
|
|
||||||
push_str("/virtual-memory");
|
|
||||||
fword("find-device");
|
|
||||||
|
|
||||||
// 0 to 16M: 1:1
|
|
||||||
PUSH(0);
|
|
||||||
fword("encode-int");
|
|
||||||
PUSH(0);
|
|
||||||
fword("encode-int");
|
|
||||||
fword("encode+");
|
|
||||||
PUSH(0);
|
|
||||||
fword("encode-int");
|
|
||||||
fword("encode+");
|
|
||||||
PUSH(16 * 1024 * 1024);
|
|
||||||
fword("encode-int");
|
|
||||||
fword("encode+");
|
|
||||||
PUSH(0x80000000);
|
|
||||||
fword("encode-int");
|
|
||||||
fword("encode+");
|
|
||||||
PUSH(0x00000036);
|
|
||||||
fword("encode-int");
|
|
||||||
fword("encode+");
|
|
||||||
|
|
||||||
// _start to _data: ROM used
|
|
||||||
PUSH(0);
|
|
||||||
fword("encode-int");
|
|
||||||
fword("encode+");
|
|
||||||
PUSH((unsigned long)&_start);
|
|
||||||
fword("encode-int");
|
|
||||||
fword("encode+");
|
|
||||||
PUSH(0);
|
|
||||||
fword("encode-int");
|
|
||||||
fword("encode+");
|
|
||||||
PUSH((unsigned long)&_data - (unsigned long)&_start);
|
|
||||||
fword("encode-int");
|
|
||||||
fword("encode+");
|
|
||||||
PUSH(0x800001ff);
|
|
||||||
fword("encode-int");
|
|
||||||
fword("encode+");
|
|
||||||
PUSH(0xf0000074);
|
|
||||||
fword("encode-int");
|
|
||||||
fword("encode+");
|
|
||||||
|
|
||||||
// _data to _end: end of RAM
|
|
||||||
PUSH(0);
|
|
||||||
fword("encode-int");
|
|
||||||
fword("encode+");
|
|
||||||
PUSH((unsigned long)&_data);
|
|
||||||
fword("encode-int");
|
|
||||||
fword("encode+");
|
|
||||||
PUSH(0);
|
|
||||||
fword("encode-int");
|
|
||||||
fword("encode+");
|
|
||||||
PUSH((unsigned long)&_data - (unsigned long)&_start);
|
|
||||||
fword("encode-int");
|
|
||||||
fword("encode+");
|
|
||||||
PUSH(((va2pa((unsigned long)&_data) - 8192) >> 32) | 0x80000000);
|
|
||||||
fword("encode-int");
|
|
||||||
fword("encode+");
|
|
||||||
PUSH(((va2pa((unsigned long)&_data) - 8192) & 0xffffffff) | 0x36);
|
|
||||||
fword("encode-int");
|
|
||||||
fword("encode+");
|
|
||||||
|
|
||||||
// VGA buffer (128k): 1:1
|
|
||||||
PUSH(0x1ff);
|
|
||||||
fword("encode-int");
|
|
||||||
fword("encode+");
|
|
||||||
PUSH(0x004a0000);
|
|
||||||
fword("encode-int");
|
|
||||||
fword("encode+");
|
|
||||||
PUSH(0);
|
|
||||||
fword("encode-int");
|
|
||||||
fword("encode+");
|
|
||||||
PUSH(128 * 1024);
|
|
||||||
fword("encode-int");
|
|
||||||
fword("encode+");
|
|
||||||
PUSH(0x800001ff);
|
|
||||||
fword("encode-int");
|
|
||||||
fword("encode+");
|
|
||||||
PUSH(0x004a0076);
|
|
||||||
fword("encode-int");
|
|
||||||
fword("encode+");
|
|
||||||
|
|
||||||
push_str("translations");
|
|
||||||
fword("property");
|
|
||||||
|
|
||||||
push_str("/openprom/client-services");
|
push_str("/openprom/client-services");
|
||||||
fword("find-device");
|
fword("find-device");
|
||||||
bind_func("claim", mmu_claim);
|
bind_func("claim", mmu_claim);
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#define NO_QEMU_PROTOS
|
#define NO_QEMU_PROTOS
|
||||||
#include "openbios/fw_cfg.h"
|
#include "openbios/fw_cfg.h"
|
||||||
#include "video_subr.h"
|
#include "video_subr.h"
|
||||||
|
#include "ofmem.h"
|
||||||
|
|
||||||
#define UUID_FMT "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x"
|
#define UUID_FMT "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x"
|
||||||
|
|
||||||
@@ -495,6 +496,8 @@ int openbios(void)
|
|||||||
printk("OpenBIOS for Sparc64\n");
|
printk("OpenBIOS for Sparc64\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
ofmem_init();
|
||||||
|
|
||||||
collect_sys_info(&sys_info);
|
collect_sys_info(&sys_info);
|
||||||
|
|
||||||
dict = malloc(DICTIONARY_SIZE);
|
dict = malloc(DICTIONARY_SIZE);
|
||||||
|
|||||||
@@ -27,11 +27,12 @@
|
|||||||
|
|
||||||
new-device
|
new-device
|
||||||
" memory" device-name
|
" memory" device-name
|
||||||
|
" memory" device-type
|
||||||
external
|
external
|
||||||
: open true ;
|
: open true ;
|
||||||
: close ;
|
: close ;
|
||||||
\ claim ( phys size align -- base )
|
\ claim ( phys size align -- base )
|
||||||
: claim 2drop ;
|
\ : claim 2drop ;
|
||||||
\ release ( phys size -- )
|
\ release ( phys size -- )
|
||||||
finish-device
|
finish-device
|
||||||
|
|
||||||
@@ -41,7 +42,7 @@ new-device
|
|||||||
: open true ;
|
: open true ;
|
||||||
: close ;
|
: close ;
|
||||||
\ claim ( phys size align -- base )
|
\ claim ( phys size align -- base )
|
||||||
: claim 2drop ;
|
\ : claim 2drop ;
|
||||||
\ release ( phys size -- )
|
\ release ( phys size -- )
|
||||||
finish-device
|
finish-device
|
||||||
|
|
||||||
|
|||||||
@@ -101,6 +101,8 @@ trap_table:
|
|||||||
ba bug; mov lvl, %g1; nop; nop; nop; nop; nop; nop;
|
ba bug; mov lvl, %g1; nop; nop; nop; nop; nop; nop;
|
||||||
#define BTRAPTL1(lvl) BTRAP(lvl)
|
#define BTRAPTL1(lvl) BTRAP(lvl)
|
||||||
#define BTRAPS(x) BTRAP(x) BTRAP(x+1) BTRAP(x+2) BTRAP(x+3) BTRAP(x+4) BTRAP(x+5) BTRAP(x+6) BTRAP(x+7)
|
#define BTRAPS(x) BTRAP(x) BTRAP(x+1) BTRAP(x+2) BTRAP(x+3) BTRAP(x+4) BTRAP(x+5) BTRAP(x+6) BTRAP(x+7)
|
||||||
|
#define BTRAPS4(x) BTRAP(x) BTRAP(x+1) BTRAP(x+2) BTRAP(x+3)
|
||||||
|
#define TRAP_HANDLER(routine) ba routine; nop; nop; nop; nop; nop; nop; nop;
|
||||||
|
|
||||||
#define STACK_BIAS 2047
|
#define STACK_BIAS 2047
|
||||||
.globl sparc64_ttable_tl0, sparc64_ttable_tl1
|
.globl sparc64_ttable_tl0, sparc64_ttable_tl1
|
||||||
@@ -131,7 +133,16 @@ tl0_irq15: TRAP_IRQ(handler_irq, 15)
|
|||||||
BTRAPS(0x40) BTRAPS(0x48)
|
BTRAPS(0x40) BTRAPS(0x48)
|
||||||
#endif
|
#endif
|
||||||
BTRAPS(0x50) BTRAPS(0x58)
|
BTRAPS(0x50) BTRAPS(0x58)
|
||||||
BTRAPS(0x60) BTRAPS(0x68)
|
BTRAPS4(0x60)
|
||||||
|
TRAP_HANDLER(reload_IMMU_tlb) ! 0x64 : instruction_access_MMU_miss
|
||||||
|
TRAP_HANDLER(reload_IMMU_tlb) ! 0x65 : instruction_access_MMU_miss
|
||||||
|
TRAP_HANDLER(reload_IMMU_tlb) ! 0x66 : instruction_access_MMU_miss
|
||||||
|
TRAP_HANDLER(reload_IMMU_tlb) ! 0x67 : instruction_access_MMU_miss
|
||||||
|
TRAP_HANDLER(reload_DMMU_tlb) ! 0x68 : data_access_MMU_miss
|
||||||
|
TRAP_HANDLER(reload_DMMU_tlb) ! 0x69 : data_access_MMU_miss
|
||||||
|
TRAP_HANDLER(reload_DMMU_tlb) ! 0x6A : data_access_MMU_miss
|
||||||
|
TRAP_HANDLER(reload_DMMU_tlb) ! 0x6B : data_access_MMU_miss
|
||||||
|
BTRAPS4(0x6C) ! data_access_protection
|
||||||
BTRAPS(0x70) BTRAPS(0x78)
|
BTRAPS(0x70) BTRAPS(0x78)
|
||||||
tl0_s0n: SPILL_WINDOW
|
tl0_s0n: SPILL_WINDOW
|
||||||
tl0_s1n: SPILL_WINDOW
|
tl0_s1n: SPILL_WINDOW
|
||||||
@@ -206,7 +217,16 @@ tl1_irq15: TRAP_IRQ(handler_irq, 15)
|
|||||||
BTRAPS(0x40) BTRAPS(0x48)
|
BTRAPS(0x40) BTRAPS(0x48)
|
||||||
#endif
|
#endif
|
||||||
BTRAPS(0x50) BTRAPS(0x58)
|
BTRAPS(0x50) BTRAPS(0x58)
|
||||||
BTRAPS(0x60) BTRAPS(0x68)
|
BTRAPS4(0x60)
|
||||||
|
TRAP_HANDLER(reload_IMMU_tlb) ! 0x64 : instruction_access_MMU_miss
|
||||||
|
TRAP_HANDLER(reload_IMMU_tlb) ! 0x65 : instruction_access_MMU_miss
|
||||||
|
TRAP_HANDLER(reload_IMMU_tlb) ! 0x66 : instruction_access_MMU_miss
|
||||||
|
TRAP_HANDLER(reload_IMMU_tlb) ! 0x67 : instruction_access_MMU_miss
|
||||||
|
TRAP_HANDLER(reload_DMMU_tlb) ! 0x68 : data_access_MMU_miss
|
||||||
|
TRAP_HANDLER(reload_DMMU_tlb) ! 0x69 : data_access_MMU_miss
|
||||||
|
TRAP_HANDLER(reload_DMMU_tlb) ! 0x6A : data_access_MMU_miss
|
||||||
|
TRAP_HANDLER(reload_DMMU_tlb) ! 0x6B : data_access_MMU_miss
|
||||||
|
BTRAPS4(0x6C) ! data_access_protection
|
||||||
BTRAPS(0x70) BTRAPS(0x78)
|
BTRAPS(0x70) BTRAPS(0x78)
|
||||||
tl1_s0n: SPILL_WINDOW
|
tl1_s0n: SPILL_WINDOW
|
||||||
tl1_s1n: SPILL_WINDOW
|
tl1_s1n: SPILL_WINDOW
|
||||||
@@ -300,6 +320,86 @@ fill_32bit:
|
|||||||
restored
|
restored
|
||||||
retry
|
retry
|
||||||
|
|
||||||
|
.globl reload_DMMU_tlb, reload_IMMU_tlb
|
||||||
|
|
||||||
|
reload_DMMU_tlb:
|
||||||
|
mov 6 << 3, %g2 ! va = fault virtual address
|
||||||
|
ldxa [%g2] ASI_DMMU, %g1 ! from tag access register
|
||||||
|
|
||||||
|
srlx %g1, 13, %g1 ! %g1 = va rounded to 8k page
|
||||||
|
sllx %g1, 13, %g1 !
|
||||||
|
|
||||||
|
setx g_ofmem_translations, %g7, %g3
|
||||||
|
ldx [%g3], %g3 ! translation_t* t = *g_ofmem_translations
|
||||||
|
dmmu_next_trans:
|
||||||
|
ldx [%g3], %g3
|
||||||
|
brz %g3, bug ! NULL pointer
|
||||||
|
nop
|
||||||
|
ldx [%g3+0x08], %g4 ! t->virt
|
||||||
|
sub %g1, %g4, %g7 ! %g7 offset = va - t->virt
|
||||||
|
brlz %g7, dmmu_next_trans ! va < t->virt ?
|
||||||
|
nop
|
||||||
|
ldx [%g3+0x10], %g4 ! t->size
|
||||||
|
sub %g7, %g4, %g4 ! va >= t->virt - t->size ?
|
||||||
|
brgez %g4, dmmu_next_trans
|
||||||
|
nop
|
||||||
|
|
||||||
|
! install 8k tlb entry
|
||||||
|
|
||||||
|
ldx [%g3+0x18], %g4 ! t->phys
|
||||||
|
add %g4, %g7, %g4 ! %g4 page physical address = t->phys + offset
|
||||||
|
ldx [%g3+0x20], %g5 ! t->mode
|
||||||
|
|
||||||
|
set 0x80000000, %g2 ! valid tte, 8k size
|
||||||
|
sllx %g2, 32, %g2
|
||||||
|
or %g2, %g5, %g2 ! mix in translation mode
|
||||||
|
or %g2, %g4, %g3 ! mix in phys addr mode
|
||||||
|
|
||||||
|
mov 6 << 3, %g2 ! page virtual address
|
||||||
|
stxa %g1, [%g2] ASI_DMMU !
|
||||||
|
stxa %g3, [%g0] ASI_DTLB_DATA_IN
|
||||||
|
|
||||||
|
retry
|
||||||
|
|
||||||
|
reload_IMMU_tlb:
|
||||||
|
mov 6 << 3, %g2 ! va = fault virtual address
|
||||||
|
ldxa [%g2] ASI_IMMU, %g1 ! from tag access register
|
||||||
|
|
||||||
|
srlx %g1, 13, %g1 ! %g1 = va rounded to 8k page
|
||||||
|
sllx %g1, 13, %g1 !
|
||||||
|
|
||||||
|
setx g_ofmem_translations, %g7, %g3
|
||||||
|
ldx [%g3], %g3 ! translation_t* t = *g_ofmem_translations
|
||||||
|
immu_next_trans:
|
||||||
|
ldx [%g3], %g3
|
||||||
|
brz %g3, bug ! NULL pointer
|
||||||
|
nop
|
||||||
|
ldx [%g3+0x08], %g4 ! t->virt
|
||||||
|
sub %g1, %g4, %g7 ! %g7 offset = va - t->virt
|
||||||
|
brlz %g7, immu_next_trans ! va < t->virt ?
|
||||||
|
nop
|
||||||
|
ldx [%g3+0x10], %g4 ! t->size
|
||||||
|
sub %g7, %g4, %g4 ! va >= t->virt - t->size ?
|
||||||
|
brgez %g4, immu_next_trans
|
||||||
|
nop
|
||||||
|
|
||||||
|
! install 8k tlb entry
|
||||||
|
|
||||||
|
ldx [%g3+0x18], %g4 ! t->phys
|
||||||
|
add %g4, %g7, %g4 ! %g4 page physical address = t->phys + offset
|
||||||
|
ldx [%g3+0x20], %g5 ! t->mode
|
||||||
|
|
||||||
|
set 0x80000000, %g2 ! valid tte, 8k size
|
||||||
|
sllx %g2, 32, %g2
|
||||||
|
or %g2, %g5, %g2 ! mix in translation mode
|
||||||
|
or %g2, %g4, %g3 ! mix in phys addr mode
|
||||||
|
|
||||||
|
mov 6 << 3, %g2 ! page virtual address
|
||||||
|
stxa %g1, [%g2] ASI_IMMU !
|
||||||
|
stxa %g3, [%g0] ASI_ITLB_DATA_IN
|
||||||
|
|
||||||
|
retry
|
||||||
|
|
||||||
__divide_error:
|
__divide_error:
|
||||||
bug:
|
bug:
|
||||||
/* Dump the exception and its context */
|
/* Dump the exception and its context */
|
||||||
|
|||||||
Reference in New Issue
Block a user