--- Gnu-Mach/i386/i386at/model_dep.c 2020/09/02 04:42:07 1.1.1.2 +++ Gnu-Mach/i386/i386at/model_dep.c 2020/09/02 04:44:34 1.1.1.3 @@ -1,25 +1,25 @@ -/* +/* * Mach Operating System * Copyright (c) 1991,1990,1989, 1988 Carnegie Mellon University * All Rights Reserved. - * + * * Permission to use, copy, modify and distribute this software and its * documentation is hereby granted, provided that both the copyright * notice and this permission notice appear in all copies of the * software, derivative works or modified versions, and any portions * thereof, and that both notices appear in supporting documentation. - * + * * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * + * * Carnegie Mellon requests users of this software to return to - * + * * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU * School of Computer Science * Carnegie Mellon University * Pittsburgh PA 15213-3890 - * + * * any improvements or extensions that they make and grant Carnegie Mellon * the rights to redistribute these changes. */ @@ -42,6 +42,8 @@ #include "vm_param.h" #include +#include +#include #include #include #include @@ -65,7 +67,8 @@ vm_offset_t phys_last_addr; /* Virtual address of physical memory, for the kvtophys/phystokv macros. */ vm_offset_t phys_mem_va; -struct multiboot_info *boot_info; +/* A copy of the multiboot info structure passed by the boot loader. */ +struct multiboot_info boot_info; /* Command line supplied to kernel. */ char *kernel_cmdline = ""; @@ -84,13 +87,13 @@ static vm_size_t avail_remaining; if zero, only use physical memory in the low 16MB of addresses. Only SCSI still has DMA problems. */ #ifdef LINUX_DEV -int use_all_mem = 1; +#define use_all_mem 1 #else #include "nscsi.h" #if NSCSI > 0 -int use_all_mem = 0; +#define use_all_mem 0 #else -int use_all_mem = 1; +#define use_all_mem 1 #endif #endif @@ -98,6 +101,9 @@ extern char version[]; extern void setup_main(); +void halt_all_cpu (boolean_t reboot) __attribute__ ((noreturn)); +void halt_cpu (void) __attribute__ ((noreturn)); + void inittodr(); /* forward */ int rebootflag = 0; /* exported to kdintr */ @@ -152,10 +158,17 @@ void machine_init() pmap_unmap_page_zero(); } +/* Conserve power on processor CPU. */ +void machine_idle (int cpu) +{ + assert (cpu == cpu_number ()); + asm volatile ("hlt" : : : "memory"); +} + /* * Halt a cpu. */ -halt_cpu() +void halt_cpu(void) { asm volatile("cli"); while(1); @@ -164,7 +177,7 @@ halt_cpu() /* * Halt the system or reboot. */ -halt_all_cpus(reboot) +void halt_all_cpus(reboot) boolean_t reboot; { if (reboot) { @@ -200,9 +213,9 @@ mem_size_init() XX make it a constant. */ phys_first_addr = 0; - phys_last_addr = 0x100000 + (boot_info->mem_upper * 0x400); + phys_last_addr = 0x100000 + (boot_info.mem_upper * 0x400); avail_remaining - = phys_last_addr - (0x100000 - (boot_info->mem_lower * 0x400) + = phys_last_addr - (0x100000 - (boot_info.mem_lower * 0x400) - 0x1000); printf("AT386 boot: physical memory from 0x%x to 0x%x\n", @@ -292,7 +305,7 @@ i386at_init() void c_boot_entry(vm_offset_t bi) { /* Stash the boot_image_info pointer. */ - boot_info = (struct multiboot_info*)phystokv(bi); + boot_info = *(struct multiboot_info*)phystokv(bi); /* XXX we currently assume phys_mem_va is always 0 here - if it isn't, we must tweak the pointers in the boot_info. */ @@ -304,8 +317,8 @@ void c_boot_entry(vm_offset_t bi) printf("\n"); /* Find the kernel command line, if there is one. */ - if (boot_info->flags & MULTIBOOT_CMDLINE) - kernel_cmdline = (char*)phystokv(boot_info->cmdline); + if (boot_info.flags & MULTIBOOT_CMDLINE) + kernel_cmdline = (char*)phystokv(boot_info.cmdline); #if MACH_KDB /* @@ -313,21 +326,21 @@ void c_boot_entry(vm_offset_t bi) * We need to do this before i386at_init() * so that the symbol table's memory won't be stomped on. */ - if ((boot_info->flags & MULTIBOOT_AOUT_SYMS) - && boot_info->syms.a.addr) + if ((boot_info.flags & MULTIBOOT_AOUT_SYMS) + && boot_info.syms.a.addr) { vm_size_t symtab_size, strtab_size; - kern_sym_start = (vm_offset_t)phystokv(boot_info->syms.a.addr); - symtab_size = (vm_offset_t)phystokv(boot_info->syms.a.tabsize); - strtab_size = (vm_offset_t)phystokv(boot_info->syms.a.strsize); + kern_sym_start = (vm_offset_t)phystokv(boot_info.syms.a.addr); + symtab_size = (vm_offset_t)phystokv(boot_info.syms.a.tabsize); + strtab_size = (vm_offset_t)phystokv(boot_info.syms.a.strsize); kern_sym_end = kern_sym_start + 4 + symtab_size + strtab_size; printf("kernel symbol table at %08x-%08x (%d,%d)\n", kern_sym_start, kern_sym_end, symtab_size, strtab_size); } -#endif MACH_KDB +#endif /* MACH_KDB */ /* * Do basic VM initialization @@ -353,7 +366,7 @@ void c_boot_entry(vm_offset_t bi) cninit(); /* need console for debugger */ Debugger(); } -#endif MACH_KDB +#endif /* MACH_KDB */ machine_slot[0].is_cpu = TRUE; machine_slot[0].running = TRUE; @@ -378,7 +391,7 @@ void c_boot_entry(vm_offset_t bi) } #else machine_slot[0].cpu_type = CPU_TYPE_I386; -#endif +#endif /* @@ -399,7 +412,7 @@ timemmap(dev,off,prot) #ifdef lint dev++; off++; -#endif lint +#endif /* lint */ if (prot & VM_PROT_WRITE) return (-1); @@ -440,26 +453,25 @@ unsigned int pmap_free_pages() } /* Always returns page-aligned regions. */ -boolean_t +static boolean_t init_alloc_aligned(vm_size_t size, vm_offset_t *addrp) { vm_offset_t addr; extern char start[], end[]; int i; + static int wrapped = 0; /* Memory regions to skip. */ - vm_offset_t boot_info_start_pa = kvtophys(boot_info); - vm_offset_t boot_info_end_pa = boot_info_start_pa + sizeof(*boot_info); - vm_offset_t cmdline_start_pa = boot_info->flags & MULTIBOOT_CMDLINE - ? boot_info->cmdline : 0; + vm_offset_t cmdline_start_pa = boot_info.flags & MULTIBOOT_CMDLINE + ? boot_info.cmdline : 0; vm_offset_t cmdline_end_pa = cmdline_start_pa ? cmdline_start_pa+strlen((char*)phystokv(cmdline_start_pa))+1 : 0; - vm_offset_t mods_start_pa = boot_info->flags & MULTIBOOT_MODS - ? boot_info->mods_addr : 0; + vm_offset_t mods_start_pa = boot_info.flags & MULTIBOOT_MODS + ? boot_info.mods_addr : 0; vm_offset_t mods_end_pa = mods_start_pa ? mods_start_pa - + boot_info->mods_count * sizeof(struct multiboot_module) + + boot_info.mods_count * sizeof(struct multiboot_module) : 0; retry: @@ -467,8 +479,25 @@ init_alloc_aligned(vm_size_t size, vm_of /* Page-align the start address. */ avail_next = round_page(avail_next); + /* Start with memory above 16MB, reserving the low memory for later. */ + if (use_all_mem && !wrapped && phys_last_addr > 16 * 1024*1024) + { + if (avail_next < 16 * 1024*1024) + avail_next = 16 * 1024*1024; + else if (avail_next == phys_last_addr) + { + /* We have used all the memory above 16MB, so now start on + the low memory. This will wind up at the end of the list + of free pages, so it should not have been allocated to any + other use in early initialization before the Linux driver + glue initialization needs to allocate low memory. */ + avail_next = 0x1000; + wrapped = 1; + } + } + /* Check if we have reached the end of memory. */ - if (avail_next == phys_last_addr) + if (avail_next == (wrapped ? 16 * 1024*1024 : phys_last_addr)) return FALSE; /* Tentatively assign the current location to the caller. */ @@ -479,7 +508,7 @@ init_alloc_aligned(vm_size_t size, vm_of avail_next += size; /* Skip past the I/O and ROM area. */ - if ((avail_next > (boot_info->mem_lower * 0x400)) && (addr < 0x100000)) + if ((avail_next > (boot_info.mem_lower * 0x400)) && (addr < 0x100000)) { avail_next = 0x100000; goto retry; @@ -491,18 +520,13 @@ init_alloc_aligned(vm_size_t size, vm_of } /* Skip our own kernel code, data, and bss. */ - if ((avail_next >= (vm_offset_t)start) && (addr < (vm_offset_t)end)) + if ((avail_next > (vm_offset_t)start) && (addr < (vm_offset_t)end)) { avail_next = (vm_offset_t)end; goto retry; } /* Skip any areas occupied by valuable boot_info data. */ - if ((avail_next > boot_info_start_pa) && (addr < boot_info_end_pa)) - { - avail_next = boot_info_end_pa; - goto retry; - } if ((avail_next > cmdline_start_pa) && (addr < cmdline_end_pa)) { avail_next = cmdline_end_pa; @@ -518,11 +542,11 @@ init_alloc_aligned(vm_size_t size, vm_of avail_next = kern_sym_end; goto retry; } - if (boot_info->flags & MULTIBOOT_MODS) + if (boot_info.flags & MULTIBOOT_MODS) { struct multiboot_module *m = (struct multiboot_module *) - phystokv(boot_info->mods_addr); - for (i = 0; i < boot_info->mods_count; i++) + phystokv(boot_info.mods_addr); + for (i = 0; i < boot_info.mods_count; i++) { if ((avail_next > m[i].mod_start) && (addr < m[i].mod_end)) @@ -563,7 +587,7 @@ boolean_t pmap_valid_page(x) { /* XXX is this OK? What does it matter for? */ return (((phys_first_addr <= x) && (x < phys_last_addr)) && - !(((boot_info->mem_lower * 1024) <= x) && (x < 1024*1024))); + !(((boot_info.mem_lower * 1024) <= x) && (x < 1024*1024))); } #ifndef NBBY