Date: Sat, 4 Oct 2014 06:01:31 +0000 (UTC) From: Takahashi Yoshihiro <nyan@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r272492 - in head/sys: conf i386/i386 pc98/pc98 Message-ID: <201410040601.s9461Vxk041359@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: nyan Date: Sat Oct 4 06:01:30 2014 New Revision: 272492 URL: https://svnweb.freebsd.org/changeset/base/272492 Log: Merge pc98's machdep.c into i386/i386/machdep.c. Deleted: head/sys/pc98/pc98/machdep.c Modified: head/sys/conf/files.pc98 head/sys/i386/i386/machdep.c Modified: head/sys/conf/files.pc98 ============================================================================== --- head/sys/conf/files.pc98 Sat Oct 4 05:03:39 2014 (r272491) +++ head/sys/conf/files.pc98 Sat Oct 4 06:01:30 2014 (r272492) @@ -149,6 +149,7 @@ i386/i386/initcpu.c standard i386/i386/io.c optional io i386/i386/k6_mem.c optional mem i386/i386/locore.s standard no-obj +i386/i386/machdep.c standard i386/i386/mem.c optional mem i386/i386/minidump_machdep.c standard i386/i386/mp_clock.c optional smp @@ -237,7 +238,6 @@ pc98/pc98/busiosubr.c standard pc98/pc98/canbepm.c optional canbepm pc98/pc98/canbus.c optional canbus pc98/pc98/canbus_if.m optional canbus -pc98/pc98/machdep.c standard pc98/pc98/pc98_machdep.c standard # # x86 shared code between IA32, AMD64 and PC98 architectures Modified: head/sys/i386/i386/machdep.c ============================================================================== --- head/sys/i386/i386/machdep.c Sat Oct 4 05:03:39 2014 (r272491) +++ head/sys/i386/i386/machdep.c Sat Oct 4 06:01:30 2014 (r272492) @@ -109,7 +109,11 @@ __FBSDID("$FreeBSD$"); #include <ddb/db_sym.h> #endif +#ifdef PC98 +#include <pc98/pc98/pc98_machdep.h> +#else #include <isa/rtc.h> +#endif #include <net/netisr.h> @@ -204,6 +208,14 @@ SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, int _udatasel, _ucodesel; u_int basemem; +#ifdef PC98 +int need_pre_dma_flush; /* If 1, use wbinvd befor DMA transfer. */ +int need_post_dma_flush; /* If 1, use invd after DMA transfer. */ + +static int ispc98 = 1; +SYSCTL_INT(_machdep, OID_AUTO, ispc98, CTLFLAG_RD, &ispc98, 0, ""); +#endif + int cold = 1; #ifdef COMPAT_43 @@ -259,7 +271,8 @@ cpu_startup(dummy) { uintmax_t memsize; char *sysenv; - + +#ifndef PC98 /* * On MacBooks, we need to disallow the legacy USB circuit to * generate an SMI# because this can cause several problems, @@ -285,6 +298,7 @@ cpu_startup(dummy) } freeenv(sysenv); } +#endif /* !PC98 */ /* * Good {morning,afternoon,evening,night}. @@ -1235,6 +1249,7 @@ SYSCTL_INT(_machdep, OID_AUTO, idle_mwai #define STATE_MWAIT 0x1 #define STATE_SLEEPING 0x2 +#ifndef PC98 static void cpu_idle_acpi(sbintime_t sbt) { @@ -1253,6 +1268,7 @@ cpu_idle_acpi(sbintime_t sbt) __asm __volatile("sti; hlt"); *state = STATE_RUNNING; } +#endif /* !PC98 */ #ifndef XEN static void @@ -1370,7 +1386,7 @@ cpu_probe_amdc1e(void) } } -#ifdef XEN +#if defined(PC98) || defined(XEN) void (*cpu_idle_fn)(sbintime_t) = cpu_idle_hlt; #else void (*cpu_idle_fn)(sbintime_t) = cpu_idle_acpi; @@ -1458,7 +1474,9 @@ struct { { cpu_idle_spin, "spin" }, { cpu_idle_mwait, "mwait" }, { cpu_idle_hlt, "hlt" }, +#ifndef PC98 { cpu_idle_acpi, "acpi" }, +#endif { NULL, NULL } }; @@ -1475,9 +1493,11 @@ idle_sysctl_available(SYSCTL_HANDLER_ARG if (strstr(idle_tbl[i].id_name, "mwait") && (cpu_feature2 & CPUID2_MON) == 0) continue; +#ifndef PC98 if (strcmp(idle_tbl[i].id_name, "acpi") == 0 && cpu_idle_hook == NULL) continue; +#endif p += sprintf(p, "%s%s", p != avail ? ", " : "", idle_tbl[i].id_name); } @@ -1512,9 +1532,11 @@ idle_sysctl(SYSCTL_HANDLER_ARGS) if (strstr(idle_tbl[i].id_name, "mwait") && (cpu_feature2 & CPUID2_MON) == 0) continue; +#ifndef PC98 if (strcmp(idle_tbl[i].id_name, "acpi") == 0 && cpu_idle_hook == NULL) continue; +#endif if (strcmp(idle_tbl[i].id_name, buf)) continue; cpu_idle_fn = idle_tbl[i].id_fn; @@ -2000,7 +2022,7 @@ sdtossd(sd, ssd) ssd->ssd_gran = sd->sd_gran; } -#ifndef XEN +#if !defined(PC98) && !defined(XEN) static int add_physmap_entry(uint64_t base, uint64_t length, vm_paddr_t *physmap, int *physmap_idxp) @@ -2107,7 +2129,9 @@ add_smap_entries(struct bios_smap *smapb if (!add_smap_entry(smap, physmap, physmap_idxp)) break; } +#endif /* !PC98 && !XEN */ +#ifndef XEN static void basemem_setup(void) { @@ -2155,7 +2179,7 @@ basemem_setup(void) for (i = basemem / 4; i < 160; i++) pte[i] = (i << PAGE_SHIFT) | PG_V | PG_RW | PG_U; } -#endif +#endif /* !XEN */ /* * Populate the (physmap) array with base/bound pairs describing the @@ -2170,6 +2194,271 @@ basemem_setup(void) * * XXX first should be vm_paddr_t. */ +#ifdef PC98 +static void +getmemsize(int first) +{ + int off, physmap_idx, pa_indx, da_indx; + u_long physmem_tunable, memtest; + vm_paddr_t physmap[PHYSMAP_SIZE]; + pt_entry_t *pte; + quad_t dcons_addr, dcons_size; + int i; + int pg_n; + u_int extmem; + u_int under16; + vm_paddr_t pa; + + bzero(physmap, sizeof(physmap)); + + /* XXX - some of EPSON machines can't use PG_N */ + pg_n = PG_N; + if (pc98_machine_type & M_EPSON_PC98) { + switch (epson_machine_id) { +#ifdef WB_CACHE + default: +#endif + case EPSON_PC486_HX: + case EPSON_PC486_HG: + case EPSON_PC486_HA: + pg_n = 0; + break; + } + } + + under16 = pc98_getmemsize(&basemem, &extmem); + basemem_setup(); + + physmap[0] = 0; + physmap[1] = basemem * 1024; + physmap_idx = 2; + physmap[physmap_idx] = 0x100000; + physmap[physmap_idx + 1] = physmap[physmap_idx] + extmem * 1024; + + /* + * Now, physmap contains a map of physical memory. + */ + +#ifdef SMP + /* make hole for AP bootstrap code */ + physmap[1] = mp_bootaddress(physmap[1]); +#endif + + /* + * Maxmem isn't the "maximum memory", it's one larger than the + * highest page of the physical address space. It should be + * called something like "Maxphyspage". We may adjust this + * based on ``hw.physmem'' and the results of the memory test. + */ + Maxmem = atop(physmap[physmap_idx + 1]); + +#ifdef MAXMEM + Maxmem = MAXMEM / 4; +#endif + + if (TUNABLE_ULONG_FETCH("hw.physmem", &physmem_tunable)) + Maxmem = atop(physmem_tunable); + + /* + * By default keep the memtest enabled. Use a general name so that + * one could eventually do more with the code than just disable it. + */ + memtest = 1; + TUNABLE_ULONG_FETCH("hw.memtest.tests", &memtest); + + if (atop(physmap[physmap_idx + 1]) != Maxmem && + (boothowto & RB_VERBOSE)) + printf("Physical memory use set to %ldK\n", Maxmem * 4); + + /* + * If Maxmem has been increased beyond what the system has detected, + * extend the last memory segment to the new limit. + */ + if (atop(physmap[physmap_idx + 1]) < Maxmem) + physmap[physmap_idx + 1] = ptoa((vm_paddr_t)Maxmem); + + /* + * We need to divide chunk if Maxmem is larger than 16MB and + * under 16MB area is not full of memory. + * (1) system area (15-16MB region) is cut off + * (2) extended memory is only over 16MB area (ex. Melco "HYPERMEMORY") + */ + if ((under16 != 16 * 1024) && (extmem > 15 * 1024)) { + /* 15M - 16M region is cut off, so need to divide chunk */ + physmap[physmap_idx + 1] = under16 * 1024; + physmap_idx += 2; + physmap[physmap_idx] = 0x1000000; + physmap[physmap_idx + 1] = physmap[2] + extmem * 1024; + } + + /* call pmap initialization to make new kernel address space */ + pmap_bootstrap(first); + + /* + * Size up each available chunk of physical memory. + */ + physmap[0] = PAGE_SIZE; /* mask off page 0 */ + pa_indx = 0; + da_indx = 1; + phys_avail[pa_indx++] = physmap[0]; + phys_avail[pa_indx] = physmap[0]; + dump_avail[da_indx] = physmap[0]; + pte = CMAP3; + + /* + * Get dcons buffer address + */ + if (getenv_quad("dcons.addr", &dcons_addr) == 0 || + getenv_quad("dcons.size", &dcons_size) == 0) + dcons_addr = 0; + + /* + * physmap is in bytes, so when converting to page boundaries, + * round up the start address and round down the end address. + */ + for (i = 0; i <= physmap_idx; i += 2) { + vm_paddr_t end; + + end = ptoa((vm_paddr_t)Maxmem); + if (physmap[i + 1] < end) + end = trunc_page(physmap[i + 1]); + for (pa = round_page(physmap[i]); pa < end; pa += PAGE_SIZE) { + int tmp, page_bad, full; + int *ptr = (int *)CADDR3; + + full = FALSE; + /* + * block out kernel memory as not available. + */ + if (pa >= KERNLOAD && pa < first) + goto do_dump_avail; + + /* + * block out dcons buffer + */ + if (dcons_addr > 0 + && pa >= trunc_page(dcons_addr) + && pa < dcons_addr + dcons_size) + goto do_dump_avail; + + page_bad = FALSE; + if (memtest == 0) + goto skip_memtest; + + /* + * map page into kernel: valid, read/write,non-cacheable + */ + *pte = pa | PG_V | PG_RW | pg_n; + invltlb(); + + tmp = *(int *)ptr; + /* + * Test for alternating 1's and 0's + */ + *(volatile int *)ptr = 0xaaaaaaaa; + if (*(volatile int *)ptr != 0xaaaaaaaa) + page_bad = TRUE; + /* + * Test for alternating 0's and 1's + */ + *(volatile int *)ptr = 0x55555555; + if (*(volatile int *)ptr != 0x55555555) + page_bad = TRUE; + /* + * Test for all 1's + */ + *(volatile int *)ptr = 0xffffffff; + if (*(volatile int *)ptr != 0xffffffff) + page_bad = TRUE; + /* + * Test for all 0's + */ + *(volatile int *)ptr = 0x0; + if (*(volatile int *)ptr != 0x0) + page_bad = TRUE; + /* + * Restore original value. + */ + *(int *)ptr = tmp; + +skip_memtest: + /* + * Adjust array of valid/good pages. + */ + if (page_bad == TRUE) + continue; + /* + * If this good page is a continuation of the + * previous set of good pages, then just increase + * the end pointer. Otherwise start a new chunk. + * Note that "end" points one higher than end, + * making the range >= start and < end. + * If we're also doing a speculative memory + * test and we at or past the end, bump up Maxmem + * so that we keep going. The first bad page + * will terminate the loop. + */ + if (phys_avail[pa_indx] == pa) { + phys_avail[pa_indx] += PAGE_SIZE; + } else { + pa_indx++; + if (pa_indx == PHYS_AVAIL_ARRAY_END) { + printf( + "Too many holes in the physical address space, giving up\n"); + pa_indx--; + full = TRUE; + goto do_dump_avail; + } + phys_avail[pa_indx++] = pa; /* start */ + phys_avail[pa_indx] = pa + PAGE_SIZE; /* end */ + } + physmem++; +do_dump_avail: + if (dump_avail[da_indx] == pa) { + dump_avail[da_indx] += PAGE_SIZE; + } else { + da_indx++; + if (da_indx == DUMP_AVAIL_ARRAY_END) { + da_indx--; + goto do_next; + } + dump_avail[da_indx++] = pa; /* start */ + dump_avail[da_indx] = pa + PAGE_SIZE; /* end */ + } +do_next: + if (full) + break; + } + } + *pte = 0; + invltlb(); + + /* + * XXX + * The last chunk must contain at least one page plus the message + * buffer to avoid complicating other code (message buffer address + * calculation, etc.). + */ + while (phys_avail[pa_indx - 1] + PAGE_SIZE + + round_page(msgbufsize) >= phys_avail[pa_indx]) { + physmem -= atop(phys_avail[pa_indx] - phys_avail[pa_indx - 1]); + phys_avail[pa_indx--] = 0; + phys_avail[pa_indx--] = 0; + } + + Maxmem = atop(phys_avail[pa_indx]); + + /* Trim off space for the message buffer. */ + phys_avail[pa_indx] -= round_page(msgbufsize); + + /* Map the message buffer. */ + for (off = 0; off < round_page(msgbufsize); off += PAGE_SIZE) + pmap_kenter((vm_offset_t)msgbufp + off, phys_avail[pa_indx] + + off); + + PT_UPDATES_FLUSH(); +} +#else /* PC98 */ static void getmemsize(int first) { @@ -2567,6 +2856,7 @@ do_next: PT_UPDATES_FLUSH(); } +#endif /* PC98 */ #ifdef XEN #define MTOPSIZE (1<<(14 + PAGE_SHIFT)) @@ -2830,6 +3120,13 @@ init386(first) */ proc_linkup0(&proc0, &thread0); +#ifdef PC98 + /* + * Initialize DMAC + */ + pc98_init_dmac(); +#endif + metadata_missing = 0; if (bootinfo.bi_modulep) { preload_metadata = (caddr_t)bootinfo.bi_modulep + KERNBASE; @@ -2993,7 +3290,9 @@ init386(first) #ifdef DEV_ISA #ifdef DEV_ATPIC +#ifndef PC98 elcr_probe(); +#endif atpic_startup(); #else /* Reset and mask the atpics and leave them shut down. */ @@ -3027,6 +3326,9 @@ init386(first) setidt(IDT_GP, &IDTVEC(prot), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); initializecpu(); /* Initialize CPU registers */ +#ifdef PC98 + initializecpucache(); +#endif /* make an initial tss so cpu can get interrupt stack on syscall! */ /* Note: -16 is so we can grow the trapframe if we came from vm86 */ @@ -3114,6 +3416,7 @@ cpu_pcpu_init(struct pcpu *pcpu, int cpu pcpu->pc_acpi_id = 0xffffffff; } +#ifndef PC98 static int smap_sysctl_handler(SYSCTL_HANDLER_ARGS) { @@ -3149,6 +3452,7 @@ smap_sysctl_handler(SYSCTL_HANDLER_ARGS) } SYSCTL_PROC(_machdep, OID_AUTO, smap, CTLTYPE_OPAQUE|CTLFLAG_RD, NULL, 0, smap_sysctl_handler, "S,bios_smap_xattr", "Raw BIOS SMAP data"); +#endif /* !PC98 */ void spinlock_enter(void)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201410040601.s9461Vxk041359>