mirror of
https://git.stationery.faith/corn/corn.git
synced 2024-11-22 04:52:17 +00:00
acpi table loading and shutdown works, plus mmap fix :3
This commit is contained in:
parent
85a9443704
commit
61e7fdf1eb
5 changed files with 140 additions and 126 deletions
|
@ -9,12 +9,12 @@
|
||||||
#include "bindings.h"
|
#include "bindings.h"
|
||||||
|
|
||||||
struct acpi_header {
|
struct acpi_header {
|
||||||
char signature[4];
|
uint32_t signature;
|
||||||
uint32_t length;
|
uint32_t length;
|
||||||
uint8_t revision;
|
uint8_t revision;
|
||||||
uint8_t checksum;
|
uint8_t checksum;
|
||||||
char oem_id[6];
|
uint8_t oem_id[6];
|
||||||
char oem_table_id[8];
|
uint8_t oem_table_id[8];
|
||||||
uint32_t oem_revision;
|
uint32_t oem_revision;
|
||||||
uint32_t creator_id;
|
uint32_t creator_id;
|
||||||
uint32_t creator_revision;
|
uint32_t creator_revision;
|
||||||
|
@ -23,9 +23,9 @@ struct acpi_header {
|
||||||
// root system descriptor pointer
|
// root system descriptor pointer
|
||||||
// ACPI 1.0
|
// ACPI 1.0
|
||||||
struct rsdp {
|
struct rsdp {
|
||||||
char signature[8];
|
uint8_t signature[8];
|
||||||
uint8_t checksum;
|
uint8_t checksum;
|
||||||
char oemid[6];
|
uint8_t oemid[6];
|
||||||
uint8_t revision;
|
uint8_t revision;
|
||||||
uint32_t rsdt_addr;
|
uint32_t rsdt_addr;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
@ -38,11 +38,12 @@ struct xsdp {
|
||||||
char oemid[6];
|
char oemid[6];
|
||||||
uint8_t revision;
|
uint8_t revision;
|
||||||
uint32_t rsdt_addr;
|
uint32_t rsdt_addr;
|
||||||
|
struct {
|
||||||
uint32_t length;
|
uint32_t length;
|
||||||
uint64_t xsdt_addr;
|
uint64_t xsdt_addr;
|
||||||
uint8_t extendeid_checksum;
|
uint8_t extendeid_checksum;
|
||||||
uint8_t reserved[3];
|
uint8_t reserved[3];
|
||||||
|
} ext;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
// root system descriptor table
|
// root system descriptor table
|
||||||
|
@ -50,14 +51,14 @@ struct xsdp {
|
||||||
struct rsdt {
|
struct rsdt {
|
||||||
struct acpi_header h;
|
struct acpi_header h;
|
||||||
uint32_t sdt_pointers[];
|
uint32_t sdt_pointers[];
|
||||||
};
|
} __attribute__((packed));
|
||||||
|
|
||||||
// eXtended system descriptor table
|
// eXtended system descriptor table
|
||||||
// ACPI 2.0
|
// ACPI 2.0
|
||||||
struct xsdt {
|
struct xsdt {
|
||||||
struct acpi_header h;
|
struct acpi_header h;
|
||||||
uint64_t sdt_pointers[];
|
uint64_t sdt_pointers[];
|
||||||
};
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
|
||||||
// generic address structure
|
// generic address structure
|
||||||
|
@ -69,6 +70,27 @@ struct gas {
|
||||||
uint64_t address;
|
uint64_t address;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// differentiated system description table
|
||||||
|
struct dsdt {
|
||||||
|
struct acpi_header h;
|
||||||
|
char s5_addr[];
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct apic {
|
||||||
|
struct acpi_header h;
|
||||||
|
// todo
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct hept {
|
||||||
|
struct acpi_header h;
|
||||||
|
// todo
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct waet {
|
||||||
|
struct acpi_header h;
|
||||||
|
// todo
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
// fixed acpi description table
|
// fixed acpi description table
|
||||||
struct fadt {
|
struct fadt {
|
||||||
struct acpi_header h;
|
struct acpi_header h;
|
||||||
|
@ -135,15 +157,20 @@ struct fadt {
|
||||||
struct gas x_pm_timer_block;
|
struct gas x_pm_timer_block;
|
||||||
struct gas x_gpe0_block;
|
struct gas x_gpe0_block;
|
||||||
struct gas x_gpe1_block;
|
struct gas x_gpe1_block;
|
||||||
};
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct acpi_state {
|
struct acpi_state {
|
||||||
union {
|
union {
|
||||||
struct xsdt *xsdt;
|
struct xsdt *xsdt;
|
||||||
struct rsdt *rsdt;
|
struct rsdt *rsdt;
|
||||||
} dst;
|
} sdt;
|
||||||
|
struct fadt *fadt;
|
||||||
|
struct dsdt *dsdt;
|
||||||
|
struct apic *apic;
|
||||||
|
struct hept *hept;
|
||||||
|
struct waet *waet;
|
||||||
uint8_t version;
|
uint8_t version;
|
||||||
struct fadt fadt;
|
|
||||||
uint16_t SLP_TYPa;
|
uint16_t SLP_TYPa;
|
||||||
uint16_t SLP_TYPb;
|
uint16_t SLP_TYPb;
|
||||||
uint16_t SLP_EN;
|
uint16_t SLP_EN;
|
||||||
|
@ -160,11 +187,10 @@ static bool checksum(uint8_t *data, size_t len) {
|
||||||
return sum == 0;
|
return sum == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int read_s5_addr(struct acpi_state *state) {
|
static int read_s5_addr(struct dsdt *dsdt) {
|
||||||
uintptr_t ptr = state->fadt.dsdt;
|
char *s5_addr = dsdt->s5_addr;
|
||||||
char *s5_addr = (void *) (ptr + 36);
|
int dsdt_len = dsdt->h.length - sizeof(struct acpi_header);
|
||||||
|
|
||||||
int dsdt_len = *((int *) (ptr+1)) - 36;
|
|
||||||
while (0 < dsdt_len--) {
|
while (0 < dsdt_len--) {
|
||||||
if (memcmp(s5_addr, "_S5_", 4) == 0)
|
if (memcmp(s5_addr, "_S5_", 4) == 0)
|
||||||
break;
|
break;
|
||||||
|
@ -179,15 +205,15 @@ static int read_s5_addr(struct acpi_state *state) {
|
||||||
|
|
||||||
if (*s5_addr == 0x0A)
|
if (*s5_addr == 0x0A)
|
||||||
s5_addr++; // skip byteprefix
|
s5_addr++; // skip byteprefix
|
||||||
state->SLP_TYPa = *(s5_addr)<<10;
|
state.SLP_TYPa = *(s5_addr)<<10;
|
||||||
s5_addr++;
|
s5_addr++;
|
||||||
|
|
||||||
if (*s5_addr == 0x0A)
|
if (*s5_addr == 0x0A)
|
||||||
s5_addr++; // skip byteprefix
|
s5_addr++; // skip byteprefix
|
||||||
state->SLP_TYPb = *(s5_addr)<<10;
|
state.SLP_TYPb = *(s5_addr)<<10;
|
||||||
|
|
||||||
state->SLP_EN = 1<<13;
|
state.SLP_EN = 1<<13;
|
||||||
state->SCI_EN = 1;
|
state.SCI_EN = 1;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -199,129 +225,115 @@ static int read_s5_addr(struct acpi_state *state) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *acpi_find_table_rsdt(struct rsdt *rsdt, const char *identifier, int ident_len) {
|
static void acpi_load_table(uint64_t addr);
|
||||||
|
|
||||||
|
static void acpi_load_rsdt_tables(struct rsdt *rsdt) {
|
||||||
int entries = (rsdt->h.length - sizeof(rsdt->h)) / 4;
|
int entries = (rsdt->h.length - sizeof(rsdt->h)) / 4;
|
||||||
|
|
||||||
for (int i = 0; i < entries; i++) {
|
for (int i = 0; i < entries; i++) {
|
||||||
struct acpi_header *h = (struct acpi_header *) (uintptr_t) rsdt->sdt_pointers[i];
|
uint32_t addr = rsdt->sdt_pointers[i];
|
||||||
char buf[6];
|
acpi_load_table(addr);
|
||||||
memcpy(buf, h->signature, 4);
|
|
||||||
buf[4] = '\n';
|
|
||||||
buf[5] = '\0';
|
|
||||||
kputs(buf);
|
|
||||||
if (!strncmp(h->signature, identifier, ident_len))
|
|
||||||
return (void *)h;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TABLE NOT FOUND
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *acpi_find_table_xsdt(struct xsdt *xsdt, const char *identifier, int ident_len) {
|
static void acpi_load_xsdt_tables(struct xsdt *xsdt) {
|
||||||
int entries = (xsdt->h.length - sizeof(xsdt->h)) / 8;
|
int entries = (xsdt->h.length - sizeof(xsdt->h)) / 8;
|
||||||
|
|
||||||
for (int i = 0; i < entries; i++) {
|
for (int i = 0; i < entries; i++) {
|
||||||
struct acpi_header *h = (struct acpi_header *) (uintptr_t) xsdt->sdt_pointers[i];
|
uint64_t addr = xsdt->sdt_pointers[i];
|
||||||
if (!strncmp(h->signature, identifier, ident_len))
|
acpi_load_table(addr);
|
||||||
return (void *)h;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TABLE NOT FOUND
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int acpi_init_rsdt(struct rsdt *rsdt) {
|
#define SIG_RSDT 0x54445352
|
||||||
|
#define SIG_XSDT 0x54445358
|
||||||
|
#define SIG_FACP 0x50434146
|
||||||
|
#define SIG_DSDT 0x54445344
|
||||||
|
#define SIG_APIC 0x43495041
|
||||||
|
#define SIG_HEPT 0x54455048
|
||||||
|
#define SIG_WAET 0x54454157
|
||||||
|
|
||||||
kprintf("RSDT: %#016lx\n", (size_t)rsdt);
|
static void acpi_handle_table(struct acpi_header *header) {
|
||||||
|
switch (header->signature) {
|
||||||
rsdt = mmap(rsdt, sizeof(struct rsdt));
|
case SIG_RSDT:
|
||||||
|
state.sdt.rsdt = (struct rsdt *) header;
|
||||||
state.dst.rsdt = rsdt;
|
acpi_load_rsdt_tables(state.sdt.rsdt);
|
||||||
state.version = 0;
|
break;
|
||||||
|
case SIG_XSDT:
|
||||||
if (!checksum((uint8_t *) &rsdt->h, rsdt->h.length))
|
state.sdt.xsdt = (struct xsdt *) header;
|
||||||
return -1;
|
acpi_load_xsdt_tables(state.sdt.xsdt);
|
||||||
|
break;
|
||||||
struct fadt *fadt = acpi_find_table_rsdt(rsdt, "FACP", 4);
|
case SIG_FACP:
|
||||||
if (!fadt)
|
state.fadt = (struct fadt *) header;
|
||||||
return -1;
|
acpi_load_table(state.fadt->dsdt);
|
||||||
|
break;
|
||||||
if (!checksum((uint8_t *) &fadt->h, fadt->h.length))
|
case SIG_DSDT:
|
||||||
return -1;
|
state.dsdt = (struct dsdt *) header;
|
||||||
|
read_s5_addr(state.dsdt);
|
||||||
state.fadt = *fadt;
|
break;
|
||||||
|
case SIG_APIC:
|
||||||
return -1;
|
state.apic = (struct apic *) header;
|
||||||
|
break;
|
||||||
|
case SIG_HEPT:
|
||||||
|
state.hept = (struct hept *) header;
|
||||||
|
break;
|
||||||
|
case SIG_WAET:
|
||||||
|
state.waet = (struct waet *) header;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int acpi_init_xsdt(struct xsdt *xsdt) {
|
static void acpi_load_table(uint64_t addr) {
|
||||||
|
struct acpi_header *temp, *mapped;
|
||||||
|
uint32_t length;
|
||||||
|
|
||||||
xsdt = mmap(xsdt, sizeof(struct xsdt));
|
temp = (struct acpi_header * ) (uintptr_t) addr;
|
||||||
return -1;
|
mapped = mmap(temp, sizeof(struct acpi_header));
|
||||||
state.dst.xsdt = xsdt;
|
length = mapped->length;
|
||||||
state.version = 2;
|
unmap(mapped);
|
||||||
|
mapped = mmap(temp, length);
|
||||||
if (!checksum((uint8_t *) &xsdt->h, xsdt->h.length))
|
if (!checksum((uint8_t *) mapped, mapped->length)) {
|
||||||
return -1;
|
unmap(mapped);
|
||||||
|
return;
|
||||||
struct fadt *fadt = acpi_find_table_xsdt(xsdt, "FACP", 4);
|
}
|
||||||
if (!fadt)
|
kprintf("%.*s: %#016lx\n", 4, (char*)&mapped->signature, (size_t)temp);
|
||||||
return -1;
|
acpi_handle_table(mapped);
|
||||||
|
|
||||||
if (!checksum((uint8_t *) &fadt->h, fadt->h.length))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
state.fadt = *fadt;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int acpi_init(void *rootsdp) {
|
int acpi_init(void *rootsdp) {
|
||||||
|
|
||||||
|
memset(&state, 0, sizeof(struct acpi_state));
|
||||||
|
|
||||||
struct rsdp *rsdp = (struct rsdp *) rootsdp;
|
struct rsdp *rsdp = (struct rsdp *) rootsdp;
|
||||||
|
|
||||||
if (!checksum((uint8_t *)rsdp, sizeof(struct rsdp)))
|
if (!checksum((uint8_t *)rsdp, sizeof(struct rsdp)))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (strncmp(rsdp->signature, "RSD PTR ", 8) != 0) {
|
if (memcmp(rsdp->signature, "RSD PTR ", 8) != 0) {
|
||||||
panic("invalid acpi rsdp signature: %.*s\n", 8, rsdp->signature);
|
panic("invalid acpi rsdp signature: %.*s\n", 8, rsdp->signature);
|
||||||
}
|
}
|
||||||
|
|
||||||
int res;
|
|
||||||
|
|
||||||
if (rsdp->revision == 0) {
|
if (rsdp->revision == 0) {
|
||||||
|
state.version = 0;
|
||||||
kprintf("ACPI 1.0\n");
|
kprintf("ACPI 1.0\n");
|
||||||
kprintf("RSDP: %#016lx\n", (size_t)rsdp);
|
acpi_load_table(rsdp->rsdt_addr);
|
||||||
res = acpi_init_rsdt(
|
|
||||||
(struct rsdt *) (uintptr_t) rsdp->rsdt_addr
|
|
||||||
);
|
|
||||||
} else if (rsdp->revision == 2) {
|
} else if (rsdp->revision == 2) {
|
||||||
|
state.version = 2;
|
||||||
struct xsdp *xsdp = (struct xsdp *) rsdp;
|
struct xsdp *xsdp = (struct xsdp *) rsdp;
|
||||||
kprintf("ACPI 2.0\n");
|
kprintf("ACPI 2.0\n");
|
||||||
kprintf("XSDP: %#016lx\n", (size_t)xsdp);
|
acpi_load_table(xsdp->ext.xsdt_addr);
|
||||||
res = acpi_init_xsdt(
|
|
||||||
(struct xsdt *) (uintptr_t) xsdp->xsdt_addr
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
panic("invalid acpi rev: %d\n", rsdp->revision);
|
panic("invalid acpi rev: %d\n", rsdp->revision);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res) {
|
kprintf("\n");
|
||||||
kprintf("...acpi failed to load\n\n");
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
kprintf("\n\n");
|
outb(state.fadt->smi_command_port,state.fadt->acpi_enable);
|
||||||
|
|
||||||
int ret = read_s5_addr(&state);
|
|
||||||
if (!ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
outb(state.fadt.smi_command_port,state.fadt.acpi_enable);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int acpi_shutdown(void) {
|
int acpi_shutdown(void) {
|
||||||
outw((unsigned int) state.fadt.pm1_a_control_block, state.SLP_TYPb | state.SLP_EN);
|
outw((unsigned int) state.fadt->pm1_a_control_block, state.SLP_TYPb | state.SLP_EN);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,7 +135,7 @@ void idt_exception_handler(uint64_t exception, uint64_t code, struct isr_regs *s
|
||||||
kprintf("Error code 0x%lX\n", code);
|
kprintf("Error code 0x%lX\n", code);
|
||||||
|
|
||||||
if (exception == EX_PAGE_FAULT) {
|
if (exception == EX_PAGE_FAULT) {
|
||||||
kprintf("Page fault address: 0x%lX\n", cr2);
|
kprintf("Page fault address: %#016lx\n", cr2);
|
||||||
}
|
}
|
||||||
|
|
||||||
kputs("\n");
|
kputs("\n");
|
||||||
|
|
|
@ -539,20 +539,20 @@ void paging_init(void) {
|
||||||
|
|
||||||
static inline void *page_align(void *addr) {
|
static inline void *page_align(void *addr) {
|
||||||
uintptr_t a = (uintptr_t) addr;
|
uintptr_t a = (uintptr_t) addr;
|
||||||
a += PAGE_SIZE - 1;
|
|
||||||
a /= PAGE_SIZE;
|
a /= PAGE_SIZE;
|
||||||
a *= PAGE_SIZE;
|
a *= PAGE_SIZE;
|
||||||
return (void *) a;
|
return (void *) a;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *mmap(void *addr, size_t len) {
|
void *mmap(void *addr, size_t len) {
|
||||||
len += (long)addr % PAGE_SIZE;
|
void *phys = page_align(addr);
|
||||||
long pages = (len + PAGE_SIZE - 1) / PAGE_SIZE;
|
ptrdiff_t error = (char*)addr - (char*)phys;
|
||||||
|
len += error;
|
||||||
|
long pages = len / PAGE_SIZE + 1;
|
||||||
void *virt = virtaddr_alloc(pages);
|
void *virt = virtaddr_alloc(pages);
|
||||||
if (virt == NULL) {
|
if (virt == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
void *phys = page_align(addr);
|
|
||||||
if (map_pages(
|
if (map_pages(
|
||||||
kernel_pml4,
|
kernel_pml4,
|
||||||
virt,
|
virt,
|
||||||
|
@ -563,7 +563,7 @@ void *mmap(void *addr, size_t len) {
|
||||||
virtaddr_free(virt);
|
virtaddr_free(virt);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return virt;
|
return (char*)virt + error;
|
||||||
}
|
}
|
||||||
|
|
||||||
void unmap(void *addr) {
|
void unmap(void *addr) {
|
||||||
|
|
|
@ -15,12 +15,12 @@ void kmain(struct boot_info *info) {
|
||||||
|
|
||||||
kprintf("enterd kmain\n");
|
kprintf("enterd kmain\n");
|
||||||
|
|
||||||
|
//acpi_shutdown();
|
||||||
|
|
||||||
// pages are allocated on write :3
|
// pages are allocated on write :3
|
||||||
char *test = kalloc(5);
|
char *test = kalloc(5);
|
||||||
*test = 1;
|
*test = 1;
|
||||||
|
|
||||||
//log_backtrace();
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
screen_redraw();
|
screen_redraw();
|
||||||
// loop so we dont halt
|
// loop so we dont halt
|
||||||
|
|
24
src/print.c
24
src/print.c
|
@ -95,6 +95,7 @@ static enum printtype conversion_to_printtype(enum format_conversion conversion)
|
||||||
return OCTAL;
|
return OCTAL;
|
||||||
case FMT_HEX:
|
case FMT_HEX:
|
||||||
case FMT_HEX_UPPER:
|
case FMT_HEX_UPPER:
|
||||||
|
case FMT_PTR:
|
||||||
return HEX;
|
return HEX;
|
||||||
default:
|
default:
|
||||||
return NONE;
|
return NONE;
|
||||||
|
@ -377,11 +378,12 @@ static void print_number_buffer(
|
||||||
const char *buf, // buffer containing the text we want to print
|
const char *buf, // buffer containing the text we want to print
|
||||||
struct spacing spacing, // the spacing on the left right and middle
|
struct spacing spacing, // the spacing on the left right and middle
|
||||||
enum printtype type,
|
enum printtype type,
|
||||||
enum charcase cc
|
enum charcase cc,
|
||||||
|
enum format_flag flags
|
||||||
) {
|
) {
|
||||||
|
|
||||||
// put the 0x at the start of the string
|
// put the 0x at the start of the string
|
||||||
if (spacing.left && spacing.zero && type == HEX) {
|
if (spacing.left && spacing.zero && type == HEX && (flags & FLG_ALTERNATE)) {
|
||||||
if (cc == UPPERCASE) {
|
if (cc == UPPERCASE) {
|
||||||
kputs("0X");
|
kputs("0X");
|
||||||
} else {
|
} else {
|
||||||
|
@ -389,7 +391,7 @@ static void print_number_buffer(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((!spacing.left || !spacing.zero) && type == OCTAL) {
|
if ((!spacing.left || !spacing.zero) && type == OCTAL && (flags & FLG_ALTERNATE)) {
|
||||||
kputc('0');
|
kputc('0');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -397,7 +399,7 @@ static void print_number_buffer(
|
||||||
spacing.zero ? kputc('0') : kputc(' ');
|
spacing.zero ? kputc('0') : kputc(' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((!spacing.left || !spacing.zero) && type == HEX) {
|
if ((!spacing.left || !spacing.zero) && type == HEX && (flags & FLG_ALTERNATE)) {
|
||||||
if (cc == UPPERCASE) {
|
if (cc == UPPERCASE) {
|
||||||
kputs("0X");
|
kputs("0X");
|
||||||
} else {
|
} else {
|
||||||
|
@ -457,18 +459,18 @@ static struct spacing get_spacing(
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned gap = 0;
|
unsigned gap = 0;
|
||||||
if (max > length) {
|
if (min > length) {
|
||||||
gap = max - length;
|
gap = min - length;
|
||||||
}
|
}
|
||||||
|
|
||||||
spacing.length = length;
|
spacing.length = length;
|
||||||
|
|
||||||
if (flags & FLG_LEFT_ALIGN) {
|
if (flags & FLG_LEFT_ALIGN) {
|
||||||
spacing.left = gap;
|
|
||||||
spacing.right = 0;
|
|
||||||
} else {
|
|
||||||
spacing.left = 0;
|
spacing.left = 0;
|
||||||
spacing.right = gap;
|
spacing.right = gap;
|
||||||
|
} else {
|
||||||
|
spacing.left = gap;
|
||||||
|
spacing.right = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
spacing.zero = (flags & FLG_ZERO);
|
spacing.zero = (flags & FLG_ZERO);
|
||||||
|
@ -574,7 +576,7 @@ static void print_signed_number(
|
||||||
unsigned length = strlen(ptr);
|
unsigned length = strlen(ptr);
|
||||||
struct spacing spacing =
|
struct spacing spacing =
|
||||||
get_spacing(width, precision, flags, length);
|
get_spacing(width, precision, flags, length);
|
||||||
print_number_buffer(ptr, spacing, type, cc);
|
print_number_buffer(ptr, spacing, type, cc, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_unsigned_number(
|
static void print_unsigned_number(
|
||||||
|
@ -591,7 +593,7 @@ static void print_unsigned_number(
|
||||||
unsigned length = strlen(ptr);
|
unsigned length = strlen(ptr);
|
||||||
struct spacing spacing =
|
struct spacing spacing =
|
||||||
get_spacing(width, precision, flags, length);
|
get_spacing(width, precision, flags, length);
|
||||||
print_number_buffer(ptr, spacing, type, cc);
|
print_number_buffer(ptr, spacing, type, cc, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool is_conversion_number(enum format_conversion conversion) {
|
static bool is_conversion_number(enum format_conversion conversion) {
|
||||||
|
|
Loading…
Reference in a new issue