mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-16 10:20:30 +00:00
Merge pc98's machdep.c into i386/i386/machdep.c.
This commit is contained in:
parent
986eedef26
commit
9407825cc6
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=272492
@ -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
|
||||
|
@ -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, cpu_startup, NULL);
|
||||
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_mwait, CTLFLAG_RWTUN, &idle_mwait,
|
||||
#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_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
|
||||
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 *smapbase, vm_paddr_t *physmap,
|
||||
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 @@ getmemsize(int first)
|
||||
|
||||
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 cpuid, size_t size)
|
||||
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)
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user