Changeset View
Changeset View
Standalone View
Standalone View
sys/amd64/amd64/machdep.c
Show First 20 Lines • Show All 92 Lines • ▼ Show 20 Lines | |||||
#include <machine/trap.h> | #include <machine/trap.h> | ||||
#include <machine/tss.h> | #include <machine/tss.h> | ||||
#ifdef SMP | #ifdef SMP | ||||
#include <machine/smp.h> | #include <machine/smp.h> | ||||
#endif | #endif | ||||
#ifdef FDT | #ifdef FDT | ||||
#include <x86/fdt.h> | #include <x86/fdt.h> | ||||
#endif | #endif | ||||
#ifdef DEV_PCI | |||||
#include <dev/pci/pcivar.h> | |||||
#endif | |||||
#ifdef DEV_ATPIC | #ifdef DEV_ATPIC | ||||
#include <x86/isa/icu.h> | #include <x86/isa/icu.h> | ||||
#else | #else | ||||
#include <x86/apicvar.h> | #include <x86/apicvar.h> | ||||
#endif | #endif | ||||
#include <isa/isareg.h> | #include <isa/isareg.h> | ||||
Show All 24 Lines | |||||
SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL); | SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL); | ||||
/* Preload data parse function */ | /* Preload data parse function */ | ||||
static caddr_t native_parse_preload_data(u_int64_t); | static caddr_t native_parse_preload_data(u_int64_t); | ||||
/* Native function to fetch and parse the e820 map */ | /* Native function to fetch and parse the e820 map */ | ||||
static void native_parse_memmap(caddr_t, vm_paddr_t *, int *); | static void native_parse_memmap(caddr_t, vm_paddr_t *, int *); | ||||
/* Helper functions for phys_avail_reserve. */ | |||||
static void phys_avail_insert_at(int index, vm_paddr_t val); | |||||
static void phys_avail_delete_at(int index); | |||||
/* Default init_ops implementation. */ | /* Default init_ops implementation. */ | ||||
struct init_ops init_ops = { | struct init_ops init_ops = { | ||||
.parse_preload_data = native_parse_preload_data, | .parse_preload_data = native_parse_preload_data, | ||||
.early_clock_source_init = i8254_init, | .early_clock_source_init = i8254_init, | ||||
.early_delay = i8254_delay, | .early_delay = i8254_delay, | ||||
.parse_memmap = native_parse_memmap, | .parse_memmap = native_parse_memmap, | ||||
#ifdef SMP | #ifdef SMP | ||||
.mp_bootaddress = mp_bootaddress, | .mp_bootaddress = mp_bootaddress, | ||||
▲ Show 20 Lines • Show All 184 Lines • ▼ Show 20 Lines | |||||
amd64_kdb_init(); | amd64_kdb_init(); | ||||
} | } | ||||
getmemsize(kmdp, physfree); | getmemsize(kmdp, physfree); | ||||
init_param2(physmem); | init_param2(physmem); | ||||
/* now running on new page tables, configured,and u/iom is accessible */ | /* now running on new page tables, configured,and u/iom is accessible */ | ||||
#ifdef DEV_PCI | |||||
/* This function might manipulate phys_avail. */ | |||||
pci_early_quirks(); | |||||
#endif | |||||
if (late_console) | if (late_console) | ||||
cninit(); | cninit(); | ||||
#ifdef DEV_ISA | #ifdef DEV_ISA | ||||
#ifdef DEV_ATPIC | #ifdef DEV_ATPIC | ||||
elcr_probe(); | elcr_probe(); | ||||
atpic_startup(); | atpic_startup(); | ||||
#else | #else | ||||
▲ Show 20 Lines • Show All 184 Lines • ▼ Show 20 Lines | |||||
void | void | ||||
outb_(u_short port, u_char data) | outb_(u_short port, u_char data) | ||||
{ | { | ||||
outb(port, data); | outb(port, data); | ||||
} | } | ||||
#endif /* KDB */ | #endif /* KDB */ | ||||
static void | |||||
phys_avail_insert_at(int index, vm_paddr_t val) | |||||
{ | |||||
int j = PHYS_AVAIL_ARRAY_END; | |||||
while (j >= index) { | |||||
phys_avail[j+1] = phys_avail[j]; | |||||
j--; | |||||
} | |||||
phys_avail[j+1] = val; | |||||
} | |||||
static void | |||||
phys_avail_delete_at(int index) | |||||
{ | |||||
int j = index; | |||||
while (j <= PHYS_AVAIL_ARRAY_END) { | |||||
phys_avail[j] = phys_avail[j+1]; | |||||
j++; | |||||
} | |||||
} | |||||
void | |||||
phys_avail_reserve(vm_paddr_t start, vm_paddr_t end) | |||||
{ | |||||
int i = 0; | |||||
kib: No init at the declaration location. | |||||
/* Check if inside a hole before first segment. */ | |||||
if (end <= phys_avail[0]) | |||||
return; | |||||
/* Check if inside any hole. */ | |||||
while (phys_avail[i+2] != 0) { | |||||
kibUnsubmitted Not Done Inline Actionsbinary ops require spaces around the op symbol. kib: binary ops require spaces around the op symbol. | |||||
johalun0_gmail.comAuthorUnsubmitted Not Done Inline ActionsDo you mean [(i+2)] ? johalun0_gmail.com: Do you mean [(i+2)] ? | |||||
kibUnsubmitted Not Done Inline ActionsI mean spaces, not braces. phys_avail[i + 2] kib: I mean spaces, not braces.
```
phys_avail[i + 2]
``` | |||||
if (start >= phys_avail[i+1] && end <= phys_avail[i+2]) | |||||
kibUnsubmitted Not Done Inline ActionsWhat is end ? Is it the address to reserve, or the address right after the reserve ? kib: What is end ? Is it the address to reserve, or the address right after the reserve ? | |||||
johalun0_gmail.comAuthorUnsubmitted Not Done Inline ActionsEnd is the address right after the reserve. Maybe having the function take base and size as arguments would make things more clear? johalun0_gmail.com: End is the address right after the reserve. Maybe having the function take base and size as… | |||||
kibUnsubmitted Not Done Inline ActionsNo, it is common to take the range end as the address after the range. But then you have off by one in the check. kib: No, it is common to take the range end as the address after the range. But then you have off… | |||||
return; | |||||
i += 2; | |||||
} | |||||
/* Check if new hole is after last segment end (i+1). */ | |||||
if (start >= phys_avail[i+1]) | |||||
return; | |||||
i=0; | |||||
/* Check if inside any segment */ | |||||
while (phys_avail[i+1] != 0) { | |||||
if (start > phys_avail[i] && end < phys_avail[i+1]) { | |||||
phys_avail_insert_at(i+1, end); | |||||
phys_avail_insert_at(i+1, start); | |||||
return; | |||||
} | |||||
i += 2; | |||||
} | |||||
/* Other cases */ | |||||
i=0; | |||||
while (phys_avail[i] < start && i <= PHYS_AVAIL_ARRAY_END) { | |||||
i++; | |||||
} | |||||
if (phys_avail[i+1] == 0) { | |||||
/* The new hole starts in the last segment and ends after. */ | |||||
phys_avail[i] = start; | |||||
return; | |||||
} | |||||
/* At the index located on or after the new hole start. */ | |||||
if (i % 2 == 0) { | |||||
/* | |||||
* Even index mean beginning of a segment. If hole ends in | |||||
* segment, shrink the segment. If exact match, delete the | |||||
* segment. Other cases are handled below. | |||||
*/ | |||||
if (start == phys_avail[i]) { | |||||
if (end < phys_avail[i+1]) { | |||||
phys_avail[i] = end; | |||||
return; | |||||
} else if (end == phys_avail[i+1]) { | |||||
phys_avail_delete_at(i); | |||||
phys_avail_delete_at(i); | |||||
return; | |||||
} | |||||
} | |||||
} else { | |||||
/* | |||||
* Odd index mean the hole starts inside a memory segment. | |||||
* Shrink segment to hole start. | |||||
*/ | |||||
phys_avail[i] = start; | |||||
i++; | |||||
} | |||||
int deleted = 0; | |||||
while (phys_avail[i] <= end && phys_avail[i+1] != 0) { | |||||
phys_avail_delete_at(i); | |||||
deleted++; | |||||
} | |||||
/* At the index located after the new hole end. */ | |||||
if (i % 2 == 0 && deleted % 2 == 1) { | |||||
/* | |||||
* If index is even and odd number of entries have been deleted, | |||||
* we are at the end of a segment. Insert hole end before this | |||||
* segment end. | |||||
*/ | |||||
phys_avail_insert_at(i, end); | |||||
} else if (i % 2 == 1) { | |||||
/* | |||||
* Odd index mean our hole ends in the previous segment, | |||||
* move segment start to new hole end. | |||||
*/ | |||||
phys_avail[i-1] = start; | |||||
} | |||||
} | |||||
Context not available. |
No init at the declaration location.