diff options
Diffstat (limited to 'arch/sparc64')
-rw-r--r-- | arch/sparc64/mm/init.c | 114 |
1 files changed, 15 insertions, 99 deletions
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index 598bfb3b0053..92d095802958 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c | |||
@@ -43,7 +43,7 @@ extern void device_scan(void); | |||
43 | 43 | ||
44 | struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS]; | 44 | struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS]; |
45 | 45 | ||
46 | unsigned long *sparc64_valid_addr_bitmap; | 46 | unsigned long *sparc64_valid_addr_bitmap __read_mostly; |
47 | 47 | ||
48 | /* Ugly, but necessary... -DaveM */ | 48 | /* Ugly, but necessary... -DaveM */ |
49 | unsigned long phys_base __read_mostly; | 49 | unsigned long phys_base __read_mostly; |
@@ -51,15 +51,6 @@ unsigned long kern_base __read_mostly; | |||
51 | unsigned long kern_size __read_mostly; | 51 | unsigned long kern_size __read_mostly; |
52 | unsigned long pfn_base __read_mostly; | 52 | unsigned long pfn_base __read_mostly; |
53 | 53 | ||
54 | /* This is even uglier. We have a problem where the kernel may not be | ||
55 | * located at phys_base. However, initial __alloc_bootmem() calls need to | ||
56 | * be adjusted to be within the 4-8Megs that the kernel is mapped to, else | ||
57 | * those page mappings wont work. Things are ok after inherit_prom_mappings | ||
58 | * is called though. Dave says he'll clean this up some other time. | ||
59 | * -- BenC | ||
60 | */ | ||
61 | static unsigned long bootmap_base; | ||
62 | |||
63 | /* get_new_mmu_context() uses "cache + 1". */ | 54 | /* get_new_mmu_context() uses "cache + 1". */ |
64 | DEFINE_SPINLOCK(ctx_alloc_lock); | 55 | DEFINE_SPINLOCK(ctx_alloc_lock); |
65 | unsigned long tlb_context_cache = CTX_FIRST_VERSION - 1; | 56 | unsigned long tlb_context_cache = CTX_FIRST_VERSION - 1; |
@@ -1415,8 +1406,6 @@ unsigned long __init bootmem_init(unsigned long *pages_avail) | |||
1415 | #endif | 1406 | #endif |
1416 | bootmap_size = init_bootmem_node(NODE_DATA(0), bootmap_pfn, pfn_base, end_pfn); | 1407 | bootmap_size = init_bootmem_node(NODE_DATA(0), bootmap_pfn, pfn_base, end_pfn); |
1417 | 1408 | ||
1418 | bootmap_base = bootmap_pfn << PAGE_SHIFT; | ||
1419 | |||
1420 | /* Now register the available physical memory with the | 1409 | /* Now register the available physical memory with the |
1421 | * allocator. | 1410 | * allocator. |
1422 | */ | 1411 | */ |
@@ -1475,89 +1464,22 @@ static unsigned long last_valid_pfn; | |||
1475 | void __init paging_init(void) | 1464 | void __init paging_init(void) |
1476 | { | 1465 | { |
1477 | extern pmd_t swapper_pmd_dir[1024]; | 1466 | extern pmd_t swapper_pmd_dir[1024]; |
1478 | unsigned long alias_base = kern_base + PAGE_OFFSET; | 1467 | unsigned long end_pfn, pages_avail, shift; |
1479 | unsigned long second_alias_page = 0; | ||
1480 | unsigned long pt, flags, end_pfn, pages_avail; | ||
1481 | unsigned long shift = alias_base - ((unsigned long)KERNBASE); | ||
1482 | unsigned long real_end; | 1468 | unsigned long real_end; |
1483 | 1469 | ||
1484 | set_bit(0, mmu_context_bmap); | 1470 | set_bit(0, mmu_context_bmap); |
1485 | 1471 | ||
1472 | shift = kern_base + PAGE_OFFSET - ((unsigned long)KERNBASE); | ||
1473 | |||
1486 | real_end = (unsigned long)_end; | 1474 | real_end = (unsigned long)_end; |
1487 | if ((real_end > ((unsigned long)KERNBASE + 0x400000))) | 1475 | if ((real_end > ((unsigned long)KERNBASE + 0x400000))) |
1488 | bigkernel = 1; | 1476 | bigkernel = 1; |
1489 | #ifdef CONFIG_BLK_DEV_INITRD | 1477 | if ((real_end > ((unsigned long)KERNBASE + 0x800000))) { |
1490 | if (sparc_ramdisk_image || sparc_ramdisk_image64) | 1478 | prom_printf("paging_init: Kernel > 8MB, too large.\n"); |
1491 | real_end = (PAGE_ALIGN(real_end) + PAGE_ALIGN(sparc_ramdisk_size)); | 1479 | prom_halt(); |
1492 | #endif | ||
1493 | |||
1494 | /* We assume physical memory starts at some 4mb multiple, | ||
1495 | * if this were not true we wouldn't boot up to this point | ||
1496 | * anyways. | ||
1497 | */ | ||
1498 | pt = kern_base | _PAGE_VALID | _PAGE_SZ4MB; | ||
1499 | pt |= _PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W; | ||
1500 | local_irq_save(flags); | ||
1501 | if (tlb_type == spitfire) { | ||
1502 | __asm__ __volatile__( | ||
1503 | " stxa %1, [%0] %3\n" | ||
1504 | " stxa %2, [%5] %4\n" | ||
1505 | " membar #Sync\n" | ||
1506 | " flush %%g6\n" | ||
1507 | " nop\n" | ||
1508 | " nop\n" | ||
1509 | " nop\n" | ||
1510 | : /* No outputs */ | ||
1511 | : "r" (TLB_TAG_ACCESS), "r" (alias_base), "r" (pt), | ||
1512 | "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), "r" (61 << 3) | ||
1513 | : "memory"); | ||
1514 | if (real_end >= KERNBASE + 0x340000) { | ||
1515 | second_alias_page = alias_base + 0x400000; | ||
1516 | __asm__ __volatile__( | ||
1517 | " stxa %1, [%0] %3\n" | ||
1518 | " stxa %2, [%5] %4\n" | ||
1519 | " membar #Sync\n" | ||
1520 | " flush %%g6\n" | ||
1521 | " nop\n" | ||
1522 | " nop\n" | ||
1523 | " nop\n" | ||
1524 | : /* No outputs */ | ||
1525 | : "r" (TLB_TAG_ACCESS), "r" (second_alias_page), "r" (pt + 0x400000), | ||
1526 | "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), "r" (60 << 3) | ||
1527 | : "memory"); | ||
1528 | } | ||
1529 | } else if (tlb_type == cheetah || tlb_type == cheetah_plus) { | ||
1530 | __asm__ __volatile__( | ||
1531 | " stxa %1, [%0] %3\n" | ||
1532 | " stxa %2, [%5] %4\n" | ||
1533 | " membar #Sync\n" | ||
1534 | " flush %%g6\n" | ||
1535 | " nop\n" | ||
1536 | " nop\n" | ||
1537 | " nop\n" | ||
1538 | : /* No outputs */ | ||
1539 | : "r" (TLB_TAG_ACCESS), "r" (alias_base), "r" (pt), | ||
1540 | "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), "r" ((0<<16) | (13<<3)) | ||
1541 | : "memory"); | ||
1542 | if (real_end >= KERNBASE + 0x340000) { | ||
1543 | second_alias_page = alias_base + 0x400000; | ||
1544 | __asm__ __volatile__( | ||
1545 | " stxa %1, [%0] %3\n" | ||
1546 | " stxa %2, [%5] %4\n" | ||
1547 | " membar #Sync\n" | ||
1548 | " flush %%g6\n" | ||
1549 | " nop\n" | ||
1550 | " nop\n" | ||
1551 | " nop\n" | ||
1552 | : /* No outputs */ | ||
1553 | : "r" (TLB_TAG_ACCESS), "r" (second_alias_page), "r" (pt + 0x400000), | ||
1554 | "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), "r" ((0<<16) | (12<<3)) | ||
1555 | : "memory"); | ||
1556 | } | ||
1557 | } | 1480 | } |
1558 | local_irq_restore(flags); | 1481 | |
1559 | 1482 | /* Set kernel pgd to upper alias so physical page computations | |
1560 | /* Now set kernel pgd to upper alias so physical page computations | ||
1561 | * work. | 1483 | * work. |
1562 | */ | 1484 | */ |
1563 | init_mm.pgd += ((shift) / (sizeof(pgd_t))); | 1485 | init_mm.pgd += ((shift) / (sizeof(pgd_t))); |
@@ -1568,15 +1490,11 @@ void __init paging_init(void) | |||
1568 | pud_set(pud_offset(&swapper_pg_dir[0], 0), | 1490 | pud_set(pud_offset(&swapper_pg_dir[0], 0), |
1569 | swapper_pmd_dir + (shift / sizeof(pgd_t))); | 1491 | swapper_pmd_dir + (shift / sizeof(pgd_t))); |
1570 | 1492 | ||
1571 | swapper_pgd_zero = pgd_val(init_mm.pgd[0]); | 1493 | swapper_pgd_zero = pgd_val(swapper_pg_dir[0]); |
1572 | 1494 | ||
1573 | /* Inherit non-locked OBP mappings. */ | 1495 | /* Inherit non-locked OBP mappings. */ |
1574 | inherit_prom_mappings(); | 1496 | inherit_prom_mappings(); |
1575 | 1497 | ||
1576 | /* Setup bootmem... */ | ||
1577 | pages_avail = 0; | ||
1578 | last_valid_pfn = end_pfn = bootmem_init(&pages_avail); | ||
1579 | |||
1580 | /* Ok, we can use our TLB miss and window trap handlers safely. | 1498 | /* Ok, we can use our TLB miss and window trap handlers safely. |
1581 | * We need to do a quick peek here to see if we are on StarFire | 1499 | * We need to do a quick peek here to see if we are on StarFire |
1582 | * or not, so setup_tba can setup the IRQ globals correctly (it | 1500 | * or not, so setup_tba can setup the IRQ globals correctly (it |
@@ -1589,13 +1507,12 @@ void __init paging_init(void) | |||
1589 | 1507 | ||
1590 | inherit_locked_prom_mappings(1); | 1508 | inherit_locked_prom_mappings(1); |
1591 | 1509 | ||
1592 | /* We only created DTLB mapping of this stuff. */ | ||
1593 | spitfire_flush_dtlb_nucleus_page(alias_base); | ||
1594 | if (second_alias_page) | ||
1595 | spitfire_flush_dtlb_nucleus_page(second_alias_page); | ||
1596 | |||
1597 | __flush_tlb_all(); | 1510 | __flush_tlb_all(); |
1598 | 1511 | ||
1512 | /* Setup bootmem... */ | ||
1513 | pages_avail = 0; | ||
1514 | last_valid_pfn = end_pfn = bootmem_init(&pages_avail); | ||
1515 | |||
1599 | { | 1516 | { |
1600 | unsigned long zones_size[MAX_NR_ZONES]; | 1517 | unsigned long zones_size[MAX_NR_ZONES]; |
1601 | unsigned long zholes_size[MAX_NR_ZONES]; | 1518 | unsigned long zholes_size[MAX_NR_ZONES]; |
@@ -1757,8 +1674,7 @@ void __init mem_init(void) | |||
1757 | 1674 | ||
1758 | i = last_valid_pfn >> ((22 - PAGE_SHIFT) + 6); | 1675 | i = last_valid_pfn >> ((22 - PAGE_SHIFT) + 6); |
1759 | i += 1; | 1676 | i += 1; |
1760 | sparc64_valid_addr_bitmap = (unsigned long *) | 1677 | sparc64_valid_addr_bitmap = (unsigned long *) alloc_bootmem(i << 3); |
1761 | __alloc_bootmem(i << 3, SMP_CACHE_BYTES, bootmap_base); | ||
1762 | if (sparc64_valid_addr_bitmap == NULL) { | 1678 | if (sparc64_valid_addr_bitmap == NULL) { |
1763 | prom_printf("mem_init: Cannot alloc valid_addr_bitmap.\n"); | 1679 | prom_printf("mem_init: Cannot alloc valid_addr_bitmap.\n"); |
1764 | prom_halt(); | 1680 | prom_halt(); |