[arch][m68k] add arch_mmu_query so the kernel boots completely
Side effect of editing: reformat all of the code in platform/qemu-virt-m68k
This commit is contained in:
@@ -9,6 +9,8 @@
|
||||
|
||||
#if M68K_MMU
|
||||
|
||||
#include <arch/mmu.h>
|
||||
#include <arch/spinlock.h>
|
||||
#include <assert.h>
|
||||
#include <kernel/vm.h>
|
||||
#include <lk/err.h>
|
||||
@@ -16,9 +18,9 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define LOCAL_TRACE 1
|
||||
#define LOCAL_TRACE 0
|
||||
|
||||
// initial mappings set up in start.S using the DTTR and ITTR registers
|
||||
// initial mappings set up in start.S
|
||||
struct mmu_initial_mapping mmu_initial_mappings[] = {
|
||||
// all of memory, mapped in start.S
|
||||
{
|
||||
@@ -377,14 +379,6 @@ void m68k_mmu_init(void) {
|
||||
LTRACE_EXIT;
|
||||
}
|
||||
|
||||
// arch mmu routines
|
||||
|
||||
#endif // M68K_MMU
|
||||
|
||||
#if ARCH_HAS_MMU
|
||||
|
||||
#include <arch/mmu.h>
|
||||
|
||||
// Default stub implementations for arch_mmu routines
|
||||
|
||||
bool arch_mmu_supports_nx_mappings(void) {
|
||||
@@ -416,7 +410,47 @@ int arch_mmu_unmap(arch_aspace_t *aspace, vaddr_t vaddr, uint count) {
|
||||
}
|
||||
|
||||
status_t arch_mmu_query(arch_aspace_t *aspace, vaddr_t vaddr, paddr_t *paddr, uint *flags) {
|
||||
return ERR_NOT_SUPPORTED;
|
||||
// Disable interrupts around the ptest instruction in case we get preempted
|
||||
spin_lock_saved_state_t state;
|
||||
arch_interrupt_save(&state, 0);
|
||||
|
||||
// Use the PTEST instruction to probe the translation
|
||||
uint32_t mmusr;
|
||||
asm volatile(
|
||||
"ptestr (%1)\n"
|
||||
"movec %%mmusr, %0"
|
||||
: "=r"(mmusr) : "a"(vaddr) : "memory");
|
||||
|
||||
arch_interrupt_restore(state, 0);
|
||||
|
||||
LTRACEF("vaddr %#x, mmusr %#x\n", (uint32_t)vaddr, mmusr);
|
||||
if ((mmusr & 0x1) == 0) {
|
||||
return ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
// extract the physical address from the mmusr
|
||||
if (paddr) {
|
||||
*paddr = (mmusr & 0xfffff000) | (vaddr & 0xfff);
|
||||
}
|
||||
if (flags) {
|
||||
*flags = 0;
|
||||
*flags |= (mmusr & (1 << 2)) ? ARCH_MMU_FLAG_PERM_RO : 0;
|
||||
*flags |= (mmusr & (1 << 7)) ? 0 : ARCH_MMU_FLAG_PERM_USER;
|
||||
uint32_t cm = mmusr & (3 << 5);
|
||||
switch (cm) {
|
||||
case 0:
|
||||
case 1:
|
||||
*flags |= ARCH_MMU_FLAG_CACHED;
|
||||
break;
|
||||
case 2:
|
||||
*flags |= ARCH_MMU_FLAG_UNCACHED_DEVICE;
|
||||
break;
|
||||
case 3:
|
||||
*flags |= ARCH_MMU_FLAG_UNCACHED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
vaddr_t arch_mmu_pick_spot(arch_aspace_t *aspace,
|
||||
@@ -430,4 +464,4 @@ void arch_mmu_context_switch(arch_aspace_t *aspace) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
#endif // ARCH_HAS_MMU
|
||||
#endif // M68K_MMU
|
||||
@@ -8,8 +8,8 @@
|
||||
#include "bootinfo.h"
|
||||
|
||||
#include <lk/compiler.h>
|
||||
#include <lk/trace.h>
|
||||
#include <lk/debug.h>
|
||||
#include <lk/trace.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define LOCAL_TRACE 0
|
||||
@@ -18,22 +18,38 @@ extern uint8_t __bss_end;
|
||||
|
||||
static const char *bootinfo_tag_to_string(enum BOOTINFO_TAGS tag) {
|
||||
switch (tag) {
|
||||
case BOOTINFO_TAG_END: return "END";
|
||||
case BOOTINFO_TAG_MACHTYPE: return "MACHTYPE";
|
||||
case BOOTINFO_TAG_CPUTYPE: return "CPUTYPE";
|
||||
case BOOTINFO_TAG_FPUTYPE: return "FPUTYPE";
|
||||
case BOOTINFO_TAG_MMUTYPE: return "MMUTYPE";
|
||||
case BOOTINFO_TAG_MEMCHUNK: return "MEMCHUNK";
|
||||
case BOOTINFO_TAG_RAMDISK: return "RAMDISK";
|
||||
case BOOTINFO_TAG_COMMAND_LINE: return "COMMAND_LINE";
|
||||
case BOOTINFO_TAG_RNG_SEED: return "RNG_SEED";
|
||||
case BOOTINFO_TAG_VIRT_QEMU_VERSION: return "VIRT_QEMU_VERSION";
|
||||
case BOOTINFO_TAG_VIRT_GF_PIC_BASE: return "VIRT_GF_PIC_BASE";
|
||||
case BOOTINFO_TAG_VIRT_GF_RTC_BASE: return "VIRT_GF_RTC_BASE";
|
||||
case BOOTINFO_TAG_VIRT_GF_TTY_BASE: return "VIRT_GF_TTY_BASE";
|
||||
case BOOTINFO_TAG_VIRT_VIRTIO_BASE: return "VIRT_VIRTIO_BASE";
|
||||
case BOOTINFO_TAG_VIRT_CTRL_BASE: return "VIRT_CTRL_BASE";
|
||||
default: return "UNKNOWN";
|
||||
case BOOTINFO_TAG_END:
|
||||
return "END";
|
||||
case BOOTINFO_TAG_MACHTYPE:
|
||||
return "MACHTYPE";
|
||||
case BOOTINFO_TAG_CPUTYPE:
|
||||
return "CPUTYPE";
|
||||
case BOOTINFO_TAG_FPUTYPE:
|
||||
return "FPUTYPE";
|
||||
case BOOTINFO_TAG_MMUTYPE:
|
||||
return "MMUTYPE";
|
||||
case BOOTINFO_TAG_MEMCHUNK:
|
||||
return "MEMCHUNK";
|
||||
case BOOTINFO_TAG_RAMDISK:
|
||||
return "RAMDISK";
|
||||
case BOOTINFO_TAG_COMMAND_LINE:
|
||||
return "COMMAND_LINE";
|
||||
case BOOTINFO_TAG_RNG_SEED:
|
||||
return "RNG_SEED";
|
||||
case BOOTINFO_TAG_VIRT_QEMU_VERSION:
|
||||
return "VIRT_QEMU_VERSION";
|
||||
case BOOTINFO_TAG_VIRT_GF_PIC_BASE:
|
||||
return "VIRT_GF_PIC_BASE";
|
||||
case BOOTINFO_TAG_VIRT_GF_RTC_BASE:
|
||||
return "VIRT_GF_RTC_BASE";
|
||||
case BOOTINFO_TAG_VIRT_GF_TTY_BASE:
|
||||
return "VIRT_GF_TTY_BASE";
|
||||
case BOOTINFO_TAG_VIRT_VIRTIO_BASE:
|
||||
return "VIRT_VIRTIO_BASE";
|
||||
case BOOTINFO_TAG_VIRT_CTRL_BASE:
|
||||
return "VIRT_CTRL_BASE";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,4 +104,3 @@ const void *bootinfo_find_record(uint16_t id, uint16_t *size_out) {
|
||||
ptr += item->size;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,34 +7,32 @@
|
||||
*/
|
||||
#include "platform_p.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <inttypes.h>
|
||||
#include <lk/err.h>
|
||||
#include <lk/debug.h>
|
||||
#include <lk/reg.h>
|
||||
#include <lk/trace.h>
|
||||
#include <kernel/debug.h>
|
||||
#include <kernel/thread.h>
|
||||
#include <platform/interrupts.h>
|
||||
#include <platform/virt.h>
|
||||
#include <platform/timer.h>
|
||||
#include <lk/debug.h>
|
||||
#include <lk/err.h>
|
||||
#include <lk/reg.h>
|
||||
#include <lk/trace.h>
|
||||
#include <platform.h>
|
||||
#include <platform/interrupts.h>
|
||||
#include <platform/timer.h>
|
||||
#include <platform/virt.h>
|
||||
|
||||
#define LOCAL_TRACE 0
|
||||
|
||||
// implementation of RTC at
|
||||
// https://github.com/qemu/qemu/blob/master/hw/rtc/goldfish_rtc.c
|
||||
volatile uint32_t * const goldfish_rtc_base = (void *)VIRT_GF_RTC_MMIO_BASE;
|
||||
volatile uint32_t *const goldfish_rtc_base = (void *)VIRT_GF_RTC_MMIO_BASE;
|
||||
|
||||
// registers
|
||||
enum {
|
||||
RTC_TIME_LOW = 0x00,
|
||||
RTC_TIME_HIGH = 0x04,
|
||||
RTC_ALARM_LOW = 0x08,
|
||||
RTC_ALARM_HIGH = 0x0c,
|
||||
RTC_IRQ_ENABLED = 0x10,
|
||||
RTC_CLEAR_ALARM = 0x14,
|
||||
RTC_ALARM_STATUS = 0x18,
|
||||
RTC_TIME_LOW = 0x00,
|
||||
RTC_TIME_HIGH = 0x04,
|
||||
RTC_ALARM_LOW = 0x08,
|
||||
RTC_ALARM_HIGH = 0x0c,
|
||||
RTC_IRQ_ENABLED = 0x10,
|
||||
RTC_CLEAR_ALARM = 0x14,
|
||||
RTC_ALARM_STATUS = 0x18,
|
||||
RTC_CLEAR_INTERRUPT = 0x1c,
|
||||
};
|
||||
|
||||
@@ -105,7 +103,7 @@ lk_time_t current_time(void) {
|
||||
return (lk_time_t)(t / 1000000ULL); // ns -> ms
|
||||
}
|
||||
|
||||
status_t platform_set_oneshot_timer (platform_timer_callback callback, void *arg, lk_time_t interval) {
|
||||
status_t platform_set_oneshot_timer(platform_timer_callback callback, void *arg, lk_time_t interval) {
|
||||
LTRACEF("callback %p, arg %p, interval %u\n", callback, arg, interval);
|
||||
|
||||
t_callback = callback;
|
||||
@@ -126,5 +124,3 @@ void platform_stop_timer(void) {
|
||||
write_reg(RTC_CLEAR_ALARM, 1);
|
||||
write_reg(RTC_CLEAR_INTERRUPT, 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -5,40 +5,44 @@
|
||||
* license that can be found in the LICENSE file or at
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
#include <kernel/thread.h>
|
||||
#include <lib/cbuf.h>
|
||||
#include <lk/reg.h>
|
||||
#include <lk/trace.h>
|
||||
#include <lib/cbuf.h>
|
||||
#include <kernel/thread.h>
|
||||
#include <platform.h>
|
||||
#include <platform/interrupts.h>
|
||||
#include <platform/debug.h>
|
||||
#include <platform/interrupts.h>
|
||||
#include <platform/virt.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#if WITH_KERNEL_VM
|
||||
#include <kernel/vm.h>
|
||||
#endif
|
||||
|
||||
#include "platform_p.h"
|
||||
|
||||
// goldfish tty
|
||||
// from https://github.com/qemu/qemu/blob/master/hw/char/goldfish_tty.c
|
||||
volatile uint32_t * const goldfish_tty_base = (void *)VIRT_GF_TTY_MMIO_BASE;
|
||||
volatile uint32_t *const goldfish_tty_base = (void *)VIRT_GF_TTY_MMIO_BASE;
|
||||
|
||||
// registers
|
||||
enum {
|
||||
REG_PUT_CHAR = 0x00,
|
||||
REG_BYTES_READY = 0x04,
|
||||
REG_CMD = 0x08,
|
||||
REG_DATA_PTR = 0x10,
|
||||
REG_DATA_LEN = 0x14,
|
||||
REG_PUT_CHAR = 0x00,
|
||||
REG_BYTES_READY = 0x04,
|
||||
REG_CMD = 0x08,
|
||||
REG_DATA_PTR = 0x10,
|
||||
REG_DATA_LEN = 0x14,
|
||||
REG_DATA_PTR_HIGH = 0x18,
|
||||
REG_VERSION = 0x20,
|
||||
REG_VERSION = 0x20,
|
||||
};
|
||||
|
||||
// commands
|
||||
|
||||
enum {
|
||||
CMD_INT_DISABLE = 0x00,
|
||||
CMD_INT_ENABLE = 0x01,
|
||||
CMD_WRITE_BUFFER = 0x02,
|
||||
CMD_READ_BUFFER = 0x03,
|
||||
CMD_INT_DISABLE = 0x00,
|
||||
CMD_INT_ENABLE = 0x01,
|
||||
CMD_WRITE_BUFFER = 0x02,
|
||||
CMD_READ_BUFFER = 0x03,
|
||||
};
|
||||
|
||||
#define RXBUF_SIZE 128
|
||||
@@ -59,7 +63,8 @@ static enum handler_return uart_irq_handler(void *arg) {
|
||||
bool resched = false;
|
||||
|
||||
// use a DMA read of one byte if a byte is ready
|
||||
if (read_reg(REG_BYTES_READY) > 0) {
|
||||
uint32_t ready = read_reg(REG_BYTES_READY);
|
||||
if (ready > 0) {
|
||||
write_reg(REG_CMD, CMD_READ_BUFFER);
|
||||
char c = transfer_buf[0];
|
||||
cbuf_write_char(&uart_rx_buf, c, false);
|
||||
@@ -74,7 +79,13 @@ void goldfish_tty_early_init(void) {
|
||||
write_reg(REG_CMD, CMD_INT_DISABLE);
|
||||
|
||||
// set up the transfer buffer for receives
|
||||
write_reg(REG_DATA_PTR, (uint32_t)transfer_buf);
|
||||
uint32_t buf_addr;
|
||||
#if WITH_KERNEL_VM
|
||||
buf_addr = (uint32_t)vaddr_to_paddr(transfer_buf);
|
||||
#else
|
||||
buf_addr = (uint32_t)transfer_buf;
|
||||
#endif
|
||||
write_reg(REG_DATA_PTR, buf_addr);
|
||||
write_reg(REG_DATA_PTR_HIGH, 0);
|
||||
write_reg(REG_DATA_LEN, sizeof(transfer_buf));
|
||||
}
|
||||
@@ -103,8 +114,9 @@ int uart_getc(char *c, bool wait) {
|
||||
}
|
||||
|
||||
void platform_dputc(char c) {
|
||||
if (c == '\n')
|
||||
if (c == '\n') {
|
||||
platform_dputc('\r');
|
||||
}
|
||||
uart_putc(c);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,18 +30,18 @@
|
||||
* CPU IRQ #7 -> NMI
|
||||
*/
|
||||
|
||||
#define VIRT_GF_PIC_MMIO_BASE 0xff000000 /* MMIO: 0xff000000 - 0xff005fff */
|
||||
#define VIRT_GF_PIC_IRQ_BASE 1 /* IRQ: #1 -> #6 */
|
||||
#define VIRT_GF_PIC_MMIO_BASE 0xff000000 /* MMIO: 0xff000000 - 0xff005fff */
|
||||
#define VIRT_GF_PIC_IRQ_BASE 1 /* IRQ: #1 -> #6 */
|
||||
#define VIRT_GF_PIC_NB 6
|
||||
|
||||
#define NUM_IRQS (VIRT_GF_PIC_NB * 32) // PIC 1 - 6
|
||||
#define NUM_IRQS (VIRT_GF_PIC_NB * 32) // PIC 1 - 6
|
||||
|
||||
/* maps (pic + irq) base one to a linear number zero based */
|
||||
#define PIC_IRQ(pic, irq) (((pic) - 1) * 32 + ((irq) - 1))
|
||||
#define PIC_IRQ(pic, irq) (((pic) - 1) * 32 + ((irq) - 1))
|
||||
|
||||
/* 2 goldfish-rtc (and timer) */
|
||||
#define VIRT_GF_RTC_MMIO_BASE 0xff006000 /* MMIO: 0xff006000 - 0xff007fff */
|
||||
#define VIRT_GF_RTC_IRQ_BASE PIC_IRQ(6, 1) /* PIC: #6, IRQ: #1 */
|
||||
#define VIRT_GF_RTC_MMIO_BASE 0xff006000 /* MMIO: 0xff006000 - 0xff007fff */
|
||||
#define VIRT_GF_RTC_IRQ_BASE PIC_IRQ(6, 1) /* PIC: #6, IRQ: #1 */
|
||||
#define VIRT_GF_RTC_NB 2
|
||||
|
||||
/* 1 goldfish-tty */
|
||||
@@ -50,7 +50,7 @@
|
||||
|
||||
/* 1 virt-ctrl */
|
||||
#define VIRT_CTRL_MMIO_BASE 0xff009000 /* MMIO: 0xff009000 - 0xff009fff */
|
||||
#define VIRT_CTRL_IRQ_BASE PIC_IRQ(1, 1) /* PIC: #1, IRQ: #1 */
|
||||
#define VIRT_CTRL_IRQ_BASE PIC_IRQ(1, 1) /* PIC: #1, IRQ: #1 */
|
||||
|
||||
/*
|
||||
* virtio-mmio size is 0x200 bytes
|
||||
@@ -58,7 +58,7 @@
|
||||
* we can attach 32 virtio devices / goldfish-pic
|
||||
* -> we can manage 32 * 4 = 128 virtio devices
|
||||
*/
|
||||
#define VIRT_VIRTIO_MMIO_BASE 0xff010000 /* MMIO: 0xff010000 - 0xff01ffff */
|
||||
#define VIRT_VIRTIO_IRQ_BASE PIC_IRQ(2, 1) /* PIC: 2, 3, 4, 5, IRQ: ALL */
|
||||
#define VIRT_VIRTIO_MMIO_BASE 0xff010000 /* MMIO: 0xff010000 - 0xff01ffff */
|
||||
#define VIRT_VIRTIO_IRQ_BASE PIC_IRQ(2, 1) /* PIC: 2, 3, 4, 5, IRQ: ALL */
|
||||
|
||||
#define NUM_VIRT_VIRTIO 128
|
||||
|
||||
@@ -8,13 +8,13 @@
|
||||
#include "platform_p.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <lk/bits.h>
|
||||
#include <lk/err.h>
|
||||
#include <lk/debug.h>
|
||||
#include <lk/reg.h>
|
||||
#include <lk/trace.h>
|
||||
#include <kernel/debug.h>
|
||||
#include <kernel/thread.h>
|
||||
#include <lk/bits.h>
|
||||
#include <lk/debug.h>
|
||||
#include <lk/err.h>
|
||||
#include <lk/reg.h>
|
||||
#include <lk/trace.h>
|
||||
#include <platform/interrupts.h>
|
||||
#include <platform/virt.h>
|
||||
|
||||
@@ -24,14 +24,14 @@
|
||||
// https://github.com/qemu/qemu/blob/master/hw/intc/goldfish_pic.c
|
||||
|
||||
enum {
|
||||
REG_STATUS = 0x00,
|
||||
REG_IRQ_PENDING = 0x04,
|
||||
REG_STATUS = 0x00,
|
||||
REG_IRQ_PENDING = 0x04,
|
||||
REG_IRQ_DISABLE_ALL = 0x08,
|
||||
REG_DISABLE = 0x0c,
|
||||
REG_ENABLE = 0x10,
|
||||
REG_DISABLE = 0x0c,
|
||||
REG_ENABLE = 0x10,
|
||||
};
|
||||
|
||||
volatile uint32_t * const goldfish_pic_base = (void *)VIRT_GF_PIC_MMIO_BASE;
|
||||
volatile uint32_t *const goldfish_pic_base = (void *)VIRT_GF_PIC_MMIO_BASE;
|
||||
|
||||
static struct int_handlers {
|
||||
int_handler handler;
|
||||
@@ -128,4 +128,3 @@ enum handler_return m68k_platform_irq(uint8_t m68k_irq) {
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -98,7 +98,8 @@ void platform_init(void) {
|
||||
goldfish_rtc_init();
|
||||
|
||||
#if M68K_MMU == 68040
|
||||
// TODO: create a VM reservation for peripheral space thats using DTTR1
|
||||
// create a VM reservation for peripheral space thats using DTTR1
|
||||
vmm_reserve_space(vmm_get_kernel_aspace(), "periph", 0x1000000, 0xff000000);
|
||||
#endif
|
||||
|
||||
/* detect any virtio devices */
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
void uart_init(void);
|
||||
|
||||
void pic_early_init(void);
|
||||
|
||||
Reference in New Issue
Block a user